X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/fc55eaa0be28743fdfc5b570451078d87cc76229..4a699e3a59b19c21b6faae714b56cac5a75df2e2:/src/gtk/dataview.cpp diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp index 12fc302973..8a6dba495a 100644 --- a/src/gtk/dataview.cpp +++ b/src/gtk/dataview.cpp @@ -25,7 +25,6 @@ #endif #include "wx/stockitem.h" -#include "wx/calctrl.h" #include "wx/popupwin.h" #include "wx/listimpl.cpp" @@ -35,6 +34,7 @@ #include "wx/gtk/private/gdkconv.h" #include "wx/gtk/private/list.h" +#include "wx/gtk/private/event.h" using namespace wxGTKImpl; class wxGtkDataViewModelNotifier; @@ -268,7 +268,15 @@ public: void SetDataViewSortColumn( wxDataViewColumn *column ) { m_dataview_sort_column = column; } wxDataViewColumn *GetDataViewSortColumn() { return m_dataview_sort_column; } - bool IsSorted() { return (m_sort_column >= 0); } + bool IsSorted() const { return m_sort_column >= 0; } + + // Should we be sorted either because we have a configured sort column or + // because we have a default sort order? + bool ShouldBeSorted() const + { + return IsSorted() || GetDataViewModel()->HasDefaultCompare(); + } + // accessors wxDataViewModel* GetDataViewModel() { return m_wx_model; } @@ -279,7 +287,7 @@ public: // item can be deleted already in the model int GetIndexOf( const wxDataViewItem &parent, const wxDataViewItem &item ); - virtual void OnInternalIdle(); + void OnInternalIdle(); protected: void InitTree(); @@ -360,7 +368,7 @@ public: m_children.Add( id ); - if (m_internal->IsSorted() || m_internal->GetDataViewModel()->HasDefaultCompare()) + if (m_internal->ShouldBeSorted()) { gs_internal = m_internal; m_children.Sort( &wxGtkTreeModelChildCmp ); @@ -369,7 +377,7 @@ public: void InsertNode( wxGtkTreeModelNode* child, unsigned pos ) { - if (m_internal->IsSorted() || m_internal->GetDataViewModel()->HasDefaultCompare()) + if (m_internal->ShouldBeSorted()) { AddNode(child); return; @@ -407,7 +415,7 @@ public: { m_children.Insert( id, pos ); - if (m_internal->IsSorted() || m_internal->GetDataViewModel()->HasDefaultCompare()) + if (m_internal->ShouldBeSorted()) { gs_internal = m_internal; m_children.Sort( &wxGtkTreeModelChildCmp ); @@ -432,6 +440,20 @@ public: } } + // returns position of child node for given item in children list or wxNOT_FOUND + int FindChildByItem(const wxDataViewItem& item) const + { + const void* itemId = item.GetID(); + const wxGtkTreeModelChildren& nodes = m_children; + const int len = nodes.size(); + for ( int i = 0; i < len; i++ ) + { + if ( nodes[i] == itemId ) + return i; + } + return wxNOT_FOUND; + } + wxGtkTreeModelNode* GetParent() { return m_parent; } wxGtkTreeModelNodes &GetNodes() @@ -470,15 +492,11 @@ extern "C" { #define GTK_TYPE_WX_TREE_MODEL (gtk_wx_tree_model_get_type ()) #define GTK_WX_TREE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModel)) -#define GTK_WX_TREE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModelClass)) #define GTK_IS_WX_TREE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_TREE_MODEL)) #define GTK_IS_WX_TREE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_TREE_MODEL)) -#define GTK_WX_TREE_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModelClass)) GType gtk_wx_tree_model_get_type (void); -typedef struct _GtkWxTreeModelClass GtkWxTreeModelClass; - struct _GtkWxTreeModel { GObject parent; @@ -488,21 +506,14 @@ struct _GtkWxTreeModel wxDataViewCtrlInternal *internal; }; -struct _GtkWxTreeModelClass -{ - GObjectClass list_parent_class; -}; - 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_init (GTypeInstance* instance, void*); -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_tree_model_init (void* g_iface, void*); +static void wxgtk_tree_model_sortable_init (void* g_iface, void*); +static void wxgtk_tree_model_drag_source_init(void* g_iface, void*); +static void wxgtk_tree_model_drag_dest_init (void* g_iface, void*); -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); static GType wxgtk_tree_model_get_column_type (GtkTreeModel *tree_model, @@ -566,9 +577,6 @@ static gboolean wxgtk_tree_model_row_drop_possible (GtkTreeDragDest *d GtkTreePath *dest_path, GtkSelectionData *selection_data); - -static GObjectClass *list_parent_class = NULL; - GType gtk_wx_tree_model_get_type (void) { @@ -578,41 +586,41 @@ gtk_wx_tree_model_get_type (void) { const GTypeInfo tree_model_info = { - sizeof (GtkWxTreeModelClass), + sizeof (GObjectClass), NULL, /* base_init */ NULL, /* base_finalize */ - (GClassInitFunc) wxgtk_tree_model_class_init, + NULL, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (GtkWxTreeModel), 0, - (GInstanceInitFunc) wxgtk_tree_model_init, + wxgtk_tree_model_init, }; static const GInterfaceInfo tree_model_iface_info = { - (GInterfaceInitFunc) wxgtk_tree_model_tree_model_init, + wxgtk_tree_model_tree_model_init, NULL, NULL }; static const GInterfaceInfo sortable_iface_info = { - (GInterfaceInitFunc) wxgtk_tree_model_sortable_init, + wxgtk_tree_model_sortable_init, NULL, NULL }; static const GInterfaceInfo drag_source_iface_info = { - (GInterfaceInitFunc) wxgtk_tree_model_drag_source_init, + wxgtk_tree_model_drag_source_init, NULL, NULL }; static const GInterfaceInfo drag_dest_iface_info = { - (GInterfaceInitFunc) wxgtk_tree_model_drag_dest_init, + wxgtk_tree_model_drag_dest_init, NULL, NULL }; @@ -645,16 +653,9 @@ wxgtk_tree_model_new(void) } static void -wxgtk_tree_model_class_init (GtkWxTreeModelClass *klass) -{ - list_parent_class = (GObjectClass*) g_type_class_peek_parent (klass); - GObjectClass *object_class = (GObjectClass*) klass; - object_class->finalize = wxgtk_tree_model_finalize; -} - -static void -wxgtk_tree_model_tree_model_init (GtkTreeModelIface *iface) +wxgtk_tree_model_tree_model_init(void* g_iface, void*) { + GtkTreeModelIface* iface = static_cast(g_iface); iface->get_flags = wxgtk_tree_model_get_flags; iface->get_n_columns = wxgtk_tree_model_get_n_columns; iface->get_column_type = wxgtk_tree_model_get_column_type; @@ -670,8 +671,9 @@ wxgtk_tree_model_tree_model_init (GtkTreeModelIface *iface) } static void -wxgtk_tree_model_sortable_init (GtkTreeSortableIface *iface) +wxgtk_tree_model_sortable_init(void* g_iface, void*) { + GtkTreeSortableIface* iface = static_cast(g_iface); iface->get_sort_column_id = wxgtk_tree_model_get_sort_column_id; iface->set_sort_column_id = wxgtk_tree_model_set_sort_column_id; iface->set_sort_func = wxgtk_tree_model_set_sort_func; @@ -680,34 +682,30 @@ wxgtk_tree_model_sortable_init (GtkTreeSortableIface *iface) } static void -wxgtk_tree_model_drag_source_init(GtkTreeDragSourceIface *iface) +wxgtk_tree_model_drag_source_init(void* g_iface, void*) { + GtkTreeDragSourceIface* iface = static_cast(g_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) +wxgtk_tree_model_drag_dest_init(void* g_iface, void*) { + GtkTreeDragDestIface* iface = static_cast(g_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) +wxgtk_tree_model_init(GTypeInstance* instance, void*) { + GtkWxTreeModel* tree_model = GTK_WX_TREE_MODEL(instance); tree_model->internal = NULL; tree_model->stamp = g_random_int(); } -static void -wxgtk_tree_model_finalize (GObject *object) -{ - /* must chain up */ - (* list_parent_class->finalize) (object); -} - } // extern "C" //----------------------------------------------------------------------------- @@ -1052,15 +1050,12 @@ extern "C" { #define GTK_TYPE_WX_CELL_RENDERER_TEXT (gtk_wx_cell_renderer_text_get_type ()) #define GTK_WX_CELL_RENDERER_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_CELL_RENDERER_TEXT, GtkWxCellRendererText)) -#define GTK_WX_CELL_RENDERER_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_CELL_RENDERER_TEXT, GtkWxCellRendererTextClass)) #define GTK_IS_WX_CELL_RENDERER_TEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_CELL_RENDERER_TEXT)) #define GTK_IS_WX_CELL_RENDERER_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_CELL_RENDERER_TEXT)) -#define GTK_WX_CELL_RENDERER_TEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_CELL_RENDERER_TEXT, GtkWxCellRendererTextClass)) GType gtk_wx_cell_renderer_text_get_type (void); typedef struct _GtkWxCellRendererText GtkWxCellRendererText; -typedef struct _GtkWxCellRendererTextClass GtkWxCellRendererTextClass; struct _GtkWxCellRendererText { @@ -1069,19 +1064,11 @@ struct _GtkWxCellRendererText wxDataViewRenderer *wx_renderer; }; -struct _GtkWxCellRendererTextClass -{ - GtkCellRendererTextClass cell_parent_class; -}; - - static GtkWxCellRendererText *gtk_wx_cell_renderer_text_new (void); static void gtk_wx_cell_renderer_text_init ( - GtkWxCellRendererText *cell ); + GTypeInstance* instance, void*); static void gtk_wx_cell_renderer_text_class_init( - GtkWxCellRendererTextClass *klass ); -static void gtk_wx_cell_renderer_text_finalize ( - GObject *object ); + void* klass, void*); static GtkCellEditable *gtk_wx_cell_renderer_text_start_editing( GtkCellRenderer *cell, GdkEvent *event, @@ -1105,15 +1092,15 @@ gtk_wx_cell_renderer_text_get_type (void) { const GTypeInfo cell_wx_info = { - sizeof (GtkWxCellRendererTextClass), + sizeof (GtkCellRendererTextClass), NULL, /* base_init */ NULL, /* base_finalize */ - (GClassInitFunc) gtk_wx_cell_renderer_text_class_init, + gtk_wx_cell_renderer_text_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (GtkWxCellRendererText), 0, /* n_preallocs */ - (GInstanceInitFunc) gtk_wx_cell_renderer_text_init, + gtk_wx_cell_renderer_text_init, }; cell_wx_type = g_type_register_static( GTK_TYPE_CELL_RENDERER_TEXT, @@ -1124,31 +1111,22 @@ gtk_wx_cell_renderer_text_get_type (void) } static void -gtk_wx_cell_renderer_text_init (GtkWxCellRendererText *cell) +gtk_wx_cell_renderer_text_init(GTypeInstance* instance, void*) { + GtkWxCellRendererText* cell = GTK_WX_CELL_RENDERER_TEXT(instance); cell->wx_renderer = NULL; } static void -gtk_wx_cell_renderer_text_class_init (GtkWxCellRendererTextClass *klass) +gtk_wx_cell_renderer_text_class_init(void* klass, void*) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (klass); text_cell_parent_class = (GObjectClass*) g_type_class_peek_parent (klass); - object_class->finalize = gtk_wx_cell_renderer_text_finalize; - cell_class->start_editing = gtk_wx_cell_renderer_text_start_editing; } -static void -gtk_wx_cell_renderer_text_finalize (GObject *object) -{ - /* must chain up */ - (* G_OBJECT_CLASS (text_cell_parent_class)->finalize) (object); -} - GtkWxCellRendererText* gtk_wx_cell_renderer_text_new (void) { @@ -1194,15 +1172,12 @@ extern "C" { #define GTK_TYPE_WX_CELL_RENDERER (gtk_wx_cell_renderer_get_type ()) #define GTK_WX_CELL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRenderer)) -#define GTK_WX_CELL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass)) #define GTK_IS_WX_CELL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_CELL_RENDERER)) #define GTK_IS_WX_CELL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_CELL_RENDERER)) -#define GTK_WX_CELL_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass)) GType gtk_wx_cell_renderer_get_type (void); typedef struct _GtkWxCellRenderer GtkWxCellRenderer; -typedef struct _GtkWxCellRendererClass GtkWxCellRendererClass; struct _GtkWxCellRenderer { @@ -1210,22 +1185,13 @@ struct _GtkWxCellRenderer /*< private >*/ wxDataViewCustomRenderer *cell; - guint32 last_click; }; -struct _GtkWxCellRendererClass -{ - GtkCellRendererClass cell_parent_class; -}; - - static GtkCellRenderer *gtk_wx_cell_renderer_new (void); static void gtk_wx_cell_renderer_init ( - GtkWxCellRenderer *cell ); + GTypeInstance* instance, void*); static void gtk_wx_cell_renderer_class_init( - GtkWxCellRendererClass *klass ); -static void gtk_wx_cell_renderer_finalize ( - GObject *object ); + void* klass, void*); static void gtk_wx_cell_renderer_get_size ( GtkCellRenderer *cell, GtkWidget *widget, @@ -1259,9 +1225,6 @@ static GtkCellEditable *gtk_wx_cell_renderer_start_editing( GdkRectangle *cell_area, GtkCellRendererState flags ); - -static GObjectClass *cell_parent_class = NULL; - } // extern "C" GType @@ -1273,15 +1236,15 @@ gtk_wx_cell_renderer_get_type (void) { const GTypeInfo cell_wx_info = { - sizeof (GtkWxCellRendererClass), + sizeof (GtkCellRendererClass), NULL, /* base_init */ NULL, /* base_finalize */ - (GClassInitFunc) gtk_wx_cell_renderer_class_init, + gtk_wx_cell_renderer_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (GtkWxCellRenderer), 0, /* n_preallocs */ - (GInstanceInitFunc) gtk_wx_cell_renderer_init, + gtk_wx_cell_renderer_init, }; cell_wx_type = g_type_register_static( GTK_TYPE_CELL_RENDERER, @@ -1292,35 +1255,23 @@ gtk_wx_cell_renderer_get_type (void) } static void -gtk_wx_cell_renderer_init (GtkWxCellRenderer *cell) +gtk_wx_cell_renderer_init(GTypeInstance* instance, void*) { + GtkWxCellRenderer* cell = GTK_WX_CELL_RENDERER(instance); cell->cell = NULL; - cell->last_click = 0; } static void -gtk_wx_cell_renderer_class_init (GtkWxCellRendererClass *klass) +gtk_wx_cell_renderer_class_init(void* klass, void*) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (klass); - cell_parent_class = (GObjectClass*) g_type_class_peek_parent (klass); - - object_class->finalize = gtk_wx_cell_renderer_finalize; - cell_class->get_size = gtk_wx_cell_renderer_get_size; cell_class->render = gtk_wx_cell_renderer_render; cell_class->activate = gtk_wx_cell_renderer_activate; cell_class->start_editing = gtk_wx_cell_renderer_start_editing; } -static void -gtk_wx_cell_renderer_finalize (GObject *object) -{ - /* must chain up */ - (* G_OBJECT_CLASS (cell_parent_class)->finalize) (object); -} - GtkCellRenderer* gtk_wx_cell_renderer_new (void) { @@ -1428,6 +1379,15 @@ gtk_wx_cell_renderer_get_size (GtkCellRenderer *renderer, *height = calc_height; } +struct wxDataViewCustomRenderer::GTKRenderParams +{ + GdkWindow* window; + GdkRectangle* expose_area; + GtkWidget* widget; + GdkRectangle* background_area; + int flags; +}; + static void gtk_wx_cell_renderer_render (GtkCellRenderer *renderer, GdkWindow *window, @@ -1441,8 +1401,13 @@ gtk_wx_cell_renderer_render (GtkCellRenderer *renderer, GtkWxCellRenderer *wxrenderer = (GtkWxCellRenderer *) renderer; wxDataViewCustomRenderer *cell = wxrenderer->cell; - cell->GTKStashRenderParams(window, widget, - background_area, expose_area, flags); + wxDataViewCustomRenderer::GTKRenderParams renderParams; + renderParams.window = window; + renderParams.expose_area = expose_area; + renderParams.widget = widget; + renderParams.background_area = background_area; + renderParams.flags = flags; + cell->GTKSetRenderParams(&renderParams); wxRect rect(wxRectFromGDKRect(cell_area)); int xpad, ypad; @@ -1473,6 +1438,8 @@ gtk_wx_cell_renderer_render (GtkCellRenderer *renderer, if (flags & GTK_CELL_RENDERER_FOCUSED) state |= wxDATAVIEW_CELL_FOCUSED; cell->WXCallRender( rect, dc, state ); + + cell->GTKSetRenderParams(NULL); } static gboolean @@ -1511,37 +1478,27 @@ gtk_wx_cell_renderer_activate( unsigned int model_col = cell->GetOwner()->GetModelColumn(); - if (!event) + if ( !event ) { - bool ret = false; - // activated by - if (cell->Activate( renderrect, model, item, model_col )) - ret = true; - - return ret; + return cell->ActivateCell(renderrect, model, item, model_col, NULL); } - else if (event->type == GDK_BUTTON_PRESS) + else if ( event->type == GDK_BUTTON_PRESS ) { - GdkEventButton *button_event = (GdkEventButton*) event; - wxPoint pt( ((int) button_event->x) - renderrect.x, - ((int) button_event->y) - renderrect.y ); - - bool ret = false; - if (button_event->button == 1) + GdkEventButton *button_event = (GdkEventButton*)event; + if ( button_event->button == 1 ) { - if (cell->LeftClick( pt, renderrect, model, item, model_col )) - ret = true; - // TODO: query system double-click time - if (button_event->time - wxrenderer->last_click < 400) - if (cell->Activate( renderrect, model, item, model_col )) - ret = true; - } - wxrenderer->last_click = button_event->time; + wxMouseEvent mouse_event(wxEVT_LEFT_DOWN); + InitMouseEvent(ctrl, mouse_event, button_event); + + mouse_event.m_x -= renderrect.x; + mouse_event.m_y -= renderrect.y; - return ret; + return cell->ActivateCell(renderrect, model, item, model_col, &mouse_event); + } } + wxLogDebug("unexpected event type in gtk_wx_cell_renderer_activate()"); return false; } @@ -2300,12 +2257,10 @@ static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle *renderer, GValue gvalue = { 0, }; g_value_init( &gvalue, G_TYPE_BOOLEAN ); g_object_get_property( G_OBJECT(renderer), "active", &gvalue ); - bool tmp = g_value_get_boolean( &gvalue ); - g_value_unset( &gvalue ); // invert it - tmp = !tmp; + wxVariant value = !g_value_get_boolean( &gvalue ); + g_value_unset( &gvalue ); - wxVariant value = tmp; if (!cell->Validate( value )) return; @@ -2363,11 +2318,9 @@ bool wxDataViewToggleRenderer::GetValue( wxVariant &value ) const GValue gvalue = { 0, }; g_value_init( &gvalue, G_TYPE_BOOLEAN ); g_object_get_property( G_OBJECT(m_renderer), "active", &gvalue ); - bool tmp = g_value_get_boolean( &gvalue ); + value = g_value_get_boolean( &gvalue ) != 0; g_value_unset( &gvalue ); - value = tmp; - return true; } @@ -2421,6 +2374,7 @@ wxDataViewCustomRenderer::wxDataViewCustomRenderer( const wxString &varianttype, { m_dc = NULL; m_text_renderer = NULL; + m_renderParams = NULL; if (no_init) m_renderer = NULL; @@ -2470,12 +2424,12 @@ void wxDataViewCustomRenderer::RenderText( const wxString &text, cell_area.width -= xoffset; gtk_cell_renderer_render( GTK_CELL_RENDERER(textRenderer), - m_renderParams.window, - m_renderParams.widget, - m_renderParams.background_area, + m_renderParams->window, + m_renderParams->widget, + m_renderParams->background_area, &cell_area, - m_renderParams.expose_area, - (GtkCellRendererState) m_renderParams.flags ); + m_renderParams->expose_area, + GtkCellRendererState(m_renderParams->flags)); } bool wxDataViewCustomRenderer::Init(wxDataViewCellMode mode, int align) @@ -2568,11 +2522,13 @@ void wxDataViewProgressRenderer::GTKSetLabel() // Take care to not use GetOwner() here if the label is empty, we can be // called from ctor when GetOwner() is still NULL in this case. - g_value_set_string( &gvalue, - m_label.empty() ? "" - : wxGTK_CONV_FONT(m_label, - GetOwner()->GetOwner()->GetFont()) - ); + wxScopedCharBuffer buf; + if ( m_label.empty() ) + buf = wxScopedCharBuffer::CreateNonOwned(""); + else + buf = wxGTK_CONV_FONT(m_label, GetOwner()->GetOwner()->GetFont()); + + g_value_set_string( &gvalue, buf); g_object_set_property( G_OBJECT(m_renderer), "text", &gvalue ); g_value_unset( &gvalue ); @@ -2665,7 +2621,7 @@ wxDataViewChoiceRenderer::wxDataViewChoiceRenderer( const wxArrayString &choices "has-entry", FALSE, NULL); - bool editable = (mode & wxDATAVIEW_CELL_EDITABLE); + bool editable = (mode & wxDATAVIEW_CELL_EDITABLE) != 0; g_object_set (m_renderer, "editable", editable, NULL); SetAlignment(alignment); @@ -2797,108 +2753,6 @@ bool wxDataViewChoiceByIndexRenderer::GetValue( wxVariant &value ) const return true; } -// --------------------------------------------------------- -// wxDataViewDateRenderer -// --------------------------------------------------------- - -class wxDataViewDateRendererPopupTransient: public wxPopupTransientWindow -{ -public: - wxDataViewDateRendererPopupTransient( wxWindow* parent, wxDateTime *value, - wxDataViewModel *model, const wxDataViewItem &item, unsigned int col ) : - wxPopupTransientWindow( parent, wxBORDER_SIMPLE ) - { - m_model = model; - m_item = item; - m_col = col; - m_cal = new wxCalendarCtrl( this, -1, *value ); - wxBoxSizer *sizer = new wxBoxSizer( wxHORIZONTAL ); - sizer->Add( m_cal, 1, wxGROW ); - SetSizer( sizer ); - sizer->Fit( this ); - } - - virtual void OnDismiss() - { - } - - void OnCalendar( wxCalendarEvent &event ); - - wxCalendarCtrl *m_cal; - wxDataViewModel *m_model; - wxDataViewItem m_item; - unsigned int m_col; - -private: - DECLARE_EVENT_TABLE() -}; - -BEGIN_EVENT_TABLE(wxDataViewDateRendererPopupTransient,wxPopupTransientWindow) - EVT_CALENDAR( -1, wxDataViewDateRendererPopupTransient::OnCalendar ) -END_EVENT_TABLE() - -void wxDataViewDateRendererPopupTransient::OnCalendar( wxCalendarEvent &event ) -{ - m_model->ChangeValue( event.GetDate(), m_item, m_col ); - DismissAndNotify(); -} - -IMPLEMENT_CLASS(wxDataViewDateRenderer, wxDataViewCustomRenderer) - -wxDataViewDateRenderer::wxDataViewDateRenderer( const wxString &varianttype, - wxDataViewCellMode mode, int align ) : - wxDataViewCustomRenderer( varianttype, mode, align ) -{ - SetMode(mode); - SetAlignment(align); -} - -bool wxDataViewDateRenderer::SetValue( const wxVariant &value ) -{ - m_date = value.GetDateTime(); - - return true; -} - -bool wxDataViewDateRenderer::GetValue( wxVariant &WXUNUSED(value) ) const -{ - return false; -} - -bool wxDataViewDateRenderer::Render( wxRect cell, wxDC *dc, int state ) -{ - dc->SetFont( GetOwner()->GetOwner()->GetFont() ); - wxString tmp = m_date.FormatDate(); - RenderText( tmp, 0, cell, dc, state ); - return true; -} - -wxSize wxDataViewDateRenderer::GetSize() const -{ - wxString tmp = m_date.FormatDate(); - wxCoord x,y,d; - GetView()->GetTextExtent( tmp, &x, &y, &d ); - return wxSize(x,y+d); -} - -bool wxDataViewDateRenderer::Activate( const wxRect& WXUNUSED(cell), wxDataViewModel *model, - const wxDataViewItem &item, unsigned int col ) -{ - wxVariant variant; - model->GetValue( variant, item, col ); - wxDateTime value = variant.GetDateTime(); - - wxDataViewDateRendererPopupTransient *popup = new wxDataViewDateRendererPopupTransient( - GetOwner()->GetOwner()->GetParent(), &value, model, item, col ); - wxPoint pos = wxGetMousePosition(); - popup->Move( pos ); - popup->Layout(); - popup->Popup( popup->m_cal ); - - return true; -} - - // --------------------------------------------------------- // wxDataViewIconTextRenderer // --------------------------------------------------------- @@ -2934,7 +2788,9 @@ bool wxDataViewIconTextRenderer::SetValue( const wxVariant &value ) m_value << value; SetTextValue(m_value.GetText()); - SetPixbufProp(m_rendererIcon, m_value.GetIcon().GetPixbuf()); + + const wxIcon& icon = m_value.GetIcon(); + SetPixbufProp(m_rendererIcon, icon.IsOk() ? icon.GetPixbuf() : NULL); return true; } @@ -3283,19 +3139,19 @@ void wxDataViewColumn::SetSortable( bool sortable ) bool wxDataViewColumn::IsSortable() const { GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN(m_column); - return gtk_tree_view_column_get_clickable( column ); + return gtk_tree_view_column_get_clickable( column ) != 0; } bool wxDataViewColumn::IsSortKey() const { GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN(m_column); - return gtk_tree_view_column_get_sort_indicator( column ); + return gtk_tree_view_column_get_sort_indicator( column ) != 0; } bool wxDataViewColumn::IsResizeable() const { GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN(m_column); - return gtk_tree_view_column_get_resizable( column ); + return gtk_tree_view_column_get_resizable( column ) != 0; } bool wxDataViewColumn::IsHidden() const @@ -3365,7 +3221,7 @@ void wxDataViewColumn::SetReorderable( bool reorderable ) bool wxDataViewColumn::IsReorderable() const { - return gtk_tree_view_column_get_reorderable( GTK_TREE_VIEW_COLUMN(m_column) ); + return gtk_tree_view_column_get_reorderable( GTK_TREE_VIEW_COLUMN(m_column) ) != 0; } //----------------------------------------------------------------------------- @@ -3744,6 +3600,7 @@ wxDataViewCtrlInternal::row_drop_possible(GtkTreeDragDest *WXUNUSED(drag_dest), event.SetItem( item ); event.SetModel( m_wx_model ); event.SetDataFormat(gtk_selection_data_get_target(selection_data)); + event.SetDataSize(gtk_selection_data_get_length(selection_data)); if (!m_owner->HandleWindowEvent( event )) return FALSE; @@ -3786,15 +3643,56 @@ bool wxDataViewCtrlInternal::ItemAdded( const wxDataViewItem &parent, const wxDa wxCHECK_MSG(parent_node, false, "Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel"); - wxDataViewItemArray siblings; - m_wx_model->GetChildren(parent, siblings); - int itemPos = siblings.Index(item, /*fromEnd=*/true); - wxCHECK_MSG( itemPos != wxNOT_FOUND, false, "adding non-existent item?" ); + wxDataViewItemArray modelSiblings; + m_wx_model->GetChildren(parent, modelSiblings); + const int modelSiblingsSize = modelSiblings.size(); + + int posInModel = modelSiblings.Index(item, /*fromEnd=*/true); + wxCHECK_MSG( posInModel != wxNOT_FOUND, false, "adding non-existent item?" ); + + const wxGtkTreeModelChildren& nodeSiblings = parent_node->GetChildren(); + const int nodeSiblingsSize = nodeSiblings.size(); + + int nodePos = 0; + + if ( posInModel == modelSiblingsSize - 1 ) + { + nodePos = nodeSiblingsSize; + } + else if ( modelSiblingsSize == nodeSiblingsSize + 1 ) + { + // This is the simple case when our node tree already matches the + // model and only this one item is missing. + nodePos = posInModel; + } + else + { + // It's possible that a larger discrepancy between the model and + // our realization exists. This can happen e.g. when adding a bunch + // of items to the model and then calling ItemsAdded() just once + // afterwards. In this case, we must find the right position by + // looking at sibling items. + + // append to the end if we won't find a better position: + nodePos = nodeSiblingsSize; + + for ( int nextItemPos = posInModel + 1; + nextItemPos < modelSiblingsSize; + nextItemPos++ ) + { + int nextNodePos = parent_node->FindChildByItem(modelSiblings[nextItemPos]); + if ( nextNodePos != wxNOT_FOUND ) + { + nodePos = nextNodePos; + break; + } + } + } if (m_wx_model->IsContainer( item )) - parent_node->InsertNode( new wxGtkTreeModelNode( parent_node, item, this ), itemPos ); + parent_node->InsertNode( new wxGtkTreeModelNode( parent_node, item, this ), nodePos ); else - parent_node->InsertLeaf( item.GetID(), itemPos ); + parent_node->InsertLeaf( item.GetID(), nodePos ); } ScheduleRefresh(); @@ -3871,7 +3769,7 @@ gboolean wxDataViewCtrlInternal::get_iter( GtkTreeIter *iter, GtkTreePath *path iter->stamp = m_gtk_model->stamp; // user_data is just the index +1 - iter->user_data = (gpointer) (i+1); + iter->user_data = wxUIntToPtr(i+1); return TRUE; } @@ -3974,7 +3872,7 @@ gboolean wxDataViewCtrlInternal::iter_next( GtkTreeIter *iter ) } // user_data is just the index +1 (+2 because we need the next) - iter->user_data = (gpointer) (n+2); + iter->user_data = wxUIntToPtr(n+2); } else { @@ -4128,7 +4026,7 @@ gboolean wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter *iter, GtkTreeIter iter->stamp = m_gtk_model->stamp; // user_data is just the index +1 - iter->user_data = (gpointer) (n+1); + iter->user_data = wxUIntToPtr(n+1); return TRUE; } @@ -4909,7 +4807,7 @@ bool wxDataViewCtrl::IsExpanded( const wxDataViewItem & item ) const GtkTreeIter iter; iter.user_data = item.GetID(); wxGtkTreePath path(m_internal->get_path( &iter )); - return gtk_tree_view_row_expanded( GTK_TREE_VIEW(m_treeview), path ); + return gtk_tree_view_row_expanded( GTK_TREE_VIEW(m_treeview), path ) != 0; } wxDataViewItem wxDataViewCtrl::DoGetCurrentItem() const @@ -4949,18 +4847,31 @@ void wxDataViewCtrl::DoSetCurrentItem(const wxDataViewItem& item) gtk_tree_view_set_cursor(GTK_TREE_VIEW(m_treeview), path, NULL, FALSE); } -void wxDataViewCtrl::StartEditor(const wxDataViewItem& item, unsigned int column) +wxDataViewColumn *wxDataViewCtrl::GetCurrentColumn() const +{ + // The tree doesn't have any current item if it hadn't been created yet but + // it's arguably not an error to call this function in this case so just + // return NULL without asserting. + if ( !m_treeview ) + return NULL; + + GtkTreeViewColumn *col; + gtk_tree_view_get_cursor(GTK_TREE_VIEW(m_treeview), NULL, &col); + return FromGTKColumn(col); +} + +void wxDataViewCtrl::EditItem(const wxDataViewItem& item, const wxDataViewColumn *column) { wxCHECK_RET( m_treeview, "Current item can't be set before creating the control." ); + wxCHECK_RET( item.IsOk(), "invalid item" ); + wxCHECK_RET( column, "no column provided" ); // We need to make sure the model knows about this item or the path would // be invalid and gtk_tree_view_set_cursor() would silently do nothing. ExpandAncestors(item); - - wxDataViewColumn *dvcolumn = GetColumn(column); - wxASSERT_MSG(dvcolumn, "Could not retrieve column"); - GtkTreeViewColumn *gcolumn = GTK_TREE_VIEW_COLUMN(dvcolumn->GetGtkHandle()); + + GtkTreeViewColumn *gcolumn = GTK_TREE_VIEW_COLUMN(column->GetGtkHandle()); // We also need to preserve the existing selection from changing. // Unfortunately the only way to do it seems to use our own selection @@ -5081,7 +4992,7 @@ bool wxDataViewCtrl::IsSelected( const wxDataViewItem & item ) const iter.stamp = m_internal->GetGtkModel()->stamp; iter.user_data = (gpointer) item.GetID(); - return gtk_tree_selection_iter_is_selected( selection, &iter ); + return gtk_tree_selection_iter_is_selected( selection, &iter ) != 0; } void wxDataViewCtrl::SelectAll() @@ -5126,7 +5037,8 @@ void wxDataViewCtrl::HitTest(const wxPoint& point, // gtk_tree_view_get_path_at_pos() is the wrong function. It doesn't mind the header but returns column. // See http://mail.gnome.org/archives/gtkmm-list/2005-January/msg00080.html // So we have to use both of them. - // Friedrich Haase 2010-9-20 + item = wxDataViewItem(0); + column = NULL; wxGtkTreePath path, pathScratch; GtkTreeViewColumn* GtkColumn = NULL; GtkTreeViewDropPosition pos = GTK_TREE_VIEW_DROP_INTO_OR_AFTER; @@ -5134,8 +5046,8 @@ void wxDataViewCtrl::HitTest(const wxPoint& point, gint cell_y = 0; // cannot directly call GtkGetTreeView(), HitTest is const and so is this pointer - wxDataViewCtrl* ctrl = (wxDataViewCtrl*)this; // ugly workaround, ctrl is NOT const - GtkTreeView* treeView = GTK_TREE_VIEW(ctrl->GtkGetTreeView()); + wxDataViewCtrl* self = const_cast(this); // ugly workaround, self is NOT const + GtkTreeView* treeView = GTK_TREE_VIEW(self->GtkGetTreeView()); // is there possibly a better suited function to get the column? gtk_tree_view_get_path_at_pos( // and this is the wrong call but it delivers the column