]> Pileus Git - ~andy/gtk/blob - gtk/gtktreemodel.c
Move GtkTreeModel from object to interface.
[~andy/gtk] / gtk / gtktreemodel.c
1 /* gtktreemodel.c
2  * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include "gtktreemodel.h"
24
25 struct _GtkTreePath
26 {
27   gint depth;
28   gint *indices;
29 };
30
31 GtkType
32 gtk_tree_model_get_type (void)
33 {
34   static GtkType tree_model_type = 0;
35
36   if (!tree_model_type)
37     {
38       static const GTypeInfo tree_model_info =
39       {
40         sizeof (GtkTreeModelIface), /* class_size */
41         NULL,           /* base_init */
42         NULL,           /* base_finalize */
43       };
44
45       tree_model_type = g_type_register_static (G_TYPE_INTERFACE, "GtkTreeModel", &tree_model_info);
46     }
47
48   return tree_model_type;
49 }
50
51 /* GtkTreePath Operations */
52 GtkTreePath *
53 gtk_tree_path_new (void)
54 {
55   GtkTreePath *retval;
56   retval = (GtkTreePath *) g_new (GtkTreePath, 1);
57   retval->depth = 0;
58   retval->indices = NULL;
59
60   return retval;
61 }
62
63 GtkTreePath *
64 gtk_tree_path_new_from_string (gchar *path)
65 {
66   GtkTreePath *retval;
67   gchar *ptr;
68   gint i;
69
70   g_return_val_if_fail (path != NULL, gtk_tree_path_new ());
71
72   retval = gtk_tree_path_new ();
73
74   while (1)
75     {
76       i = strtol (path, &ptr, 10);
77       gtk_tree_path_append_index (retval, i);
78
79       if (*ptr == '\000')
80         break;
81       path = ptr + 1;
82     }
83
84   return retval;
85 }
86
87 gchar *
88 gtk_tree_path_to_string (GtkTreePath *path)
89 {
90   gchar *retval, *ptr;
91   gint i;
92
93   if (path->depth == 0)
94     return NULL;
95
96   ptr = retval = (gchar *) g_new0 (char *, path->depth*8);
97   sprintf (retval, "%d", path->indices[0]);
98   while (*ptr != '\000')
99     ptr++;
100
101   for (i = 1; i < path->depth; i++)
102     {
103       sprintf (ptr, ":%d", path->indices[i]);
104       while (*ptr != '\000')
105         ptr++;
106     }
107
108   return retval;
109 }
110
111 GtkTreePath *
112 gtk_tree_path_new_root (void)
113 {
114   GtkTreePath *retval;
115
116   retval = gtk_tree_path_new ();
117   gtk_tree_path_append_index (retval, 0);
118
119   return retval;
120 }
121
122 void
123 gtk_tree_path_append_index (GtkTreePath *path,
124                             gint         index)
125 {
126   gint *new_indices = g_new (gint, ++path->depth);
127   if (path->indices == NULL)
128     {
129       path->indices = new_indices;
130       path->indices[0] = index;
131       return;
132     }
133
134   memcpy (new_indices, path->indices, (path->depth - 1)*sizeof (gint));
135   g_free (path->indices);
136   path->indices = new_indices;
137   path->indices[path->depth - 1] = index;
138 }
139
140 void
141 gtk_tree_path_prepend_index (GtkTreePath *path,
142                              gint       index)
143 {
144   gint *new_indices = g_new (gint, ++path->depth);
145   if (path->indices == NULL)
146     {
147       path->indices = new_indices;
148       path->indices[0] = index;
149       return;
150     }
151   memcpy (new_indices + 1, path->indices, (path->depth - 1)*sizeof (gint));
152   g_free (path->indices);
153   path->indices = new_indices;
154   path->indices[0] = index;
155 }
156
157 gint
158 gtk_tree_path_get_depth (GtkTreePath *path)
159 {
160   return path->depth;
161 }
162
163 gint *
164 gtk_tree_path_get_indices (GtkTreePath *path)
165 {
166   return path->indices;
167 }
168
169 void
170 gtk_tree_path_free (GtkTreePath *path)
171 {
172   g_free (path->indices);
173   g_free (path);
174 }
175
176 GtkTreePath *
177 gtk_tree_path_copy (GtkTreePath *path)
178 {
179   GtkTreePath *retval;
180
181   retval = g_new (GtkTreePath, 1);
182   retval->depth = path->depth;
183   retval->indices = g_new (gint, path->depth);
184   memcpy (retval->indices, path->indices, path->depth * sizeof (gint));
185   return retval;
186 }
187
188 gint
189 gtk_tree_path_compare (GtkTreePath  *a,
190                        GtkTreePath  *b)
191 {
192   gint p = 0, q = 0;
193
194   g_return_val_if_fail (a != NULL, 0);
195   g_return_val_if_fail (b != NULL, 0);
196   g_return_val_if_fail (a->depth > 0, 0);
197   g_return_val_if_fail (b->depth > 0, 0);
198
199   do
200     {
201       if (a->indices[p] == b->indices[q])
202         continue;
203       return (a->indices[p] < b->indices[q]?1:-1);
204     }
205   while (++p < a->depth && ++q < b->depth);
206   if (a->depth == b->depth)
207     return 0;
208   return (a->depth < b->depth?1:-1);
209 }
210
211 void
212 gtk_tree_path_next (GtkTreePath *path)
213 {
214   g_return_if_fail (path != NULL);
215
216   path->indices[path->depth - 1] ++;
217 }
218
219 gint
220 gtk_tree_path_prev (GtkTreePath *path)
221 {
222   g_return_val_if_fail (path != NULL, FALSE);
223
224   if (path->indices[path->depth] == 0)
225     return FALSE;
226
227   path->indices[path->depth - 1] --;
228
229   return TRUE;
230 }
231
232 gint
233 gtk_tree_path_up (GtkTreePath *path)
234 {
235   g_return_val_if_fail (path != NULL, FALSE);
236
237   if (path->depth == 1)
238     return FALSE;
239
240   path->depth--;
241
242   return TRUE;
243 }
244
245 void
246 gtk_tree_path_down (GtkTreePath *path)
247 {
248   g_return_if_fail (path != NULL);
249
250   gtk_tree_path_append_index (path, 0);
251 }
252
253 gint
254 gtk_tree_model_get_n_columns (GtkTreeModel *tree_model)
255 {
256   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_n_columns != NULL, 0);
257   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->get_n_columns) (tree_model);
258 }
259
260 /* Node options */
261 GtkTreeNode
262 gtk_tree_model_get_node (GtkTreeModel *tree_model,
263                          GtkTreePath  *path)
264 {
265   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_node != NULL, NULL);
266   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->get_node) (tree_model, path);
267 }
268
269 GtkTreePath *
270 gtk_tree_model_get_path (GtkTreeModel *tree_model,
271                          GtkTreeNode   node)
272 {
273   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_path != NULL, NULL);
274   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->get_path) (tree_model, node);
275 }
276
277 void
278 gtk_tree_model_node_get_value (GtkTreeModel *tree_model,
279                                GtkTreeNode   node,
280                                gint        column,
281                                GValue     *value)
282 {
283   g_return_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->node_get_value != NULL);
284   (* GTK_TREE_MODEL_GET_IFACE (tree_model)->node_get_value) (tree_model, node, column, value);
285 }
286
287 gboolean
288 gtk_tree_model_node_next (GtkTreeModel  *tree_model,
289                           GtkTreeNode   *node)
290 {
291   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->node_next != NULL, FALSE);
292   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->node_next) (tree_model, node);
293 }
294
295 GtkTreeNode
296 gtk_tree_model_node_children (GtkTreeModel *tree_model,
297                               GtkTreeNode   node)
298 {
299   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->node_children != NULL, NULL);
300   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->node_children) (tree_model, node);
301 }
302
303 gboolean
304 gtk_tree_model_node_has_child (GtkTreeModel *tree_model,
305                                GtkTreeNode   node)
306 {
307   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->node_has_child != NULL, FALSE);
308   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->node_has_child) (tree_model, node);
309 }
310
311 gint
312 gtk_tree_model_node_n_children (GtkTreeModel *tree_model,
313                                 GtkTreeNode   node)
314 {
315   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->node_n_children != NULL, -1);
316   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->node_n_children) (tree_model, node);
317 }
318
319 GtkTreeNode
320 gtk_tree_model_node_nth_child (GtkTreeModel *tree_model,
321                                GtkTreeNode   node,
322                                gint        n)
323 {
324   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->node_nth_child != NULL, NULL);
325   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->node_nth_child) (tree_model, node, n);
326 }
327
328 GtkTreeNode
329 gtk_tree_model_node_parent (GtkTreeModel *tree_model,
330                             GtkTreeNode   node)
331 {
332   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->node_parent != NULL, NULL);
333   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->node_parent) (tree_model, node);
334 }
335