1 /////////////////////////////////////////////////////////////////////////////
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"
15 #if wxUSE_DATAVIEWCTRL
17 #include "wx/dataview.h"
18 #include "wx/stockitem.h"
19 #include "wx/dcclient.h"
21 #include "wx/gtk/private.h"
22 #include "wx/gtk/win_gtk.h"
24 #include <gobject/gvaluecollector.h>
25 #include <gtk/gtktreemodel.h>
26 #include <gtk/gtktreednd.h>
28 //-----------------------------------------------------------------------------
30 //-----------------------------------------------------------------------------
34 //-----------------------------------------------------------------------------
36 //-----------------------------------------------------------------------------
38 extern void wxapp_install_idle_handler();
41 //-----------------------------------------------------------------------------
43 //-----------------------------------------------------------------------------
45 extern bool g_blockEventsOnDrag
;
47 //-----------------------------------------------------------------------------
48 // define new GTK+ class wxGtkListStore
49 //-----------------------------------------------------------------------------
53 #define GTK_TYPE_WX_LIST_STORE (gtk_wx_list_store_get_type ())
54 #define GTK_WX_LIST_STORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_LIST_STORE, GtkWxListStore))
55 #define GTK_WX_LIST_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_LIST_STORE, GtkWxListStoreClass))
56 #define GTK_IS_WX_LIST_STORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_LIST_STORE))
57 #define GTK_IS_WX_LIST_STORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_LIST_STORE))
58 #define GTK_WX_LIST_STORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_LIST_STORE, GtkWxListStoreClass))
60 GType
gtk_wx_list_store_get_type (void);
62 typedef struct _GtkWxListStore GtkWxListStore
;
63 typedef struct _GtkWxListStoreClass GtkWxListStoreClass
;
65 struct _GtkWxListStore
71 wxDataViewListModel
*model
;
74 struct _GtkWxListStoreClass
76 GObjectClass list_parent_class
;
80 static GtkWxListStore
*wxgtk_list_store_new (void);
81 static void wxgtk_list_store_init (GtkWxListStore
*list_store
);
82 static void wxgtk_list_store_class_init (GtkWxListStoreClass
*klass
);
83 static void wxgtk_list_store_tree_model_init (GtkTreeModelIface
*iface
);
84 static void wxgtk_list_store_finalize (GObject
*object
);
85 static GtkTreeModelFlags
wxgtk_list_store_get_flags (GtkTreeModel
*tree_model
);
86 static gint
wxgtk_list_store_get_n_columns (GtkTreeModel
*tree_model
);
87 static GType
wxgtk_list_store_get_column_type (GtkTreeModel
*tree_model
,
89 static gboolean
wxgtk_list_store_get_iter (GtkTreeModel
*tree_model
,
92 static GtkTreePath
*wxgtk_list_store_get_path (GtkTreeModel
*tree_model
,
94 static void wxgtk_list_store_get_value (GtkTreeModel
*tree_model
,
98 static gboolean
wxgtk_list_store_iter_next (GtkTreeModel
*tree_model
,
100 static gboolean
wxgtk_list_store_iter_children (GtkTreeModel
*tree_model
,
102 GtkTreeIter
*parent
);
103 static gboolean
wxgtk_list_store_iter_has_child (GtkTreeModel
*tree_model
,
105 static gint
wxgtk_list_store_iter_n_children (GtkTreeModel
*tree_model
,
107 static gboolean
wxgtk_list_store_iter_nth_child (GtkTreeModel
*tree_model
,
111 static gboolean
wxgtk_list_store_iter_parent (GtkTreeModel
*tree_model
,
115 static GObjectClass
*list_parent_class
= NULL
;
118 gtk_wx_list_store_get_type (void)
120 static GType list_store_type
= 0;
122 if (!list_store_type
)
124 static const GTypeInfo list_store_info
=
126 sizeof (GtkWxListStoreClass
),
127 NULL
, /* base_init */
128 NULL
, /* base_finalize */
129 (GClassInitFunc
) wxgtk_list_store_class_init
,
130 NULL
, /* class_finalize */
131 NULL
, /* class_data */
132 sizeof (GtkWxListStore
),
134 (GInstanceInitFunc
) wxgtk_list_store_init
,
137 static const GInterfaceInfo tree_model_info
=
139 (GInterfaceInitFunc
) wxgtk_list_store_tree_model_init
,
144 list_store_type
= g_type_register_static (G_TYPE_OBJECT
, "GtkWxListStore",
145 &list_store_info
, (GTypeFlags
)0 );
147 g_type_add_interface_static (list_store_type
,
152 return list_store_type
;
155 static GtkWxListStore
*
156 wxgtk_list_store_new(void)
158 GtkWxListStore
*retval
= (GtkWxListStore
*) g_object_new (GTK_TYPE_WX_LIST_STORE
, NULL
);
163 wxgtk_list_store_class_init (GtkWxListStoreClass
*klass
)
165 list_parent_class
= (GObjectClass
*) g_type_class_peek_parent (klass
);
166 GObjectClass
*object_class
= (GObjectClass
*) klass
;
167 object_class
->finalize
= wxgtk_list_store_finalize
;
171 wxgtk_list_store_tree_model_init (GtkTreeModelIface
*iface
)
173 iface
->get_flags
= wxgtk_list_store_get_flags
;
174 iface
->get_n_columns
= wxgtk_list_store_get_n_columns
;
175 iface
->get_column_type
= wxgtk_list_store_get_column_type
;
176 iface
->get_iter
= wxgtk_list_store_get_iter
;
177 iface
->get_path
= wxgtk_list_store_get_path
;
178 iface
->get_value
= wxgtk_list_store_get_value
;
179 iface
->iter_next
= wxgtk_list_store_iter_next
;
180 iface
->iter_children
= wxgtk_list_store_iter_children
;
181 iface
->iter_has_child
= wxgtk_list_store_iter_has_child
;
182 iface
->iter_n_children
= wxgtk_list_store_iter_n_children
;
183 iface
->iter_nth_child
= wxgtk_list_store_iter_nth_child
;
184 iface
->iter_parent
= wxgtk_list_store_iter_parent
;
188 wxgtk_list_store_init (GtkWxListStore
*list_store
)
190 list_store
->model
= NULL
;
191 list_store
->stamp
= g_random_int();
195 wxgtk_list_store_finalize (GObject
*object
)
197 /* GtkWxListStore *list_store = GTK_WX_LIST_STORE (object); */
199 /* we need to sort out, which class deletes what */
200 /* delete list_store->model; */
203 (* list_parent_class
->finalize
) (object
);
208 //-----------------------------------------------------------------------------
209 // implement callbacks from wxGtkListStore class by letting
210 // them call the methods of wxWidgets' wxDataViewListModel
211 //-----------------------------------------------------------------------------
213 static GtkTreeModelFlags
214 wxgtk_list_store_get_flags (GtkTreeModel
*tree_model
)
216 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), (GtkTreeModelFlags
)0 );
218 // GTK+ list store uses a linked list for storing the
219 // items and a pointer to a child is used as the member
220 // field of a GtkTreeIter. This means that the iter is
221 // valid in the GtkListStore as long as the child exists.
222 // We use the index of the row and since the index of a
223 // specific row will change if a row above is deleted,
224 // the iter does not persist
225 return /* GTK_TREE_MODEL_ITERS_PERSIST | */ GTK_TREE_MODEL_LIST_ONLY
;
229 wxgtk_list_store_get_n_columns (GtkTreeModel
*tree_model
)
231 GtkWxListStore
*list_store
= (GtkWxListStore
*) tree_model
;
232 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), 0);
234 return list_store
->model
->GetNumberOfCols();
238 wxgtk_list_store_get_column_type (GtkTreeModel
*tree_model
,
241 GtkWxListStore
*list_store
= (GtkWxListStore
*) tree_model
;
242 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), G_TYPE_INVALID
);
244 GType gtype
= G_TYPE_INVALID
;
246 wxString wxtype
= list_store
->model
->GetColType( (size_t) index
);
248 if (wxtype
== wxT("string"))
249 gtype
= G_TYPE_STRING
;
255 wxgtk_list_store_get_iter (GtkTreeModel
*tree_model
,
259 GtkWxListStore
*list_store
= (GtkWxListStore
*) tree_model
;
260 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), FALSE
);
261 g_return_val_if_fail (gtk_tree_path_get_depth (path
) > 0, FALSE
);
263 size_t i
= (size_t)gtk_tree_path_get_indices (path
)[0];
265 if (i
>= list_store
->model
->GetNumberOfRows())
268 iter
->stamp
= list_store
->stamp
;
269 // user_data is just the index
270 iter
->user_data
= (gpointer
) i
;
276 wxgtk_list_store_get_path (GtkTreeModel
*tree_model
,
279 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), NULL
);
280 g_return_val_if_fail (iter
->stamp
== GTK_WX_LIST_STORE (tree_model
)->stamp
, NULL
);
282 GtkTreePath
*retval
= gtk_tree_path_new ();
283 // user_data is just the index
284 int i
= (int) iter
->user_data
;
285 gtk_tree_path_append_index (retval
, i
);
290 wxgtk_list_store_get_value (GtkTreeModel
*tree_model
,
295 GtkWxListStore
*list_store
= (GtkWxListStore
*) tree_model
;
296 g_return_if_fail (GTK_IS_WX_LIST_STORE (tree_model
) );
298 wxDataViewListModel
*model
= list_store
->model
;
299 wxString mtype
= model
->GetColType( (size_t) column
);
300 if (mtype
== wxT("string"))
302 g_value_init( value
, G_TYPE_STRING
);
303 wxVariant variant
= model
->GetValue( (size_t) column
, (size_t) iter
->user_data
);
304 g_value_set_string( value
, wxGTK_CONV(variant
.GetString()) );
311 GtkTreeDataList
*list
;
312 gint tmp_column
= column
;
314 g_return_if_fail (column
< GTK_LIST_STORE (tree_model
)->n_columns
);
315 g_return_if_fail (GTK_LIST_STORE (tree_model
)->stamp
== iter
->stamp
);
317 list
= G_SLIST (iter
->user_data
)->data
;
319 while (tmp_column
-- > 0 && list
)
323 g_value_init (value
, GTK_LIST_STORE (tree_model
)->column_headers
[column
]);
325 _gtk_tree_data_list_node_to_value (list
,
326 GTK_LIST_STORE (tree_model
)->column_headers
[column
],
333 wxgtk_list_store_iter_next (GtkTreeModel
*tree_model
,
336 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), FALSE
);
337 GtkWxListStore
*list_store
= (GtkWxListStore
*) tree_model
;
339 g_return_val_if_fail (list_store
->stamp
== iter
->stamp
, FALSE
);
341 int n
= (int) iter
->user_data
;
346 if (n
>= (int) list_store
->model
->GetNumberOfRows())
349 iter
->user_data
= (gpointer
) ++n
;
355 wxgtk_list_store_iter_children (GtkTreeModel
*tree_model
,
359 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), FALSE
);
360 GtkWxListStore
*list_store
= (GtkWxListStore
*) tree_model
;
362 // this is a list, nodes have no children
366 iter
->stamp
= list_store
->stamp
;
367 iter
->user_data
= (gpointer
) -1;
373 wxgtk_list_store_iter_has_child (GtkTreeModel
*tree_model
,
380 wxgtk_list_store_iter_n_children (GtkTreeModel
*tree_model
,
383 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), -1);
384 GtkWxListStore
*list_store
= (GtkWxListStore
*) tree_model
;
387 return (gint
) list_store
->model
->GetNumberOfRows();
389 g_return_val_if_fail (list_store
->stamp
== iter
->stamp
, -1);
395 wxgtk_list_store_iter_nth_child (GtkTreeModel
*tree_model
,
400 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), FALSE
);
401 GtkWxListStore
*list_store
= (GtkWxListStore
*) tree_model
;
409 if (n
>= (gint
) list_store
->model
->GetNumberOfRows())
412 iter
->stamp
= list_store
->stamp
;
413 iter
->user_data
= (gpointer
) n
;
419 wxgtk_list_store_iter_parent (GtkTreeModel
*tree_model
,
426 //-----------------------------------------------------------------------------
427 // define new GTK+ class wxGtkCellRenderer
428 //-----------------------------------------------------------------------------
432 #define GTK_TYPE_WX_CELL_RENDERER (gtk_wx_cell_renderer_get_type ())
433 #define GTK_WX_CELL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRenderer))
434 #define GTK_WX_CELL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass))
435 #define GTK_IS_WX_CELL_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_WX_CELL_RENDERER))
436 #define GTK_IS_WX_CELL_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_WX_CELL_RENDERER))
437 #define GTK_WX_CELL_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_WX_CELL_RENDERER, GtkWxCellRendererClass))
439 GType
gtk_wx_cell_renderer_get_type (void);
441 typedef struct _GtkWxCellRenderer GtkWxCellRenderer
;
442 typedef struct _GtkWxCellRendererClass GtkWxCellRendererClass
;
444 struct _GtkWxCellRenderer
446 GtkCellRenderer parent
;
449 wxDataViewCustomCell
*cell
;
452 struct _GtkWxCellRendererClass
454 GtkCellRendererClass cell_parent_class
;
459 static GtkCellRenderer
*gtk_wx_cell_renderer_new (void);
460 static void gtk_wx_cell_renderer_init (GtkWxCellRenderer
*cell
);
461 static void gtk_wx_cell_renderer_class_init (GtkWxCellRendererClass
*klass
);
462 static void gtk_wx_cell_renderer_finalize (GObject
*object
);
463 static void gtk_wx_cell_renderer_get_size (GtkCellRenderer
*cell
,
465 GdkRectangle
*rectangle
,
470 static void gtk_wx_cell_renderer_render (GtkCellRenderer
*cell
,
473 GdkRectangle
*background_area
,
474 GdkRectangle
*cell_area
,
475 GdkRectangle
*expose_area
,
476 GtkCellRendererState flags
);
478 static GObjectClass
*cell_parent_class
= NULL
;
483 gtk_wx_cell_renderer_get_type (void)
485 static GType cell_wx_type
= 0;
489 static const GTypeInfo cell_wx_info
=
491 sizeof (GtkWxCellRendererClass
),
492 NULL
, /* base_init */
493 NULL
, /* base_finalize */
494 (GClassInitFunc
) gtk_wx_cell_renderer_class_init
,
495 NULL
, /* class_finalize */
496 NULL
, /* class_data */
497 sizeof (GtkWxCellRenderer
),
499 (GInstanceInitFunc
) gtk_wx_cell_renderer_init
,
503 g_type_register_static (GTK_TYPE_CELL_RENDERER
, "GtkWxCellRenderer",
504 &cell_wx_info
, (GTypeFlags
)0);
511 gtk_wx_cell_renderer_init (GtkWxCellRenderer
*cell
)
517 gtk_wx_cell_renderer_class_init (GtkWxCellRendererClass
*klass
)
519 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
520 GtkCellRendererClass
*cell_class
= GTK_CELL_RENDERER_CLASS (klass
);
522 cell_parent_class
= (GObjectClass
*) g_type_class_peek_parent (klass
);
524 object_class
->finalize
= gtk_wx_cell_renderer_finalize
;
526 cell_class
->get_size
= gtk_wx_cell_renderer_get_size
;
527 cell_class
->render
= gtk_wx_cell_renderer_render
;
531 gtk_wx_cell_renderer_finalize (GObject
*object
)
534 (* G_OBJECT_CLASS (cell_parent_class
)->finalize
) (object
);
538 gtk_wx_cell_renderer_new (void)
540 return (GtkCellRenderer
*) g_object_new (GTK_TYPE_WX_CELL_RENDERER
, NULL
);
544 gtk_wx_cell_renderer_get_size (GtkCellRenderer
*renderer
,
546 GdkRectangle
*cell_area
,
552 GtkWxCellRenderer
*wxrenderer
= (GtkWxCellRenderer
*) renderer
;
553 wxDataViewCustomCell
*cell
= wxrenderer
->cell
;
555 wxSize size
= cell
->GetSize();
557 gint calc_width
= (gint
) renderer
->xpad
* 2 + size
.x
;
558 gint calc_height
= (gint
) renderer
->ypad
* 2 + size
.y
;
565 if (cell_area
&& size
.x
> 0 && size
.y
> 0)
569 *x_offset
= (gint
)((renderer
->xalign
*
570 (cell_area
->width
- calc_width
- 2 * renderer
->xpad
)));
571 *x_offset
= MAX (*x_offset
, 0) + renderer
->xpad
;
575 *y_offset
= (gint
)((renderer
->yalign
*
576 (cell_area
->height
- calc_height
- 2 * renderer
->ypad
)));
577 *y_offset
= MAX (*y_offset
, 0) + renderer
->ypad
;
585 *height
= calc_height
;
589 gtk_wx_cell_renderer_render (GtkCellRenderer
*renderer
,
592 GdkRectangle
*background_area
,
593 GdkRectangle
*cell_area
,
594 GdkRectangle
*expose_area
,
595 GtkCellRendererState flags
)
598 GtkWxCellRenderer
*wxrenderer
= (GtkWxCellRenderer
*) renderer
;
599 wxDataViewCustomCell
*cell
= wxrenderer
->cell
;
602 gtk_wx_cell_renderer_get_size (renderer
, widget
, cell_area
,
608 rect
.x
+= cell_area
->x
;
609 rect
.y
+= cell_area
->y
;
610 rect
.width
-= renderer
->xpad
* 2;
611 rect
.height
-= renderer
->ypad
* 2;
614 if (gdk_rectangle_intersect (expose_area
, &rect
, &dummy
))
616 wxRect
renderrect( rect
.x
, rect
.y
, rect
.width
, rect
.height
);
617 wxWindowDC
* dc
= (wxWindowDC
*) cell
->GetDC();
618 dc
->m_window
= window
;
621 if (flags
& GTK_CELL_RENDERER_SELECTED
)
622 state
|= wxDATAVIEW_CELL_SELECTED
;
623 if (flags
& GTK_CELL_RENDERER_PRELIT
)
624 state
|= wxDATAVIEW_CELL_PRELIT
;
625 if (flags
& GTK_CELL_RENDERER_INSENSITIVE
)
626 state
|= wxDATAVIEW_CELL_INSENSITIVE
;
627 if (flags
& GTK_CELL_RENDERER_INSENSITIVE
)
628 state
|= wxDATAVIEW_CELL_INSENSITIVE
;
629 if (flags
& GTK_CELL_RENDERER_FOCUSED
)
630 state
|= wxDATAVIEW_CELL_FOCUSED
;
631 cell
->Render( renderrect
, dc
, state
);
635 // ---------------------------------------------------------
636 // wxGtkDataViewListModelNotifier
637 // ---------------------------------------------------------
639 class wxGtkDataViewListModelNotifier
: public wxDataViewListModelNotifier
642 wxGtkDataViewListModelNotifier( GtkWxListStore
* gtk_store
, wxDataViewListModel
*wx_model
);
644 virtual bool RowAppended();
645 virtual bool RowPrepended();
646 virtual bool RowInserted( size_t before
);
647 virtual bool RowDeleted( size_t row
);
648 virtual bool RowChanged( size_t row
);
649 virtual bool ValueChanged( size_t col
, size_t row
);
650 virtual bool Cleared();
652 GtkWxListStore
*m_gtk_store
;
653 wxDataViewListModel
*m_wx_model
;
656 // ---------------------------------------------------------
657 // wxGtkDataViewListModelNotifier
658 // ---------------------------------------------------------
660 wxGtkDataViewListModelNotifier::wxGtkDataViewListModelNotifier(
661 GtkWxListStore
* gtk_store
, wxDataViewListModel
*wx_model
)
663 m_gtk_store
= gtk_store
;
664 m_wx_model
= wx_model
;
667 bool wxGtkDataViewListModelNotifier::RowAppended()
669 size_t pos
= m_wx_model
->GetNumberOfRows()-1;
672 iter
.stamp
= m_gtk_store
->stamp
;
673 iter
.user_data
= (gpointer
) pos
;
675 GtkTreePath
*path
= gtk_tree_path_new ();
676 gtk_tree_path_append_index (path
, (gint
) pos
);
677 gtk_tree_model_row_inserted (GTK_TREE_MODEL (m_gtk_store
), path
, &iter
);
678 gtk_tree_path_free (path
);
683 bool wxGtkDataViewListModelNotifier::RowPrepended()
686 iter
.stamp
= m_gtk_store
->stamp
;
687 iter
.user_data
= (gpointer
) 0;
689 GtkTreePath
*path
= gtk_tree_path_new ();
690 gtk_tree_path_append_index (path
, (gint
) 0);
691 gtk_tree_model_row_inserted (GTK_TREE_MODEL (m_gtk_store
), path
, &iter
);
692 gtk_tree_path_free (path
);
697 bool wxGtkDataViewListModelNotifier::RowInserted( size_t before
)
702 bool wxGtkDataViewListModelNotifier::RowDeleted( size_t row
)
707 bool wxGtkDataViewListModelNotifier::RowChanged( size_t row
)
710 iter
.stamp
= m_gtk_store
->stamp
;
711 iter
.user_data
= (gpointer
) row
;
712 GtkTreePath
*path
= gtk_tree_model_get_path (GTK_TREE_MODEL (m_gtk_store
), &iter
);
713 gtk_tree_model_row_changed (GTK_TREE_MODEL (m_gtk_store
), path
, &iter
);
714 gtk_tree_path_free (path
);
719 bool wxGtkDataViewListModelNotifier::ValueChanged( size_t col
, size_t row
)
721 return RowChanged( row
);
724 bool wxGtkDataViewListModelNotifier::Cleared()
729 // ---------------------------------------------------------
731 // ---------------------------------------------------------
733 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCell
, wxDataViewCellBase
)
735 wxDataViewCell::wxDataViewCell( const wxString
&varianttype
, wxDataViewCellMode mode
) :
736 wxDataViewCellBase( varianttype
, mode
)
741 // ---------------------------------------------------------
742 // wxDataViewTextCell
743 // ---------------------------------------------------------
746 static void wxGtkTextRendererEditedCallback( GtkCellRendererText
*renderer
,
747 gchar
*arg1
, gchar
*arg2
, gpointer user_data
);
750 static void wxGtkTextRendererEditedCallback( GtkCellRendererText
*renderer
,
751 gchar
*arg1
, gchar
*arg2
, gpointer user_data
)
753 wxDataViewTextCell
*cell
= (wxDataViewTextCell
*) user_data
;
755 wxString tmp
= wxGTK_CONV_BACK( arg2
);
756 wxVariant value
= tmp
;
757 if (!cell
->Validate( value
))
760 wxDataViewListModel
*model
= cell
->GetOwner()->GetOwner()->GetModel();
762 GtkTreePath
*path
= gtk_tree_path_new_from_string( arg1
);
763 size_t model_row
= (size_t)gtk_tree_path_get_indices (path
)[0];
764 gtk_tree_path_free( path
);
766 size_t model_col
= cell
->GetOwner()->GetModelColumn();
768 model
->SetValue( value
, model_col
, model_row
);
769 model
->ValueChanged( model_col
, model_row
);
772 IMPLEMENT_ABSTRACT_CLASS(wxDataViewTextCell
, wxDataViewCell
)
774 wxDataViewTextCell::wxDataViewTextCell( const wxString
&varianttype
, wxDataViewCellMode mode
) :
775 wxDataViewCell( varianttype
, mode
)
777 m_renderer
= (void*) gtk_cell_renderer_text_new();
779 if (m_mode
& wxDATAVIEW_CELL_EDITABLE
)
781 GValue gvalue
= { 0, };
782 g_value_init( &gvalue
, G_TYPE_BOOLEAN
);
783 g_value_set_boolean( &gvalue
, true );
784 g_object_set_property( G_OBJECT(m_renderer
), "editable", &gvalue
);
785 g_value_unset( &gvalue
);
787 g_signal_connect_after( m_renderer
, "edited", G_CALLBACK(wxGtkTextRendererEditedCallback
), this );
791 bool wxDataViewTextCell::SetValue( const wxVariant
&value
)
793 wxString tmp
= value
;
795 GValue gvalue
= { 0, };
796 g_value_init( &gvalue
, G_TYPE_STRING
);
797 g_value_set_string( &gvalue
, wxGTK_CONV( tmp
) );
798 g_object_set_property( G_OBJECT(m_renderer
), "text", &gvalue
);
799 g_value_unset( &gvalue
);
804 bool wxDataViewTextCell::GetValue( wxVariant
&value
)
806 GValue gvalue
= { 0, };
807 g_value_init( &gvalue
, G_TYPE_STRING
);
808 g_object_get_property( G_OBJECT(m_renderer
), "text", &gvalue
);
809 wxString tmp
= wxGTK_CONV_BACK( g_value_get_string( &gvalue
) );
810 g_value_unset( &gvalue
);
817 // ---------------------------------------------------------
818 // wxDataViewToggleCell
819 // ---------------------------------------------------------
822 static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle
*renderer
,
823 gchar
*path
, gpointer user_data
);
826 static void wxGtkToggleRendererToggledCallback( GtkCellRendererToggle
*renderer
,
827 gchar
*path
, gpointer user_data
)
829 wxDataViewToggleCell
*cell
= (wxDataViewToggleCell
*) user_data
;
832 GValue gvalue
= { 0, };
833 g_value_init( &gvalue
, G_TYPE_BOOLEAN
);
834 g_object_get_property( G_OBJECT(renderer
), "active", &gvalue
);
835 bool tmp
= g_value_get_boolean( &gvalue
);
836 g_value_unset( &gvalue
);
840 wxVariant value
= tmp
;
841 if (!cell
->Validate( value
))
844 wxDataViewListModel
*model
= cell
->GetOwner()->GetOwner()->GetModel();
846 GtkTreePath
*gtk_path
= gtk_tree_path_new_from_string( path
);
847 size_t model_row
= (size_t)gtk_tree_path_get_indices (gtk_path
)[0];
848 gtk_tree_path_free( gtk_path
);
850 size_t model_col
= cell
->GetOwner()->GetModelColumn();
852 model
->SetValue( value
, model_col
, model_row
);
853 model
->ValueChanged( model_col
, model_row
);
856 IMPLEMENT_ABSTRACT_CLASS(wxDataViewToggleCell
, wxDataViewCell
)
858 wxDataViewToggleCell::wxDataViewToggleCell( const wxString
&varianttype
,
859 wxDataViewCellMode mode
) :
860 wxDataViewCell( varianttype
, mode
)
862 m_renderer
= (void*) gtk_cell_renderer_toggle_new();
864 if (m_mode
& wxDATAVIEW_CELL_EDITABLE
)
866 GValue gvalue
= { 0, };
867 g_value_init( &gvalue
, G_TYPE_BOOLEAN
);
868 g_value_set_boolean( &gvalue
, true );
869 g_object_set_property( G_OBJECT(m_renderer
), "activatable", &gvalue
);
870 g_value_unset( &gvalue
);
872 g_signal_connect_after( m_renderer
, "toggled", G_CALLBACK(wxGtkToggleRendererToggledCallback
), this );
876 bool wxDataViewToggleCell::SetValue( const wxVariant
&value
)
880 GValue gvalue
= { 0, };
881 g_value_init( &gvalue
, G_TYPE_BOOLEAN
);
882 g_value_set_boolean( &gvalue
, tmp
);
883 g_object_set_property( G_OBJECT(m_renderer
), "active", &gvalue
);
884 g_value_unset( &gvalue
);
889 bool wxDataViewToggleCell::GetValue( wxVariant
&value
)
891 GValue gvalue
= { 0, };
892 g_value_init( &gvalue
, G_TYPE_BOOLEAN
);
893 g_object_get_property( G_OBJECT(m_renderer
), "active", &gvalue
);
894 bool tmp
= g_value_get_boolean( &gvalue
);
895 g_value_unset( &gvalue
);
902 // ---------------------------------------------------------
903 // wxDataViewCustomCell
904 // ---------------------------------------------------------
906 class wxDataViewCtrlDC
: public wxWindowDC
909 wxDataViewCtrlDC( wxDataViewCtrl
*window
)
911 GtkWidget
*widget
= window
->GetHandle();
915 m_context
= window
->GtkGetPangoDefaultContext();
916 m_layout
= pango_layout_new( m_context
);
917 m_fontdesc
= pango_font_description_copy( widget
->style
->font_desc
);
919 m_cmap
= gtk_widget_get_colormap( widget
? widget
: window
->m_widget
);
927 // ---------------------------------------------------------
928 // wxDataViewCustomCell
929 // ---------------------------------------------------------
931 IMPLEMENT_ABSTRACT_CLASS(wxDataViewCustomCell
, wxDataViewCell
)
933 wxDataViewCustomCell::wxDataViewCustomCell( const wxString
&varianttype
,
934 wxDataViewCellMode mode
) :
935 wxDataViewCell( varianttype
, mode
)
939 GtkWxCellRenderer
*renderer
= (GtkWxCellRenderer
*) gtk_wx_cell_renderer_new();
940 renderer
->cell
= this;
942 m_renderer
= (void*) renderer
;
945 wxDataViewCustomCell::~wxDataViewCustomCell()
951 wxDC
*wxDataViewCustomCell::GetDC()
954 m_dc
= new wxDataViewCtrlDC( GetOwner()->GetOwner() );
959 // ---------------------------------------------------------
961 // ---------------------------------------------------------
964 static void wxGtkTreeCellDataFunc( GtkTreeViewColumn
*column
,
965 GtkCellRenderer
*cell
,
972 static void wxGtkTreeCellDataFunc( GtkTreeViewColumn
*column
,
973 GtkCellRenderer
*renderer
,
978 g_return_if_fail (GTK_IS_WX_LIST_STORE (model
));
979 GtkWxListStore
*list_store
= (GtkWxListStore
*) model
;
981 wxDataViewCell
*cell
= (wxDataViewCell
*) data
;
983 size_t model_row
= (size_t) iter
->user_data
;
985 wxVariant value
= list_store
->model
->GetValue(
986 cell
->GetOwner()->GetModelColumn(), model_row
);
988 if (value
.GetType() != cell
->GetVariantType())
989 wxPrintf( wxT("Wrong type\n") );
991 cell
->SetValue( value
);
994 IMPLEMENT_ABSTRACT_CLASS(wxDataViewColumn
, wxDataViewColumnBase
)
996 wxDataViewColumn::wxDataViewColumn( const wxString
&title
, wxDataViewCell
*cell
,
997 size_t model_column
, int flags
) :
998 wxDataViewColumnBase( title
, cell
, model_column
, flags
)
1000 GtkCellRenderer
*renderer
= (GtkCellRenderer
*) cell
->GetGtkHandle();
1002 GtkTreeViewColumn
*column
= gtk_tree_view_column_new();
1004 gtk_tree_view_column_set_title( column
, wxGTK_CONV(title
) );
1006 gtk_tree_view_column_pack_start( column
, renderer
, TRUE
);
1008 gtk_tree_view_column_set_cell_data_func( column
, renderer
,
1009 wxGtkTreeCellDataFunc
, (gpointer
) cell
, NULL
);
1011 m_column
= (void*) column
;
1014 wxDataViewColumn::~wxDataViewColumn()
1018 void wxDataViewColumn::SetTitle( const wxString
&title
)
1020 wxDataViewColumnBase::SetTitle( title
);
1022 GtkTreeViewColumn
*column
= (GtkTreeViewColumn
*)m_column
;
1023 gtk_tree_view_column_set_title( column
, wxGTK_CONV(title
) );
1026 //-----------------------------------------------------------------------------
1028 //-----------------------------------------------------------------------------
1030 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl
, wxDataViewCtrlBase
)
1032 wxDataViewCtrl::~wxDataViewCtrl()
1036 void wxDataViewCtrl::Init()
1040 bool wxDataViewCtrl::Create(wxWindow
*parent
, wxWindowID id
,
1041 const wxPoint
& pos
, const wxSize
& size
,
1042 long style
, const wxValidator
& validator
)
1046 m_needParent
= TRUE
;
1047 m_acceptsFocus
= TRUE
;
1049 if (!PreCreation( parent
, pos
, size
) ||
1050 !CreateBase( parent
, id
, pos
, size
, style
, validator
))
1052 wxFAIL_MSG( wxT("wxDataViewCtrl creation failed") );
1056 m_widget
= gtk_tree_view_new();
1058 m_parent
->DoAddChild( this );
1065 bool wxDataViewCtrl::AssociateModel( wxDataViewListModel
*model
)
1067 if (!wxDataViewCtrlBase::AssociateModel( model
))
1070 GtkWxListStore
*gtk_store
= wxgtk_list_store_new();
1071 gtk_store
->model
= model
;
1073 wxGtkDataViewListModelNotifier
*notifier
=
1074 new wxGtkDataViewListModelNotifier( gtk_store
, model
);
1076 model
->SetNotifier( notifier
);
1078 gtk_tree_view_set_model( GTK_TREE_VIEW(m_widget
), GTK_TREE_MODEL(gtk_store
) );
1083 bool wxDataViewCtrl::AppendColumn( wxDataViewColumn
*col
)
1085 if (!wxDataViewCtrlBase::AppendColumn(col
))
1088 GtkTreeViewColumn
*column
= (GtkTreeViewColumn
*)col
->GetGtkHandle();
1090 gtk_tree_view_append_column( GTK_TREE_VIEW(m_widget
), column
);
1096 #endif // wxUSE_DATAVIEWCTRL