X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/41936464fd460f5f66db75c82672af9870e47e5f..99d6720118134b3717fc314ac164eb5b30352785:/src/gtk/dataview.cpp diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp index e27c908000..51713e1c48 100644 --- a/src/gtk/dataview.cpp +++ b/src/gtk/dataview.cpp @@ -34,6 +34,7 @@ #include "wx/gtk/dcclient.h" #include "wx/gtk/private/gdkconv.h" +#include "wx/gtk/private/list.h" using namespace wxGTKImpl; class wxGtkDataViewModelNotifier; @@ -98,6 +99,26 @@ private: wxDECLARE_NO_COPY_CLASS(wxGtkTreePath); }; +// ---------------------------------------------------------------------------- +// wxGtkTreePathList: self-destroying list of GtkTreePath objects. +// ---------------------------------------------------------------------------- + +class wxGtkTreePathList : public wxGtkList +{ +public: + // Ctor takes ownership of the list. + explicit wxGtkTreePathList(GList* list) + : wxGtkList(list) + { + } + + ~wxGtkTreePathList() + { + // Delete the list contents, wxGtkList will delete the list itself. + g_list_foreach(m_list, (GFunc)gtk_tree_path_free, NULL); + } +}; + // ---------------------------------------------------------------------------- // wxGtkTreeSelectionLock: prevent selection from changing during the // lifetime of this object @@ -300,7 +321,7 @@ private: static int LINKAGEMODE wxGtkTreeModelChildCmp( void** id1, void** id2 ) { - int ret = gs_internal->GetDataViewModel()->Compare( *id1, *id2, + int ret = gs_internal->GetDataViewModel()->Compare( wxDataViewItem(*id1), wxDataViewItem(*id2), gs_internal->GetSortColumn(), (gs_internal->GetSortOrder() == GTK_SORT_ASCENDING) ); return ret; @@ -1567,12 +1588,14 @@ bool wxGtkDataViewModelNotifier::ItemDeleted( const wxDataViewItem &parent, cons GTK_TREE_MODEL(wxgtk_model), &iter )); #else // so get the path from the parent - GtkTreeIter iter; - iter.stamp = wxgtk_model->stamp; - iter.user_data = (gpointer) parent.GetID(); - wxGtkTreePath path(wxgtk_tree_model_get_path( - GTK_TREE_MODEL(wxgtk_model), &iter )); + GtkTreeIter parentIter; + parentIter.stamp = wxgtk_model->stamp; + parentIter.user_data = (gpointer) parent.GetID(); + wxGtkTreePath parentPath(wxgtk_tree_model_get_path( + GTK_TREE_MODEL(wxgtk_model), &parentIter )); + // and add the final index ourselves + wxGtkTreePath path(gtk_tree_path_copy(parentPath)); int index = m_internal->GetIndexOf( parent, item ); gtk_tree_path_append_index( path, index ); #endif @@ -1582,6 +1605,17 @@ bool wxGtkDataViewModelNotifier::ItemDeleted( const wxDataViewItem &parent, cons m_internal->ItemDeleted( parent, item ); + // Did we remove the last child, causing 'parent' to become a leaf? + if ( !m_wx_model->IsContainer(parent) ) + { + gtk_tree_model_row_has_child_toggled + ( + GTK_TREE_MODEL(wxgtk_model), + parentPath, + &parentIter + ); + } + return true; } @@ -1623,23 +1657,28 @@ bool wxGtkDataViewModelNotifier::ValueChanged( const wxDataViewItem &item, unsig GtkTreeView *widget = GTK_TREE_VIEW(ctrl->GtkGetTreeView()); GtkTreeViewColumn *gcolumn = GTK_TREE_VIEW_COLUMN(column->GetGtkHandle()); - // Get cell area - GtkTreeIter iter; - iter.stamp = wxgtk_model->stamp; - iter.user_data = (gpointer) item.GetID(); - wxGtkTreePath path(wxgtk_tree_model_get_path( - GTK_TREE_MODEL(wxgtk_model), &iter )); - GdkRectangle cell_area; - gtk_tree_view_get_cell_area( widget, path, gcolumn, &cell_area ); - - GtkAdjustment* hadjust = gtk_tree_view_get_hadjustment( widget ); - double d = gtk_adjustment_get_value( hadjust ); - int xdiff = (int) d; - - int ydiff = gcolumn->button->allocation.height; - // Redraw - gtk_widget_queue_draw_area( GTK_WIDGET(widget), - cell_area.x - xdiff, ydiff + cell_area.y, cell_area.width, cell_area.height ); + // Don't attempt to refresh not yet realized tree, it is useless + // and results in GTK errors. + if ( gtk_widget_get_realized(ctrl->GtkGetTreeView()) ) + { + // Get cell area + GtkTreeIter iter; + iter.stamp = wxgtk_model->stamp; + iter.user_data = (gpointer) item.GetID(); + wxGtkTreePath path(wxgtk_tree_model_get_path( + GTK_TREE_MODEL(wxgtk_model), &iter )); + GdkRectangle cell_area; + gtk_tree_view_get_cell_area( widget, path, gcolumn, &cell_area ); + + GtkAdjustment* hadjust = gtk_tree_view_get_hadjustment( widget ); + double d = gtk_adjustment_get_value( hadjust ); + int xdiff = (int) d; + + int ydiff = gcolumn->button->allocation.height; + // Redraw + gtk_widget_queue_draw_area( GTK_WIDGET(widget), + cell_area.x - xdiff, ydiff + cell_area.y, cell_area.width, cell_area.height ); + } m_internal->ValueChanged( item, model_column ); @@ -3334,7 +3373,7 @@ int wxGtkTreeModelChildWithPosCmp( const void* data1, const void* data2, const v static int LINKAGEMODE wxGtkTreeModelChildPtrCmp( void*** data1, void*** data2 ) { - return gs_internal->GetDataViewModel()->Compare( **data1, **data2, + return gs_internal->GetDataViewModel()->Compare( wxDataViewItem(**data1), wxDataViewItem(**data2), gs_internal->GetSortColumn(), (gs_internal->GetSortOrder() == GTK_SORT_ASCENDING) ); } @@ -4811,13 +4850,9 @@ int wxDataViewCtrl::GetColumnPosition( const wxDataViewColumn *column ) const { GtkTreeViewColumn *gtk_column = GTK_TREE_VIEW_COLUMN(column->GetGtkHandle()); - GList *list = gtk_tree_view_get_columns( GTK_TREE_VIEW(m_treeview) ); - - gint pos = g_list_index( list, (gconstpointer) gtk_column ); - - g_list_free( list ); + wxGtkList list(gtk_tree_view_get_columns(GTK_TREE_VIEW(m_treeview))); - return pos; + return g_list_index( list, (gconstpointer) gtk_column ); } wxDataViewColumn *wxDataViewCtrl::GetSortingColumn() const @@ -4913,39 +4948,11 @@ void wxDataViewCtrl::StartEditor(const wxDataViewItem& item, unsigned int column gtk_tree_view_set_cursor(GTK_TREE_VIEW(m_treeview), path, gcolumn, TRUE); } -wxDataViewItem wxDataViewCtrl::GetSelection() const +int wxDataViewCtrl::GetSelectedItemsCount() const { GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview) ); - if (m_windowStyle & wxDV_MULTIPLE) - { - // Report the first one - GtkTreeModel *model; - GList *list = gtk_tree_selection_get_selected_rows( selection, &model ); - - if (list) - { - GtkTreePath *path = (GtkTreePath*) list->data; - wxDataViewItem item(GTKPathToItem(path)); - - // delete list - g_list_foreach( list, (GFunc) gtk_tree_path_free, NULL ); - g_list_free( list ); - - return item; - } - } - else - { - GtkTreeIter iter; - if (gtk_tree_selection_get_selected( selection, NULL, &iter )) - { - wxDataViewItem item( iter.user_data ); - return item; - } - } - - return wxDataViewItem(0); + return gtk_tree_selection_count_selected_rows(selection); } int wxDataViewCtrl::GetSelections( wxDataViewItemArray & sel ) const @@ -4956,38 +4963,25 @@ int wxDataViewCtrl::GetSelections( wxDataViewItemArray & sel ) const if (HasFlag(wxDV_MULTIPLE)) { GtkTreeModel *model; - GList *list = gtk_tree_selection_get_selected_rows( selection, &model ); + wxGtkTreePathList list(gtk_tree_selection_get_selected_rows(selection, &model)); - int count = 0; - while (list) + for ( GList* current = list; current; current = g_list_next(current) ) { - GtkTreePath *path = (GtkTreePath*) list->data; + GtkTreePath *path = (GtkTreePath*) current->data; sel.Add(GTKPathToItem(path)); - - list = g_list_next( list ); - count++; } - - // delete list - g_list_foreach( list, (GFunc) gtk_tree_path_free, NULL ); - g_list_free( list ); - - return count; } else { - GtkTreeModel *model; GtkTreeIter iter; - gboolean has_selection = gtk_tree_selection_get_selected( selection, &model, &iter ); - if (has_selection) + if (gtk_tree_selection_get_selected( selection, NULL, &iter )) { - sel.Add( wxDataViewItem( (void*) iter.user_data) ); - return 1; + sel.Add( wxDataViewItem(iter.user_data) ); } } - return 0; + return sel.size(); } void wxDataViewCtrl::SetSelections( const wxDataViewItemArray & sel )