X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/55fbde1232bff0ed44c23775911574ac1b2f8a0a..a8780ad5bbd52c859eaeba01c2f739cbb15c1576:/src/gtk/dataview.cpp?ds=inline diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp index 7bab43fa23..c16bb6cc67 100644 --- a/src/gtk/dataview.cpp +++ b/src/gtk/dataview.cpp @@ -47,57 +47,67 @@ //----------------------------------------------------------------------------- class wxGtkTreeModelNode; -WX_DEFINE_ARRAY_PTR( wxGtkTreeModelNode*, wxGtkTreeModelNodes ); + +extern "C" { +typedef struct _GtkWxTreeModel GtkWxTreeModel; +} + +int LINKAGEMODE wxGtkTreeModelNodeCmp( wxGtkTreeModelNode* node1, wxGtkTreeModelNode* node2 ); + +WX_DEFINE_SORTED_ARRAY( wxGtkTreeModelNode*, wxGtkTreeModelNodes ); class wxGtkTreeModelNode { public: - wxGtkTreeModelNode( wxGtkTreeModelNode* parent, const wxDataViewItem &item ) + wxGtkTreeModelNode( wxGtkTreeModelNode* parent, const wxDataViewItem &item, + wxDataViewCtrlInternal *internal ) { m_parent = parent; m_item = item; + m_internal = internal; + m_children = new wxGtkTreeModelNodes( wxGtkTreeModelNodeCmp ); } ~wxGtkTreeModelNode() { - size_t count = m_children.GetCount(); + size_t count = m_children->GetCount(); size_t i; for (i = 0; i < count; i++) { - wxGtkTreeModelNode *child = m_children[i]; + wxGtkTreeModelNode *child = m_children->Item( i ); delete child; } + delete m_children; } wxGtkTreeModelNode* GetParent() { return m_parent; } wxGtkTreeModelNodes &GetChildren() - { return m_children; } + { return *m_children; } wxGtkTreeModelNode* GetNthChild( unsigned int n ) - { return m_children.Item( n ); } - void Insert( wxGtkTreeModelNode* child, unsigned int n) - { m_children.Insert( child, n); } - void Append( wxGtkTreeModelNode* child ) - { m_children.Add( child ); } - - unsigned int GetChildCount() { return m_children.GetCount(); } + { return m_children->Item( n ); } + unsigned int Add( wxGtkTreeModelNode* child ) + { return m_children->Add( child ); } + + unsigned int GetChildCount() { return m_children->GetCount(); } wxDataViewItem &GetItem() { return m_item; } + wxDataViewCtrlInternal *GetInternal() { return m_internal; } bool HasChildren() { return m_hasChildren; } void SetHasChildren( bool has ) { m_hasChildren = has; } + void Resort(); + private: - wxGtkTreeModelNode *m_parent; - wxGtkTreeModelNodes m_children; - wxDataViewItem m_item; - bool m_hasChildren; + wxGtkTreeModelNode *m_parent; + wxGtkTreeModelNodes *m_children; + wxDataViewItem m_item; + bool m_hasChildren; + wxDataViewCtrlInternal *m_internal; }; -extern "C" { -typedef struct _GtkWxTreeModel GtkWxTreeModel; -} class wxDataViewCtrlInternal { @@ -107,6 +117,7 @@ public: gboolean get_iter( GtkTreeIter *iter, GtkTreePath *path ); GtkTreePath *get_path( GtkTreeIter *iter); + GtkTreePath *get_path_safe( GtkTreeIter *iter); gboolean iter_next( GtkTreeIter *iter ); gboolean iter_children( GtkTreeIter *iter, GtkTreeIter *parent); gboolean iter_has_child( GtkTreeIter *iter ); @@ -115,11 +126,14 @@ public: gboolean iter_parent( GtkTreeIter *iter, GtkTreeIter *child ); wxDataViewModel* GetDataViewModel() { return m_wx_model; } - GtkWxTreeModel* GetOwner() { return m_gtk_model; } + wxDataViewCtrl* GetOwner() { return m_owner; } + GtkWxTreeModel* GetGtkModel() { return m_gtk_model; } bool ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item ); bool ItemDeleted( const wxDataViewItem &item ); + void Resort(); + protected: void InitTree(); wxGtkTreeModelNode *FindNode( const wxDataViewItem &item ); @@ -133,6 +147,12 @@ private: wxDataViewCtrl *m_owner; }; + +int LINKAGEMODE wxGtkTreeModelNodeCmp( wxGtkTreeModelNode* node1, wxGtkTreeModelNode* node2 ) +{ + return node1->GetInternal()->GetDataViewModel()->Compare( node1->GetItem(), node2->GetItem() ); +} + //----------------------------------------------------------------------------- // data //----------------------------------------------------------------------------- @@ -163,9 +183,6 @@ struct _GtkWxTreeModel /*< private >*/ gint stamp; wxDataViewCtrlInternal *internal; - - gint sort_column_id; - GtkSortType order; }; struct _GtkWxTreeModelClass @@ -188,6 +205,8 @@ static gboolean wxgtk_tree_model_get_iter (GtkTreeModel *tree_mo GtkTreePath *path); static GtkTreePath *wxgtk_tree_model_get_path (GtkTreeModel *tree_model, GtkTreeIter *iter); +static GtkTreePath *wxgtk_tree_model_get_path_safe (GtkTreeModel *tree_model, + GtkTreeIter *iter); static void wxgtk_tree_model_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter, gint column, @@ -326,8 +345,6 @@ wxgtk_tree_model_init (GtkWxTreeModel *tree_model) { tree_model->internal = NULL; tree_model->stamp = g_random_int(); - tree_model->sort_column_id = -2; - tree_model->order = GTK_SORT_ASCENDING; } static void @@ -405,6 +422,17 @@ wxgtk_tree_model_get_path (GtkTreeModel *tree_model, return wxtree_model->internal->get_path( iter ); } +static GtkTreePath * +wxgtk_tree_model_get_path_safe (GtkTreeModel *tree_model, + GtkTreeIter *iter) +{ + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), NULL); + g_return_val_if_fail (iter->stamp == GTK_WX_TREE_MODEL (wxtree_model)->stamp, NULL); + + return wxtree_model->internal->get_path_safe( iter ); +} + static void wxgtk_tree_model_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter, @@ -509,14 +537,17 @@ gboolean wxgtk_tree_model_get_sort_column_id (GtkTreeSortable *sortabl g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (sortable), FALSE); - if (tree_model->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID) - return FALSE; - if (sort_column_id) - *sort_column_id = tree_model->sort_column_id; + *sort_column_id = tree_model->internal->GetDataViewModel()->GetSortingColumn(); if (order) - *order = tree_model->order; + { + bool ascending = tree_model->internal->GetDataViewModel()->GetSortOrderAscending(); + if (ascending) + *order = GTK_SORT_ASCENDING; + else + *order = GTK_SORT_DESCENDING; + } return TRUE; } @@ -526,20 +557,23 @@ void wxgtk_tree_model_set_sort_column_id (GtkTreeSortable *sortabl GtkSortType order) { GtkWxTreeModel *tree_model = (GtkWxTreeModel *) sortable; - g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable) ); - if ((tree_model->sort_column_id == sort_column_id) && - (tree_model->order == order)) - return; - - tree_model->sort_column_id = sort_column_id; - tree_model->order = order; + bool ascending = TRUE; + if (order != GTK_SORT_ASCENDING) + ascending = FALSE; + if ((sort_column_id == tree_model->internal->GetDataViewModel()->GetSortingColumn()) && + (ascending == tree_model->internal->GetDataViewModel()->GetSortOrderAscending())) + return; + + tree_model->internal->GetDataViewModel()->SetSortingColumn( sort_column_id ); + + tree_model->internal->GetDataViewModel()->SetSortOrderAscending( ascending ); + gtk_tree_sortable_sort_column_changed (sortable); - - wxPrintf( "wxgtk_tree_model_set_column_id, sort_column_id = %d, order = %d\n", sort_column_id, (int)order ); - // sort + + tree_model->internal->GetDataViewModel()->Resort(); } void wxgtk_tree_model_set_sort_func (GtkTreeSortable *sortable, @@ -550,9 +584,6 @@ void wxgtk_tree_model_set_sort_func (GtkTreeSortable *sortabl { g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable) ); g_return_if_fail (func != NULL); - - wxPrintf( "wxgtk_tree_model_set_sort_func, sort_column_id = %d\n", sort_column_id ); - // sort } void wxgtk_tree_model_set_default_sort_func (GtkTreeSortable *sortable, @@ -943,6 +974,7 @@ public: virtual bool ItemChanged( const wxDataViewItem &item ); virtual bool ValueChanged( const wxDataViewItem &item, unsigned int col ); virtual bool Cleared(); + virtual void Resort(); GtkWxTreeModel *m_wxgtk_model; wxDataViewModel *m_wx_model; @@ -991,7 +1023,7 @@ bool wxGtkDataViewModelNotifier::ItemDeleted( const wxDataViewItem &item ) iter.stamp = m_wxgtk_model->stamp; iter.user_data = (gpointer) item.GetID(); - GtkTreePath *path = wxgtk_tree_model_get_path( + GtkTreePath *path = wxgtk_tree_model_get_path_safe( GTK_TREE_MODEL(m_wxgtk_model), &iter ); gtk_tree_model_row_deleted( GTK_TREE_MODEL(m_wxgtk_model), path ); @@ -1002,6 +1034,11 @@ bool wxGtkDataViewModelNotifier::ItemDeleted( const wxDataViewItem &item ) return true; } +void wxGtkDataViewModelNotifier::Resort() +{ + m_owner->GtkGetInternal()->Resort(); +} + bool wxGtkDataViewModelNotifier::ItemChanged( const wxDataViewItem &item ) { GtkTreeIter iter; @@ -2047,6 +2084,73 @@ void wxDataViewColumn::SetWidth( int width ) } +//----------------------------------------------------------------------------- +// wxGtkTreeModelNode +//----------------------------------------------------------------------------- + +void wxGtkTreeModelNode::Resort() +{ + size_t count = m_children->GetCount(); + if (count == 0) + return; + + if (count == 1) + { + wxGtkTreeModelNode *node = m_children->Item( 0 ); + node->Resort(); + return; + } + + wxGtkTreeModelNodes *new_array = new wxGtkTreeModelNodes( wxGtkTreeModelNodeCmp ); + + size_t pos; + + for (pos = 0; pos < count; pos++) + new_array->Add( m_children->Item( pos ) ); + + + gint *new_order = new gint[count]; + + for (pos = 0; pos < count; pos++) + { + wxGtkTreeModelNode *node = new_array->Item( pos ); + size_t old_pos; + for (old_pos = 0; old_pos < count; old_pos++) + { + if (node == m_children->Item(old_pos)) + { + new_order[pos] = old_pos; + break; + } + } + } + +// for (pos = 0; pos < count; pos++) +// m_children->Clear(); + delete m_children; + + m_children = new_array; + + GtkTreeModel *gtk_tree_model = GTK_TREE_MODEL( m_internal->GetGtkModel() ); + + GtkTreeIter iter; + iter.user_data = (gpointer) GetItem().GetID(); + iter.stamp = m_internal->GetGtkModel()->stamp; + GtkTreePath *path = wxgtk_tree_model_get_path( gtk_tree_model, &iter ); + + gtk_tree_model_rows_reordered( gtk_tree_model, path, &iter, new_order ); + + gtk_tree_path_free (path); + + delete [] new_order; + + for (pos = 0; pos < count; pos++) + { + wxGtkTreeModelNode *node = m_children->Item( pos ); + node->Resort(); + } +} + //----------------------------------------------------------------------------- // wxDataViewCtrlInternal //----------------------------------------------------------------------------- @@ -2066,6 +2170,14 @@ wxDataViewCtrlInternal::~wxDataViewCtrlInternal() g_object_unref( m_gtk_model ); } +void wxDataViewCtrlInternal::InitTree() +{ + wxDataViewItem item; + m_root = new wxGtkTreeModelNode( NULL, item, this ); + + BuildBranch( m_root ); +} + void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode *node ) { if (node->GetChildCount() == 0) @@ -2073,17 +2185,21 @@ void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode *node ) wxDataViewItem child = m_wx_model->GetFirstChild( node->GetItem() ); while (child.IsOk()) { - // wxPrintf( "AddItem %d\n", (int) child.GetID() ); - node->Append( new wxGtkTreeModelNode( node, child ) ); + node->Add( new wxGtkTreeModelNode( node, child, this ) ); child = m_wx_model->GetNextSibling( child ); } } } +void wxDataViewCtrlInternal::Resort() +{ + m_root->Resort(); +} + bool wxDataViewCtrlInternal::ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item ) { wxGtkTreeModelNode *parent_node = FindNode( parent ); - parent_node->Append( new wxGtkTreeModelNode( parent_node, item ) ); + parent_node->Add( new wxGtkTreeModelNode( parent_node, item, this ) ); return true; } @@ -2091,8 +2207,15 @@ bool wxDataViewCtrlInternal::ItemDeleted( const wxDataViewItem &item ) { wxGtkTreeModelNode *node = FindNode( item ); wxGtkTreeModelNode *parent = node->GetParent(); - parent->GetChildren().Remove( node ); - delete node; + size_t pos; + for (pos = 0; pos < parent->GetChildren().GetCount(); pos++) + { + if (node == parent->GetChildren().Item( pos )) + { + parent->GetChildren().RemoveAt( pos ); + continue; + } + } return true; } @@ -2139,14 +2262,43 @@ GtkTreePath *wxDataViewCtrlInternal::get_path( GtkTreeIter *iter ) return retval; } +GtkTreePath *wxDataViewCtrlInternal::get_path_safe( GtkTreeIter *iter ) +{ + GtkTreePath *retval = gtk_tree_path_new (); + + wxGtkTreeModelNode *node = FindNode( iter ); + while (node->GetParent()) + { + wxGtkTreeModelNode *parent = node->GetParent(); + size_t pos; + for (pos = 0; pos < parent->GetChildren().GetCount(); pos++) + { + if (node == parent->GetChildren().Item( pos )) + { + gtk_tree_path_prepend_index( retval, (int) pos ); + continue; + } + } + + node = parent; + } + + return retval; +} + gboolean wxDataViewCtrlInternal::iter_next( GtkTreeIter *iter ) { - wxDataViewItem item( (void*) iter->user_data ); - item = m_wx_model->GetNextSibling( item ); - if (!item.IsOk()) + wxGtkTreeModelNode *node = FindNode( iter ); + wxGtkTreeModelNode *parent = node->GetParent(); + unsigned int pos = parent->GetChildren().Index( node ); + + if (pos == parent->GetChildren().GetCount()-1) return FALSE; - - iter->user_data = (gpointer) item.GetID(); + + node = parent->GetChildren().Item( pos+1 ); + + iter->stamp = m_gtk_model->stamp; + iter->user_data = (gpointer) node->GetItem().GetID(); return TRUE; } @@ -2185,6 +2337,8 @@ gint wxDataViewCtrlInternal::iter_n_children( GtkTreeIter *iter ) wxGtkTreeModelNode *parent_node = FindNode( iter ); BuildBranch( parent_node ); + + // wxPrintf( "iter_n_children %d\n", parent_node->GetChildCount() ); return parent_node->GetChildCount(); } @@ -2204,6 +2358,8 @@ gboolean wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter *iter, GtkTreeIter wxGtkTreeModelNode *child_node = parent_node->GetChildren().Item( (size_t) n ); if (!child_node) return FALSE; + + // wxPrintf( "iter_nth_child %d\n", n ); iter->stamp = m_gtk_model->stamp; iter->user_data = (gpointer) child_node->GetItem().GetID(); @@ -2226,14 +2382,6 @@ gboolean wxDataViewCtrlInternal::iter_parent( GtkTreeIter *iter, GtkTreeIter *ch return TRUE; } -void wxDataViewCtrlInternal::InitTree() -{ - wxDataViewItem item; - m_root = new wxGtkTreeModelNode( NULL, item ); - - BuildBranch( m_root ); -} - static wxGtkTreeModelNode* wxDataViewCtrlInternal_FindNode( wxGtkTreeModelNode *node, const wxDataViewItem &item ) { @@ -2245,11 +2393,17 @@ wxDataViewCtrlInternal_FindNode( wxGtkTreeModelNode *node, const wxDataViewItem { wxGtkTreeModelNode *child = node->GetChildren().Item( i ); if (child->GetItem().GetID() == item.GetID()) + { + // wxPrintf( "leave findnode at %d\n", i ); return child; + } wxGtkTreeModelNode *node2 = wxDataViewCtrlInternal_FindNode( child, item ); if (node2) + { + // wxPrintf( "branch findnode at %d\n", i ); return node2; + } } return NULL; @@ -2261,6 +2415,8 @@ wxGtkTreeModelNode *wxDataViewCtrlInternal::FindNode( GtkTreeIter *iter ) return m_root; wxDataViewItem item( (void*) iter->user_data ); + if (!item.IsOk()) + return m_root; wxGtkTreeModelNode *result = wxDataViewCtrlInternal_FindNode( m_root, item ); @@ -2276,6 +2432,9 @@ wxGtkTreeModelNode *wxDataViewCtrlInternal::FindNode( GtkTreeIter *iter ) wxGtkTreeModelNode *wxDataViewCtrlInternal::FindNode( const wxDataViewItem &item ) { + if (!item.IsOk()) + return m_root; + wxGtkTreeModelNode *result = wxDataViewCtrlInternal_FindNode( m_root, item ); if (!result)