]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/dataview.cpp
Don't pop explicitly changed status messages.
[wxWidgets.git] / src / gtk / dataview.cpp
index 58bdbbb501293a8bdf0e82d73c48a9a110be32da..85fcee31858bc2d3543d769391de98e13e35eaac 100644 (file)
@@ -92,10 +92,10 @@ public:
 
     // sorting interface
     void SetSortOrder( GtkSortType sort_order ) { m_sort_order = sort_order; }
-    GtkSortType GetSortOrder()                  { return m_sort_order; }
+    GtkSortType GetSortOrder() const            { return m_sort_order; }
 
     void SetSortColumn( int column )            { m_sort_column = column; }
-    int GetSortColumn()                         { return m_sort_column; }
+    int GetSortColumn() const                   { return m_sort_column; }
 
     void SetDataViewSortColumn( wxDataViewColumn *column ) { m_dataview_sort_column = column; }
     wxDataViewColumn *GetDataViewSortColumn()   { return m_dataview_sort_column; }
@@ -104,6 +104,7 @@ public:
 
     // accessors
     wxDataViewModel* GetDataViewModel() { return m_wx_model; }
+    const wxDataViewModel* GetDataViewModel() const { return m_wx_model; }
     wxDataViewCtrl* GetOwner()          { return m_owner; }
     GtkWxTreeModel* GetGtkModel()       { return m_gtk_model; }
 
@@ -154,7 +155,7 @@ class wxGtkTreeModelNode
 {
 public:
     wxGtkTreeModelNode( wxGtkTreeModelNode* parent, const wxDataViewItem &item,
-      wxDataViewCtrlInternal *internal )
+                        wxDataViewCtrlInternal *internal )
     {
         m_parent = parent;
         m_item = item;
@@ -220,7 +221,6 @@ public:
                     break;
                 }
             }
-
         }
 
     wxGtkTreeModelNode* GetParent()
@@ -230,8 +230,8 @@ public:
     wxGtkTreeModelChildren &GetChildren()
         { return m_children; }
 
-    unsigned int GetChildCount() { return m_children.GetCount(); }
-    unsigned int GetNodesCount() { return m_nodes.GetCount(); }
+    unsigned int GetChildCount() const { return m_children.GetCount(); }
+    unsigned int GetNodesCount() const { return m_nodes.GetCount(); }
 
     wxDataViewItem &GetItem() { return m_item; }
     wxDataViewCtrlInternal *GetInternal() { return m_internal; }
@@ -327,7 +327,7 @@ 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);
+                                                        GtkSortType           *order);
 static void     wxgtk_tree_model_set_sort_column_id    (GtkTreeSortable       *sortable,
                                                         gint                   sort_column_id,
                                                         GtkSortType            order);
@@ -355,7 +355,7 @@ static gboolean wxgtk_tree_model_drag_data_received    (GtkTreeDragDest       *d
                                                         GtkSelectionData      *selection_data);
 static gboolean wxgtk_tree_model_row_drop_possible     (GtkTreeDragDest       *drag_dest,
                                                         GtkTreePath           *dest_path,
-                                                       GtkSelectionData      *selection_data);
+                                                        GtkSelectionData      *selection_data);
 
 
 static GObjectClass *list_parent_class = NULL;
@@ -535,14 +535,12 @@ wxgtk_tree_model_get_column_type (GtkTreeModel *tree_model,
 
     wxString wxtype = wxtree_model->internal->GetDataViewModel()->GetColumnType( (unsigned int) index );
 
-    wxPrintf( "get_column_type %s\n", wxtype );
-
     if (wxtype == wxT("string"))
         gtype = G_TYPE_STRING;
     else
     {
         gtype = G_TYPE_STRING;
-        // wxFAIL_MSG( _T("non-string columns not supported yet") );
+        // wxFAIL_MSG( wxT("non-string columns not supported yet") );
     }
 
     return gtype;
@@ -593,7 +591,7 @@ wxgtk_tree_model_get_value (GtkTreeModel *tree_model,
     }
     else
     {
-        wxFAIL_MSG( _T("non-string columns not supported yet") );
+        wxFAIL_MSG( wxT("non-string columns not supported yet") );
     }
 }
 
