source: trunk/third/libbonoboui/bonobo/bonobo-ui-sync-toolbar.c @ 18588

Revision 18588, 22.4 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18587, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2/*
3 * bonobo-ui-sync-toolbar.h: The Bonobo UI/XML sync engine for toolbars
4 *
5 * Author:
6 *      Michael Meeks (michael@ximian.com)
7 *
8 * Copyright 2000 Ximian, Inc.
9 */
10
11#include <config.h>
12#include <stdlib.h>
13#include <string.h>
14
15#include <gdk/gdkkeysyms.h>
16#include <gtk/gtk.h>
17#include <bonobo/bonobo-i18n.h>
18
19#include <bonobo/bonobo-ui-xml.h>
20#include <bonobo/bonobo-ui-util.h>
21#include <bonobo/bonobo-ui-engine.h>
22#include <bonobo/bonobo-ui-engine-config.h>
23#include <bonobo/bonobo-ui-sync.h>
24#include <bonobo/bonobo-ui-sync-toolbar.h>
25#include <bonobo/bonobo-ui-preferences.h>
26#include <bonobo/bonobo-ui-private.h>
27
28#include <bonobo/bonobo-ui-toolbar.h>
29#include <bonobo/bonobo-ui-toolbar-button-item.h>
30#include <bonobo/bonobo-ui-toolbar-toggle-button-item.h>
31#include <bonobo/bonobo-ui-toolbar-separator-item.h>
32#include <bonobo/bonobo-ui-toolbar-popup-item.h>
33#include <bonobo/bonobo-ui-toolbar-control-item.h>
34
35static GObjectClass *parent_class = NULL;
36
37static GQuark dockitem_id = 0;
38static GQuark toolitem_id = 0;
39
40#define PARENT_TYPE bonobo_ui_sync_get_type ()
41
42static BonoboUIToolbarControlDisplay
43decode_control_disp (const char *txt)
44{
45        if (!txt || !strcmp (txt, "control"))
46                return BONOBO_UI_TOOLBAR_CONTROL_DISPLAY_CONTROL;
47
48        else if (!strcmp (txt, "button"))
49                return BONOBO_UI_TOOLBAR_CONTROL_DISPLAY_BUTTON;
50
51        else if (!strcmp (txt, "none"))
52                return BONOBO_UI_TOOLBAR_CONTROL_DISPLAY_NONE;
53
54        else
55                return BONOBO_UI_TOOLBAR_CONTROL_DISPLAY_CONTROL;
56}
57
58static gboolean
59string_array_contains (char **str_array, const char *match)
60{
61        int i = 0;
62        char *string;
63
64        while ((string = str_array [i++]))
65                if (strcmp (string, match) == 0)
66                        return TRUE;
67
68        return FALSE;
69}
70
71static void
72impl_bonobo_ui_sync_toolbar_state (BonoboUISync     *sync,
73                                   BonoboUINode     *node,
74                                   BonoboUINode     *cmd_node,
75                                   GtkWidget        *widget,
76                                   GtkWidget        *parent)
77{
78        char *type, *label, *txt;
79        char *min_width;
80        char *behavior;
81        char **behavior_array;
82        gboolean priority;
83
84        /* FIXME: to debug control problem */
85        gtk_widget_show (widget);
86
87        if ((behavior = bonobo_ui_engine_get_attr (node, cmd_node, "behavior"))) {
88               
89                behavior_array = g_strsplit (behavior, ",", -1);
90                bonobo_ui_node_free_string (behavior);
91
92                bonobo_ui_toolbar_item_set_expandable (
93                        BONOBO_UI_TOOLBAR_ITEM (widget),
94                        string_array_contains (behavior_array, "expandable"));
95
96                bonobo_ui_toolbar_item_set_pack_end (
97                        BONOBO_UI_TOOLBAR_ITEM (widget),
98                        string_array_contains (behavior_array, "pack-end"));
99
100                g_strfreev (behavior_array);
101        }
102
103        if ((txt = bonobo_ui_engine_get_attr (node, cmd_node, "priority"))) {
104                priority = atoi (txt);
105                bonobo_ui_node_free_string (txt);
106        } else
107                priority = FALSE;
108
109        bonobo_ui_toolbar_item_set_want_label (
110                BONOBO_UI_TOOLBAR_ITEM (widget), priority);
111
112        type  = bonobo_ui_engine_get_attr (node, cmd_node, "type");
113        label = bonobo_ui_engine_get_attr (node, cmd_node, "label");
114       
115        if (!type || !strcmp (type, "toggle")) {
116
117                if (BONOBO_IS_UI_TOOLBAR_BUTTON_ITEM (widget) &&
118                    (bonobo_ui_node_peek_attr (node, "pixtype") ||
119                     bonobo_ui_node_peek_attr (cmd_node, "pixtype"))) {
120                        GtkWidget *image;
121                        BonoboUIToolbarButtonItem *button_item;
122
123                        button_item = (BonoboUIToolbarButtonItem *) widget;
124
125                        image = bonobo_ui_toolbar_button_item_get_image (button_item);
126                        if (!image) {
127                                image = gtk_image_new ();
128                                bonobo_ui_toolbar_button_item_set_image (button_item, image);
129                        }
130
131                        bonobo_ui_util_xml_set_image (
132                                GTK_IMAGE (image), node, cmd_node,
133                                GTK_ICON_SIZE_LARGE_TOOLBAR);
134                        gtk_widget_show (image);
135                }
136
137                if (label)
138                        bonobo_ui_toolbar_button_item_set_label (
139                                BONOBO_UI_TOOLBAR_BUTTON_ITEM (widget), label);
140        }
141
142        bonobo_ui_node_free_string (type);
143        bonobo_ui_node_free_string (label);
144
145        if (bonobo_ui_node_has_name (node, "control")) {
146                const char *txt;
147                BonoboUIToolbarControlDisplay hdisp, vdisp;
148                gboolean sensitive;
149               
150                txt = bonobo_ui_node_peek_attr (node, "hdisplay");
151                hdisp = decode_control_disp (txt);
152
153                txt = bonobo_ui_node_peek_attr (node, "vdisplay");
154                vdisp = decode_control_disp (txt);
155
156                bonobo_ui_toolbar_control_item_set_display (
157                        BONOBO_UI_TOOLBAR_CONTROL_ITEM (widget), hdisp, vdisp);
158
159                txt = bonobo_ui_node_peek_attr (node, "sensitive");
160                if (txt)
161                        sensitive = atoi (txt);
162                else
163                        sensitive = TRUE;
164
165                bonobo_ui_toolbar_control_item_set_sensitive (
166                        BONOBO_UI_TOOLBAR_CONTROL_ITEM (widget), sensitive);
167        }
168
169        if ((min_width = bonobo_ui_engine_get_attr (node, cmd_node, "min_width"))) {
170                bonobo_ui_toolbar_item_set_minimum_width (BONOBO_UI_TOOLBAR_ITEM (widget),
171                                                          atoi (min_width));
172                bonobo_ui_node_free_string (min_width);
173        }
174       
175        if ((txt = bonobo_ui_engine_get_attr (node, cmd_node, "tip"))) {
176                bonobo_ui_toolbar_item_set_tooltip (
177                        BONOBO_UI_TOOLBAR_ITEM (widget),
178                        bonobo_ui_toolbar_get_tooltips (
179                                BONOBO_UI_TOOLBAR (parent)), txt);
180
181                bonobo_ui_node_free_string (txt);
182        }
183
184        bonobo_ui_engine_queue_update (
185                sync->engine, widget, node, cmd_node);
186}
187
188static gint
189exec_verb_cb (GtkWidget *item, BonoboUIEngine *engine)
190{
191        bonobo_ui_engine_emit_verb_on_w (engine, GTK_WIDGET (item));
192
193        return FALSE;
194}
195
196static gint
197win_item_emit_ui_event (BonoboUIToolbarItem *item,
198                        const char          *state,
199                        BonoboUIEngine      *engine)
200{
201        BonoboUINode     *node = bonobo_ui_engine_widget_get_node (
202                GTK_WIDGET (item));
203
204        g_return_val_if_fail (node != NULL, FALSE);
205
206        bonobo_ui_engine_emit_event_on (engine, node, state);
207
208        return FALSE;
209}
210
211
212static GtkWidget *
213toolbar_build_control (BonoboUISync     *sync,
214                       BonoboUINode     *node,
215                       BonoboUINode     *cmd_node,
216                       int              *pos,
217                       GtkWidget        *parent)
218{
219        GtkWidget  *item;
220       
221        g_return_val_if_fail (sync != NULL, NULL);
222        g_return_val_if_fail (node != NULL, NULL);
223
224        if ((item = bonobo_ui_engine_node_get_widget (
225                sync->engine, node))) {
226
227                g_assert (item->parent == NULL);
228
229        } else {
230                Bonobo_Control control;
231
232                control = bonobo_ui_engine_node_get_object (
233                        sync->engine, node);
234
235                if (control != CORBA_OBJECT_NIL) {
236                        item = bonobo_ui_toolbar_control_item_new (control);
237
238                        if (!item)
239                                return NULL;
240
241                        bonobo_ui_engine_stamp_custom (
242                                sync->engine, node);
243                } else
244                        return NULL;
245        }
246
247        gtk_widget_show (item);
248
249        bonobo_ui_toolbar_insert (BONOBO_UI_TOOLBAR (parent),
250                                  BONOBO_UI_TOOLBAR_ITEM (item),
251                                  (*pos)++);
252
253        return item;
254}
255
256static GtkWidget *
257toolbar_build_widget (BonoboUISync *sync,
258                      BonoboUINode *node,
259                      BonoboUINode *cmd_node,
260                      int          *pos,
261                      GtkWidget    *parent)
262{
263        char         *type, *stock_id;
264        GtkWidget    *item;
265
266        g_return_val_if_fail (sync != NULL, NULL);
267        g_return_val_if_fail (node != NULL, NULL);
268
269        type = bonobo_ui_engine_get_attr (node, cmd_node, "type");
270
271        if ((stock_id = bonobo_ui_engine_get_attr (node, cmd_node, "stockid"))) {
272                GtkStockItem  stock_item;
273                GtkIconSet   *icon_set;
274
275                if (!gtk_stock_lookup (stock_id, &stock_item))
276                        g_warning ("Unknown stock id '%s' on %s", stock_id,
277                                   bonobo_ui_xml_make_path (node));
278                else {
279                        gchar *label;
280                        int i, len;
281
282                        label = g_strdup (dgettext (stock_item.translation_domain, stock_item.label));
283
284                        len = strlen (label);
285                        for (i = 0; i < len; i++) {
286                                if (label [i] == '_') {
287                                        strcpy (label+i, label+i+1);
288                                        len--;
289                                }
290                        }
291
292                        bonobo_ui_node_set_attr (node, "label", label);
293
294                        g_free (label);
295                }
296
297                icon_set = gtk_icon_factory_lookup_default (stock_id);
298
299                if (icon_set) {
300                        bonobo_ui_node_set_attr (node, "pixtype", "stock");
301                        bonobo_ui_node_set_attr (node, "pixname", stock_id);
302                }
303        }
304
305        if (bonobo_ui_node_has_name (node, "separator")) {
306                item = bonobo_ui_toolbar_separator_item_new ();
307                gtk_widget_set_sensitive (item, FALSE);
308
309        } else if (!type)
310                item = bonobo_ui_toolbar_button_item_new (NULL, NULL);
311       
312        else if (!strcmp (type, "toggle"))
313                item = bonobo_ui_toolbar_toggle_button_item_new (NULL, NULL);
314       
315        else {
316                /* FIXME: Implement radio-toolbars */
317                g_warning ("Invalid type '%s'", type);
318                return NULL;
319        }
320
321        bonobo_ui_node_free_string (type);
322       
323        bonobo_ui_toolbar_insert (BONOBO_UI_TOOLBAR (parent),
324                                  BONOBO_UI_TOOLBAR_ITEM (item),
325                                  (*pos)++);
326        gtk_widget_show (item);
327
328        return item;
329}
330
331static GtkWidget *
332impl_bonobo_ui_sync_toolbar_build (BonoboUISync     *sync,
333                                   BonoboUINode     *node,
334                                   BonoboUINode     *cmd_node,
335                                   int              *pos,
336                                   GtkWidget        *parent)
337{
338        GtkWidget *widget;
339        char      *verb;
340       
341        if (bonobo_ui_node_has_name (node, "control"))
342                widget = toolbar_build_control (
343                        sync, node, cmd_node, pos, parent);
344        else
345                widget = toolbar_build_widget (
346                        sync, node, cmd_node, pos, parent);
347
348        if (widget) {
349                /* FIXME: What about "id"s ! ? */
350                if ((verb = bonobo_ui_engine_get_attr (node, NULL, "verb"))) {
351                        g_signal_connect (GTK_OBJECT (widget), "activate",
352                                            (GtkSignalFunc) exec_verb_cb,
353                                            sync->engine);
354                        bonobo_ui_node_free_string (verb);
355                }
356               
357                g_signal_connect (GTK_OBJECT (widget), "state_altered",
358                                    (GtkSignalFunc) win_item_emit_ui_event,
359                                    sync->engine);
360        }
361
362        return widget;
363}
364
365static GtkWidget *
366impl_bonobo_ui_sync_toolbar_build_placeholder (BonoboUISync     *sync,
367                                               BonoboUINode     *node,
368                                               BonoboUINode     *cmd_node,
369                                               int              *pos,
370                                               GtkWidget        *parent)
371{
372        GtkWidget *widget;
373
374        widget = bonobo_ui_toolbar_separator_item_new ();
375        gtk_widget_set_sensitive (widget, FALSE);
376       
377        bonobo_ui_toolbar_insert (BONOBO_UI_TOOLBAR (parent),
378                                  BONOBO_UI_TOOLBAR_ITEM (widget),
379                                  (*pos)++);
380
381        return widget;
382}
383
384static BonoboDockItem *
385get_dock_item (BonoboUISyncToolbar *sync,
386               const char          *dockname)
387{
388        guint dummy;
389       
390        g_return_val_if_fail (dockname != NULL, NULL);
391
392        return bonobo_dock_get_item_by_name (sync->dock,
393                                            dockname,
394                                            &dummy, &dummy,
395                                            &dummy, &dummy);
396}
397
398static GList *
399impl_bonobo_ui_sync_toolbar_get_widgets (BonoboUISync *sync,
400                                         BonoboUINode *node)
401{
402        const char     *dockname;
403        BonoboDockItem *item;
404
405        dockname = bonobo_ui_node_peek_attr (node, "name");
406        item = get_dock_item (BONOBO_UI_SYNC_TOOLBAR (sync), dockname);
407
408        if (!item) {
409                g_warning ("Serious internal error building toolbar");
410                return NULL;
411        }
412
413        return bonobo_ui_toolbar_get_children (
414                BONOBO_UI_TOOLBAR (GTK_BIN (item)->child));
415}
416
417static void
418impl_bonobo_ui_sync_toolbar_state_update (BonoboUISync *sync,
419                                          GtkWidget    *widget,
420                                          const char   *new_state)
421{
422        g_return_if_fail (widget != NULL);
423
424        if (new_state) {
425                if (BONOBO_IS_UI_TOOLBAR_ITEM (widget))
426                        bonobo_ui_toolbar_item_set_state (
427                                BONOBO_UI_TOOLBAR_ITEM (widget), new_state);
428               
429                else
430                        g_warning ("TESTME: strange, setting "
431                                   "state '%s' on weird object '%s'",
432                                   new_state,
433                                   g_type_name_from_instance (
434                                           (GTypeInstance *) widget));
435        }
436}
437
438static void
439impl_dispose (GObject *object)
440{
441        BonoboUISyncToolbar *sync = (BonoboUISyncToolbar *) object;
442
443        if (sync->dock) {
444                g_object_unref (sync->dock);
445                sync->dock = NULL;
446        }
447
448        parent_class->dispose (object);
449}
450
451static gboolean
452impl_bonobo_ui_sync_toolbar_ignore_widget (BonoboUISync *sync,
453                                           GtkWidget    *widget)
454{
455        return BONOBO_IS_UI_TOOLBAR_POPUP_ITEM (widget);
456}
457
458static BonoboUIToolbarStyle
459parse_look (const char *look)
460{
461        if (look) {
462                if (!strcmp (look, "both"))
463                        return BONOBO_UI_TOOLBAR_STYLE_ICONS_AND_TEXT;
464
465                if (!strcmp (look, "icon"))
466                        return BONOBO_UI_TOOLBAR_STYLE_ICONS_ONLY;
467
468                if (!strcmp (look, "text"))
469                        return BONOBO_UI_TOOLBAR_STYLE_TEXT_ONLY;
470
471                if (!strcmp (look, "both_horiz"))
472                        return BONOBO_UI_TOOLBAR_STYLE_PRIORITY_TEXT;
473        }
474
475        return bonobo_ui_preferences_get_toolbar_style ();
476}
477
478BonoboUIToolbarStyle
479bonobo_ui_sync_toolbar_get_look (BonoboUIEngine *engine,
480                                 BonoboUINode   *node)
481{
482        const char *txt;
483        BonoboUIToolbarStyle look;
484
485        if ((txt = bonobo_ui_node_peek_attr (node, "look")))
486                look = parse_look (txt);
487
488        else {
489                GtkWidget *widget;
490
491                widget = bonobo_ui_engine_node_get_widget (engine, node);
492
493                if (!widget || !BONOBO_IS_UI_TOOLBAR (widget) ||
494                    bonobo_ui_toolbar_get_orientation (BONOBO_UI_TOOLBAR (widget)) ==
495                    GTK_ORIENTATION_HORIZONTAL) {
496                        txt = bonobo_ui_node_peek_attr (node, "hlook");
497                        look = parse_look (txt);
498                } else {
499                        txt = bonobo_ui_node_peek_attr (node, "vlook");
500                        look = parse_look (txt);
501                }
502        }               
503       
504        return look;
505}
506
507static char *
508do_config_popup (BonoboUIEngineConfig *config,
509                 BonoboUINode         *config_node,
510                 BonoboUIEngine       *popup_engine)
511{
512        char *ret;
513        gboolean tip;
514        const char *txt;
515        BonoboUIToolbarStyle style;
516       
517        tip = TRUE;
518        if ((txt = bonobo_ui_node_peek_attr (config_node, "tips")))
519                tip = atoi (txt);
520
521        style = bonobo_ui_sync_toolbar_get_look (bonobo_ui_engine_config_get_engine (config),
522                                                 config_node);
523
524        ret = g_strdup_printf (
525                "<Root>"
526                "<commands>"
527                "<cmd name=\"LookBoth\" state=\"%d\"/>"
528                "<cmd name=\"LookIcon\" state=\"%d\"/>"
529                "<cmd name=\"LookText\" state=\"%d\"/>"
530                "</commands>"
531                "<popups>"
532                "<popup>"
533                "<submenu label=\"%s\">"
534                "<menuitem verb=\"LookBoth\" label=\"%s\" set=\"both\" "
535                "type=\"radio\" group=\"look\"/>"
536                "<menuitem verb=\"LookIcon\" label=\"%s\" set=\"icon\" "
537                "type=\"radio\" group=\"look\"/>"
538                "<menuitem verb=\"LookText\" label=\"%s\" set=\"text\" "
539                "type=\"radio\" group=\"look\"/>"
540                "</submenu>"
541                "<separator/>"
542                "<menuitem verb=\"Tip\" label=\"%s\" set=\"%d\"/>"
543                "<menuitem verb=\"Hide\" label=\"%s\"/>"
544                "<menuitem verb=\"Customize\" label=\"%s\" tip=\"%s\""
545                " pixtype=\"stock\" pixname=\"Preferences\"/>"
546                "</popup>"
547                "</popups>"
548                "</Root>",
549                style == BONOBO_UI_TOOLBAR_STYLE_ICONS_AND_TEXT,
550                style == BONOBO_UI_TOOLBAR_STYLE_ICONS_ONLY,
551                style == BONOBO_UI_TOOLBAR_STYLE_PRIORITY_TEXT,
552                _("Look"), _("B_oth"), _("_Icon"), _("T_ext"),
553                tip ? _("Hide t_ips") :  _("Show t_ips"), !tip,
554                _("_Hide toolbar"), _("Customi_ze"),
555                _("Customize the toolbar"));
556
557        return ret;
558}
559
560static void
561config_verb_fn (BonoboUIEngineConfig *config,
562                const char           *path,
563                const char           *opt_state,
564                BonoboUIEngine       *popup_engine,
565                BonoboUINode         *popup_node)
566{
567        const char *verb;
568        gboolean changed = TRUE;
569
570        if ((verb = bonobo_ui_node_peek_attr (popup_node, "verb"))) {
571                const char *set;
572
573                set = bonobo_ui_node_peek_attr (popup_node, "set");
574
575                if (!strcmp (verb, "Hide"))
576                        bonobo_ui_engine_config_add (
577                                config, path, "hidden", "1");
578
579                else if (!strcmp (verb, "Show"))
580                        bonobo_ui_engine_config_remove (
581                                config, path, "hidden");
582
583                else if (!strcmp (verb, "Tip"))
584                        bonobo_ui_engine_config_add (
585                                config, path, "tips", set);
586
587                else if (!strncmp (verb, "Look", 4)) {
588                        if (opt_state && atoi (opt_state))
589                                bonobo_ui_engine_config_add (
590                                        config, path, "look", set);
591                        else
592                                changed = FALSE;
593                       
594                } else if (!strcmp (verb, "Customize")) {
595                        bonobo_ui_engine_config_configure (config);
596                        changed = FALSE;
597
598                } else
599                        g_warning ("Unknown verb '%s'", verb);
600        }
601
602
603        if (changed)
604                bonobo_ui_engine_config_serialize (config);
605}
606
607static BonoboDockItem *
608create_dockitem (BonoboUISyncToolbar *sync,
609                 BonoboUINode        *node,
610                 const char          *dockname)
611{
612        BonoboDockItem *item;
613        BonoboDockItemBehavior beh = 0;
614        const char *prop;
615        char      **behavior_array;
616        gboolean force_detachable = FALSE;
617        BonoboDockPlacement placement = BONOBO_DOCK_TOP;
618        gint band_num = 1;
619        gint position = 0;
620        guint offset = 0;
621        gboolean in_new_band = TRUE;
622        gboolean can_config = TRUE;
623        BonoboUIToolbar *toolbar;
624
625        if ((prop = bonobo_ui_node_peek_attr (node, "behavior"))) {
626                behavior_array = g_strsplit (prop, ",", -1);
627       
628                if (string_array_contains (behavior_array, "detachable"))
629                        force_detachable = TRUE;
630
631                if (string_array_contains (behavior_array, "exclusive"))
632                        beh |= BONOBO_DOCK_ITEM_BEH_EXCLUSIVE;
633
634                if (string_array_contains (behavior_array, "never vertical"))
635                        beh |= BONOBO_DOCK_ITEM_BEH_NEVER_VERTICAL;
636
637                if (string_array_contains (behavior_array, "never floating"))
638                        beh |= BONOBO_DOCK_ITEM_BEH_NEVER_FLOATING;
639
640                if (string_array_contains (behavior_array, "never horizontal"))
641                        beh |= BONOBO_DOCK_ITEM_BEH_NEVER_HORIZONTAL;
642
643                g_strfreev (behavior_array);
644        }
645
646        if (!force_detachable && !bonobo_ui_preferences_get_toolbar_detachable ())
647                beh |= BONOBO_DOCK_ITEM_BEH_LOCKED;
648
649        item = BONOBO_DOCK_ITEM (bonobo_dock_item_new (
650                dockname, beh));
651
652        bonobo_dock_item_set_shadow_type (item, GTK_SHADOW_OUT);
653        gtk_container_set_border_width (GTK_CONTAINER (item), 2);
654
655        if ((prop = bonobo_ui_node_peek_attr (node, "placement"))) {
656                if (!strcmp (prop, "top"))
657                        placement = BONOBO_DOCK_TOP;
658                else if (!strcmp (prop, "right"))
659                        placement = BONOBO_DOCK_RIGHT;
660                else if (!strcmp (prop, "bottom"))
661                        placement = BONOBO_DOCK_BOTTOM;
662                else if (!strcmp (prop, "left"))
663                        placement = BONOBO_DOCK_LEFT;
664                else if (!strcmp (prop, "floating"))
665                        placement = BONOBO_DOCK_FLOATING;
666        }
667
668        if ((prop = bonobo_ui_node_peek_attr (node, "band_num")))
669                band_num = atoi (prop);
670
671        if ((prop = bonobo_ui_node_peek_attr (node, "position")))
672                position = atoi (prop);
673
674        if ((prop = bonobo_ui_node_peek_attr (node, "offset")))
675                offset = atoi (prop);
676
677        if ((prop = bonobo_ui_node_peek_attr (node, "in_new_band")))
678                in_new_band = atoi (prop);
679
680        bonobo_dock_add_item (sync->dock, item,
681                              placement, band_num,
682                              position, offset, in_new_band);
683
684               
685        toolbar = BONOBO_UI_TOOLBAR (bonobo_ui_toolbar_new ());
686
687        gtk_container_add (GTK_CONTAINER (item),
688                           GTK_WIDGET (toolbar));
689        gtk_widget_show (GTK_WIDGET (toolbar));
690
691        if ((prop = bonobo_ui_node_peek_attr (node, "config")))
692                can_config = atoi (prop);
693        else
694                can_config = TRUE;
695
696        if (can_config) {
697                char *path;
698                path = bonobo_ui_xml_make_path (node);
699
700                bonobo_ui_engine_config_connect (
701                        GTK_WIDGET (item), sync->parent.engine,
702                        path, do_config_popup, config_verb_fn);
703
704                bonobo_ui_engine_config_connect (
705                        GTK_WIDGET (toolbar), sync->parent.engine,
706                        path, do_config_popup, config_verb_fn);
707
708                g_free (path);
709        }
710
711        return item;
712}
713
714static void
715impl_bonobo_ui_sync_toolbar_remove_root (BonoboUISync *sync,
716                                         BonoboUINode *node)
717{
718        const char *name;
719
720        if ((name = bonobo_ui_node_peek_attr (node, "name"))) {
721                BonoboDockItem *item;
722
723                item = get_dock_item (BONOBO_UI_SYNC_TOOLBAR (sync), name);
724
725                if (item)
726                        gtk_widget_destroy (GTK_WIDGET (item));
727        }
728}
729
730static void
731impl_bonobo_ui_sync_toolbar_update_root (BonoboUISync *sync,
732                                         BonoboUINode *node)
733{
734        const char *txt;
735        const char *dockname;
736        gboolean    tooltips;
737        gboolean    detachable;
738        BonoboDockItem *item;
739        BonoboUIToolbar *toolbar;
740        BonoboUIToolbarStyle look;
741
742        dockname = bonobo_ui_node_peek_attr (node, "name");
743
744        g_return_if_fail (dockname != NULL);
745
746        item = get_dock_item (BONOBO_UI_SYNC_TOOLBAR (sync), dockname);
747       
748        if (!item)
749                item = create_dockitem (BONOBO_UI_SYNC_TOOLBAR (sync),
750                                        node, dockname);
751
752        if ((txt = bonobo_ui_node_peek_attr (node, "behavior")) &&
753            strstr (txt, "detachable"))
754                detachable = TRUE;
755        else
756                detachable = bonobo_ui_preferences_get_toolbar_detachable ();
757        bonobo_dock_item_set_locked (item, !detachable);
758
759        toolbar = BONOBO_UI_TOOLBAR (GTK_BIN (item)->child);
760
761        bonobo_ui_engine_stamp_root (sync->engine, node, GTK_WIDGET (toolbar));
762
763        if ((txt = bonobo_ui_node_peek_attr (node, "look"))) {
764                look = parse_look (txt);
765                bonobo_ui_toolbar_set_hv_styles (toolbar, look, look);
766
767        } else {
768                BonoboUIToolbarStyle vlook, hlook;
769
770                txt = bonobo_ui_node_peek_attr (node, "hlook");
771                hlook = parse_look (txt);
772
773                txt = bonobo_ui_node_peek_attr (node, "vlook");
774                vlook = parse_look (txt);
775
776                bonobo_ui_toolbar_set_hv_styles (toolbar, hlook, vlook);
777        }               
778
779#if 0
780        if ((txt = bonobo_ui_node_get_attr (node, "relief"))) {
781
782                if (!strcmp (txt, "normal"))
783                        bonobo_ui_toolbar_set_relief (
784                                toolbar, GTK_RELIEF_NORMAL);
785
786                else if (!strcmp (txt, "half"))
787                        bonobo_ui_toolbar_set_relief (
788                                toolbar, GTK_RELIEF_HALF);
789                else
790                        bonobo_ui_toolbar_set_relief (
791                                toolbar, GTK_RELIEF_NONE);
792                bonobo_ui_node_free_string (txt);
793        }
794#endif
795
796        if ((txt = bonobo_ui_node_peek_attr (node, "tips")))
797                tooltips = atoi (txt);
798        else
799                tooltips = TRUE;
800
801        bonobo_ui_toolbar_show_tooltips (toolbar, tooltips);
802
803       /*
804        * FIXME: It shouldn't be necessary to explicitly resize the
805        * dock, since resizing a widget is supposed to resize it's parent,
806        * but the dock is not resized correctly on dockitem show / hides.
807        */
808        if (bonobo_ui_sync_do_show_hide (sync, node, NULL, GTK_WIDGET (item)))
809                gtk_widget_queue_resize (GTK_WIDGET (
810                        BONOBO_UI_SYNC_TOOLBAR (sync)->dock));
811}
812
813static gboolean
814impl_bonobo_ui_sync_toolbar_can_handle (BonoboUISync *sync,
815                                        BonoboUINode *node)
816{
817        if (!dockitem_id) {
818                dockitem_id = g_quark_from_static_string ("dockitem");
819                toolitem_id = g_quark_from_static_string ("toolitem");
820        }
821
822        return (node->name_id == dockitem_id ||
823                node->name_id == toolitem_id);
824}
825
826GtkWidget *
827impl_bonobo_ui_sync_toolbar_wrap_widget (BonoboUISync *sync,
828                                         GtkWidget    *custom_widget)
829{
830        if (!BONOBO_IS_UI_TOOLBAR_ITEM (custom_widget))
831                return bonobo_ui_toolbar_control_item_new_widget (custom_widget);
832        else
833                return custom_widget;
834}
835
836static void
837class_init (BonoboUISyncClass *sync_class)
838{
839        GObjectClass *object_class;
840
841        parent_class = g_type_class_peek_parent (sync_class);
842
843        object_class = G_OBJECT_CLASS (sync_class);
844        object_class->dispose = impl_dispose;
845
846        sync_class->sync_state = impl_bonobo_ui_sync_toolbar_state;
847        sync_class->build      = impl_bonobo_ui_sync_toolbar_build;
848        sync_class->build_placeholder = impl_bonobo_ui_sync_toolbar_build_placeholder;
849
850        sync_class->get_widgets   = impl_bonobo_ui_sync_toolbar_get_widgets;
851        sync_class->ignore_widget = impl_bonobo_ui_sync_toolbar_ignore_widget;
852        sync_class->remove_root   = impl_bonobo_ui_sync_toolbar_remove_root;
853        sync_class->update_root   = impl_bonobo_ui_sync_toolbar_update_root;
854
855        sync_class->state_update  = impl_bonobo_ui_sync_toolbar_state_update;
856        sync_class->can_handle    = impl_bonobo_ui_sync_toolbar_can_handle;
857
858        sync_class->wrap_widget   = impl_bonobo_ui_sync_toolbar_wrap_widget;
859}
860
861GType
862bonobo_ui_sync_toolbar_get_type (void)
863{
864        static GType type = 0;
865
866        if (type == 0) {
867                GTypeInfo info = {
868                        sizeof (BonoboUISyncToolbarClass),
869                        (GBaseInitFunc) NULL,
870                        (GBaseFinalizeFunc) NULL,
871                        (GClassInitFunc) class_init,
872                        NULL, /* class_finalize */
873                        NULL, /* class_data */
874                        sizeof (BonoboUISyncToolbar),
875                        0, /* n_preallocs */
876                        (GInstanceInitFunc) NULL
877                };
878
879                type = g_type_register_static (PARENT_TYPE, "BonoboUISyncToolbar",
880                                               &info, 0);
881        }
882
883        return type;
884}
885
886BonoboUISync *
887bonobo_ui_sync_toolbar_new (BonoboUIEngine  *engine,
888                            BonoboDock       *dock)
889{
890        BonoboUISyncToolbar *sync;
891
892        g_return_val_if_fail (BONOBO_IS_UI_ENGINE (engine), NULL);
893
894        sync = g_object_new (BONOBO_TYPE_UI_SYNC_TOOLBAR, NULL);
895
896        sync->dock = g_object_ref (dock);
897
898        return bonobo_ui_sync_construct (
899                BONOBO_UI_SYNC (sync), engine, FALSE, TRUE);
900}
Note: See TracBrowser for help on using the repository browser.