X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/caf6e6dee8d177844bb633786ec8c05eba6972bc..6d7b547184bfdcdf67790755deb0122050b1d728:/src/gtk/listbox.cpp diff --git a/src/gtk/listbox.cpp b/src/gtk/listbox.cpp index 5712ee3955..beb8d7d336 100644 --- a/src/gtk/listbox.cpp +++ b/src/gtk/listbox.cpp @@ -14,18 +14,22 @@ #if wxUSE_LISTBOX #include "wx/listbox.h" -#include "wx/dynarray.h" -#include "wx/arrstr.h" -#include "wx/utils.h" -#include "wx/intl.h" -#include "wx/checklst.h" -#include "wx/settings.h" -#include "wx/log.h" + +#ifndef WX_PRECOMP + #include "wx/dynarray.h" + #include "wx/intl.h" + #include "wx/log.h" + #include "wx/utils.h" + #include "wx/settings.h" + #include "wx/checklst.h" + #include "wx/arrstr.h" +#endif + #include "wx/gtk/private.h" #include "wx/gtk/treeentry_gtk.h" #if wxUSE_TOOLTIPS -#include "wx/tooltip.h" + #include "wx/tooltip.h" #endif #include @@ -102,7 +106,7 @@ gtk_listbox_row_activated_callback(GtkTreeView *treeview, (wxClientData*) gtk_tree_entry_get_userdata(entry) ); else if ( listbox->HasClientUntypedData() ) event.SetClientData( gtk_tree_entry_get_userdata(entry) ); - g_object_unref(G_OBJECT(entry)); + g_object_unref (entry); } else { @@ -316,7 +320,7 @@ static gboolean gtk_listitem_select_cb( GtkTreeSelection* selection, listbox->GetEventHandler()->ProcessEvent( event ); - g_object_unref(G_OBJECT(entry)); + g_object_unref (entry); return FALSE; //We handled it/did it manually } @@ -370,8 +374,8 @@ static gint gtk_listbox_sort_callback(GtkTreeModel *model, int ret = strcasecmp(gtk_tree_entry_get_collate_key(entry), gtk_tree_entry_get_collate_key(entry2)); - g_object_unref(G_OBJECT(entry)); - g_object_unref(G_OBJECT(entry2)); + g_object_unref (entry); + g_object_unref (entry2); return ret; } @@ -401,7 +405,7 @@ static gboolean gtk_listbox_searchequal_callback(GtkTreeModel* model, gtk_tree_entry_get_collate_key(entry)); g_free(keycollatekey); - g_object_unref(G_OBJECT(entry)); + g_object_unref (entry); return ret != 0; } @@ -467,6 +471,9 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC ); } + + GtkScrolledWindowSetBorder(m_widget, style); + m_treeview = GTK_TREE_VIEW( gtk_tree_view_new( ) ); //wxListBox doesn't have a header :) @@ -495,7 +502,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, gtk_tree_view_set_model(m_treeview, GTK_TREE_MODEL(m_liststore)); - g_object_unref(G_OBJECT(m_liststore)); //free on treeview destruction + g_object_unref (m_liststore); //free on treeview destruction // Disable the pop-up textctrl that enables searching - note that // the docs specify that even if this disabled (which we are doing) @@ -591,7 +598,7 @@ wxListBox::~wxListBox() // ---------------------------------------------------------------------------- void wxListBox::GtkInsertItems(const wxArrayString& items, - void** clientData, int pos) + void** clientData, unsigned int pos) { wxCHECK_RET( m_treeview != NULL, wxT("invalid listbox") ); @@ -599,8 +606,8 @@ void wxListBox::GtkInsertItems(const wxArrayString& items, // Create and set column ids and GValues - size_t nNum = items.GetCount(); - int nCurCount = wxListBox::GetCount(); + unsigned int nNum = items.GetCount(); + unsigned int nCurCount = wxListBox::GetCount(); wxASSERT_MSG(pos <= nCurCount, wxT("Invalid index passed to wxListBox")); GtkTreeIter* pIter = NULL; // append by default @@ -610,7 +617,7 @@ void wxListBox::GtkInsertItems(const wxArrayString& items, gboolean res = gtk_tree_model_iter_nth_child( GTK_TREE_MODEL(m_liststore), &iter, NULL, //NULL = parent = get first - pos ); + (int)pos ); if(!res) { wxLogSysError(wxT("internal wxListBox error in insertion")); @@ -620,15 +627,15 @@ void wxListBox::GtkInsertItems(const wxArrayString& items, pIter = &iter; } - for (size_t i = 0; i < nNum; ++i) + for (unsigned int i = 0; i < nNum; ++i) { wxString label = items[i]; #if wxUSE_CHECKLISTBOX && !wxUSE_NATIVEGTKCHECKLIST - if (m_hasCheckBoxes) - { - label.Prepend(wxCHECKLBOX_STRING); - } + if (m_hasCheckBoxes) + { + label.Prepend(wxCHECKLBOX_STRING); + } #endif // wxUSE_CHECKLISTBOX @@ -656,19 +663,21 @@ void wxListBox::GtkInsertItems(const wxArrayString& items, gtk_list_store_set(m_liststore, &itercur, 0, entry, -1); - g_object_unref(G_OBJECT(entry)); //liststore always refs :) + g_object_unref (entry); //liststore always refs :) } } -void wxListBox::DoInsertItems(const wxArrayString& items, int pos) +void wxListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) { + wxCHECK_RET( IsValidInsert(pos), wxT("invalid index in wxListBox::InsertItems") ); + GtkInsertItems(items, NULL, pos); } int wxListBox::DoAppend( const wxString& item ) { // Call DoInsertItems - int nWhere = wxListBox::GetCount(); + unsigned int nWhere = wxListBox::GetCount(); wxArrayString aItems; aItems.Add(item); wxListBox::DoInsertItems(aItems, nWhere); @@ -695,7 +704,7 @@ void wxListBox::Clear() gtk_list_store_clear( m_liststore ); /* well, THAT was easy :) */ } -void wxListBox::Delete( int n ) +void wxListBox::Delete(unsigned int n) { wxCHECK_RET( m_treeview != NULL, wxT("invalid listbox") ); @@ -706,7 +715,7 @@ void wxListBox::Delete( int n ) GTK_TREE_MODEL(m_liststore), &iter, NULL, //NULL = parent = get first n - ); + ); wxCHECK_RET( res, wxT("wrong listbox index") ); @@ -730,7 +739,7 @@ struct _GtkTreeEntry* wxListBox::GtkGetEntry(int n) const if (!res) { wxLogDebug(wxT("gtk_tree_model_iter_nth_child failed\n") - wxT("Passed in value was:[%i] List size:[%i]"), + wxT("Passed in value was:[%i] List size:[%u]"), n, wxListBox::GetCount() ); return NULL; } @@ -747,37 +756,37 @@ struct _GtkTreeEntry* wxListBox::GtkGetEntry(int n) const // client data // ---------------------------------------------------------------------------- -void* wxListBox::DoGetItemClientData( int n ) const +void* wxListBox::DoGetItemClientData(unsigned int n) const { - wxCHECK_MSG( n >= 0 && n < wxListBox::GetCount(), NULL, + wxCHECK_MSG( IsValid(n), NULL, wxT("Invalid index passed to GetItemClientData") ); GtkTreeEntry* entry = GtkGetEntry(n); wxCHECK_MSG(entry, NULL, wxT("could not get entry")); void* userdata = gtk_tree_entry_get_userdata( entry ); - g_object_unref(G_OBJECT(entry)); + g_object_unref (entry); return userdata; } -wxClientData* wxListBox::DoGetItemClientObject( int n ) const +wxClientData* wxListBox::DoGetItemClientObject(unsigned int n) const { return (wxClientData*) wxListBox::DoGetItemClientData(n); } -void wxListBox::DoSetItemClientData( int n, void* clientData ) +void wxListBox::DoSetItemClientData(unsigned int n, void* clientData) { - wxCHECK_RET( n >= 0 && n < wxListBox::GetCount(), + wxCHECK_RET( IsValid(n), wxT("Invalid index passed to SetItemClientData") ); GtkTreeEntry* entry = GtkGetEntry(n); wxCHECK_RET(entry, wxT("could not get entry")); gtk_tree_entry_set_userdata( entry, clientData ); - g_object_unref(G_OBJECT(entry)); + g_object_unref (entry); } -void wxListBox::DoSetItemClientObject( int n, wxClientData* clientData ) +void wxListBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) { // wxItemContainer already deletes data for us wxListBox::DoSetItemClientData(n, (void*) clientData); @@ -787,8 +796,9 @@ void wxListBox::DoSetItemClientObject( int n, wxClientData* clientData ) // string list access // ---------------------------------------------------------------------------- -void wxListBox::SetString( int n, const wxString &string ) +void wxListBox::SetString(unsigned int n, const wxString &string) { + wxCHECK_RET( IsValid(n), wxT("invalid index in wxListBox::SetString") ); wxCHECK_RET( m_treeview != NULL, wxT("invalid listbox") ); GtkTreeEntry* entry = GtkGetEntry(n); @@ -797,8 +807,8 @@ void wxListBox::SetString( int n, const wxString &string ) wxString label = string; #if wxUSE_CHECKLISTBOX && !wxUSE_NATIVEGTKCHECKLIST - if (m_hasCheckBoxes) - label.Prepend(wxCHECKLBOX_STRING); + if (m_hasCheckBoxes) + label.Prepend(wxCHECKLBOX_STRING); #endif // wxUSE_CHECKLISTBOX // RN: This may look wierd but the problem is that the TreeView @@ -806,7 +816,7 @@ void wxListBox::SetString( int n, const wxString &string ) // notification function... void* userdata = gtk_tree_entry_get_userdata(entry); gtk_tree_entry_set_userdata(entry, NULL); //don't delete on destroy - g_object_unref(G_OBJECT(entry)); + g_object_unref (entry); bool bWasSelected = wxListBox::IsSelected(n); wxListBox::Delete(n); @@ -818,7 +828,7 @@ void wxListBox::SetString( int n, const wxString &string ) wxListBox::GtkSetSelection(n, true, true); } -wxString wxListBox::GetString( int n ) const +wxString wxListBox::GetString(unsigned int n) const { wxCHECK_MSG( m_treeview != NULL, wxEmptyString, wxT("invalid listbox") ); @@ -835,15 +845,15 @@ wxString wxListBox::GetString( int n ) const label.erase(0, 4); #endif // wxUSE_CHECKLISTBOX - g_object_unref(G_OBJECT(entry)); + g_object_unref (entry); return label; } -int wxListBox::GetCount() const +unsigned int wxListBox::GetCount() const { - wxCHECK_MSG( m_treeview != NULL, -1, wxT("invalid listbox") ); + wxCHECK_MSG( m_treeview != NULL, 0, wxT("invalid listbox") ); - return gtk_tree_model_iter_n_children(GTK_TREE_MODEL(m_liststore), NULL); + return (unsigned int)gtk_tree_model_iter_n_children(GTK_TREE_MODEL(m_liststore), NULL); } int wxListBox::FindString( const wxString &item, bool bCase ) const @@ -851,12 +861,12 @@ int wxListBox::FindString( const wxString &item, bool bCase ) const wxCHECK_MSG( m_treeview != NULL, wxNOT_FOUND, wxT("invalid listbox") ); //Sort of hackish - maybe there is a faster way - int nCount = wxListBox::GetCount(); + unsigned int nCount = wxListBox::GetCount(); - for(int i = 0; i < nCount; ++i) + for(unsigned int i = 0; i < nCount; ++i) { if( item.IsSameAs( wxListBox::GetString(i), bCase ) ) - return i; + return (int)i; } @@ -870,8 +880,8 @@ int wxListBox::FindString( const wxString &item, bool bCase ) const int wxListBox::GetSelection() const { - wxCHECK_MSG( m_treeview != NULL, -1, wxT("invalid listbox")); - wxCHECK_MSG( HasFlag(wxLB_SINGLE), -1, + wxCHECK_MSG( m_treeview != NULL, wxNOT_FOUND, wxT("invalid listbox")); + wxCHECK_MSG( HasFlag(wxLB_SINGLE), wxNOT_FOUND, wxT("must be single selection listbox")); GtkTreeIter iter; @@ -879,7 +889,7 @@ int wxListBox::GetSelection() const // only works on single-sel if (!gtk_tree_selection_get_selected(selection, NULL, &iter)) - return -1; + return wxNOT_FOUND; GtkTreePath* path = gtk_tree_model_get_path(GTK_TREE_MODEL(m_liststore), &iter); @@ -893,7 +903,7 @@ int wxListBox::GetSelection() const int wxListBox::GetSelections( wxArrayInt& aSelections ) const { - wxCHECK_MSG( m_treeview != NULL, -1, wxT("invalid listbox") ); + wxCHECK_MSG( m_treeview != NULL, wxNOT_FOUND, wxT("invalid listbox") ); aSelections.Empty(); @@ -934,7 +944,30 @@ bool wxListBox::IsSelected( int n ) const void wxListBox::DoSetSelection( int n, bool select ) { - return GtkSetSelection(n, select, true); //docs say no events here + // passing -1 to SetSelection() is documented to deselect all items + if ( n == wxNOT_FOUND ) + { + // ... and not generate any events in the process + GtkDeselectAll(); + } + + wxCHECK_RET( IsValid(n), wxT("invalid index in wxListBox::SetSelection") ); + + // don't generate the selection event + GtkSetSelection(n, select, true); +} + +void wxListBox::GtkDeselectAll() +{ + wxCHECK_RET( m_treeview != NULL, wxT("invalid listbox") ); + + GtkTreeSelection* selection = gtk_tree_view_get_selection(m_treeview); + + m_blockEvent = true; + + gtk_tree_selection_unselect_all(selection); + + m_blockEvent = false; } void wxListBox::GtkSetSelection(int n, const bool select, const bool blockEvent) @@ -964,7 +997,7 @@ void wxListBox::GtkSetSelection(int n, const bool select, const bool blockEvent) void wxListBox::DoSetFirstItem( int n ) { wxCHECK_RET( m_treeview, wxT("invalid listbox") ); - wxCHECK_RET( n >= 0 && n < wxListBox::GetCount(), wxT("invalid index")); + wxCHECK_RET( IsValid(n), wxT("invalid index")); //RN: I have no idea why this line is needed... if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (m_treeview)) @@ -994,6 +1027,11 @@ void wxListBox::DoSetFirstItem( int n ) int wxListBox::DoListHitTest(const wxPoint& point) const { + // gtk_tree_view_get_path_at_pos() also gets items that are not visible and + // we only want visible items we need to check for it manually here + if ( !GetClientRect().Inside(point) ) + return wxNOT_FOUND; + // need to translate from master window since it is in client coords gint binx, biny; gdk_window_get_geometry(gtk_tree_view_get_bin_window(m_treeview), @@ -1051,7 +1089,7 @@ void wxListBox::DoApplyWidgetStyle(GtkRcStyle *style) GdkWindow *window = gtk_tree_view_get_bin_window(m_treeview); if (window) { - m_backgroundColour.CalcPixel( gdk_window_get_colormap( window ) ); + m_backgroundColour.CalcPixel( gdk_drawable_get_colormap( window ) ); gdk_window_set_background( window, m_backgroundColour.GetColor() ); gdk_window_clear( window ); } @@ -1092,13 +1130,13 @@ wxSize wxListBox::DoGetBestSize() const // Get the visible area of the tree view (limit to the 10th item // so that it isn't too big) - int count = GetCount(); + unsigned int count = GetCount(); if (count) { int wLine; // Find the widest line - for(int i = 0; i < count; i++) { + for(unsigned int i = 0; i < count; i++) { wxString str(GetString(i)); GetTextExtent(str, &wLine, NULL); lbWidth = wxMax(lbWidth, wLine); @@ -1116,8 +1154,8 @@ wxSize wxListBox::DoGetBestSize() const } #endif - // don't make the listbox too tall (limit height to around 10 items) but don't - // make it too small neither + // don't make the listbox too tall (limit height to around 10 items) but don't + // make it too small neither lbHeight = (cy+4) * wxMin(wxMax(count, 3), 10); }