@@ -603,8 +601,8 @@ wxgtk_tree_model_iter_next (GtkTreeModel  *tree_model,
 {
     GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model;
 
-    if (wxtree_model->stamp != iter->stamp)
-       wxPrintf( "crash\n" );
+    // This happens when clearing the view by calling .._set_model( NULL );
+    if (iter->stamp == 0) return FALSE;
 
     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE);
     g_return_val_if_fail (wxtree_model->stamp == iter->stamp, FALSE);
@@ -640,11 +638,9 @@ wxgtk_tree_model_iter_n_children (GtkTreeModel *tree_model,
                                   GtkTreeIter  *iter)
 {
     GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model;
-    g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE);
-    
-    if (iter != NULL)
-        g_return_val_if_fail (wxtree_model->stamp == iter->stamp, 0);
-        
+    g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), 0);
+    g_return_val_if_fail ( !iter || wxtree_model->stamp == iter->stamp, 0);
+
     return wxtree_model->internal->iter_n_children( iter );
 }
 
@@ -733,7 +729,7 @@ wxgtk_tree_model_drag_data_received (GtkTreeDragDest  *drag_dest,
 static gboolean
 wxgtk_tree_model_row_drop_possible (GtkTreeDragDest  *drag_dest,
                                     GtkTreePath      *dest_path,
-                                   GtkSelectionData *selection_data)
+                                    GtkSelectionData *selection_data)
 {
     GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) drag_dest;
     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE);
@@ -809,24 +805,27 @@ wxgtk_tree_model_set_sort_func (GtkTreeSortable        *sortable,
                                 gint                    WXUNUSED(sort_column_id),
                                 GtkTreeIterCompareFunc  func,
                                 gpointer                WXUNUSED(data),
-                                GtkDestroyNotify        WXUNUSED(destroy) )
+                                GtkDestroyNotify        WXUNUSED(destroy))
 {
     g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable) );
     g_return_if_fail (func != NULL);
 }
 
-void     wxgtk_tree_model_set_default_sort_func (GtkTreeSortable          *sortable,
-                                                GtkTreeIterCompareFunc    func,
-                                                gpointer                  WXUNUSED(data),
-                                                GtkDestroyNotify          WXUNUSED(destroy) )
+static void
+wxgtk_tree_model_set_default_sort_func (GtkTreeSortable          *sortable,
+                                        GtkTreeIterCompareFunc    func,
+                                        gpointer                  WXUNUSED(data),
+                                        GtkDestroyNotify          WXUNUSED(destroy))
 {
     g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable) );
     g_return_if_fail (func != NULL);
 
-    wxPrintf( "wxgtk_tree_model_set_default_sort_func\n" );
+    //wxPrintf( "wxgtk_tree_model_set_default_sort_func\n" );
+    // TODO: remove this code
 }
 
-gboolean wxgtk_tree_model_has_default_sort_func (GtkTreeSortable        *sortable)
+static gboolean
+wxgtk_tree_model_has_default_sort_func (GtkTreeSortable        *sortable)
 {
     g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (sortable), FALSE );
 
@@ -834,7 +833,152 @@ gboolean wxgtk_tree_model_has_default_sort_func (GtkTreeSortable        *sortabl
 }
 
 //-----------------------------------------------------------------------------
