X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2ee3ee1bc8ac2f95029835ebc115fac0a1fbd02a..1a86d2e52c76551a8067403bc08d82bee0186d2c:/src/common/lboxcmn.cpp diff --git a/src/common/lboxcmn.cpp b/src/common/lboxcmn.cpp index 8525ef8104..dfd4b69564 100644 --- a/src/common/lboxcmn.cpp +++ b/src/common/lboxcmn.cpp @@ -1,12 +1,12 @@ /////////////////////////////////////////////////////////////////////////////// -// Name: common/lboxcmn.cpp +// Name: src/common/lboxcmn.cpp // Purpose: wxListBox class methods common to all platforms // Author: Vadim Zeitlin // Modified by: // Created: 22.10.99 // RCS-ID: $Id$ -// Copyright: (c) wxWindows team -// Licence: wxWindows licence +// Copyright: (c) wxWidgets team +// Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// // ============================================================================ @@ -17,10 +17,6 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ - #pragma implementation "listboxbase.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -28,124 +24,205 @@ #pragma hdrstop #endif +#if wxUSE_LISTBOX + +#include "wx/listbox.h" + #ifndef WX_PRECOMP - #include "wx/listbox.h" + #include "wx/dynarray.h" + #include "wx/arrstr.h" #endif +#include "wx/log.h" + // ============================================================================ // implementation // ============================================================================ -// ---------------------------------------------------------------------------- -// adding items -// ---------------------------------------------------------------------------- - -void wxListBoxBase::InsertItems(int nItems, const wxString *items, int pos) +wxListBoxBase::~wxListBoxBase() { - wxArrayString aItems; - for ( int n = 0; n < nItems; n++ ) - { - aItems.Add(items[n]); - } - - DoInsertItems(aItems, pos); -} - - -void wxListBoxBase::Set(int nItems, const wxString* items, void **clientData) -{ - wxArrayString aItems; - for ( int n = 0; n < nItems; n++ ) - { - aItems.Add(items[n]); - } - - DoSetItems(aItems, clientData); + // this destructor is required for Darwin } // ---------------------------------------------------------------------------- // selection // ---------------------------------------------------------------------------- -wxString wxListBoxBase::GetStringSelection () const -{ - wxString s; - int sel = GetSelection(); - if ( sel != -1 ) - s = GetString(sel); - - return s; -} - bool wxListBoxBase::SetStringSelection(const wxString& s, bool select) { - int sel = FindString(s); - wxCHECK_MSG( sel != -1, FALSE, - wxT("invalid string in wxListBox::SetStringSelection") ); + const int sel = FindString(s); + if ( sel == wxNOT_FOUND ) + return false; SetSelection(sel, select); - return TRUE; + return true; } -// ---------------------------------------------------------------------------- -// client data -// ---------------------------------------------------------------------------- - -void wxListBoxBase::SetClientObject(int n, wxClientData *data) +void wxListBoxBase::DeselectAll(int itemToLeaveSelected) { - wxASSERT_MSG( m_clientDataItemsType != ClientData_Void, - wxT("can't have both object and void client data") ); - - wxClientData *clientDataOld = DoGetClientObject(n); - if ( clientDataOld ) - delete clientDataOld; - - DoSetClientObject(n, data); - m_clientDataItemsType = ClientData_Object; + if ( HasMultipleSelection() ) + { + wxArrayInt selections; + GetSelections(selections); + + size_t count = selections.GetCount(); + for ( size_t n = 0; n < count; n++ ) + { + int item = selections[n]; + if ( item != itemToLeaveSelected ) + Deselect(item); + } + } + else // single selection + { + int sel = GetSelection(); + if ( sel != wxNOT_FOUND && sel != itemToLeaveSelected ) + { + Deselect(sel); + } + } } -wxClientData *wxListBoxBase::GetClientObject(int n) const +void wxListBoxBase::UpdateOldSelections() { - wxASSERT_MSG( m_clientDataItemsType == ClientData_Object, - wxT("this window doesn't have object client data") ); - - return DoGetClientObject(n); + if (HasFlag(wxLB_MULTIPLE) || HasFlag(wxLB_EXTENDED)) + GetSelections( m_oldSelections ); } -void wxListBoxBase::SetClientData(int n, void *data) +static void LBSendEvent( wxCommandEvent &event, wxListBoxBase *listbox, int item ) { - wxASSERT_MSG( m_clientDataItemsType != ClientData_Object, - wxT("can't have both object and void client data") ); - - DoSetClientData(n, data); - m_clientDataItemsType = ClientData_Void; + event.SetInt( item ); + event.SetString( listbox->GetString( item ) ); + if ( listbox->HasClientObjectData() ) + event.SetClientObject( listbox->GetClientObject(item) ); + else if ( listbox->HasClientUntypedData() ) + event.SetClientData( listbox->GetClientData(item) ); + listbox->HandleWindowEvent( event ); } -void *wxListBoxBase::GetClientData(int n) const +void wxListBoxBase::CalcAndSendEvent() { - wxASSERT_MSG( m_clientDataItemsType == ClientData_Void, - wxT("this window doesn't have void client data") ); - - return DoGetClientData(n); + wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, GetId() ); + event.SetEventObject( this ); + + wxArrayInt selections; + GetSelections( selections ); + + if ((selections.GetCount() == 0) && (m_oldSelections.GetCount() == 0)) + { + // nothing changed, just leave + return; + } + + if (selections.GetCount() == m_oldSelections.GetCount()) + { + bool changed = false; + size_t idx; + for (idx = 0; idx < selections.GetCount(); idx++) + { + if (selections[idx] != m_oldSelections[idx]) + { + changed = true; + break; + } + } + + // nothing changed, just leave + if (!changed) + return; + } + + if (selections.GetCount() == 0) + { + // indicate that this is a deselection + event.SetExtraLong( 0 ); + int item = m_oldSelections[0]; + m_oldSelections = selections; + LBSendEvent( event, this, item ); + return; + } + + int item; + // Now test if any new item is selected + bool any_new_selected = false; + size_t idx; + for (idx = 0; idx < selections.GetCount(); idx++) + { + item = selections[idx]; + if (m_oldSelections.Index(item) == wxNOT_FOUND) + { + any_new_selected = true; + break; + } + } + + if (any_new_selected) + { + // indicate that this is a selection + event.SetExtraLong( 1 ); + m_oldSelections = selections; + LBSendEvent( event, this, item ); + return; + } + + // Now test if any new item is deselected + bool any_new_deselected = false; + for (idx = 0; idx < m_oldSelections.GetCount(); idx++) + { + item = m_oldSelections[idx]; + if (selections.Index(item) == wxNOT_FOUND) + { + any_new_deselected = true; + break; + } + } + + if (any_new_deselected) + { + // indicate that this is a selection + event.SetExtraLong( 0 ); + m_oldSelections = selections; + LBSendEvent( event, this, item ); + return; + } + + wxLogError( wxT("Wrong wxListBox selection") ); } // ---------------------------------------------------------------------------- // misc // ---------------------------------------------------------------------------- +void wxListBoxBase::Command(wxCommandEvent& event) +{ + SetSelection(event.GetInt(), event.GetExtraLong() != 0); + (void)ProcessEvent(event); +} + +// ---------------------------------------------------------------------------- +// SetFirstItem() and such +// ---------------------------------------------------------------------------- + void wxListBoxBase::SetFirstItem(const wxString& s) { int n = FindString(s); - wxCHECK_RET( n != -1, wxT("invalid string in wxListBox::SetFirstItem") ); + wxCHECK_RET( n != wxNOT_FOUND, wxT("invalid string in wxListBox::SetFirstItem") ); DoSetFirstItem(n); } -void wxListBoxBase::Command(wxCommandEvent & event) +void wxListBoxBase::AppendAndEnsureVisible(const wxString& s) { - SetSelection(event.m_commandInt, event.m_extraLong); - (void)ProcessEvent(event); + Append(s); + EnsureVisible(GetCount() - 1); +} + +void wxListBoxBase::EnsureVisible(int WXUNUSED(n)) +{ + // the base class version does nothing (the only alternative would be to + // call SetFirstItem() but this is probably even more stupid) } +#endif // wxUSE_LISTBOX