+//-----------------------------------------------------------------------------
+// wxDataViewCtrlInternal
+//-----------------------------------------------------------------------------
+
+wxDataViewCtrlInternal::wxDataViewCtrlInternal( wxDataViewCtrl *owner,
+ wxDataViewModel *wx_model, GtkWxTreeModel *gtk_model )
+{
+ m_owner = owner;
+ m_wx_model = wx_model;
+ m_gtk_model = gtk_model;
+ m_root = NULL;
+ InitTree();
+}
+
+wxDataViewCtrlInternal::~wxDataViewCtrlInternal()
+{
+ g_object_unref( m_gtk_model );
+}
+
+void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode *node )
+{
+ if (node->GetChildCount() == 0)
+ {
+ wxDataViewItem child = m_wx_model->GetFirstChild( node->GetItem() );
+ while (child.IsOk())
+ {
+ // wxPrintf( "AddItem %d\n", (int) child.GetID() );
+ node->Append( new wxGtkTreeModelNode( node, child ) );
+ child = m_wx_model->GetNextSibling( child );
+ }
+ }
+}
+
+bool wxDataViewCtrlInternal::ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item )
+{
+ wxGtkTreeModelNode *parent_node = FindNode( parent );
+ parent_node->Append( new wxGtkTreeModelNode( parent_node, item ) );
+ return true;
+}
+
+bool wxDataViewCtrlInternal::ItemDeleted( const wxDataViewItem &item )
+{
+ wxGtkTreeModelNode *node = FindNode( item );
+ wxGtkTreeModelNode *parent = node->GetParent();
+ parent->GetChildren().Remove( node );
+ delete node;
+
+ return true;
+}
+
+gboolean wxDataViewCtrlInternal::get_iter( GtkTreeIter *iter, GtkTreePath *path )
+{
+ int depth = gtk_tree_path_get_depth( path );
+
+ wxGtkTreeModelNode *node = m_root;
+
+ int i;
+ for (i = 0; i < depth; i++)
+ {
+ BuildBranch( node );
+
+ gint pos = gtk_tree_path_get_indices (path)[i];
+ if (pos < 0) return FALSE;
+ if ((size_t)pos >= node->GetChildCount()) return FALSE;
+
+ node = node->GetChildren().Item( (size_t) pos );
+ }
+
+ iter->stamp = m_gtk_model->stamp;
+ iter->user_data = (gpointer) node->GetItem().GetID();
+
+ return TRUE;
+}
+
+GtkTreePath *wxDataViewCtrlInternal::get_path( GtkTreeIter *iter )
+{
+ GtkTreePath *retval = gtk_tree_path_new ();
+
+ wxGtkTreeModelNode *node = FindNode( iter );
+ while (node->GetParent())
+ {
+ wxGtkTreeModelNode *parent = node->GetParent();
+ int pos = parent->GetChildren().Index( node );
+
+ gtk_tree_path_prepend_index( retval, pos );
+
+ node = parent;
+ }
+
+ return retval;
+}
+
+gboolean wxDataViewCtrlInternal::iter_next( GtkTreeIter *iter )
+{
+ wxDataViewItem item( (void*) iter->user_data );
+ item = m_wx_model->GetNextSibling( item );
+ if (!item.IsOk())
+ return FALSE;
+
+ iter->user_data = (gpointer) item.GetID();
+
+ return TRUE;
+}
+
+gboolean wxDataViewCtrlInternal::iter_children( GtkTreeIter *iter, GtkTreeIter *parent )
+{
+ wxDataViewItem item( (void*) parent->user_data );
+
+ if (!m_wx_model->HasChildren( item ))
+ return FALSE;
+
+ wxGtkTreeModelNode *parent_node = FindNode( parent );
+ BuildBranch( parent_node );
+
+ wxGtkTreeModelNode *first_child_node = parent_node->GetChildren().Item( 0 );
+
+ iter->stamp = m_gtk_model->stamp;
+ iter->user_data = (gpointer) first_child_node->GetItem().GetID();
+
+ return TRUE;
+}
+
+gboolean wxDataViewCtrlInternal::iter_has_child( GtkTreeIter *iter )
+{
+ wxDataViewItem item( (void*) iter->user_data );
+
+ return m_wx_model->HasChildren( item );
+}
+
+gint wxDataViewCtrlInternal::iter_n_children( GtkTreeIter *iter )
+{
+ wxDataViewItem item( (void*) iter->user_data );
+
+ if (!m_wx_model->HasChildren( item ))
+ return 0;
+
+ wxGtkTreeModelNode *parent_node = FindNode( iter );
+ BuildBranch( parent_node );
+
+ return parent_node->GetChildCount();
+}
+
+gboolean wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter *iter, GtkTreeIter *parent, gint n )
+{
+ void* id = NULL;
+ if (parent) id = (void*) parent->user_data;
+ wxDataViewItem item( id );
+
+ if (!m_wx_model->HasChildren( item ))
+ return FALSE;
+
+ wxGtkTreeModelNode *parent_node = FindNode( parent );
+ BuildBranch( parent_node );
+
+ wxGtkTreeModelNode *child_node = parent_node->GetChildren().Item( (size_t) n );
+ if (!child_node)
+ return FALSE;
+
+ iter->stamp = m_gtk_model->stamp;
+ iter->user_data = (gpointer) child_node->GetItem().GetID();
+
+ return TRUE;
+}
+
+gboolean wxDataViewCtrlInternal::iter_parent( GtkTreeIter *iter, GtkTreeIter *child )
+{
+ wxDataViewItem item( (void*) child->user_data );
+
+ wxGtkTreeModelNode *node = FindNode( child );
+ node = node->GetParent();
+ if (!node)
+ return FALSE;
+
+ iter->stamp = m_gtk_model->stamp;
+ iter->user_data = (gpointer) node->GetItem().GetID();
+
+ return TRUE;
+}
+
+void wxDataViewCtrlInternal::InitTree()
+{
+ wxDataViewItem item;
+ m_root = new wxGtkTreeModelNode( NULL, item );
+
+ BuildBranch( m_root );
+}
+
+static wxGtkTreeModelNode*
+wxDataViewCtrlInternal_FindNode( wxGtkTreeModelNode *node, const wxDataViewItem &item )
+{
+ if (!node) return NULL;
+
+ size_t count = node->GetChildCount();
+ size_t i;
+ for (i = 0; i < count; i++)
+ {
+ wxGtkTreeModelNode *child = node->GetChildren().Item( i );
+ if (child->GetItem().GetID() == item.GetID())
+ return child;
+
+ wxGtkTreeModelNode *node2 = wxDataViewCtrlInternal_FindNode( child, item );
+ if (node2)
+ return node2;
+ }
+
+ return NULL;
+}
+
+wxGtkTreeModelNode *wxDataViewCtrlInternal::FindNode( GtkTreeIter *iter )
+{
+ if (!iter)
+ return m_root;
+
+ wxDataViewItem item( (void*) iter->user_data );
+
+ wxGtkTreeModelNode *result = wxDataViewCtrlInternal_FindNode( m_root, item );
+
+ if (!result)
+ {
+ wxPrintf( "Not found %d\n", (int) iter->user_data );
+ char *crash = NULL;
+ *crash = 0;
+ }
+
+ return result;
+}
+
+wxGtkTreeModelNode *wxDataViewCtrlInternal::FindNode( const wxDataViewItem &item )
+{
+ wxGtkTreeModelNode *result = wxDataViewCtrlInternal_FindNode( m_root, item );
+
+ if (!result)
+ {
+ wxPrintf( "Not found %d\n", (int) item.GetID() );
+ char *crash = NULL;
+ *crash = 0;
+ }
+
+ return result;
+}
+