-// define new GTK+ class wxGtkRendererRenderer
+// define new GTK+ class GtkWxRendererText
+//-----------------------------------------------------------------------------
+
+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
+{
+  GtkCellRendererText parent;
+  
+  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 );
+static void gtk_wx_cell_renderer_text_class_init(
+                        GtkWxCellRendererTextClass *klass );
+static void gtk_wx_cell_renderer_text_finalize (
+                        GObject                *object );
+static GtkCellEditable *gtk_wx_cell_renderer_text_start_editing(
+                        GtkCellRenderer         *cell,
+                        GdkEvent                *event,
+                        GtkWidget               *widget,
+                        const gchar             *path,
+                        GdkRectangle            *background_area,
+                        GdkRectangle            *cell_area,
+                        GtkCellRendererState     flags );
+
+
+static GObjectClass *text_cell_parent_class = NULL;
+
+}  // extern "C"
+
+GType
+gtk_wx_cell_renderer_text_get_type (void)
+{
+    static GType cell_wx_type = 0;
+
+    if (!cell_wx_type)
+    {
+        const GTypeInfo cell_wx_info =
+        {
+            sizeof (GtkWxCellRendererTextClass),
+            NULL, /* base_init */
+            NULL, /* base_finalize */
+            (GClassInitFunc) 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,
+        };
+
+        cell_wx_type = g_type_register_static( GTK_TYPE_CELL_RENDERER_TEXT,
+            "GtkWxCellRendererText", &cell_wx_info, (GTypeFlags)0 );
+    }
+
+    return cell_wx_type;
+}
+
+static void
+gtk_wx_cell_renderer_text_init (GtkWxCellRendererText *cell)
+{
+    cell->wx_renderer = NULL;
+}
+
+static void
+gtk_wx_cell_renderer_text_class_init (GtkWxCellRendererTextClass *klass)
+{
+    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)
+{
+    return (GtkWxCellRendererText*) g_object_new (GTK_TYPE_WX_CELL_RENDERER_TEXT, NULL);
+}
+
+static GtkCellEditable *gtk_wx_cell_renderer_text_start_editing(
+                        GtkCellRenderer         *gtk_renderer,
+                        GdkEvent                *gdk_event,
+                        GtkWidget               *widget,
+                        const gchar             *path,
+                        GdkRectangle            *background_area,
+                        GdkRectangle            *cell_area,
+                        GtkCellRendererState     flags )
+{
+    GtkWxCellRendererText *wxgtk_renderer = (GtkWxCellRendererText *) gtk_renderer;
+    wxDataViewRenderer *wx_renderer = wxgtk_renderer->wx_renderer;
+
+    GtkTreePath *treepath = gtk_tree_path_new_from_string( path );
+    GtkTreeIter iter;
+    wx_renderer->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter, treepath );
+    wxDataViewItem item( (void*) iter.user_data );;
+    gtk_tree_path_free( treepath );
+
+    wxDataViewColumn *column = wx_renderer->GetOwner();
+    wxDataViewCtrl *dv = column->GetOwner();
+    wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_START_EDITING, dv->GetId() );
+    event.SetDataViewColumn( column );
+    event.SetModel( dv->GetModel() );
+    event.SetColumn( wx_renderer->GetOwner()->GetModelColumn() );
+    event.SetItem( item );
+    dv->HandleWindowEvent( event );
+    
+    if (event.IsAllowed())
+        return GTK_CELL_RENDERER_CLASS(text_cell_parent_class)->
+           start_editing( gtk_renderer, gdk_event, widget, path, background_area, cell_area, flags );
+    else
+        return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// define new GTK+ class GtkWxCellRenderer
 //-----------------------------------------------------------------------------
 
 extern "C" {
@@ -974,8 +1118,6 @@ gtk_wx_cell_renderer_new (void)
     return (GtkCellRenderer*) g_object_new (GTK_TYPE_WX_CELL_RENDERER, NULL);
 }
 
