X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/fa93d732e2afd376527d9c0eb726057f15f18868..b39badac119fe944152cd1408a90b82e710ea598:/src/gtk/dataview.cpp diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp index a1b7a3ccbb..fcbe97e09e 100644 --- a/src/gtk/dataview.cpp +++ b/src/gtk/dataview.cpp @@ -352,7 +352,7 @@ public: } } - unsigned int AddNode( wxGtkTreeModelNode* child ) + void AddNode( wxGtkTreeModelNode* child ) { m_nodes.Add( child ); @@ -364,24 +364,54 @@ public: { gs_internal = m_internal; m_children.Sort( &wxGtkTreeModelChildCmp ); - return m_children.Index( id ); + } + } + + void InsertNode( wxGtkTreeModelNode* child, unsigned pos ) + { + if (m_internal->IsSorted() || m_internal->GetDataViewModel()->HasDefaultCompare()) + { + AddNode(child); + return; } - return m_children.GetCount()-1; + void *id = child->GetItem().GetID(); + + // Insert into m_nodes so that the order of nodes in m_nodes is the + // same as the order of their corresponding IDs in m_children: + const unsigned int count = m_nodes.GetCount(); + bool inserted = false; + for (unsigned i = 0; i < count; i++) + { + wxGtkTreeModelNode *node = m_nodes[i]; + int posInChildren = m_children.Index(node->GetItem().GetID()); + if ( (unsigned)posInChildren >= pos ) + { + m_nodes.Insert(child, i); + inserted = true; + break; + } + } + if ( !inserted ) + m_nodes.Add(child); + + m_children.Insert( id, pos ); } - unsigned int AddLeave( void* id ) + void AddLeaf( void* id ) { - m_children.Add( id ); + InsertLeaf(id, m_children.size()); + } + + void InsertLeaf( void* id, unsigned pos ) + { + m_children.Insert( id, pos ); if (m_internal->IsSorted() || m_internal->GetDataViewModel()->HasDefaultCompare()) { gs_internal = m_internal; m_children.Sort( &wxGtkTreeModelChildCmp ); - return m_children.Index( id ); } - - return m_children.GetCount()-1; } void DeleteChild( void* id ) @@ -1588,12 +1618,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 @@ -1603,6 +1635,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; } @@ -1644,23 +1687,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 ); @@ -1957,7 +2005,7 @@ wxEllipsizeMode wxDataViewRenderer::GetEllipsizeMode() const } void -wxDataViewRenderer::GtkOnTextEdited(const gchar *itempath, const wxString& str) +wxDataViewRenderer::GtkOnTextEdited(const char *itempath, const wxString& str) { wxVariant value(str); if (!Validate( value )) @@ -2720,7 +2768,7 @@ wxDataViewChoiceByIndexRenderer::wxDataViewChoiceByIndexRenderer( const wxArrayS { } -void wxDataViewChoiceByIndexRenderer::GtkOnTextEdited(const gchar *itempath, const wxString& str) +void wxDataViewChoiceByIndexRenderer::GtkOnTextEdited(const char *itempath, const wxString& str) { wxVariant value( (long) GetChoices().Index( str ) ); @@ -3238,14 +3286,6 @@ bool wxDataViewColumn::IsSortable() const return gtk_tree_view_column_get_clickable( column ); } -void wxDataViewColumn::SetAsSortKey( bool WXUNUSED(sort) ) -{ - // it might not make sense to have this function in wxHeaderColumn at - // all in fact, changing of the sort order should only be done using the - // associated control API - wxFAIL_MSG( "not implemented" ); -} - bool wxDataViewColumn::IsSortKey() const { GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN(m_column); @@ -3556,7 +3596,7 @@ void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode *node ) if (m_wx_model->IsContainer( child )) node->AddNode( new wxGtkTreeModelNode( node, child, this ) ); else - node->AddLeave( child.GetID() ); + node->AddLeaf( child.GetID() ); // Don't send any events here } @@ -3743,13 +3783,18 @@ bool wxDataViewCtrlInternal::ItemAdded( const wxDataViewItem &parent, const wxDa if (!m_wx_model->IsVirtualListModel()) { wxGtkTreeModelNode *parent_node = FindNode( parent ); - wxASSERT_MSG(parent_node, + wxCHECK_MSG(parent_node, false, "Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel"); + wxDataViewItemArray siblings; + m_wx_model->GetChildren(parent, siblings); + int itemPos = siblings.Index(item, /*fromEnd=*/true); + wxCHECK_MSG( itemPos != wxNOT_FOUND, false, "adding non-existent item?" ); + if (m_wx_model->IsContainer( item )) - parent_node->AddNode( new wxGtkTreeModelNode( parent_node, item, this ) ); + parent_node->InsertNode( new wxGtkTreeModelNode( parent_node, item, this ), itemPos ); else - parent_node->AddLeave( item.GetID() ); + parent_node->InsertLeaf( item.GetID(), itemPos ); } ScheduleRefresh(); @@ -4491,22 +4536,21 @@ gtk_dataview_button_press_callback( GtkWidget *WXUNUSED(widget), GtkTreeViewColumn *column = NULL; gint cell_x = 0; gint cell_y = 0; - if (gtk_tree_view_get_path_at_pos( + gtk_tree_view_get_path_at_pos + ( GTK_TREE_VIEW(dv->GtkGetTreeView()), (int) gdk_event->x, (int) gdk_event->y, path.ByRef(), &column, &cell_x, - &cell_y)) - { - if (path) - { - wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, dv->GetId() ); - event.SetItem(dv->GTKPathToItem(path)); - event.SetModel( dv->GetModel() ); - return dv->HandleWindowEvent( event ); - } - } + &cell_y + ); + + wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, dv->GetId() ); + if (path) + event.SetItem(dv->GTKPathToItem(path)); + event.SetModel( dv->GetModel() ); + return dv->HandleWindowEvent( event ); } return FALSE;