]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/dataview.cpp
Starting wxDataView..
[wxWidgets.git] / src / gtk / dataview.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: dataview.cpp
3 // Purpose: wxDataViewCtrl GTK+2 implementation
4 // Author: Robert Roebling
5 // Id: $Id$
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
12
13 #include "wx/defs.h"
14
15 #if wxUSE_DATAVIEWCTRL
16
17 #include "wx/dataview.h"
18 #include "wx/stockitem.h"
19
20 #include "wx/gtk/private.h"
21 #include "wx/gtk/win_gtk.h"
22
23 #include <gobject/gvaluecollector.h>
24 #include "gtktreemodel.h"
25 #include "gtktreedatalist.h"
26 #include "gtktreednd.h"
27
28 //-----------------------------------------------------------------------------
29 // classes
30 //-----------------------------------------------------------------------------
31
32 class wxDataViewCtrl;
33
34 //-----------------------------------------------------------------------------
35 // idle system
36 //-----------------------------------------------------------------------------
37
38 extern void wxapp_install_idle_handler();
39 extern bool g_isIdle;
40
41 //-----------------------------------------------------------------------------
42 // data
43 //-----------------------------------------------------------------------------
44
45 extern bool g_blockEventsOnDrag;
46
47 //-----------------------------------------------------------------------------
48 // define new GTK+ class wxGtkListStore
49 //-----------------------------------------------------------------------------
50
51 extern "C" {
52
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))
59
60 GType gtk_wx_list_store_get_type (void);
61
62 typedef struct _GtkWxListStore GtkWxListStore;
63 typedef struct _GtkWxListStoreClass GtkWxListStoreClass;
64
65 struct _GtkWxListStore
66 {
67 GObject parent;
68
69 /*< private >*/
70 gint stamp;
71 wxDataViewListModel *model;
72 };
73
74 struct _GtkWxListStoreClass
75 {
76 GObjectClass parent_class;
77
78 };
79
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,
87 gint index);
88 static gboolean wxgtk_list_store_get_iter (GtkTreeModel *tree_model,
89 GtkTreeIter *iter,
90 GtkTreePath *path);
91 static GtkTreePath *wxgtk_list_store_get_path (GtkTreeModel *tree_model,
92 GtkTreeIter *iter);
93 static void wxgtk_list_store_get_value (GtkTreeModel *tree_model,
94 GtkTreeIter *iter,
95 gint column,
96 GValue *value);
97 static gboolean wxgtk_list_store_iter_next (GtkTreeModel *tree_model,
98 GtkTreeIter *iter);
99 static gboolean wxgtk_list_store_iter_children (GtkTreeModel *tree_model,
100 GtkTreeIter *iter,
101 GtkTreeIter *parent);
102 static gboolean wxgtk_list_store_iter_has_child (GtkTreeModel *tree_model,
103 GtkTreeIter *iter);
104 static gint wxgtk_list_store_iter_n_children (GtkTreeModel *tree_model,
105 GtkTreeIter *iter);
106 static gboolean wxgtk_list_store_iter_nth_child (GtkTreeModel *tree_model,
107 GtkTreeIter *iter,
108 GtkTreeIter *parent,
109 gint n);
110 static gboolean wxgtk_list_store_iter_parent (GtkTreeModel *tree_model,
111 GtkTreeIter *iter,
112 GtkTreeIter *child);
113
114 static void gtk_list_store_set_n_columns (GtkWxListStore *list_store,
115 gint n_columns);
116 static void gtk_list_store_set_column_type (GtkWxListStore *list_store,
117 gint column,
118 GType type);
119
120 static GObjectClass *parent_class = NULL;
121
122 GType
123 wxgtk_list_store_get_type (void)
124 {
125 static GType list_store_type = 0;
126
127 if (!list_store_type)
128 {
129 static const GTypeInfo list_store_info =
130 {
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),
138 0,
139 (GInstanceInitFunc) wxgtk_list_store_init,
140 };
141
142 static const GInterfaceInfo tree_model_info =
143 {
144 (GInterfaceInitFunc) wxgtk_list_store_tree_model_init,
145 NULL,
146 NULL
147 };
148
149 list_store_type = g_type_register_static (G_TYPE_OBJECT, "GtkWxListStore",
150 &list_store_info, 0);
151
152 g_type_add_interface_static (list_store_type,
153 GTK_TYPE_TREE_MODEL,
154 &tree_model_info);
155 }
156
157 return list_store_type;
158 }
159
160 static void
161 wxgtk_list_store_class_init (GtkWxListStoreClass *class)
162 {
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;
167 }
168
169 static void
170 wxgtk_list_store_tree_model_init (GtkTreeModelIface *iface)
171 {
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;
184 }
185
186 static void
187 wxgtk_list_store_init (GtkWxListStore *list_store)
188 {
189 list_store->model = NULL;
190 list_store->stamp = g_random_init();
191 }
192
193 static void
194 wxgtk_list_store_finalize (GObject *object)
195 {
196 GtkWxListStore *list_store = GTK_LIST_STORE (object);
197
198 /* we need to sort out, which class deletes what */
199 delete model;
200
201 /* must chain up */
202 (* parent_class->finalize) (object);
203 }
204
205 } // extern "C"
206
207 //-----------------------------------------------------------------------------
208 // implement callbacks from wxGtkListStore class by letting
209 // them call the methods of wxWidgets' wxDataViewListModel
210 //-----------------------------------------------------------------------------
211
212 static GtkTreeModelFlags
213 wxgtk_list_store_get_flags (GtkTreeModel *tree_model)
214 {
215 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), 0);
216
217 return GTK_TREE_MODEL_ITERS_PERSIST | GTK_TREE_MODEL_LIST_ONLY;
218 }
219
220 static gint
221 wxgtk_list_store_get_n_columns (GtkTreeModel *tree_model)
222 {
223 GtkWxListStore *list_store = (GtkWxListStore *) tree_model;
224 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), 0);
225
226 return list_store->model->GetColumns();
227 }
228
229 static GType
230 wxgtk_list_store_get_column_type (GtkTreeModel *tree_model,
231 gint index)
232 {
233 GtkWxListStore *list_store = (GtkWxListStore *) tree_model;
234 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), G_TYPE_INVALID);
235
236 GType gtype = G_TYPE_INVALID;
237 #if 0
238 list_store->model->GetColumnType( index );
239 // convert wxtype to GType
240 gtype = ..
241 #endif
242
243 return gtype;
244 }
245
246 static gboolean
247 wxgtk_list_store_get_iter (GtkTreeModel *tree_model,
248 GtkTreeIter *iter,
249 GtkTreePath *path)
250 {
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);
254
255 #if 0
256 i = gtk_tree_path_get_indices (path)[0];
257
258 if (i >= list_store->length)
259 return FALSE;
260
261 list = g_slist_nth (G_SLIST (list_store->root), i);
262
263 /* If this fails, list_store->length has gotten mangled. */
264 g_assert (list);
265
266 iter->stamp = list_store->stamp;
267 iter->user_data = list;
268 #endif
269
270 return TRUE;
271 }
272
273 static GtkTreePath *
274 wxgtk_list_store_get_path (GtkTreeModel *tree_model,
275 GtkTreeIter *iter)
276 {
277 GtkWxListStore *list_store = (GtkListStore *) tree_model;
278 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), NULL);
279
280 #if 0
281 g_return_val_if_fail (iter->stamp == GTK_WX_LIST_STORE (tree_model)->stamp, NULL);
282
283 GtkTreePath *retval;
284 GSList *list;
285 gint i = 0;
286
287 if (G_SLIST (iter->user_data) == G_SLIST (GTK_LIST_STORE (tree_model)->tail))
288 {
289 retval = gtk_tree_path_new ();
290 gtk_tree_path_append_index (retval, GTK_LIST_STORE (tree_model)->length - 1);
291 return retval;
292 }
293
294 for (list = G_SLIST (GTK_LIST_STORE (tree_model)->root); list; list = list->next)
295 {
296 if (list == G_SLIST (iter->user_data))
297 break;
298 i++;
299 }
300 if (list == NULL)
301 return NULL;
302
303 retval = gtk_tree_path_new ();
304 gtk_tree_path_append_index (retval, i);
305 return retval;
306 #endif
307
308 return NULL;
309 }
310
311 static void
312 wxgtk_list_store_get_value (GtkTreeModel *tree_model,
313 GtkTreeIter *iter,
314 gint column,
315 GValue *value)
316 {
317 GtkWxListStore *list_store = (GtkListStore *) tree_model;
318 g_return_if_fail (GTK_IS_WX_LIST_STORE (tree_model) );
319
320 #if 0
321 GtkTreeDataList *list;
322 gint tmp_column = column;
323
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);
326
327 list = G_SLIST (iter->user_data)->data;
328
329 while (tmp_column-- > 0 && list)
330 list = list->next;
331
332 if (list == NULL)
333 g_value_init (value, GTK_LIST_STORE (tree_model)->column_headers[column]);
334 else
335 _gtk_tree_data_list_node_to_value (list,
336 GTK_LIST_STORE (tree_model)->column_headers[column],
337 value);
338 #endif
339
340 }
341
342 static gboolean
343 wxgtk_list_store_iter_next (GtkTreeModel *tree_model,
344 GtkTreeIter *iter)
345 {
346 GtkWxListStore *list_store = (GtkListStore *) tree_model;
347 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), FALSE);
348
349 #if 0
350 g_return_val_if_fail (GTK_LIST_STORE (tree_model)->stamp == iter->stamp, FALSE);
351
352 iter->user_data = G_SLIST (iter->user_data)->next;
353
354 return (iter->user_data != NULL);
355 #endif
356
357 return NULL;
358 }
359
360 static gboolean
361 wxgtk_list_store_iter_children (GtkTreeModel *tree_model,
362 GtkTreeIter *iter,
363 GtkTreeIter *parent)
364 {
365 /* this is a list, nodes have no children */
366 if (parent)
367 return FALSE;
368
369 /* but if parent == NULL we return the list itself */
370 if (GTK_WX_LIST_STORE (tree_model)->root)
371 {
372 iter->stamp = GTK_WX_LIST_STORE (tree_model)->stamp;
373 iter->user_data = GTK_WX_LIST_STORE (tree_model)->root;
374 return TRUE;
375 }
376 else
377 {
378 return FALSE;
379 }
380 }
381
382 static gboolean
383 wxgtk_list_store_iter_has_child (GtkTreeModel *tree_model,
384 GtkTreeIter *iter)
385 {
386 return FALSE;
387 }
388
389 static gint
390 wxgtk_list_store_iter_n_children (GtkTreeModel *tree_model,
391 GtkTreeIter *iter)
392 {
393 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), -1);
394
395 if (iter == NULL)
396 return GTK_WX_LIST_STORE (tree_model)->model->GetLength();
397
398 g_return_val_if_fail (GTK_WX_LIST_STORE (tree_model)->stamp == iter->stamp, -1);
399
400 return 0;
401 }
402
403 static gboolean
404 wxgtk_list_store_iter_nth_child (GtkTreeModel *tree_model,
405 GtkTreeIter *iter,
406 GtkTreeIter *parent,
407 gint n)
408 {
409 #if 0
410 GSList *child;
411
412 g_return_val_if_fail (GTK_IS_LIST_STORE (tree_model), FALSE);
413
414 if (parent)
415 return FALSE;
416
417 child = g_slist_nth (G_SLIST (GTK_LIST_STORE (tree_model)->root), n);
418
419 if (child)
420 {
421 iter->stamp = GTK_LIST_STORE (tree_model)->stamp;
422 iter->user_data = child;
423 return TRUE;
424 }
425 else
426 #endif
427 return FALSE;
428 }
429
430 static gboolean
431 wxgtk_list_store_iter_parent (GtkTreeModel *tree_model,
432 GtkTreeIter *iter,
433 GtkTreeIter *child)
434 {
435 return FALSE;
436 }
437
438
439 //-----------------------------------------------------------------------------
440 // wxDataViewCtrl
441 //-----------------------------------------------------------------------------
442
443 IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl,wxControl)
444
445
446 #endif // wxUSE_DATAVIEWCTRL
447