X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d8331a013b9cd0109a3a6d3c4e7b60b0b524eb06..628f87da565360ec2fce102c9b46341cf42cd3d3:/src/gtk/dataview.cpp diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp index 926d1e4645..c74207cd42 100644 --- a/src/gtk/dataview.cpp +++ b/src/gtk/dataview.cpp @@ -26,6 +26,8 @@ #include "wx/calctrl.h" #include "wx/popupwin.h" #include "wx/icon.h" +#include "wx/list.h" +#include "wx/listimpl.cpp" #include "wx/gtk/private.h" @@ -41,7 +43,9 @@ //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -wxDataViewModel *g_model = NULL; +class wxDataViewCtrlInternal; + +wxDataViewCtrlInternal *g_internal = NULL; class wxGtkTreeModelNode; @@ -53,6 +57,9 @@ typedef struct _GtkWxTreeModel GtkWxTreeModel; // wxDataViewCtrlInternal //----------------------------------------------------------------------------- +WX_DECLARE_LIST(wxDataViewItem, ItemList); +WX_DEFINE_LIST(ItemList); + class wxDataViewCtrlInternal { public: @@ -74,12 +81,18 @@ public: GtkWxTreeModel* GetGtkModel() { return m_gtk_model; } bool ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item ); - bool ItemDeleted( const wxDataViewItem &item ); + bool ItemDeleted( const wxDataViewItem &parent, const wxDataViewItem &item ); bool ItemChanged( const wxDataViewItem &item ); bool ValueChanged( const wxDataViewItem &item, unsigned int col ); bool Cleared(); void Resort(); + void SetSortOrder( GtkSortType sort_order ) { m_sort_order = sort_order; } + GtkSortType GetSortOrder() { return m_sort_order; } + + void SetSortColumn( unsigned int column ) { m_sort_column = column; } + unsigned int GetSortColumn() { return m_sort_column; } + protected: void InitTree(); wxGtkTreeModelNode *FindNode( const wxDataViewItem &item ); @@ -93,6 +106,8 @@ private: wxDataViewModel *m_wx_model; GtkWxTreeModel *m_gtk_model; wxDataViewCtrl *m_owner; + GtkSortType m_sort_order; + unsigned int m_sort_column; }; @@ -114,13 +129,13 @@ public: m_parent = parent; m_item = item; m_internal = internal; - g_model = internal->GetDataViewModel(); + g_internal = internal; m_children = new wxGtkTreeModelChildren( wxGtkTreeModelNodeCmp ); } ~wxGtkTreeModelNode() { - g_model = m_internal->GetDataViewModel(); + g_internal = m_internal; size_t count = m_children->GetCount(); size_t i; for (i = 0; i < count; i++) @@ -133,20 +148,20 @@ public: unsigned int AddNode( wxGtkTreeModelNode* child ) { - g_model = m_internal->GetDataViewModel(); + g_internal = m_internal; m_nodes.Add( child ); return m_children->Add( child->GetItem().GetID() ); } unsigned int AddLeave( void* id ) { - g_model = m_internal->GetDataViewModel(); + g_internal = m_internal; return m_children->Add( id ); } void DeleteChild( void* id ) { - g_model = m_internal->GetDataViewModel(); + g_internal = m_internal; size_t pos; size_t count = m_children->GetCount(); for (pos = 0; pos < count; pos++) @@ -197,7 +212,10 @@ private: int LINKAGEMODE wxGtkTreeModelNodeCmp( void* id1, void* id2 ) { - return g_model->Compare( id1, id2 ); + int ret = g_internal->GetDataViewModel()->Compare( id1, id2, + g_internal->GetSortColumn(), (g_internal->GetSortOrder() == GTK_SORT_ASCENDING) ); + + return ret; } //----------------------------------------------------------------------------- @@ -585,42 +603,38 @@ gboolean wxgtk_tree_model_get_sort_column_id (GtkTreeSortable *sortabl g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (sortable), FALSE); if (sort_column_id) - *sort_column_id = tree_model->internal->GetDataViewModel()->GetSortingColumn(); + *sort_column_id = tree_model->internal->GetSortColumn(); if (order) - { - bool ascending = tree_model->internal->GetDataViewModel()->GetSortOrderAscending(); - if (ascending) - *order = GTK_SORT_ASCENDING; - else - *order = GTK_SORT_DESCENDING; - } + *order = tree_model->internal->GetSortOrder(); return TRUE; } -void wxgtk_tree_model_set_sort_column_id (GtkTreeSortable *sortable, +void wxgtk_tree_model_set_sort_column_id (GtkTreeSortable *sortable, gint sort_column_id, GtkSortType order) { GtkWxTreeModel *tree_model = (GtkWxTreeModel *) sortable; g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable) ); - bool ascending = TRUE; - if (order != GTK_SORT_ASCENDING) - ascending = FALSE; - - if ((sort_column_id == (gint) tree_model->internal->GetDataViewModel()->GetSortingColumn()) && - (ascending == tree_model->internal->GetDataViewModel()->GetSortOrderAscending())) + if ((sort_column_id == (gint) tree_model->internal->GetSortColumn()) && + (order == tree_model->internal->GetSortOrder())) return; - tree_model->internal->GetDataViewModel()->SetSortingColumn( sort_column_id ); + tree_model->internal->SetSortColumn( sort_column_id ); - tree_model->internal->GetDataViewModel()->SetSortOrderAscending( ascending ); + tree_model->internal->SetSortOrder( order ); gtk_tree_sortable_sort_column_changed (sortable); tree_model->internal->GetDataViewModel()->Resort(); + + wxDataViewCtrl *dv = tree_model->internal->GetOwner(); + wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED, dv->GetId() ); + // TODO event.SetDataViewColumn( column ); + event.SetModel( dv->GetModel() ); + dv->GetEventHandler()->ProcessEvent( event ); } void wxgtk_tree_model_set_sort_func (GtkTreeSortable *sortable, @@ -1017,7 +1031,7 @@ public: ~wxGtkDataViewModelNotifier(); virtual bool ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item ); - virtual bool ItemDeleted( const wxDataViewItem &item ); + virtual bool ItemDeleted( const wxDataViewItem &parent, const wxDataViewItem &item ); virtual bool ItemChanged( const wxDataViewItem &item ); virtual bool ValueChanged( const wxDataViewItem &item, unsigned int col ); virtual bool Cleared(); @@ -1064,7 +1078,7 @@ bool wxGtkDataViewModelNotifier::ItemAdded( const wxDataViewItem &parent, const return true; } -bool wxGtkDataViewModelNotifier::ItemDeleted( const wxDataViewItem &item ) +bool wxGtkDataViewModelNotifier::ItemDeleted( const wxDataViewItem &parent, const wxDataViewItem &item ) { GtkTreeIter iter; iter.stamp = m_wxgtk_model->stamp; @@ -1076,7 +1090,7 @@ bool wxGtkDataViewModelNotifier::ItemDeleted( const wxDataViewItem &item ) GTK_TREE_MODEL(m_wxgtk_model), path ); gtk_tree_path_free (path); - m_owner->GtkGetInternal()->ItemDeleted( item ); + m_owner->GtkGetInternal()->ItemDeleted( parent, item ); return true; } @@ -1834,7 +1848,7 @@ gtk_dataview_header_button_press_callback( GtkWidget *widget, event.SetDataViewColumn( column ); event.SetModel( dv->GetModel() ); if (dv->GetEventHandler()->ProcessEvent( event )) - return TRUE; + return FALSE; } return FALSE; @@ -2147,7 +2161,7 @@ void wxDataViewColumn::SetWidth( int width ) void wxGtkTreeModelNode::Resort() { - g_model = m_internal->GetDataViewModel(); + g_internal = m_internal; size_t child_count = GetChildCount(); if (child_count == 0) @@ -2234,6 +2248,8 @@ wxDataViewCtrlInternal::wxDataViewCtrlInternal( wxDataViewCtrl *owner, m_wx_model = wx_model; m_gtk_model = gtk_model; m_root = NULL; + m_sort_order = GTK_SORT_ASCENDING; + m_sort_column = 0; InitTree(); } @@ -2252,10 +2268,6 @@ void wxDataViewCtrlInternal::InitTree() void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode *node ) { - wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_ADDED, m_owner->GetId() ); - event.SetEventObject( m_owner ); - event.SetModel( m_owner->GetModel() ); - if (node->GetChildCount() == 0) { wxDataViewItem child = m_wx_model->GetFirstChild( node->GetItem() ); @@ -2265,9 +2277,8 @@ void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode *node ) node->AddNode( new wxGtkTreeModelNode( node, child, this ) ); else node->AddLeave( child.GetID() ); - - event.SetItem( child ); - m_owner->GetEventHandler()->ProcessEvent( event ); + + // Don't send any events here child = m_wx_model->GetNextSibling( child ); } @@ -2296,10 +2307,10 @@ bool wxDataViewCtrlInternal::ItemAdded( const wxDataViewItem &parent, const wxDa return true; } -bool wxDataViewCtrlInternal::ItemDeleted( const wxDataViewItem &item ) +bool wxDataViewCtrlInternal::ItemDeleted( const wxDataViewItem &parent, const wxDataViewItem &item ) { - wxGtkTreeModelNode *parent = FindParentNode( item ); - parent->DeleteChild( item.GetID() ); + wxGtkTreeModelNode *parent_node = FindNode( parent ); + parent_node->DeleteChild( item.GetID() ); wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_DELETED, m_owner->GetId() ); event.SetEventObject( m_owner ); @@ -2345,7 +2356,7 @@ bool wxDataViewCtrlInternal::Cleared() gboolean wxDataViewCtrlInternal::get_iter( GtkTreeIter *iter, GtkTreePath *path ) { - g_model = m_wx_model; + g_internal = this; int depth = gtk_tree_path_get_depth( path ); @@ -2387,7 +2398,7 @@ gboolean wxDataViewCtrlInternal::get_iter( GtkTreeIter *iter, GtkTreePath *path GtkTreePath *wxDataViewCtrlInternal::get_path( GtkTreeIter *iter ) { - g_model = m_wx_model; + g_internal = this; GtkTreePath *retval = gtk_tree_path_new (); void *id = iter->user_data; @@ -2407,7 +2418,7 @@ GtkTreePath *wxDataViewCtrlInternal::get_path( GtkTreeIter *iter ) GtkTreePath *wxDataViewCtrlInternal::get_path_safe( GtkTreeIter *iter ) { - g_model = m_wx_model; + g_internal = this; GtkTreePath *retval = gtk_tree_path_new (); void *id = iter->user_data; @@ -2434,9 +2445,12 @@ GtkTreePath *wxDataViewCtrlInternal::get_path_safe( GtkTreeIter *iter ) gboolean wxDataViewCtrlInternal::iter_next( GtkTreeIter *iter ) { - g_model = m_wx_model; + g_internal = this; wxGtkTreeModelNode *parent = FindParentNode( iter ); + if( parent == NULL ) + return FALSE; + unsigned int pos = parent->GetChildren().Index( iter->user_data ); if (pos == parent->GetChildCount()-1) @@ -2450,7 +2464,7 @@ gboolean wxDataViewCtrlInternal::iter_next( GtkTreeIter *iter ) gboolean wxDataViewCtrlInternal::iter_children( GtkTreeIter *iter, GtkTreeIter *parent ) { - g_model = m_wx_model; + g_internal = this; wxDataViewItem item( (void*) parent->user_data ); @@ -2471,7 +2485,7 @@ gboolean wxDataViewCtrlInternal::iter_children( GtkTreeIter *iter, GtkTreeIter * gboolean wxDataViewCtrlInternal::iter_has_child( GtkTreeIter *iter ) { - g_model = m_wx_model; + g_internal = this; wxDataViewItem item( (void*) iter->user_data ); bool is_container = m_wx_model->IsContainer( item ); @@ -2487,7 +2501,7 @@ gboolean wxDataViewCtrlInternal::iter_has_child( GtkTreeIter *iter ) gint wxDataViewCtrlInternal::iter_n_children( GtkTreeIter *iter ) { - g_model = m_wx_model; + g_internal = this; wxDataViewItem item( (void*) iter->user_data ); @@ -2504,7 +2518,7 @@ gint wxDataViewCtrlInternal::iter_n_children( GtkTreeIter *iter ) gboolean wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter *iter, GtkTreeIter *parent, gint n ) { - g_model = m_wx_model; + g_internal = this; void* id = NULL; if (parent) id = (void*) parent->user_data; @@ -2526,7 +2540,7 @@ gboolean wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter *iter, GtkTreeIter gboolean wxDataViewCtrlInternal::iter_parent( GtkTreeIter *iter, GtkTreeIter *child ) { - g_model = m_wx_model; + g_internal = this; wxGtkTreeModelNode *node = FindParentNode( child ); if (!node) @@ -2539,30 +2553,48 @@ gboolean wxDataViewCtrlInternal::iter_parent( GtkTreeIter *iter, GtkTreeIter *ch } static wxGtkTreeModelNode* -wxDataViewCtrlInternal_FindNode( wxGtkTreeModelNode *node, const wxDataViewItem &item ) +wxDataViewCtrlInternal_FindNode( wxDataViewModel * model, wxGtkTreeModelNode *treeNode, const wxDataViewItem &item ) { - if (!node) return NULL; + if( model == NULL ) + return NULL; - size_t count = node->GetNodesCount(); - size_t i; - for (i = 0; i < count; i++) + ItemList list; + list.DeleteContents( true ); + wxDataViewItem it( item ); + while( it.IsOk() ) { - wxGtkTreeModelNode *child = node->GetNodes().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) + wxDataViewItem * pItem = new wxDataViewItem( it ); + list.Insert( pItem ); + it = model->GetParent( it ); + } + + wxGtkTreeModelNode * node = treeNode; + for( ItemList::compatibility_iterator n = list.GetFirst(); n; n = n->GetNext() ) + { + if( node && node->GetNodes().GetCount() != 0 ) { - // wxPrintf( "branch findnode at %d\n", i ); - return node2; + int len = node->GetNodes().GetCount(); + wxGtkTreeModelNodes nodes = node->GetNodes(); + int j = 0; + for( ; j < len; j ++) + { + if( nodes[j]->GetItem() == *(n->GetData())) + { + node = nodes[j]; + break; + } + } + + if( j == len ) + { + return NULL; + } } + else + return NULL; } - - return NULL; + return node; + } wxGtkTreeModelNode *wxDataViewCtrlInternal::FindNode( GtkTreeIter *iter ) @@ -2574,7 +2606,7 @@ wxGtkTreeModelNode *wxDataViewCtrlInternal::FindNode( GtkTreeIter *iter ) if (!item.IsOk()) return m_root; - wxGtkTreeModelNode *result = wxDataViewCtrlInternal_FindNode( m_root, item ); + wxGtkTreeModelNode *result = wxDataViewCtrlInternal_FindNode( m_wx_model, m_root, item ); if (!result) { @@ -2591,7 +2623,7 @@ wxGtkTreeModelNode *wxDataViewCtrlInternal::FindNode( const wxDataViewItem &item if (!item.IsOk()) return m_root; - wxGtkTreeModelNode *result = wxDataViewCtrlInternal_FindNode( m_root, item ); + wxGtkTreeModelNode *result = wxDataViewCtrlInternal_FindNode( m_wx_model, m_root, item ); if (!result) { @@ -2604,31 +2636,56 @@ wxGtkTreeModelNode *wxDataViewCtrlInternal::FindNode( const wxDataViewItem &item } static wxGtkTreeModelNode* -wxDataViewCtrlInternal_FindParentNode( wxGtkTreeModelNode *node, const wxDataViewItem &item ) +wxDataViewCtrlInternal_FindParentNode( wxDataViewModel * model, wxGtkTreeModelNode *treeNode, const wxDataViewItem &item ) { - size_t child_count = node->GetChildCount(); - void *id = item.GetID(); - const wxGtkTreeModelChildren &children = node->GetChildren(); - size_t pos; - for (pos = 0; pos < child_count; pos++) + if( model == NULL ) + return NULL; + + ItemList list; + list.DeleteContents( true ); + if( !item.IsOk() ) + return NULL; + + wxDataViewItem it( model->GetParent( item ) ); + while( it.IsOk() ) { - if (children.Item( pos ) == id) - return node; + wxDataViewItem * pItem = new wxDataViewItem( it ); + list.Insert( pItem ); + it = model->GetParent( it ); } - size_t node_count = node->GetNodesCount(); - for (pos = 0; pos < node_count; pos++) + wxGtkTreeModelNode * node = treeNode; + for( ItemList::compatibility_iterator n = list.GetFirst(); n; n = n->GetNext() ) { - wxGtkTreeModelNode *child = node->GetNodes().Item( pos ); - - wxGtkTreeModelNode *node2 = wxDataViewCtrlInternal_FindParentNode( child, item ); - if (node2) + if( node && node->GetNodes().GetCount() != 0 ) { - // wxPrintf( "branch findnode at %d\n", i ); - return node2; + int len = node->GetNodes().GetCount(); + wxGtkTreeModelNodes nodes = node->GetNodes(); + int j = 0; + for( ; j < len; j ++) + { + if( nodes[j]->GetItem() == *(n->GetData())) + { + node = nodes[j]; + break; + } + } + + if( j == len ) + { + return NULL; + } } + else + return NULL; + } + //Examine whether the node is item's parent node + int len = node->GetChildCount(); + for( int i = 0; i < len ; i ++ ) + { + if( node->GetChildren().Item( i ) == item.GetID() ) + return node; } - return NULL; } @@ -2641,7 +2698,7 @@ wxGtkTreeModelNode *wxDataViewCtrlInternal::FindParentNode( GtkTreeIter *iter ) if (!item.IsOk()) return NULL; - return wxDataViewCtrlInternal_FindParentNode( m_root, item ); + return wxDataViewCtrlInternal_FindParentNode( m_wx_model, m_root, item ); } wxGtkTreeModelNode *wxDataViewCtrlInternal::FindParentNode( const wxDataViewItem &item ) @@ -2649,7 +2706,7 @@ wxGtkTreeModelNode *wxDataViewCtrlInternal::FindParentNode( const wxDataViewItem if (!item.IsOk()) return NULL; - return wxDataViewCtrlInternal_FindParentNode( m_root, item ); + return wxDataViewCtrlInternal_FindParentNode( m_wx_model, m_root, item ); } //----------------------------------------------------------------------------- @@ -2663,7 +2720,7 @@ wxdataview_selection_changed_callback( GtkTreeSelection* selection, wxDataViewCt return; wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_SELECTED, dv->GetId() ); - // TODO: item + event.SetItem( dv->GetSelection() ); event.SetModel( dv->GetModel() ); dv->GetEventHandler()->ProcessEvent( event ); } @@ -2682,8 +2739,60 @@ wxdataview_row_activated_callback( GtkTreeView* treeview, GtkTreePath *path, dv->GetEventHandler()->ProcessEvent( event ); } +static gboolean +wxdataview_test_expand_row_callback( GtkTreeView* treeview, GtkTreeIter* iter, + GtkTreePath *path, wxDataViewCtrl *dv ) +{ + wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING, dv->GetId() ); + + wxDataViewItem item( (void*) iter->user_data );; + event.SetItem( item ); + event.SetModel( dv->GetModel() ); + dv->GetEventHandler()->ProcessEvent( event ); + + return !event.IsAllowed(); +} + +static void +wxdataview_row_expanded_callback( GtkTreeView* treeview, GtkTreeIter* iter, + GtkTreePath *path, wxDataViewCtrl *dv ) +{ + wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED, dv->GetId() ); + + wxDataViewItem item( (void*) iter->user_data );; + event.SetItem( item ); + event.SetModel( dv->GetModel() ); + dv->GetEventHandler()->ProcessEvent( event ); +} + +static gboolean +wxdataview_test_collapse_row_callback( GtkTreeView* treeview, GtkTreeIter* iter, + GtkTreePath *path, wxDataViewCtrl *dv ) +{ + wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING, dv->GetId() ); + + wxDataViewItem item( (void*) iter->user_data );; + event.SetItem( item ); + event.SetModel( dv->GetModel() ); + dv->GetEventHandler()->ProcessEvent( event ); + + return !event.IsAllowed(); +} + +static void +wxdataview_row_collapsed_callback( GtkTreeView* treeview, GtkTreeIter* iter, + GtkTreePath *path, wxDataViewCtrl *dv ) +{ + wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED, dv->GetId() ); + + wxDataViewItem item( (void*) iter->user_data );; + event.SetItem( item ); + event.SetModel( dv->GetModel() ); + dv->GetEventHandler()->ProcessEvent( event ); +} + //----------------------------------------------------------------------------- -// wxDataViewCtrl + // wxDataViewCtrl //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -2707,8 +2816,7 @@ void gtk_dataviewctrl_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation *alloc, wxDataViewCtrl *win ) { - - wxWindowList::Node *node = win->GetChildren().GetFirst(); + wxWindowList::compatibility_iterator node = win->GetChildren().GetFirst(); while (node) { wxWindow *child = node->GetData(); @@ -2817,9 +2925,21 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, GtkEnableSelectionEvents(); - g_signal_connect_after (m_treeview, "row_activated", + g_signal_connect_after (m_treeview, "row-activated", G_CALLBACK (wxdataview_row_activated_callback), this); + g_signal_connect (m_treeview, "test-collapse-row", + G_CALLBACK (wxdataview_test_collapse_row_callback), this); + + g_signal_connect_after (m_treeview, "row-collapsed", + G_CALLBACK (wxdataview_row_collapsed_callback), this); + + g_signal_connect (m_treeview, "test-expand-row", + G_CALLBACK (wxdataview_test_expand_row_callback), this); + + g_signal_connect_after (m_treeview, "row-expanded", + G_CALLBACK (wxdataview_row_expanded_callback), this); + return true; } @@ -2875,6 +2995,22 @@ wxDataViewItem wxDataViewCtrl::GetSelection() 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; + GtkTreeIter iter; + m_internal->get_iter( &iter, path ); + + // delete list + g_list_foreach( list, (GFunc) gtk_tree_path_free, NULL ); + g_list_free( list ); + + return wxDataViewItem( (void*) iter.user_data ); + } } else { @@ -2889,6 +3025,137 @@ wxDataViewItem wxDataViewCtrl::GetSelection() return wxDataViewItem(0); } +int wxDataViewCtrl::GetSelections( wxDataViewItemArray & sel ) const +{ + sel.Clear(); + + GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview) ); + if (HasFlag(wxDV_MULTIPLE)) + { + GtkTreeModel *model; + GList *list = gtk_tree_selection_get_selected_rows( selection, &model ); + + int count = 0; + while (list) + { + GtkTreePath *path = (GtkTreePath*) list->data; + + GtkTreeIter iter; + m_internal->get_iter( &iter, path ); + + sel.Add( wxDataViewItem( (void*) iter.user_data ) ); + + 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) + { + sel.Add( wxDataViewItem( (void*) iter.user_data) ); + return 1; + } + } + + return 0; +} + +void wxDataViewCtrl::SetSelections( const wxDataViewItemArray & sel ) +{ + GtkDisableSelectionEvents(); + + GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview) ); + + gtk_tree_selection_unselect_all( selection ); + + size_t i; + for (i = 0; i < sel.GetCount(); i++) + { + GtkTreeIter iter; + iter.user_data = (gpointer) sel[i].GetID(); + gtk_tree_selection_select_iter( selection, &iter ); + } + + GtkEnableSelectionEvents(); +} + +void wxDataViewCtrl::Select( const wxDataViewItem & item ) +{ + GtkDisableSelectionEvents(); + + GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview) ); + + GtkTreeIter iter; + iter.user_data = (gpointer) item.GetID(); + gtk_tree_selection_select_iter( selection, &iter ); + + GtkEnableSelectionEvents(); +} + +void wxDataViewCtrl::Unselect( const wxDataViewItem & item ) +{ + GtkDisableSelectionEvents(); + + GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview) ); + + GtkTreeIter iter; + iter.user_data = (gpointer) item.GetID(); + gtk_tree_selection_unselect_iter( selection, &iter ); + + GtkEnableSelectionEvents(); +} + +bool wxDataViewCtrl::IsSelected( const wxDataViewItem & item ) const +{ + GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview) ); + + GtkTreeIter iter; + iter.user_data = (gpointer) item.GetID(); + + return gtk_tree_selection_iter_is_selected( selection, &iter ); +} + +void wxDataViewCtrl::SelectAll() +{ + GtkDisableSelectionEvents(); + + GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview) ); + + gtk_tree_selection_select_all( selection ); + + GtkEnableSelectionEvents(); +} + +void wxDataViewCtrl::UnselectAll() +{ + GtkDisableSelectionEvents(); + + GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview) ); + + gtk_tree_selection_unselect_all( selection ); + + GtkEnableSelectionEvents(); +} + +void wxDataViewCtrl::EnsureVisible( const wxDataViewItem & item, wxDataViewColumn *column ) +{ + GtkTreeIter iter; + iter.user_data = (gpointer) item.GetID(); + GtkTreePath *path = m_internal->get_path( &iter ); + gtk_tree_view_scroll_to_cell( GTK_TREE_VIEW(m_treeview), path, NULL, false, 0.0, 0.0 ); + gtk_tree_path_free( path ); +} + void wxDataViewCtrl::DoSetExpanderColumn() { } @@ -2900,15 +3167,15 @@ void wxDataViewCtrl::DoSetIndent() void wxDataViewCtrl::GtkDisableSelectionEvents() { GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview) ); - g_signal_connect_after (selection, "changed", - G_CALLBACK (wxdataview_selection_changed_callback), this); + g_signal_handlers_disconnect_by_func( selection, + (gpointer) (wxdataview_selection_changed_callback), this); } void wxDataViewCtrl::GtkEnableSelectionEvents() { GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview) ); - g_signal_handlers_disconnect_by_func( selection, - (gpointer) (wxdataview_selection_changed_callback), this); + g_signal_connect_after (selection, "changed", + G_CALLBACK (wxdataview_selection_changed_callback), this); } // static