]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/dataview.cpp
Remove obsolete header used only with CodeWarrior MetroWerks compiler.
[wxWidgets.git] / src / gtk / dataview.cpp
index 4246a441b51df5e1be1c85564b742a24b0df356f..5e777e02506237fa9d06ef206ead8fd8f1c18951 100644 (file)
@@ -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;
@@ -279,7 +279,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();
@@ -352,7 +352,7 @@ public:
         }
     }
 
-    unsigned int AddNode( wxGtkTreeModelNode* child )
+    void AddNode( wxGtkTreeModelNode* child )
         {
             m_nodes.Add( child );
 
@@ -364,24 +364,54 @@ public:
             {
                 gs_internal = m_internal;
                 m_children.Sort( &wxGtkTreeModelChildCmp );
-                return m_children.Index( id );
             }
+        }
+
+    void InsertNode( wxGtkTreeModelNode* child, unsigned pos )
+        {
+            if (m_internal->IsSorted() || m_internal->GetDataViewModel()->HasDefaultCompare())
+            {
+                AddNode(child);
+                return;
+            }
+
+            void *id = child->GetItem().GetID();
+
+            // Insert into m_nodes so that the order of nodes in m_nodes is the
+            // same as the order of their corresponding IDs in m_children:
+            const unsigned int count = m_nodes.GetCount();
+            bool inserted = false;
+            for (unsigned i = 0; i < count; i++)
+            {
+                wxGtkTreeModelNode *node = m_nodes[i];
+                int posInChildren = m_children.Index(node->GetItem().GetID());
+                if ( (unsigned)posInChildren >= pos )
+                {
+                    m_nodes.Insert(child, i);
+                    inserted = true;
+                    break;
+                }
+            }
+            if ( !inserted )
+                m_nodes.Add(child);
 
-            return m_children.GetCount()-1;
+            m_children.Insert( id, pos );
         }
 
-    unsigned int AddLeave( void* id )
+    void AddLeaf( void* id )
         {
-            m_children.Add( id );
+            InsertLeaf(id, m_children.size());
+        }
+
+    void InsertLeaf( void* id, unsigned pos )
+        {
+            m_children.Insert( id, pos );
 
             if (m_internal->IsSorted() || m_internal->GetDataViewModel()->HasDefaultCompare())
             {
                 gs_internal = m_internal;
                 m_children.Sort( &wxGtkTreeModelChildCmp );
-                return m_children.Index( id );
             }
-
-            return m_children.GetCount()-1;
         }
 
     void DeleteChild( void* id )
@@ -402,6 +432,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()
@@ -440,15 +484,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;
@@ -458,21 +498,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,
@@ -536,9 +569,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)
 {
@@ -548,41 +578,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
         };
