1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/dataview.cpp
3 // Purpose: wxDataViewCtrl GTK+2 implementation
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
13 #if wxUSE_DATAVIEWCTRL
15 #include "wx/dataview.h"
17 #ifndef wxUSE_GENERICDATAVIEWCTRL
21 #include "wx/dcclient.h"
25 #include "wx/stockitem.h"
26 #include "wx/calctrl.h"
27 #include "wx/popupwin.h"
31 #include "wx/gtk/private.h"
32 #include "wx/gtk/win_gtk.h"
34 #include <gobject/gvaluecollector.h>
35 #include <gtk/gtktreemodel.h>
36 #include <gtk/gtktreesortable.h>
37 #include <gtk/gtktreednd.h>
39 #include <gdk/gdkkeysyms.h>
41 //-----------------------------------------------------------------------------
43 //-----------------------------------------------------------------------------
47 //-----------------------------------------------------------------------------
49 //-----------------------------------------------------------------------------
51 extern bool g_blockEventsOnDrag
;
53 //-----------------------------------------------------------------------------
54 // define new GTK+ class wxGtkTreeModel
55 //-----------------------------------------------------------------------------
59 #define GTK_TYPE_WX_TREE_MODEL (gtk_wx_tree_model_get_type ())
60 #define GTK_WX_TREE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModel))
61 #define GTK_WX_TREE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModelClass))
62 #define GTK_IS_WX_TREE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_TREE_MODEL))
63 #define GTK_IS_WX_TREE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_TREE_MODEL))
64 #define GTK_WX_TREE_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_TREE_MODEL, GtkWxTreeModelClass))
66 GType
gtk_wx_tree_model_get_type (void);
68 typedef struct _GtkWxTreeModel GtkWxTreeModel
;
69 typedef struct _GtkWxTreeModelClass GtkWxTreeModelClass
;
71 struct _GtkWxTreeModel
77 wxDataViewModel
*model
;
81 GtkTreeIterCompareFunc default_sort_func
;
84 struct _GtkWxTreeModelClass
86 GObjectClass list_parent_class
;
89 static GtkWxTreeModel
*wxgtk_tree_model_new (void);
90 static void wxgtk_tree_model_init (GtkWxTreeModel
*tree_model
);
91 static void wxgtk_tree_model_class_init (GtkWxTreeModelClass
*klass
);
92 static void wxgtk_tree_model_tree_model_init (GtkTreeModelIface
*iface
);
93 static void wxgtk_tree_model_sortable_init (GtkTreeSortableIface
*iface
);
94 static void wxgtk_tree_model_finalize (GObject
*object
);
95 static GtkTreeModelFlags
wxgtk_tree_model_get_flags (GtkTreeModel
*tree_model
);
96 static gint
wxgtk_tree_model_get_n_columns (GtkTreeModel
*tree_model
);
97 static GType
wxgtk_tree_model_get_column_type (GtkTreeModel
*tree_model
,
99 static gboolean
wxgtk_tree_model_get_iter (GtkTreeModel
*tree_model
,
102 static GtkTreePath
*wxgtk_tree_model_get_path (GtkTreeModel
*tree_model
,
104 static void wxgtk_tree_model_get_value (GtkTreeModel
*tree_model
,
108 static gboolean
wxgtk_tree_model_iter_next (GtkTreeModel
*tree_model
,
110 static gboolean
wxgtk_tree_model_iter_children (GtkTreeModel
*tree_model
,
112 GtkTreeIter
*parent
);
113 static gboolean
wxgtk_tree_model_iter_has_child (GtkTreeModel
*tree_model
,
115 static gint
wxgtk_tree_model_iter_n_children (GtkTreeModel
*tree_model
,
117 static gboolean
wxgtk_tree_model_iter_nth_child (GtkTreeModel
*tree_model
,
121 static gboolean
wxgtk_tree_model_iter_parent (GtkTreeModel
*tree_model
,
126 static gboolean
wxgtk_tree_model_get_sort_column_id (GtkTreeSortable
*sortable
,
127 gint
*sort_column_id
,
129 static void wxgtk_tree_model_set_sort_column_id (GtkTreeSortable
*sortable
,
132 static void wxgtk_tree_model_set_sort_func (GtkTreeSortable
*sortable
,
134 GtkTreeIterCompareFunc func
,
136 GtkDestroyNotify destroy
);
137 static void wxgtk_tree_model_set_default_sort_func (GtkTreeSortable
*sortable
,
138 GtkTreeIterCompareFunc func
,
140 GtkDestroyNotify destroy
);
141 static gboolean
wxgtk_tree_model_has_default_sort_func (GtkTreeSortable
*sortable
);
145 static GObjectClass
*list_parent_class
= NULL
;
148 gtk_wx_tree_model_get_type (void)
150 static GType tree_model_type
= 0;
152 if (!tree_model_type
)
154 const GTypeInfo tree_model_info
=
156 sizeof (GtkWxTreeModelClass
),
157 NULL
, /* base_init */
158 NULL
, /* base_finalize */
159 (GClassInitFunc
) wxgtk_tree_model_class_init
,
160 NULL
, /* class_finalize */
161 NULL
, /* class_data */
162 sizeof (GtkWxTreeModel
),
164 (GInstanceInitFunc
) wxgtk_tree_model_init
,
167 static const GInterfaceInfo tree_model_iface_info
=
169 (GInterfaceInitFunc
) wxgtk_tree_model_tree_model_init
,
174 static const GInterfaceInfo sortable_iface_info
=
176 (GInterfaceInitFunc
) wxgtk_tree_model_sortable_init
,
181 tree_model_type
= g_type_register_static (G_TYPE_OBJECT
, "GtkWxTreeModel",
182 &tree_model_info
, (GTypeFlags
)0 );
184 g_type_add_interface_static (tree_model_type
,
186 &tree_model_iface_info
);
187 g_type_add_interface_static (tree_model_type
,
188 GTK_TYPE_TREE_SORTABLE
,
189 &sortable_iface_info
);
192 return tree_model_type
;
195 static GtkWxTreeModel
*
196 wxgtk_tree_model_new(void)
198 GtkWxTreeModel
*retval
= (GtkWxTreeModel
*) g_object_new (GTK_TYPE_WX_TREE_MODEL
, NULL
);
203 wxgtk_tree_model_class_init (GtkWxTreeModelClass
*klass
)
205 list_parent_class
= (GObjectClass
*) g_type_class_peek_parent (klass
);
206 GObjectClass
*object_class
= (GObjectClass
*) klass
;
207 object_class
->finalize
= wxgtk_tree_model_finalize
;
211 wxgtk_tree_model_tree_model_init (GtkTreeModelIface
*iface
)
213 iface
->get_flags
= wxgtk_tree_model_get_flags
;
214 iface
->get_n_columns
= wxgtk_tree_model_get_n_columns
;
215 iface
->get_column_type
= wxgtk_tree_model_get_column_type
;
216 iface
->get_iter
= wxgtk_tree_model_get_iter
;
217 iface
->get_path
= wxgtk_tree_model_get_path
;
218 iface
->get_value
= wxgtk_tree_model_get_value
;
219 iface
->iter_next
= wxgtk_tree_model_iter_next
;
220 iface
->iter_children
= wxgtk_tree_model_iter_children
;
221 iface
->iter_has_child
= wxgtk_tree_model_iter_has_child
;
222 iface
->iter_n_children
= wxgtk_tree_model_iter_n_children
;
223 iface
->iter_nth_child
= wxgtk_tree_model_iter_nth_child
;
224 iface
->iter_parent
= wxgtk_tree_model_iter_parent
;
228 wxgtk_tree_model_sortable_init (GtkTreeSortableIface
*iface
)
230 iface
->get_sort_column_id
= wxgtk_tree_model_get_sort_column_id
;
231 iface
->set_sort_column_id
= wxgtk_tree_model_set_sort_column_id
;
232 iface
->set_sort_func
= wxgtk_tree_model_set_sort_func
;
233 iface
->set_default_sort_func
= wxgtk_tree_model_set_default_sort_func
;
234 iface
->has_default_sort_func
= wxgtk_tree_model_has_default_sort_func
;
238 wxgtk_tree_model_init (GtkWxTreeModel
*tree_model
)
240 tree_model
->model
= NULL
;
241 tree_model
->stamp
= g_random_int();
242 tree_model
->sort_column_id
= -2;
243 tree_model
->order
= GTK_SORT_ASCENDING
;
244 tree_model
->default_sort_func
= NULL
;
248 wxgtk_tree_model_finalize (GObject
*object
)
250 /* GtkWxTreeModel *tree_model = GTK_WX_LIST_STORE (object); */
252 /* we need to sort out, which class deletes what */
253 /* delete tree_model->model; */
256 (* list_parent_class
->finalize
) (object
);
261 //-----------------------------------------------------------------------------
262 // implement callbacks from wxGtkTreeModel class by letting
263 // them call the methods of wxWidgets' wxDataViewModel
264 //-----------------------------------------------------------------------------
266 static GtkTreeModelFlags
267 wxgtk_tree_model_get_flags (GtkTreeModel
*tree_model
)
269 g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (tree_model
), (GtkTreeModelFlags
)0 );
271 return GTK_TREE_MODEL_ITERS_PERSIST
;
275 wxgtk_tree_model_get_n_columns (GtkTreeModel
*tree_model
)
277 GtkWxTreeModel
*wxtree_model
= (GtkWxTreeModel
*) tree_model
;
278 g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), 0);
280 return wxtree_model
->model
->GetColumnCount();
284 wxgtk_tree_model_get_column_type (GtkTreeModel
*tree_model
,
287 GtkWxTreeModel
*wxtree_model
= (GtkWxTreeModel
*) tree_model
;
288 g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), G_TYPE_INVALID
);
290 GType gtype
= G_TYPE_INVALID
;
292 wxString wxtype
= wxtree_model
->model
->GetColumnType( (unsigned int) index
);
294 if (wxtype
== wxT("string"))
295 gtype
= G_TYPE_STRING
;
298 wxFAIL_MSG( _T("non-string columns not supported yet") );
305 wxgtk_tree_model_get_iter (GtkTreeModel
*tree_model
,
309 GtkWxTreeModel
*wxtree_model
= (GtkWxTreeModel
*) tree_model
;
310 g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
);
311 g_return_val_if_fail (gtk_tree_path_get_depth (path
) > 0, FALSE
);
313 wxDataViewModel
*model
= wxtree_model
->model
;
315 int depth
= gtk_tree_path_get_depth( path
);
320 for (i
= 0; i
< depth
; i
++)
322 gint pos
= gtk_tree_path_get_indices (path
)[i
];
323 item
= model
->GetNthChild( item
, (unsigned int) pos
);
329 iter
->stamp
= wxtree_model
->stamp
;
330 iter
->user_data
= (gpointer
) item
.GetID();
336 wxgtk_tree_model_get_path (GtkTreeModel
*tree_model
,
339 GtkWxTreeModel
*wxtree_model
= (GtkWxTreeModel
*) tree_model
;
340 g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), NULL
);
341 g_return_val_if_fail (iter
->stamp
== GTK_WX_TREE_MODEL (wxtree_model
)->stamp
, NULL
);
343 GtkTreePath
*retval
= gtk_tree_path_new ();
344 wxDataViewItem
item( (wxUint32
) iter
->user_data
);
346 wxDataViewModel
*model
= wxtree_model
->model
;
351 wxDataViewItem parent
= model
->GetParent( item
);
354 wxPrintf( wxT("wrong parent\n") );
356 wxDataViewItem node
= model
->GetFirstChild( parent
);
358 while (node
.GetID() != item
.GetID())
360 node
= model
->GetNextSibling( node
);
363 wxPrintf( wxT("wrong node\n") );
368 gtk_tree_path_prepend_index( retval
, n
);
370 item
= model
->GetParent( item
);
377 wxgtk_tree_model_get_value (GtkTreeModel
*tree_model
,
382 GtkWxTreeModel
*wxtree_model
= (GtkWxTreeModel
*) tree_model
;
383 g_return_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
) );
385 wxDataViewModel
*model
= wxtree_model
->model
;
386 wxString mtype
= model
->GetColumnType( (unsigned int) column
);
387 if (mtype
== wxT("string"))
390 g_value_init( value
, G_TYPE_STRING
);
391 wxDataViewItem
item( (wxUint32
) iter
->user_data
);
392 model
->GetValue( variant
, item
, (unsigned int) column
);
394 g_value_set_string( value
, variant
.GetString().utf8_str() );
398 wxFAIL_MSG( _T("non-string columns not supported yet") );
403 wxgtk_tree_model_iter_next (GtkTreeModel
*tree_model
,
406 GtkWxTreeModel
*wxtree_model
= (GtkWxTreeModel
*) tree_model
;
407 g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
);
409 g_return_val_if_fail (wxtree_model
->stamp
== iter
->stamp
, FALSE
);
411 wxDataViewModel
*model
= wxtree_model
->model
;
413 wxDataViewItem
item( (wxUint32
) iter
->user_data
);
414 item
= model
->GetNextSibling( item
);
418 iter
->user_data
= (gpointer
) item
.GetID();
424 wxgtk_tree_model_iter_children (GtkTreeModel
*tree_model
,
428 GtkWxTreeModel
*wxtree_model
= (GtkWxTreeModel
*) tree_model
;
429 g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
);
431 g_return_val_if_fail (wxtree_model
->stamp
== parent
->stamp
, FALSE
);
433 wxDataViewModel
*model
= wxtree_model
->model
;
435 wxDataViewItem
item( (wxUint32
) parent
->user_data
);
436 item
= model
->GetFirstChild( item
);
440 iter
->stamp
= wxtree_model
->stamp
;
441 iter
->user_data
= (gpointer
) item
.GetID();
447 wxgtk_tree_model_iter_has_child (GtkTreeModel
*tree_model
,
450 GtkWxTreeModel
*wxtree_model
= (GtkWxTreeModel
*) tree_model
;
451 g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
);
453 g_return_val_if_fail (wxtree_model
->stamp
== iter
->stamp
, FALSE
);
455 wxDataViewModel
*model
= wxtree_model
->model
;
457 wxDataViewItem
item( (wxUint32
) iter
->user_data
);
459 return model
->HasChildren( item
);
463 wxgtk_tree_model_iter_n_children (GtkTreeModel
*tree_model
,
466 GtkWxTreeModel
*wxtree_model
= (GtkWxTreeModel
*) tree_model
;
467 g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
);
469 g_return_val_if_fail (wxtree_model
->stamp
== iter
->stamp
, 0);
471 wxDataViewModel
*model
= wxtree_model
->model
;
473 wxDataViewItem
item( (wxUint32
) iter
->user_data
);
475 return model
->GetChildCount( item
);
479 wxgtk_tree_model_iter_nth_child (GtkTreeModel
*tree_model
,
484 GtkWxTreeModel
*wxtree_model
= (GtkWxTreeModel
*) tree_model
;
485 g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
);
487 wxDataViewModel
*model
= wxtree_model
->model
;
492 item
= model
->GetNthChild( item
, n
);
497 iter
->stamp
= wxtree_model
->stamp
;
498 iter
->user_data
= (gpointer
) item
.GetID();
502 g_return_val_if_fail (wxtree_model
->stamp
== parent
->stamp
, FALSE
);
504 wxDataViewItem
item( (wxUint32
) parent
->user_data
);
505 item
= model
->GetNthChild( item
, n
);
510 iter
->stamp
= wxtree_model
->stamp
;
511 iter
->user_data
= (gpointer
) item
.GetID();
518 wxgtk_tree_model_iter_parent (GtkTreeModel
*tree_model
,
522 GtkWxTreeModel
*wxtree_model
= (GtkWxTreeModel
*) tree_model
;
523 g_return_val_if_fail (GTK_IS_WX_TREE_MODEL (wxtree_model
), FALSE
);
525 g_return_val_if_fail (wxtree_model
->stamp
== child
->stamp
, FALSE
);
527 wxDataViewModel
*model
= wxtree_model
->model
;
529 wxDataViewItem
item( (wxUint32
) child
->user_data
);
530 item
= model
->GetParent( item
);
535 iter
->stamp
= wxtree_model
->stamp
;
536 iter
->user_data
= (gpointer
) item
.GetID();
542 gboolean
wxgtk_tree_model_get_sort_column_id (GtkTreeSortable
*sortable
,
543 gint
*sort_column_id
,
549 void wxgtk_tree_model_set_sort_column_id (GtkTreeSortable
*sortable
,
555 void wxgtk_tree_model_set_sort_func (GtkTreeSortable
*sortable
,
557 GtkTreeIterCompareFunc func
,
559 GtkDestroyNotify destroy
)
563 void wxgtk_tree_model_set_default_sort_func (GtkTreeSortable
*sortable
,
564 GtkTreeIterCompareFunc func
,
566 GtkDestroyNotify destroy
)
570 gboolean
wxgtk_tree_model_has_default_sort_func (GtkTreeSortable
*sortable
)
575 //-----------------------------------------------------------------------------
576 // define new GTK+ class wxGtkRendererRenderer
577 //-----------------------------------------------------------------------------
581 #define GTK_TYPE_WX_CELL_RENDERER (gtk_wx_cell_renderer_get_type ())
582 #define GTK_WX_CELL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRenderer))
583 #define GTK_WX_CELL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass))
584 #define GTK_IS_WX_CELL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_CELL_RENDERER))
585 #define GTK_IS_WX_CELL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_CELL_RENDERER))
586 #define GTK_WX_CELL_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass))
588 GType
gtk_wx_cell_renderer_get_type (void);
590 typedef struct _GtkWxCellRenderer GtkWxCellRenderer
;
591 typedef struct _GtkWxCellRendererClass GtkWxCellRendererClass
;
593 struct _GtkWxCellRenderer
595 GtkCellRenderer parent
;
598 wxDataViewCustomRenderer
*cell
;
602 struct _GtkWxCellRendererClass
604 GtkCellRendererClass cell_parent_class
;
608 static GtkCellRenderer
*gtk_wx_cell_renderer_new (void);
609 static void gtk_wx_cell_renderer_init (
610 GtkWxCellRenderer
*cell
);
611 static void gtk_wx_cell_renderer_class_init(
612 GtkWxCellRendererClass
*klass
);
613 static void gtk_wx_cell_renderer_finalize (
615 static void gtk_wx_cell_renderer_get_size (
616 GtkCellRenderer
*cell
,
618 GdkRectangle
*rectangle
,
623 static void gtk_wx_cell_renderer_render (
624 GtkCellRenderer
*cell
,
627 GdkRectangle
*background_area
,
628 GdkRectangle
*cell_area
,
629 GdkRectangle
*expose_area
,
630 GtkCellRendererState flags
);
631 static gboolean
gtk_wx_cell_renderer_activate(
632 GtkCellRenderer
*cell
,
636 GdkRectangle
*background_area
,
637 GdkRectangle
*cell_area
,
638 GtkCellRendererState flags
);
639 static GtkCellEditable
*gtk_wx_cell_renderer_start_editing(
640 GtkCellRenderer
*cell
,
644 GdkRectangle
*background_area
,
645 GdkRectangle
*cell_area
,
646 GtkCellRendererState flags
);
649 static GObjectClass
*cell_parent_class
= NULL
;
654 gtk_wx_cell_renderer_get_type (void)
656 static GType cell_wx_type
= 0;
660 const GTypeInfo cell_wx_info
=
662 sizeof (GtkWxCellRendererClass
),
663 NULL
, /* base_init */
664 NULL
, /* base_finalize */
665 (GClassInitFunc
) gtk_wx_cell_renderer_class_init
,
666 NULL
, /* class_finalize */
667 NULL
, /* class_data */
668 sizeof (GtkWxCellRenderer
),
670 (GInstanceInitFunc
) gtk_wx_cell_renderer_init
,
673 cell_wx_type
= g_type_register_static( GTK_TYPE_CELL_RENDERER
,
674 "GtkWxCellRenderer", &cell_wx_info
, (GTypeFlags
)0 );
681 gtk_wx_cell_renderer_init (GtkWxCellRenderer
*cell
)
684 cell
->last_click
= 0;
688 gtk_wx_cell_renderer_class_init (GtkWxCellRendererClass
*klass
)
690 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
691 GtkCellRendererClass
*cell_class
= GTK_CELL_RENDERER_CLASS (klass
);
693 cell_parent_class
= (GObjectClass
*) g_type_class_peek_parent (klass
);
695 object_class
->finalize
= gtk_wx_cell_renderer_finalize
;
697 cell_class
->get_size
= gtk_wx_cell_renderer_get_size
;
698 cell_class
->render
= gtk_wx_cell_renderer_render
;
699 cell_class
->activate
= gtk_wx_cell_renderer_activate
;
700 cell_class
->start_editing
= gtk_wx_cell_renderer_start_editing
;
704 gtk_wx_cell_renderer_finalize (GObject
*object
)
707 (* G_OBJECT_CLASS (cell_parent_class
)->finalize
) (object
);
711 gtk_wx_cell_renderer_new (void)
713 return (GtkCellRenderer
*) g_object_new (GTK_TYPE_WX_CELL_RENDERER
, NULL
);
718 static GtkCellEditable
*gtk_wx_cell_renderer_start_editing(
719 GtkCellRenderer
*renderer
,
723 GdkRectangle
*background_area
,
724 GdkRectangle
*cell_area
,
725 GtkCellRendererState flags
)
727 GtkWxCellRenderer
*wxrenderer
= (GtkWxCellRenderer
*) renderer
;
728 wxDataViewCustomRenderer
*cell
= wxrenderer
->cell
;
729 if (!cell
->HasEditorCtrl())
733 gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
,
739 rect
.x
+= cell_area
->x
;
740 rect
.y
+= cell_area
->y
;
741 // rect.width -= renderer->xpad * 2;
742 // rect.height -= renderer->ypad * 2;
744 // wxRect renderrect( rect.x, rect.y, rect.width, rect.height );
745 wxRect
renderrect( cell_area
->x
, cell_area
->y
, cell_area
->width
, cell_area
->height
);
747 // wxDataViewListModel *model = cell->GetOwner()->GetOwner()->GetModel();
749 GtkTreePath
*treepath
= gtk_tree_path_new_from_string( path
);
750 unsigned int model_row
= (unsigned int)gtk_tree_path_get_indices (treepath
)[0];
751 gtk_tree_path_free( treepath
);
753 cell
->StartEditing( model_row
, renderrect
);
759 gtk_wx_cell_renderer_get_size (GtkCellRenderer
*renderer
,
761 GdkRectangle
*cell_area
,
767 GtkWxCellRenderer
*wxrenderer
= (GtkWxCellRenderer
*) renderer
;
768 wxDataViewCustomRenderer
*cell
= wxrenderer
->cell
;
770 wxSize size
= cell
->GetSize();
772 gint calc_width
= (gint
) renderer
->xpad
* 2 + size
.x
;
773 gint calc_height
= (gint
) renderer
->ypad
* 2 + size
.y
;
780 if (cell_area
&& size
.x
> 0 && size
.y
> 0)
784 *x_offset
= (gint
)((renderer
->xalign
*
785 (cell_area
->width
- calc_width
- 2 * renderer
->xpad
)));
786 *x_offset
= MAX (*x_offset
, 0) + renderer
->xpad
;
790 *y_offset
= (gint
)((renderer
->yalign
*
791 (cell_area
->height
- calc_height
- 2 * renderer
->ypad
)));
792 *y_offset
= MAX (*y_offset
, 0) + renderer
->ypad
;
800 *height
= calc_height
;
804 gtk_wx_cell_renderer_render (GtkCellRenderer
*renderer
,
807 GdkRectangle
*background_area
,
808 GdkRectangle
*cell_area
,
809 GdkRectangle
*expose_area
,
810 GtkCellRendererState flags
)
813 GtkWxCellRenderer
*wxrenderer
= (GtkWxCellRenderer
*) renderer
;
814 wxDataViewCustomRenderer
*cell
= wxrenderer
->cell
;
817 gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
,
823 rect
.x
+= cell_area
->x
;
824 rect
.y
+= cell_area
->y
;
825 rect
.width
-= renderer
->xpad
* 2;
826 rect
.height
-= renderer
->ypad
* 2;
829 if (gdk_rectangle_intersect (expose_area
, &rect
, &dummy
))
831 wxRect
renderrect( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
832 wxWindowDC
* dc
= (wxWindowDC
*) cell
->GetDC();
833 if (dc
->m_window
== NULL
)
835 dc
->m_window
= window
;
840 if (flags
& GTK_CELL_RENDERER_SELECTED
)
841 state
|= wxDATAVIEW_CELL_SELECTED
;
842 if (flags
& GTK_CELL_RENDERER_PRELIT
)
843 state
|= wxDATAVIEW_CELL_PRELIT
;
844 if (flags
& GTK_CELL_RENDERER_INSENSITIVE
)
845 state
|= wxDATAVIEW_CELL_INSENSITIVE
;
846 if (flags
& GTK_CELL_RENDERER_INSENSITIVE
)
847 state
|= wxDATAVIEW_CELL_INSENSITIVE
;
848 if (flags
& GTK_CELL_RENDERER_FOCUSED
)
849 state
|= wxDATAVIEW_CELL_FOCUSED
;
850 cell
->Render( renderrect
, dc
, state
);
855 gtk_wx_cell_renderer_activate(
856 GtkCellRenderer
*renderer
,
860 GdkRectangle
*background_area
,
861 GdkRectangle
*cell_area
,
862 GtkCellRendererState flags
)
864 GtkWxCellRenderer
*wxrenderer
= (GtkWxCellRenderer
*) renderer
;
865 wxDataViewCustomRenderer
*cell
= wxrenderer
->cell
;
868 gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
,
874 rect
.x
+= cell_area
->x
;
875 rect
.y
+= cell_area
->y
;
876 rect
.width
-= renderer
->xpad
* 2;
877 rect
.height
-= renderer
->ypad
* 2;
879 wxRect
renderrect( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
881 wxDataViewModel
*model
= cell
->GetOwner()->GetOwner()->GetModel();
883 GtkTreePath
*treepath
= gtk_tree_path_new_from_string( path
);
884 unsigned int model_row
= (unsigned int)gtk_tree_path_get_indices (treepath
)[0];
885 gtk_tree_path_free( treepath
);
887 unsigned int model_col
= cell
->GetOwner()->GetModelColumn();
893 // activated by <ENTER>
894 if (cell
->Activate( renderrect
, model
, model_col
, model_row
))
899 else if (event
->type
== GDK_BUTTON_PRESS
)
901 GdkEventButton
*button_event
= (GdkEventButton
*) event
;
902 wxPoint
pt( ((int) button_event
->x
) - renderrect
.x
,
903 ((int) button_event
->y
) - renderrect
.y
);
906 if (button_event
->button
== 1)
908 if (cell
->LeftClick( pt
, renderrect
, model
, model_col
, model_row
))
910 // TODO: query system double-click time
911 if (button_event
->time
- wxrenderer
->last_click
< 400)
912 if (cell
->Activate( renderrect
, model
, model_col
, model_row
))
915 if (button_event
->button
== 3)
917 if (cell
->RightClick( pt
, renderrect
, model
, model_col
, model_row
))
921 wxrenderer
->last_click
= button_event
->time
;
929 // ---------------------------------------------------------
930 // wxGtkDataViewModelNotifier
931 // ---------------------------------------------------------
933 class wxGtkDataViewModelNotifier
: public wxDataViewModelNotifier
936 wxGtkDataViewModelNotifier( GtkWxTreeModel
*wxgtk_model
,
937 wxDataViewModel
*wx_model
,
938 wxDataViewCtrl
*ctrl
);
939 ~wxGtkDataViewModelNotifier();
941 virtual bool ItemAdded( const wxDataViewItem
&parent
, const wxDataViewItem
&item
);
942 virtual bool ItemDeleted( const wxDataViewItem
&item
);
943 virtual bool ItemChanged( const wxDataViewItem
&item
);
944 virtual bool ValueChanged( const wxDataViewItem
&item
, unsigned int col
);
945 virtual bool Cleared();
947 GtkWxTreeModel
*m_wxgtk_model
;
948 wxDataViewModel
*m_wx_model
;
949 wxDataViewCtrl
*m_owner
;
952 // ---------------------------------------------------------
953 // wxGtkDataViewListModelNotifier
954 // ---------------------------------------------------------
956 wxGtkDataViewModelNotifier::wxGtkDataViewModelNotifier(
957 GtkWxTreeModel
* wxgtk_model
, wxDataViewModel
*wx_model
,
958 wxDataViewCtrl
*ctrl
)
960 m_wxgtk_model
= wxgtk_model
;
961 m_wx_model
= wx_model
;
965 wxGtkDataViewModelNotifier::~wxGtkDataViewModelNotifier()
968 m_wxgtk_model
= NULL
;
971 bool wxGtkDataViewModelNotifier::ItemAdded( const wxDataViewItem
&parent
, const wxDataViewItem
&item
)
974 iter
.stamp
= m_wxgtk_model
->stamp
;
975 iter
.user_data
= (gpointer
) item
.GetID();
977 GtkTreePath
*path
= wxgtk_tree_model_get_path(
978 GTK_TREE_MODEL(m_wxgtk_model
), &iter
);
979 gtk_tree_model_row_inserted(
980 GTK_TREE_MODEL(m_wxgtk_model
), path
, &iter
);
981 gtk_tree_path_free (path
);
986 bool wxGtkDataViewModelNotifier::ItemDeleted( const wxDataViewItem
&item
)
989 iter
.stamp
= m_wxgtk_model
->stamp
;
990 iter
.user_data
= (gpointer
) item
.GetID();
992 GtkTreePath
*path
= wxgtk_tree_model_get_path(
993 GTK_TREE_MODEL(m_wxgtk_model
), &iter
);
994 gtk_tree_model_row_deleted(
995 GTK_TREE_MODEL(m_wxgtk_model
), path
);
996 gtk_tree_path_free (path
);
1001 bool wxGtkDataViewModelNotifier::ItemChanged( const wxDataViewItem
&item
)
1004 iter
.stamp
= m_wxgtk_model
->stamp
;
1005 iter
.user_data
= (gpointer
) item
.GetID();
1007 GtkTreePath
*path
= wxgtk_tree_model_get_path(
1008 GTK_TREE_MODEL(m_wxgtk_model
), &iter
);
1009 gtk_tree_model_row_changed(
1010 GTK_TREE_MODEL(m_wxgtk_model
), path
, &iter
);
1011 gtk_tree_path_free (path
);
1016 bool wxGtkDataViewModelNotifier::ValueChanged( const wxDataViewItem
&item
, unsigned int model_col
)
1018 // This adds GTK+'s missing MVC logic for ValueChanged
1020 for (index
= 0; index
< m_owner
->GetColumnCount(); index
++)
1022 wxDataViewColumn
*column
= m_owner
->GetColumn( index
);
1023 if (column
->GetModelColumn() == model_col
)
1025 GtkTreeView
*widget
= GTK_TREE_VIEW(m_owner
->m_treeview
);
1026 GtkTreeViewColumn
*gcolumn
= GTK_TREE_VIEW_COLUMN(column
->GetGtkHandle());
1030 iter
.stamp
= m_wxgtk_model
->stamp
;
1031 iter
.user_data
= (gpointer
) item
.GetID();
1032 GtkTreePath
*path
= wxgtk_tree_model_get_path(
1033 GTK_TREE_MODEL(m_wxgtk_model
), &iter
);
1034 GdkRectangle cell_area
;
1035 gtk_tree_view_get_cell_area( widget
, path
, gcolumn
, &cell_area
);
1036 gtk_tree_path_free( path
);
1038 GtkAdjustment
* hadjust
= gtk_tree_view_get_hadjustment( widget
);
1039 double d
= gtk_adjustment_get_value( hadjust
);
1040 int xdiff
= (int) d
;
1042 int ydiff
= gcolumn
->button
->allocation
.height
;
1044 gtk_widget_queue_draw_area( GTK_WIDGET(widget
),
1045 cell_area
.x
- xdiff
, ydiff
+ cell_area
.y
, cell_area
.width
, cell_area
.height
);
1052 bool wxGtkDataViewModelNotifier::Cleared()
1057 // ---------------------------------------------------------
1058 // wxDataViewRenderer
1059 // ---------------------------------------------------------
1061 IMPLEMENT_ABSTRACT_CLASS(wxDataViewRenderer
, wxDataViewRendererBase
)
1063 wxDataViewRenderer::wxDataViewRenderer( const wxString
&varianttype
, wxDataViewCellMode mode
,
1065 wxDataViewRendererBase( varianttype
, mode
, align
)
1069 // NOTE: SetMode() and SetAlignment() needs to be called in the renderer's ctor,
1070 // after the m_renderer pointer has been initialized
1073 void wxDataViewRenderer::SetMode( wxDataViewCellMode mode
)
1075 GtkCellRendererMode gtkMode
;
1078 case wxDATAVIEW_CELL_INERT
:
1079 gtkMode
= GTK_CELL_RENDERER_MODE_INERT
;
1081 case wxDATAVIEW_CELL_ACTIVATABLE
:
1082 gtkMode
= GTK_CELL_RENDERER_MODE_ACTIVATABLE
;
1084 case wxDATAVIEW_CELL_EDITABLE
:
1085 gtkMode
= GTK_CELL_RENDERER_MODE_EDITABLE
;
1089 GValue gvalue
= { 0, };
1090 g_value_init( &gvalue
, gtk_cell_renderer_mode_get_type() );
1091 g_value_set_enum( &gvalue
, gtkMode
);
1092 g_object_set_property( G_OBJECT(m_renderer
), "mode", &gvalue
);
1093 g_value_unset( &gvalue
);
1096 wxDataViewCellMode
wxDataViewRenderer::GetMode() const
1098 wxDataViewCellMode ret
;
1101 g_object_get( G_OBJECT(m_renderer
), "mode", &gvalue
, NULL
);
1103 switch (g_value_get_enum(&gvalue
))
1105 case GTK_CELL_RENDERER_MODE_INERT
:
1106 ret
= wxDATAVIEW_CELL_INERT
;
1108 case GTK_CELL_RENDERER_MODE_ACTIVATABLE
:
1109 ret
= wxDATAVIEW_CELL_ACTIVATABLE
;
1111 case GTK_CELL_RENDERER_MODE_EDITABLE
:
1112 ret
= wxDATAVIEW_CELL_EDITABLE
;
1116 g_value_unset( &gvalue
);
1121 void wxDataViewRenderer::SetAlignment( int align
)
1123 // horizontal alignment:
1125 gfloat xalign
= 0.0;
1126 if (align
& wxALIGN_RIGHT
)
1128 else if (align
& wxALIGN_CENTER_HORIZONTAL
)
1131 GValue gvalue
= { 0, };
1132 g_value_init( &gvalue
, G_TYPE_FLOAT
);
1133 g_value_set_float( &gvalue
, xalign
);
1134 g_object_set_property( G_OBJECT(m_renderer
), "xalign", &gvalue
);
1135 g_value_unset( &gvalue
);
1137 // vertical alignment:
1139 gfloat yalign
= 0.0;
1140 if (align
& wxALIGN_BOTTOM
)
1142 else if (align
& wxALIGN_CENTER_VERTICAL
)
1145 GValue gvalue2
= { 0, };
1146 g_value_init( &gvalue2
, G_TYPE_FLOAT
);
1147 g_value_set_float( &gvalue2
, yalign
);
1148 g_object_set_property( G_OBJECT(m_renderer
), "yalign", &gvalue2
);
1149 g_value_unset( &gvalue2
);
1152 int wxDataViewRenderer::GetAlignment() const
1157 // horizontal alignment:
1159 g_object_get( G_OBJECT(m_renderer
), "xalign", &gvalue
, NULL
);
1160 float xalign
= g_value_get_float( &gvalue
);
1162 ret
|= wxALIGN_LEFT
;
1163 else if (xalign
== 0.5)
1164 ret
|= wxALIGN_CENTER_HORIZONTAL
;
1166 ret
|= wxALIGN_RIGHT
;
1167 g_value_unset( &gvalue
);
1170 // vertical alignment:
1172 g_object_get( G_OBJECT(m_renderer
), "yalign", &gvalue
, NULL
);
1173 float yalign
= g_value_get_float( &gvalue
);
1176 else if (yalign
== 0.5)
1177 ret
|= wxALIGN_CENTER_VERTICAL
;
1179 ret
|= wxALIGN_BOTTOM
;
1180 g_value_unset( &gvalue
);
1187 // ---------------------------------------------------------
1188 // wxDataViewTextRenderer
1189 // ---------------------------------------------------------
1192 static void wxGtkTextRendererEditedCallback( GtkCellRendererText
*renderer
,
1193 gchar
*arg1
, gchar
*arg2
, gpointer user_data
);
1196 static void wxGtkTextRendererEditedCallback( GtkCellRendererText
*renderer
,
1197 gchar
*arg1
, gchar
*arg2
, gpointer user_data
)
1199 wxDataViewTextRenderer
*cell
= (wxDataViewTextRenderer
*) user_data
;
1201 wxString tmp
= wxGTK_CONV_BACK_FONT(arg2
, cell
->GetOwner()->GetOwner()->GetFont());
1202 wxVariant value
= tmp
;
1203 if (!cell
->Validate( value
))
1206 wxDataViewModel
*model
= cell
->GetOwner()->GetOwner()->GetModel();
1208 GtkTreePath
*path
= gtk_tree_path_new_from_string( arg1
);
1209 unsigned int model_row
= (unsigned int)gtk_tree_path_get_indices (path
)[0];
1210 gtk_tree_path_free( path
);
1212 unsigned int model_col
= cell
->GetOwner()->GetModelColumn();
1214 model
->SetValue( value
, model_col
, model_row
);
1215 model
->ValueChanged( model_col
, model_row
);
1218 IMPLEMENT_CLASS(wxDataViewTextRenderer
, wxDataViewRenderer
)
1220 wxDataViewTextRenderer::wxDataViewTextRenderer( const wxString
&varianttype
, wxDataViewCellMode mode
,
1222 wxDataViewRenderer( varianttype
, mode
, align
)
1224 m_renderer
= (GtkCellRenderer
*) gtk_cell_renderer_text_new();
1226 if (mode
& wxDATAVIEW_CELL_EDITABLE
)
1228 GValue gvalue
= { 0, };
1229 g_value_init( &gvalue
, G_TYPE_BOOLEAN
);
1230 g_value_set_boolean( &gvalue
, true );
1231 g_object_set_property( G_OBJECT(m_renderer
), "editable", &gvalue
);
1232 g_value_unset( &gvalue
);
1234 g_signal_connect_after( m_renderer
, "edited", G_CALLBACK(wxGtkTextRendererEditedCallback
), this );
1238 SetAlignment(align
);
1241 bool wxDataViewTextRenderer::SetValue( const wxVariant
&value
)
1243 wxString tmp
= value
;
1245 GValue gvalue
= { 0, };
1246 g_value_init( &gvalue
, G_TYPE_STRING
);
1247 g_value_set_string( &gvalue
, wxGTK_CONV_FONT( tmp
, GetOwner()->GetOwner()->GetFont() ) );
1248 g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue
);
1249 g_value_unset( &gvalue
);
1254 bool wxDataViewTextRenderer::GetValue( wxVariant
&value
) const
1256 GValue gvalue
= { 0, };
1257 g_value_init( &gvalue
, G_TYPE_STRING
);
1258 g_object_get_property( G_OBJECT(m_renderer
), "text", &gvalue
);
1259 wxString tmp
= wxGTK_CONV_BACK_FONT( g_value_get_string( &gvalue
),
1260 wx_const_cast(wxDataViewTextRenderer
*, this)->GetOwner()->GetOwner()->GetFont() );
1261 g_value_unset( &gvalue
);
1268 void wxDataViewTextRenderer::SetAlignment( int align
)
1270 wxDataViewRenderer::SetAlignment(align
);
1272 if (gtk_check_version(2,10,0))
1275 // horizontal alignment:
1276 PangoAlignment pangoAlign
= PANGO_ALIGN_LEFT
;
1277 if (align
& wxALIGN_RIGHT
)
1278 pangoAlign
= PANGO_ALIGN_RIGHT
;
1279 else if (align
& wxALIGN_CENTER_HORIZONTAL
)
1280 pangoAlign
= PANGO_ALIGN_CENTER
;
1282 GValue gvalue
= { 0, };
1283 g_value_init( &gvalue
, gtk_cell_renderer_mode_get_type() );
1284 g_value_set_enum( &gvalue
, pangoAlign
);
1285 g_object_set_property( G_OBJECT(m_renderer
), "alignment", &gvalue
);
1286 g_value_unset( &gvalue
);
1289 // ---------------------------------------------------------
1290 // wxDataViewBitmapRenderer
1291 // ---------------------------------------------------------
1293 IMPLEMENT_CLASS(wxDataViewBitmapRenderer
, wxDataViewRenderer
)
1295 wxDataViewBitmapRenderer::wxDataViewBitmapRenderer( const wxString
&varianttype
, wxDataViewCellMode mode
,
1297 wxDataViewRenderer( varianttype
, mode
, align
)
1299 m_renderer
= (GtkCellRenderer
*) gtk_cell_renderer_pixbuf_new();
1302 SetAlignment(align
);
1305 bool wxDataViewBitmapRenderer::SetValue( const wxVariant
&value
)
1307 if (value
.GetType() == wxT("wxBitmap"))
1312 // This may create a Pixbuf representation in the
1313 // wxBitmap object (and it will stay there)
1314 GdkPixbuf
*pixbuf
= bitmap
.GetPixbuf();
1316 GValue gvalue
= { 0, };
1317 g_value_init( &gvalue
, G_TYPE_OBJECT
);
1318 g_value_set_object( &gvalue
, pixbuf
);
1319 g_object_set_property( G_OBJECT(m_renderer
), "pixbuf", &gvalue
);
1320 g_value_unset( &gvalue
);
1325 if (value
.GetType() == wxT("wxIcon"))
1330 // This may create a Pixbuf representation in the
1331 // wxBitmap object (and it will stay there)
1332 GdkPixbuf
*pixbuf
= bitmap
.GetPixbuf();
1334 GValue gvalue
= { 0, };
1335 g_value_init( &gvalue
, G_TYPE_OBJECT
);
1336 g_value_set_object( &gvalue
, pixbuf
);
1337 g_object_set_property( G_OBJECT(m_renderer
), "pixbuf", &gvalue
);
1338 g_value_unset( &gvalue
);
1346 bool wxDataViewBitmapRenderer::GetValue( wxVariant
&value
) const
1351 // ---------------------------------------------------------
1352 // wxDataViewToggleRenderer
1353 // ---------------------------------------------------------
1356 static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle
*renderer
,
1357 gchar
*path
, gpointer user_data
);
1360 static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle
*renderer
,
1361 gchar
*path
, gpointer user_data
)
1363 wxDataViewToggleRenderer
*cell
= (wxDataViewToggleRenderer
*) user_data
;
1366 GValue gvalue
= { 0, };
1367 g_value_init( &gvalue
, G_TYPE_BOOLEAN
);
1368 g_object_get_property( G_OBJECT(renderer
), "active", &gvalue
);
1369 bool tmp
= g_value_get_boolean( &gvalue
);
1370 g_value_unset( &gvalue
);
1374 wxVariant value
= tmp
;
1375 if (!cell
->Validate( value
))
1378 wxDataViewModel
*model
= cell
->GetOwner()->GetOwner()->GetModel();
1380 GtkTreePath
*gtk_path
= gtk_tree_path_new_from_string( path
);
1381 unsigned int model_row
= (unsigned int)gtk_tree_path_get_indices (gtk_path
)[0];
1382 gtk_tree_path_free( gtk_path
);
1384 unsigned int model_col
= cell
->GetOwner()->GetModelColumn();
1386 model
->SetValue( value
, model_col
, model_row
);
1387 model
->ValueChanged( model_col
, model_row
);
1390 IMPLEMENT_CLASS(wxDataViewToggleRenderer
, wxDataViewRenderer
)
1392 wxDataViewToggleRenderer::wxDataViewToggleRenderer( const wxString
&varianttype
,
1393 wxDataViewCellMode mode
, int align
) :
1394 wxDataViewRenderer( varianttype
, mode
, align
)
1396 m_renderer
= (GtkCellRenderer
*) gtk_cell_renderer_toggle_new();
1398 if (mode
& wxDATAVIEW_CELL_ACTIVATABLE
)
1400 g_signal_connect_after( m_renderer
, "toggled",
1401 G_CALLBACK(wxGtkToggleRendererToggledCallback
), this );
1405 GValue gvalue
= { 0, };
1406 g_value_init( &gvalue
, G_TYPE_BOOLEAN
);
1407 g_value_set_boolean( &gvalue
, false );
1408 g_object_set_property( G_OBJECT(m_renderer
), "activatable", &gvalue
);
1409 g_value_unset( &gvalue
);
1413 SetAlignment(align
);
1416 bool wxDataViewToggleRenderer::SetValue( const wxVariant
&value
)
1420 GValue gvalue
= { 0, };
1421 g_value_init( &gvalue
, G_TYPE_BOOLEAN
);
1422 g_value_set_boolean( &gvalue
, tmp
);
1423 g_object_set_property( G_OBJECT(m_renderer
), "active", &gvalue
);
1424 g_value_unset( &gvalue
);
1429 bool wxDataViewToggleRenderer::GetValue( wxVariant
&value
) const
1431 GValue gvalue
= { 0, };
1432 g_value_init( &gvalue
, G_TYPE_BOOLEAN
);
1433 g_object_get_property( G_OBJECT(m_renderer
), "active", &gvalue
);
1434 bool tmp
= g_value_get_boolean( &gvalue
);
1435 g_value_unset( &gvalue
);
1442 // ---------------------------------------------------------
1443 // wxDataViewCustomRenderer
1444 // ---------------------------------------------------------
1446 class wxDataViewCtrlDC
: public wxWindowDC
1449 wxDataViewCtrlDC( wxDataViewCtrl
*window
)
1451 GtkWidget
*widget
= window
->m_treeview
;
1455 m_context
= window
->GtkGetPangoDefaultContext();
1456 m_layout
= pango_layout_new( m_context
);
1457 m_fontdesc
= pango_font_description_copy( widget
->style
->font_desc
);
1459 m_cmap
= gtk_widget_get_colormap( widget
? widget
: window
->m_widget
);
1461 // Set m_window later
1463 // m_owner = window;
1467 // ---------------------------------------------------------
1468 // wxDataViewCustomRenderer
1469 // ---------------------------------------------------------
1471 IMPLEMENT_CLASS(wxDataViewCustomRenderer
, wxDataViewRenderer
)
1473 wxDataViewCustomRenderer::wxDataViewCustomRenderer( const wxString
&varianttype
,
1474 wxDataViewCellMode mode
, int align
,
1476 wxDataViewRenderer( varianttype
, mode
, align
)
1486 bool wxDataViewCustomRenderer::Init(wxDataViewCellMode mode
, int align
)
1488 GtkWxCellRenderer
*renderer
= (GtkWxCellRenderer
*) gtk_wx_cell_renderer_new();
1489 renderer
->cell
= this;
1491 m_renderer
= (GtkCellRenderer
*) renderer
;
1494 SetAlignment(align
);
1499 wxDataViewCustomRenderer::~wxDataViewCustomRenderer()
1505 wxDC
*wxDataViewCustomRenderer::GetDC()
1509 if (GetOwner() == NULL
)
1511 if (GetOwner()->GetOwner() == NULL
)
1513 m_dc
= new wxDataViewCtrlDC( GetOwner()->GetOwner() );
1519 // ---------------------------------------------------------
1520 // wxDataViewProgressRenderer
1521 // ---------------------------------------------------------
1523 IMPLEMENT_CLASS(wxDataViewProgressRenderer
, wxDataViewCustomRenderer
)
1525 wxDataViewProgressRenderer::wxDataViewProgressRenderer( const wxString
&label
,
1526 const wxString
&varianttype
, wxDataViewCellMode mode
, int align
) :
1527 wxDataViewCustomRenderer( varianttype
, mode
, align
, true )
1533 if (!gtk_check_version(2,6,0))
1535 m_renderer
= (GtkCellRenderer
*) gtk_cell_renderer_progress_new();
1537 GValue gvalue
= { 0, };
1538 g_value_init( &gvalue
, G_TYPE_STRING
);
1540 // FIXME: font encoding support
1541 g_value_set_string( &gvalue
, wxGTK_CONV_SYS(m_label
) );
1542 g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue
);
1543 g_value_unset( &gvalue
);
1546 SetAlignment(align
);
1551 // Use custom cell code
1552 wxDataViewCustomRenderer::Init(mode
, align
);
1556 wxDataViewProgressRenderer::~wxDataViewProgressRenderer()
1560 bool wxDataViewProgressRenderer::SetValue( const wxVariant
&value
)
1563 if (!gtk_check_version(2,6,0))
1565 gint tmp
= (long) value
;
1566 GValue gvalue
= { 0, };
1567 g_value_init( &gvalue
, G_TYPE_INT
);
1568 g_value_set_int( &gvalue
, tmp
);
1569 g_object_set_property( G_OBJECT(m_renderer
), "value", &gvalue
);
1570 g_value_unset( &gvalue
);
1575 m_value
= (long) value
;
1577 if (m_value
< 0) m_value
= 0;
1578 if (m_value
> 100) m_value
= 100;
1584 bool wxDataViewProgressRenderer::GetValue( wxVariant
&value
) const
1589 bool wxDataViewProgressRenderer::Render( wxRect cell
, wxDC
*dc
, int state
)
1591 double pct
= (double)m_value
/ 100.0;
1593 bar
.width
= (int)(cell
.width
* pct
);
1594 dc
->SetPen( *wxTRANSPARENT_PEN
);
1595 dc
->SetBrush( *wxBLUE_BRUSH
);
1596 dc
->DrawRectangle( bar
);
1598 dc
->SetBrush( *wxTRANSPARENT_BRUSH
);
1599 dc
->SetPen( *wxBLACK_PEN
);
1600 dc
->DrawRectangle( cell
);
1605 wxSize
wxDataViewProgressRenderer::GetSize() const
1607 return wxSize(40,12);
1610 // ---------------------------------------------------------
1611 // wxDataViewDateRenderer
1612 // ---------------------------------------------------------
1614 class wxDataViewDateRendererPopupTransient
: public wxPopupTransientWindow
1617 wxDataViewDateRendererPopupTransient( wxWindow
* parent
, wxDateTime
*value
,
1618 wxDataViewModel
*model
, const wxDataViewItem
&item
, unsigned int col
) :
1619 wxPopupTransientWindow( parent
, wxBORDER_SIMPLE
)
1624 m_cal
= new wxCalendarCtrl( this, -1, *value
);
1625 wxBoxSizer
*sizer
= new wxBoxSizer( wxHORIZONTAL
);
1626 sizer
->Add( m_cal
, 1, wxGROW
);
1631 virtual void OnDismiss()
1635 void OnCalendar( wxCalendarEvent
&event
);
1637 wxCalendarCtrl
*m_cal
;
1638 wxDataViewModel
*m_model
;
1639 wxDataViewItem m_item
;
1643 DECLARE_EVENT_TABLE()
1646 BEGIN_EVENT_TABLE(wxDataViewDateRendererPopupTransient
,wxPopupTransientWindow
)
1647 EVT_CALENDAR( -1, wxDataViewDateRendererPopupTransient::OnCalendar
)
1650 void wxDataViewDateRendererPopupTransient::OnCalendar( wxCalendarEvent
&event
)
1652 wxDateTime date
= event
.GetDate();
1653 wxVariant value
= date
;
1654 m_model
->SetValue( value
, m_item
, m_col
);
1655 m_model
->ValueChanged( m_item
, m_col
);
1659 IMPLEMENT_CLASS(wxDataViewDateRenderer
, wxDataViewCustomRenderer
)
1661 wxDataViewDateRenderer::wxDataViewDateRenderer( const wxString
&varianttype
,
1662 wxDataViewCellMode mode
, int align
) :
1663 wxDataViewCustomRenderer( varianttype
, mode
, align
)
1666 SetAlignment(align
);
1669 bool wxDataViewDateRenderer::SetValue( const wxVariant
&value
)
1671 m_date
= value
.GetDateTime();
1676 bool wxDataViewDateRenderer::GetValue( wxVariant
&value
) const
1681 bool wxDataViewDateRenderer::Render( wxRect cell
, wxDC
*dc
, int state
)
1683 dc
->SetFont( GetOwner()->GetOwner()->GetFont() );
1684 wxString tmp
= m_date
.FormatDate();
1685 dc
->DrawText( tmp
, cell
.x
, cell
.y
);
1690 wxSize
wxDataViewDateRenderer::GetSize() const
1692 wxString tmp
= m_date
.FormatDate();
1694 GetView()->GetTextExtent( tmp
, &x
, &y
, &d
);
1695 return wxSize(x
,y
+d
);
1698 bool wxDataViewDateRenderer::Activate( wxRect cell
, wxDataViewModel
*model
,
1699 const wxDataViewItem
&item
, unsigned int col
)
1702 model
->GetValue( variant
, item
, col
);
1703 wxDateTime value
= variant
.GetDateTime();
1705 wxDataViewDateRendererPopupTransient
*popup
= new wxDataViewDateRendererPopupTransient(
1706 GetOwner()->GetOwner()->GetParent(), &value
, model
, item
, col
);
1707 wxPoint pos
= wxGetMousePosition();
1710 popup
->Popup( popup
->m_cal
);
1715 // ---------------------------------------------------------
1717 // ---------------------------------------------------------
1721 gtk_dataview_header_button_press_callback( GtkWidget
*widget
,
1722 GdkEventButton
*gdk_event
,
1723 wxDataViewColumn
*column
)
1725 if (gdk_event
->type
!= GDK_BUTTON_PRESS
)
1728 if (gdk_event
->button
== 1)
1730 wxDataViewCtrl
*dv
= column
->GetOwner();
1731 wxDataViewEvent
event( wxEVT_COMMAND_DATAVIEW_COLUMN_HEADER_CLICK
, dv
->GetId() );
1732 event
.SetDataViewColumn( column
);
1733 event
.SetModel( dv
->GetModel() );
1734 dv
->GetEventHandler()->ProcessEvent( event
);
1741 static void wxGtkTreeCellDataFunc( GtkTreeViewColumn
*column
,
1742 GtkCellRenderer
*cell
,
1743 GtkTreeModel
*model
,
1749 static void wxGtkTreeCellDataFunc( GtkTreeViewColumn
*column
,
1750 GtkCellRenderer
*renderer
,
1751 GtkTreeModel
*model
,
1755 g_return_if_fail (GTK_IS_WX_TREE_MODEL (model
));
1756 GtkWxTreeModel
*tree_model
= (GtkWxTreeModel
*) model
;
1758 wxDataViewRenderer
*cell
= (wxDataViewRenderer
*) data
;
1760 wxDataViewItem
item( (wxUint32
) iter
->user_data
);
1763 tree_model
->model
->GetValue( value
, item
, cell
->GetOwner()->GetModelColumn() );
1765 if (value
.GetType() != cell
->GetVariantType())
1766 wxLogError( wxT("Wrong type, required: %s but: %s"),
1767 value
.GetType().c_str(),
1768 cell
->GetVariantType().c_str() );
1770 cell
->SetValue( value
);
1773 wxListItemAttr attr
;
1774 tree_model
->model
->GetAttr( attr
, cell
->GetOwner()->GetModelColumn(), model_row
);
1776 if (attr
.HasBackgroundColour())
1778 wxColour colour
= attr
.GetBackgroundColour();
1779 const GdkColor
* const gcol
= colour
.GetColor();
1781 GValue gvalue
= { 0, };
1782 g_value_init( &gvalue
, GDK_TYPE_COLOR
);
1783 g_value_set_boxed( &gvalue
, gcol
);
1784 g_object_set_property( G_OBJECT(renderer
), "cell-background_gdk", &gvalue
);
1785 g_value_unset( &gvalue
);
1789 GValue gvalue
= { 0, };
1790 g_value_init( &gvalue
, G_TYPE_BOOLEAN
);
1791 g_value_set_boolean( &gvalue
, FALSE
);
1792 g_object_set_property( G_OBJECT(renderer
), "cell-background-set", &gvalue
);
1793 g_value_unset( &gvalue
);
1799 IMPLEMENT_CLASS(wxDataViewColumn
, wxDataViewColumnBase
)
1801 wxDataViewColumn::wxDataViewColumn( const wxString
&title
, wxDataViewRenderer
*cell
,
1802 unsigned int model_column
, int width
,
1803 wxAlignment align
, int flags
) :
1804 wxDataViewColumnBase( title
, cell
, model_column
, width
, align
, flags
)
1806 Init( align
, flags
, width
);
1808 gtk_tree_view_column_set_clickable( GTK_TREE_VIEW_COLUMN(m_column
), TRUE
);
1812 wxDataViewColumn::wxDataViewColumn( const wxBitmap
&bitmap
, wxDataViewRenderer
*cell
,
1813 unsigned int model_column
, int width
,
1814 wxAlignment align
, int flags
) :
1815 wxDataViewColumnBase( bitmap
, cell
, model_column
, width
, align
, flags
)
1817 Init( align
, flags
, width
);
1819 SetBitmap( bitmap
);
1822 void wxDataViewColumn::Init(wxAlignment align
, int flags
, int width
)
1824 m_isConnected
= false;
1826 GtkCellRenderer
*renderer
= (GtkCellRenderer
*) GetRenderer()->GetGtkHandle();
1827 GtkTreeViewColumn
*column
= gtk_tree_view_column_new();
1828 m_column
= (GtkWidget
*) column
;
1831 SetAlignment( align
);
1833 // NOTE: we prefer not to call SetMinWidth(wxDVC_DEFAULT_MINWIDTH);
1834 // as GTK+ is smart and unless explicitely told, will set the minimal
1835 // width to the title's lenght, which is a better default
1837 // the GTK_TREE_VIEW_COLUMN_FIXED is required by the "fixed height" mode
1838 // that we use for the wxDataViewCtrl
1839 gtk_tree_view_column_set_fixed_width( column
, width
< 0 ? wxDVC_DEFAULT_WIDTH
: width
);
1840 gtk_tree_view_column_set_sizing( column
, GTK_TREE_VIEW_COLUMN_FIXED
);
1842 gtk_tree_view_column_pack_end( column
, renderer
, TRUE
);
1844 gtk_tree_view_column_set_cell_data_func( column
, renderer
,
1845 wxGtkTreeCellDataFunc
, (gpointer
) GetRenderer(), NULL
);
1848 wxDataViewColumn::~wxDataViewColumn()
1852 void wxDataViewColumn::OnInternalIdle()
1857 if (GTK_WIDGET_REALIZED(GetOwner()->m_treeview
))
1859 GtkTreeViewColumn
*column
= GTK_TREE_VIEW_COLUMN(m_column
);
1862 g_signal_connect(column
->button
, "button_press_event",
1863 G_CALLBACK (gtk_dataview_header_button_press_callback
), this);
1865 m_isConnected
= true;
1870 void wxDataViewColumn::SetOwner( wxDataViewCtrl
*owner
)
1872 wxDataViewColumnBase::SetOwner( owner
);
1874 GtkTreeViewColumn
*column
= GTK_TREE_VIEW_COLUMN(m_column
);
1876 gtk_tree_view_column_set_title( column
, wxGTK_CONV_FONT(GetTitle(), GetOwner()->GetFont() ) );
1879 void wxDataViewColumn::SetTitle( const wxString
&title
)
1881 GtkTreeViewColumn
*column
= GTK_TREE_VIEW_COLUMN(m_column
);
1885 // disconnect before column->button gets recreated
1886 g_signal_handlers_disconnect_by_func( column
->button
,
1887 (GtkWidget
*) gtk_dataview_header_button_press_callback
, this);
1889 m_isConnected
= false;
1892 // FIXME: can it really happen that we don't have the owner here??
1893 wxDataViewCtrl
*ctrl
= GetOwner();
1894 gtk_tree_view_column_set_title( column
, ctrl
? wxGTK_CONV_FONT(title
, ctrl
->GetFont())
1895 : wxGTK_CONV_SYS(title
) );
1897 gtk_tree_view_column_set_widget( column
, NULL
);
1900 wxString
wxDataViewColumn::GetTitle() const
1902 const gchar
*str
= gtk_tree_view_column_get_title( GTK_TREE_VIEW_COLUMN(m_column
) );
1903 return wxConvFileName
->cMB2WX(str
);
1906 void wxDataViewColumn::SetBitmap( const wxBitmap
&bitmap
)
1908 wxDataViewColumnBase::SetBitmap( bitmap
);
1910 GtkTreeViewColumn
*column
= GTK_TREE_VIEW_COLUMN(m_column
);
1913 GtkImage
*gtk_image
= GTK_IMAGE( gtk_image_new() );
1915 GdkBitmap
*mask
= (GdkBitmap
*) NULL
;
1916 if (bitmap
.GetMask())
1917 mask
= bitmap
.GetMask()->GetBitmap();
1919 if (bitmap
.HasPixbuf())
1921 gtk_image_set_from_pixbuf(GTK_IMAGE(gtk_image
),
1922 bitmap
.GetPixbuf());
1926 gtk_image_set_from_pixmap(GTK_IMAGE(gtk_image
),
1927 bitmap
.GetPixmap(), mask
);
1929 gtk_widget_show( GTK_WIDGET(gtk_image
) );
1931 gtk_tree_view_column_set_widget( column
, GTK_WIDGET(gtk_image
) );
1935 gtk_tree_view_column_set_widget( column
, NULL
);
1939 void wxDataViewColumn::SetHidden( bool hidden
)
1941 gtk_tree_view_column_set_visible( GTK_TREE_VIEW_COLUMN(m_column
), !hidden
);
1944 void wxDataViewColumn::SetResizeable( bool resizeable
)
1946 gtk_tree_view_column_set_resizable( GTK_TREE_VIEW_COLUMN(m_column
), resizeable
);
1949 void wxDataViewColumn::SetAlignment( wxAlignment align
)
1951 GtkTreeViewColumn
*column
= GTK_TREE_VIEW_COLUMN(m_column
);
1953 gfloat xalign
= 0.0;
1954 if (align
== wxALIGN_RIGHT
)
1956 if (align
== wxALIGN_CENTER_HORIZONTAL
||
1957 align
== wxALIGN_CENTER
)
1960 gtk_tree_view_column_set_alignment( column
, xalign
);
1963 wxAlignment
wxDataViewColumn::GetAlignment() const
1965 gfloat xalign
= gtk_tree_view_column_get_alignment( GTK_TREE_VIEW_COLUMN(m_column
) );
1968 return wxALIGN_RIGHT
;
1970 return wxALIGN_CENTER_HORIZONTAL
;
1972 return wxALIGN_LEFT
;
1975 void wxDataViewColumn::SetSortable( bool sortable
)
1977 GtkTreeViewColumn
*column
= GTK_TREE_VIEW_COLUMN(m_column
);
1978 gtk_tree_view_column_set_sort_indicator( column
, sortable
);
1981 bool wxDataViewColumn::IsSortable() const
1983 GtkTreeViewColumn
*column
= GTK_TREE_VIEW_COLUMN(m_column
);
1984 return gtk_tree_view_column_get_sort_indicator( column
);
1987 bool wxDataViewColumn::IsResizeable() const
1989 GtkTreeViewColumn
*column
= GTK_TREE_VIEW_COLUMN(m_column
);
1990 return gtk_tree_view_column_get_resizable( column
);
1993 bool wxDataViewColumn::IsHidden() const
1995 GtkTreeViewColumn
*column
= GTK_TREE_VIEW_COLUMN(m_column
);
1996 return !gtk_tree_view_column_get_visible( column
);
1999 void wxDataViewColumn::SetSortOrder( bool ascending
)
2001 GtkTreeViewColumn
*column
= GTK_TREE_VIEW_COLUMN(m_column
);
2004 gtk_tree_view_column_set_sort_order( column
, GTK_SORT_ASCENDING
);
2006 gtk_tree_view_column_set_sort_order( column
, GTK_SORT_DESCENDING
);
2009 bool wxDataViewColumn::IsSortOrderAscending() const
2011 GtkTreeViewColumn
*column
= GTK_TREE_VIEW_COLUMN(m_column
);
2013 return (gtk_tree_view_column_get_sort_order( column
) != GTK_SORT_DESCENDING
);
2016 void wxDataViewColumn::SetMinWidth( int width
)
2018 gtk_tree_view_column_set_min_width( GTK_TREE_VIEW_COLUMN(m_column
), width
);
2021 int wxDataViewColumn::GetMinWidth() const
2023 return gtk_tree_view_column_get_min_width( GTK_TREE_VIEW_COLUMN(m_column
) );
2026 int wxDataViewColumn::GetWidth() const
2028 return gtk_tree_view_column_get_width( GTK_TREE_VIEW_COLUMN(m_column
) );
2031 void wxDataViewColumn::SetWidth( int width
)
2033 gtk_tree_view_column_set_fixed_width( GTK_TREE_VIEW_COLUMN(m_column
), width
);
2037 //-----------------------------------------------------------------------------
2038 // wxDataViewCtrl signal callbacks
2039 //-----------------------------------------------------------------------------
2042 wxdataview_selection_changed_callback( GtkTreeSelection
* selection
, wxDataViewCtrl
*dv
)
2044 if (!GTK_WIDGET_REALIZED(dv
->m_widget
))
2047 wxDataViewEvent
event( wxEVT_COMMAND_DATAVIEW_ITEM_SELECTED
, dv
->GetId() );
2049 event
.SetModel( dv
->GetModel() );
2050 dv
->GetEventHandler()->ProcessEvent( event
);
2054 wxdataview_row_activated_callback( GtkTreeView
* treeview
, GtkTreePath
*path
,
2055 GtkTreeViewColumn
*column
, wxDataViewCtrl
*dv
)
2057 wxDataViewEvent
event( wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED
, dv
->GetId() );
2059 event
.SetModel( dv
->GetModel() );
2060 dv
->GetEventHandler()->ProcessEvent( event
);
2063 //-----------------------------------------------------------------------------
2065 //-----------------------------------------------------------------------------
2067 //-----------------------------------------------------------------------------
2068 // InsertChild for wxDataViewCtrl
2069 //-----------------------------------------------------------------------------
2071 static void wxInsertChildInDataViewCtrl( wxWindowGTK
* parent
, wxWindowGTK
* child
)
2073 wxDataViewCtrl
* dvc
= (wxDataViewCtrl
*) parent
;
2074 GtkWidget
*treeview
= dvc
->GtkGetTreeView();
2076 // Insert widget in GtkTreeView
2077 if (GTK_WIDGET_REALIZED(treeview
))
2078 gtk_widget_set_parent_window( child
->m_widget
,
2079 gtk_tree_view_get_bin_window( GTK_TREE_VIEW(treeview
) ) );
2080 gtk_widget_set_parent( child
->m_widget
, treeview
);
2084 void gtk_dataviewctrl_size_callback( GtkWidget
*WXUNUSED(widget
),
2085 GtkAllocation
*alloc
,
2086 wxDataViewCtrl
*win
)
2089 wxWindowList::Node
*node
= win
->GetChildren().GetFirst();
2092 wxWindow
*child
= node
->GetData();
2095 gtk_widget_size_request( child
->m_widget
, &req
);
2097 GtkAllocation alloc
;
2098 alloc
.x
= child
->m_x
;
2099 alloc
.y
= child
->m_y
;
2100 alloc
.width
= child
->m_width
;
2101 alloc
.height
= child
->m_height
;
2102 gtk_widget_size_allocate( child
->m_widget
, &alloc
);
2104 node
= node
->GetNext();
2110 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl
, wxDataViewCtrlBase
)
2112 wxDataViewCtrl::~wxDataViewCtrl()
2115 GetModel()->RemoveNotifier( m_notifier
);
2117 // remove the model from the GtkTreeView before it gets destroyed by the
2118 // wxDataViewCtrlBase's dtor
2119 gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview
), NULL
);
2122 void wxDataViewCtrl::Init()
2127 bool wxDataViewCtrl::Create(wxWindow
*parent
, wxWindowID id
,
2128 const wxPoint
& pos
, const wxSize
& size
,
2129 long style
, const wxValidator
& validator
)
2133 if (!PreCreation( parent
, pos
, size
) ||
2134 !CreateBase( parent
, id
, pos
, size
, style
, validator
))
2136 wxFAIL_MSG( wxT("wxDataViewCtrl creation failed") );
2140 m_insertCallback
= wxInsertChildInDataViewCtrl
;
2142 m_widget
= gtk_scrolled_window_new (NULL
, NULL
);
2144 GtkScrolledWindowSetBorder(m_widget
, style
);
2146 m_treeview
= gtk_tree_view_new();
2147 gtk_container_add (GTK_CONTAINER (m_widget
), m_treeview
);
2149 g_signal_connect (m_treeview
, "size_allocate",
2150 G_CALLBACK (gtk_dataviewctrl_size_callback
), this);
2153 if (!gtk_check_version(2,6,0))
2154 gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview
), TRUE
);
2157 if (style
& wxDV_MULTIPLE
)
2159 GtkTreeSelection
*selection
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) );
2160 gtk_tree_selection_set_mode( selection
, GTK_SELECTION_MULTIPLE
);
2163 gtk_tree_view_set_headers_visible( GTK_TREE_VIEW(m_treeview
), (style
& wxDV_NO_HEADER
) == 0 );
2166 if (!gtk_check_version(2,10,0))
2168 GtkTreeViewGridLines grid
= GTK_TREE_VIEW_GRID_LINES_NONE
;
2170 if ((style
& wxDV_HORIZ_RULES
) != 0 &&
2171 (style
& wxDV_VERT_RULES
) != 0)
2172 grid
= GTK_TREE_VIEW_GRID_LINES_BOTH
;
2173 else if (style
& wxDV_VERT_RULES
)
2174 grid
= GTK_TREE_VIEW_GRID_LINES_VERTICAL
;
2175 else if (style
& wxDV_HORIZ_RULES
)
2176 grid
= GTK_TREE_VIEW_GRID_LINES_HORIZONTAL
;
2178 gtk_tree_view_set_grid_lines( GTK_TREE_VIEW(m_treeview
), grid
);
2183 gtk_tree_view_set_rules_hint( GTK_TREE_VIEW(m_treeview
), (style
& wxDV_HORIZ_RULES
) != 0 );
2186 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_widget
),
2187 GTK_POLICY_AUTOMATIC
, GTK_POLICY_ALWAYS
);
2188 gtk_widget_show (m_treeview
);
2190 m_parent
->DoAddChild( this );
2194 GtkEnableSelectionEvents();
2196 g_signal_connect_after (m_treeview
, "row_activated",
2197 G_CALLBACK (wxdataview_row_activated_callback
), this);
2202 void wxDataViewCtrl::OnInternalIdle()
2204 wxWindow::OnInternalIdle();
2206 unsigned int cols
= GetColumnCount();
2208 for (i
= 0; i
< cols
; i
++)
2210 wxDataViewColumn
*col
= GetColumn( i
);
2211 col
->OnInternalIdle();
2215 bool wxDataViewCtrl::AssociateModel( wxDataViewModel
*model
)
2217 if (!wxDataViewCtrlBase::AssociateModel( model
))
2220 GtkWxTreeModel
*gtk_store
= wxgtk_tree_model_new();
2221 gtk_store
->model
= model
;
2223 m_notifier
= new wxGtkDataViewModelNotifier( gtk_store
, model
, this );
2225 model
->AddNotifier( m_notifier
);
2227 gtk_tree_view_set_model( GTK_TREE_VIEW(m_treeview
), GTK_TREE_MODEL(gtk_store
) );
2228 g_object_unref( gtk_store
);
2233 bool wxDataViewCtrl::AppendColumn( wxDataViewColumn
*col
)
2235 if (!wxDataViewCtrlBase::AppendColumn(col
))
2238 GtkTreeViewColumn
*column
= (GtkTreeViewColumn
*)col
->GetGtkHandle();
2240 gtk_tree_view_append_column( GTK_TREE_VIEW(m_treeview
), column
);
2245 void wxDataViewCtrl::GtkDisableSelectionEvents()
2247 GtkTreeSelection
*selection
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) );
2248 g_signal_connect_after (selection
, "changed",
2249 G_CALLBACK (wxdataview_selection_changed_callback
), this);
2252 void wxDataViewCtrl::GtkEnableSelectionEvents()
2254 GtkTreeSelection
*selection
= gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview
) );
2255 g_signal_handlers_disconnect_by_func( selection
,
2256 (gpointer
) (wxdataview_selection_changed_callback
), this);
2261 wxDataViewCtrl::GetClassDefaultAttributes(wxWindowVariant
WXUNUSED(variant
))
2263 return GetDefaultAttributesFromGTKWidget(gtk_tree_view_new
);
2268 // !wxUSE_GENERICDATAVIEWCTRL
2271 // wxUSE_DATAVIEWCTRL