]> Pileus Git - ~andy/gtk/blob - gtk/gtkwidgetpath.c
GtkWidgetPath: properly use const
[~andy/gtk] / gtk / gtkwidgetpath.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 2010 Carlos Garnacho <carlosg@gnome.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser 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  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser 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 "config.h"
21
22 #include <string.h>
23
24 #include "gtkwidget.h"
25 #include "gtkwidgetpath.h"
26
27 typedef struct GtkPathElement GtkPathElement;
28
29 struct GtkPathElement
30 {
31   GType type;
32   gchar *name;
33   GHashTable *regions;
34 };
35
36 struct GtkWidgetPath
37 {
38   GArray *elems; /* First element contains the described widget */
39 };
40
41 GtkWidgetPath *
42 gtk_widget_path_new (void)
43 {
44   GtkWidgetPath *path;
45
46   path = g_slice_new0 (GtkWidgetPath);
47   path->elems = g_array_new (FALSE, TRUE, sizeof (GtkPathElement));
48
49   return path;
50 }
51
52 GtkWidgetPath *
53 gtk_widget_path_copy (const GtkWidgetPath *path)
54 {
55   GtkWidgetPath *new_path;
56   guint i;
57
58   g_return_val_if_fail (path != NULL, NULL);
59
60   new_path = gtk_widget_path_new ();
61
62   for (i = 0; i < path->elems->len; i++)
63     {
64       GtkPathElement *elem, new = { 0 };
65
66       elem = &g_array_index (path->elems, GtkPathElement, i);
67
68       new.type = elem->type;
69       new.name = g_strdup (elem->name);
70
71       if (elem->regions)
72         {
73           GHashTableIter iter;
74           gpointer key, value;
75
76           g_hash_table_iter_init (&iter, elem->regions);
77           new.regions = g_hash_table_new_full (g_str_hash,
78                                                g_str_equal,
79                                                (GDestroyNotify) g_free,
80                                                NULL);
81
82           while (g_hash_table_iter_next (&iter, &key, &value))
83             g_hash_table_insert (new.regions,
84                                  g_strdup ((const gchar *) key),
85                                  value);
86         }
87
88       g_array_append_val (new_path->elems, new);
89     }
90
91   return new_path;
92 }
93
94 void
95 gtk_widget_path_free (GtkWidgetPath *path)
96 {
97   guint i;
98
99   g_return_if_fail (path != NULL);
100
101   for (i = 0; i < path->elems->len; i++)
102     {
103       GtkPathElement *elem;
104
105       elem = &g_array_index (path->elems, GtkPathElement, i);
106       g_free (elem->name);
107
108       if (elem->regions)
109         g_hash_table_destroy (elem->regions);
110     }
111
112   g_array_free (path->elems, TRUE);
113   g_slice_free (GtkWidgetPath, path);
114 }
115
116 guint
117 gtk_widget_path_length (const GtkWidgetPath *path)
118 {
119   g_return_val_if_fail (path != NULL, 0);
120
121   return path->elems->len;
122 }
123
124 guint
125 gtk_widget_path_prepend_type (GtkWidgetPath *path,
126                               GType          type)
127 {
128   GtkPathElement new = { 0 };
129
130   g_return_val_if_fail (path != NULL, 0);
131   g_return_val_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET), 0);
132
133   new.type = type;
134   g_array_append_val (path->elems, new);
135
136   return path->elems->len - 1;
137 }
138
139 GType
140 gtk_widget_path_get_element_type (const GtkWidgetPath *path,
141                                   guint                pos)
142 {
143   GtkPathElement *elem;
144
145   g_return_val_if_fail (path != NULL, G_TYPE_INVALID);
146   g_return_val_if_fail (pos < path->elems->len, G_TYPE_INVALID);
147
148   elem = &g_array_index (path->elems, GtkPathElement, pos);
149   return elem->type;
150 }
151
152 void
153 gtk_widget_path_set_element_type (GtkWidgetPath *path,
154                                   guint          pos,
155                                   GType          type)
156 {
157   GtkPathElement *elem;
158
159   g_return_if_fail (path != NULL);
160   g_return_if_fail (pos < path->elems->len);
161   g_return_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET));
162
163   elem = &g_array_index (path->elems, GtkPathElement, pos);
164   elem->type = type;
165 }
166
167 G_CONST_RETURN gchar *
168 gtk_widget_path_get_element_name (const GtkWidgetPath *path,
169                                   guint                pos)
170 {
171   GtkPathElement *elem;
172
173   g_return_val_if_fail (path != NULL, NULL);
174   g_return_val_if_fail (pos < path->elems->len, NULL);
175
176   elem = &g_array_index (path->elems, GtkPathElement, pos);
177   return elem->name;
178 }
179
180 void
181 gtk_widget_path_set_element_name (GtkWidgetPath *path,
182                                   guint          pos,
183                                   const gchar   *name)
184 {
185   GtkPathElement *elem;
186
187   g_return_if_fail (path != NULL);
188   g_return_if_fail (pos < path->elems->len);
189   g_return_if_fail (name != NULL);
190
191   elem = &g_array_index (path->elems, GtkPathElement, pos);
192
193   if (elem->name)
194     g_free (elem->name);
195
196   elem->name = g_strdup (name);
197 }
198
199 void
200 gtk_widget_path_iter_add_region (GtkWidgetPath      *path,
201                                  guint               pos,
202                                  const gchar        *name,
203                                  GtkChildClassFlags  flags)
204 {
205   GtkPathElement *elem;
206
207   g_return_if_fail (path != NULL);
208   g_return_if_fail (pos < path->elems->len);
209   g_return_if_fail (name != NULL);
210
211   elem = &g_array_index (path->elems, GtkPathElement, pos);
212
213   if (!elem->regions)
214     elem->regions = g_hash_table_new_full (g_str_hash,
215                                            g_str_equal,
216                                            (GDestroyNotify) g_free,
217                                            NULL);
218
219   g_hash_table_insert (elem->regions,
220                        g_strdup (name),
221                        GUINT_TO_POINTER (flags));
222 }
223
224 void
225 gtk_widget_path_iter_remove_region (GtkWidgetPath *path,
226                                     guint          pos,
227                                     const gchar   *name)
228 {
229   GtkPathElement *elem;
230
231   g_return_if_fail (path != NULL);
232   g_return_if_fail (pos < path->elems->len);
233   g_return_if_fail (name != NULL);
234
235   elem = &g_array_index (path->elems, GtkPathElement, pos);
236
237   if (elem->regions)
238     g_hash_table_remove (elem->regions, name);
239 }
240
241 void
242 gtk_widget_path_iter_clear_regions (GtkWidgetPath *path,
243                                     guint          pos)
244 {
245   GtkPathElement *elem;
246
247   g_return_if_fail (path != NULL);
248   g_return_if_fail (pos < path->elems->len);
249
250   elem = &g_array_index (path->elems, GtkPathElement, pos);
251
252   if (elem->regions)
253     g_hash_table_remove_all (elem->regions);
254 }
255
256 GSList *
257 gtk_widget_path_iter_list_regions (const GtkWidgetPath *path,
258                                    guint                pos)
259 {
260   GtkPathElement *elem;
261   GHashTableIter iter;
262   GSList *list = NULL;
263   gpointer key;
264
265   g_return_val_if_fail (path != NULL, NULL);
266   g_return_val_if_fail (pos < path->elems->len, NULL);
267
268   elem = &g_array_index (path->elems, GtkPathElement, pos);
269
270   if (!elem->regions)
271     return NULL;
272
273   g_hash_table_iter_init (&iter, elem->regions);
274
275   while (g_hash_table_iter_next (&iter, &key, NULL))
276     list = g_slist_prepend (list, key);
277
278   return list;
279 }
280
281 gboolean
282 gtk_widget_path_iter_has_region (const GtkWidgetPath *path,
283                                  guint                pos,
284                                  const gchar         *name,
285                                  GtkChildClassFlags  *flags)
286 {
287   GtkPathElement *elem;
288   gpointer value;
289
290   g_return_val_if_fail (path != NULL, FALSE);
291   g_return_val_if_fail (pos < path->elems->len, FALSE);
292   g_return_val_if_fail (name != NULL, FALSE);
293
294   elem = &g_array_index (path->elems, GtkPathElement, pos);
295
296   if (!elem->regions)
297     return FALSE;
298
299   if (!g_hash_table_lookup_extended (elem->regions, name, NULL, &value))
300     return FALSE;
301
302   if (flags)
303     *flags = GPOINTER_TO_UINT (value);
304
305   return TRUE;
306 }
307
308 GType
309 gtk_widget_path_get_widget_type (const GtkWidgetPath *path)
310 {
311   GtkPathElement *elem;
312
313   g_return_val_if_fail (path != NULL, G_TYPE_INVALID);
314
315   elem = &g_array_index (path->elems, GtkPathElement, 0);
316   return elem->type;
317 }
318
319 gboolean
320 gtk_widget_path_is_type (const GtkWidgetPath *path,
321                          GType                type)
322 {
323   GtkPathElement *elem;
324
325   g_return_val_if_fail (path != NULL, FALSE);
326   g_return_val_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET), FALSE);
327
328   elem = &g_array_index (path->elems, GtkPathElement, 0);
329
330   if (elem->type == type ||
331       g_type_is_a (elem->type, type))
332     return TRUE;
333
334   return FALSE;
335 }
336
337 gboolean
338 gtk_widget_path_has_parent (const GtkWidgetPath *path,
339                             GType                type)
340 {
341   guint i;
342
343   g_return_val_if_fail (path != NULL, FALSE);
344   g_return_val_if_fail (g_type_is_a (type, GTK_TYPE_WIDGET), FALSE);
345
346   for (i = 1; i < path->elems->len; i++)
347     {
348       GtkPathElement *elem;
349
350       elem = &g_array_index (path->elems, GtkPathElement, i);
351
352       if (elem->type == type ||
353           g_type_is_a (elem->type, type))
354         return TRUE;
355     }
356
357   return FALSE;
358 }
359
360 #define __GTK_WIDGET_PATH_C__
361 #include "gtkaliasdef.c"