#include "wx/calctrl.h"
#include "wx/popupwin.h"
#include "wx/icon.h"
+#include "wx/list.h"
+#include "wx/listimpl.cpp"
#include "wx/gtk/private.h"
#include <gdk/gdkkeysyms.h>
//-----------------------------------------------------------------------------
-// classes
//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// wxGtkTreeModelNode
-//-----------------------------------------------------------------------------
+wxDataViewModel *g_model = NULL;
class wxGtkTreeModelNode;
-WX_DEFINE_ARRAY_PTR( wxGtkTreeModelNode*, wxGtkTreeModelNodes );
-
-class wxGtkTreeModelNode
-{
-public:
- wxGtkTreeModelNode( wxGtkTreeModelNode* parent, const wxDataViewItem &item )
- {
- m_parent = parent;
- m_item = item;
- }
-
- ~wxGtkTreeModelNode()
- {
- size_t count = m_children.GetCount();
- size_t i;
- for (i = 0; i < count; i++)
- {
- wxGtkTreeModelNode *child = m_children[i];
- delete child;
- }
- }
-
- wxGtkTreeModelNode* GetParent()
- { return m_parent; }
- wxGtkTreeModelNodes &GetChildren()
- { return m_children; }
- wxGtkTreeModelNode* GetNthChild( unsigned int n )
- { return m_children.Item( n ); }
- void Insert( wxGtkTreeModelNode* child, unsigned int n)
- { m_children.Insert( child, n); }
- void Append( wxGtkTreeModelNode* child )
- { m_children.Add( child ); }
-
- unsigned int GetChildCount() { return m_children.GetCount(); }
-
- wxDataViewItem &GetItem() { return m_item; }
-
- bool HasChildren() { return m_hasChildren; }
- void SetHasChildren( bool has ) { m_hasChildren = has; }
-
-private:
- wxGtkTreeModelNode *m_parent;
- wxGtkTreeModelNodes m_children;
- wxDataViewItem m_item;
- bool m_hasChildren;
-};
-
extern "C" {
typedef struct _GtkWxTreeModel GtkWxTreeModel;
}
-class wxGtkTreeModel
+//-----------------------------------------------------------------------------
+// wxDataViewCtrlInternal
+//-----------------------------------------------------------------------------
+
+WX_DECLARE_LIST(wxDataViewItem, ItemList);
+WX_DEFINE_LIST(ItemList);
+
+class wxDataViewCtrlInternal
{
public:
- wxGtkTreeModel( wxDataViewModel *wx_model, GtkWxTreeModel *owner );
- ~wxGtkTreeModel();
+ wxDataViewCtrlInternal( wxDataViewCtrl *owner, wxDataViewModel *wx_model, GtkWxTreeModel *owner );
+ ~wxDataViewCtrlInternal();
gboolean get_iter( GtkTreeIter *iter, GtkTreePath *path );
GtkTreePath *get_path( GtkTreeIter *iter);
+ GtkTreePath *get_path_safe( GtkTreeIter *iter);
gboolean iter_next( GtkTreeIter *iter );
gboolean iter_children( GtkTreeIter *iter, GtkTreeIter *parent);
gboolean iter_has_child( GtkTreeIter *iter );
gboolean iter_parent( GtkTreeIter *iter, GtkTreeIter *child );
wxDataViewModel* GetDataViewModel() { return m_wx_model; }
- GtkWxTreeModel* GetOwner() { return m_owner; }
+ wxDataViewCtrl* GetOwner() { return m_owner; }
+ GtkWxTreeModel* GetGtkModel() { return m_gtk_model; }
bool ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item );
- bool ItemDeleted( const wxDataViewItem &item );
+ bool ItemDeleted( const wxDataViewItem &parent, const wxDataViewItem &item );
+ bool ItemChanged( const wxDataViewItem &item );
+ bool ValueChanged( const wxDataViewItem &item, unsigned int col );
+ bool Cleared();
+ void Resort();
protected:
void InitTree();
wxGtkTreeModelNode *FindNode( const wxDataViewItem &item );
wxGtkTreeModelNode *FindNode( GtkTreeIter *iter );
+ wxGtkTreeModelNode *FindParentNode( const wxDataViewItem &item );
+ wxGtkTreeModelNode *FindParentNode( GtkTreeIter *iter );
void BuildBranch( wxGtkTreeModelNode *branch );
private:
wxGtkTreeModelNode *m_root;
wxDataViewModel *m_wx_model;
- GtkWxTreeModel *m_owner;
+ GtkWxTreeModel *m_gtk_model;
+ wxDataViewCtrl *m_owner;
+};
+
+
+//-----------------------------------------------------------------------------
+// wxGtkTreeModelNode
+//-----------------------------------------------------------------------------
+
+int LINKAGEMODE wxGtkTreeModelNodeCmp( void *id1, void *id2 );
+
+WX_DEFINE_ARRAY_PTR( wxGtkTreeModelNode*, wxGtkTreeModelNodes );
+WX_DEFINE_SORTED_ARRAY( void* , wxGtkTreeModelChildren );
+
+class wxGtkTreeModelNode
+{
+public:
+ wxGtkTreeModelNode( wxGtkTreeModelNode* parent, const wxDataViewItem &item,
+ wxDataViewCtrlInternal *internal )
+ {
+ m_parent = parent;
+ m_item = item;
+ m_internal = internal;
+ g_model = internal->GetDataViewModel();
+ m_children = new wxGtkTreeModelChildren( wxGtkTreeModelNodeCmp );
+ }
+
+ ~wxGtkTreeModelNode()
+ {
+ g_model = m_internal->GetDataViewModel();
+ size_t count = m_children->GetCount();
+ size_t i;
+ for (i = 0; i < count; i++)
+ {
+ wxGtkTreeModelNode *child = m_nodes.Item( i );
+ delete child;
+ }
+ delete m_children;
+ }
+
+ unsigned int AddNode( wxGtkTreeModelNode* child )
+ {
+ g_model = m_internal->GetDataViewModel();
+ m_nodes.Add( child );
+ return m_children->Add( child->GetItem().GetID() );
+ }
+
+ unsigned int AddLeave( void* id )
+ {
+ g_model = m_internal->GetDataViewModel();
+ return m_children->Add( id );
+ }
+
+ void DeleteChild( void* id )
+ {
+ g_model = m_internal->GetDataViewModel();
+ size_t pos;
+ size_t count = m_children->GetCount();
+ for (pos = 0; pos < count; pos++)
+ {
+ if (m_children->Item( pos ) == id)
+ {
+ m_children->RemoveAt( pos );
+ break;
+ }
+ }
+ count = m_nodes.GetCount();
+ for (pos = 0; pos < count; pos++)
+ {
+ wxGtkTreeModelNode *node = m_nodes.Item( pos );
+ if (node->GetItem().GetID() == id)
+ {
+ m_nodes.RemoveAt( pos );
+ delete node;
+ break;
+ }
+ }
+
+ }
+
+ wxGtkTreeModelNode* GetParent()
+ { return m_parent; }
+ wxGtkTreeModelNodes &GetNodes()
+ { return m_nodes; }
+ wxGtkTreeModelChildren &GetChildren()
+ { return *m_children; }
+
+ unsigned int GetChildCount() { return m_children->GetCount(); }
+ unsigned int GetNodesCount() { return m_nodes.GetCount(); }
+
+ wxDataViewItem &GetItem() { return m_item; }
+ wxDataViewCtrlInternal *GetInternal() { return m_internal; }
+
+ void Resort();
+
+private:
+ wxGtkTreeModelNode *m_parent;
+ wxGtkTreeModelNodes m_nodes;
+ wxGtkTreeModelChildren *m_children;
+ wxDataViewItem m_item;
+ wxDataViewCtrlInternal *m_internal;
};
+
+int LINKAGEMODE wxGtkTreeModelNodeCmp( void* id1, void* id2 )
+{
+ return g_model->Compare( id1, id2 );
+}
+
//-----------------------------------------------------------------------------
// data
//-----------------------------------------------------------------------------
/*< private >*/
gint stamp;
- wxGtkTreeModel *model;
-
- gint sort_column_id;
- GtkSortType order;
+ wxDataViewCtrlInternal *internal;
};
struct _GtkWxTreeModelClass
GtkTreePath *path);
static GtkTreePath *wxgtk_tree_model_get_path (GtkTreeModel *tree_model,
GtkTreeIter *iter);
+static GtkTreePath *wxgtk_tree_model_get_path_safe (GtkTreeModel *tree_model,
+ GtkTreeIter *iter);
static void wxgtk_tree_model_get_value (GtkTreeModel *tree_model,
GtkTreeIter *iter,
gint column,
static void
wxgtk_tree_model_init (GtkWxTreeModel *tree_model)
{
- tree_model->model = NULL;
+ tree_model->internal = NULL;
tree_model->stamp = g_random_int();
- tree_model->sort_column_id = -2;
- tree_model->order = GTK_SORT_ASCENDING;
}
static void
wxgtk_tree_model_finalize (GObject *object)
{
- GtkWxTreeModel *tree_model = GTK_WX_TREE_MODEL(object);
-
- /* we need to sort out, which class deletes what */
- 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->GetDataViewModel()->GetColumnCount();
+ return wxtree_model->internal->GetDataViewModel()->GetColumnCount();
}
static GType
GType gtype = G_TYPE_INVALID;
- wxString wxtype = wxtree_model->model->GetDataViewModel()->GetColumnType( (unsigned int) index );
+ wxString wxtype = wxtree_model->internal->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);
- return wxtree_model->model->get_iter( iter, path );
+ return wxtree_model->internal->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);
- return wxtree_model->model->get_path( iter );
+ return wxtree_model->internal->get_path( iter );
+}
+
+static GtkTreePath *
+wxgtk_tree_model_get_path_safe (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ GtkWxTreeModel *wxtree_model = (GtkWxTreeModel *) tree_model;
+ 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);
+
+ return wxtree_model->internal->get_path_safe( 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->GetDataViewModel();
+ wxDataViewModel *model = wxtree_model->internal->GetDataViewModel();
wxString mtype = model->GetColumnType( (unsigned int) column );
if (mtype == wxT("string"))
{
g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE);
g_return_val_if_fail (wxtree_model->stamp == iter->stamp, FALSE);
- return wxtree_model->model->iter_next( iter );
+ return wxtree_model->internal->iter_next( iter );
}
static gboolean
g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE);
g_return_val_if_fail (wxtree_model->stamp == parent->stamp, FALSE);
- return wxtree_model->model->iter_children( iter, parent );
+ return wxtree_model->internal->iter_children( iter, parent );
}
static gboolean
g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE);
g_return_val_if_fail (wxtree_model->stamp == iter->stamp, FALSE);
- return wxtree_model->model->iter_has_child( iter );
+ return wxtree_model->internal->iter_has_child( iter );
}
static gint
g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE);
g_return_val_if_fail (wxtree_model->stamp == iter->stamp, 0);
- return wxtree_model->model->iter_n_children( iter );
+ return wxtree_model->internal->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);
- return wxtree_model->model->iter_nth_child( iter, parent, n );
+ return wxtree_model->internal->iter_nth_child( iter, parent, n );
}
static gboolean
g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model), FALSE);
g_return_val_if_fail (wxtree_model->stamp == child->stamp, FALSE);
- return wxtree_model->model->iter_parent( iter, child );
+ return wxtree_model->internal->iter_parent( iter, child );
}
/* sortable */
g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (sortable), FALSE);
- if (tree_model->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
- return FALSE;
-
if (sort_column_id)
- *sort_column_id = tree_model->sort_column_id;
+ *sort_column_id = tree_model->internal->GetDataViewModel()->GetSortingColumn();
if (order)
- *order = tree_model->order;
+ {
+ bool ascending = tree_model->internal->GetDataViewModel()->GetSortOrderAscending();
+ if (ascending)
+ *order = GTK_SORT_ASCENDING;
+ else
+ *order = GTK_SORT_DESCENDING;
+ }
return TRUE;
}
GtkSortType order)
{
GtkWxTreeModel *tree_model = (GtkWxTreeModel *) sortable;
-
g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable) );
- if ((tree_model->sort_column_id == sort_column_id) &&
- (tree_model->order == order))
- return;
-
- tree_model->sort_column_id = sort_column_id;
- tree_model->order = order;
+ bool ascending = TRUE;
+ if (order != GTK_SORT_ASCENDING)
+ ascending = FALSE;
+ if ((sort_column_id == (gint) tree_model->internal->GetDataViewModel()->GetSortingColumn()) &&
+ (ascending == tree_model->internal->GetDataViewModel()->GetSortOrderAscending()))
+ return;
+
+ tree_model->internal->GetDataViewModel()->SetSortingColumn( sort_column_id );
+
+ tree_model->internal->GetDataViewModel()->SetSortOrderAscending( ascending );
+
gtk_tree_sortable_sort_column_changed (sortable);
-
- wxPrintf( "wxgtk_tree_model_set_column_id, sort_column_id = %d, order = %d\n", sort_column_id, (int)order );
- // sort
+
+ tree_model->internal->GetDataViewModel()->Resort();
}
void wxgtk_tree_model_set_sort_func (GtkTreeSortable *sortable,
{
g_return_if_fail (GTK_IS_WX_TREE_MODEL (sortable) );
g_return_if_fail (func != NULL);
-
- wxPrintf( "wxgtk_tree_model_set_sort_func, sort_column_id = %d\n", sort_column_id );
- // sort
}
void wxgtk_tree_model_set_default_sort_func (GtkTreeSortable *sortable,
return FALSE;
}
-
//-----------------------------------------------------------------------------
-// wxGtkTreeModel
+// define new GTK+ class wxGtkRendererRenderer
//-----------------------------------------------------------------------------
-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 );
- }
- }
-}
+extern "C" {
-bool wxGtkTreeModel::ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item )
-{
- wxGtkTreeModelNode *parent_node = FindNode( parent );
- parent_node->Append( new wxGtkTreeModelNode( parent_node, item ) );
- return true;
-}
+#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;
-bool wxGtkTreeModel::ItemDeleted( const wxDataViewItem &item )
+struct _GtkWxCellRenderer
{
- wxGtkTreeModelNode *node = FindNode( item );
- wxGtkTreeModelNode *parent = node->GetParent();
- parent->GetChildren().Remove( node );
- delete node;
+ GtkCellRenderer parent;
- return true;
-}
+ /*< private >*/
+ wxDataViewCustomRenderer *cell;
+ guint32 last_click;
+};
-gboolean wxGtkTreeModel::get_iter( GtkTreeIter *iter, GtkTreePath *path )
+struct _GtkWxCellRendererClass
{
- int depth = gtk_tree_path_get_depth( path );
+ GtkCellRendererClass cell_parent_class;
+};
- 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 );
- }
+static GtkCellRenderer *gtk_wx_cell_renderer_new (void);
+static void gtk_wx_cell_renderer_init (
+ GtkWxCellRenderer *cell );
+static void gtk_wx_cell_renderer_class_init(
+ GtkWxCellRendererClass *klass );
+static void gtk_wx_cell_renderer_finalize (
+ GObject *object );
+static void gtk_wx_cell_renderer_get_size (
+ GtkCellRenderer *cell,
+ GtkWidget *widget,
+ GdkRectangle *rectangle,
+ gint *x_offset,
+ gint *y_offset,
+ gint *width,
+ gint *height );
+static void gtk_wx_cell_renderer_render (
+ GtkCellRenderer *cell,
+ GdkWindow *window,
+ GtkWidget *widget,
+ GdkRectangle *background_area,
+ GdkRectangle *cell_area,
+ GdkRectangle *expose_area,
+ GtkCellRendererState flags );
+static gboolean gtk_wx_cell_renderer_activate(
+ GtkCellRenderer *cell,
+ GdkEvent *event,
+ GtkWidget *widget,
+ const gchar *path,
+ GdkRectangle *background_area,
+ GdkRectangle *cell_area,
+ GtkCellRendererState flags );
+static GtkCellEditable *gtk_wx_cell_renderer_start_editing(
+ GtkCellRenderer *cell,
+ GdkEvent *event,
+ GtkWidget *widget,
+ const gchar *path,
+ GdkRectangle *background_area,
+ GdkRectangle *cell_area,
+ GtkCellRendererState flags );
- iter->stamp = m_owner->stamp;
- iter->user_data = (gpointer) node->GetItem().GetID();
- return TRUE;
-}
+static GObjectClass *cell_parent_class = NULL;
-GtkTreePath *wxGtkTreeModel::get_path( GtkTreeIter *iter )
+} // extern "C"
+
+GType
+gtk_wx_cell_renderer_get_type (void)
{
- GtkTreePath *retval = gtk_tree_path_new ();
-
- wxGtkTreeModelNode *node = FindNode( iter );
- while (node->GetParent())
+ static GType cell_wx_type = 0;
+
+ if (!cell_wx_type)
{
- wxGtkTreeModelNode *parent = node->GetParent();
- int pos = parent->GetChildren().Index( node );
-
- gtk_tree_path_prepend_index( retval, pos );
+ const GTypeInfo cell_wx_info =
+ {
+ sizeof (GtkWxCellRendererClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) gtk_wx_cell_renderer_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GtkWxCellRenderer),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) gtk_wx_cell_renderer_init,
+ };
- node = parent;
+ cell_wx_type = g_type_register_static( GTK_TYPE_CELL_RENDERER,
+ "GtkWxCellRenderer", &cell_wx_info, (GTypeFlags)0 );
}
- return retval;
+ return cell_wx_type;
}
-gboolean wxGtkTreeModel::iter_next( GtkTreeIter *iter )
+static void
+gtk_wx_cell_renderer_init (GtkWxCellRenderer *cell)
{
- 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;
+ cell->cell = NULL;
+ cell->last_click = 0;
}
-gboolean wxGtkTreeModel::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_owner->stamp;
- iter->user_data = (gpointer) first_child_node->GetItem().GetID();
-
- return TRUE;
-}
-
-gboolean wxGtkTreeModel::iter_has_child( GtkTreeIter *iter )
-{
- wxDataViewItem item( (void*) iter->user_data );
-
- return m_wx_model->HasChildren( item );
-}
-
-gint wxGtkTreeModel::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 wxGtkTreeModel::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_owner->stamp;
- iter->user_data = (gpointer) child_node->GetItem().GetID();
-
- return TRUE;
-}
-
-gboolean wxGtkTreeModel::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_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( (void*) 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;
-}
-
-wxGtkTreeModelNode *wxGtkTreeModel::FindNode( const wxDataViewItem &item )
-{
- wxGtkTreeModelNode *result = wxGtkTreeModel_FindNode( m_root, item );
-
- if (!result)
- {
- wxPrintf( "Not found %d\n", (int) item.GetID() );
- char *crash = NULL;
- *crash = 0;
- }
-
- return result;
-}
-
-//-----------------------------------------------------------------------------
-// define new GTK+ class wxGtkRendererRenderer
-//-----------------------------------------------------------------------------
-
-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
-{
- GtkCellRenderer parent;
-
- /*< 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 );
-static void gtk_wx_cell_renderer_class_init(
- GtkWxCellRendererClass *klass );
-static void gtk_wx_cell_renderer_finalize (
- GObject *object );
-static void gtk_wx_cell_renderer_get_size (
- GtkCellRenderer *cell,
- GtkWidget *widget,
- GdkRectangle *rectangle,
- gint *x_offset,
- gint *y_offset,
- gint *width,
- gint *height );
-static void gtk_wx_cell_renderer_render (
- GtkCellRenderer *cell,
- GdkWindow *window,
- GtkWidget *widget,
- GdkRectangle *background_area,
- GdkRectangle *cell_area,
- GdkRectangle *expose_area,
- GtkCellRendererState flags );
-static gboolean gtk_wx_cell_renderer_activate(
- GtkCellRenderer *cell,
- GdkEvent *event,
- GtkWidget *widget,
- const gchar *path,
- GdkRectangle *background_area,
- GdkRectangle *cell_area,
- GtkCellRendererState flags );
-static GtkCellEditable *gtk_wx_cell_renderer_start_editing(
- GtkCellRenderer *cell,
- GdkEvent *event,
- GtkWidget *widget,
- const gchar *path,
- GdkRectangle *background_area,
- GdkRectangle *cell_area,
- GtkCellRendererState flags );
-
-
-static GObjectClass *cell_parent_class = NULL;
-
-} // extern "C"
-
-GType
-gtk_wx_cell_renderer_get_type (void)
-{
- static GType cell_wx_type = 0;
-
- if (!cell_wx_type)
- {
- const GTypeInfo cell_wx_info =
- {
- sizeof (GtkWxCellRendererClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) gtk_wx_cell_renderer_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (GtkWxCellRenderer),
- 0, /* n_preallocs */
- (GInstanceInitFunc) gtk_wx_cell_renderer_init,
- };
-
- cell_wx_type = g_type_register_static( GTK_TYPE_CELL_RENDERER,
- "GtkWxCellRenderer", &cell_wx_info, (GTypeFlags)0 );
- }
-
- return cell_wx_type;
-}
-
-static void
-gtk_wx_cell_renderer_init (GtkWxCellRenderer *cell)
-{
- cell->cell = NULL;
- cell->last_click = 0;
-}
-
-static void
-gtk_wx_cell_renderer_class_init (GtkWxCellRendererClass *klass)
+static void
+gtk_wx_cell_renderer_class_init (GtkWxCellRendererClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (klass);
// wxRect renderrect( rect.x, rect.y, rect.width, rect.height );
wxRect renderrect( cell_area->x, cell_area->y, cell_area->width, cell_area->height );
- // wxDataViewListModel *model = cell->GetOwner()->GetOwner()->GetModel();
-
GtkTreePath *treepath = gtk_tree_path_new_from_string( path );
- // TODO
- wxDataViewItem item;
+ GtkTreeIter iter;
+ cell->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter, treepath );
+ wxDataViewItem item( (void*) iter.user_data );
gtk_tree_path_free( treepath );
cell->StartEditing( item, renderrect );
~wxGtkDataViewModelNotifier();
virtual bool ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item );
- virtual bool ItemDeleted( const wxDataViewItem &item );
+ virtual bool ItemDeleted( const wxDataViewItem &parent, const wxDataViewItem &item );
virtual bool ItemChanged( const wxDataViewItem &item );
virtual bool ValueChanged( const wxDataViewItem &item, unsigned int col );
virtual bool Cleared();
+ virtual void Resort();
GtkWxTreeModel *m_wxgtk_model;
wxDataViewModel *m_wx_model;
bool wxGtkDataViewModelNotifier::ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item )
{
- m_wxgtk_model->model->ItemAdded( parent, item );
+ m_owner->GtkGetInternal()->ItemAdded( parent, item );
GtkTreeIter iter;
iter.stamp = m_wxgtk_model->stamp;
return true;
}
-bool wxGtkDataViewModelNotifier::ItemDeleted( const wxDataViewItem &item )
+bool wxGtkDataViewModelNotifier::ItemDeleted( const wxDataViewItem &parent, const wxDataViewItem &item )
{
GtkTreeIter iter;
iter.stamp = m_wxgtk_model->stamp;
iter.user_data = (gpointer) item.GetID();
- GtkTreePath *path = wxgtk_tree_model_get_path(
+ GtkTreePath *path = wxgtk_tree_model_get_path_safe(
GTK_TREE_MODEL(m_wxgtk_model), &iter );
gtk_tree_model_row_deleted(
GTK_TREE_MODEL(m_wxgtk_model), path );
gtk_tree_path_free (path);
- m_wxgtk_model->model->ItemDeleted( item );
+ m_owner->GtkGetInternal()->ItemDeleted( parent, item );
return true;
}
+void wxGtkDataViewModelNotifier::Resort()
+{
+ m_owner->GtkGetInternal()->Resort();
+}
+
bool wxGtkDataViewModelNotifier::ItemChanged( const wxDataViewItem &item )
{
GtkTreeIter iter;
GTK_TREE_MODEL(m_wxgtk_model), path, &iter );
gtk_tree_path_free (path);
+ m_owner->GtkGetInternal()->ItemChanged( item );
+
return true;
}
// Redraw
gtk_widget_queue_draw_area( GTK_WIDGET(widget),
cell_area.x - xdiff, ydiff + cell_area.y, cell_area.width, cell_area.height );
+
+ m_owner->GtkGetInternal()->ValueChanged( item, model_col );
+
+ return true;
}
}
- return true;
+ return false;
}
bool wxGtkDataViewModelNotifier::Cleared()
{
+ // TODO: delete everything
+
+ m_owner->GtkGetInternal()->Cleared();
+
return false;
}
GtkTreePath *path = gtk_tree_path_new_from_string( arg1 );
GtkTreeIter iter;
- // TODO
- wxDataViewItem item;
+ cell->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter, path );
+ wxDataViewItem item( (void*) iter.user_data );;
gtk_tree_path_free( path );
unsigned int model_col = cell->GetOwner()->GetModelColumn();
wxDataViewModel *model = cell->GetOwner()->GetOwner()->GetModel();
GtkTreePath *gtk_path = gtk_tree_path_new_from_string( path );
- // TODO
- wxDataViewItem item;
+ GtkTreeIter iter;
+ cell->GetOwner()->GetOwner()->GtkGetInternal()->get_iter( &iter, gtk_path );
+ wxDataViewItem item( (void*) iter.user_data );;
gtk_tree_path_free( gtk_path );
unsigned int model_col = cell->GetOwner()->GetModelColumn();
wxDataViewItem item( (void*) iter->user_data );
wxVariant value;
- tree_model->model->GetDataViewModel()->GetValue( value, item, cell->GetOwner()->GetModelColumn() );
+ tree_model->internal->GetDataViewModel()->GetValue( value, item, cell->GetOwner()->GetModelColumn() );
if (value.GetType() != cell->GetVariantType())
wxLogError( wxT("Wrong type, required: %s but: %s"),
//-----------------------------------------------------------------------------
-// wxDataViewCtrl signal callbacks
+// wxGtkTreeModelNode
//-----------------------------------------------------------------------------
-static void
-wxdataview_selection_changed_callback( GtkTreeSelection* selection, wxDataViewCtrl *dv )
+void wxGtkTreeModelNode::Resort()
{
- if (!GTK_WIDGET_REALIZED(dv->m_widget))
+ g_model = m_internal->GetDataViewModel();
+
+ size_t child_count = GetChildCount();
+ if (child_count == 0)
return;
- wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_SELECTED, dv->GetId() );
- // TODO: item
- event.SetModel( dv->GetModel() );
- dv->GetEventHandler()->ProcessEvent( event );
-}
+ size_t node_count = GetNodesCount();
-static void
-wxdataview_row_activated_callback( GtkTreeView* treeview, GtkTreePath *path,
- GtkTreeViewColumn *column, wxDataViewCtrl *dv )
-{
- wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, dv->GetId() );
- // TODO: item
- event.SetModel( dv->GetModel() );
- dv->GetEventHandler()->ProcessEvent( event );
-}
+ if (child_count == 1)
+ {
+ if (node_count == 1)
+ {
+ wxGtkTreeModelNode *node = m_nodes.Item( 0 );
+ node->Resort();
+ }
+ return;
+ }
-//-----------------------------------------------------------------------------
-// wxDataViewCtrl
-//-----------------------------------------------------------------------------
+ wxGtkTreeModelChildren *new_array = new wxGtkTreeModelChildren( wxGtkTreeModelNodeCmp );
+
+ size_t pos;
+ for (pos = 0; pos < child_count; pos++)
+ new_array->Add( m_children->Item( pos ) );
+
+ gint *new_order = new gint[child_count];
+
+ for (pos = 0; pos < child_count; pos++)
+ {
+ void *id = new_array->Item( pos );
+ size_t old_pos;
+ for (old_pos = 0; old_pos < child_count; old_pos++)
+ {
+ if (id == m_children->Item(old_pos))
+ {
+ new_order[pos] = old_pos;
+ break;
+ }
+ }
+ }
+
+// for (pos = 0; pos < count; pos++)
+// m_children->Clear();
+ delete m_children;
+
+ m_children = new_array;
+
+ GtkTreeModel *gtk_tree_model = GTK_TREE_MODEL( m_internal->GetGtkModel() );
+
+ GtkTreePath *path = gtk_tree_path_new ();
+ wxGtkTreeModelNode *parent = GetParent();
+ void *id = GetItem().GetID();
+
+ while (parent)
+ {
+ int pos = parent->GetChildren().Index( id );
+ gtk_tree_path_prepend_index( path, pos );
+ id = parent->GetItem().GetID();
+ parent = parent->GetParent();
+ }
+
+ GtkTreeIter iter;
+ iter.user_data = id;
+ iter.stamp = m_internal->GetGtkModel()->stamp;
+ gtk_tree_model_rows_reordered( gtk_tree_model, path, &iter, new_order );
+
+ gtk_tree_path_free (path);
+
+ delete [] new_order;
+
+ for (pos = 0; pos < node_count; pos++)
+ {
+ wxGtkTreeModelNode *node = m_nodes.Item( pos );
+ node->Resort();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// 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::InitTree()
+{
+ wxDataViewItem item;
+ m_root = new wxGtkTreeModelNode( NULL, item, this );
+
+ BuildBranch( m_root );
+}
+
+void wxDataViewCtrlInternal::BuildBranch( wxGtkTreeModelNode *node )
+{
+ if (node->GetChildCount() == 0)
+ {
+ wxDataViewItem child = m_wx_model->GetFirstChild( node->GetItem() );
+ while (child.IsOk())
+ {
+ if (m_wx_model->IsContainer( child ))
+ node->AddNode( new wxGtkTreeModelNode( node, child, this ) );
+ else
+ node->AddLeave( child.GetID() );
+
+ // Don't send any events here
+
+ child = m_wx_model->GetNextSibling( child );
+ }
+ }
+}
+
+void wxDataViewCtrlInternal::Resort()
+{
+ m_root->Resort();
+}
+
+bool wxDataViewCtrlInternal::ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item )
+{
+ wxGtkTreeModelNode *parent_node = FindNode( parent );
+ if (m_wx_model->IsContainer( item ))
+ parent_node->AddNode( new wxGtkTreeModelNode( parent_node, item, this ) );
+ else
+ parent_node->AddLeave( item.GetID() );
+
+ wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_ADDED, m_owner->GetId() );
+ event.SetEventObject( m_owner );
+ event.SetModel( m_owner->GetModel() );
+ event.SetItem( item );
+ m_owner->GetEventHandler()->ProcessEvent( event );
+
+ return true;
+}
+
+bool wxDataViewCtrlInternal::ItemDeleted( const wxDataViewItem &parent, const wxDataViewItem &item )
+{
+ wxGtkTreeModelNode *parent_node = FindNode( parent );
+ parent_node->DeleteChild( item.GetID() );
+
+ wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_DELETED, m_owner->GetId() );
+ event.SetEventObject( m_owner );
+ event.SetModel( m_owner->GetModel() );
+ event.SetItem( item );
+ m_owner->GetEventHandler()->ProcessEvent( event );
+
+ return true;
+}
+
+bool wxDataViewCtrlInternal::ItemChanged( const wxDataViewItem &item )
+{
+ wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_MODEL_ITEM_CHANGED, m_owner->GetId() );
+ event.SetEventObject( m_owner );
+ event.SetModel( m_owner->GetModel() );
+ event.SetItem( item );
+ m_owner->GetEventHandler()->ProcessEvent( event );
+
+ return true;
+}
+
+bool wxDataViewCtrlInternal::ValueChanged( const wxDataViewItem &item, unsigned int col )
+{
+ wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_MODEL_VALUE_CHANGED, m_owner->GetId() );
+ event.SetEventObject( m_owner );
+ event.SetModel( m_owner->GetModel() );
+ event.SetColumn( col );
+ event.SetItem( item );
+ m_owner->GetEventHandler()->ProcessEvent( event );
+
+ return true;
+}
+
+bool wxDataViewCtrlInternal::Cleared()
+{
+ wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_MODEL_CLEARED, m_owner->GetId() );
+ event.SetEventObject( m_owner );
+ event.SetModel( m_owner->GetModel() );
+ m_owner->GetEventHandler()->ProcessEvent( event );
+
+ return true;
+}
+
+gboolean wxDataViewCtrlInternal::get_iter( GtkTreeIter *iter, GtkTreePath *path )
+{
+ g_model = m_wx_model;
+
+ 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;
+
+ void* id = node->GetChildren().Item( (size_t) pos );
+
+ if (i == depth-1)
+ {
+ iter->stamp = m_gtk_model->stamp;
+ iter->user_data = id;
+ return TRUE;
+ }
+
+ size_t count = node->GetNodes().GetCount();
+ size_t pos2;
+ for (pos2 = 0; pos2 < count; pos2++)
+ {
+ wxGtkTreeModelNode *child_node = node->GetNodes().Item( pos2 );
+ if (child_node->GetItem().GetID() == id)
+ {
+ node = child_node;
+ break;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+GtkTreePath *wxDataViewCtrlInternal::get_path( GtkTreeIter *iter )
+{
+ g_model = m_wx_model;
+
+ GtkTreePath *retval = gtk_tree_path_new ();
+ void *id = iter->user_data;
+
+ wxGtkTreeModelNode *node = FindParentNode( iter );
+ while (node)
+ {
+ int pos = node->GetChildren().Index( id );
+ gtk_tree_path_prepend_index( retval, pos );
+
+ id = node->GetItem().GetID();
+ node = node->GetParent();
+ }
+
+ return retval;
+}
+
+GtkTreePath *wxDataViewCtrlInternal::get_path_safe( GtkTreeIter *iter )
+{
+ g_model = m_wx_model;
+
+ GtkTreePath *retval = gtk_tree_path_new ();
+ void *id = iter->user_data;
+
+ wxGtkTreeModelNode *node = FindParentNode( iter );
+ while (node)
+ {
+ size_t pos;
+ for (pos = 0; pos < node->GetChildren().GetCount(); pos++)
+ {
+ if (id == node->GetChildren().Item( pos ))
+ {
+ gtk_tree_path_prepend_index( retval, (int) pos );
+ continue;
+ }
+ }
+
+ id = node->GetItem().GetID();
+ node = node->GetParent();
+ }
+
+ return retval;
+}
+
+gboolean wxDataViewCtrlInternal::iter_next( GtkTreeIter *iter )
+{
+ g_model = m_wx_model;
+
+ wxGtkTreeModelNode *parent = FindParentNode( iter );
+ if( parent == NULL )
+ return FALSE;
+
+ unsigned int pos = parent->GetChildren().Index( iter->user_data );
+
+ if (pos == parent->GetChildCount()-1)
+ return FALSE;
+
+ iter->stamp = m_gtk_model->stamp;
+ iter->user_data = parent->GetChildren().Item( pos+1 );
+
+ return TRUE;
+}
+
+gboolean wxDataViewCtrlInternal::iter_children( GtkTreeIter *iter, GtkTreeIter *parent )
+{
+ g_model = m_wx_model;
+
+ wxDataViewItem item( (void*) parent->user_data );
+
+ if (!m_wx_model->IsContainer( item ))
+ return FALSE;
+
+ wxGtkTreeModelNode *parent_node = FindNode( parent );
+ BuildBranch( parent_node );
+
+ if (parent_node->GetChildCount() == 0)
+ return FALSE;
+
+ iter->stamp = m_gtk_model->stamp;
+ iter->user_data = (gpointer) parent_node->GetChildren().Item( 0 );
+
+ return TRUE;
+}
+
+gboolean wxDataViewCtrlInternal::iter_has_child( GtkTreeIter *iter )
+{
+ g_model = m_wx_model;
+
+ wxDataViewItem item( (void*) iter->user_data );
+ bool is_container = m_wx_model->IsContainer( item );
+
+ if (!is_container)
+ return FALSE;
+
+ wxGtkTreeModelNode *node = FindNode( iter );
+ BuildBranch( node );
+
+ return (node->GetChildCount() > 0);
+}
+
+gint wxDataViewCtrlInternal::iter_n_children( GtkTreeIter *iter )
+{
+ g_model = m_wx_model;
+
+ wxDataViewItem item( (void*) iter->user_data );
+
+ if (!m_wx_model->IsContainer( item ))
+ return 0;
+
+ wxGtkTreeModelNode *parent_node = FindNode( iter );
+ BuildBranch( parent_node );
+
+ // wxPrintf( "iter_n_children %d\n", parent_node->GetChildCount() );
+
+ return parent_node->GetChildCount();
+}
+
+gboolean wxDataViewCtrlInternal::iter_nth_child( GtkTreeIter *iter, GtkTreeIter *parent, gint n )
+{
+ g_model = m_wx_model;
+
+ void* id = NULL;
+ if (parent) id = (void*) parent->user_data;
+ wxDataViewItem item( id );
+
+ if (!m_wx_model->IsContainer( item ))
+ return FALSE;
+
+ wxGtkTreeModelNode *parent_node = FindNode( parent );
+ BuildBranch( parent_node );
+
+ // wxPrintf( "iter_nth_child %d\n", n );
+
+ iter->stamp = m_gtk_model->stamp;
+ iter->user_data = parent_node->GetChildren().Item( n );
+
+ return TRUE;
+}
+
+gboolean wxDataViewCtrlInternal::iter_parent( GtkTreeIter *iter, GtkTreeIter *child )
+{
+ g_model = m_wx_model;
+
+ wxGtkTreeModelNode *node = FindParentNode( child );
+ if (!node)
+ return FALSE;
+
+ iter->stamp = m_gtk_model->stamp;
+ iter->user_data = (gpointer) node->GetItem().GetID();
+
+ return TRUE;
+}
+
+static wxGtkTreeModelNode*
+wxDataViewCtrlInternal_FindNode( wxDataViewModel * model, wxGtkTreeModelNode *treeNode, const wxDataViewItem &item )
+{
+ if( model == NULL )
+ return NULL;
+
+ ItemList list;
+ list.DeleteContents( true );
+ wxDataViewItem it( item );
+ while( it.IsOk() )
+ {
+ wxDataViewItem * pItem = new wxDataViewItem( it );
+ list.Insert( pItem );
+ it = model->GetParent( it );
+ }
+
+ wxGtkTreeModelNode * node = treeNode;
+ for( ItemList::compatibility_iterator n = list.GetFirst(); n; n = n->GetNext() )
+ {
+ if( node && node->GetNodes().GetCount() != 0 )
+ {
+ int len = node->GetNodes().GetCount();
+ wxGtkTreeModelNodes nodes = node->GetNodes();
+ int j = 0;
+ for( ; j < len; j ++)
+ {
+ if( nodes[j]->GetItem() == *(n->GetData()))
+ {
+ node = nodes[j];
+ break;
+ }
+ }
+
+ if( j == len )
+ {
+ return NULL;
+ }
+ }
+ else
+ return NULL;
+ }
+ return node;
+
+}
+
+wxGtkTreeModelNode *wxDataViewCtrlInternal::FindNode( GtkTreeIter *iter )
+{
+ if (!iter)
+ return m_root;
+
+ wxDataViewItem item( (void*) iter->user_data );
+ if (!item.IsOk())
+ return m_root;
+
+ wxGtkTreeModelNode *result = wxDataViewCtrlInternal_FindNode( m_wx_model, 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 )
+{
+ if (!item.IsOk())
+ return m_root;
+
+ wxGtkTreeModelNode *result = wxDataViewCtrlInternal_FindNode( m_wx_model, m_root, item );
+
+ if (!result)
+ {
+ wxPrintf( "Not found %d\n", (int) item.GetID() );
+ char *crash = NULL;
+ *crash = 0;
+ }
+
+ return result;
+}
+
+static wxGtkTreeModelNode*
+wxDataViewCtrlInternal_FindParentNode( wxDataViewModel * model, wxGtkTreeModelNode *treeNode, const wxDataViewItem &item )
+{
+ if( model == NULL )
+ return NULL;
+
+ ItemList list;
+ list.DeleteContents( true );
+ if( !item.IsOk() )
+ return NULL;
+
+ wxDataViewItem it( model->GetParent( item ) );
+ while( it.IsOk() )
+ {
+ wxDataViewItem * pItem = new wxDataViewItem( it );
+ list.Insert( pItem );
+ it = model->GetParent( it );
+ }
+
+ wxGtkTreeModelNode * node = treeNode;
+ for( ItemList::compatibility_iterator n = list.GetFirst(); n; n = n->GetNext() )
+ {
+ if( node && node->GetNodes().GetCount() != 0 )
+ {
+ int len = node->GetNodes().GetCount();
+ wxGtkTreeModelNodes nodes = node->GetNodes();
+ int j = 0;
+ for( ; j < len; j ++)
+ {
+ if( nodes[j]->GetItem() == *(n->GetData()))
+ {
+ node = nodes[j];
+ break;
+ }
+ }
+
+ if( j == len )
+ {
+ return NULL;
+ }
+ }
+ else
+ return NULL;
+ }
+ //Examine whether the node is item's parent node
+ int len = node->GetChildCount();
+ for( int i = 0; i < len ; i ++ )
+ {
+ if( node->GetChildren().Item( i ) == item.GetID() )
+ return node;
+ }
+ return NULL;
+}
+
+wxGtkTreeModelNode *wxDataViewCtrlInternal::FindParentNode( GtkTreeIter *iter )
+{
+ if (!iter)
+ return NULL;
+
+ wxDataViewItem item( (void*) iter->user_data );
+ if (!item.IsOk())
+ return NULL;
+
+ return wxDataViewCtrlInternal_FindParentNode( m_wx_model, m_root, item );
+}
+
+wxGtkTreeModelNode *wxDataViewCtrlInternal::FindParentNode( const wxDataViewItem &item )
+{
+ if (!item.IsOk())
+ return NULL;
+
+ return wxDataViewCtrlInternal_FindParentNode( m_wx_model, m_root, item );
+}
+
+//-----------------------------------------------------------------------------
+// wxDataViewCtrl signal callbacks
+//-----------------------------------------------------------------------------
+
+static void
+wxdataview_selection_changed_callback( GtkTreeSelection* selection, wxDataViewCtrl *dv )
+{
+ if (!GTK_WIDGET_REALIZED(dv->m_widget))
+ return;
+
+ wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_SELECTED, dv->GetId() );
+ // TODO: item
+ event.SetModel( dv->GetModel() );
+ dv->GetEventHandler()->ProcessEvent( event );
+}
+
+static void
+wxdataview_row_activated_callback( GtkTreeView* treeview, GtkTreePath *path,
+ GtkTreeViewColumn *column, wxDataViewCtrl *dv )
+{
+ wxDataViewEvent event( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED, dv->GetId() );
+
+ GtkTreeIter iter;
+ dv->GtkGetInternal()->get_iter( &iter, path );
+ wxDataViewItem item( (void*) iter.user_data );;
+ event.SetItem( item );
+ event.SetModel( dv->GetModel() );
+ dv->GetEventHandler()->ProcessEvent( event );
+}
+
+//-----------------------------------------------------------------------------
+// wxDataViewCtrl
+//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// InsertChild for wxDataViewCtrl
GtkAllocation *alloc,
wxDataViewCtrl *win )
{
-
- wxWindowList::Node *node = win->GetChildren().GetFirst();
+ wxWindowList::compatibility_iterator node = win->GetChildren().GetFirst();
while (node)
{
wxWindow *child = node->GetData();
// remove the model from the GtkTreeView before it gets destroyed by the
// wxDataViewCtrlBase's dtor
gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview), NULL );
+
+ delete m_internal;
}
void wxDataViewCtrl::Init()
if (!wxDataViewCtrlBase::AssociateModel( model ))
return false;
- 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;
+ GtkWxTreeModel *gtk_model = wxgtk_tree_model_new();
+ m_internal = new wxDataViewCtrlInternal( this, model, gtk_model );
+ gtk_model->internal = m_internal;
- m_notifier = new wxGtkDataViewModelNotifier( gtkwx_tree_model, model, this );
+ m_notifier = new wxGtkDataViewModelNotifier( gtk_model, model, this );
model->AddNotifier( m_notifier );
- gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview), GTK_TREE_MODEL(gtkwx_tree_model) );
- g_object_unref( gtkwx_tree_model );
+ gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview), GTK_TREE_MODEL(gtk_model) );
+
+ // unref in wxDataViewCtrlInternal
+ // g_object_unref( gtk_model );
return true;
}