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"
20 #include "wx/gtk/private.h"
21 #include "wx/gtk/win_gtk.h"
23 #include <gobject/gvaluecollector.h>
24 #include "gtktreemodel.h"
25 #include "gtktreedatalist.h"
26 #include "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 parent_class
;
80 static void wxgtk_list_store_init (GtkWxListStore
*list_store
);
81 static void wxgtk_list_store_class_init (GtkWxListStoreClass
*class);
82 static void wxgtk_list_store_tree_model_init (GtkTreeModelIface
*iface
);
83 static void wxgtk_list_store_finalize (GObject
*object
);
84 static GtkTreeModelFlags
wxgtk_list_store_get_flags (GtkTreeModel
*tree_model
);
85 static gint
wxgtk_list_store_get_n_columns (GtkTreeModel
*tree_model
);
86 static GType
wxgtk_list_store_get_column_type (GtkTreeModel
*tree_model
,
88 static gboolean
wxgtk_list_store_get_iter (GtkTreeModel
*tree_model
,
91 static GtkTreePath
*wxgtk_list_store_get_path (GtkTreeModel
*tree_model
,
93 static void wxgtk_list_store_get_value (GtkTreeModel
*tree_model
,
97 static gboolean
wxgtk_list_store_iter_next (GtkTreeModel
*tree_model
,
99 static gboolean
wxgtk_list_store_iter_children (GtkTreeModel
*tree_model
,
101 GtkTreeIter
*parent
);
102 static gboolean
wxgtk_list_store_iter_has_child (GtkTreeModel
*tree_model
,
104 static gint
wxgtk_list_store_iter_n_children (GtkTreeModel
*tree_model
,
106 static gboolean
wxgtk_list_store_iter_nth_child (GtkTreeModel
*tree_model
,
110 static gboolean
wxgtk_list_store_iter_parent (GtkTreeModel
*tree_model
,
114 static void gtk_list_store_set_n_columns (GtkWxListStore
*list_store
,
116 static void gtk_list_store_set_column_type (GtkWxListStore
*list_store
,
120 static GObjectClass
*parent_class
= NULL
;
123 wxgtk_list_store_get_type (void)
125 static GType list_store_type
= 0;
127 if (!list_store_type
)
129 static const GTypeInfo list_store_info
=
131 sizeof (GtkWxListStoreClass
),
132 NULL
, /* base_init */
133 NULL
, /* base_finalize */
134 (GClassInitFunc
) wxgtk_list_store_class_init
,
135 NULL
, /* class_finalize */
136 NULL
, /* class_data */
137 sizeof (GtkWxListStore
),
139 (GInstanceInitFunc
) wxgtk_list_store_init
,
142 static const GInterfaceInfo tree_model_info
=
144 (GInterfaceInitFunc
) wxgtk_list_store_tree_model_init
,
149 list_store_type
= g_type_register_static (G_TYPE_OBJECT
, "GtkWxListStore",
150 &list_store_info
, 0);
152 g_type_add_interface_static (list_store_type
,
157 return list_store_type
;
161 wxgtk_list_store_class_init (GtkWxListStoreClass
*class)
163 GObjectClass
*object_class
;
164 parent_class
= g_type_class_peek_parent (class);
165 object_class
= (GObjectClass
*) class;
166 object_class
->finalize
= wxgtk_list_store_finalize
;
170 wxgtk_list_store_tree_model_init (GtkTreeModelIface
*iface
)
172 iface
->get_flags
= wxgtk_list_store_get_flags
;
173 iface
->get_n_columns
= wxgtk_list_store_get_n_columns
;
174 iface
->get_column_type
= wxgtk_list_store_get_column_type
;
175 iface
->get_iter
= wxgtk_list_store_get_iter
;
176 iface
->get_path
= wxgtk_list_store_get_path
;
177 iface
->get_value
= wxgtk_list_store_get_value
;
178 iface
->iter_next
= wxgtk_list_store_iter_next
;
179 iface
->iter_children
= wxgtk_list_store_iter_children
;
180 iface
->iter_has_child
= wxgtk_list_store_iter_has_child
;
181 iface
->iter_n_children
= wxgtk_list_store_iter_n_children
;
182 iface
->iter_nth_child
= wxgtk_list_store_iter_nth_child
;
183 iface
->iter_parent
= wxgtk_list_store_iter_parent
;
187 wxgtk_list_store_init (GtkWxListStore
*list_store
)
189 list_store
->model
= NULL
;
190 list_store
->stamp
= g_random_init();
194 wxgtk_list_store_finalize (GObject
*object
)
196 GtkWxListStore
*list_store
= GTK_LIST_STORE (object
);
198 /* we need to sort out, which class deletes what */
202 (* parent_class
->finalize
) (object
);
207 //-----------------------------------------------------------------------------
208 // implement callbacks from wxGtkListStore class by letting
209 // them call the methods of wxWidgets' wxDataViewListModel
210 //-----------------------------------------------------------------------------
212 static GtkTreeModelFlags
213 wxgtk_list_store_get_flags (GtkTreeModel
*tree_model
)
215 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), 0);
217 return GTK_TREE_MODEL_ITERS_PERSIST
| GTK_TREE_MODEL_LIST_ONLY
;
221 wxgtk_list_store_get_n_columns (GtkTreeModel
*tree_model
)
223 GtkWxListStore
*list_store
= (GtkWxListStore
*) tree_model
;
224 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), 0);
226 return list_store
->model
->GetColumns();
230 wxgtk_list_store_get_column_type (GtkTreeModel
*tree_model
,
233 GtkWxListStore
*list_store
= (GtkWxListStore
*) tree_model
;
234 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), G_TYPE_INVALID
);
236 GType gtype
= G_TYPE_INVALID
;
238 list_store
->model
->GetColumnType( index
);
239 // convert wxtype to GType
247 wxgtk_list_store_get_iter (GtkTreeModel
*tree_model
,
251 GtkWxListStore
*list_store
= (GtkWxListStore
*) tree_model
;
252 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), FALSE
);
253 g_return_val_if_fail (gtk_tree_path_get_depth (path
) > 0, FALSE
);
256 i
= gtk_tree_path_get_indices (path
)[0];
258 if (i
>= list_store
->length
)
261 list
= g_slist_nth (G_SLIST (list_store
->root
), i
);
263 /* If this fails, list_store->length has gotten mangled. */
266 iter
->stamp
= list_store
->stamp
;
267 iter
->user_data
= list
;
274 wxgtk_list_store_get_path (GtkTreeModel
*tree_model
,
277 GtkWxListStore
*list_store
= (GtkListStore
*) tree_model
;
278 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), NULL
);
281 g_return_val_if_fail (iter
->stamp
== GTK_WX_LIST_STORE (tree_model
)->stamp
, NULL
);
287 if (G_SLIST (iter
->user_data
) == G_SLIST (GTK_LIST_STORE (tree_model
)->tail
))
289 retval
= gtk_tree_path_new ();
290 gtk_tree_path_append_index (retval
, GTK_LIST_STORE (tree_model
)->length
- 1);
294 for (list
= G_SLIST (GTK_LIST_STORE (tree_model
)->root
); list
; list
= list
->next
)
296 if (list
== G_SLIST (iter
->user_data
))
303 retval
= gtk_tree_path_new ();
304 gtk_tree_path_append_index (retval
, i
);
312 wxgtk_list_store_get_value (GtkTreeModel
*tree_model
,
317 GtkWxListStore
*list_store
= (GtkListStore
*) tree_model
;
318 g_return_if_fail (GTK_IS_WX_LIST_STORE (tree_model
) );
321 GtkTreeDataList
*list
;
322 gint tmp_column
= column
;
324 g_return_if_fail (column
< GTK_LIST_STORE (tree_model
)->n_columns
);
325 g_return_if_fail (GTK_LIST_STORE (tree_model
)->stamp
== iter
->stamp
);
327 list
= G_SLIST (iter
->user_data
)->data
;
329 while (tmp_column
-- > 0 && list
)
333 g_value_init (value
, GTK_LIST_STORE (tree_model
)->column_headers
[column
]);
335 _gtk_tree_data_list_node_to_value (list
,
336 GTK_LIST_STORE (tree_model
)->column_headers
[column
],
343 wxgtk_list_store_iter_next (GtkTreeModel
*tree_model
,
346 GtkWxListStore
*list_store
= (GtkListStore
*) tree_model
;
347 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), FALSE
);
350 g_return_val_if_fail (GTK_LIST_STORE (tree_model
)->stamp
== iter
->stamp
, FALSE
);
352 iter
->user_data
= G_SLIST (iter
->user_data
)->next
;
354 return (iter
->user_data
!= NULL
);
361 wxgtk_list_store_iter_children (GtkTreeModel
*tree_model
,
365 /* this is a list, nodes have no children */
369 /* but if parent == NULL we return the list itself */
370 if (GTK_WX_LIST_STORE (tree_model
)->root
)
372 iter
->stamp
= GTK_WX_LIST_STORE (tree_model
)->stamp
;
373 iter
->user_data
= GTK_WX_LIST_STORE (tree_model
)->root
;
383 wxgtk_list_store_iter_has_child (GtkTreeModel
*tree_model
,
390 wxgtk_list_store_iter_n_children (GtkTreeModel
*tree_model
,
393 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model
), -1);
396 return GTK_WX_LIST_STORE (tree_model
)->model
->GetLength();
398 g_return_val_if_fail (GTK_WX_LIST_STORE (tree_model
)->stamp
== iter
->stamp
, -1);
404 wxgtk_list_store_iter_nth_child (GtkTreeModel
*tree_model
,
412 g_return_val_if_fail (GTK_IS_LIST_STORE (tree_model
), FALSE
);
417 child
= g_slist_nth (G_SLIST (GTK_LIST_STORE (tree_model
)->root
), n
);
421 iter
->stamp
= GTK_LIST_STORE (tree_model
)->stamp
;
422 iter
->user_data
= child
;
431 wxgtk_list_store_iter_parent (GtkTreeModel
*tree_model
,
439 //-----------------------------------------------------------------------------
441 //-----------------------------------------------------------------------------
443 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl
,wxControl
)
446 #endif // wxUSE_DATAVIEWCTRL