X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2056dede02ac6010a35086d9ea6738df9bc49796..4b3f61d14cbc6cc117373d173ecf08fbec4c9a38:/src/gtk/dataview.cpp diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp index a34303416b..5f31a0fa05 100644 --- a/src/gtk/dataview.cpp +++ b/src/gtk/dataview.cpp @@ -23,6 +23,7 @@ #include "wx/icon.h" #include "wx/list.h" #include "wx/settings.h" + #include "wx/dataobj.h" #include "wx/crt.h" #endif @@ -32,6 +33,8 @@ #include "wx/listimpl.cpp" #include "wx/gtk/private.h" +#include "wx/gtk/dc.h" +#include "wx/gtk/dcclient.h" //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -56,9 +59,10 @@ WX_DEFINE_LIST(ItemList) class wxDataViewCtrlInternal { public: - wxDataViewCtrlInternal( wxDataViewCtrl *owner, wxDataViewModel *wx_model, GtkWxTreeModel *owner ); + wxDataViewCtrlInternal( wxDataViewCtrl *owner, wxDataViewModel *wx_model, GtkWxTreeModel *gtk_model ); ~wxDataViewCtrlInternal(); - + + // model iface GtkTreeModelFlags get_flags(); gboolean get_iter( GtkTreeIter *iter, GtkTreePath *path ); GtkTreePath *get_path( GtkTreeIter *iter); @@ -68,30 +72,42 @@ public: gint iter_n_children( GtkTreeIter *iter ); gboolean iter_nth_child( GtkTreeIter *iter, GtkTreeIter *parent, gint n ); gboolean iter_parent( GtkTreeIter *iter, GtkTreeIter *child ); - - wxDataViewModel* GetDataViewModel() { return m_wx_model; } - wxDataViewCtrl* GetOwner() { return m_owner; } - GtkWxTreeModel* GetGtkModel() { return m_gtk_model; } + // dnd iface + gboolean row_draggable( GtkTreeDragSource *drag_source, GtkTreePath *path ); + gboolean drag_data_delete( GtkTreeDragSource *drag_source, GtkTreePath* path ); + gboolean drag_data_get( GtkTreeDragSource *drag_source, GtkTreePath *path, + GtkSelectionData *selection_data ); + gboolean drag_data_received( GtkTreeDragDest *drag_dest, GtkTreePath *dest, + GtkSelectionData *selection_data ); + gboolean row_drop_possible( GtkTreeDragDest *drag_dest, GtkTreePath *dest_path, + GtkSelectionData *selection_data ); + + // notifactions from wxDataViewModel bool ItemAdded( const wxDataViewItem &parent, 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(); - + + // sorting interface void SetSortOrder( GtkSortType sort_order ) { m_sort_order = sort_order; } GtkSortType GetSortOrder() { return m_sort_order; } void SetSortColumn( int column ) { m_sort_column = column; } int GetSortColumn() { return m_sort_column; } - + void SetDataViewSortColumn( wxDataViewColumn *column ) { m_dataview_sort_column = column; } wxDataViewColumn *GetDataViewSortColumn() { return m_dataview_sort_column; } - + bool IsSorted() { return (m_sort_column >= 0); } - - + + // accessors + wxDataViewModel* GetDataViewModel() { return m_wx_model; } + wxDataViewCtrl* GetOwner() { return m_owner; } + GtkWxTreeModel* GetGtkModel() { return m_gtk_model; } + protected: void InitTree(); wxGtkTreeModelNode *FindNode( const wxDataViewItem &item ); @@ -99,7 +115,7 @@ protected: wxGtkTreeModelNode *FindParentNode( const wxDataViewItem &item ); wxGtkTreeModelNode *FindParentNode( GtkTreeIter *iter ); void BuildBranch( wxGtkTreeModelNode *branch ); - + private: wxGtkTreeModelNode *m_root; wxDataViewModel *m_wx_model; @@ -117,9 +133,9 @@ private: int LINKAGEMODE wxGtkTreeModelChildCmp( void** id1, void** id2 ) { - int ret = g_internal->GetDataViewModel()->Compare( *id1, *id2, + int ret = g_internal->GetDataViewModel()->Compare( *id1, *id2, g_internal->GetSortColumn(), (g_internal->GetSortOrder() == GTK_SORT_ASCENDING) ); - + return ret; } @@ -131,14 +147,14 @@ class wxGtkTreeModelNode public: wxGtkTreeModelNode( wxGtkTreeModelNode* parent, const wxDataViewItem &item, wxDataViewCtrlInternal *internal ) - { - m_parent = parent; + { + m_parent = parent; m_item = item; m_internal = internal; } - + ~wxGtkTreeModelNode() - { + { size_t count = m_children.GetCount(); size_t i; for (i = 0; i < count; i++) @@ -148,12 +164,12 @@ public: } } - unsigned int AddNode( wxGtkTreeModelNode* child ) - { + unsigned int AddNode( wxGtkTreeModelNode* child ) + { m_nodes.Add( child ); - + void *id = child->GetItem().GetID(); - + m_children.Add( id ); if (m_internal->IsSorted() || m_internal->GetDataViewModel()->HasDefaultCompare()) @@ -165,7 +181,7 @@ public: return m_children.GetCount()-1; } - + unsigned int AddLeave( void* id ) { m_children.Add( id ); @@ -179,15 +195,15 @@ public: return m_children.GetCount()-1; } - + void DeleteChild( void* id ) { m_children.Remove( id ); - + unsigned int count = m_nodes.GetCount(); unsigned int pos; for (pos = 0; pos < count; pos++) - { + { wxGtkTreeModelNode *node = m_nodes.Item( pos ); if (node->GetItem().GetID() == id) { @@ -196,29 +212,29 @@ public: break; } } - + } - - wxGtkTreeModelNode* GetParent() + + wxGtkTreeModelNode* GetParent() { return m_parent; } - wxGtkTreeModelNodes &GetNodes() + wxGtkTreeModelNodes &GetNodes() { return m_nodes; } - wxGtkTreeModelChildren &GetChildren() + wxGtkTreeModelChildren &GetChildren() { return m_children; } - + unsigned int GetChildCount() { return m_children.GetCount(); } unsigned int GetNodesCount() { return m_nodes.GetCount(); } wxDataViewItem &GetItem() { return m_item; } wxDataViewCtrlInternal *GetInternal() { return m_internal; } - + void Resort(); - + private: wxGtkTreeModelNode *m_parent; wxGtkTreeModelNodes m_nodes; wxGtkTreeModelChildren m_children; - wxDataViewItem m_item; + wxDataViewItem m_item; wxDataViewCtrlInternal *m_internal; }; @@ -263,8 +279,12 @@ struct _GtkWxTreeModelClass static GtkWxTreeModel *wxgtk_tree_model_new (void); static void wxgtk_tree_model_init (GtkWxTreeModel *tree_model); static void wxgtk_tree_model_class_init (GtkWxTreeModelClass *klass); -static void wxgtk_tree_model_tree_model_init (GtkTreeModelIface *iface); -static void wxgtk_tree_model_sortable_init (GtkTreeSortableIface *iface); + +static void wxgtk_tree_model_tree_model_init (GtkTreeModelIface *iface); +static void wxgtk_tree_model_sortable_init (GtkTreeSortableIface *iface); +static void wxgtk_tree_model_drag_source_init(GtkTreeDragSourceIface *iface); +static void wxgtk_tree_model_drag_dest_init (GtkTreeDragDestIface *iface); + static void wxgtk_tree_model_finalize (GObject *object); static GtkTreeModelFlags wxgtk_tree_model_get_flags (GtkTreeModel *tree_model); static gint wxgtk_tree_model_get_n_columns (GtkTreeModel *tree_model); @@ -298,22 +318,36 @@ static gboolean wxgtk_tree_model_iter_parent (GtkTreeModel *tree_mo /* sortable */ static gboolean wxgtk_tree_model_get_sort_column_id (GtkTreeSortable *sortable, - gint *sort_column_id, - GtkSortType *order); + gint *sort_column_id, + GtkSortType *order); static void wxgtk_tree_model_set_sort_column_id (GtkTreeSortable *sortable, - gint sort_column_id, - GtkSortType order); + gint sort_column_id, + GtkSortType order); static void wxgtk_tree_model_set_sort_func (GtkTreeSortable *sortable, - gint sort_column_id, - GtkTreeIterCompareFunc func, - gpointer data, - GtkDestroyNotify destroy); + gint sort_column_id, + GtkTreeIterCompareFunc func, + gpointer data, + GtkDestroyNotify destroy); static void wxgtk_tree_model_set_default_sort_func (GtkTreeSortable *sortable, - GtkTreeIterCompareFunc func, - gpointer data, - GtkDestroyNotify destroy); + GtkTreeIterCompareFunc func, + gpointer data, + GtkDestroyNotify destroy); static gboolean wxgtk_tree_model_has_default_sort_func (GtkTreeSortable *sortable); +/* drag'n'drop */ +static gboolean wxgtk_tree_model_row_draggable (GtkTreeDragSource *drag_source, + GtkTreePath *path); +static gboolean wxgtk_tree_model_drag_data_delete (GtkTreeDragSource *drag_source, + GtkTreePath *path); +static gboolean wxgtk_tree_model_drag_data_get (GtkTreeDragSource *drag_source, + GtkTreePath *path, + GtkSelectionData *selection_data); +static gboolean wxgtk_tree_model_drag_data_received (GtkTreeDragDest *drag_dest, + GtkTreePath *dest, + GtkSelectionData *selection_data); +static gboolean wxgtk_tree_model_row_drop_possible (GtkTreeDragDest *drag_dest, + GtkTreePath *dest_path, + GtkSelectionData *selection_data); static GObjectClass *list_parent_class = NULL; @@ -352,6 +386,20 @@ gtk_wx_tree_model_get_type (void) NULL }; + static const GInterfaceInfo drag_source_iface_info = + { + (GInterfaceInitFunc) wxgtk_tree_model_drag_source_init, + NULL, + NULL + }; + + static const GInterfaceInfo drag_dest_iface_info = + { + (GInterfaceInitFunc) wxgtk_tree_model_drag_dest_init, + NULL, + NULL + }; + tree_model_type = g_type_register_static (G_TYPE_OBJECT, "GtkWxTreeModel", &tree_model_info, (GTypeFlags)0 ); @@ -361,6 +409,12 @@ gtk_wx_tree_model_get_type (void) g_type_add_interface_static (tree_model_type, GTK_TYPE_TREE_SORTABLE, &sortable_iface_info); + g_type_add_interface_static (tree_model_type, + GTK_TYPE_TREE_DRAG_DEST, + &drag_dest_iface_info); + g_type_add_interface_static (tree_model_type, + GTK_TYPE_TREE_DRAG_SOURCE, + &drag_source_iface_info); } return tree_model_type; @@ -408,6 +462,21 @@ wxgtk_tree_model_sortable_init (GtkTreeSortableIface *iface) iface->has_default_sort_func = wxgtk_tree_model_has_default_sort_func; } +static void +wxgtk_tree_model_drag_source_init(GtkTreeDragSourceIface *iface) +{ + iface->row_draggable = wxgtk_tree_model_row_draggable; + iface->drag_data_delete = wxgtk_tree_model_drag_data_delete; + iface->drag_data_get = wxgtk_tree_model_drag_data_get; +} + +static void +wxgtk_tree_model_drag_dest_init (GtkTreeDragDestIface *iface) +{ + iface->drag_data_received = wxgtk_tree_model_drag_data_received; + iface->row_drop_possible = wxgtk_tree_model_row_drop_possible; +} + static void wxgtk_tree_model_init (GtkWxTreeModel *tree_model) { @@ -523,9 +592,13 @@ wxgtk_tree_model_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter) { GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model; + + if (wxtree_model->stamp != iter->stamp) + wxPrintf( "crash\n" ); + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE); g_return_val_if_fail (wxtree_model->stamp == iter->stamp, FALSE); - + return wxtree_model->internal->iter_next( iter ); } @@ -583,85 +656,157 @@ wxgtk_tree_model_iter_parent (GtkTreeModel *tree_model, GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model; g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE); g_return_val_if_fail (wxtree_model->stamp == child->stamp, FALSE); - + return wxtree_model->internal->iter_parent( iter, child ); } -/* sortable */ -gboolean wxgtk_tree_model_get_sort_column_id (GtkTreeSortable *sortable, - gint *sort_column_id, - GtkSortType *order) +/* drag'n'drop iface */ +static gboolean +wxgtk_tree_model_row_draggable (GtkTreeDragSource *drag_source, + GtkTreePath *path) { - GtkWxTreeModel *tree_model = (GtkWxTreeModel *) sortable; + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) drag_source; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE); + + return wxtree_model->internal->row_draggable( drag_source, path ); +} + +static gboolean +wxgtk_tree_model_drag_data_delete (GtkTreeDragSource *drag_source, + GtkTreePath *path) +{ + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) drag_source; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE); + + return wxtree_model->internal->drag_data_delete( drag_source, path ); +} + +static gboolean +wxgtk_tree_model_drag_data_get (GtkTreeDragSource *drag_source, + GtkTreePath *path, + GtkSelectionData *selection_data) +{ + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) drag_source; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE); + +#if 0 + wxPrintf( "drag_get_data\n"); + + wxGtkString atom_selection(gdk_atom_name(selection_data->selection)); + wxPrintf( "selection %s\n", wxString::FromAscii(atom_selection) ); + + wxGtkString atom_target(gdk_atom_name(selection_data->target)); + wxPrintf( "target %s\n", wxString::FromAscii(atom_target) ); + + wxGtkString atom_type(gdk_atom_name(selection_data->type)); + wxPrintf( "type %s\n", wxString::FromAscii(atom_type) ); + + wxPrintf( "format %d\n", selection_data->format ); +#endif + + return wxtree_model->internal->drag_data_get( drag_source, path, selection_data ); +} + +static gboolean +wxgtk_tree_model_drag_data_received (GtkTreeDragDest *drag_dest, + GtkTreePath *dest, + GtkSelectionData *selection_data) +{ + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) drag_dest; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE); + + return wxtree_model->internal->drag_data_received( drag_dest, dest, selection_data ); +} + +static gboolean +wxgtk_tree_model_row_drop_possible (GtkTreeDragDest *drag_dest, + GtkTreePath *dest_path, + GtkSelectionData *selection_data) +{ + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) drag_dest; + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE); + + return wxtree_model->internal->row_drop_possible( drag_dest, dest_path, selection_data ); +} + +/* sortable iface */ +static gboolean +wxgtk_tree_model_get_sort_column_id (GtkTreeSortable *sortable, + gint *sort_column_id, + GtkSortType *order) +{ + GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) sortable; g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (sortable), FALSE); - if (!tree_model->internal->IsSorted()) + if (!wxtree_model->internal->IsSorted()) { if (sort_column_id) *sort_column_id = -1; - + return TRUE; } if (sort_column_id) - *sort_column_id = tree_model->internal->GetSortColumn(); - + *sort_column_id = wxtree_model->internal->GetSortColumn(); + if (order) - *order = tree_model->internal->GetSortOrder(); - + *order = wxtree_model->internal->GetSortOrder(); + return TRUE; } wxDataViewColumn *gs_lastLeftClickHeader = NULL; -void wxgtk_tree_model_set_sort_column_id (GtkTreeSortable *sortable, - gint sort_column_id, - GtkSortType order) +static 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) ); tree_model->internal->SetDataViewSortColumn( gs_lastLeftClickHeader ); - + if ((sort_column_id != (gint) tree_model->internal->GetSortColumn()) || (order != tree_model->internal->GetSortOrder())) { tree_model->internal->SetSortColumn( sort_column_id ); tree_model->internal->SetSortOrder( order ); - + gtk_tree_sortable_sort_column_changed (sortable); - + tree_model->internal->GetDataViewModel()->Resort(); } if (gs_lastLeftClickHeader) { - wxDataViewCtrl *dv = tree_model->internal->GetOwner(); + wxDataViewCtrl *dv = tree_model->internal->GetOwner(); wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_COLUMN_SORTED, dv->GetId() ); event.SetDataViewColumn( gs_lastLeftClickHeader ); event.SetModel( dv->GetModel() ); - dv->GetEventHandler()->ProcessEvent( event ); + dv->HandleWindowEvent( event ); } - + gs_lastLeftClickHeader = NULL; } -void wxgtk_tree_model_set_sort_func (GtkTreeSortable *sortable, - gint sort_column_id, - GtkTreeIterCompareFunc func, - gpointer data, - GtkDestroyNotify destroy) +static void +wxgtk_tree_model_set_sort_func (GtkTreeSortable *sortable, + gint WXUNUSED(sort_column_id), + GtkTreeIterCompareFunc func, + gpointer WXUNUSED(data), + GtkDestroyNotify WXUNUSED(destroy) ) { g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable) ); g_return_if_fail (func != NULL); } -void wxgtk_tree_model_set_default_sort_func (GtkTreeSortable *sortable, - GtkTreeIterCompareFunc func, - gpointer data, - GtkDestroyNotify destroy) +void wxgtk_tree_model_set_default_sort_func (GtkTreeSortable *sortable, + GtkTreeIterCompareFunc func, + gpointer WXUNUSED(data), + GtkDestroyNotify WXUNUSED(destroy) ) { g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable) ); g_return_if_fail (func != NULL); @@ -671,6 +816,8 @@ void wxgtk_tree_model_set_default_sort_func (GtkTreeSortable *sortabl gboolean wxgtk_tree_model_has_default_sort_func (GtkTreeSortable *sortable) { + g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (sortable), FALSE ); + return FALSE; } @@ -819,12 +966,12 @@ gtk_wx_cell_renderer_new (void) static GtkCellEditable *gtk_wx_cell_renderer_start_editing( GtkCellRenderer *renderer, - GdkEvent *event, + GdkEvent *WXUNUSED(event), GtkWidget *widget, const gchar *path, - GdkRectangle *background_area, + GdkRectangle *WXUNUSED(background_area), GdkRectangle *cell_area, - GtkCellRendererState flags ) + GtkCellRendererState WXUNUSED(flags) ) { GtkWxCellRenderer *wxrenderer = (GtkWxCellRenderer *) renderer; wxDataViewCustomRenderer *cell = wxrenderer->cell; @@ -859,7 +1006,7 @@ static GtkCellEditable *gtk_wx_cell_renderer_start_editing( static void gtk_wx_cell_renderer_get_size (GtkCellRenderer *renderer, - GtkWidget *widget, + GtkWidget *WXUNUSED(widget), GdkRectangle *cell_area, gint *x_offset, gint *y_offset, @@ -939,20 +1086,12 @@ gtk_wx_cell_renderer_render (GtkCellRenderer *renderer, { wxRect renderrect( rect.x, rect.y, rect.width, rect.height ); wxWindowDC* dc = (wxWindowDC*) cell->GetDC(); -#if wxUSE_NEW_DC - wxGTKWindowDCImpl *impldc = (wxGTKWindowDCImpl *) dc->GetImpl(); - if (impldc->m_window == NULL) + wxWindowDCImpl *impl = (wxWindowDCImpl *) dc->GetImpl(); + if (impl->m_gdkwindow == NULL) { - impldc->m_window = window; - impldc->SetUpDC(); + impl->m_gdkwindow = window; + impl->SetUpDC(); } -#else - if (dc->m_window == NULL) - { - dc->m_window = window; - dc->SetUpDC(); - } -#endif int state = 0; if (flags & GTK_CELL_RENDERER_SELECTED) @@ -975,9 +1114,9 @@ gtk_wx_cell_renderer_activate( GdkEvent *event, GtkWidget *widget, const gchar *path, - GdkRectangle *background_area, + GdkRectangle *WXUNUSED(background_area), GdkRectangle *cell_area, - GtkCellRendererState flags ) + GtkCellRendererState WXUNUSED(flags) ) { GtkWxCellRenderer *wxrenderer = (GtkWxCellRenderer *) renderer; wxDataViewCustomRenderer *cell = wxrenderer->cell; @@ -1066,6 +1205,9 @@ public: virtual bool Cleared(); virtual void Resort(); + void SetGtkModel( GtkWxTreeModel *model ) { m_wxgtk_model = model; } + +private: GtkWxTreeModel *m_wxgtk_model; wxDataViewModel *m_wx_model; wxDataViewCtrl *m_owner; @@ -1098,9 +1240,9 @@ bool wxGtkDataViewModelNotifier::ItemAdded( const wxDataViewItem &parent, const 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( GTK_TREE_MODEL(m_wxgtk_model), &iter ); - gtk_tree_model_row_inserted( + gtk_tree_model_row_inserted( GTK_TREE_MODEL(m_wxgtk_model), path, &iter); gtk_tree_path_free (path); @@ -1113,14 +1255,14 @@ bool wxGtkDataViewModelNotifier::ItemDeleted( const wxDataViewItem &parent, cons 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( GTK_TREE_MODEL(m_wxgtk_model), &iter ); gtk_tree_model_row_deleted( GTK_TREE_MODEL(m_wxgtk_model), path ); gtk_tree_path_free (path); m_owner->GtkGetInternal()->ItemDeleted( parent, item ); - + return true; } @@ -1135,14 +1277,14 @@ bool wxGtkDataViewModelNotifier::ItemChanged( 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( GTK_TREE_MODEL(m_wxgtk_model), &iter ); gtk_tree_model_row_changed( GTK_TREE_MODEL(m_wxgtk_model), path, &iter ); gtk_tree_path_free (path); m_owner->GtkGetInternal()->ItemChanged( item ); - + return true; } @@ -1162,7 +1304,7 @@ bool wxGtkDataViewModelNotifier::ValueChanged( const wxDataViewItem &item, unsig GtkTreeIter iter; 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( GTK_TREE_MODEL(m_wxgtk_model), &iter ); GdkRectangle cell_area; gtk_tree_view_get_cell_area( widget, path, gcolumn, &cell_area ); @@ -1176,9 +1318,9 @@ bool wxGtkDataViewModelNotifier::ValueChanged( const wxDataViewItem &item, unsig // Redraw gtk_widget_queue_draw_area( GTK_WIDGET(widget), cell_area.x - xdiff, ydiff + cell_area.y, cell_area.width, cell_area.height ); - + m_owner->GtkGetInternal()->ValueChanged( item, model_col ); - + return true; } } @@ -1188,10 +1330,15 @@ bool wxGtkDataViewModelNotifier::ValueChanged( const wxDataViewItem &item, unsig bool wxGtkDataViewModelNotifier::Cleared() { - // TODO: delete everything - + gtk_tree_view_set_model( GTK_TREE_VIEW(m_owner->m_treeview), NULL ); + + // this will create a new GTK model m_owner->GtkGetInternal()->Cleared(); + SetGtkModel( m_owner->GtkGetInternal()->GetGtkModel() ); + + gtk_tree_view_set_model( GTK_TREE_VIEW(m_owner->m_treeview), GTK_TREE_MODEL(m_wxgtk_model) ); + return false; } @@ -1202,7 +1349,7 @@ bool wxGtkDataViewModelNotifier::Cleared() static gpointer s_user_data = NULL; static void -wxgtk_cell_editable_editing_done( GtkCellEditable *editable, +wxgtk_cell_editable_editing_done( GtkCellEditable *WXUNUSED(editable), wxDataViewRenderer *wxrenderer ) { wxDataViewColumn *column = wxrenderer->GetOwner(); @@ -1212,11 +1359,11 @@ wxgtk_cell_editable_editing_done( GtkCellEditable *editable, event.SetModel( dv->GetModel() ); wxDataViewItem item( s_user_data ); event.SetItem( item ); - dv->GetEventHandler()->ProcessEvent( event ); + dv->HandleWindowEvent( event ); } -static void -wxgtk_renderer_editing_started( GtkCellRenderer *cell, GtkCellEditable *editable, +static void +wxgtk_renderer_editing_started( GtkCellRenderer *WXUNUSED(cell), GtkCellEditable *editable, gchar *path, wxDataViewRenderer *wxrenderer ) { wxDataViewColumn *column = wxrenderer->GetOwner(); @@ -1230,16 +1377,16 @@ wxgtk_renderer_editing_started( GtkCellRenderer *cell, GtkCellEditable *editable gtk_tree_path_free( tree_path ); wxDataViewItem item( iter.user_data ); event.SetItem( item ); - dv->GetEventHandler()->ProcessEvent( event ); + dv->HandleWindowEvent( event ); if (GTK_IS_CELL_EDITABLE(editable)) { s_user_data = iter.user_data; - + g_signal_connect (GTK_CELL_EDITABLE (editable), "editing_done", G_CALLBACK (wxgtk_cell_editable_editing_done), (gpointer) wxrenderer ); - + } } @@ -1282,7 +1429,7 @@ void wxDataViewRenderer::SetMode( wxDataViewCellMode mode ) break; } - // This value is most often ignored in GtkTreeView + // This value is most often ignored in GtkTreeView GValue gvalue = { 0, }; g_value_init( &gvalue, gtk_cell_renderer_mode_get_type() ); g_value_set_enum( &gvalue, gtkMode ); @@ -1390,7 +1537,7 @@ static void wxGtkTextRendererEditedCallback( GtkCellRendererText *renderer, gchar *arg1, gchar *arg2, gpointer user_data ); } -static void wxGtkTextRendererEditedCallback( GtkCellRendererText *renderer, +static void wxGtkTextRendererEditedCallback( GtkCellRendererText *WXUNUSED(renderer), gchar *arg1, gchar *arg2, gpointer user_data ) { wxDataViewTextRenderer *cell = (wxDataViewTextRenderer*) user_data; @@ -1431,7 +1578,7 @@ wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString &varianttype, wxD g_value_unset( &gvalue ); g_signal_connect_after( m_renderer, "edited", G_CALLBACK(wxGtkTextRendererEditedCallback), this ); - + GtkInitHandlers(); } @@ -1445,7 +1592,7 @@ bool wxDataViewTextRenderer::SetValue( const wxVariant &value ) GValue gvalue = { 0, }; g_value_init( &gvalue, G_TYPE_STRING ); - g_value_set_string( &gvalue, wxGTK_CONV( tmp ) ); + g_value_set_string( &gvalue, wxGTK_CONV_FONT( tmp, GetOwner()->GetOwner()->GetFont() ) ); g_object_set_property( G_OBJECT(m_renderer), "text", &gvalue ); g_value_unset( &gvalue ); @@ -1457,7 +1604,7 @@ bool wxDataViewTextRenderer::GetValue( wxVariant &value ) const GValue gvalue = { 0, }; g_value_init( &gvalue, G_TYPE_STRING ); g_object_get_property( G_OBJECT(m_renderer), "text", &gvalue ); - wxString tmp = wxGTK_CONV_BACK( g_value_get_string( &gvalue ) ); + wxString tmp = wxGTK_CONV_BACK_FONT( g_value_get_string( &gvalue ), wx_const_cast(wxDataViewTextRenderer*, this)->GetOwner()->GetOwner()->GetFont() ); g_value_unset( &gvalue ); value = tmp; @@ -1486,18 +1633,18 @@ void wxDataViewTextRenderer::SetAlignment( int align ) g_value_unset( &gvalue ); } -// --------------------------------------------------------- +// --------------------------------------------------------- // wxDataViewTextRendererAttr -// --------------------------------------------------------- +// --------------------------------------------------------- IMPLEMENT_CLASS(wxDataViewTextRendererAttr,wxDataViewTextRenderer) -wxDataViewTextRendererAttr::wxDataViewTextRendererAttr( const wxString &varianttype, +wxDataViewTextRendererAttr::wxDataViewTextRendererAttr( const wxString &varianttype, wxDataViewCellMode mode, int align ) : wxDataViewTextRenderer( varianttype, mode, align ) { } - + // --------------------------------------------------------- // wxDataViewBitmapRenderer // --------------------------------------------------------- @@ -1555,7 +1702,7 @@ bool wxDataViewBitmapRenderer::SetValue( const wxVariant &value ) return false; } -bool wxDataViewBitmapRenderer::GetValue( wxVariant &value ) const +bool wxDataViewBitmapRenderer::GetValue( wxVariant &WXUNUSED(value) ) const { return false; } @@ -1657,41 +1804,38 @@ bool wxDataViewToggleRenderer::GetValue( wxVariant &value ) const // wxDataViewCustomRenderer // --------------------------------------------------------- -class wxDataViewCtrlDC: public wxWindowDC +class wxDataViewCtrlDCImpl: public wxWindowDCImpl { public: - wxDataViewCtrlDC( wxDataViewCtrl *window ) - { -#if wxUSE_NEW_DC - wxGTKWindowDCImpl *impl = (wxGTKWindowDCImpl*) GetImpl(); - + wxDataViewCtrlDCImpl( wxDC *owner, wxDataViewCtrl *window ) : + wxWindowDCImpl( owner ) + { GtkWidget *widget = window->m_treeview; // Set later - impl->m_window = NULL; - - impl->m_context = window->GtkGetPangoDefaultContext(); - impl->m_layout = pango_layout_new( impl->m_context ); - impl->m_fontdesc = pango_font_description_copy( widget->style->font_desc ); - - impl->m_cmap = gtk_widget_get_colormap( widget ? widget : window->m_widget ); + m_gdkwindow = NULL; -#else - GtkWidget *widget = window->m_treeview; - // Set later - m_window = NULL; + m_window = window; m_context = window->GtkGetPangoDefaultContext(); m_layout = pango_layout_new( m_context ); m_fontdesc = pango_font_description_copy( widget->style->font_desc ); m_cmap = gtk_widget_get_colormap( widget ? widget : window->m_widget ); -#endif - // Set m_window later + + // Set m_gdkwindow later // SetUpDC(); - // m_owner = window; } }; +class wxDataViewCtrlDC: public wxWindowDC +{ +public: + wxDataViewCtrlDC( wxDataViewCtrl *window ) : + wxWindowDC( new wxDataViewCtrlDCImpl( this, window ) ) + { } +}; + + // --------------------------------------------------------- // wxDataViewCustomRenderer // --------------------------------------------------------- @@ -1712,7 +1856,8 @@ wxDataViewCustomRenderer::wxDataViewCustomRenderer( const wxString &varianttype, Init(mode, align); } -void wxDataViewCustomRenderer::RenderText( const wxString &text, int xoffset, wxRect cell, wxDC *dc, int state ) +void wxDataViewCustomRenderer::RenderText( const wxString &text, int xoffset, + wxRect WXUNUSED(cell), wxDC *WXUNUSED(dc), int WXUNUSED(state) ) { #if 0 wxDataViewCtrl *view = GetOwner()->GetOwner(); @@ -1724,16 +1869,16 @@ void wxDataViewCustomRenderer::RenderText( const wxString &text, int xoffset, wx #else if (!m_text_renderer) m_text_renderer = gtk_cell_renderer_text_new(); - + GValue gvalue = { 0, }; g_value_init( &gvalue, G_TYPE_STRING ); - g_value_set_string( &gvalue, wxGTK_CONV( text ) ); + g_value_set_string( &gvalue, wxGTK_CONV_FONT( text, GetOwner()->GetOwner()->GetFont() ) ); g_object_set_property( G_OBJECT(m_text_renderer), "text", &gvalue ); g_value_unset( &gvalue ); ((GdkRectangle*) cell_area)->x += xoffset; ((GdkRectangle*) cell_area)->width -= xoffset; - + gtk_cell_renderer_render( m_text_renderer, window, widget, @@ -1741,7 +1886,7 @@ void wxDataViewCustomRenderer::RenderText( const wxString &text, int xoffset, wx (GdkRectangle*) cell_area, (GdkRectangle*) expose_area, (GtkCellRendererState) flags ); - + ((GdkRectangle*) cell_area)->x -= xoffset; ((GdkRectangle*) cell_area)->width += xoffset; #endif @@ -1758,7 +1903,7 @@ bool wxDataViewCustomRenderer::Init(wxDataViewCellMode mode, int align) SetAlignment(align); GtkInitHandlers(); - + return true; } @@ -1806,7 +1951,7 @@ wxDataViewProgressRenderer::wxDataViewProgressRenderer( const wxString &label, GValue gvalue = { 0, }; g_value_init( &gvalue, G_TYPE_STRING ); - g_value_set_string( &gvalue, wxGTK_CONV(m_label) ); + g_value_set_string( &gvalue, wxGTK_CONV_FONT( m_label, GetOwner()->GetOwner()->GetFont() ) ); g_object_set_property( G_OBJECT(m_renderer), "text", &gvalue ); g_value_unset( &gvalue ); @@ -1849,12 +1994,12 @@ bool wxDataViewProgressRenderer::SetValue( const wxVariant &value ) return true; } -bool wxDataViewProgressRenderer::GetValue( wxVariant &value ) const +bool wxDataViewProgressRenderer::GetValue( wxVariant &WXUNUSED(value) ) const { return false; } -bool wxDataViewProgressRenderer::Render( wxRect cell, wxDC *dc, int state ) +bool wxDataViewProgressRenderer::Render( wxRect cell, wxDC *dc, int WXUNUSED(state) ) { double pct = (double)m_value / 100.0; wxRect bar = cell; @@ -1941,7 +2086,7 @@ bool wxDataViewDateRenderer::SetValue( const wxVariant &value ) return true; } -bool wxDataViewDateRenderer::GetValue( wxVariant &value ) const +bool wxDataViewDateRenderer::GetValue( wxVariant &WXUNUSED(value) ) const { return false; } @@ -1962,7 +2107,7 @@ wxSize wxDataViewDateRenderer::GetSize() const return wxSize(x,y+d); } -bool wxDataViewDateRenderer::Activate( wxRect cell, wxDataViewModel *model, +bool wxDataViewDateRenderer::Activate( wxRect WXUNUSED(cell), wxDataViewModel *model, const wxDataViewItem &item, unsigned int col ) { wxVariant variant; @@ -1980,13 +2125,13 @@ bool wxDataViewDateRenderer::Activate( wxRect cell, wxDataViewModel *model, } -// --------------------------------------------------------- +// --------------------------------------------------------- // wxDataViewIconTextRenderer -// --------------------------------------------------------- +// --------------------------------------------------------- IMPLEMENT_CLASS(wxDataViewIconTextRenderer, wxDataViewCustomRenderer) -wxDataViewIconTextRenderer::wxDataViewIconTextRenderer( +wxDataViewIconTextRenderer::wxDataViewIconTextRenderer( const wxString &varianttype, wxDataViewCellMode mode, int align ) : wxDataViewCustomRenderer( varianttype, mode, align ) { @@ -1997,7 +2142,7 @@ wxDataViewIconTextRenderer::wxDataViewIconTextRenderer( wxDataViewIconTextRenderer::~wxDataViewIconTextRenderer() { } - + bool wxDataViewIconTextRenderer::SetValue( const wxVariant &value ) { m_value << value; @@ -2008,7 +2153,7 @@ bool wxDataViewIconTextRenderer::GetValue( wxVariant &value ) const { return false; } - + bool wxDataViewIconTextRenderer::Render( wxRect cell, wxDC *dc, int state ) { const wxIcon &icon = m_value.GetIcon(); @@ -2019,7 +2164,7 @@ bool wxDataViewIconTextRenderer::Render( wxRect cell, wxDC *dc, int state ) dc->DrawIcon( icon, cell.x, cell.y + yoffset ); offset = icon.GetWidth() + 4; } - + RenderText( m_value.GetText(), offset, cell, dc, state ); return true; @@ -2034,7 +2179,7 @@ wxSize wxDataViewIconTextRenderer::GetSize() const GetView()->GetTextExtent( m_value.GetText(), &x, &y, &d ); size.x += x; size.y = y+d; - return size; + return size; } wxControl* wxDataViewIconTextRenderer::CreateEditorCtrl( wxWindow *parent, wxRect labelRect, const wxVariant &value ) @@ -2068,7 +2213,7 @@ gtk_dataview_header_button_press_callback( GtkWidget *widget, wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK, dv->GetId() ); event.SetDataViewColumn( column ); event.SetModel( dv->GetModel() ); - if (dv->GetEventHandler()->ProcessEvent( event )) + if (dv->HandleWindowEvent( event )) return FALSE; } @@ -2078,7 +2223,7 @@ gtk_dataview_header_button_press_callback( GtkWidget *widget, wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK, dv->GetId() ); event.SetDataViewColumn( column ); event.SetModel( dv->GetModel() ); - if (dv->GetEventHandler()->ProcessEvent( event )) + if (dv->HandleWindowEvent( event )) return FALSE; } @@ -2111,7 +2256,7 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *column, if (!wx_model->IsIndexListModel()) { - + if (wx_model->IsContainer( item )) { if (wx_model->HasContainerColumns( item ) || (cell->GetOwner()->GetModelColumn() == 0)) @@ -2129,7 +2274,7 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *column, g_value_set_boolean( &gvalue, FALSE ); g_object_set_property( G_OBJECT(renderer), "visible", &gvalue ); g_value_unset( &gvalue ); - + return; } } @@ -2141,7 +2286,7 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *column, g_object_set_property( G_OBJECT(renderer), "visible", &gvalue ); g_value_unset( &gvalue ); } - + } wxVariant value; @@ -2160,7 +2305,7 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *column, bool colour_set = false; bool style_set = false; bool weight_set = false; - + if (wx_model->GetAttr( item, cell->GetOwner()->GetModelColumn(), attr )) { // this must be a GtkCellRendererText @@ -2174,10 +2319,10 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *column, g_value_set_boxed( &gvalue, gcol ); g_object_set_property( G_OBJECT(renderer), "foreground_gdk", &gvalue ); g_value_unset( &gvalue ); - + colour_set = true; } - + if (attr.GetItalic()) { GValue gvalue = { 0, }; @@ -2185,10 +2330,10 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *column, g_value_set_enum( &gvalue, PANGO_STYLE_ITALIC ); g_object_set_property( G_OBJECT(renderer), "style", &gvalue ); g_value_unset( &gvalue ); - + style_set = true; } - + if (attr.GetBold()) { GValue gvalue = { 0, }; @@ -2196,11 +2341,11 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *column, g_value_set_enum( &gvalue, PANGO_WEIGHT_BOLD ); g_object_set_property( G_OBJECT(renderer), "weight", &gvalue ); g_value_unset( &gvalue ); - + weight_set = true; } } - + if (!style_set) { GValue gvalue = { 0, }; @@ -2209,7 +2354,7 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *column, g_object_set_property( G_OBJECT(renderer), "style-set", &gvalue ); g_value_unset( &gvalue ); } - + if (!weight_set) { GValue gvalue = { 0, }; @@ -2218,7 +2363,7 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *column, g_object_set_property( G_OBJECT(renderer), "weight-set", &gvalue ); g_value_unset( &gvalue ); } - + if (!colour_set) { GValue gvalue = { 0, }; @@ -2435,7 +2580,7 @@ wxAlignment wxDataViewColumn::GetAlignment() const void wxDataViewColumn::SetSortable( bool sortable ) { GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN(m_column); - + if (sortable) { gtk_tree_view_column_set_sort_column_id( column, GetModelColumn() ); @@ -2504,6 +2649,15 @@ void wxDataViewColumn::SetWidth( int width ) gtk_tree_view_column_set_fixed_width( GTK_TREE_VIEW_COLUMN(m_column), width ); } +void wxDataViewColumn::SetReorderable( bool reorderable ) +{ + gtk_tree_view_column_set_reorderable( GTK_TREE_VIEW_COLUMN(m_column), reorderable ); +} + +bool wxDataViewColumn::IsReorderable() const +{ + return gtk_tree_view_column_get_reorderable( GTK_TREE_VIEW_COLUMN(m_column) ); +} //----------------------------------------------------------------------------- // wxGtkTreeModelNode @@ -2529,12 +2683,12 @@ void wxGtkTreeModelNode::Resort() wxGtkTreeModelChildren temp; WX_APPEND_ARRAY( temp, m_children ); - + g_internal = m_internal; m_children.Sort( &wxGtkTreeModelChildCmp ); gint *new_order = new gint[child_count]; - + unsigned int pos; for (pos = 0; pos < child_count; pos++) { @@ -2542,21 +2696,21 @@ void wxGtkTreeModelNode::Resort() int old_pos = temp.Index( id ); new_order[pos] = old_pos; } - + GtkTreeModel *gtk_tree_model = GTK_TREE_MODEL( m_internal->GetGtkModel() ); GtkTreeIter iter; iter.user_data = GetItem().GetID(); iter.stamp = m_internal->GetGtkModel()->stamp; - + GtkTreePath *path = m_internal->get_path( &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 < node_count; pos++) { wxGtkTreeModelNode *node = m_nodes.Item( pos ); @@ -2568,26 +2722,26 @@ void wxGtkTreeModelNode::Resort() // wxDataViewCtrlInternal //----------------------------------------------------------------------------- -wxDataViewCtrlInternal::wxDataViewCtrlInternal( wxDataViewCtrl *owner, +wxDataViewCtrlInternal::wxDataViewCtrlInternal( wxDataViewCtrl *owner, wxDataViewModel *wx_model, GtkWxTreeModel *gtk_model ) -{ +{ m_owner = owner; - m_wx_model = wx_model; - m_gtk_model = gtk_model; - m_root = NULL; + m_wx_model = wx_model; + m_gtk_model = gtk_model; + m_root = NULL; m_sort_order = GTK_SORT_ASCENDING; m_sort_column = -1; m_dataview_sort_column = NULL; - + if (!m_wx_model->IsIndexListModel()) InitTree(); } - + wxDataViewCtrlInternal::~wxDataViewCtrlInternal() { g_object_unref( m_gtk_model ); } - + void wxDataViewCtrlInternal::InitTree() { wxDataViewItem item; @@ -2606,17 +2760,91 @@ void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode *node ) for (pos = 0; pos < count; pos++) { wxDataViewItem child = children[pos]; - + if (m_wx_model->IsContainer( child )) node->AddNode( new wxGtkTreeModelNode( node, child, this ) ); else node->AddLeave( child.GetID() ); - + // Don't send any events here } } } +// GTK+ dnd iface + +gboolean wxDataViewCtrlInternal::row_draggable( GtkTreeDragSource *WXUNUSED(drag_source), + GtkTreePath *path ) +{ + GtkTreeIter iter; + if (!get_iter( &iter, path )) return FALSE; + + wxDataViewItem item( (void*) iter.user_data ); + + return m_wx_model->IsDraggable( item ); +} + +gboolean wxDataViewCtrlInternal::drag_data_delete( GtkTreeDragSource *WXUNUSED(drag_source), + GtkTreePath* path ) +{ + return FALSE; +} + +gboolean wxDataViewCtrlInternal::drag_data_get( GtkTreeDragSource *WXUNUSED(drag_source), + GtkTreePath *path, GtkSelectionData *selection_data ) +{ + GtkTreeIter iter; + if (!get_iter( &iter, path )) return FALSE; + + wxDataViewItem item( (void*) iter.user_data ); + + wxDataFormat format( selection_data->target ); + + size_t size = m_wx_model->GetDragDataSize( item, format ); + if (size == 0) return FALSE; + + void *data = malloc( size ); + + m_wx_model->GetDragData( item, format, data, size ); + + gtk_selection_data_set( selection_data, selection_data->target, + 8, (const guchar*) data, size ); + + free( data ); + + return TRUE; +} + +gboolean wxDataViewCtrlInternal::drag_data_received( GtkTreeDragDest *WXUNUSED(drag_dest), + GtkTreePath *dest, GtkSelectionData *selection_data ) +{ + return FALSE; +} + +gboolean wxDataViewCtrlInternal::row_drop_possible( GtkTreeDragDest *WXUNUSED(drag_dest), + GtkTreePath *dest_path, GtkSelectionData *selection_data ) +{ + return FALSE; +} + +// notifications from wxDataViewModel + +bool wxDataViewCtrlInternal::Cleared() +{ + if (m_root) + { + delete m_root; + InitTree(); + } + + // Create new GTK model + g_object_unref( m_gtk_model ); + m_gtk_model = wxgtk_tree_model_new(); + m_gtk_model->internal = this; + + return true; +} + void wxDataViewCtrlInternal::Resort() { if (!m_wx_model->IsIndexListModel()) @@ -2633,7 +2861,7 @@ bool wxDataViewCtrlInternal::ItemAdded( const wxDataViewItem &parent, const wxDa else parent_node->AddLeave( item.GetID() ); } - + return true; } @@ -2644,7 +2872,7 @@ bool wxDataViewCtrlInternal::ItemDeleted( const wxDataViewItem &parent, const wx wxGtkTreeModelNode *parent_node = FindNode( parent ); parent_node->DeleteChild( item.GetID() ); } - + return true; } @@ -2654,8 +2882,8 @@ bool wxDataViewCtrlInternal::ItemChanged( const wxDataViewItem &item ) event.SetEventObject( m_owner ); event.SetModel( m_owner->GetModel() ); event.SetItem( item ); - m_owner->GetEventHandler()->ProcessEvent( event ); - + m_owner->HandleWindowEvent( event ); + return true; } @@ -2667,16 +2895,13 @@ bool wxDataViewCtrlInternal::ValueChanged( const wxDataViewItem &item, unsigned event.SetColumn( col ); event.SetDataViewColumn( GetOwner()->GetColumn(col) ); event.SetItem( item ); - m_owner->GetEventHandler()->ProcessEvent( event ); - - return true; -} + m_owner->HandleWindowEvent( event ); -bool wxDataViewCtrlInternal::Cleared() -{ return true; } +// GTK+ model iface + GtkTreeModelFlags wxDataViewCtrlInternal::get_flags() { if (m_wx_model->IsIndexListModel()) @@ -2690,10 +2915,10 @@ gboolean wxDataViewCtrlInternal::get_iter( GtkTreeIter *iter, GtkTreePath *path if (m_wx_model->IsIndexListModel()) { wxDataViewIndexListModel *wx_model = (wxDataViewIndexListModel*) m_wx_model; - + unsigned int i = (unsigned int)gtk_tree_path_get_indices (path)[0]; - if (i >= wx_model->GetLastIndex()) + if (i >= wx_model->GetLastIndex() + 1) return FALSE; iter->stamp = m_gtk_model->stamp; @@ -2709,16 +2934,16 @@ gboolean wxDataViewCtrlInternal::get_iter( GtkTreeIter *iter, GtkTreePath *path wxGtkTreeModelNode *node = m_root; int i; - for (i = 0; i < depth; i++) + for (i = 0; i < depth; i++) { BuildBranch( node ); - + gint pos = gtk_tree_path_get_indices (path)[i]; if (pos < 0) return FALSE; if ((size_t)pos >= node->GetChildCount()) return FALSE; - + void* id = node->GetChildren().Item( (size_t) pos ); - + if (i == depth-1) { iter->stamp = m_gtk_model->stamp; @@ -2736,7 +2961,7 @@ gboolean wxDataViewCtrlInternal::get_iter( GtkTreeIter *iter, GtkTreePath *path node = child_node; break; } - } + } } } @@ -2746,7 +2971,7 @@ gboolean wxDataViewCtrlInternal::get_iter( GtkTreeIter *iter, GtkTreePath *path GtkTreePath *wxDataViewCtrlInternal::get_path( GtkTreeIter *iter ) { GtkTreePath *retval = gtk_tree_path_new (); - + if (m_wx_model->IsIndexListModel()) { // user_data is just the index @@ -2755,20 +2980,20 @@ GtkTreePath *wxDataViewCtrlInternal::get_path( GtkTreeIter *iter ) } else { - void *id = iter->user_data; - + void *id = iter->user_data; + wxGtkTreeModelNode *node = FindParentNode( iter ); while (node) { int pos = node->GetChildren().Index( id ); gtk_tree_path_prepend_index( retval, pos ); - + id = node->GetItem().GetID(); node = node->GetParent(); } } - + return retval; } @@ -2777,13 +3002,13 @@ gboolean wxDataViewCtrlInternal::iter_next( GtkTreeIter *iter ) if (m_wx_model->IsIndexListModel()) { wxDataViewIndexListModel *wx_model = (wxDataViewIndexListModel*) m_wx_model; - + int n = (wxUIntPtr) iter->user_data; if (n == -1) return FALSE; - if (n >= (int) wx_model->GetLastIndex()-2) + if (n >= (int) wx_model->GetLastIndex()) return FALSE; iter->user_data = (gpointer) ++n; @@ -2798,7 +3023,7 @@ gboolean wxDataViewCtrlInternal::iter_next( GtkTreeIter *iter ) if (pos == (int) parent->GetChildCount()-1) return FALSE; - + iter->stamp = m_gtk_model->stamp; iter->user_data = parent->GetChildren().Item( pos+1 ); } @@ -2822,20 +3047,20 @@ gboolean wxDataViewCtrlInternal::iter_children( GtkTreeIter *iter, GtkTreeIter * else { wxDataViewItem item( (void*) parent->user_data ); - + if (!m_wx_model->IsContainer( item )) return FALSE; - + wxGtkTreeModelNode *parent_node = FindNode( parent ); BuildBranch( parent_node ); - + if (parent_node->GetChildCount() == 0) return FALSE; - + iter->stamp = m_gtk_model->stamp; iter->user_data = (gpointer) parent_node->GetChildren().Item( 0 ); } - + return TRUE; } @@ -2849,15 +3074,15 @@ gboolean wxDataViewCtrlInternal::iter_has_child( GtkTreeIter *iter ) else { wxDataViewItem item( (void*) iter->user_data ); - + bool is_container = m_wx_model->IsContainer( item ); - + if (!is_container) return FALSE; - + wxGtkTreeModelNode *node = FindNode( iter ); BuildBranch( node ); - + return (node->GetChildCount() > 0); } } @@ -2867,24 +3092,24 @@ gint wxDataViewCtrlInternal::iter_n_children( GtkTreeIter *iter ) if (m_wx_model->IsIndexListModel()) { wxDataViewIndexListModel *wx_model = (wxDataViewIndexListModel*) m_wx_model; - + if (iter == NULL) - return (gint) wx_model->GetLastIndex()-1; + return (gint) wx_model->GetLastIndex() + 1; return 0; } else { wxDataViewItem item( (void*) iter->user_data ); - + if (!m_wx_model->IsContainer( item )) return 0; - + wxGtkTreeModelNode *parent_node = FindNode( iter ); BuildBranch( parent_node ); // wxPrintf( "iter_n_children %d\n", parent_node->GetChildCount() ); - + return parent_node->GetChildCount(); } } @@ -2894,14 +3119,14 @@ gboolean wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter *iter, GtkTreeIter if (m_wx_model->IsIndexListModel()) { wxDataViewIndexListModel *wx_model = (wxDataViewIndexListModel*) m_wx_model; - + if (parent) return FALSE; if (n < 0) return FALSE; - if (n >= (gint) wx_model->GetLastIndex()-1) + if (n >= (gint) wx_model->GetLastIndex() + 1) return FALSE; iter->stamp = m_gtk_model->stamp; @@ -2914,15 +3139,15 @@ gboolean wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter *iter, GtkTreeIter void* id = NULL; if (parent) id = (void*) parent->user_data; wxDataViewItem item( id ); - + if (!m_wx_model->IsContainer( item )) return FALSE; - + wxGtkTreeModelNode *parent_node = FindNode( parent ); BuildBranch( parent_node ); // wxPrintf( "iter_nth_child %d\n", n ); - + iter->stamp = m_gtk_model->stamp; iter->user_data = parent_node->GetChildren().Item( n ); @@ -2941,14 +3166,14 @@ gboolean wxDataViewCtrlInternal::iter_parent( GtkTreeIter *iter, GtkTreeIter *ch wxGtkTreeModelNode *node = FindParentNode( child ); if (!node) return FALSE; - + iter->stamp = m_gtk_model->stamp; iter->user_data = (gpointer) node->GetItem().GetID(); return TRUE; } } - + static wxGtkTreeModelNode* wxDataViewCtrlInternal_FindNode( wxDataViewModel * model, wxGtkTreeModelNode *treeNode, const wxDataViewItem &item ) { @@ -2958,7 +3183,7 @@ wxDataViewCtrlInternal_FindNode( wxDataViewModel * model, wxGtkTreeModelNode *tr ItemList list; list.DeleteContents( true ); wxDataViewItem it( item ); - + while( it.IsOk() ) { wxDataViewItem * pItem = new wxDataViewItem( it ); @@ -2980,7 +3205,7 @@ wxDataViewCtrlInternal_FindNode( wxDataViewModel * model, wxGtkTreeModelNode *tr { node = nodes[j]; break; - } + } } if( j == len ) @@ -3003,16 +3228,16 @@ wxGtkTreeModelNode *wxDataViewCtrlInternal::FindNode( GtkTreeIter *iter ) wxDataViewItem item( (void*) iter->user_data ); if (!item.IsOk()) return m_root; - + wxGtkTreeModelNode *result = wxDataViewCtrlInternal_FindNode( m_wx_model, m_root, item ); - + if (!result) { wxLogDebug( "Not found %p", iter->user_data ); char *crash = NULL; *crash = 0; } - + return result; } @@ -3022,14 +3247,14 @@ wxGtkTreeModelNode *wxDataViewCtrlInternal::FindNode( const wxDataViewItem &item return m_root; wxGtkTreeModelNode *result = wxDataViewCtrlInternal_FindNode( m_wx_model, m_root, item ); - + if (!result) { wxLogDebug( "Not found %p", item.GetID() ); char *crash = NULL; *crash = 0; } - + return result; } @@ -3066,7 +3291,7 @@ wxDataViewCtrlInternal_FindParentNode( wxDataViewModel * model, wxGtkTreeModelNo { node = nodes[j]; break; - } + } } if( j == len ) @@ -3091,7 +3316,7 @@ wxGtkTreeModelNode *wxDataViewCtrlInternal::FindParentNode( GtkTreeIter *iter ) { if (!iter) return NULL; - + wxDataViewItem item( (void*) iter->user_data ); if (!item.IsOk()) return NULL; @@ -3120,7 +3345,7 @@ wxdataview_selection_changed_callback( GtkTreeSelection* selection, wxDataViewCt wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, dv->GetId() ); event.SetItem( dv->GetSelection() ); event.SetModel( dv->GetModel() ); - dv->GetEventHandler()->ProcessEvent( event ); + dv->HandleWindowEvent( event ); } static void @@ -3134,7 +3359,7 @@ wxdataview_row_activated_callback( GtkTreeView* treeview, GtkTreePath *path, wxDataViewItem item( (void*) iter.user_data );; event.SetItem( item ); event.SetModel( dv->GetModel() ); - dv->GetEventHandler()->ProcessEvent( event ); + dv->HandleWindowEvent( event ); } static gboolean @@ -3146,8 +3371,8 @@ wxdataview_test_expand_row_callback( GtkTreeView* treeview, GtkTreeIter* iter, wxDataViewItem item( (void*) iter->user_data );; event.SetItem( item ); event.SetModel( dv->GetModel() ); - dv->GetEventHandler()->ProcessEvent( event ); - + dv->HandleWindowEvent( event ); + return !event.IsAllowed(); } @@ -3160,7 +3385,7 @@ wxdataview_row_expanded_callback( GtkTreeView* treeview, GtkTreeIter* iter, wxDataViewItem item( (void*) iter->user_data );; event.SetItem( item ); event.SetModel( dv->GetModel() ); - dv->GetEventHandler()->ProcessEvent( event ); + dv->HandleWindowEvent( event ); } static gboolean @@ -3172,8 +3397,8 @@ wxdataview_test_collapse_row_callback( GtkTreeView* treeview, GtkTreeIter* iter, wxDataViewItem item( (void*) iter->user_data );; event.SetItem( item ); event.SetModel( dv->GetModel() ); - dv->GetEventHandler()->ProcessEvent( event ); - + dv->HandleWindowEvent( event ); + return !event.IsAllowed(); } @@ -3186,7 +3411,7 @@ wxdataview_row_collapsed_callback( GtkTreeView* treeview, GtkTreeIter* iter, wxDataViewItem item( (void*) iter->user_data );; event.SetItem( item ); event.SetModel( dv->GetModel() ); - dv->GetEventHandler()->ProcessEvent( event ); + dv->HandleWindowEvent( event ); } //----------------------------------------------------------------------------- @@ -3240,8 +3465,8 @@ void gtk_dataviewctrl_size_callback( GtkWidget *WXUNUSED(widget), static gboolean gtk_dataview_motion_notify_callback( GtkWidget *widget, - GdkEventMotion *gdk_event, - wxDataViewCtrl *dv ) + GdkEventMotion *gdk_event, + wxDataViewCtrl *dv ) { if (gdk_event->is_hint) { @@ -3257,7 +3482,7 @@ gtk_dataview_motion_notify_callback( GtkWidget *widget, GtkTreeViewColumn *column = NULL; gint cell_x = 0; gint cell_y = 0; - if (gtk_tree_view_get_path_at_pos( + if (gtk_tree_view_get_path_at_pos( GTK_TREE_VIEW(dv->GtkGetTreeView()), (int) gdk_event->x, (int) gdk_event->y, &path, @@ -3269,9 +3494,9 @@ gtk_dataview_motion_notify_callback( GtkWidget *widget, { GtkTreeIter iter; dv->GtkGetInternal()->get_iter( &iter, path ); - + // wxPrintf( "mouse %d %d\n", (int) gdk_event->x, (int) gdk_event->y ); - + gtk_tree_path_free( path ); } } @@ -3280,6 +3505,47 @@ gtk_dataview_motion_notify_callback( GtkWidget *widget, return FALSE; } +//----------------------------------------------------------------------------- +// "button_press_event" +//----------------------------------------------------------------------------- + +static gboolean +gtk_dataview_button_press_callback( GtkWidget *WXUNUSED(widget), + GdkEventButton *gdk_event, + wxDataViewCtrl *dv ) +{ + if ((gdk_event->button == 3) && (gdk_event->type == GDK_BUTTON_PRESS)) + { + GtkTreePath *path = NULL; + GtkTreeViewColumn *column = NULL; + gint cell_x = 0; + gint cell_y = 0; + if (gtk_tree_view_get_path_at_pos( + GTK_TREE_VIEW(dv->GtkGetTreeView()), + (int) gdk_event->x, (int) gdk_event->y, + &path, + &column, + &cell_x, + &cell_y)) + { + if (path) + { + GtkTreeIter iter; + dv->GtkGetInternal()->get_iter( &iter, path ); + + wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, dv->GetId() ); + wxDataViewItem item( (void*) iter.user_data );; + event.SetItem( item ); + event.SetModel( dv->GetModel() ); + bool ret = dv->HandleWindowEvent( event ); + gtk_tree_path_free( path ); + return ret; + } + } + } + + return FALSE; +} IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl, wxDataViewCtrlBase) @@ -3291,15 +3557,18 @@ wxDataViewCtrl::~wxDataViewCtrl() // remove the model from the GtkTreeView before it gets destroyed by the // wxDataViewCtrlBase's dtor gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview), NULL ); - + delete m_internal; } void wxDataViewCtrl::Init() { m_notifier = NULL; + m_internal = NULL; } +static GtkTargetEntry gs_target; + bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxValidator& validator ) @@ -3325,6 +3594,13 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, g_signal_connect (m_treeview, "size_allocate", G_CALLBACK (gtk_dataviewctrl_size_callback), this); + gs_target.target = "UTF8_STRING"; + gs_target.flags = 0; + gs_target.info = -1; + gtk_tree_view_enable_model_drag_source( GTK_TREE_VIEW(m_treeview), + GDK_BUTTON1_MASK, &gs_target, 1, (GdkDragAction) GDK_ACTION_COPY ); + + #ifdef __WXGTK26__ if (!gtk_check_version(2,6,0)) gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview), TRUE ); @@ -3351,13 +3627,12 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, else if (style & wxDV_HORIZ_RULES) grid = GTK_TREE_VIEW_GRID_LINES_HORIZONTAL; - gtk_tree_view_set_grid_lines( GTK_TREE_VIEW(m_treeview), grid ); + if (grid != GTK_TREE_VIEW_GRID_LINES_NONE) + gtk_tree_view_set_grid_lines( GTK_TREE_VIEW(m_treeview), grid ); } - else #endif - { - gtk_tree_view_set_rules_hint( GTK_TREE_VIEW(m_treeview), (style & wxDV_HORIZ_RULES) != 0 ); - } + + gtk_tree_view_set_rules_hint( GTK_TREE_VIEW(m_treeview), (style & wxDV_ROW_LINES) != 0 ); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); @@ -3380,13 +3655,16 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, 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); g_signal_connect (m_treeview, "motion_notify_event", G_CALLBACK (gtk_dataview_motion_notify_callback), this); + g_signal_connect (m_treeview, "button_press_event", + G_CALLBACK (gtk_dataview_button_press_callback), this); + return true; } @@ -3405,6 +3683,15 @@ void wxDataViewCtrl::OnInternalIdle() bool wxDataViewCtrl::AssociateModel( wxDataViewModel *model ) { + if (GetModel()) + { + delete m_internal; + m_internal = NULL; + + delete m_notifier; + m_notifier = NULL; + } + if (!wxDataViewCtrlBase::AssociateModel( model )) return false; @@ -3417,7 +3704,7 @@ bool wxDataViewCtrl::AssociateModel( wxDataViewModel *model ) model->AddNotifier( m_notifier ); gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview), GTK_TREE_MODEL(gtk_model) ); - + // unref in wxDataViewCtrlInternal // g_object_unref( gtk_model ); @@ -3431,7 +3718,7 @@ bool wxDataViewCtrl::AppendColumn( wxDataViewColumn *col ) m_cols.Append( col ); - gtk_tree_view_append_column( GTK_TREE_VIEW(m_treeview), + gtk_tree_view_append_column( GTK_TREE_VIEW(m_treeview), GTK_TREE_VIEW_COLUMN(col->GetGtkHandle()) ); return true; @@ -3444,7 +3731,7 @@ bool wxDataViewCtrl::PrependColumn( wxDataViewColumn *col ) m_cols.Insert( col ); - gtk_tree_view_insert_column( GTK_TREE_VIEW(m_treeview), + gtk_tree_view_insert_column( GTK_TREE_VIEW(m_treeview), GTK_TREE_VIEW_COLUMN(col->GetGtkHandle()), 0 ); return true; @@ -3460,7 +3747,7 @@ wxDataViewColumn* wxDataViewCtrl::GetColumn( unsigned int pos ) const GtkTreeViewColumn *gtk_col = gtk_tree_view_get_column( GTK_TREE_VIEW(m_treeview), pos ); if (!gtk_col) return NULL; - + wxDataViewColumnList::const_iterator iter; for (iter = m_cols.begin(); iter != m_cols.end(); iter++) { @@ -3470,13 +3757,13 @@ wxDataViewColumn* wxDataViewCtrl::GetColumn( unsigned int pos ) const return col; } } - + return NULL; } bool wxDataViewCtrl::DeleteColumn( wxDataViewColumn *column ) { - gtk_tree_view_remove_column( GTK_TREE_VIEW(m_treeview), + gtk_tree_view_remove_column( GTK_TREE_VIEW(m_treeview), GTK_TREE_VIEW_COLUMN(column->GetGtkHandle()) ); m_cols.remove( column ); @@ -3492,12 +3779,12 @@ bool wxDataViewCtrl::ClearColumns() for (iter = m_cols.begin(); iter != m_cols.end(); iter++) { wxDataViewColumn *col = *iter; - gtk_tree_view_remove_column( GTK_TREE_VIEW(m_treeview), + gtk_tree_view_remove_column( GTK_TREE_VIEW(m_treeview), GTK_TREE_VIEW_COLUMN(col->GetGtkHandle()) ); } - + m_cols.clear(); - + return true; } @@ -3506,9 +3793,9 @@ int wxDataViewCtrl::GetColumnPosition( const wxDataViewColumn *column ) const GtkTreeViewColumn *gtk_column = GTK_TREE_VIEW_COLUMN(column->GetConstGtkHandle()); 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 ); return pos; @@ -3540,23 +3827,23 @@ void wxDataViewCtrl::Collapse( const wxDataViewItem & item ) wxDataViewItem wxDataViewCtrl::GetSelection() 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; 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 ); } } @@ -3569,7 +3856,7 @@ wxDataViewItem wxDataViewCtrl::GetSelection() const return item; } } - + return wxDataViewItem(0); } @@ -3587,7 +3874,7 @@ int wxDataViewCtrl::GetSelections( wxDataViewItemArray & sel ) const while (list) { GtkTreePath *path = (GtkTreePath*) list->data; - + GtkTreeIter iter; m_internal->get_iter( &iter, path ); @@ -3621,11 +3908,11 @@ int wxDataViewCtrl::GetSelections( wxDataViewItemArray & sel ) const 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++) { @@ -3633,7 +3920,7 @@ void wxDataViewCtrl::SetSelections( const wxDataViewItemArray & sel ) iter.user_data = (gpointer) sel[i].GetID(); gtk_tree_selection_select_iter( selection, &iter ); } - + GtkEnableSelectionEvents(); } @@ -3669,29 +3956,29 @@ bool wxDataViewCtrl::IsSelected( const wxDataViewItem & item ) const 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(); } @@ -3704,14 +3991,14 @@ void wxDataViewCtrl::EnsureVisible( const wxDataViewItem & item, const wxDataVie gtk_tree_path_free( path ); } -void wxDataViewCtrl::HitTest( const wxPoint &point, +void wxDataViewCtrl::HitTest( const wxPoint &point, wxDataViewItem &item, wxDataViewColumn *&column ) const { item = wxDataViewItem(0); column = NULL; } -wxRect wxDataViewCtrl::GetItemRect( const wxDataViewItem &item, +wxRect wxDataViewCtrl::GetItemRect( const wxDataViewItem &item, const wxDataViewColumn *column ) const { return wxRect(); @@ -3719,7 +4006,7 @@ wxRect wxDataViewCtrl::GetItemRect( const wxDataViewItem &item, void wxDataViewCtrl::DoSetExpanderColumn() { - gtk_tree_view_set_expander_column( GTK_TREE_VIEW(m_treeview), + gtk_tree_view_set_expander_column( GTK_TREE_VIEW(m_treeview), GTK_TREE_VIEW_COLUMN( GetExpanderColumn()->GetGtkHandle() ) ); }