X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/33ba5a05623023af942a6b34b0758a98b12d4c82..ff58644a54af11b74b8e9b33a00de8496c531566:/src/gtk/dataview.cpp diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp index c8ea7178d3..0ecca2c7f1 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 @@ -58,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); @@ -71,10 +73,17 @@ public: 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 ); @@ -82,6 +91,7 @@ public: bool Cleared(); void Resort(); + // sorting interface void SetSortOrder( GtkSortType sort_order ) { m_sort_order = sort_order; } GtkSortType GetSortOrder() { return m_sort_order; } @@ -93,6 +103,10 @@ public: 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(); @@ -265,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); @@ -300,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; @@ -354,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 ); @@ -363,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; @@ -410,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) { @@ -525,13 +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 ); } @@ -593,16 +660,86 @@ wxgtk_tree_model_iter_parent (GtkTreeModel *tree_model, 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; @@ -612,19 +749,20 @@ gboolean wxgtk_tree_model_get_sort_column_id (GtkTreeSortable *sortabl 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) ); @@ -654,11 +792,12 @@ void wxgtk_tree_model_set_sort_column_id (GtkTreeSortable *sortable, gs_lastLeftClickHeader = NULL; } -void wxgtk_tree_model_set_sort_func (GtkTreeSortable *sortable, - gint WXUNUSED(sort_column_id), - GtkTreeIterCompareFunc func, - gpointer WXUNUSED(data), - GtkDestroyNotify WXUNUSED(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); @@ -678,7 +817,7 @@ void wxgtk_tree_model_set_default_sort_func (GtkTreeSortable *sorta gboolean wxgtk_tree_model_has_default_sort_func (GtkTreeSortable *sortable) { g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (sortable), FALSE ); - + return FALSE; } @@ -941,7 +1080,7 @@ gtk_wx_cell_renderer_render (GtkCellRenderer *renderer, rect.y += cell_area->y; rect.width -= renderer->xpad * 2; rect.height -= renderer->ypad * 2; - + GdkRectangle dummy; if (gdk_rectangle_intersect (expose_area, &rect, &dummy)) { @@ -1033,12 +1172,6 @@ gtk_wx_cell_renderer_activate( if (cell->Activate( renderrect, model, item, model_col )) ret = true; } - if (button_event->button == 3) - { - if (cell->RightClick( pt, renderrect, model, item, model_col )) - ret = true; - } - wxrenderer->last_click = button_event->time; return ret; @@ -1192,14 +1325,14 @@ bool wxGtkDataViewModelNotifier::ValueChanged( const wxDataViewItem &item, unsig bool wxGtkDataViewModelNotifier::Cleared() { 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; } @@ -1279,15 +1412,21 @@ void wxDataViewRenderer::SetMode( wxDataViewCellMode mode ) GtkCellRendererMode gtkMode; switch (mode) { - case wxDATAVIEW_CELL_INERT: - gtkMode = GTK_CELL_RENDERER_MODE_INERT; - break; - case wxDATAVIEW_CELL_ACTIVATABLE: - gtkMode = GTK_CELL_RENDERER_MODE_ACTIVATABLE; - break; - case wxDATAVIEW_CELL_EDITABLE: - gtkMode = GTK_CELL_RENDERER_MODE_EDITABLE; - break; + case wxDATAVIEW_CELL_INERT: + gtkMode = GTK_CELL_RENDERER_MODE_INERT; + break; + + case wxDATAVIEW_CELL_ACTIVATABLE: + gtkMode = GTK_CELL_RENDERER_MODE_ACTIVATABLE; + break; + + case wxDATAVIEW_CELL_EDITABLE: + gtkMode = GTK_CELL_RENDERER_MODE_EDITABLE; + break; + + default: + wxFAIL_MSG( "unknown wxDataViewCellMode value" ); + return; } // This value is most often ignored in GtkTreeView @@ -1307,15 +1446,21 @@ wxDataViewCellMode wxDataViewRenderer::GetMode() const switch (g_value_get_enum(&gvalue)) { - case GTK_CELL_RENDERER_MODE_INERT: - ret = wxDATAVIEW_CELL_INERT; - break; - case GTK_CELL_RENDERER_MODE_ACTIVATABLE: - ret = wxDATAVIEW_CELL_ACTIVATABLE; - break; - case GTK_CELL_RENDERER_MODE_EDITABLE: - ret = wxDATAVIEW_CELL_EDITABLE; - break; + default: + wxFAIL_MSG( "unknown GtkCellRendererMode value" ); + // fall through (we have to return something) + + case GTK_CELL_RENDERER_MODE_INERT: + ret = wxDATAVIEW_CELL_INERT; + break; + + case GTK_CELL_RENDERER_MODE_ACTIVATABLE: + ret = wxDATAVIEW_CELL_ACTIVATABLE; + break; + + case GTK_CELL_RENDERER_MODE_EDITABLE: + ret = wxDATAVIEW_CELL_EDITABLE; + break; } g_value_unset( &gvalue ); @@ -1323,8 +1468,21 @@ wxDataViewCellMode wxDataViewRenderer::GetMode() const return ret; } -void wxDataViewRenderer::SetAlignment( int align ) +void wxDataViewRenderer::GtkUpdateAlignment() { + int align = m_alignment; + + // query alignment from column ? + if (align == -1) + { + // None there yet + if (GetOwner() == NULL) + return; + + align = GetOwner()->GetAlignment(); + align |= wxALIGN_CENTRE_VERTICAL; + } + // horizontal alignment: gfloat xalign = 0.0; @@ -1354,40 +1512,16 @@ void wxDataViewRenderer::SetAlignment( int align ) g_value_unset( &gvalue2 ); } -int wxDataViewRenderer::GetAlignment() const +void wxDataViewRenderer::SetAlignment( int align ) { - int ret = 0; - GValue gvalue; - - // horizontal alignment: - - g_object_get( G_OBJECT(m_renderer), "xalign", &gvalue, NULL ); - float xalign = g_value_get_float( &gvalue ); - if (xalign < 0.5) - ret |= wxALIGN_LEFT; - else if (xalign == 0.5) - ret |= wxALIGN_CENTER_HORIZONTAL; - else - ret |= wxALIGN_RIGHT; - g_value_unset( &gvalue ); - - - // vertical alignment: - - g_object_get( G_OBJECT(m_renderer), "yalign", &gvalue, NULL ); - float yalign = g_value_get_float( &gvalue ); - if (yalign < 0.5) - ret |= wxALIGN_TOP; - else if (yalign == 0.5) - ret |= wxALIGN_CENTER_VERTICAL; - else - ret |= wxALIGN_BOTTOM; - g_value_unset( &gvalue ); - - return ret; + m_alignment = align; + GtkUpdateAlignment(); } - +int wxDataViewRenderer::GetAlignment() const +{ + return m_alignment; +} // --------------------------------------------------------- // wxDataViewTextRenderer @@ -1453,7 +1587,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 ); @@ -1465,7 +1599,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; @@ -1674,7 +1808,7 @@ public: GtkWidget *widget = window->m_treeview; // Set later m_gdkwindow = NULL; - + m_window = window; m_context = window->GtkGetPangoDefaultContext(); @@ -1693,9 +1827,9 @@ class wxDataViewCtrlDC: public wxWindowDC public: wxDataViewCtrlDC( wxDataViewCtrl *window ) : wxWindowDC( new wxDataViewCtrlDCImpl( this, window ) ) - { } + { } }; - + // --------------------------------------------------------- // wxDataViewCustomRenderer @@ -1717,7 +1851,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(); @@ -1732,7 +1867,7 @@ void wxDataViewCustomRenderer::RenderText( const wxString &text, int xoffset, wx 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 ); @@ -1811,7 +1946,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 ); @@ -1854,12 +1989,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; @@ -1946,7 +2081,7 @@ bool wxDataViewDateRenderer::SetValue( const wxVariant &value ) return true; } -bool wxDataViewDateRenderer::GetValue( wxVariant &value ) const +bool wxDataViewDateRenderer::GetValue( wxVariant &WXUNUSED(value) ) const { return false; } @@ -1967,7 +2102,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; @@ -2009,7 +2144,7 @@ bool wxDataViewIconTextRenderer::SetValue( const wxVariant &value ) return true; } -bool wxDataViewIconTextRenderer::GetValue( wxVariant &value ) const +bool wxDataViewIconTextRenderer::GetValue( wxVariant &WXUNUSED(value) ) const { return false; } @@ -2042,12 +2177,14 @@ wxSize wxDataViewIconTextRenderer::GetSize() const return size; } -wxControl* wxDataViewIconTextRenderer::CreateEditorCtrl( wxWindow *parent, wxRect labelRect, const wxVariant &value ) +wxControl* wxDataViewIconTextRenderer::CreateEditorCtrl( + wxWindow *WXUNUSED(parent), wxRect WXUNUSED(labelRect), const wxVariant &WXUNUSED(value) ) { return NULL; } -bool wxDataViewIconTextRenderer::GetValueFromEditorCtrl( wxControl* editor, wxVariant &value ) +bool wxDataViewIconTextRenderer::GetValueFromEditorCtrl( + wxControl* WXUNUSED(editor), wxVariant &WXUNUSED(value) ) { return false; } @@ -2058,7 +2195,7 @@ bool wxDataViewIconTextRenderer::GetValueFromEditorCtrl( wxControl* editor, wxVa static gboolean -gtk_dataview_header_button_press_callback( GtkWidget *widget, +gtk_dataview_header_button_press_callback( GtkWidget *WXUNUSED(widget), GdkEventButton *gdk_event, wxDataViewColumn *column ) { @@ -2068,7 +2205,7 @@ gtk_dataview_header_button_press_callback( GtkWidget *widget, if (gdk_event->button == 1) { gs_lastLeftClickHeader = column; - + wxDataViewCtrl *dv = column->GetOwner(); wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK, dv->GetId() ); event.SetDataViewColumn( column ); @@ -2099,7 +2236,7 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *column, } -static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *column, +static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *WXUNUSED(column), GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, @@ -2114,7 +2251,7 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *column, wxDataViewModel *wx_model = tree_model->internal->GetDataViewModel(); - if (!wx_model->IsIndexListModel()) + if (!wx_model->IsVirtualListModel()) { if (wx_model->IsContainer( item )) @@ -2295,14 +2432,7 @@ void wxDataViewColumn::Init(wxAlignment align, int flags, int width) SetFlags( flags ); SetAlignment( align ); - // NOTE: we prefer not to call SetMinWidth(wxDVC_DEFAULT_MINWIDTH); - // as GTK+ is smart and unless explicitely told, will set the minimal - // width to the title's lenght, which is a better default - - // the GTK_TREE_VIEW_COLUMN_FIXED is required by the "fixed height" mode - // that we use for the wxDataViewCtrl - gtk_tree_view_column_set_fixed_width( column, width < 0 ? wxDVC_DEFAULT_WIDTH : width ); - gtk_tree_view_column_set_sizing( column, GTK_TREE_VIEW_COLUMN_FIXED ); + SetWidth( width ); gtk_tree_view_column_pack_end( column, renderer, TRUE ); @@ -2423,6 +2553,9 @@ void wxDataViewColumn::SetAlignment( wxAlignment align ) xalign = 0.5; gtk_tree_view_column_set_alignment( column, xalign ); + + if (m_renderer && m_renderer->GetAlignment() == -1) + m_renderer->GtkUpdateAlignment(); } wxAlignment wxDataViewColumn::GetAlignment() const @@ -2506,9 +2639,36 @@ int wxDataViewColumn::GetWidth() const void wxDataViewColumn::SetWidth( int width ) { - gtk_tree_view_column_set_fixed_width( GTK_TREE_VIEW_COLUMN(m_column), width ); + if (width < 0) + { +#if 1 + gtk_tree_view_column_set_sizing( GTK_TREE_VIEW_COLUMN(m_column), GTK_TREE_VIEW_COLUMN_FIXED ); + + // TODO find a better calculation + gtk_tree_view_column_set_fixed_width( GTK_TREE_VIEW_COLUMN(m_column), wxDVC_DEFAULT_WIDTH ); +#else + // this is unpractical for large numbers of items and disables + // user resizing, which is totally unexpected + gtk_tree_view_column_set_sizing( GTK_TREE_VIEW_COLUMN(m_column), GTK_TREE_VIEW_COLUMN_AUTOSIZE ); +#endif + } + else + { + gtk_tree_view_column_set_sizing( GTK_TREE_VIEW_COLUMN(m_column), GTK_TREE_VIEW_COLUMN_FIXED ); + + 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 @@ -2584,7 +2744,7 @@ wxDataViewCtrlInternal::wxDataViewCtrlInternal( wxDataViewCtrl *owner, m_sort_column = -1; m_dataview_sort_column = NULL; - if (!m_wx_model->IsIndexListModel()) + if (!m_wx_model->IsVirtualListModel()) InitTree(); } @@ -2622,31 +2782,94 @@ void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode *node ) } } +// 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 *WXUNUSED(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 *WXUNUSED(dest), + GtkSelectionData *WXUNUSED(selection_data)) +{ + return FALSE; +} + +gboolean +wxDataViewCtrlInternal::row_drop_possible(GtkTreeDragDest *WXUNUSED(drag_dest), + GtkTreePath *WXUNUSED(dest_path), + GtkSelectionData *WXUNUSED(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()) + if (!m_wx_model->IsVirtualListModel()) m_root->Resort(); } bool wxDataViewCtrlInternal::ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item ) { - if (!m_wx_model->IsIndexListModel()) + if (!m_wx_model->IsVirtualListModel()) { wxGtkTreeModelNode *parent_node = FindNode( parent ); if (m_wx_model->IsContainer( item )) @@ -2660,7 +2883,7 @@ bool wxDataViewCtrlInternal::ItemAdded( const wxDataViewItem &parent, const wxDa bool wxDataViewCtrlInternal::ItemDeleted( const wxDataViewItem &parent, const wxDataViewItem &item ) { - if (!m_wx_model->IsIndexListModel()) + if (!m_wx_model->IsVirtualListModel()) { wxGtkTreeModelNode *parent_node = FindNode( parent ); parent_node->DeleteChild( item.GetID() ); @@ -2693,9 +2916,11 @@ bool wxDataViewCtrlInternal::ValueChanged( const wxDataViewItem &item, unsigned return true; } +// GTK+ model iface + GtkTreeModelFlags wxDataViewCtrlInternal::get_flags() { - if (m_wx_model->IsIndexListModel()) + if (m_wx_model->IsVirtualListModel()) return GTK_TREE_MODEL_LIST_ONLY; else return GTK_TREE_MODEL_ITERS_PERSIST; @@ -2703,7 +2928,7 @@ GtkTreeModelFlags wxDataViewCtrlInternal::get_flags() gboolean wxDataViewCtrlInternal::get_iter( GtkTreeIter *iter, GtkTreePath *path ) { - if (m_wx_model->IsIndexListModel()) + if (m_wx_model->IsVirtualListModel()) { wxDataViewIndexListModel *wx_model = (wxDataViewIndexListModel*) m_wx_model; @@ -2763,7 +2988,7 @@ GtkTreePath *wxDataViewCtrlInternal::get_path( GtkTreeIter *iter ) { GtkTreePath *retval = gtk_tree_path_new (); - if (m_wx_model->IsIndexListModel()) + if (m_wx_model->IsVirtualListModel()) { // user_data is just the index int i = (wxUIntPtr) iter->user_data; @@ -2790,7 +3015,7 @@ GtkTreePath *wxDataViewCtrlInternal::get_path( GtkTreeIter *iter ) gboolean wxDataViewCtrlInternal::iter_next( GtkTreeIter *iter ) { - if (m_wx_model->IsIndexListModel()) + if (m_wx_model->IsVirtualListModel()) { wxDataViewIndexListModel *wx_model = (wxDataViewIndexListModel*) m_wx_model; @@ -2824,7 +3049,7 @@ gboolean wxDataViewCtrlInternal::iter_next( GtkTreeIter *iter ) gboolean wxDataViewCtrlInternal::iter_children( GtkTreeIter *iter, GtkTreeIter *parent ) { - if (m_wx_model->IsIndexListModel()) + if (m_wx_model->IsVirtualListModel()) { // this is a list, nodes have no children if (parent) @@ -2857,7 +3082,7 @@ gboolean wxDataViewCtrlInternal::iter_children( GtkTreeIter *iter, GtkTreeIter * gboolean wxDataViewCtrlInternal::iter_has_child( GtkTreeIter *iter ) { - if (m_wx_model->IsIndexListModel()) + if (m_wx_model->IsVirtualListModel()) { // this is a list, nodes have no children return FALSE; @@ -2880,7 +3105,7 @@ gboolean wxDataViewCtrlInternal::iter_has_child( GtkTreeIter *iter ) gint wxDataViewCtrlInternal::iter_n_children( GtkTreeIter *iter ) { - if (m_wx_model->IsIndexListModel()) + if (m_wx_model->IsVirtualListModel()) { wxDataViewIndexListModel *wx_model = (wxDataViewIndexListModel*) m_wx_model; @@ -2907,7 +3132,7 @@ gint wxDataViewCtrlInternal::iter_n_children( GtkTreeIter *iter ) gboolean wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter *iter, GtkTreeIter *parent, gint n ) { - if (m_wx_model->IsIndexListModel()) + if (m_wx_model->IsVirtualListModel()) { wxDataViewIndexListModel *wx_model = (wxDataViewIndexListModel*) m_wx_model; @@ -2948,7 +3173,7 @@ gboolean wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter *iter, GtkTreeIter gboolean wxDataViewCtrlInternal::iter_parent( GtkTreeIter *iter, GtkTreeIter *child ) { - if (m_wx_model->IsIndexListModel()) + if (m_wx_model->IsVirtualListModel()) { return FALSE; } @@ -3128,7 +3353,7 @@ wxGtkTreeModelNode *wxDataViewCtrlInternal::FindParentNode( const wxDataViewItem //----------------------------------------------------------------------------- static void -wxdataview_selection_changed_callback( GtkTreeSelection* selection, wxDataViewCtrl *dv ) +wxdataview_selection_changed_callback( GtkTreeSelection* WXUNUSED(selection), wxDataViewCtrl *dv ) { if (!GTK_WIDGET_REALIZED(dv->m_widget)) return; @@ -3140,8 +3365,8 @@ wxdataview_selection_changed_callback( GtkTreeSelection* selection, wxDataViewCt } static void -wxdataview_row_activated_callback( GtkTreeView* treeview, GtkTreePath *path, - GtkTreeViewColumn *column, wxDataViewCtrl *dv ) +wxdataview_row_activated_callback( GtkTreeView* WXUNUSED(treeview), GtkTreePath *path, + GtkTreeViewColumn *WXUNUSED(column), wxDataViewCtrl *dv ) { wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, dv->GetId() ); @@ -3154,8 +3379,8 @@ wxdataview_row_activated_callback( GtkTreeView* treeview, GtkTreePath *path, } static gboolean -wxdataview_test_expand_row_callback( GtkTreeView* treeview, GtkTreeIter* iter, - GtkTreePath *path, wxDataViewCtrl *dv ) +wxdataview_test_expand_row_callback( GtkTreeView* WXUNUSED(treeview), GtkTreeIter* iter, + GtkTreePath *WXUNUSED(path), wxDataViewCtrl *dv ) { wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDING, dv->GetId() ); @@ -3168,8 +3393,8 @@ wxdataview_test_expand_row_callback( GtkTreeView* treeview, GtkTreeIter* iter, } static void -wxdataview_row_expanded_callback( GtkTreeView* treeview, GtkTreeIter* iter, - GtkTreePath *path, wxDataViewCtrl *dv ) +wxdataview_row_expanded_callback( GtkTreeView* WXUNUSED(treeview), GtkTreeIter* iter, + GtkTreePath *WXUNUSED(path), wxDataViewCtrl *dv ) { wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_EXPANDED, dv->GetId() ); @@ -3180,8 +3405,8 @@ wxdataview_row_expanded_callback( GtkTreeView* treeview, GtkTreeIter* iter, } static gboolean -wxdataview_test_collapse_row_callback( GtkTreeView* treeview, GtkTreeIter* iter, - GtkTreePath *path, wxDataViewCtrl *dv ) +wxdataview_test_collapse_row_callback( GtkTreeView* WXUNUSED(treeview), GtkTreeIter* iter, + GtkTreePath *WXUNUSED(path), wxDataViewCtrl *dv ) { wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSING, dv->GetId() ); @@ -3194,8 +3419,8 @@ wxdataview_test_collapse_row_callback( GtkTreeView* treeview, GtkTreeIter* iter, } static void -wxdataview_row_collapsed_callback( GtkTreeView* treeview, GtkTreeIter* iter, - GtkTreePath *path, wxDataViewCtrl *dv ) +wxdataview_row_collapsed_callback( GtkTreeView* WXUNUSED(treeview), GtkTreeIter* iter, + GtkTreePath *WXUNUSED(path), wxDataViewCtrl *dv ) { wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_COLLAPSED, dv->GetId() ); @@ -3227,7 +3452,7 @@ static void wxInsertChildInDataViewCtrl( wxWindowGTK* parent, wxWindowGTK* child static void gtk_dataviewctrl_size_callback( GtkWidget *WXUNUSED(widget), - GtkAllocation *alloc, + GtkAllocation *WXUNUSED(gtk_alloc), wxDataViewCtrl *win ) { wxWindowList::compatibility_iterator node = win->GetChildren().GetFirst(); @@ -3255,7 +3480,7 @@ void gtk_dataviewctrl_size_callback( GtkWidget *WXUNUSED(widget), //----------------------------------------------------------------------------- static gboolean -gtk_dataview_motion_notify_callback( GtkWidget *widget, +gtk_dataview_motion_notify_callback( GtkWidget *WXUNUSED(widget), GdkEventMotion *gdk_event, wxDataViewCtrl *dv ) { @@ -3358,6 +3583,8 @@ void wxDataViewCtrl::Init() 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 ) @@ -3383,6 +3610,12 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, g_signal_connect (m_treeview, "size_allocate", G_CALLBACK (gtk_dataviewctrl_size_callback), this); + gs_target.target = const_cast("UTF8_STRING"); + gs_target.flags = 0; + gs_target.info = static_cast(-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 ); @@ -3446,7 +3679,7 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id, g_signal_connect (m_treeview, "button_press_event", G_CALLBACK (gtk_dataview_button_press_callback), this); - + return true; } @@ -3469,11 +3702,11 @@ bool wxDataViewCtrl::AssociateModel( wxDataViewModel *model ) { delete m_internal; m_internal = NULL; - + delete m_notifier; m_notifier = NULL; } - + if (!wxDataViewCtrlBase::AssociateModel( model )) return false; @@ -3500,6 +3733,15 @@ bool wxDataViewCtrl::AppendColumn( wxDataViewColumn *col ) m_cols.Append( col ); +#ifdef __WXGTK26__ + if (!gtk_check_version(2,6,0)) + { + if (gtk_tree_view_column_get_sizing( GTK_TREE_VIEW_COLUMN(col->GetGtkHandle()) ) != + GTK_TREE_VIEW_COLUMN_FIXED) + gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview), FALSE ); + } +#endif + gtk_tree_view_append_column( GTK_TREE_VIEW(m_treeview), GTK_TREE_VIEW_COLUMN(col->GetGtkHandle()) ); @@ -3513,6 +3755,15 @@ bool wxDataViewCtrl::PrependColumn( wxDataViewColumn *col ) m_cols.Insert( col ); +#ifdef __WXGTK26__ + if (!gtk_check_version(2,6,0)) + { + if (gtk_tree_view_column_get_sizing( GTK_TREE_VIEW_COLUMN(col->GetGtkHandle()) ) != + GTK_TREE_VIEW_COLUMN_FIXED) + gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview), FALSE ); + } +#endif + gtk_tree_view_insert_column( GTK_TREE_VIEW(m_treeview), GTK_TREE_VIEW_COLUMN(col->GetGtkHandle()), 0 ); @@ -3764,7 +4015,8 @@ void wxDataViewCtrl::UnselectAll() GtkEnableSelectionEvents(); } -void wxDataViewCtrl::EnsureVisible( const wxDataViewItem & item, const wxDataViewColumn *column ) +void wxDataViewCtrl::EnsureVisible(const wxDataViewItem& item, + const wxDataViewColumn *WXUNUSED(column)) { GtkTreeIter iter; iter.user_data = (gpointer) item.GetID(); @@ -3773,15 +4025,17 @@ void wxDataViewCtrl::EnsureVisible( const wxDataViewItem & item, const wxDataVie gtk_tree_path_free( path ); } -void wxDataViewCtrl::HitTest( const wxPoint &point, - wxDataViewItem &item, wxDataViewColumn *&column ) const +void wxDataViewCtrl::HitTest(const wxPoint& WXUNUSED(point), + wxDataViewItem& item, + wxDataViewColumn *& column) const { item = wxDataViewItem(0); column = NULL; } -wxRect wxDataViewCtrl::GetItemRect( const wxDataViewItem &item, - const wxDataViewColumn *column ) const +wxRect +wxDataViewCtrl::GetItemRect(const wxDataViewItem& WXUNUSED(item), + const wxDataViewColumn *WXUNUSED(column)) const { return wxRect(); }