]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/dataview.cpp
gcc initializer order fix warning (patch 1432835)
[wxWidgets.git] / src / gtk / dataview.cpp
CommitLineData
790b137e
RR
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
32class wxDataViewCtrl;
33
34//-----------------------------------------------------------------------------
35// idle system
36//-----------------------------------------------------------------------------
37
38extern void wxapp_install_idle_handler();
39extern bool g_isIdle;
40
41//-----------------------------------------------------------------------------
42// data
43//-----------------------------------------------------------------------------
44
45extern bool g_blockEventsOnDrag;
46
47//-----------------------------------------------------------------------------
48// define new GTK+ class wxGtkListStore
49//-----------------------------------------------------------------------------
50
51extern "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
60GType gtk_wx_list_store_get_type (void);
61
62typedef struct _GtkWxListStore GtkWxListStore;
63typedef struct _GtkWxListStoreClass GtkWxListStoreClass;
64
65struct _GtkWxListStore
66{
67 GObject parent;
68
69 /*< private >*/
70 gint stamp;
71 wxDataViewListModel *model;
72};
73
74struct _GtkWxListStoreClass
75{
76 GObjectClass parent_class;
77
78};
79
80static void wxgtk_list_store_init (GtkWxListStore *list_store);
81static void wxgtk_list_store_class_init (GtkWxListStoreClass *class);
82static void wxgtk_list_store_tree_model_init (GtkTreeModelIface *iface);
83static void wxgtk_list_store_finalize (GObject *object);
84static GtkTreeModelFlags wxgtk_list_store_get_flags (GtkTreeModel *tree_model);
85static gint wxgtk_list_store_get_n_columns (GtkTreeModel *tree_model);
86static GType wxgtk_list_store_get_column_type (GtkTreeModel *tree_model,
87 gint index);
88static gboolean wxgtk_list_store_get_iter (GtkTreeModel *tree_model,
89 GtkTreeIter *iter,
90 GtkTreePath *path);
91static GtkTreePath *wxgtk_list_store_get_path (GtkTreeModel *tree_model,
92 GtkTreeIter *iter);
93static void wxgtk_list_store_get_value (GtkTreeModel *tree_model,
94 GtkTreeIter *iter,
95 gint column,
96 GValue *value);
97static gboolean wxgtk_list_store_iter_next (GtkTreeModel *tree_model,
98 GtkTreeIter *iter);
99static gboolean wxgtk_list_store_iter_children (GtkTreeModel *tree_model,
100 GtkTreeIter *iter,
101 GtkTreeIter *parent);
102static gboolean wxgtk_list_store_iter_has_child (GtkTreeModel *tree_model,
103 GtkTreeIter *iter);
104static gint wxgtk_list_store_iter_n_children (GtkTreeModel *tree_model,
105 GtkTreeIter *iter);
106static gboolean wxgtk_list_store_iter_nth_child (GtkTreeModel *tree_model,
107 GtkTreeIter *iter,
108 GtkTreeIter *parent,
109 gint n);
110static gboolean wxgtk_list_store_iter_parent (GtkTreeModel *tree_model,
111 GtkTreeIter *iter,
112 GtkTreeIter *child);
113
114static void gtk_list_store_set_n_columns (GtkWxListStore *list_store,
115 gint n_columns);
116static void gtk_list_store_set_column_type (GtkWxListStore *list_store,
117 gint column,
118 GType type);
119
120static GObjectClass *parent_class = NULL;
121
122GType
123wxgtk_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
160static void
161wxgtk_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
169static void
170wxgtk_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
186static void
187wxgtk_list_store_init (GtkWxListStore *list_store)
188{
189 list_store->model = NULL;
190 list_store->stamp = g_random_init();
191}
192
193static void
194wxgtk_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
212static GtkTreeModelFlags
213wxgtk_list_store_get_flags (GtkTreeModel *tree_model)
214{
215 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), 0);
216
67cbdfc1
RR
217 // GTK+ list store uses a linked list for storing the
218 // items and a pointer to a child is used as the member
219 // field of a GtkTreeIter. This means that the iter is
220 // valid in the GtkListStore as long as the child exists.
221 // We use the index of the row and since the index of a
222 // specific row will change if a row above is deleted,
223 // the iter does not persist
224 return /* GTK_TREE_MODEL_ITERS_PERSIST | */ GTK_TREE_MODEL_LIST_ONLY;
790b137e
RR
225}
226
227static gint
228wxgtk_list_store_get_n_columns (GtkTreeModel *tree_model)
229{
230 GtkWxListStore *list_store = (GtkWxListStore *) tree_model;
231 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), 0);
232
233 return list_store->model->GetColumns();
234}
235
236static GType
237wxgtk_list_store_get_column_type (GtkTreeModel *tree_model,
238 gint index)
239{
240 GtkWxListStore *list_store = (GtkWxListStore *) tree_model;
241 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), G_TYPE_INVALID);
242
243 GType gtype = G_TYPE_INVALID;
244#if 0
245 list_store->model->GetColumnType( index );
246 // convert wxtype to GType
247 gtype = ..
248#endif
249
250 return gtype;
251}
252
253static gboolean
254wxgtk_list_store_get_iter (GtkTreeModel *tree_model,
255 GtkTreeIter *iter,
256 GtkTreePath *path)
257{
258 GtkWxListStore *list_store = (GtkWxListStore *) tree_model;
259 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), FALSE);
260 g_return_val_if_fail (gtk_tree_path_get_depth (path) > 0, FALSE);
261
262#if 0
263 i = gtk_tree_path_get_indices (path)[0];
264
265 if (i >= list_store->length)
266 return FALSE;
267
268 list = g_slist_nth (G_SLIST (list_store->root), i);
269
270 /* If this fails, list_store->length has gotten mangled. */
271 g_assert (list);
272
273 iter->stamp = list_store->stamp;
274 iter->user_data = list;
275#endif
276
277 return TRUE;
278}
279
280static GtkTreePath *
281wxgtk_list_store_get_path (GtkTreeModel *tree_model,
282 GtkTreeIter *iter)
283{
284 GtkWxListStore *list_store = (GtkListStore *) tree_model;
285 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), NULL);
286
287#if 0
288 g_return_val_if_fail (iter->stamp == GTK_WX_LIST_STORE (tree_model)->stamp, NULL);
289
290 GtkTreePath *retval;
291 GSList *list;
292 gint i = 0;
293
294 if (G_SLIST (iter->user_data) == G_SLIST (GTK_LIST_STORE (tree_model)->tail))
295 {
296 retval = gtk_tree_path_new ();
297 gtk_tree_path_append_index (retval, GTK_LIST_STORE (tree_model)->length - 1);
298 return retval;
299 }
300
301 for (list = G_SLIST (GTK_LIST_STORE (tree_model)->root); list; list = list->next)
302 {
303 if (list == G_SLIST (iter->user_data))
304 break;
305 i++;
306 }
307 if (list == NULL)
308 return NULL;
309
310 retval = gtk_tree_path_new ();
311 gtk_tree_path_append_index (retval, i);
312 return retval;
313#endif
314
315 return NULL;
316}
317
318static void
319wxgtk_list_store_get_value (GtkTreeModel *tree_model,
320 GtkTreeIter *iter,
321 gint column,
322 GValue *value)
323{
324 GtkWxListStore *list_store = (GtkListStore *) tree_model;
325 g_return_if_fail (GTK_IS_WX_LIST_STORE (tree_model) );
326
327#if 0
328 GtkTreeDataList *list;
329 gint tmp_column = column;
330
331 g_return_if_fail (column < GTK_LIST_STORE (tree_model)->n_columns);
332 g_return_if_fail (GTK_LIST_STORE (tree_model)->stamp == iter->stamp);
333
334 list = G_SLIST (iter->user_data)->data;
335
336 while (tmp_column-- > 0 && list)
337 list = list->next;
338
339 if (list == NULL)
340 g_value_init (value, GTK_LIST_STORE (tree_model)->column_headers[column]);
341 else
342 _gtk_tree_data_list_node_to_value (list,
343 GTK_LIST_STORE (tree_model)->column_headers[column],
344 value);
345#endif
346
347}
348
349static gboolean
350wxgtk_list_store_iter_next (GtkTreeModel *tree_model,
351 GtkTreeIter *iter)
352{
790b137e 353 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), FALSE);
67cbdfc1 354 GtkWxListStore *list_store = (GtkListStore *) tree_model;
790b137e 355
67cbdfc1 356 g_return_val_if_fail (list_store->stamp == iter->stamp, FALSE);
790b137e 357
67cbdfc1
RR
358 int n = (int) iter->user_data;
359
360 if (n == -1)
361 return FALSE;
362
363 if (n >= (int) list_store->model->GetRowCount())
364 return FALSE;
365
366 iter->user_data = (gpointer) n++;
790b137e 367
67cbdfc1 368 return TRUE;
790b137e
RR
369}
370
371static gboolean
372wxgtk_list_store_iter_children (GtkTreeModel *tree_model,
373 GtkTreeIter *iter,
374 GtkTreeIter *parent)
375{
67cbdfc1
RR
376 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), FALSE);
377 GtkWxListStore *list_store = (GtkListStore *) tree_model;
378
379 // this is a list, nodes have no children
790b137e
RR
380 if (parent)
381 return FALSE;
382
67cbdfc1
RR
383 iter->stamp = list_store->stamp;
384 iter->user_data = (gpointer) -1;
385
386 return TRUE;
790b137e
RR
387}
388
389static gboolean
390wxgtk_list_store_iter_has_child (GtkTreeModel *tree_model,
391 GtkTreeIter *iter)
392{
393 return FALSE;
394}
395
396static gint
397wxgtk_list_store_iter_n_children (GtkTreeModel *tree_model,
398 GtkTreeIter *iter)
399{
400 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), -1);
67cbdfc1 401 GtkWxListStore *list_store = (GtkListStore *) tree_model;
790b137e
RR
402
403 if (iter == NULL)
67cbdfc1 404 return (gint) list_store->model->GetRowCount();
790b137e 405
67cbdfc1 406 g_return_val_if_fail (list_store->stamp == iter->stamp, -1);
790b137e
RR
407
408 return 0;
409}
410
411static gboolean
412wxgtk_list_store_iter_nth_child (GtkTreeModel *tree_model,
413 GtkTreeIter *iter,
414 GtkTreeIter *parent,
415 gint n)
416{
67cbdfc1
RR
417 g_return_val_if_fail (GTK_IS_WX_LIST_STORE (tree_model), FALSE);
418 GtkWxListStore *list_store = (GtkListStore *) tree_model;
419
420 if (parent)
421 return FALSE;
790b137e 422
67cbdfc1
RR
423 if (n < 0)
424 return FALSE;
425
426 if (n >= (gint) list_store->model->GetRowCount())
427 return FALSE;
790b137e 428
67cbdfc1
RR
429 iter->stamp = list_store->stamp;
430 iter->user_data = (gpointer) n;
431
432 return TRUE;
790b137e
RR
433}
434
435static gboolean
436wxgtk_list_store_iter_parent (GtkTreeModel *tree_model,
437 GtkTreeIter *iter,
438 GtkTreeIter *child)
439{
440 return FALSE;
441}
442
443
444//-----------------------------------------------------------------------------
445// wxDataViewCtrl
446//-----------------------------------------------------------------------------
447
448IMPLEMENT_DYNAMIC_CLASS(wxDataViewCtrl,wxControl)
449
450
451#endif // wxUSE_DATAVIEWCTRL
452