// the expander space margin
static const int EXPANDER_MARGIN = 4;
-bool operator == ( const wxDataViewItem & left, const wxDataViewItem & right )
-{
- return left.GetID() == right.GetID();
-}
-
//-----------------------------------------------------------------------------
// wxDataViewHeaderWindow
//-----------------------------------------------------------------------------
void DestroyTree();
private:
wxDataViewTreeNode * GetTreeNodeByRow( unsigned int row );
- wxDataViewTreeNode * GetTreeNodeByItem( const wxDataViewItem & item ) { return NULL; }
+ wxDataViewTreeNode * GetTreeNodeByItem( const wxDataViewItem & item ){};
int RecalculateCount() ;
m_currentCol->GetRenderer()->StartEditing( m_currentRow, labelRect );
}
+//------------------------------------------------------------------
+// Helper class for do operation on the tree node
+//------------------------------------------------------------------
class DoJob
{
public:
DoJob(){};
- virtual ~DoJob() { }
-
- virtual bool operator() ( wxDataViewTreeNode * node ) = 0 ;
+ virtual ~DoJob(){};
+
+ //The return value control how the tree-walker tranverse the tree
+ // 0: Job done, stop tranverse and return
+ // 1: Ignore the current node's subtree and continue
+ // 2: Job not done, continue
+ enum { OK = 0 , IGR = 1, CONT = 2 };
+ virtual int operator() ( wxDataViewTreeNode * node ) = 0 ;
};
class ItemAddJob: public DoJob
{
public:
ItemAddJob( const wxDataViewItem & parent, const wxDataViewItem & item )
- { this->parent = parent ; this->item = item; }
- virtual ~ItemAddJob() { }
+ { this->parent = parent ; this->item = item ; }
+ virtual ~ItemAddJob(){};
- virtual bool operator() ( wxDataViewTreeNode * node )
+ virtual int operator() ( wxDataViewTreeNode * node )
{
if( node->GetItem() == parent )
{
wxDataViewTreeNode * newnode = new wxDataViewTreeNode( node );
newnode->SetItem(item);
node->AppendChild( newnode);
- return true;
+ return OK;
}
- return false;
+ return CONT;
}
-
private:
wxDataViewItem parent, item;
};
for( ; i < len ; i ++ )
{
wxDataViewTreeNode * n = nodes[i];
- if( func( n ) )
- return true;
- if( Walker( n , func ) )
- return true;
+ switch( func( n ) )
+ {
+ case DoJob::OK :
+ return true ;
+ case DoJob::IGR:
+ continue;
+ case DoJob::CONT:
+ default:
+ ;
+ }
+
+ if( Walker( n , func ) )
+ return true;
}
return false;
}
+
bool wxDataViewMainWindow::ItemAdded(const wxDataViewItem & parent, const wxDataViewItem & item)
{
ItemAddJob job( parent, item);
if( col->GetModelColumn() == GetOwner()->GetExpanderColumn() )
{
//Calculate the indent first
- indent = cell_rect.x + GetOwner()->GetIndent() * indent;
-
+ indent = cell_rect.x + GetOwner()->GetIndent() * indent;
+
int expander_width = m_lineHeight - 2*EXPANDER_MARGIN;
- // change the cell_rect.x to the appropriate pos
- int expander_x = indent + EXPANDER_MARGIN , expander_y = cell_rect.y + EXPANDER_MARGIN ;
+ // change the cell_rect.x to the appropriate pos
+ int expander_x = indent + EXPANDER_MARGIN , expander_y = cell_rect.y + EXPANDER_MARGIN ;
indent = indent + m_lineHeight ; //try to use the m_lineHeight as the expander space
dc.SetPen( m_penExpander );
- dc.SetBrush( wxNullBrush );
- if( node->HasChildren() )
- {
- dc.DrawRoundedRectangle( expander_x,expander_y,expander_width,expander_width, 1.0);
- dc.DrawLine( expander_x + 2 , expander_y + expander_width/2, expander_x + expander_width - 2, expander_y + expander_width/2 );
-
- if( !node->IsOpen() )
- dc.DrawLine( expander_x + expander_width/2, expander_y + 2, expander_x + expander_width/2, expander_y + expander_width -2 );
- }
- else
- {
- // I am wandering whether we should draw dot lines between tree nodes
- }
-
- //force the expander column to left-center align
- cell->SetAlignment( wxALIGN_CENTER_VERTICAL );
+ dc.SetBrush( wxNullBrush );
+ if( node->HasChildren() )
+ {
+ //dc.DrawRoundedRectangle( expander_x,expander_y,expander_width,expander_width, 1.0);
+ //dc.DrawLine( expander_x + 2 , expander_y + expander_width/2, expander_x + expander_width - 2, expander_y + expander_width/2 );
+ wxRect rect( expander_x , expander_y, expander_width, expander_width);
+ if( node->IsOpen() )
+ wxRendererNative::Get().DrawTreeItemButton( this, dc, rect, wxCONTROL_EXPANDED );
+ else
+ wxRendererNative::Get().DrawTreeItemButton( this, dc, rect );
+ }
+ else
+ {
+ // I am wandering whether we should draw dot lines between tree nodes
+ }
+
+ //force the expander column to left-center align
+ cell->SetAlignment( wxALIGN_CENTER_VERTICAL );
}
// cannot be bigger than allocated space
wxSize size = cell->GetSize();
- // Because of the tree structure indent, here we should minus the width of the cell for drawing
+ // Because of the tree structure indent, here we should minus the width of the cell for drawing
size.x = wxMin( size.x + 2*PADDING_RIGHTLEFT, cell_rect.width - indent );
size.y = wxMin( size.y + 2*PADDING_TOPBOTTOM, cell_rect.height );
if ( m_count == -1 )
{
m_count = RecalculateCount();
- int width, height;
- GetVirtualSize( &width, &height );
+ int width, height;
+ GetVirtualSize( &width, &height );
height = m_count * m_lineHeight;
SetVirtualSize( width, height );
RowToItemJob( unsigned int row , int current ) { this->row = row; this->current = current ;}
virtual ~RowToItemJob(){};
- virtual bool operator() ( wxDataViewTreeNode * node )
+ virtual int operator() ( wxDataViewTreeNode * node )
{
- if ( current == row)
- {
- ret = node->GetItem() ;
- return true;
- }
- current ++;
- return false;
- }
-
- wxDataViewItem GetResult() { return ret; }
-
+ if( current == row)
+ {
+ ret = node->GetItem() ;
+ return DoJob::OK;
+ }
+ current ++;
+ if ( node->IsOpen())
+ return DoJob::CONT;
+ else
+ return DoJob::IGR;
+ }
+
+ wxDataViewItem GetResult(){ return ret; }
private:
unsigned int row;
int current ;
class RowToTreeNodeJob: public DoJob
{
public:
- RowToTreeNodeJob( unsigned int row , int current )
- { this->row = row; this->current = current ; ret = NULL ; }
- virtual ~RowToTreeNodeJob() { }
+ RowToTreeNodeJob( unsigned int row , int current ) { this->row = row; this->current = current ; ret = NULL ; }
+ virtual ~RowToTreeNodeJob(){};
virtual int operator() ( wxDataViewTreeNode * node )
- {
- if( current == row)
- {
- ret = node ;
- return DoJob::OK;
- }
- current ++;
- if ( node->IsOpen())
- return DoJob::CONT;
- else
- return DoJob::IGR;
+ {
+ if( current == row)
+ {
+ ret = node ;
+ return DoJob::OK;
}
+ current ++;
+ if ( node->IsOpen())
+ return DoJob::CONT;
+ else
+ return DoJob::IGR;
+ }
wxDataViewTreeNode * GetResult(){ return ret; }
private:
{
public:
CountJob(){ count = 0 ; }
- virtual ~CountJob() { }
+ virtual ~CountJob(){};
virtual int operator () ( wxDataViewTreeNode * node )
{
- count ++;
- if (node->IsOpen())
- return DoJob::CONT;
- else
- return DoJob::IGR;
+ count ++;
+ if ( node->IsOpen())
+ return DoJob::CONT;
+ else
+ return DoJob::IGR;
}
unsigned int GetResult()
wxDataViewTreeNode * node = GetTreeNodeByRow(row);
if( node != NULL )
{
- if (node->HasChildren())
- if (!node->IsOpen())
+ if( node->HasChildren())
+ if( !node->IsOpen())
{
- node->ToggleOpen();
- m_count = -1;
- Refresh();
- // RefreshRows(row,GetLastVisibleRow());
+ node->ToggleOpen();
+ m_count = -1;
+ Refresh();
+ //RefreshRows(row,GetLastVisibleRow());
}
}
}
void wxDataViewMainWindow::OnCollapsing(unsigned int row)
{
wxDataViewTreeNode * node = GetTreeNodeByRow(row);
- if (node != NULL)
+ if( node != NULL )
{
if( node->HasChildren() && node->IsOpen() )
{
m_count = -1;
Refresh();
//RefreshRows(row,GetLastVisibleRow());
- }
- else
- {
- node = node->GetParent();
- if( node != NULL )
- {
- int parent = GetRowByItem( node->GetItem()) ;
- SelectRow( row, false);
- SelectRow(parent , true );
- ChangeCurrentRow( parent );
- }
- }
+ }
+ else
+ {
+ node = node->GetParent();
+ if( node != NULL )
+ {
+ int parent = GetRowByItem( node->GetItem()) ;
+ SelectRow( row, false);
+ SelectRow(parent , true );
+ ChangeCurrentRow( parent );
+ }
+ }
}
}
ItemToRowJob(const wxDataViewItem & item){ this->item = item ; ret = 0 ; }
virtual ~ItemToRowJob(){};
- virtual bool operator() ( wxDataViewTreeNode * node)
- {
- ret ++;
- if( node->GetItem() == item )
- return true;
- return false;
- }
+ virtual int operator() ( wxDataViewTreeNode * node)
+ {
+ ret ++;
+ if( node->GetItem() == item )
+ return DoJob::OK;
+
+ if( node->IsOpen())
+ return DoJob::CONT;
+ else
+ return DoJob::IGR;
+ }
//the row number is begin from zero
int GetResult(){ return ret -1 ; }
}
//Process the event of user clicking the expander
- bool expander = false;
- wxDataViewTreeNode * node = GetTreeNodeByRow(current);
- if( node!=NULL && node->HasChildren() )
- {
- int indent = node->GetIndentLevel();
- indent = GetOwner()->GetIndent()*indent;
- wxRect rect( xpos + indent + EXPANDER_MARGIN, current * m_lineHeight + EXPANDER_MARGIN, m_lineHeight-2*EXPANDER_MARGIN,m_lineHeight-2*EXPANDER_MARGIN);
- if( rect.Contains( x, y) )
- {
- expander = true;
- node->ToggleOpen();
- m_count = -1; //make the current row number fail
+ bool expander = false;
+ wxDataViewTreeNode * node = GetTreeNodeByRow(current);
+ if( node!=NULL && node->HasChildren() )
+ {
+ int indent = node->GetIndentLevel();
+ indent = GetOwner()->GetIndent()*indent;
+ wxRect rect( xpos + indent + EXPANDER_MARGIN, current * m_lineHeight + EXPANDER_MARGIN, m_lineHeight-2*EXPANDER_MARGIN,m_lineHeight-2*EXPANDER_MARGIN);
+ if( rect.Contains( x, y) )
+ {
+ expander = true;
+ node->ToggleOpen();
+ m_count = -1; //make the current row number fail
- Refresh();
- //int last_row = GetLastVisibleRow();
- //RefreshRows( current, last_row );
- }
- }
+ Refresh();
+ //int last_row = GetLastVisibleRow();
+ //RefreshRows( current, last_row );
+ }
+ }
//If the user click the expander, we do not do editing even if the column with expander are editable
if (m_lastOnSame && !expander )
class wxGtkTreeModelNode
{
public:
- wxGtkTreeModelNode( wxGtkTreeModelNode* parent )
+ wxGtkTreeModelNode( wxGtkTreeModelNode* parent, const wxDataViewItem &item )
{
m_parent = parent;
+ m_item = item;
}
~wxGtkTreeModelNode()
unsigned int GetChildCount() { return m_children.GetCount(); }
wxDataViewItem &GetItem() { return m_item; }
- void SetItem( wxDataViewItem& item ) { m_item = item; }
bool HasChildren() { return m_hasChildren; }
void SetHasChildren( bool has ) { m_hasChildren = has; }
class wxGtkTreeModel
{
public:
- wxGtkTreeModel( wxDataViewModel *wx_model, GtkWxTreeModel *gtk_model )
- {
- m_wx_model = wx_model;
- m_gtk_model = gtk_model;
- m_root = NULL;
- InitTree();
- }
-
+ wxGtkTreeModel( wxDataViewModel *wx_model, GtkWxTreeModel *owner );
~wxGtkTreeModel();
gboolean get_iter( GtkTreeIter *iter, GtkTreePath *path );
gboolean iter_nth_child( GtkTreeIter *iter, GtkTreeIter *parent, gint n );
gboolean iter_parent( GtkTreeIter *iter, GtkTreeIter *child );
+ wxDataViewModel* GetDataViewModel() { return m_wx_model; }
+ GtkWxTreeModel* GetOwner() { return m_owner; }
+
protected:
void InitTree();
wxGtkTreeModelNode *FindNode( GtkTreeIter *iter );
+ void BuildBranch( wxGtkTreeModelNode *branch );
private:
wxGtkTreeModelNode *m_root;
wxDataViewModel *m_wx_model;
- GtkWxTreeModel *m_gtk_model;
+ GtkWxTreeModel *m_owner;
};
//-----------------------------------------------------------------------------
/*< private >*/
gint stamp;
- wxDataViewModel *model;
+ wxGtkTreeModel *model;
gint sort_column_id;
GtkSortType order;
- GtkTreeIterCompareFunc default_sort_func;
- GtkTreeIterCompareFunc sort_func;
};
struct _GtkWxTreeModelClass
tree_model->stamp = g_random_int();
tree_model->sort_column_id = -2;
tree_model->order = GTK_SORT_ASCENDING;
- tree_model->sort_func = NULL;
- tree_model->default_sort_func = NULL;
}
static void
wxgtk_tree_model_finalize (GObject *object)
{
- /* GtkWxTreeModel *tree_model = GTK_WX_LIST_STORE (object); */
+ GtkWxTreeModel *tree_model = GTK_WX_TREE_MODEL(object);
/* we need to sort out, which class deletes what */
- /* delete tree_model->model; */
+ delete tree_model->model;
/* must chain up */
(* list_parent_class->finalize) (object);
GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model;
g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), 0);
- return wxtree_model->model->GetColumnCount();
+ return wxtree_model->model->GetDataViewModel()->GetColumnCount();
}
static GType
GType gtype = G_TYPE_INVALID;
- wxString wxtype = wxtree_model->model->GetColumnType( (unsigned int) index );
+ wxString wxtype = wxtree_model->model->GetDataViewModel()->GetColumnType( (unsigned int) index );
if (wxtype == wxT("string"))
gtype = G_TYPE_STRING;
g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE);
g_return_val_if_fail (gtk_tree_path_get_depth (path) > 0, FALSE);
- wxDataViewModel *model = wxtree_model->model;
-
- int depth = gtk_tree_path_get_depth( path );
-
- wxDataViewItem item;
-
- int i;
- for (i = 0; i < depth; i++)
- {
- gint pos = gtk_tree_path_get_indices (path)[i];
- item = model->GetNthChild( item, (unsigned int) pos );
-
- if (!item.IsOk())
- return FALSE;
- }
-
- iter->stamp = wxtree_model->stamp;
- iter->user_data = (gpointer) item.GetID();
-
- return TRUE;
+ return wxtree_model->model->get_iter( iter, path );
}
static GtkTreePath *
g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), NULL);
g_return_val_if_fail (iter->stamp == GTK_WX_TREE_MODEL (wxtree_model)->stamp, NULL);
- GtkTreePath *retval = gtk_tree_path_new ();
- wxDataViewItem item( (wxUint32) iter->user_data );
-
- wxDataViewModel *model = wxtree_model->model;
-
- while (item.IsOk())
- {
- int n = 0;
- wxDataViewItem parent = model->GetParent( item );
-
- if (!parent.IsOk())
- wxPrintf( wxT("wrong parent\n") );
-
- wxDataViewItem node = model->GetFirstChild( parent );
-
- while (node.GetID() != item.GetID())
- {
- node = model->GetNextSibling( node );
-
- if (!node.IsOk())
- wxPrintf( wxT("wrong node\n") );
-
- n++;
- }
-
- gtk_tree_path_prepend_index( retval, n );
-
- item = model->GetParent( item );
- }
-
- return retval;
+ return wxtree_model->model->get_path( iter );
}
static void
GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model;
g_return_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model) );
- wxDataViewModel *model = wxtree_model->model;
+ wxDataViewModel *model = wxtree_model->model->GetDataViewModel();
wxString mtype = model->GetColumnType( (unsigned int) column );
if (mtype == wxT("string"))
{
{
GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model;
g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE);
-
g_return_val_if_fail (wxtree_model->stamp == iter->stamp, FALSE);
- wxDataViewModel *model = wxtree_model->model;
-
- wxDataViewItem item( (wxUint32) iter->user_data );
- item = model->GetNextSibling( item );
- if (!item.IsOk())
- return FALSE;
-
- iter->user_data = (gpointer) item.GetID();
-
- return TRUE;
+ return wxtree_model->model->iter_next( iter );
}
static gboolean
{
GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model;
g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE);
-
g_return_val_if_fail (wxtree_model->stamp == parent->stamp, FALSE);
-
- wxDataViewModel *model = wxtree_model->model;
-
- wxDataViewItem item( (wxUint32) parent->user_data );
- item = model->GetFirstChild( item );
- if (!item.IsOk())
- return FALSE;
- iter->stamp = wxtree_model->stamp;
- iter->user_data = (gpointer) item.GetID();
-
- return TRUE;
+ return wxtree_model->model->iter_children( iter, parent );
}
static gboolean
{
GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model;
g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE);
-
g_return_val_if_fail (wxtree_model->stamp == iter->stamp, FALSE);
-
- wxDataViewModel *model = wxtree_model->model;
-
- wxDataViewItem item( (wxUint32) iter->user_data );
-
- return model->HasChildren( item );
+
+ return wxtree_model->model->iter_has_child( iter );
}
static gint
{
GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model;
g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE);
-
g_return_val_if_fail (wxtree_model->stamp == iter->stamp, 0);
-
- wxDataViewModel *model = wxtree_model->model;
-
- wxDataViewItem item( (wxUint32) iter->user_data );
-
- return model->GetChildCount( item );
+
+ return wxtree_model->model->iter_n_children( iter );
}
static gboolean
GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model;
g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE);
- wxDataViewModel *model = wxtree_model->model;
-
- if (!parent)
- {
- wxDataViewItem item;
- item = model->GetNthChild( item, n );
-
- if (!item.IsOk())
- return FALSE;
-
- iter->stamp = wxtree_model->stamp;
- iter->user_data = (gpointer) item.GetID();
- }
- else
- {
- g_return_val_if_fail (wxtree_model->stamp == parent->stamp, FALSE);
-
- wxDataViewItem item( (wxUint32) parent->user_data );
- item = model->GetNthChild( item, n );
-
- if (!item.IsOk())
- return FALSE;
-
- iter->stamp = wxtree_model->stamp;
- iter->user_data = (gpointer) item.GetID();
- }
-
- return TRUE;
+ return wxtree_model->model->iter_nth_child( iter, parent, n );
}
static gboolean
{
GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model;
g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE);
-
g_return_val_if_fail (wxtree_model->stamp == child->stamp, FALSE);
- wxDataViewModel *model = wxtree_model->model;
-
- wxDataViewItem item( (wxUint32) child->user_data );
- item = model->GetParent( item );
-
- if (!item.IsOk())
- return FALSE;
-
- iter->stamp = wxtree_model->stamp;
- iter->user_data = (gpointer) item.GetID();
-
- return TRUE;
+ return wxtree_model->model->iter_parent( iter, child );
}
/* sortable */
(tree_model->order == order))
return;
- if (sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
- {
- g_return_if_fail (tree_model->default_sort_func != NULL);
- }
-
tree_model->sort_column_id = sort_column_id;
tree_model->order = order;
gpointer data,
GtkDestroyNotify destroy)
{
- GtkWxTreeModel *tree_model = (GtkWxTreeModel *) sortable;
-
g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable) );
g_return_if_fail (func != NULL);
- tree_model->sort_func = func;
-
wxPrintf( "wxgtk_tree_model_set_sort_func, sort_column_id = %d\n", sort_column_id );
// sort
}
gpointer data,
GtkDestroyNotify destroy)
{
- GtkWxTreeModel *tree_model = (GtkWxTreeModel *) sortable;
-
g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable) );
-
g_return_if_fail (func != NULL);
- tree_model->default_sort_func = func;
-
wxPrintf( "wxgtk_tree_model_set_default_sort_func\n" );
}
return FALSE;
}
+
+//-----------------------------------------------------------------------------
+// wxGtkTreeModel
+//-----------------------------------------------------------------------------
+
+wxGtkTreeModel::wxGtkTreeModel( wxDataViewModel *wx_model, GtkWxTreeModel *owner )
+{
+ m_wx_model = wx_model;
+ m_owner = owner;
+ m_root = NULL;
+ InitTree();
+}
+
+wxGtkTreeModel::~wxGtkTreeModel()
+{
+}
+
+void wxGtkTreeModel::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 );
+ }
+ }
+}
+
+gboolean wxGtkTreeModel::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_owner->stamp;
+ iter->user_data = (gpointer) node->GetItem().GetID();
+
+ return TRUE;
+}
+
+GtkTreePath *wxGtkTreeModel::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( parent );
+
+ gtk_tree_path_prepend_index( retval, pos );
+
+ node = parent;
+ }
+
+ return retval;
+}
+
+gboolean wxGtkTreeModel::iter_next( GtkTreeIter *iter )
+{
+ wxDataViewItem item( (wxUint32) iter->user_data );
+ item = m_wx_model->GetNextSibling( item );
+ if (!item.IsOk())
+ return FALSE;
+
+ iter->user_data = (gpointer) item.GetID();
+
+ return TRUE;
+}
+
+gboolean wxGtkTreeModel::iter_children( GtkTreeIter *iter, GtkTreeIter *parent )
+{
+ wxDataViewItem item( (wxUint32) 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_owner->stamp;
+ iter->user_data = (gpointer) first_child_node->GetItem().GetID();
+
+ return TRUE;
+}
+
+gboolean wxGtkTreeModel::iter_has_child( GtkTreeIter *iter )
+{
+ wxDataViewItem item( (wxUint32) iter->user_data );
+
+ return m_wx_model->HasChildren( item );
+}
+
+gint wxGtkTreeModel::iter_n_children( GtkTreeIter *iter )
+{
+ wxDataViewItem item( (wxUint32) iter->user_data );
+
+ if (!m_wx_model->HasChildren( item ))
+ return 0;
+
+ wxGtkTreeModelNode *parent_node = FindNode( iter );
+ BuildBranch( parent_node );
+
+ return parent_node->GetChildCount();
+}
+
+gboolean wxGtkTreeModel::iter_nth_child( GtkTreeIter *iter, GtkTreeIter *parent, gint n )
+{
+ wxUint32 id = 0;
+ if (parent) id = (wxUint32) 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_owner->stamp;
+ iter->user_data = (gpointer) child_node->GetItem().GetID();
+
+ return TRUE;
+}
+
+gboolean wxGtkTreeModel::iter_parent( GtkTreeIter *iter, GtkTreeIter *child )
+{
+ wxDataViewItem item( (wxUint32) child->user_data );
+
+ wxGtkTreeModelNode *node = FindNode( child );
+ node = node->GetParent();
+ if (!node)
+ return FALSE;
+
+ iter->stamp = m_owner->stamp;
+ iter->user_data = (gpointer) node->GetItem().GetID();
+
+ return TRUE;
+}
+
+void wxGtkTreeModel::InitTree()
+{
+ wxDataViewItem item;
+ m_root = new wxGtkTreeModelNode( NULL, item );
+
+ BuildBranch( m_root );
+}
+
+static wxGtkTreeModelNode*
+wxGtkTreeModel_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 = wxGtkTreeModel_FindNode( child, item );
+ if (node2)
+ return node2;
+ }
+
+ return NULL;
+}
+
+wxGtkTreeModelNode *wxGtkTreeModel::FindNode( GtkTreeIter *iter )
+{
+ if (!iter)
+ return m_root;
+
+ wxDataViewItem item( (wxUint32) iter->user_data );
+
+ wxGtkTreeModelNode *result = wxGtkTreeModel_FindNode( m_root, item );
+
+ if (!result)
+ {
+ wxPrintf( "Not found %d\n", (int) iter->user_data );
+ char *crash = NULL;
+ *crash = 0;
+ }
+
+ return result;
+}
+
//-----------------------------------------------------------------------------
// define new GTK+ class wxGtkRendererRenderer
//-----------------------------------------------------------------------------
wxDataViewItem item( (wxUint32) iter->user_data );
wxVariant value;
- tree_model->model->GetValue( value, item, cell->GetOwner()->GetModelColumn() );
+ tree_model->model->GetDataViewModel()->GetValue( value, item, cell->GetOwner()->GetModelColumn() );
if (value.GetType() != cell->GetVariantType())
wxLogError( wxT("Wrong type, required: %s but: %s"),
if (!wxDataViewCtrlBase::AssociateModel( model ))
return false;
- GtkWxTreeModel *gtk_store = wxgtk_tree_model_new();
- gtk_store->model = model;
+ GtkWxTreeModel *gtkwx_tree_model = wxgtk_tree_model_new();
+ wxGtkTreeModel *wxgtk_tree_model = new wxGtkTreeModel( model, gtkwx_tree_model );
+
+ gtkwx_tree_model->model = wxgtk_tree_model;
- m_notifier = new wxGtkDataViewModelNotifier( gtk_store, model, this );
+ m_notifier = new wxGtkDataViewModelNotifier( gtkwx_tree_model, model, this );
model->AddNotifier( m_notifier );
- gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview), GTK_TREE_MODEL(gtk_store) );
- g_object_unref( gtk_store );
+ gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview), GTK_TREE_MODEL(gtkwx_tree_model) );
+ g_object_unref( gtkwx_tree_model );
return true;
}