X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2154130cd11ff567041bf6b74f6fead9dcd8983b..a1bdd4ab9bb8cdcf8a14b8a64a5f5508be48ba4c:/src/gtk/listbox.cpp diff --git a/src/gtk/listbox.cpp b/src/gtk/listbox.cpp index 225c06994d..0a266f5376 100644 --- a/src/gtk/listbox.cpp +++ b/src/gtk/listbox.cpp @@ -79,7 +79,7 @@ gtk_listbox_row_activated_callback(GtkTreeView * WXUNUSED(treeview), if (listbox->IsSelected(sel)) { - GtkTreeEntry* entry = listbox->GtkGetEntry(sel); + GtkTreeEntry* entry = listbox->GTKGetEntry(sel); if (entry) { @@ -112,17 +112,6 @@ gtk_listbox_row_activated_callback(GtkTreeView * WXUNUSED(treeview), // "changed" //----------------------------------------------------------------------------- -static void SendEvent( wxCommandEvent &event, wxListBox *listbox, int item ) -{ - 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 ); -} - extern "C" { static void gtk_listitem_changed_callback(GtkTreeSelection * WXUNUSED(selection), @@ -130,96 +119,15 @@ gtk_listitem_changed_callback(GtkTreeSelection * WXUNUSED(selection), { if (g_blockEventsOnDrag) return; - wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, listbox->GetId() ); - event.SetEventObject( listbox ); - - if (listbox->HasFlag(wxLB_MULTIPLE) || listbox->HasFlag(wxLB_EXTENDED)) + if (listbox->HasFlag(wxLB_MULTIPLE | wxLB_EXTENDED)) { - wxArrayInt selections; - listbox->GetSelections( selections ); - - if ((selections.GetCount() == 0) && (listbox->m_oldSelection.GetCount() == 0)) - { - // nothing changed, just leave - return; - } - - if (selections.GetCount() == listbox->m_oldSelection.GetCount()) - { - bool changed = false; - size_t idx; - for (idx = 0; idx < selections.GetCount(); idx++) - { - if (selections[idx] != listbox->m_oldSelection[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 = listbox->m_oldSelection[0]; - listbox->m_oldSelection = selections; - SendEvent( event, listbox, 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 (listbox->m_oldSelection.Index(item) == wxNOT_FOUND) - { - any_new_selected = true; - break; - } - } - - if (any_new_selected) - { - // indicate that this is a selection - event.SetExtraLong( 1 ); - listbox->m_oldSelection = selections; - SendEvent( event, listbox, item ); - return; - } - - // Now test if any new item is deselected - bool any_new_deselected = false; - for (idx = 0; idx < listbox->m_oldSelection.GetCount(); idx++) - { - item = listbox->m_oldSelection[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 ); - listbox->m_oldSelection = selections; - SendEvent( event, listbox, item ); - return; - } - - wxLogError( wxT("Wrong wxListBox selection") ); + listbox->CalcAndSendEvent(); } - else + else // single selection { + wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, listbox->GetId() ); + event.SetEventObject( listbox ); + int index = listbox->GetSelection(); if (index == wxNOT_FOUND) { @@ -233,7 +141,7 @@ gtk_listitem_changed_callback(GtkTreeSelection * WXUNUSED(selection), } else { - GtkTreeEntry* entry = listbox->GtkGetEntry( index ); + GtkTreeEntry* entry = listbox->GTKGetEntry( index ); // indicate that this is a selection event.SetExtraLong( 1 ); @@ -261,23 +169,32 @@ gtk_listitem_changed_callback(GtkTreeSelection * WXUNUSED(selection), //----------------------------------------------------------------------------- extern "C" { -static gint +static gboolean gtk_listbox_key_press_callback( GtkWidget *WXUNUSED(widget), GdkEventKey *gdk_event, wxListBox *listbox ) { - if ((gdk_event->keyval == GDK_Return) || + if ((gdk_event->keyval == GDK_Return) || (gdk_event->keyval == GDK_ISO_Enter) || (gdk_event->keyval == GDK_KP_Enter)) { - int index = listbox->GetSelection(); + int index = -1; + if (!listbox->HasMultipleSelection()) + index = listbox->GetSelection(); + else + { + wxArrayInt sels; + if (listbox->GetSelections( sels ) < 1) + return FALSE; + index = sels[0]; + } + if (index != wxNOT_FOUND) { - wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, listbox->GetId() ); event.SetEventObject( listbox ); - - GtkTreeEntry* entry = listbox->GtkGetEntry( index ); + + GtkTreeEntry* entry = listbox->GTKGetEntry( index ); // indicate that this is a selection event.SetExtraLong( 1 ); @@ -295,7 +212,7 @@ gtk_listbox_key_press_callback( GtkWidget *WXUNUSED(widget), /* bool ret = */ listbox->HandleWindowEvent( event ); g_object_unref (entry); - + // wxMac and wxMSW always invoke default action // if (!ret) { @@ -308,13 +225,13 @@ gtk_listbox_key_press_callback( GtkWidget *WXUNUSED(widget), gtk_window_activate_default( gtk_window ); } } - + // Always intercept, otherwise we'd get another dclick // event from row_activated return TRUE; } } - + return FALSE; } } @@ -413,7 +330,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControlWithItems) void wxListBox::Init() { - m_treeview = (GtkTreeView*) NULL; + m_treeview = NULL; #if wxUSE_CHECKLISTBOX m_hasCheckBoxes = false; #endif // wxUSE_CHECKLISTBOX @@ -444,7 +361,8 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, return false; } - m_widget = gtk_scrolled_window_new( (GtkAdjustment*) NULL, (GtkAdjustment*) NULL ); + m_widget = gtk_scrolled_window_new( NULL, NULL ); + g_object_ref(m_widget); if (style & wxLB_ALWAYS_SB) { gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(m_widget), @@ -457,7 +375,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, } - GtkScrolledWindowSetBorder(m_widget, style); + GTKScrolledWindowSetBorder(m_widget, style); m_treeview = GTK_TREE_VIEW( gtk_tree_view_new( ) ); @@ -504,17 +422,13 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, gtk_tree_view_set_enable_search(m_treeview, FALSE); GtkSelectionMode mode; - if (style & wxLB_MULTIPLE) + // GTK_SELECTION_EXTENDED is a deprecated synonym for GTK_SELECTION_MULTIPLE + if ( style & (wxLB_MULTIPLE | wxLB_EXTENDED) ) { mode = GTK_SELECTION_MULTIPLE; } - else if (style & wxLB_EXTENDED) - { - mode = GTK_SELECTION_EXTENDED; - } - else + else // no multi-selection flags specified { - // if style was 0 set single mode m_windowStyle |= wxLB_SINGLE; mode = GTK_SELECTION_SINGLE; } @@ -562,7 +476,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, g_signal_connect_after (selection, "changed", G_CALLBACK (gtk_listitem_changed_callback), this); - + return true; } @@ -573,7 +487,7 @@ wxListBox::~wxListBox() Clear(); } -void wxListBox::GtkDisableEvents() +void wxListBox::GTKDisableEvents() { GtkTreeSelection* selection = gtk_tree_view_get_selection( m_treeview ); @@ -581,14 +495,23 @@ void wxListBox::GtkDisableEvents() (gpointer) gtk_listitem_changed_callback, this); } -void wxListBox::GtkEnableEvents() +void wxListBox::GTKEnableEvents() { GtkTreeSelection* selection = gtk_tree_view_get_selection( m_treeview ); g_signal_handlers_unblock_by_func(selection, (gpointer) gtk_listitem_changed_callback, this); - - GtkUpdateOldSelection(); + + UpdateOldSelections(); +} + + +void wxListBox::Update() +{ + wxWindow::Update(); + + if (m_treeview) + gdk_window_process_updates(GTK_WIDGET(m_treeview)->window, TRUE); } // ---------------------------------------------------------------------------- @@ -608,7 +531,7 @@ int wxListBox::DoInsertItems(const wxArrayStringsAdapter& items, GtkTreeIter iter; if ( pos != GetCount() ) { - wxCHECK_MSG( GtkGetIteratorFor(pos, &iter), wxNOT_FOUND, + wxCHECK_MSG( GTKGetIteratorFor(pos, &iter), wxNOT_FOUND, wxT("internal wxListBox error in insertion") ); pIter = &iter; @@ -626,14 +549,16 @@ int wxListBox::DoInsertItems(const wxArrayStringsAdapter& items, GtkTreeIter itercur; gtk_list_store_insert_before(m_liststore, &itercur, pIter); - GtkSetItem(itercur, entry); + GTKSetItem(itercur, entry); g_object_unref (entry); if (clientData) - AssignNewItemClientData(GtkGetIndexFor(itercur), clientData, i, type); + AssignNewItemClientData(GTKGetIndexFor(itercur), clientData, i, type); } + UpdateOldSelections(); + return pos + numItems - 1; } @@ -645,13 +570,13 @@ void wxListBox::DoClear() { wxCHECK_RET( m_treeview != NULL, wxT("invalid listbox") ); - GtkDisableEvents(); // just in case + GTKDisableEvents(); // just in case InvalidateBestSize(); gtk_list_store_clear( m_liststore ); /* well, THAT was easy :) */ - - GtkEnableEvents(); + + GTKEnableEvents(); } void wxListBox::DoDeleteOneItem(unsigned int n) @@ -660,23 +585,23 @@ void wxListBox::DoDeleteOneItem(unsigned int n) InvalidateBestSize(); - GtkDisableEvents(); // just in case + GTKDisableEvents(); // just in case GtkTreeIter iter; - wxCHECK_RET( GtkGetIteratorFor(n, &iter), wxT("wrong listbox index") ); + wxCHECK_RET( GTKGetIteratorFor(n, &iter), wxT("wrong listbox index") ); // this returns false if iter is invalid (e.g. deleting item at end) but // since we don't use iter, we ignore the return value gtk_list_store_remove(m_liststore, &iter); - - GtkEnableEvents(); + + GTKEnableEvents(); } // ---------------------------------------------------------------------------- // helper functions for working with iterators // ---------------------------------------------------------------------------- -bool wxListBox::GtkGetIteratorFor(unsigned pos, GtkTreeIter *iter) const +bool wxListBox::GTKGetIteratorFor(unsigned pos, GtkTreeIter *iter) const { if ( !gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(m_liststore), iter, NULL, pos) ) @@ -688,14 +613,14 @@ bool wxListBox::GtkGetIteratorFor(unsigned pos, GtkTreeIter *iter) const return true; } -int wxListBox::GtkGetIndexFor(GtkTreeIter& iter) const +int wxListBox::GTKGetIndexFor(GtkTreeIter& iter) const { GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(m_liststore), &iter); gint* pIntPath = gtk_tree_path_get_indices(path); - wxCHECK_MSG( pIntPath, wxNOT_FOUND, _T("failed to get iterator path") ); + wxCHECK_MSG( pIntPath, wxNOT_FOUND, wxT("failed to get iterator path") ); int idx = pIntPath[0]; @@ -705,10 +630,10 @@ int wxListBox::GtkGetIndexFor(GtkTreeIter& iter) const } // get GtkTreeEntry from position (note: you need to g_unref it if valid) -GtkTreeEntry *wxListBox::GtkGetEntry(unsigned n) const +GtkTreeEntry *wxListBox::GTKGetEntry(unsigned n) const { GtkTreeIter iter; - if ( !GtkGetIteratorFor(n, &iter) ) + if ( !GTKGetIteratorFor(n, &iter) ) return NULL; @@ -719,7 +644,7 @@ GtkTreeEntry *wxListBox::GtkGetEntry(unsigned n) const return entry; } -void wxListBox::GtkSetItem(GtkTreeIter& iter, const GtkTreeEntry *entry) +void wxListBox::GTKSetItem(GtkTreeIter& iter, const GtkTreeEntry *entry) { #if wxUSE_CHECKLISTBOX if ( m_hasCheckBoxes ) @@ -745,7 +670,7 @@ void* wxListBox::DoGetItemClientData(unsigned int n) const wxCHECK_MSG( IsValid(n), NULL, wxT("Invalid index passed to GetItemClientData") ); - GtkTreeEntry* entry = GtkGetEntry(n); + GtkTreeEntry* entry = GTKGetEntry(n); wxCHECK_MSG(entry, NULL, wxT("could not get entry")); void* userdata = gtk_tree_entry_get_userdata( entry ); @@ -758,7 +683,7 @@ void wxListBox::DoSetItemClientData(unsigned int n, void* clientData) wxCHECK_RET( IsValid(n), wxT("Invalid index passed to SetItemClientData") ); - GtkTreeEntry* entry = GtkGetEntry(n); + GtkTreeEntry* entry = GTKGetEntry(n); wxCHECK_RET(entry, wxT("could not get entry")); gtk_tree_entry_set_userdata( entry, clientData ); @@ -774,7 +699,7 @@ void wxListBox::SetString(unsigned int n, const wxString& label) wxCHECK_RET( IsValid(n), wxT("invalid index in wxListBox::SetString") ); wxCHECK_RET( m_treeview != NULL, wxT("invalid listbox") ); - GtkTreeEntry* entry = GtkGetEntry(n); + GtkTreeEntry* entry = GTKGetEntry(n); wxCHECK_RET( entry, wxT("wrong listbox index") ); // update the item itself @@ -782,18 +707,18 @@ void wxListBox::SetString(unsigned int n, const wxString& label) // and update the model which will refresh the tree too GtkTreeIter iter; - wxCHECK_RET( GtkGetIteratorFor(n, &iter), _T("failed to get iterator") ); + wxCHECK_RET( GTKGetIteratorFor(n, &iter), wxT("failed to get iterator") ); // FIXME: this resets the checked status of a wxCheckListBox item - GtkSetItem(iter, entry); + GTKSetItem(iter, entry); } wxString wxListBox::GetString(unsigned int n) const { wxCHECK_MSG( m_treeview != NULL, wxEmptyString, wxT("invalid listbox") ); - GtkTreeEntry* entry = GtkGetEntry(n); + GtkTreeEntry* entry = GTKGetEntry(n); wxCHECK_MSG( entry, wxEmptyString, wxT("wrong listbox index") ); wxString label = wxGTK_CONV_BACK( gtk_tree_entry_get_label(entry) ); @@ -844,7 +769,7 @@ int wxListBox::GetSelection() const if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) return wxNOT_FOUND; - return GtkGetIndexFor(iter); + return GTKGetIndexFor(iter); } int wxListBox::GetSelections( wxArrayInt& aSelections ) const @@ -853,7 +778,7 @@ int wxListBox::GetSelections( wxArrayInt& aSelections ) const aSelections.Empty(); - int i = 0; + int i = 0; GtkTreeIter iter; GtkTreeSelection* selection = gtk_tree_view_get_selection(m_treeview); @@ -878,7 +803,7 @@ bool wxListBox::IsSelected( int n ) const GtkTreeSelection* selection = gtk_tree_view_get_selection(m_treeview); GtkTreeIter iter; - wxCHECK_MSG( GtkGetIteratorFor(n, &iter), false, wxT("Invalid index") ); + wxCHECK_MSG( GTKGetIteratorFor(n, &iter), false, wxT("Invalid index") ); return gtk_tree_selection_iter_is_selected(selection, &iter); } @@ -887,23 +812,23 @@ void wxListBox::DoSetSelection( int n, bool select ) { wxCHECK_RET( m_treeview != NULL, wxT("invalid listbox") ); - GtkDisableEvents(); - + GTKDisableEvents(); + GtkTreeSelection* selection = gtk_tree_view_get_selection(m_treeview); // passing -1 to SetSelection() is documented to deselect all items if ( n == wxNOT_FOUND ) { gtk_tree_selection_unselect_all(selection); - GtkEnableEvents(); + GTKEnableEvents(); return; } wxCHECK_RET( IsValid(n), wxT("invalid index in wxListBox::SetSelection") ); - + GtkTreeIter iter; - wxCHECK_RET( GtkGetIteratorFor(n, &iter), wxT("Invalid index") ); + wxCHECK_RET( GTKGetIteratorFor(n, &iter), wxT("Invalid index") ); if (select) gtk_tree_selection_select_iter(selection, &iter); @@ -917,13 +842,7 @@ void wxListBox::DoSetSelection( int n, bool select ) gtk_tree_path_free(path); - GtkEnableEvents(); -} - -void wxListBox::GtkUpdateOldSelection() -{ - if (HasFlag(wxLB_MULTIPLE) || HasFlag(wxLB_EXTENDED)) - GetSelections( m_oldSelection ); + GTKEnableEvents(); } void wxListBox::DoScrollToCell(int n, float alignY, float alignX) @@ -936,7 +855,7 @@ void wxListBox::DoScrollToCell(int n, float alignY, float alignX) return; GtkTreeIter iter; - if ( !GtkGetIteratorFor(n, &iter) ) + if ( !GTKGetIteratorFor(n, &iter) ) return; GtkTreePath* path = gtk_tree_model_get_path( @@ -1001,10 +920,10 @@ int wxListBox::DoListHitTest(const wxPoint& point) const // ---------------------------------------------------------------------------- #if wxUSE_TOOLTIPS -void wxListBox::ApplyToolTip( GtkTooltips *tips, const gchar *tip ) +void wxListBox::GTKApplyToolTip( GtkTooltips *tips, const gchar *tip ) { // RN: Is this needed anymore? - gtk_tooltips_set_tip( tips, GTK_WIDGET( m_treeview ), tip, (gchar*) NULL ); + gtk_tooltips_set_tip( tips, GTK_WIDGET( m_treeview ), tip, NULL ); } #endif // wxUSE_TOOLTIPS