-
-
 static GtkCellEditable *gtk_wx_cell_renderer_start_editing(
                         GtkCellRenderer         *renderer,
                         GdkEvent                *WXUNUSED(event),
@@ -1105,8 +1247,12 @@ gtk_wx_cell_renderer_render (GtkCellRenderer      *renderer,
         wxRect renderrect( rect.x, rect.y, rect.width, rect.height );
         wxWindowDC* dc = (wxWindowDC*) cell->GetDC();
         wxWindowDCImpl *impl = (wxWindowDCImpl *) dc->GetImpl();
-        if (impl->m_gdkwindow == NULL)
+
+        // Reinitialize wxWindowDC's GDK window if drawing occurs into a different
+        // window such as a DnD drop window.
+        if (window != impl->m_gdkwindow)
         {
+            impl->Destroy();
             impl->m_gdkwindow = window;
             impl->SetUpDC();
         }
@@ -1342,16 +1488,9 @@ 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;
+    
+    return true;
 }
 
 // ---------------------------------------------------------
@@ -1378,6 +1517,9 @@ static void
 wxgtk_renderer_editing_started( GtkCellRenderer *WXUNUSED(cell), GtkCellEditable *editable,
                                 gchar *path, wxDataViewRenderer *wxrenderer )
 {
+    if (!editable)
+       return;
+
     wxDataViewColumn *column = wxrenderer->GetOwner();
     wxDataViewCtrl *dv = column->GetOwner();
     wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_EDITING_STARTED, dv->GetId() );
@@ -1580,7 +1722,9 @@ wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString &varianttype, wxD
                                                 int align ) :
     wxDataViewRenderer( varianttype, mode, align )
 {
-    m_renderer = (GtkCellRenderer*) gtk_cell_renderer_text_new();
+    GtkWxCellRendererText *text_renderer = gtk_wx_cell_renderer_text_new();
+    text_renderer->wx_renderer = this;
+    m_renderer = (GtkCellRenderer*) text_renderer;
 
     if (mode & wxDATAVIEW_CELL_EDITABLE)
     {
@@ -1829,7 +1973,7 @@ public:
 
         m_window = window;
 
-        m_context = window->GtkGetPangoDefaultContext();
+        m_context = window->GTKGetPangoDefaultContext();
         m_layout = pango_layout_new( m_context );
         m_fontdesc = pango_font_description_copy( widget->style->font_desc );
 
@@ -2049,9 +2193,12 @@ wxDataViewChoiceRenderer::wxDataViewChoiceRenderer( const wxArrayString &choices
         m_renderer = (GtkCellRenderer*) gtk_cell_renderer_combo_new();
 
         GtkListStore *store = gtk_list_store_new( 1, G_TYPE_STRING );
-        size_t n;
-        for (n = 0; n < m_choices.GetCount(); n++)
-            gtk_list_store_insert_with_values( store, NULL, n, 0, m_choices[n].utf8_str(), -1 );
+        for (size_t n = 0; n < m_choices.GetCount(); n++)
+        {
+            gtk_list_store_insert_with_values(
+                store, NULL, n, 0,
+                static_cast<const char *>(m_choices[n].utf8_str()), -1 );
+        }
 
         g_object_set (m_renderer,
                 "model", store,
@@ -2114,10 +2261,13 @@ bool wxDataViewChoiceRenderer::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 temp = wxGTK_CONV_BACK_FONT( g_value_get_string( &gvalue ), const_cast<wxDataViewTextRenderer*>(this)->GetOwner()->GetOwner()->GetFont() );
+        wxString temp = wxGTK_CONV_BACK_FONT( g_value_get_string( &gvalue ),
+                const_cast<wxDataViewChoiceRenderer*>(this)->GetOwner()->GetOwner()->GetFont() );
         g_value_unset( &gvalue );
         value = temp;
-        wxPrintf( "temp %s\n", temp );
+
+        //wxPrintf( "temp %s\n", temp );
+        // TODO: remove this code
     }
     else
 #endif
@@ -2422,9 +2572,11 @@ static void wxGtkTreeCellDataFunc( GtkTreeViewColumn *WXUNUSED(column),
     wx_model->GetValue( value, item, cell->GetOwner()->GetModelColumn() );
 
     if (value.GetType() != cell->GetVariantType())
+    {
         wxLogError( wxT("Wrong type, required: %s but: %s"),
                     value.GetType().c_str(),
                     cell->GetVariantType().c_str() );
+    }
 
     cell->SetValue( value );
 
@@ -2813,6 +2965,36 @@ bool wxDataViewColumn::IsReorderable() const
 // wxGtkTreeModelNode
 //-----------------------------------------------------------------------------
 
+#if 0
+class wxGtkTreeModelChildWithPos
+{
+public:
+    unsigned int pos;
+    void        *id;
+};
+
+static
+int wxGtkTreeModelChildWithPosCmp( const void* data1, const void* data2, const void* user_data )
+{
+    const wxGtkTreeModelChildWithPos* child1 = (const wxGtkTreeModelChildWithPos*) data1;
+    const wxGtkTreeModelChildWithPos* child2 = (const wxGtkTreeModelChildWithPos*) data2;
+    const wxDataViewCtrlInternal *internal = (const wxDataViewCtrlInternal *) user_data;
+    int ret = internal->GetDataViewModel()->Compare( child1->id, child2->id,
+        internal->GetSortColumn(), (internal->GetSortOrder() == GTK_SORT_DESCENDING) );
+
+    return ret;
+}
+#else
+static
+int LINKAGEMODE wxGtkTreeModelChildPtrCmp( void*** data1, void*** data2 )
+{
+    return gs_internal->GetDataViewModel()->Compare( **data1, **data2,
+        gs_internal->GetSortColumn(), (gs_internal->GetSortOrder() == GTK_SORT_ASCENDING) );
+}
+
+WX_DEFINE_ARRAY_PTR( void**, wxGtkTreeModelChildrenPtr );
+#endif
+
 void wxGtkTreeModelNode::Resort()
 {
     size_t child_count = GetChildCount();
@@ -2831,14 +3013,68 @@ void wxGtkTreeModelNode::Resort()
         return;
     }
 
+    gint *new_order = new gint[child_count];
+
+#if 1
+    // m_children has the original *void
+    // ptrs points to these
+    wxGtkTreeModelChildrenPtr ptrs;
+    size_t i;
+    for (i = 0; i < child_count; i++)
+       ptrs.Add( &(m_children[i]) );
+    // Sort the ptrs
+    gs_internal = m_internal;
+    ptrs.Sort( &wxGtkTreeModelChildPtrCmp );
     wxGtkTreeModelChildren temp;
+    void** base_ptr = &(m_children[0]);
+    // Transfer positions to new_order array and 
+    // IDs to temp
+    for (i = 0; i < child_count; i++)
+    {
+        new_order[i] = ptrs[i] - base_ptr;
+        temp.Add( *ptrs[i] );
+    }
+
+    // Transfer IDs back to m_children
+    m_children.Clear();
     WX_APPEND_ARRAY( temp, m_children );
+#endif
+#if 0
+    // Too slow
 
-    gs_internal = m_internal;
-    m_children.Sort( &wxGtkTreeModelChildCmp );
+    // Build up array with IDs and original positions
+    wxGtkTreeModelChildWithPos* temp = new wxGtkTreeModelChildWithPos[child_count];
+    size_t i;
+    for (i = 0; i < child_count; i++)
+    {
+       temp[i].pos = i;
+       temp[i].id = m_children[i];
+    }
+    // Sort array keeping original positions
+    wxQsort( temp, child_count, sizeof(wxGtkTreeModelChildWithPos),
+             &wxGtkTreeModelChildWithPosCmp, m_internal );
+    // Transfer positions to new_order array and
+    // IDs to m_children
+    m_children.Clear();
+    for (i = 0; i < child_count; i++)
+    {
+       new_order[i] = temp[i].pos;
+       m_children.Add( temp[i].id );
+    }
+    // Delete array
+    delete [] temp;
+#endif
 
-    gint *new_order = new gint[child_count];
+#if 0
+    // Too slow
+    
+    wxGtkTreeModelChildren temp;
+    WX_APPEND_ARRAY( temp, m_children );
 
+    gs_internal = m_internal;
+    m_children.Sort( &wxGtkTreeModelChildCmp );
+    
     unsigned int pos;
     for (pos = 0; pos < child_count; pos++)
     {
@@ -2846,6 +3082,7 @@ void wxGtkTreeModelNode::Resort()
         int old_pos = temp.Index( id );
         new_order[pos] = old_pos;
     }
+#endif
 
     GtkTreeModel *gtk_tree_model = GTK_TREE_MODEL( m_internal->GetGtkModel() );
 
@@ -2860,7 +3097,8 @@ void wxGtkTreeModelNode::Resort()
     gtk_tree_path_free (path);
 
     delete [] new_order;
-
+    
+    unsigned int pos;
     for (pos = 0; pos < node_count; pos++)
     {
         wxGtkTreeModelNode *node = m_nodes.Item( pos );
@@ -3076,17 +3314,16 @@ wxDataViewCtrlInternal::row_drop_possible(GtkTreeDragDest *WXUNUSED(drag_dest),
 
 bool wxDataViewCtrlInternal::Cleared()
 {
+    GtkWidget* tree_widget = GetOwner()->GtkGetTreeView();
+    gtk_tree_view_set_model( GTK_TREE_VIEW(tree_widget), NULL );
+    gtk_tree_view_set_model( GTK_TREE_VIEW(tree_widget), GTK_TREE_MODEL(m_gtk_model) );
+    
     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;
 }
 
@@ -3101,6 +3338,9 @@ bool wxDataViewCtrlInternal::ItemAdded( const wxDataViewItem &parent, const wxDa
     if (!m_wx_model->IsVirtualListModel())
     {
         wxGtkTreeModelNode *parent_node = FindNode( parent );
+        wxASSERT_MSG(parent_node,
+            "Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel");
+
         if (m_wx_model->IsContainer( item ))
             parent_node->AddNode( new wxGtkTreeModelNode( parent_node, item, this ) );
         else
@@ -3115,6 +3355,9 @@ bool wxDataViewCtrlInternal::ItemDeleted( const wxDataViewItem &parent, const wx
     if (!m_wx_model->IsVirtualListModel())
     {
         wxGtkTreeModelNode *parent_node = FindNode( parent );
+        wxASSERT_MSG(parent_node,
+            "Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel");
+
         parent_node->DeleteChild( item.GetID() );
     }
 
@@ -3157,18 +3400,19 @@ GtkTreeModelFlags wxDataViewCtrlInternal::get_flags()
 
 gboolean wxDataViewCtrlInternal::get_iter( GtkTreeIter *iter, GtkTreePath *path )
 {
+
     if (m_wx_model->IsVirtualListModel())
     {
-        wxDataViewIndexListModel *wx_model = (wxDataViewIndexListModel*) m_wx_model;
-
+        wxDataViewVirtualListModel *wx_model = (wxDataViewVirtualListModel*) m_wx_model;
+    
         unsigned int i = (unsigned int)gtk_tree_path_get_indices (path)[0];
-
-        if (i >= wx_model->GetLastIndex() + 1)
+        
+        if (i >= wx_model->GetCount())
             return FALSE;
 
         iter->stamp = m_gtk_model->stamp;
-        // user_data is just the index
-        iter->user_data = (gpointer) i;
+        // user_data is just the index +1
+        iter->user_data = (gpointer) (i+1);
 
         return TRUE;
     }
@@ -3219,8 +3463,8 @@ GtkTreePath *wxDataViewCtrlInternal::get_path( GtkTreeIter *iter )
 
     if (m_wx_model->IsVirtualListModel())
     {
-        // user_data is just the index
-        int i = (wxUIntPtr) iter->user_data;
+        // user_data is just the index +1
+        int i = ( (wxUIntPtr) iter->user_data ) -1;
         gtk_tree_path_append_index (retval, i);
     }
     else
@@ -3246,30 +3490,43 @@ gboolean wxDataViewCtrlInternal::iter_next( GtkTreeIter *iter )
 {
     if (m_wx_model->IsVirtualListModel())
     {
-        wxDataViewIndexListModel *wx_model = (wxDataViewIndexListModel*) m_wx_model;
+        wxDataViewVirtualListModel *wx_model = (wxDataViewVirtualListModel*) m_wx_model;
 
-        int n = (wxUIntPtr) iter->user_data;
+        // user_data is just the index +1
+        int n = ( (wxUIntPtr) iter->user_data ) -1;
 
         if (n == -1)
+        {
+            iter->user_data = NULL;
             return FALSE;
+        }
 
-        if (n >= (int) wx_model->GetLastIndex())
+        if (n >= (int) wx_model->GetCount()-1)
+        {
+            iter->user_data = NULL;
             return FALSE;
-
-        iter->user_data = (gpointer) ++n;
+        }
+        
+        // user_data is just the index +1 (+2 because we need the next)
+        iter->user_data = (gpointer) (n+2);
     }
     else
     {
         wxGtkTreeModelNode *parent = FindParentNode( iter );
         if( parent == NULL )
+        {
+            iter->user_data = NULL;
             return FALSE;
+        }
 
         int pos = parent->GetChildren().Index( iter->user_data );
 
         if (pos == (int) parent->GetChildCount()-1)
+        {
+            iter->user_data = NULL;
             return FALSE;
+        }
 
-        iter->stamp = m_gtk_model->stamp;
         iter->user_data = parent->GetChildren().Item( pos+1 );
     }
 
@@ -3285,18 +3542,29 @@ gboolean wxDataViewCtrlInternal::iter_children( GtkTreeIter *iter, GtkTreeIter *
             return FALSE;
 
         iter->stamp = m_gtk_model->stamp;
-        iter->user_data = (gpointer) -1;
+        iter->user_data = (gpointer) 1;
 
         return TRUE;
     }
     else
     {
+        if (iter == NULL)
+        {
+            if (m_root->GetChildCount() == 0) return FALSE;
+            iter->stamp = m_gtk_model->stamp;
+            iter->user_data = (gpointer) m_root->GetChildren().Item( 0 );
+            return TRUE;
+        }
+        
         wxDataViewItem item( (void*) parent->user_data );
 
         if (!m_wx_model->IsContainer( item ))
             return FALSE;
 
         wxGtkTreeModelNode *parent_node = FindNode( parent );
+        wxASSERT_MSG(parent_node,
+            "Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel");
+
         BuildBranch( parent_node );
 
         if (parent_node->GetChildCount() == 0)
@@ -3313,11 +3581,19 @@ gboolean wxDataViewCtrlInternal::iter_has_child( GtkTreeIter *iter )
 {
     if (m_wx_model->IsVirtualListModel())
     {
+        wxDataViewVirtualListModel *wx_model = (wxDataViewVirtualListModel*) m_wx_model;
+
+        if (iter == NULL)
+            return (wx_model->GetCount() > 0);
+        
         // this is a list, nodes have no children
         return FALSE;
     }
     else
     {
+        if (iter == NULL)
+            return (m_root->GetChildCount() > 0);
+    
         wxDataViewItem item( (void*) iter->user_data );
 
         bool is_container = m_wx_model->IsContainer( item );
@@ -3326,6 +3602,9 @@ gboolean wxDataViewCtrlInternal::iter_has_child( GtkTreeIter *iter )
             return FALSE;
 
         wxGtkTreeModelNode *node = FindNode( iter );
+        wxASSERT_MSG(node,
+            "Did you forget a call to ItemAdded()? The iterator is unknown to the wxGtkTreeModel");
+
         BuildBranch( node );
 
         return (node->GetChildCount() > 0);
@@ -3336,10 +3615,10 @@ gint wxDataViewCtrlInternal::iter_n_children( GtkTreeIter *iter )
 {
     if (m_wx_model->IsVirtualListModel())
     {
-        wxDataViewIndexListModel *wx_model = (wxDataViewIndexListModel*) m_wx_model;
+        wxDataViewVirtualListModel *wx_model = (wxDataViewVirtualListModel*) m_wx_model;
 
         if (iter == NULL)
-            return (gint) wx_model->GetLastIndex() + 1;
+            return (gint) wx_model->GetCount();
 
         return 0;
     }
@@ -3347,16 +3626,17 @@ gint wxDataViewCtrlInternal::iter_n_children( GtkTreeIter *iter )
     {
         if (iter == NULL)
             return m_root->GetChildCount();
-            
+
         wxDataViewItem item( (void*) iter->user_data );
 
         if (!m_wx_model->IsContainer( item ))
             return 0;
 
         wxGtkTreeModelNode *parent_node = FindNode( iter );
-        BuildBranch( parent_node );
+        wxASSERT_MSG(parent_node,
+            "Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel");
 
-        // wxPrintf( "iter_n_children %d\n", parent_node->GetChildCount() );
+        BuildBranch( parent_node );
 
         return parent_node->GetChildCount();
     }
@@ -3366,7 +3646,7 @@ gboolean wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter *iter, GtkTreeIter
 {
     if (m_wx_model->IsVirtualListModel())
     {
-        wxDataViewIndexListModel *wx_model = (wxDataViewIndexListModel*) m_wx_model;
+        wxDataViewVirtualListModel *wx_model = (wxDataViewVirtualListModel*) m_wx_model;
 
         if (parent)
             return FALSE;
@@ -3374,11 +3654,12 @@ gboolean wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter *iter, GtkTreeIter
         if (n < 0)
             return FALSE;
 
-        if (n >= (gint) wx_model->GetLastIndex() + 1)
+        if (n >= (gint) wx_model->GetCount())
             return FALSE;
 
         iter->stamp = m_gtk_model->stamp;
-        iter->user_data = (gpointer) n;
+        // user_data is just the index +1
+        iter->user_data = (gpointer) (n+1);
 
         return TRUE;
     }
@@ -3392,9 +3673,10 @@ gboolean wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter *iter, GtkTreeIter
             return FALSE;
 
         wxGtkTreeModelNode *parent_node = FindNode( parent );
-        BuildBranch( parent_node );
+        wxASSERT_MSG(parent_node,
+            "Did you forget a call to ItemAdded()? The parent node is unknown to the wxGtkTreeModel");
 
-        // wxPrintf( "iter_nth_child %d\n", n );
+        BuildBranch( parent_node );
 
         iter->stamp = m_gtk_model->stamp;
         iter->user_data = parent_node->GetChildren().Item( n );
@@ -3479,12 +3761,15 @@ wxGtkTreeModelNode *wxDataViewCtrlInternal::FindNode( GtkTreeIter *iter )
 
     wxGtkTreeModelNode *result = wxDataViewCtrlInternal_FindNode( m_wx_model, m_root, item );
 
+/*
     if (!result)
     {
         wxLogDebug( "Not found %p", iter->user_data );
         char *crash = NULL;
         *crash = 0;
     }
+    // TODO: remove this code
+*/
 
     return result;
 }
@@ -3496,12 +3781,15 @@ wxGtkTreeModelNode *wxDataViewCtrlInternal::FindNode( const wxDataViewItem &item
 
     wxGtkTreeModelNode *result = wxDataViewCtrlInternal_FindNode( m_wx_model, m_root, item );
 
+/*
     if (!result)
     {
         wxLogDebug( "Not found %p", item.GetID() );
         char *crash = NULL;
         *crash = 0;
     }
+    // TODO: remove this code
+*/
 
     return result;
 }
@@ -3738,8 +4026,6 @@ gtk_dataview_motion_notify_callback( GtkWidget *WXUNUSED(widget),
             GtkTreeIter iter;
             dv->GtkGetInternal()->get_iter( &iter, path );
 
-            // wxPrintf( "mouse %d %d\n", (int) gdk_event->x, (int) gdk_event->y );
-
             gtk_tree_path_free( path );
         }
     }
@@ -3830,7 +4116,7 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id,
     m_widget = gtk_scrolled_window_new (NULL, NULL);
     g_object_ref(m_widget);
 
-    GtkScrolledWindowSetBorder(m_widget, style);
+    GTKScrolledWindowSetBorder(m_widget, style);
 
     m_treeview = gtk_tree_view_new();
     gtk_container_add (GTK_CONTAINER (m_widget), m_treeview);
@@ -3875,7 +4161,7 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id,
     gtk_tree_view_set_rules_hint( GTK_TREE_VIEW(m_treeview), (style & wxDV_ROW_LINES) != 0 );
 
     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_widget),
-        GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
+        GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
     gtk_widget_show (m_treeview);
 
     m_parent->DoAddChild( this );