1 | /* GTK - The GIMP Toolkit |
---|
2 | * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald |
---|
3 | * |
---|
4 | * GtkItemFactory: Flexible item factory with automatic rc handling |
---|
5 | * Copyright (C) 1998 Tim Janik |
---|
6 | * |
---|
7 | * This library is free software; you can redistribute it and/or |
---|
8 | * modify it under the terms of the GNU Library General Public |
---|
9 | * License as published by the Free Software Foundation; either |
---|
10 | * version 2 of the License, or (at your option) any later version. |
---|
11 | * |
---|
12 | * This library is distributed in the hope that it will be useful, |
---|
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
15 | * Library General Public License for more details. |
---|
16 | * |
---|
17 | * You should have received a copy of the GNU Library General Public |
---|
18 | * License along with this library; if not, write to the |
---|
19 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
---|
20 | * Boston, MA 02111-1307, USA. |
---|
21 | */ |
---|
22 | |
---|
23 | /* |
---|
24 | * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS |
---|
25 | * file for a list of people on the GTK+ Team. See the ChangeLog |
---|
26 | * files for a list of changes. These files are distributed with |
---|
27 | * GTK+ at ftp://ftp.gtk.org/pub/gtk/. |
---|
28 | */ |
---|
29 | |
---|
30 | #include "gtkitemfactory.h" |
---|
31 | #include "gtk/gtksignal.h" |
---|
32 | #include "gtk/gtkoptionmenu.h" |
---|
33 | #include "gtk/gtkmenubar.h" |
---|
34 | #include "gtk/gtkmenu.h" |
---|
35 | #include "gtk/gtkmenuitem.h" |
---|
36 | #include "gtk/gtkradiomenuitem.h" |
---|
37 | #include "gtk/gtkcheckmenuitem.h" |
---|
38 | #include "gtk/gtktearoffmenuitem.h" |
---|
39 | #include "gtk/gtkaccellabel.h" |
---|
40 | #include "gdk/gdkkeysyms.h" |
---|
41 | #include <string.h> |
---|
42 | #include <sys/stat.h> |
---|
43 | #include <fcntl.h> |
---|
44 | #include <unistd.h> |
---|
45 | #include <stdio.h> |
---|
46 | |
---|
47 | |
---|
48 | |
---|
49 | /* --- defines --- */ |
---|
50 | #define ITEM_FACTORY_STRING ((gchar*) item_factory_string) |
---|
51 | #define ITEM_BLOCK_SIZE (128) |
---|
52 | |
---|
53 | |
---|
54 | /* --- structures --- */ |
---|
55 | typedef struct _GtkIFCBData GtkIFCBData; |
---|
56 | typedef struct _GtkIFDumpData GtkIFDumpData; |
---|
57 | struct _GtkIFCBData |
---|
58 | { |
---|
59 | GtkItemFactoryCallback func; |
---|
60 | guint callback_type; |
---|
61 | gpointer func_data; |
---|
62 | guint callback_action; |
---|
63 | }; |
---|
64 | struct _GtkIFDumpData |
---|
65 | { |
---|
66 | GtkPrintFunc print_func; |
---|
67 | gpointer func_data; |
---|
68 | guint modified_only : 1; |
---|
69 | GtkPatternSpec *pspec; |
---|
70 | }; |
---|
71 | |
---|
72 | |
---|
73 | /* --- prototypes --- */ |
---|
74 | static void gtk_item_factory_class_init (GtkItemFactoryClass *klass); |
---|
75 | static void gtk_item_factory_init (GtkItemFactory *ifactory); |
---|
76 | static void gtk_item_factory_destroy (GtkObject *object); |
---|
77 | static void gtk_item_factory_finalize (GtkObject *object); |
---|
78 | |
---|
79 | |
---|
80 | /* --- static variables --- */ |
---|
81 | static GtkItemFactoryClass *gtk_item_factory_class = NULL; |
---|
82 | static GtkObjectClass *parent_class = NULL; |
---|
83 | static const gchar *item_factory_string = "Gtk-<ItemFactory>"; |
---|
84 | static GMemChunk *ifactory_item_chunks = NULL; |
---|
85 | static GMemChunk *ifactory_cb_data_chunks = NULL; |
---|
86 | static GQuark quark_popup_data = 0; |
---|
87 | static GQuark quark_if_menu_pos = 0; |
---|
88 | static GQuark quark_item_factory = 0; |
---|
89 | static GQuark quark_item_path = 0; |
---|
90 | static GQuark quark_action = 0; |
---|
91 | static GQuark quark_accel_group = 0; |
---|
92 | static GQuark quark_type_item = 0; |
---|
93 | static GQuark quark_type_title = 0; |
---|
94 | static GQuark quark_type_radio_item = 0; |
---|
95 | static GQuark quark_type_check_item = 0; |
---|
96 | static GQuark quark_type_toggle_item = 0; |
---|
97 | static GQuark quark_type_tearoff_item = 0; |
---|
98 | static GQuark quark_type_separator_item = 0; |
---|
99 | static GQuark quark_type_branch = 0; |
---|
100 | static GQuark quark_type_last_branch = 0; |
---|
101 | static GScannerConfig ifactory_scanner_config = |
---|
102 | { |
---|
103 | ( |
---|
104 | " \t\n" |
---|
105 | ) /* cset_skip_characters */, |
---|
106 | ( |
---|
107 | G_CSET_a_2_z |
---|
108 | "_" |
---|
109 | G_CSET_A_2_Z |
---|
110 | ) /* cset_identifier_first */, |
---|
111 | ( |
---|
112 | G_CSET_a_2_z |
---|
113 | "-+_0123456789" |
---|
114 | G_CSET_A_2_Z |
---|
115 | G_CSET_LATINS |
---|
116 | G_CSET_LATINC |
---|
117 | ) /* cset_identifier_nth */, |
---|
118 | ( ";\n" ) /* cpair_comment_single */, |
---|
119 | |
---|
120 | FALSE /* case_sensitive */, |
---|
121 | |
---|
122 | TRUE /* skip_comment_multi */, |
---|
123 | TRUE /* skip_comment_single */, |
---|
124 | FALSE /* scan_comment_multi */, |
---|
125 | TRUE /* scan_identifier */, |
---|
126 | FALSE /* scan_identifier_1char */, |
---|
127 | FALSE /* scan_identifier_NULL */, |
---|
128 | TRUE /* scan_symbols */, |
---|
129 | TRUE /* scan_binary */, |
---|
130 | TRUE /* scan_octal */, |
---|
131 | TRUE /* scan_float */, |
---|
132 | TRUE /* scan_hex */, |
---|
133 | FALSE /* scan_hex_dollar */, |
---|
134 | TRUE /* scan_string_sq */, |
---|
135 | TRUE /* scan_string_dq */, |
---|
136 | TRUE /* numbers_2_int */, |
---|
137 | FALSE /* int_2_float */, |
---|
138 | FALSE /* identifier_2_string */, |
---|
139 | TRUE /* char_2_token */, |
---|
140 | FALSE /* symbol_2_token */, |
---|
141 | }; |
---|
142 | |
---|
143 | |
---|
144 | /* --- functions --- */ |
---|
145 | GtkType |
---|
146 | gtk_item_factory_get_type (void) |
---|
147 | { |
---|
148 | static GtkType item_factory_type = 0; |
---|
149 | |
---|
150 | if (!item_factory_type) |
---|
151 | { |
---|
152 | static const GtkTypeInfo item_factory_info = |
---|
153 | { |
---|
154 | "GtkItemFactory", |
---|
155 | sizeof (GtkItemFactory), |
---|
156 | sizeof (GtkItemFactoryClass), |
---|
157 | (GtkClassInitFunc) gtk_item_factory_class_init, |
---|
158 | (GtkObjectInitFunc) gtk_item_factory_init, |
---|
159 | /* reserved_1 */ NULL, |
---|
160 | /* reserved_2 */ NULL, |
---|
161 | (GtkClassInitFunc) NULL, |
---|
162 | }; |
---|
163 | |
---|
164 | item_factory_type = gtk_type_unique (GTK_TYPE_OBJECT, &item_factory_info); |
---|
165 | } |
---|
166 | |
---|
167 | return item_factory_type; |
---|
168 | } |
---|
169 | |
---|
170 | static void |
---|
171 | gtk_item_factory_class_init (GtkItemFactoryClass *class) |
---|
172 | { |
---|
173 | GtkObjectClass *object_class; |
---|
174 | |
---|
175 | gtk_item_factory_class = class; |
---|
176 | |
---|
177 | parent_class = gtk_type_class (GTK_TYPE_OBJECT); |
---|
178 | |
---|
179 | object_class = (GtkObjectClass*) class; |
---|
180 | |
---|
181 | object_class->destroy = gtk_item_factory_destroy; |
---|
182 | object_class->finalize = gtk_item_factory_finalize; |
---|
183 | |
---|
184 | class->cpair_comment_single = g_strdup (";\n"); |
---|
185 | |
---|
186 | class->item_ht = g_hash_table_new (g_str_hash, g_str_equal); |
---|
187 | class->dummy = NULL; |
---|
188 | ifactory_item_chunks = |
---|
189 | g_mem_chunk_new ("GtkItemFactoryItem", |
---|
190 | sizeof (GtkItemFactoryItem), |
---|
191 | sizeof (GtkItemFactoryItem) * ITEM_BLOCK_SIZE, |
---|
192 | G_ALLOC_ONLY); |
---|
193 | ifactory_cb_data_chunks = |
---|
194 | g_mem_chunk_new ("GtkIFCBData", |
---|
195 | sizeof (GtkIFCBData), |
---|
196 | sizeof (GtkIFCBData) * ITEM_BLOCK_SIZE, |
---|
197 | G_ALLOC_AND_FREE); |
---|
198 | |
---|
199 | quark_popup_data = g_quark_from_static_string ("GtkItemFactory-popup-data"); |
---|
200 | quark_if_menu_pos = g_quark_from_static_string ("GtkItemFactory-menu-position"); |
---|
201 | quark_item_factory = g_quark_from_static_string ("GtkItemFactory"); |
---|
202 | quark_item_path = g_quark_from_static_string ("GtkItemFactory-path"); |
---|
203 | quark_action = g_quark_from_static_string ("GtkItemFactory-action"); |
---|
204 | quark_accel_group = g_quark_from_static_string ("GtkAccelGroup"); |
---|
205 | quark_type_item = g_quark_from_static_string ("<Item>"); |
---|
206 | quark_type_title = g_quark_from_static_string ("<Title>"); |
---|
207 | quark_type_radio_item = g_quark_from_static_string ("<RadioItem>"); |
---|
208 | quark_type_check_item = g_quark_from_static_string ("<CheckItem>"); |
---|
209 | quark_type_toggle_item = g_quark_from_static_string ("<ToggleItem>"); |
---|
210 | quark_type_tearoff_item = g_quark_from_static_string ("<Tearoff>"); |
---|
211 | quark_type_separator_item = g_quark_from_static_string ("<Separator>"); |
---|
212 | quark_type_branch = g_quark_from_static_string ("<Branch>"); |
---|
213 | quark_type_last_branch = g_quark_from_static_string ("<LastBranch>"); |
---|
214 | } |
---|
215 | |
---|
216 | static void |
---|
217 | gtk_item_factory_init (GtkItemFactory *ifactory) |
---|
218 | { |
---|
219 | GtkObject *object; |
---|
220 | |
---|
221 | object = GTK_OBJECT (ifactory); |
---|
222 | |
---|
223 | ifactory->path = NULL; |
---|
224 | ifactory->accel_group = NULL; |
---|
225 | ifactory->widget = NULL; |
---|
226 | ifactory->items = NULL; |
---|
227 | ifactory->translate_func = NULL; |
---|
228 | ifactory->translate_data = NULL; |
---|
229 | ifactory->translate_notify = NULL; |
---|
230 | } |
---|
231 | |
---|
232 | GtkItemFactory* |
---|
233 | gtk_item_factory_new (GtkType container_type, |
---|
234 | const gchar *path, |
---|
235 | GtkAccelGroup *accel_group) |
---|
236 | { |
---|
237 | GtkItemFactory *ifactory; |
---|
238 | |
---|
239 | g_return_val_if_fail (path != NULL, NULL); |
---|
240 | |
---|
241 | ifactory = gtk_type_new (GTK_TYPE_ITEM_FACTORY); |
---|
242 | gtk_item_factory_construct (ifactory, container_type, path, accel_group); |
---|
243 | |
---|
244 | return ifactory; |
---|
245 | } |
---|
246 | |
---|
247 | static void |
---|
248 | gtk_item_factory_callback_marshal (GtkWidget *widget, |
---|
249 | gpointer func_data) |
---|
250 | { |
---|
251 | GtkIFCBData *data; |
---|
252 | |
---|
253 | data = func_data; |
---|
254 | |
---|
255 | if (data->callback_type == 1) |
---|
256 | { |
---|
257 | GtkItemFactoryCallback1 func1 = data->func; |
---|
258 | func1 (data->func_data, data->callback_action, widget); |
---|
259 | } |
---|
260 | else if (data->callback_type == 2) |
---|
261 | { |
---|
262 | GtkItemFactoryCallback2 func2 = data->func; |
---|
263 | func2 (widget, data->func_data, data->callback_action); |
---|
264 | } |
---|
265 | } |
---|
266 | |
---|
267 | static void |
---|
268 | gtk_item_factory_propagate_accelerator (GtkItemFactoryItem *item, |
---|
269 | GtkWidget *exclude) |
---|
270 | { |
---|
271 | GSList *widget_list; |
---|
272 | GSList *slist; |
---|
273 | |
---|
274 | if (item->in_propagation) |
---|
275 | return; |
---|
276 | |
---|
277 | item->in_propagation = TRUE; |
---|
278 | |
---|
279 | widget_list = NULL; |
---|
280 | for (slist = item->widgets; slist; slist = slist->next) |
---|
281 | { |
---|
282 | GtkWidget *widget; |
---|
283 | |
---|
284 | widget = slist->data; |
---|
285 | |
---|
286 | if (widget != exclude) |
---|
287 | { |
---|
288 | gtk_widget_ref (widget); |
---|
289 | widget_list = g_slist_prepend (widget_list, widget); |
---|
290 | } |
---|
291 | } |
---|
292 | |
---|
293 | for (slist = widget_list; slist; slist = slist->next) |
---|
294 | { |
---|
295 | GtkWidget *widget; |
---|
296 | GtkAccelGroup *accel_group; |
---|
297 | guint signal_id; |
---|
298 | |
---|
299 | widget = slist->data; |
---|
300 | |
---|
301 | accel_group = gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_accel_group); |
---|
302 | |
---|
303 | signal_id = gtk_signal_lookup ("activate", GTK_OBJECT_TYPE (widget)); |
---|
304 | if (signal_id && accel_group) |
---|
305 | { |
---|
306 | if (item->accelerator_key) |
---|
307 | gtk_widget_add_accelerator (widget, |
---|
308 | "activate", |
---|
309 | accel_group, |
---|
310 | item->accelerator_key, |
---|
311 | item->accelerator_mods, |
---|
312 | GTK_ACCEL_VISIBLE); |
---|
313 | else |
---|
314 | { |
---|
315 | GSList *work; |
---|
316 | |
---|
317 | work = gtk_accel_group_entries_from_object (GTK_OBJECT (widget)); |
---|
318 | while (work) |
---|
319 | { |
---|
320 | GtkAccelEntry *ac_entry; |
---|
321 | |
---|
322 | ac_entry = work->data; |
---|
323 | work = work->next; |
---|
324 | if (ac_entry->accel_flags & GTK_ACCEL_VISIBLE && |
---|
325 | ac_entry->accel_group == accel_group && |
---|
326 | ac_entry->signal_id == signal_id) |
---|
327 | gtk_widget_remove_accelerator (GTK_WIDGET (widget), |
---|
328 | ac_entry->accel_group, |
---|
329 | ac_entry->accelerator_key, |
---|
330 | ac_entry->accelerator_mods); |
---|
331 | } |
---|
332 | } |
---|
333 | } |
---|
334 | |
---|
335 | gtk_widget_unref (widget); |
---|
336 | } |
---|
337 | |
---|
338 | g_slist_free (widget_list); |
---|
339 | |
---|
340 | item->in_propagation = FALSE; |
---|
341 | } |
---|
342 | |
---|
343 | static gint |
---|
344 | gtk_item_factory_item_add_accelerator (GtkWidget *widget, |
---|
345 | guint accel_signal_id, |
---|
346 | GtkAccelGroup *accel_group, |
---|
347 | guint accel_key, |
---|
348 | guint accel_mods, |
---|
349 | GtkAccelFlags accel_flags, |
---|
350 | GtkItemFactoryItem *item) |
---|
351 | { |
---|
352 | if (!item->in_propagation && |
---|
353 | g_slist_find (item->widgets, widget) && |
---|
354 | accel_signal_id == gtk_signal_lookup ("activate", GTK_OBJECT_TYPE (widget))) |
---|
355 | { |
---|
356 | item->accelerator_key = accel_key; |
---|
357 | item->accelerator_mods = accel_mods; |
---|
358 | item->modified = TRUE; |
---|
359 | |
---|
360 | gtk_item_factory_propagate_accelerator (item, widget); |
---|
361 | } |
---|
362 | |
---|
363 | return TRUE; |
---|
364 | } |
---|
365 | |
---|
366 | static void |
---|
367 | gtk_item_factory_item_remove_accelerator (GtkWidget *widget, |
---|
368 | GtkAccelGroup *accel_group, |
---|
369 | guint accel_key, |
---|
370 | guint accel_mods, |
---|
371 | GtkItemFactoryItem *item) |
---|
372 | { |
---|
373 | if (!item->in_propagation && |
---|
374 | g_slist_find (item->widgets, widget) && |
---|
375 | item->accelerator_key == accel_key && |
---|
376 | item->accelerator_mods == accel_mods) |
---|
377 | { |
---|
378 | item->accelerator_key = 0; |
---|
379 | item->accelerator_mods = 0; |
---|
380 | item->modified = TRUE; |
---|
381 | |
---|
382 | gtk_item_factory_propagate_accelerator (item, widget); |
---|
383 | } |
---|
384 | } |
---|
385 | |
---|
386 | static void |
---|
387 | gtk_item_factory_item_remove_widget (GtkWidget *widget, |
---|
388 | GtkItemFactoryItem *item) |
---|
389 | { |
---|
390 | item->widgets = g_slist_remove (item->widgets, widget); |
---|
391 | gtk_object_remove_data_by_id (GTK_OBJECT (widget), quark_item_factory); |
---|
392 | gtk_object_remove_data_by_id (GTK_OBJECT (widget), quark_item_path); |
---|
393 | } |
---|
394 | |
---|
395 | void |
---|
396 | gtk_item_factory_add_foreign (GtkWidget *accel_widget, |
---|
397 | const gchar *full_path, |
---|
398 | GtkAccelGroup *accel_group, |
---|
399 | guint keyval, |
---|
400 | GdkModifierType modifiers) |
---|
401 | { |
---|
402 | GtkItemFactoryClass *class; |
---|
403 | GtkItemFactoryItem *item; |
---|
404 | |
---|
405 | g_return_if_fail (GTK_IS_WIDGET (accel_widget)); |
---|
406 | g_return_if_fail (full_path != NULL); |
---|
407 | |
---|
408 | class = gtk_type_class (GTK_TYPE_ITEM_FACTORY); |
---|
409 | |
---|
410 | keyval = keyval != GDK_VoidSymbol ? keyval : 0; |
---|
411 | |
---|
412 | item = g_hash_table_lookup (class->item_ht, full_path); |
---|
413 | if (!item) |
---|
414 | { |
---|
415 | item = g_chunk_new (GtkItemFactoryItem, ifactory_item_chunks); |
---|
416 | |
---|
417 | item->path = g_strdup (full_path); |
---|
418 | item->accelerator_key = keyval; |
---|
419 | item->accelerator_mods = modifiers; |
---|
420 | item->modified = FALSE; |
---|
421 | item->in_propagation = FALSE; |
---|
422 | item->dummy = NULL; |
---|
423 | item->widgets = NULL; |
---|
424 | |
---|
425 | g_hash_table_insert (class->item_ht, item->path, item); |
---|
426 | } |
---|
427 | |
---|
428 | item->widgets = g_slist_prepend (item->widgets, accel_widget); |
---|
429 | gtk_signal_connect (GTK_OBJECT (accel_widget), |
---|
430 | "destroy", |
---|
431 | GTK_SIGNAL_FUNC (gtk_item_factory_item_remove_widget), |
---|
432 | item); |
---|
433 | |
---|
434 | /* set the item path for the widget |
---|
435 | */ |
---|
436 | gtk_object_set_data_by_id (GTK_OBJECT (accel_widget), quark_item_path, item->path); |
---|
437 | gtk_widget_set_name (accel_widget, item->path); |
---|
438 | if (accel_group) |
---|
439 | { |
---|
440 | gtk_accel_group_ref (accel_group); |
---|
441 | gtk_object_set_data_by_id_full (GTK_OBJECT (accel_widget), |
---|
442 | quark_accel_group, |
---|
443 | accel_group, |
---|
444 | (GtkDestroyNotify) gtk_accel_group_unref); |
---|
445 | } |
---|
446 | else |
---|
447 | gtk_object_set_data_by_id (GTK_OBJECT (accel_widget), quark_accel_group, NULL); |
---|
448 | |
---|
449 | /* install defined accelerators |
---|
450 | */ |
---|
451 | if (gtk_signal_lookup ("activate", GTK_OBJECT_TYPE (accel_widget))) |
---|
452 | { |
---|
453 | if (item->accelerator_key && accel_group) |
---|
454 | gtk_widget_add_accelerator (accel_widget, |
---|
455 | "activate", |
---|
456 | accel_group, |
---|
457 | item->accelerator_key, |
---|
458 | item->accelerator_mods, |
---|
459 | GTK_ACCEL_VISIBLE); |
---|
460 | else |
---|
461 | gtk_widget_remove_accelerators (accel_widget, |
---|
462 | "activate", |
---|
463 | TRUE); |
---|
464 | } |
---|
465 | |
---|
466 | /* keep track of accelerator changes |
---|
467 | */ |
---|
468 | gtk_signal_connect_after (GTK_OBJECT (accel_widget), |
---|
469 | "add-accelerator", |
---|
470 | GTK_SIGNAL_FUNC (gtk_item_factory_item_add_accelerator), |
---|
471 | item); |
---|
472 | gtk_signal_connect_after (GTK_OBJECT (accel_widget), |
---|
473 | "remove-accelerator", |
---|
474 | GTK_SIGNAL_FUNC (gtk_item_factory_item_remove_accelerator), |
---|
475 | item); |
---|
476 | } |
---|
477 | |
---|
478 | static void |
---|
479 | ifactory_cb_data_free (gpointer mem) |
---|
480 | { |
---|
481 | g_mem_chunk_free (ifactory_cb_data_chunks, mem); |
---|
482 | } |
---|
483 | |
---|
484 | static void |
---|
485 | gtk_item_factory_add_item (GtkItemFactory *ifactory, |
---|
486 | const gchar *path, |
---|
487 | const gchar *accelerator, |
---|
488 | GtkItemFactoryCallback callback, |
---|
489 | guint callback_action, |
---|
490 | gpointer callback_data, |
---|
491 | guint callback_type, |
---|
492 | gchar *item_type, |
---|
493 | GtkWidget *widget) |
---|
494 | { |
---|
495 | GtkItemFactoryClass *class; |
---|
496 | GtkItemFactoryItem *item; |
---|
497 | gchar *fpath; |
---|
498 | guint keyval, mods; |
---|
499 | |
---|
500 | g_return_if_fail (widget != NULL); |
---|
501 | g_return_if_fail (item_type != NULL); |
---|
502 | |
---|
503 | class = GTK_ITEM_FACTORY_CLASS (GTK_OBJECT (ifactory)->klass); |
---|
504 | |
---|
505 | /* set accelerator group on menu widgets |
---|
506 | */ |
---|
507 | if (GTK_IS_MENU (widget)) |
---|
508 | gtk_menu_set_accel_group ((GtkMenu*) widget, ifactory->accel_group); |
---|
509 | |
---|
510 | /* connect callback if neccessary |
---|
511 | */ |
---|
512 | if (callback) |
---|
513 | { |
---|
514 | GtkIFCBData *data; |
---|
515 | |
---|
516 | data = g_chunk_new (GtkIFCBData, ifactory_cb_data_chunks); |
---|
517 | data->func = callback; |
---|
518 | data->callback_type = callback_type; |
---|
519 | data->func_data = callback_data; |
---|
520 | data->callback_action = callback_action; |
---|
521 | |
---|
522 | gtk_object_weakref (GTK_OBJECT (widget), |
---|
523 | ifactory_cb_data_free, |
---|
524 | data); |
---|
525 | gtk_signal_connect (GTK_OBJECT (widget), |
---|
526 | "activate", |
---|
527 | GTK_SIGNAL_FUNC (gtk_item_factory_callback_marshal), |
---|
528 | data); |
---|
529 | } |
---|
530 | |
---|
531 | /* link the widget into its item-entry |
---|
532 | * and keep back pointer on both the item factory and the widget |
---|
533 | */ |
---|
534 | gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_action, GUINT_TO_POINTER (callback_action)); |
---|
535 | gtk_object_set_data_by_id (GTK_OBJECT (widget), quark_item_factory, ifactory); |
---|
536 | if (accelerator) |
---|
537 | gtk_accelerator_parse (accelerator, &keyval, &mods); |
---|
538 | else |
---|
539 | { |
---|
540 | keyval = 0; |
---|
541 | mods = 0; |
---|
542 | } |
---|
543 | fpath = g_strconcat (ifactory->path, path, NULL); |
---|
544 | gtk_item_factory_add_foreign (widget, fpath, ifactory->accel_group, keyval, mods); |
---|
545 | item = g_hash_table_lookup (class->item_ht, fpath); |
---|
546 | g_free (fpath); |
---|
547 | |
---|
548 | g_return_if_fail (item != NULL); |
---|
549 | |
---|
550 | if (!g_slist_find (ifactory->items, item)) |
---|
551 | ifactory->items = g_slist_prepend (ifactory->items, item); |
---|
552 | } |
---|
553 | |
---|
554 | void |
---|
555 | gtk_item_factory_construct (GtkItemFactory *ifactory, |
---|
556 | GtkType container_type, |
---|
557 | const gchar *path, |
---|
558 | GtkAccelGroup *accel_group) |
---|
559 | { |
---|
560 | guint len; |
---|
561 | |
---|
562 | g_return_if_fail (ifactory != NULL); |
---|
563 | g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory)); |
---|
564 | g_return_if_fail (ifactory->accel_group == NULL); |
---|
565 | g_return_if_fail (path != NULL); |
---|
566 | if (!gtk_type_is_a (container_type, GTK_TYPE_OPTION_MENU)) |
---|
567 | g_return_if_fail (gtk_type_is_a (container_type, GTK_TYPE_MENU_SHELL)); |
---|
568 | |
---|
569 | len = strlen (path); |
---|
570 | |
---|
571 | if (path[0] != '<' && path[len - 1] != '>') |
---|
572 | { |
---|
573 | g_warning ("GtkItemFactory: invalid factory path `%s'", path); |
---|
574 | return; |
---|
575 | } |
---|
576 | |
---|
577 | if (accel_group) |
---|
578 | { |
---|
579 | ifactory->accel_group = accel_group; |
---|
580 | gtk_accel_group_ref (ifactory->accel_group); |
---|
581 | } |
---|
582 | else |
---|
583 | ifactory->accel_group = gtk_accel_group_new (); |
---|
584 | |
---|
585 | ifactory->path = g_strdup (path); |
---|
586 | ifactory->widget = |
---|
587 | gtk_widget_new (container_type, |
---|
588 | "GtkObject::signal::destroy", gtk_widget_destroyed, &ifactory->widget, |
---|
589 | NULL); |
---|
590 | gtk_object_ref (GTK_OBJECT (ifactory)); |
---|
591 | gtk_object_sink (GTK_OBJECT (ifactory)); |
---|
592 | |
---|
593 | gtk_item_factory_add_item (ifactory, |
---|
594 | "", NULL, |
---|
595 | NULL, 0, NULL, 0, |
---|
596 | ITEM_FACTORY_STRING, |
---|
597 | ifactory->widget); |
---|
598 | } |
---|
599 | |
---|
600 | GtkItemFactory* |
---|
601 | gtk_item_factory_from_path (const gchar *path) |
---|
602 | { |
---|
603 | GtkItemFactoryClass *class; |
---|
604 | GtkItemFactoryItem *item; |
---|
605 | gchar *fname; |
---|
606 | guint i; |
---|
607 | |
---|
608 | g_return_val_if_fail (path != NULL, NULL); |
---|
609 | g_return_val_if_fail (path[0] == '<', NULL); |
---|
610 | |
---|
611 | class = gtk_type_class (GTK_TYPE_ITEM_FACTORY); |
---|
612 | |
---|
613 | i = 0; |
---|
614 | while (path[i] && path[i] != '>') |
---|
615 | i++; |
---|
616 | if (path[i] != '>') |
---|
617 | { |
---|
618 | g_warning ("gtk_item_factory_from_path(): invalid factory path \"%s\"", |
---|
619 | path); |
---|
620 | return NULL; |
---|
621 | } |
---|
622 | fname = g_new (gchar, i + 2); |
---|
623 | g_memmove (fname, path, i + 1); |
---|
624 | fname[i + 1] = 0; |
---|
625 | |
---|
626 | item = g_hash_table_lookup (class->item_ht, fname); |
---|
627 | |
---|
628 | g_free (fname); |
---|
629 | |
---|
630 | if (item && item->widgets) |
---|
631 | return gtk_item_factory_from_widget (item->widgets->data); |
---|
632 | |
---|
633 | return NULL; |
---|
634 | } |
---|
635 | |
---|
636 | static void |
---|
637 | gtk_item_factory_destroy (GtkObject *object) |
---|
638 | { |
---|
639 | GtkItemFactory *ifactory; |
---|
640 | GSList *slist; |
---|
641 | |
---|
642 | g_return_if_fail (object != NULL); |
---|
643 | g_return_if_fail (GTK_IS_ITEM_FACTORY (object)); |
---|
644 | |
---|
645 | ifactory = (GtkItemFactory*) object; |
---|
646 | |
---|
647 | if (ifactory->widget) |
---|
648 | { |
---|
649 | GtkObject *dobj; |
---|
650 | |
---|
651 | dobj = GTK_OBJECT (ifactory->widget); |
---|
652 | |
---|
653 | gtk_object_ref (dobj); |
---|
654 | gtk_object_sink (dobj); |
---|
655 | gtk_object_destroy (dobj); |
---|
656 | gtk_object_unref (dobj); |
---|
657 | |
---|
658 | ifactory->widget = NULL; |
---|
659 | } |
---|
660 | |
---|
661 | for (slist = ifactory->items; slist; slist = slist->next) |
---|
662 | { |
---|
663 | GtkItemFactoryItem *item = slist->data; |
---|
664 | GSList *link; |
---|
665 | |
---|
666 | for (link = item->widgets; link; link = link->next) |
---|
667 | if (gtk_object_get_data_by_id (link->data, quark_item_factory) == ifactory) |
---|
668 | gtk_object_remove_data_by_id (link->data, quark_item_factory); |
---|
669 | } |
---|
670 | g_slist_free (ifactory->items); |
---|
671 | ifactory->items = NULL; |
---|
672 | |
---|
673 | parent_class->destroy (object); |
---|
674 | } |
---|
675 | |
---|
676 | static void |
---|
677 | gtk_item_factory_finalize (GtkObject *object) |
---|
678 | { |
---|
679 | GtkItemFactory *ifactory; |
---|
680 | |
---|
681 | g_return_if_fail (object != NULL); |
---|
682 | g_return_if_fail (GTK_IS_ITEM_FACTORY (object)); |
---|
683 | |
---|
684 | ifactory = GTK_ITEM_FACTORY (object); |
---|
685 | |
---|
686 | gtk_accel_group_unref (ifactory->accel_group); |
---|
687 | g_free (ifactory->path); |
---|
688 | g_assert (ifactory->widget == NULL); |
---|
689 | |
---|
690 | if (ifactory->translate_notify) |
---|
691 | ifactory->translate_notify (ifactory->translate_data); |
---|
692 | |
---|
693 | parent_class->finalize (object); |
---|
694 | } |
---|
695 | |
---|
696 | GtkItemFactory* |
---|
697 | gtk_item_factory_from_widget (GtkWidget *widget) |
---|
698 | { |
---|
699 | g_return_val_if_fail (widget != NULL, NULL); |
---|
700 | g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); |
---|
701 | |
---|
702 | return gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_item_factory); |
---|
703 | } |
---|
704 | |
---|
705 | gchar* |
---|
706 | gtk_item_factory_path_from_widget (GtkWidget *widget) |
---|
707 | { |
---|
708 | g_return_val_if_fail (widget != NULL, NULL); |
---|
709 | g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); |
---|
710 | |
---|
711 | return gtk_object_get_data_by_id (GTK_OBJECT (widget), quark_item_path); |
---|
712 | } |
---|
713 | |
---|
714 | static void |
---|
715 | gtk_item_factory_foreach (gpointer hash_key, |
---|
716 | gpointer value, |
---|
717 | gpointer user_data) |
---|
718 | { |
---|
719 | GtkItemFactoryItem *item; |
---|
720 | GtkIFDumpData *data; |
---|
721 | gchar *string; |
---|
722 | gchar *name; |
---|
723 | gchar comment_prefix[2] = "\000\000"; |
---|
724 | |
---|
725 | item = value; |
---|
726 | data = user_data; |
---|
727 | |
---|
728 | if (data->pspec && !gtk_pattern_match_string (data->pspec, item->path)) |
---|
729 | return; |
---|
730 | |
---|
731 | comment_prefix[0] = gtk_item_factory_class->cpair_comment_single[0]; |
---|
732 | |
---|
733 | name = gtk_accelerator_name (item->accelerator_key, item->accelerator_mods); |
---|
734 | string = g_strconcat (item->modified ? "" : comment_prefix, |
---|
735 | "(menu-path \"", |
---|
736 | hash_key, |
---|
737 | "\" \"", |
---|
738 | name, |
---|
739 | "\")", |
---|
740 | NULL); |
---|
741 | g_free (name); |
---|
742 | |
---|
743 | data->print_func (data->func_data, string); |
---|
744 | |
---|
745 | g_free (string); |
---|
746 | } |
---|
747 | |
---|
748 | void |
---|
749 | gtk_item_factory_dump_items (GtkPatternSpec *path_pspec, |
---|
750 | gboolean modified_only, |
---|
751 | GtkPrintFunc print_func, |
---|
752 | gpointer func_data) |
---|
753 | { |
---|
754 | GtkIFDumpData data; |
---|
755 | |
---|
756 | g_return_if_fail (print_func != NULL); |
---|
757 | |
---|
758 | if (!gtk_item_factory_class) |
---|
759 | gtk_type_class (GTK_TYPE_ITEM_FACTORY); |
---|
760 | |
---|
761 | data.print_func = print_func; |
---|
762 | data.func_data = func_data; |
---|
763 | data.modified_only = (modified_only != FALSE); |
---|
764 | data.pspec = path_pspec; |
---|
765 | |
---|
766 | g_hash_table_foreach (gtk_item_factory_class->item_ht, gtk_item_factory_foreach, &data); |
---|
767 | } |
---|
768 | |
---|
769 | void |
---|
770 | gtk_item_factory_print_func (gpointer FILE_pointer, |
---|
771 | gchar *string) |
---|
772 | { |
---|
773 | FILE *f_out = FILE_pointer; |
---|
774 | |
---|
775 | g_return_if_fail (FILE_pointer != NULL); |
---|
776 | g_return_if_fail (string != NULL); |
---|
777 | |
---|
778 | fputs (string, f_out); |
---|
779 | fputc ('\n', f_out); |
---|
780 | } |
---|
781 | |
---|
782 | void |
---|
783 | gtk_item_factory_dump_rc (const gchar *file_name, |
---|
784 | GtkPatternSpec *path_pspec, |
---|
785 | gboolean modified_only) |
---|
786 | { |
---|
787 | FILE *f_out; |
---|
788 | |
---|
789 | g_return_if_fail (file_name != NULL); |
---|
790 | |
---|
791 | f_out = fopen (file_name, "w"); |
---|
792 | if (!f_out) |
---|
793 | return; |
---|
794 | |
---|
795 | fputs ("; ", f_out); |
---|
796 | if (g_get_prgname ()) |
---|
797 | fputs (g_get_prgname (), f_out); |
---|
798 | fputs (" GtkItemFactory rc-file -*- scheme -*-\n", f_out); |
---|
799 | fputs ("; this file is an automated menu-path dump\n", f_out); |
---|
800 | fputs (";\n", f_out); |
---|
801 | |
---|
802 | gtk_item_factory_dump_items (path_pspec, |
---|
803 | modified_only, |
---|
804 | gtk_item_factory_print_func, |
---|
805 | f_out); |
---|
806 | |
---|
807 | fclose (f_out); |
---|
808 | } |
---|
809 | |
---|
810 | void |
---|
811 | gtk_item_factory_create_items (GtkItemFactory *ifactory, |
---|
812 | guint n_entries, |
---|
813 | GtkItemFactoryEntry *entries, |
---|
814 | gpointer callback_data) |
---|
815 | { |
---|
816 | gtk_item_factory_create_items_ac (ifactory, n_entries, entries, callback_data, 1); |
---|
817 | } |
---|
818 | |
---|
819 | void |
---|
820 | gtk_item_factory_create_items_ac (GtkItemFactory *ifactory, |
---|
821 | guint n_entries, |
---|
822 | GtkItemFactoryEntry *entries, |
---|
823 | gpointer callback_data, |
---|
824 | guint callback_type) |
---|
825 | { |
---|
826 | guint i; |
---|
827 | |
---|
828 | g_return_if_fail (ifactory != NULL); |
---|
829 | g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory)); |
---|
830 | g_return_if_fail (callback_type >= 1 && callback_type <= 2); |
---|
831 | |
---|
832 | if (n_entries == 0) |
---|
833 | return; |
---|
834 | |
---|
835 | g_return_if_fail (entries != NULL); |
---|
836 | |
---|
837 | for (i = 0; i < n_entries; i++) |
---|
838 | gtk_item_factory_create_item (ifactory, entries + i, callback_data, callback_type); |
---|
839 | } |
---|
840 | |
---|
841 | GtkWidget* |
---|
842 | gtk_item_factory_get_widget (GtkItemFactory *ifactory, |
---|
843 | const gchar *path) |
---|
844 | { |
---|
845 | GtkItemFactoryClass *class; |
---|
846 | GtkItemFactoryItem *item; |
---|
847 | |
---|
848 | g_return_val_if_fail (GTK_IS_ITEM_FACTORY (ifactory), NULL); |
---|
849 | g_return_val_if_fail (path != NULL, NULL); |
---|
850 | |
---|
851 | class = GTK_ITEM_FACTORY_CLASS (GTK_OBJECT (ifactory)->klass); |
---|
852 | |
---|
853 | if (path[0] == '<') |
---|
854 | item = g_hash_table_lookup (class->item_ht, (gpointer) path); |
---|
855 | else |
---|
856 | { |
---|
857 | gchar *fpath; |
---|
858 | |
---|
859 | fpath = g_strconcat (ifactory->path, path, NULL); |
---|
860 | item = g_hash_table_lookup (class->item_ht, fpath); |
---|
861 | g_free (fpath); |
---|
862 | } |
---|
863 | |
---|
864 | if (item) |
---|
865 | { |
---|
866 | GSList *slist; |
---|
867 | |
---|
868 | for (slist = item->widgets; slist; slist = slist->next) |
---|
869 | { |
---|
870 | if (gtk_item_factory_from_widget (slist->data) == ifactory) |
---|
871 | return slist->data; |
---|
872 | } |
---|
873 | } |
---|
874 | |
---|
875 | return NULL; |
---|
876 | } |
---|
877 | |
---|
878 | GtkWidget* |
---|
879 | gtk_item_factory_get_widget_by_action (GtkItemFactory *ifactory, |
---|
880 | guint action) |
---|
881 | { |
---|
882 | GSList *slist; |
---|
883 | |
---|
884 | g_return_val_if_fail (GTK_IS_ITEM_FACTORY (ifactory), NULL); |
---|
885 | |
---|
886 | for (slist = ifactory->items; slist; slist = slist->next) |
---|
887 | { |
---|
888 | GtkItemFactoryItem *item = slist->data; |
---|
889 | GSList *link; |
---|
890 | |
---|
891 | for (link = item->widgets; link; link = link->next) |
---|
892 | if (gtk_object_get_data_by_id (link->data, quark_item_factory) == ifactory && |
---|
893 | gtk_object_get_data_by_id (link->data, quark_action) == GUINT_TO_POINTER (action)) |
---|
894 | return link->data; |
---|
895 | } |
---|
896 | |
---|
897 | return NULL; |
---|
898 | } |
---|
899 | |
---|
900 | GtkWidget* |
---|
901 | gtk_item_factory_get_item (GtkItemFactory *ifactory, |
---|
902 | const gchar *path) |
---|
903 | { |
---|
904 | GtkWidget *widget; |
---|
905 | |
---|
906 | g_return_val_if_fail (GTK_IS_ITEM_FACTORY (ifactory), NULL); |
---|
907 | g_return_val_if_fail (path != NULL, NULL); |
---|
908 | |
---|
909 | widget = gtk_item_factory_get_widget (ifactory, path); |
---|
910 | |
---|
911 | if (GTK_IS_MENU (widget)) |
---|
912 | widget = gtk_menu_get_attach_widget (GTK_MENU (widget)); |
---|
913 | |
---|
914 | return GTK_IS_ITEM (widget) ? widget : NULL; |
---|
915 | } |
---|
916 | |
---|
917 | GtkWidget* |
---|
918 | gtk_item_factory_get_item_by_action (GtkItemFactory *ifactory, |
---|
919 | guint action) |
---|
920 | { |
---|
921 | GtkWidget *widget; |
---|
922 | |
---|
923 | g_return_val_if_fail (GTK_IS_ITEM_FACTORY (ifactory), NULL); |
---|
924 | |
---|
925 | widget = gtk_item_factory_get_widget_by_action (ifactory, action); |
---|
926 | |
---|
927 | if (GTK_IS_MENU (widget)) |
---|
928 | widget = gtk_menu_get_attach_widget (GTK_MENU (widget)); |
---|
929 | |
---|
930 | return GTK_IS_ITEM (widget) ? widget : NULL; |
---|
931 | } |
---|
932 | |
---|
933 | static gboolean |
---|
934 | gtk_item_factory_parse_path (GtkItemFactory *ifactory, |
---|
935 | gchar *str, |
---|
936 | gchar **path, |
---|
937 | gchar **parent_path, |
---|
938 | gchar **item) |
---|
939 | { |
---|
940 | gchar *translation; |
---|
941 | gchar *p, *q; |
---|
942 | |
---|
943 | *path = g_strdup (str); |
---|
944 | |
---|
945 | p = q = *path; |
---|
946 | while (*p) |
---|
947 | { |
---|
948 | if (*p != '_') |
---|
949 | { |
---|
950 | *q++ = *p; |
---|
951 | } |
---|
952 | p++; |
---|
953 | } |
---|
954 | *q = 0; |
---|
955 | |
---|
956 | *parent_path = g_strdup (*path); |
---|
957 | p = strrchr (*parent_path, '/'); |
---|
958 | if (!p) |
---|
959 | { |
---|
960 | g_warning ("GtkItemFactory: invalid entry path `%s'", str); |
---|
961 | return FALSE; |
---|
962 | } |
---|
963 | *p = 0; |
---|
964 | |
---|
965 | if (ifactory->translate_func) |
---|
966 | translation = ifactory->translate_func (str, ifactory->translate_data); |
---|
967 | else |
---|
968 | translation = str; |
---|
969 | |
---|
970 | p = strrchr (translation, '/'); |
---|
971 | if (p) |
---|
972 | p++; |
---|
973 | else |
---|
974 | p = translation; |
---|
975 | |
---|
976 | *item = g_strdup (p); |
---|
977 | |
---|
978 | return TRUE; |
---|
979 | } |
---|
980 | |
---|
981 | void |
---|
982 | gtk_item_factory_create_item (GtkItemFactory *ifactory, |
---|
983 | GtkItemFactoryEntry *entry, |
---|
984 | gpointer callback_data, |
---|
985 | guint callback_type) |
---|
986 | { |
---|
987 | GtkOptionMenu *option_menu = NULL; |
---|
988 | GtkWidget *parent; |
---|
989 | GtkWidget *widget; |
---|
990 | GSList *radio_group; |
---|
991 | gchar *name; |
---|
992 | gchar *parent_path; |
---|
993 | gchar *path; |
---|
994 | guint accel_key; |
---|
995 | guint type_id; |
---|
996 | GtkType type; |
---|
997 | gchar *item_type_path; |
---|
998 | |
---|
999 | g_return_if_fail (ifactory != NULL); |
---|
1000 | g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory)); |
---|
1001 | g_return_if_fail (entry != NULL); |
---|
1002 | g_return_if_fail (entry->path != NULL); |
---|
1003 | g_return_if_fail (entry->path[0] == '/'); |
---|
1004 | g_return_if_fail (callback_type >= 1 && callback_type <= 2); |
---|
1005 | |
---|
1006 | if (!entry->item_type || |
---|
1007 | entry->item_type[0] == 0) |
---|
1008 | { |
---|
1009 | item_type_path = "<Item>"; |
---|
1010 | type_id = quark_type_item; |
---|
1011 | } |
---|
1012 | else |
---|
1013 | { |
---|
1014 | item_type_path = entry->item_type; |
---|
1015 | type_id = gtk_object_data_try_key (item_type_path); |
---|
1016 | } |
---|
1017 | |
---|
1018 | radio_group = NULL; |
---|
1019 | if (type_id == quark_type_item) |
---|
1020 | type = GTK_TYPE_MENU_ITEM; |
---|
1021 | else if (type_id == quark_type_title) |
---|
1022 | type = GTK_TYPE_MENU_ITEM; |
---|
1023 | else if (type_id == quark_type_radio_item) |
---|
1024 | type = GTK_TYPE_RADIO_MENU_ITEM; |
---|
1025 | else if (type_id == quark_type_check_item) |
---|
1026 | type = GTK_TYPE_CHECK_MENU_ITEM; |
---|
1027 | else if (type_id == quark_type_tearoff_item) |
---|
1028 | type = GTK_TYPE_TEAROFF_MENU_ITEM; |
---|
1029 | else if (type_id == quark_type_toggle_item) |
---|
1030 | type = GTK_TYPE_CHECK_MENU_ITEM; |
---|
1031 | else if (type_id == quark_type_separator_item) |
---|
1032 | type = GTK_TYPE_MENU_ITEM; |
---|
1033 | else if (type_id == quark_type_branch) |
---|
1034 | type = GTK_TYPE_MENU_ITEM; |
---|
1035 | else if (type_id == quark_type_last_branch) |
---|
1036 | type = GTK_TYPE_MENU_ITEM; |
---|
1037 | else |
---|
1038 | { |
---|
1039 | GtkWidget *radio_link; |
---|
1040 | |
---|
1041 | radio_link = gtk_item_factory_get_widget (ifactory, item_type_path); |
---|
1042 | if (radio_link && GTK_IS_RADIO_MENU_ITEM (radio_link)) |
---|
1043 | { |
---|
1044 | type = GTK_TYPE_RADIO_MENU_ITEM; |
---|
1045 | radio_group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (radio_link)); |
---|
1046 | } |
---|
1047 | else |
---|
1048 | { |
---|
1049 | g_warning ("GtkItemFactory: entry path `%s' has invalid type `%s'", |
---|
1050 | entry->path, |
---|
1051 | item_type_path); |
---|
1052 | return; |
---|
1053 | } |
---|
1054 | } |
---|
1055 | |
---|
1056 | if (!gtk_item_factory_parse_path (ifactory, entry->path, |
---|
1057 | &path, &parent_path, &name)) |
---|
1058 | return; |
---|
1059 | |
---|
1060 | parent = gtk_item_factory_get_widget (ifactory, parent_path); |
---|
1061 | if (!parent) |
---|
1062 | { |
---|
1063 | GtkItemFactoryEntry pentry; |
---|
1064 | gchar *ppath, *p; |
---|
1065 | |
---|
1066 | ppath = g_strdup (entry->path); |
---|
1067 | p = strrchr (ppath, '/'); |
---|
1068 | g_return_if_fail (p != NULL); |
---|
1069 | *p = 0; |
---|
1070 | pentry.path = ppath; |
---|
1071 | pentry.accelerator = NULL; |
---|
1072 | pentry.callback = NULL; |
---|
1073 | pentry.callback_action = 0; |
---|
1074 | pentry.item_type = "<Branch>"; |
---|
1075 | |
---|
1076 | gtk_item_factory_create_item (ifactory, &pentry, NULL, 1); |
---|
1077 | g_free (ppath); |
---|
1078 | |
---|
1079 | parent = gtk_item_factory_get_widget (ifactory, parent_path); |
---|
1080 | g_return_if_fail (parent != NULL); |
---|
1081 | } |
---|
1082 | g_free (parent_path); |
---|
1083 | |
---|
1084 | if (GTK_IS_OPTION_MENU (parent)) |
---|
1085 | { |
---|
1086 | option_menu = GTK_OPTION_MENU (parent); |
---|
1087 | if (!option_menu->menu) |
---|
1088 | gtk_option_menu_set_menu (option_menu, gtk_widget_new (GTK_TYPE_MENU, NULL)); |
---|
1089 | parent = option_menu->menu; |
---|
1090 | } |
---|
1091 | |
---|
1092 | g_return_if_fail (GTK_IS_CONTAINER (parent)); |
---|
1093 | |
---|
1094 | widget = gtk_widget_new (type, |
---|
1095 | "GtkWidget::visible", TRUE, |
---|
1096 | "GtkWidget::sensitive", (type_id != quark_type_separator_item && |
---|
1097 | type_id != quark_type_title), |
---|
1098 | "GtkWidget::parent", parent, |
---|
1099 | NULL); |
---|
1100 | if (option_menu && !option_menu->menu_item) |
---|
1101 | gtk_option_menu_set_history (option_menu, 0); |
---|
1102 | |
---|
1103 | if (type == GTK_TYPE_RADIO_MENU_ITEM) |
---|
1104 | gtk_radio_menu_item_set_group (GTK_RADIO_MENU_ITEM (widget), radio_group); |
---|
1105 | if (GTK_IS_CHECK_MENU_ITEM (widget)) |
---|
1106 | gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (widget), TRUE); |
---|
1107 | |
---|
1108 | /* install underline accelerators for this item |
---|
1109 | */ |
---|
1110 | if (type_id != quark_type_separator_item && |
---|
1111 | type_id != quark_type_tearoff_item && |
---|
1112 | *name) |
---|
1113 | { |
---|
1114 | GtkWidget *label; |
---|
1115 | |
---|
1116 | label = gtk_widget_new (GTK_TYPE_ACCEL_LABEL, |
---|
1117 | "GtkWidget::visible", TRUE, |
---|
1118 | "GtkWidget::parent", widget, |
---|
1119 | "GtkAccelLabel::accel_widget", widget, |
---|
1120 | "GtkMisc::xalign", 0.0, |
---|
1121 | NULL); |
---|
1122 | |
---|
1123 | accel_key = gtk_label_parse_uline (GTK_LABEL (label), name); |
---|
1124 | |
---|
1125 | if (accel_key != GDK_VoidSymbol) |
---|
1126 | { |
---|
1127 | if (GTK_IS_MENU_BAR (parent)) |
---|
1128 | gtk_widget_add_accelerator (widget, |
---|
1129 | "activate_item", |
---|
1130 | ifactory->accel_group, |
---|
1131 | accel_key, GDK_MOD1_MASK, |
---|
1132 | GTK_ACCEL_LOCKED); |
---|
1133 | |
---|
1134 | if (GTK_IS_MENU (parent)) |
---|
1135 | gtk_widget_add_accelerator (widget, |
---|
1136 | "activate_item", |
---|
1137 | gtk_menu_ensure_uline_accel_group (GTK_MENU (parent)), |
---|
1138 | accel_key, 0, |
---|
1139 | GTK_ACCEL_LOCKED); |
---|
1140 | } |
---|
1141 | } |
---|
1142 | |
---|
1143 | g_free (name); |
---|
1144 | |
---|
1145 | if (type_id == quark_type_branch || |
---|
1146 | type_id == quark_type_last_branch) |
---|
1147 | { |
---|
1148 | if (entry->callback) |
---|
1149 | g_warning ("gtk_item_factory_create_item(): Can't specify a callback on a branch: \"%s\"", |
---|
1150 | entry->path); |
---|
1151 | |
---|
1152 | if (type_id == quark_type_last_branch) |
---|
1153 | gtk_menu_item_right_justify (GTK_MENU_ITEM (widget)); |
---|
1154 | |
---|
1155 | parent = widget; |
---|
1156 | widget = gtk_widget_new (GTK_TYPE_MENU, |
---|
1157 | NULL); |
---|
1158 | |
---|
1159 | gtk_menu_item_set_submenu (GTK_MENU_ITEM (parent), widget); |
---|
1160 | } |
---|
1161 | |
---|
1162 | gtk_item_factory_add_item (ifactory, |
---|
1163 | path, entry->accelerator, |
---|
1164 | (type_id == quark_type_branch || |
---|
1165 | type_id == quark_type_last_branch) ? |
---|
1166 | (GtkItemFactoryCallback) NULL : entry->callback, |
---|
1167 | entry->callback_action, callback_data, |
---|
1168 | callback_type, |
---|
1169 | item_type_path, |
---|
1170 | widget); |
---|
1171 | |
---|
1172 | g_free (path); |
---|
1173 | } |
---|
1174 | |
---|
1175 | void |
---|
1176 | gtk_item_factory_create_menu_entries (guint n_entries, |
---|
1177 | GtkMenuEntry *entries) |
---|
1178 | { |
---|
1179 | static GtkPatternSpec pspec_separator = { 42, 0 }; |
---|
1180 | static GtkPatternSpec pspec_check = { 42, 0 }; |
---|
1181 | guint i; |
---|
1182 | |
---|
1183 | if (!n_entries) |
---|
1184 | return; |
---|
1185 | g_return_if_fail (entries != NULL); |
---|
1186 | |
---|
1187 | if (pspec_separator.pattern_length == 0) |
---|
1188 | { |
---|
1189 | gtk_pattern_spec_init (&pspec_separator, "*<separator>*"); |
---|
1190 | gtk_pattern_spec_init (&pspec_check, "*<check>*"); |
---|
1191 | } |
---|
1192 | |
---|
1193 | for (i = 0; i < n_entries; i++) |
---|
1194 | { |
---|
1195 | GtkItemFactory *ifactory; |
---|
1196 | GtkItemFactoryEntry entry; |
---|
1197 | gchar *path; |
---|
1198 | gchar *cpath; |
---|
1199 | |
---|
1200 | path = entries[i].path; |
---|
1201 | ifactory = gtk_item_factory_from_path (path); |
---|
1202 | if (!ifactory) |
---|
1203 | { |
---|
1204 | g_warning ("gtk_item_factory_create_menu_entries(): " |
---|
1205 | "entry[%u] refers to unknown item factory: \"%s\"", |
---|
1206 | i, entries[i].path); |
---|
1207 | continue; |
---|
1208 | } |
---|
1209 | |
---|
1210 | while (*path != '>') |
---|
1211 | path++; |
---|
1212 | path++; |
---|
1213 | cpath = NULL; |
---|
1214 | |
---|
1215 | entry.path = path; |
---|
1216 | entry.accelerator = entries[i].accelerator; |
---|
1217 | entry.callback = entries[i].callback; |
---|
1218 | entry.callback_action = 0; |
---|
1219 | if (gtk_pattern_match_string (&pspec_separator, path)) |
---|
1220 | entry.item_type = "<Separator>"; |
---|
1221 | else if (!gtk_pattern_match_string (&pspec_check, path)) |
---|
1222 | entry.item_type = NULL; |
---|
1223 | else |
---|
1224 | { |
---|
1225 | gboolean in_brace = FALSE; |
---|
1226 | gchar *c; |
---|
1227 | |
---|
1228 | cpath = g_new (gchar, strlen (path)); |
---|
1229 | c = cpath; |
---|
1230 | while (*path != 0) |
---|
1231 | { |
---|
1232 | if (*path == '<') |
---|
1233 | in_brace = TRUE; |
---|
1234 | else if (*path == '>') |
---|
1235 | in_brace = FALSE; |
---|
1236 | else if (!in_brace) |
---|
1237 | *(c++) = *path; |
---|
1238 | path++; |
---|
1239 | } |
---|
1240 | *c = 0; |
---|
1241 | entry.item_type = "<ToggleItem>"; |
---|
1242 | entry.path = cpath; |
---|
1243 | } |
---|
1244 | |
---|
1245 | gtk_item_factory_create_item (ifactory, &entry, entries[i].callback_data, 2); |
---|
1246 | entries[i].widget = gtk_item_factory_get_widget (ifactory, entries[i].path); |
---|
1247 | g_free (cpath); |
---|
1248 | } |
---|
1249 | } |
---|
1250 | |
---|
1251 | void |
---|
1252 | gtk_item_factories_path_delete (const gchar *ifactory_path, |
---|
1253 | const gchar *path) |
---|
1254 | { |
---|
1255 | GtkItemFactoryClass *class; |
---|
1256 | GtkItemFactoryItem *item; |
---|
1257 | |
---|
1258 | g_return_if_fail (path != NULL); |
---|
1259 | |
---|
1260 | class = gtk_type_class (GTK_TYPE_ITEM_FACTORY); |
---|
1261 | |
---|
1262 | if (path[0] == '<') |
---|
1263 | item = g_hash_table_lookup (class->item_ht, (gpointer) path); |
---|
1264 | else |
---|
1265 | { |
---|
1266 | gchar *fpath; |
---|
1267 | |
---|
1268 | g_return_if_fail (ifactory_path != NULL); |
---|
1269 | |
---|
1270 | fpath = g_strconcat (ifactory_path, path, NULL); |
---|
1271 | item = g_hash_table_lookup (class->item_ht, fpath); |
---|
1272 | g_free (fpath); |
---|
1273 | } |
---|
1274 | |
---|
1275 | if (item) |
---|
1276 | { |
---|
1277 | GSList *widget_list; |
---|
1278 | GSList *slist; |
---|
1279 | |
---|
1280 | widget_list = NULL; |
---|
1281 | for (slist = item->widgets; slist; slist = slist->next) |
---|
1282 | { |
---|
1283 | GtkWidget *widget; |
---|
1284 | |
---|
1285 | widget = slist->data; |
---|
1286 | widget_list = g_slist_prepend (widget_list, widget); |
---|
1287 | gtk_widget_ref (widget); |
---|
1288 | } |
---|
1289 | |
---|
1290 | for (slist = widget_list; slist; slist = slist->next) |
---|
1291 | { |
---|
1292 | GtkWidget *widget; |
---|
1293 | |
---|
1294 | widget = slist->data; |
---|
1295 | gtk_widget_destroy (widget); |
---|
1296 | gtk_widget_unref (widget); |
---|
1297 | } |
---|
1298 | g_slist_free (widget_list); |
---|
1299 | } |
---|
1300 | } |
---|
1301 | |
---|
1302 | void |
---|
1303 | gtk_item_factory_delete_item (GtkItemFactory *ifactory, |
---|
1304 | const gchar *path) |
---|
1305 | { |
---|
1306 | GtkItemFactoryClass *class; |
---|
1307 | GtkItemFactoryItem *item; |
---|
1308 | gchar *fpath; |
---|
1309 | |
---|
1310 | g_return_if_fail (ifactory != NULL); |
---|
1311 | g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory)); |
---|
1312 | g_return_if_fail (path != NULL); |
---|
1313 | |
---|
1314 | class = GTK_ITEM_FACTORY_CLASS (GTK_OBJECT (ifactory)->klass); |
---|
1315 | |
---|
1316 | fpath = g_strconcat (ifactory->path, path, NULL); |
---|
1317 | item = g_hash_table_lookup (class->item_ht, fpath); |
---|
1318 | g_free (fpath); |
---|
1319 | |
---|
1320 | if (item) |
---|
1321 | { |
---|
1322 | GtkWidget *widget = NULL; |
---|
1323 | GSList *slist; |
---|
1324 | |
---|
1325 | for (slist = item->widgets; slist; slist = slist->next) |
---|
1326 | { |
---|
1327 | widget = slist->data; |
---|
1328 | |
---|
1329 | if (gtk_item_factory_from_widget (widget) == ifactory) |
---|
1330 | break; |
---|
1331 | } |
---|
1332 | |
---|
1333 | if (slist) |
---|
1334 | gtk_widget_destroy (widget); |
---|
1335 | } |
---|
1336 | } |
---|
1337 | |
---|
1338 | void |
---|
1339 | gtk_item_factory_delete_entry (GtkItemFactory *ifactory, |
---|
1340 | GtkItemFactoryEntry *entry) |
---|
1341 | { |
---|
1342 | g_return_if_fail (ifactory != NULL); |
---|
1343 | g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory)); |
---|
1344 | g_return_if_fail (entry != NULL); |
---|
1345 | |
---|
1346 | gtk_item_factory_delete_item (ifactory, entry->path); |
---|
1347 | } |
---|
1348 | |
---|
1349 | void |
---|
1350 | gtk_item_factory_delete_entries (GtkItemFactory *ifactory, |
---|
1351 | guint n_entries, |
---|
1352 | GtkItemFactoryEntry *entries) |
---|
1353 | { |
---|
1354 | guint i; |
---|
1355 | |
---|
1356 | g_return_if_fail (ifactory != NULL); |
---|
1357 | g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory)); |
---|
1358 | if (n_entries > 0) |
---|
1359 | g_return_if_fail (entries != NULL); |
---|
1360 | |
---|
1361 | for (i = 0; i < n_entries; i++) |
---|
1362 | gtk_item_factory_delete_item (ifactory, (entries + i)->path); |
---|
1363 | } |
---|
1364 | |
---|
1365 | typedef struct |
---|
1366 | { |
---|
1367 | guint x; |
---|
1368 | guint y; |
---|
1369 | } MenuPos; |
---|
1370 | |
---|
1371 | static void |
---|
1372 | gtk_item_factory_menu_pos (GtkMenu *menu, |
---|
1373 | gint *x, |
---|
1374 | gint *y, |
---|
1375 | gpointer func_data) |
---|
1376 | { |
---|
1377 | MenuPos *mpos = func_data; |
---|
1378 | |
---|
1379 | *x = mpos->x; |
---|
1380 | *y = mpos->y; |
---|
1381 | } |
---|
1382 | |
---|
1383 | gpointer |
---|
1384 | gtk_item_factory_popup_data_from_widget (GtkWidget *widget) |
---|
1385 | { |
---|
1386 | GtkItemFactory *ifactory; |
---|
1387 | |
---|
1388 | g_return_val_if_fail (widget != NULL, NULL); |
---|
1389 | g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); |
---|
1390 | |
---|
1391 | ifactory = gtk_item_factory_from_widget (widget); |
---|
1392 | if (ifactory) |
---|
1393 | return gtk_object_get_data_by_id (GTK_OBJECT (ifactory), quark_popup_data); |
---|
1394 | |
---|
1395 | return NULL; |
---|
1396 | } |
---|
1397 | |
---|
1398 | gpointer |
---|
1399 | gtk_item_factory_popup_data (GtkItemFactory *ifactory) |
---|
1400 | { |
---|
1401 | g_return_val_if_fail (ifactory != NULL, NULL); |
---|
1402 | g_return_val_if_fail (GTK_IS_ITEM_FACTORY (ifactory), NULL); |
---|
1403 | |
---|
1404 | return gtk_object_get_data_by_id (GTK_OBJECT (ifactory), quark_popup_data); |
---|
1405 | } |
---|
1406 | |
---|
1407 | static void |
---|
1408 | ifactory_delete_popup_data (GtkObject *object, |
---|
1409 | GtkItemFactory *ifactory) |
---|
1410 | { |
---|
1411 | gtk_signal_disconnect_by_func (object, |
---|
1412 | GTK_SIGNAL_FUNC (ifactory_delete_popup_data), |
---|
1413 | ifactory); |
---|
1414 | gtk_object_remove_data_by_id (GTK_OBJECT (ifactory), quark_popup_data); |
---|
1415 | } |
---|
1416 | |
---|
1417 | void |
---|
1418 | gtk_item_factory_popup (GtkItemFactory *ifactory, |
---|
1419 | guint x, |
---|
1420 | guint y, |
---|
1421 | guint mouse_button, |
---|
1422 | guint32 time) |
---|
1423 | { |
---|
1424 | gtk_item_factory_popup_with_data (ifactory, NULL, NULL, x, y, mouse_button, time); |
---|
1425 | } |
---|
1426 | |
---|
1427 | void |
---|
1428 | gtk_item_factory_popup_with_data (GtkItemFactory *ifactory, |
---|
1429 | gpointer popup_data, |
---|
1430 | GtkDestroyNotify destroy, |
---|
1431 | guint x, |
---|
1432 | guint y, |
---|
1433 | guint mouse_button, |
---|
1434 | guint32 time) |
---|
1435 | { |
---|
1436 | MenuPos *mpos; |
---|
1437 | |
---|
1438 | g_return_if_fail (ifactory != NULL); |
---|
1439 | g_return_if_fail (GTK_IS_ITEM_FACTORY (ifactory)); |
---|
1440 | g_return_if_fail (GTK_IS_MENU (ifactory->widget)); |
---|
1441 | |
---|
1442 | mpos = gtk_object_get_data_by_id (GTK_OBJECT (ifactory->widget), quark_if_menu_pos); |
---|
1443 | |
---|
1444 | if (!mpos) |
---|
1445 | { |
---|
1446 | mpos = g_new0 (MenuPos, 1); |
---|
1447 | gtk_object_set_data_by_id_full (GTK_OBJECT (ifactory->widget), |
---|
1448 | quark_if_menu_pos, |
---|
1449 | mpos, |
---|
1450 | g_free); |
---|
1451 | } |
---|
1452 | |
---|
1453 | mpos->x = x; |
---|
1454 | mpos->y = y; |
---|
1455 | |
---|
1456 | if (popup_data != NULL) |
---|
1457 | { |
---|
1458 | gtk_object_set_data_by_id_full (GTK_OBJECT (ifactory), |
---|
1459 | quark_popup_data, |
---|
1460 | popup_data, |
---|
1461 | destroy); |
---|
1462 | gtk_signal_connect (GTK_OBJECT (ifactory->widget), |
---|
1463 | "selection-done", |
---|
1464 | GTK_SIGNAL_FUNC (ifactory_delete_popup_data), |
---|
1465 | ifactory); |
---|
1466 | } |
---|
1467 | |
---|
1468 | gtk_menu_popup (GTK_MENU (ifactory->widget), |
---|
1469 | NULL, NULL, |
---|
1470 | gtk_item_factory_menu_pos, mpos, |
---|
1471 | mouse_button, time); |
---|
1472 | } |
---|
1473 | |
---|
1474 | static guint |
---|
1475 | gtk_item_factory_parse_menu_path (GScanner *scanner, |
---|
1476 | GtkItemFactoryClass *class) |
---|
1477 | { |
---|
1478 | GtkItemFactoryItem *item; |
---|
1479 | |
---|
1480 | g_scanner_get_next_token (scanner); |
---|
1481 | if (scanner->token != G_TOKEN_STRING) |
---|
1482 | return G_TOKEN_STRING; |
---|
1483 | |
---|
1484 | g_scanner_peek_next_token (scanner); |
---|
1485 | if (scanner->next_token != G_TOKEN_STRING) |
---|
1486 | { |
---|
1487 | g_scanner_get_next_token (scanner); |
---|
1488 | return G_TOKEN_STRING; |
---|
1489 | } |
---|
1490 | |
---|
1491 | item = g_hash_table_lookup (class->item_ht, scanner->value.v_string); |
---|
1492 | if (!item) |
---|
1493 | { |
---|
1494 | item = g_chunk_new (GtkItemFactoryItem, ifactory_item_chunks); |
---|
1495 | |
---|
1496 | item->path = g_strdup (scanner->value.v_string); |
---|
1497 | item->accelerator_key = 0; |
---|
1498 | item->accelerator_mods = 0; |
---|
1499 | item->modified = TRUE; |
---|
1500 | item->in_propagation = FALSE; |
---|
1501 | item->dummy = NULL; |
---|
1502 | item->widgets = NULL; |
---|
1503 | |
---|
1504 | g_hash_table_insert (class->item_ht, item->path, item); |
---|
1505 | } |
---|
1506 | g_scanner_get_next_token (scanner); |
---|
1507 | |
---|
1508 | if (!item->in_propagation) |
---|
1509 | { |
---|
1510 | guint old_keyval; |
---|
1511 | guint old_mods; |
---|
1512 | |
---|
1513 | old_keyval = item->accelerator_key; |
---|
1514 | old_mods = item->accelerator_mods; |
---|
1515 | gtk_accelerator_parse (scanner->value.v_string, |
---|
1516 | &item->accelerator_key, |
---|
1517 | &item->accelerator_mods); |
---|
1518 | if (old_keyval != item->accelerator_key || |
---|
1519 | old_mods != item->accelerator_mods) |
---|
1520 | { |
---|
1521 | item->modified = TRUE; |
---|
1522 | gtk_item_factory_propagate_accelerator (item, NULL); |
---|
1523 | } |
---|
1524 | } |
---|
1525 | |
---|
1526 | g_scanner_get_next_token (scanner); |
---|
1527 | if (scanner->token != ')') |
---|
1528 | return ')'; |
---|
1529 | else |
---|
1530 | return G_TOKEN_NONE; |
---|
1531 | } |
---|
1532 | |
---|
1533 | static void |
---|
1534 | gtk_item_factory_parse_statement (GScanner *scanner, |
---|
1535 | GtkItemFactoryClass *class) |
---|
1536 | { |
---|
1537 | guint expected_token; |
---|
1538 | |
---|
1539 | g_scanner_get_next_token (scanner); |
---|
1540 | |
---|
1541 | if (scanner->token == G_TOKEN_SYMBOL) |
---|
1542 | { |
---|
1543 | guint (*parser_func) (GScanner*, GtkItemFactoryClass*); |
---|
1544 | |
---|
1545 | parser_func = scanner->value.v_symbol; |
---|
1546 | |
---|
1547 | /* check whether this is a GtkItemFactory symbol. |
---|
1548 | */ |
---|
1549 | if (parser_func == gtk_item_factory_parse_menu_path) |
---|
1550 | expected_token = parser_func (scanner, class); |
---|
1551 | else |
---|
1552 | expected_token = G_TOKEN_SYMBOL; |
---|
1553 | } |
---|
1554 | else |
---|
1555 | expected_token = G_TOKEN_SYMBOL; |
---|
1556 | |
---|
1557 | /* skip rest of statement on errrors |
---|
1558 | */ |
---|
1559 | if (expected_token != G_TOKEN_NONE) |
---|
1560 | { |
---|
1561 | register guint level; |
---|
1562 | |
---|
1563 | level = 1; |
---|
1564 | if (scanner->token == ')') |
---|
1565 | level--; |
---|
1566 | if (scanner->token == '(') |
---|
1567 | level++; |
---|
1568 | |
---|
1569 | while (!g_scanner_eof (scanner) && level > 0) |
---|
1570 | { |
---|
1571 | g_scanner_get_next_token (scanner); |
---|
1572 | |
---|
1573 | if (scanner->token == '(') |
---|
1574 | level++; |
---|
1575 | else if (scanner->token == ')') |
---|
1576 | level--; |
---|
1577 | } |
---|
1578 | } |
---|
1579 | } |
---|
1580 | |
---|
1581 | void |
---|
1582 | gtk_item_factory_parse_rc_string (const gchar *rc_string) |
---|
1583 | { |
---|
1584 | GScanner *scanner; |
---|
1585 | |
---|
1586 | g_return_if_fail (rc_string != NULL); |
---|
1587 | |
---|
1588 | if (!gtk_item_factory_class) |
---|
1589 | gtk_type_class (GTK_TYPE_ITEM_FACTORY); |
---|
1590 | |
---|
1591 | ifactory_scanner_config.cpair_comment_single = gtk_item_factory_class->cpair_comment_single; |
---|
1592 | scanner = g_scanner_new (&ifactory_scanner_config); |
---|
1593 | |
---|
1594 | g_scanner_input_text (scanner, rc_string, strlen (rc_string)); |
---|
1595 | |
---|
1596 | gtk_item_factory_parse_rc_scanner (scanner); |
---|
1597 | |
---|
1598 | g_scanner_destroy (scanner); |
---|
1599 | } |
---|
1600 | |
---|
1601 | void |
---|
1602 | gtk_item_factory_parse_rc_scanner (GScanner *scanner) |
---|
1603 | { |
---|
1604 | gpointer saved_symbol; |
---|
1605 | |
---|
1606 | g_return_if_fail (scanner != NULL); |
---|
1607 | |
---|
1608 | if (!gtk_item_factory_class) |
---|
1609 | gtk_type_class (GTK_TYPE_ITEM_FACTORY); |
---|
1610 | |
---|
1611 | saved_symbol = g_scanner_lookup_symbol (scanner, "menu-path"); |
---|
1612 | g_scanner_remove_symbol (scanner, "menu-path"); |
---|
1613 | g_scanner_add_symbol (scanner, "menu-path", gtk_item_factory_parse_menu_path); |
---|
1614 | |
---|
1615 | g_scanner_peek_next_token (scanner); |
---|
1616 | |
---|
1617 | while (scanner->next_token == '(') |
---|
1618 | { |
---|
1619 | g_scanner_get_next_token (scanner); |
---|
1620 | |
---|
1621 | gtk_item_factory_parse_statement (scanner, gtk_item_factory_class); |
---|
1622 | |
---|
1623 | g_scanner_peek_next_token (scanner); |
---|
1624 | } |
---|
1625 | |
---|
1626 | g_scanner_remove_symbol (scanner, "menu-path"); |
---|
1627 | g_scanner_add_symbol (scanner, "menu-path", saved_symbol); |
---|
1628 | } |
---|
1629 | |
---|
1630 | void |
---|
1631 | gtk_item_factory_parse_rc (const gchar *file_name) |
---|
1632 | { |
---|
1633 | gint fd; |
---|
1634 | GScanner *scanner; |
---|
1635 | |
---|
1636 | g_return_if_fail (file_name != NULL); |
---|
1637 | |
---|
1638 | if (!S_ISREG (g_scanner_stat_mode (file_name))) |
---|
1639 | return; |
---|
1640 | |
---|
1641 | fd = open (file_name, O_RDONLY); |
---|
1642 | if (fd < 0) |
---|
1643 | return; |
---|
1644 | |
---|
1645 | if (!gtk_item_factory_class) |
---|
1646 | gtk_type_class (GTK_TYPE_ITEM_FACTORY); |
---|
1647 | |
---|
1648 | ifactory_scanner_config.cpair_comment_single = gtk_item_factory_class->cpair_comment_single; |
---|
1649 | scanner = g_scanner_new (&ifactory_scanner_config); |
---|
1650 | |
---|
1651 | g_scanner_input_file (scanner, fd); |
---|
1652 | |
---|
1653 | gtk_item_factory_parse_rc_scanner (scanner); |
---|
1654 | |
---|
1655 | g_scanner_destroy (scanner); |
---|
1656 | |
---|
1657 | close (fd); |
---|
1658 | } |
---|
1659 | |
---|
1660 | void |
---|
1661 | gtk_item_factory_set_translate_func (GtkItemFactory *ifactory, |
---|
1662 | GtkTranslateFunc func, |
---|
1663 | gpointer data, |
---|
1664 | GtkDestroyNotify notify) |
---|
1665 | { |
---|
1666 | g_return_if_fail (ifactory != NULL); |
---|
1667 | |
---|
1668 | if (ifactory->translate_notify) |
---|
1669 | ifactory->translate_notify (ifactory->translate_data); |
---|
1670 | |
---|
1671 | ifactory->translate_func = func; |
---|
1672 | ifactory->translate_data = data; |
---|
1673 | ifactory->translate_notify = notify; |
---|
1674 | } |
---|