@@ -615,16 +645,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<GtkTreeModelIface*>(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;
@@ -640,8 +663,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<GtkTreeSortableIface*>(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;
@@ -650,34 +674,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<GtkTreeDragSourceIface*>(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<GtkTreeDragDestIface*>(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"
 
 //-----------------------------------------------------------------------------
@@ -1022,15 +1042,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
 {
@@ -1039,19 +1056,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,
@@ -1075,15 +1084,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,
@@ -1094,31 +1103,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)
 {
@@ -1164,15 +1164,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
 {
@@ -1180,22 +1177,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,
@@ -1229,9 +1217,6 @@ static GtkCellEditable *gtk_wx_cell_renderer_start_editing(
                         GdkRectangle            *cell_area,
                         GtkCellRendererState     flags );
 
-
-static GObjectClass *cell_parent_class = NULL;
-
 }  // extern "C"
 
 GType
@@ -1243,15 +1228,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,
@@ -1262,35 +1247,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)
 {
@@ -1398,6 +1371,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,
@@ -1411,8 +1393,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;
@@ -1443,6 +1430,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
@@ -1481,37 +1470,27 @@ gtk_wx_cell_renderer_activate(
 
     unsigned int model_col = cell->GetOwner()->GetModelColumn();
 
-    if (!event)
+    if ( !event )
     {
-        bool ret = false;
-
         // activated by <ENTER>
-        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);
 
-        return ret;
+            mouse_event.m_x -= renderrect.x;
+            mouse_event.m_y -= renderrect.y;
+
+            return cell->ActivateCell(renderrect, model, item, model_col, &mouse_event);
+        }
     }
 
+    wxLogDebug("unexpected event type in gtk_wx_cell_renderer_activate()");
     return false;
 }
 
@@ -1588,12 +1567,14 @@ bool wxGtkDataViewModelNotifier::ItemDeleted( const wxDataViewItem &parent, cons
         GTK_TREE_MODEL(wxgtk_model), &iter ));
 #else
     // so get the path from the parent
-    GtkTreeIter iter;
-    iter.stamp = wxgtk_model->stamp;
-    iter.user_data = (gpointer) parent.GetID();
-    wxGtkTreePath path(wxgtk_tree_model_get_path(
-        GTK_TREE_MODEL(wxgtk_model), &iter ));
+    GtkTreeIter parentIter;
+    parentIter.stamp = wxgtk_model->stamp;
+    parentIter.user_data = (gpointer) parent.GetID();
+    wxGtkTreePath parentPath(wxgtk_tree_model_get_path(
+        GTK_TREE_MODEL(wxgtk_model), &parentIter ));
+
     // and add the final index ourselves
+    wxGtkTreePath path(gtk_tree_path_copy(parentPath));
     int index = m_internal->GetIndexOf( parent, item );
     gtk_tree_path_append_index( path, index );
 #endif
@@ -1603,6 +1584,17 @@ bool wxGtkDataViewModelNotifier::ItemDeleted( const wxDataViewItem &parent, cons
 
     m_internal->ItemDeleted( parent, item );
 
+    // Did we remove the last child, causing 'parent' to become a leaf?
+    if ( !m_wx_model->IsContainer(parent) )
+    {
+        gtk_tree_model_row_has_child_toggled
+        (
+            GTK_TREE_MODEL(wxgtk_model),
+            parentPath,
+            &parentIter
+        );
+    }
+
     return true;
 }
 
@@ -1962,7 +1954,7 @@ wxEllipsizeMode wxDataViewRenderer::GetEllipsizeMode() const
 }
 
 void
-wxDataViewRenderer::GtkOnTextEdited(const gchar *itempath, const wxString& str)
+wxDataViewRenderer::GtkOnTextEdited(const char *itempath, const wxString& str)
 {
     wxVariant value(str);
     if (!Validate( value ))
@@ -2378,6 +2370,7 @@ wxDataViewCustomRenderer::wxDataViewCustomRenderer( const wxString &varianttype,
 {
     m_dc = NULL;
     m_text_renderer = NULL;
+    m_renderParams = NULL;
 
     if (no_init)
         m_renderer = NULL;
@@ -2427,12 +2420,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)
@@ -2525,11 +2518,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 );
 
@@ -2725,7 +2720,7 @@ wxDataViewChoiceByIndexRenderer::wxDataViewChoiceByIndexRenderer( const wxArrayS
 {
 }
 
-void wxDataViewChoiceByIndexRenderer::GtkOnTextEdited(const gchar *itempath, const wxString& str)
+void wxDataViewChoiceByIndexRenderer::GtkOnTextEdited(const char *itempath, const wxString& str)
 {
     wxVariant value( (long) GetChoices().Index( str ) );
 
@@ -2754,108 +2749,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
 // ---------------------------------------------------------
@@ -3243,14 +3136,6 @@ bool wxDataViewColumn::IsSortable() const
     return gtk_tree_view_column_get_clickable( column );
 }
 
-void wxDataViewColumn::SetAsSortKey( bool WXUNUSED(sort) )
-{
-    // it might not make sense to have this function in wxHeaderColumn at
-    // all in fact, changing of the sort order should only be done using the
-    // associated control API
-    wxFAIL_MSG( "not implemented" );
-}
-
 bool wxDataViewColumn::IsSortKey() const
 {
     GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN(m_column);
@@ -3561,7 +3446,7 @@ void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode *node )
             if (m_wx_model->IsContainer( child ))
                 node->AddNode( new wxGtkTreeModelNode( node, child, this ) );
             else
-                node->AddLeave( child.GetID() );
+                node->AddLeaf( child.GetID() );
 
             // Don't send any events here
         }
@@ -3748,13 +3633,59 @@ bool wxDataViewCtrlInternal::ItemAdded( const wxDataViewItem &parent, const wxDa
     if (!m_wx_model->IsVirtualListModel())
     {
         wxGtkTreeModelNode *parent_node = FindNode( parent );
-        wxASSERT_MSG(parent_node,
+        wxCHECK_MSG(parent_node, false,
             "Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel");
 
+        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->AddNode( new wxGtkTreeModelNode( parent_node, item, this ) );
+            parent_node->InsertNode( new wxGtkTreeModelNode( parent_node, item, this ), nodePos );
         else
-            parent_node->AddLeave( item.GetID() );
+            parent_node->InsertLeaf( item.GetID(), nodePos );
     }
 
     ScheduleRefresh();
@@ -3831,7 +3762,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;
     }
@@ -3934,7 +3865,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
     {
@@ -4088,7 +4019,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;
     }
@@ -4496,22 +4427,21 @@ gtk_dataview_button_press_callback( GtkWidget *WXUNUSED(widget),
         GtkTreeViewColumn *column = NULL;
         gint cell_x = 0;
         gint cell_y = 0;
-        if (gtk_tree_view_get_path_at_pos(
+        gtk_tree_view_get_path_at_pos
+        (
             GTK_TREE_VIEW(dv->GtkGetTreeView()),
             (int) gdk_event->x, (int) gdk_event->y,
             path.ByRef(),
             &column,
             &cell_x,
-            &cell_y))
-        {
-            if (path)
-            {
-                wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, dv->GetId() );
-                event.SetItem(dv->GTKPathToItem(path));
-                event.SetModel( dv->GetModel() );
-                return dv->HandleWindowEvent( event );
-             }
-        }
+            &cell_y
+        );
+
+        wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, dv->GetId() );
+        if (path)
+            event.SetItem(dv->GTKPathToItem(path));
+        event.SetModel( dv->GetModel() );
+        return dv->HandleWindowEvent( event );
     }
 
     return FALSE;
@@ -4574,6 +4504,8 @@ bool wxDataViewCtrl::Create(wxWindow *parent,
     m_treeview = gtk_tree_view_new();
     gtk_container_add (GTK_CONTAINER (m_widget), m_treeview);
 
+    m_focusWidget = GTK_WIDGET(m_treeview);
+
     g_signal_connect (m_treeview, "size_allocate",
                      G_CALLBACK (gtk_dataviewctrl_size_callback), this);
 
@@ -4908,18 +4840,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
@@ -5085,7 +5030,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;
@@ -5093,8 +5039,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<wxDataViewCtrl *>(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