source: trunk/third/evolution/shell/e-shell-user-creatable-items-handler.c @ 18142

Revision 18142, 20.4 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18141, 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/* e-shell-user-creatable-items-handler.c
3 *
4 * Copyright (C) 2001  Ximian, Inc.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public
8 * License as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 *
20 * Author: Ettore Perazzoli <ettore@ximian.com>
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#include "e-shell-user-creatable-items-handler.h"
28
29#include "e-shell-corba-icon-utils.h"
30
31#include "widgets/misc/e-combo-button.h"
32
33#include "e-util/e-corba-utils.h"
34
35#include <gal/util/e-util.h>
36
37#include <bonobo/bonobo-ui-util.h>
38
39#include <libgnome/gnome-i18n.h>
40
41#include <gtk/gtksignal.h>
42#include <gtk/gtktooltips.h>
43
44#include <stdlib.h>
45#include <ctype.h>
46
47
48#define PARENT_TYPE gtk_object_get_type ()
49static GtkObjectClass *parent_class = NULL;
50
51
52#define VERB_PREFIX "ShellUserCreatableItemVerb"
53
54#define EVOLUTION_MAIL_OAFIID "OAFIID:GNOME_Evolution_Mail_ShellComponent"
55
56#define SHELL_VIEW_KEY          "EShellUserCreatableItemsHandler:shell_view"
57#define COMBO_BUTTON_WIDGET_KEY "EShellUserCreatableItemsHandler:combo_button"
58#define TOOLTIPS_KEY            "EShellUserCreatableItemsHandler:tooltips"
59
60struct _Component {
61        EvolutionShellComponentClient *component_client;
62
63        GNOME_Evolution_UserCreatableItemTypeList *type_list;
64};
65typedef struct _Component Component;
66
67/* Representation of a single menu item.  */
68struct _MenuItem {
69        const char *label;
70        char shortcut;
71        char *verb;
72        char *tooltip;
73        GdkPixbuf *icon;
74        char *component_id;
75        char *folder_type;
76};
77typedef struct _MenuItem MenuItem;
78
79struct _EShellUserCreatableItemsHandlerPrivate {
80        /* The components that register user creatable items.  */
81        GSList *components;     /* Component */
82
83        /* The "New ..." menu items.  */
84        GSList *menu_items;     /* MenuItem */
85
86        /* The default item (the mailer's "message" item).  To be used when the
87           component in the view we are in doesn't provide a default user
88           creatable type.  This pointer always points to one of the menu items
89           in ->menu_items.  */
90        const MenuItem *default_menu_item;
91};
92
93
94/* Component struct handling.  */
95
96static Component *
97component_new (const char *id,
98               EvolutionShellComponentClient *client)
99{
100        CORBA_Environment ev;
101        Component *new;
102        GNOME_Evolution_ShellComponent objref;
103
104        new = g_new (Component, 1);
105
106        new->component_client = client;
107        gtk_object_ref (GTK_OBJECT (client));
108
109        CORBA_exception_init (&ev);
110
111        objref = bonobo_object_corba_objref (BONOBO_OBJECT (client));
112        new->type_list = GNOME_Evolution_ShellComponent__get_userCreatableItemTypes (objref, &ev);
113
114        if (ev._major != CORBA_NO_EXCEPTION)
115                new->type_list = NULL;
116
117        CORBA_exception_free (&ev);
118
119        return new;
120}
121
122static void
123component_free (Component *component)
124{
125        gtk_object_unref (GTK_OBJECT (component->component_client));
126
127        if (component->type_list != NULL)
128                CORBA_free (component->type_list);
129
130        g_free (component);
131}
132
133
134/* Helper functions.  */
135
136static gboolean
137item_is_default (const MenuItem *item,
138                 const char *folder_type,
139                 const char *component_id)
140{
141        if (component_id == NULL || folder_type == NULL)
142                return FALSE;
143
144        if (item->folder_type != NULL && *item->folder_type != 0) {
145                if (strcmp (item->folder_type, folder_type) == 0)
146                        return TRUE;
147                else
148                        return FALSE;
149        }
150
151        if (strcmp (item->component_id, component_id) == 0)
152                return TRUE;
153        else
154                return FALSE;
155}
156
157static char *
158create_verb_from_component_number_and_type_id (int component_num,
159                                               const char *type_id)
160{
161        return g_strdup_printf (VERB_PREFIX ":%d:%s", component_num, type_id);
162}
163
164
165/* Setting up menu items for the "File -> New" submenu and the "New" toolbar
166   button.  */
167
168static void
169ensure_menu_items (EShellUserCreatableItemsHandler *handler)
170{
171        EShellUserCreatableItemsHandlerPrivate *priv;
172        GSList *menu_items;
173        GSList *p;
174        int component_num;
175        const char *default_verb;
176
177        priv = handler->priv;
178        if (priv->menu_items != NULL)
179                return;
180
181        menu_items = NULL;
182        component_num = 0;
183        default_verb = NULL;
184        for (p = priv->components; p != NULL; p = p->next) {
185                const Component *component;
186                int i;
187
188                component = (const Component *) p->data;
189                if (component->type_list != NULL) {
190                        for (i = 0; i < component->type_list->_length; i ++) {
191                                const GNOME_Evolution_UserCreatableItemType *type;
192                                MenuItem *item;
193
194                                type = (const GNOME_Evolution_UserCreatableItemType *) component->type_list->_buffer + i;
195
196                                item = g_new (MenuItem, 1);
197                                item->label        = type->menuDescription;
198                                item->shortcut     = type->menuShortcut;
199                                item->verb         = create_verb_from_component_number_and_type_id (component_num, type->id);
200                                item->tooltip      = type->tooltip;
201                                item->component_id = g_strdup (evolution_shell_component_client_get_id (component->component_client));
202                                item->folder_type  = g_strdup (type->folderType);
203
204                                if (strcmp (item->component_id, EVOLUTION_MAIL_OAFIID) == 0
205                                    && strcmp (type->id, "message") == 0)
206                                        default_verb = item->verb;
207
208                                if (type->icon.width == 0 || type->icon.height == 0)
209                                        item->icon = NULL;
210                                else
211                                        item->icon = e_new_gdk_pixbuf_from_corba_icon (& type->icon, 16, 16);
212
213                                menu_items = g_slist_prepend (menu_items, item);
214                        }
215                }
216
217                component_num ++;
218        }
219
220        priv->menu_items = menu_items;
221
222        priv->default_menu_item = NULL;
223        if (default_verb != NULL) {
224                for (p = priv->menu_items; p != NULL; p = p->next) {
225                        const MenuItem *item;
226
227                        item = (const MenuItem *) p->data;
228                        if (strcmp (item->verb, default_verb) == 0)
229                                priv->default_menu_item = item;
230                }
231        }
232}
233
234static void
235free_menu_items (GSList *menu_items)
236{
237        GSList *p;
238
239        if (menu_items == NULL)
240                return;
241
242        for (p = menu_items; p != NULL; p = p->next) {
243                MenuItem *item;
244
245                item = (MenuItem *) p->data;
246                g_free (item->verb);
247
248                if (item->icon != NULL)
249                        gdk_pixbuf_unref (item->icon);
250
251                g_free (item->component_id);
252
253                g_free (item);
254        }
255
256        g_slist_free (menu_items);
257}
258
259static const MenuItem *
260get_default_action_for_view (EShellUserCreatableItemsHandler *handler,
261                             EShellView *shell_view)
262{
263        EShellUserCreatableItemsHandlerPrivate *priv;
264        const char *view_component_id;
265        const GSList *p;
266
267        priv = handler->priv;
268
269        view_component_id = e_shell_view_get_current_component_id (shell_view);
270        if (view_component_id == NULL)
271                return NULL;
272
273        for (p = priv->menu_items; p != NULL; p = p->next) {
274                const MenuItem *item;
275
276                item = (const MenuItem *) p->data;
277                if (item_is_default (item,
278                                     e_shell_view_get_current_folder_type (shell_view),
279                                     e_shell_view_get_current_component_id (shell_view)))
280                        return item;
281        }
282
283        return priv->default_menu_item;
284}
285
286
287/* The XML description for "File -> New".  */
288
289/* This adds a menu item for @item.  If @first is true, the keyboard shortcut
290   is going to be "Control-N" instead of whatever the component defines.  */
291static void
292append_xml_for_menu_item (GString *xml,
293                          const MenuItem *item,
294                          gboolean first)
295{
296        char *encoded_label;
297        char *encoded_tooltip;
298
299        encoded_label = bonobo_ui_util_encode_str (item->label);
300        g_string_sprintfa (xml, "<menuitem name=\"New:%s\" verb=\"%s\" label=\"%s\"",
301                           item->verb, item->verb, encoded_label);
302
303        if (first)
304                g_string_sprintfa (xml, " accel=\"*Control*N\"");
305        else if (item->shortcut != '\0')
306                g_string_sprintfa (xml, " accel=\"*Control**Shift*%c\"", item->shortcut);
307
308        if (item->icon != NULL) {
309                char *pixbuf_xml;
310               
311                pixbuf_xml = bonobo_ui_util_pixbuf_to_xml (item->icon);
312                g_string_sprintfa (xml, " pixtype=\"pixbuf\" pixname=\"%s\"", pixbuf_xml);
313                g_free (pixbuf_xml);
314        }
315
316        encoded_tooltip = bonobo_ui_util_encode_str (item->tooltip);
317        g_string_sprintfa (xml, " tip=\"%s\"", encoded_tooltip);
318
319        g_string_append (xml, "/> ");
320
321        g_free (encoded_label);
322        g_free (encoded_tooltip);
323}
324
325static int
326item_types_sort_func (const void *a,
327                      const void *b)
328{
329        const MenuItem *item_a;
330        const MenuItem *item_b;
331        const char *p1, *p2;
332
333        item_a = (const MenuItem *) a;
334        item_b = (const MenuItem *) b;
335
336        p1 = item_a->label;
337        p2 = item_b->label;
338
339        while (*p1 != '\0' && *p2 != '\0') {
340                if (*p1 == '_') {
341                        p1 ++;
342                        continue;
343                }
344
345                if (*p2 == '_') {
346                        p2 ++;
347                        continue;
348                }
349
350                if (toupper ((int) *p1) < toupper ((int) *p2))
351                        return -1;
352                else if (toupper ((int) *p1) > toupper ((int) *p2))
353                        return +1;
354
355                p1 ++, p2 ++;
356        }
357
358        if (*p1 == '\0') {
359                if (*p2 == '\0')
360                        return 0;
361                else
362                        return -1;
363        } else {
364                return +1;
365        }
366}
367
368static char *
369create_menu_xml (EShellUserCreatableItemsHandler *handler,
370                 const char *folder_type,
371                 const char *component_id)
372{
373        EShellUserCreatableItemsHandlerPrivate *priv;
374        GString *xml;
375        GSList *p;
376        GSList *non_default_items;
377        char *retval;
378
379        priv = handler->priv;
380
381        ensure_menu_items (handler);
382
383        xml = g_string_new ("");
384
385        g_string_append (xml, "<placeholder name=\"ComponentItems\">");
386        g_string_append (xml, "<placeholder name=\"EShellUserCreatableItemsPlaceholder\">");
387
388        /* 1. Add all the elements that are default for this component.  (Note
389              that we don't need to do any sorting since the items are already
390              sorted alphabetically.)  */
391
392        if (component_id != NULL) {
393                gboolean first = TRUE;
394
395                for (p = priv->menu_items; p != NULL; p = p->next) {
396                        const MenuItem *item;
397
398                        item = (const MenuItem *) p->data;
399                        if (item_is_default (item, folder_type, component_id)) {
400                                append_xml_for_menu_item (xml, item, first);
401                                first = FALSE;
402                        }
403                }
404        }
405
406        /* 2. Add a separator. */
407
408        if (component_id != NULL)
409                g_string_sprintfa (xml, "<separator f=\"\" name=\"EShellUserCreatableItemsHandlerSeparator\"/>");
410
411        /* 3. Add the elements that are not default for this component.  */
412
413        non_default_items = NULL;
414        for (p = priv->menu_items; p != NULL; p = p->next) {
415                const MenuItem *item;
416
417                item = (const MenuItem *) p->data;
418                if (! item_is_default (item, folder_type, component_id))
419                        non_default_items = g_slist_prepend (non_default_items, (void *) item);
420        }
421
422        non_default_items = g_slist_sort (non_default_items, item_types_sort_func);
423        for (p = non_default_items; p != NULL; p = p->next)
424                append_xml_for_menu_item (xml, (const MenuItem *) p->data, FALSE);
425        g_slist_free (non_default_items);
426
427        /* Done...  */
428
429        g_string_append (xml, "</placeholder>"); /* EShellUserCreatableItemsPlaceholder */
430        g_string_append (xml, "</placeholder>"); /* ComponentItems */
431
432        retval = xml->str;
433        g_string_free (xml, FALSE);
434
435        return retval;
436}
437
438
439/* Verb handling.  */
440
441static void
442execute_verb (EShellUserCreatableItemsHandler *handler,
443              EShellView *shell_view,
444              const char *verb_name)
445{
446        EShellUserCreatableItemsHandlerPrivate *priv;
447        const Component *component;
448        int component_number;
449        const char *p;
450        const char *id;
451        GSList *component_list_item;
452        int i;
453
454        priv = handler->priv;
455
456        p = strchr (verb_name, ':');
457        g_assert (p != NULL);
458        component_number = atoi (p + 1);
459
460        p = strchr (p + 1, ':');
461        g_assert (p != NULL);
462        id = p + 1;
463
464        component_list_item = g_slist_nth (priv->components, component_number);
465        g_assert (component_list_item != NULL);
466
467        component = (const Component *) component_list_item->data;
468
469        if (component->type_list == NULL)
470                return;
471
472        for (i = 0; i < component->type_list->_length; i ++) {
473                if (strcmp (component->type_list->_buffer[i].id, id) == 0) {
474                        CORBA_Environment ev;
475
476                        CORBA_exception_init (&ev);
477
478                        GNOME_Evolution_ShellComponent_userCreateNewItem
479                                (bonobo_object_corba_objref (BONOBO_OBJECT (component->component_client)),
480                                 id,
481                                 e_safe_corba_string (e_shell_view_get_current_physical_uri (shell_view)),
482                                 e_safe_corba_string (e_shell_view_get_current_folder_type (shell_view)),
483                                 &ev);
484
485                        if (ev._major != CORBA_NO_EXCEPTION)
486                                g_warning ("Error in userCreateNewItem -- %s", ev._repo_id);
487
488                        CORBA_exception_free (&ev);
489                        return;
490                }
491        }
492}
493
494static void
495verb_fn (BonoboUIComponent *ui_component,
496         void *data,
497         const char *verb_name)
498{
499        EShellUserCreatableItemsHandler *handler;
500        EShellView *shell_view;
501
502        shell_view = gtk_object_get_data (GTK_OBJECT (ui_component), SHELL_VIEW_KEY);
503        g_assert (E_IS_SHELL_VIEW (shell_view));
504
505        handler = E_SHELL_USER_CREATABLE_ITEMS_HANDLER (data);
506
507        execute_verb (handler, shell_view, verb_name);
508}
509
510static void
511add_verbs (EShellUserCreatableItemsHandler *handler,
512           EShellView *shell_view)
513{
514        EShellUserCreatableItemsHandlerPrivate *priv;
515        BonoboUIComponent *ui_component;
516        int component_num;
517        GSList *p;
518
519        priv = handler->priv;
520
521        ui_component = e_shell_view_get_bonobo_ui_component (shell_view);
522        gtk_object_set_data (GTK_OBJECT (ui_component), SHELL_VIEW_KEY, shell_view);
523
524        component_num = 0;
525        for (p = priv->components; p != NULL; p = p->next) {
526                const Component *component;
527                int i;
528
529                component = (const Component *) p->data;
530
531                if (component->type_list != NULL) {
532                        for (i = 0; i < component->type_list->_length; i ++) {
533                                char *verb_name;
534
535                                verb_name = create_verb_from_component_number_and_type_id
536                                        (component_num, component->type_list->_buffer[i].id);
537
538                                bonobo_ui_component_add_verb (ui_component, verb_name, verb_fn, handler);
539
540                                g_free (verb_name);
541                        }
542                }
543
544                component_num ++;
545        }
546}
547
548
549/* The "New" button in the toolbar.  */
550
551static void
552combo_button_activate_default_callback (EComboButton *combo_button,
553                                        void *data)
554{
555        EShellView *shell_view;
556        EShellUserCreatableItemsHandler *handler;
557        const MenuItem *menu_item;
558
559        shell_view = E_SHELL_VIEW (data);
560        handler = e_shell_get_user_creatable_items_handler (e_shell_view_get_shell (shell_view));
561
562        menu_item = get_default_action_for_view (handler, shell_view);
563        execute_verb (handler, shell_view, menu_item->verb);
564}
565
566static void
567setup_toolbar_button (EShellUserCreatableItemsHandler *handler,
568                      EShellView *shell_view)
569{
570        EShellUserCreatableItemsHandlerPrivate *priv;
571        BonoboUIComponent *ui_component;
572        GtkWidget *combo_button;
573        GtkWidget *menu;
574        GtkTooltips *tooltips;
575        BonoboControl *control;
576
577        priv = handler->priv;
578
579        menu = gtk_menu_new ();
580
581        combo_button = e_combo_button_new ();
582        e_combo_button_set_menu (E_COMBO_BUTTON (combo_button), GTK_MENU (menu));
583        e_combo_button_set_label (E_COMBO_BUTTON (combo_button), _("New"));
584        gtk_widget_show (combo_button);
585
586        gtk_signal_connect (GTK_OBJECT (combo_button), "activate_default",
587                            GTK_SIGNAL_FUNC (combo_button_activate_default_callback),
588                            shell_view);
589
590        ui_component = e_shell_view_get_bonobo_ui_component (shell_view);
591        bonobo_window_add_popup (BONOBO_WINDOW (shell_view), GTK_MENU (menu), "/popups/NewPopup");
592
593        control = bonobo_control_new (combo_button);
594
595        bonobo_ui_component_object_set (ui_component, "/Toolbar/NewComboButton",
596                                        BONOBO_OBJREF (control), NULL);
597
598        gtk_object_set_data (GTK_OBJECT (shell_view), COMBO_BUTTON_WIDGET_KEY, combo_button);
599
600        tooltips = gtk_tooltips_new ();
601        gtk_object_set_data (GTK_OBJECT (combo_button), TOOLTIPS_KEY, tooltips);
602}
603
604
605/* This handles the menus for a given EShellView.  We have to rebuild the menu
606   and set the toolbar button every time the view changes, and clean up when
607   the view is destroyed.  */
608
609static void
610shell_view_view_changed_callback (EShellView *shell_view,
611                                  const char *evolution_path,
612                                  const char *physical_uri,
613                                  const char *folder_type,
614                                  const char *component_id,
615                                  void *data)
616{
617        EShellUserCreatableItemsHandler *handler;
618        EShellUserCreatableItemsHandlerPrivate *priv;
619        GtkWidget *combo_button_widget;
620        GtkTooltips *tooltips;
621        BonoboUIComponent *ui_component;
622        const MenuItem *default_menu_item;
623        char *menu_xml;
624
625        handler = E_SHELL_USER_CREATABLE_ITEMS_HANDLER (data);
626        priv = handler->priv;
627
628        combo_button_widget = gtk_object_get_data (GTK_OBJECT (shell_view), COMBO_BUTTON_WIDGET_KEY);
629        g_assert (E_IS_COMBO_BUTTON (combo_button_widget));
630
631        tooltips = gtk_object_get_data (GTK_OBJECT (combo_button_widget), TOOLTIPS_KEY);
632        g_assert (tooltips != NULL);
633
634        default_menu_item = get_default_action_for_view (handler, shell_view);
635        if (default_menu_item == NULL) {
636                gtk_widget_set_sensitive (combo_button_widget, FALSE);
637                e_combo_button_set_label (E_COMBO_BUTTON (combo_button_widget), _("New"));
638                e_combo_button_set_icon (E_COMBO_BUTTON (combo_button_widget), NULL);
639                gtk_tooltips_set_tip (tooltips, combo_button_widget, NULL, NULL);
640                return;
641        }
642
643        gtk_widget_set_sensitive (combo_button_widget, TRUE);
644
645        e_combo_button_set_icon (E_COMBO_BUTTON (combo_button_widget), default_menu_item->icon);
646        gtk_tooltips_set_tip (tooltips, combo_button_widget, default_menu_item->tooltip, NULL);
647
648        ui_component = e_shell_view_get_bonobo_ui_component (shell_view);
649        bonobo_ui_component_rm (ui_component, "/menu/File/New/ComponentItems/EShellUserCreatableItemsPlaceholder", NULL);
650        bonobo_ui_component_rm (ui_component, "/popups/NewPopup/ComponentItems/EShellUserCreatableItemsPlaceholder", NULL);
651
652        menu_xml = create_menu_xml (handler,
653                                    e_shell_view_get_current_folder_type (shell_view),
654                                    e_shell_view_get_current_component_id (shell_view));
655        bonobo_ui_component_set (ui_component, "/menu/File/New", menu_xml, NULL);
656        bonobo_ui_component_set (ui_component, "/popups/NewPopup", menu_xml, NULL);
657        g_free (menu_xml);
658}
659
660
661/* GtkObject methods.  */
662
663static void
664impl_destroy (GtkObject *object)
665{
666        EShellUserCreatableItemsHandler *handler;
667        EShellUserCreatableItemsHandlerPrivate *priv;
668        GSList *p;
669
670        handler = E_SHELL_USER_CREATABLE_ITEMS_HANDLER (object);
671        priv = handler->priv;
672
673        for (p = priv->components; p != NULL; p = p->next)
674                component_free ((Component *) p->data);
675
676        g_slist_free (priv->components);
677
678        free_menu_items (priv->menu_items);
679
680        g_free (priv);
681
682        (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
683}
684
685
686static void
687class_init (GtkObjectClass *object_class)
688{
689        parent_class = gtk_type_class (PARENT_TYPE);
690
691        object_class->destroy = impl_destroy;
692}
693
694static void
695init (EShellUserCreatableItemsHandler *shell_user_creatable_items_handler)
696{
697        EShellUserCreatableItemsHandlerPrivate *priv;
698
699        priv = g_new (EShellUserCreatableItemsHandlerPrivate, 1);
700        priv->components        = NULL;
701        priv->menu_items        = NULL;
702        priv->default_menu_item = NULL;
703
704        shell_user_creatable_items_handler->priv = priv;
705}
706
707
708EShellUserCreatableItemsHandler *
709e_shell_user_creatable_items_handler_new (void)
710{
711        EShellUserCreatableItemsHandler *new;
712
713        new = gtk_type_new (e_shell_user_creatable_items_handler_get_type ());
714
715        return new;
716}
717
718void
719e_shell_user_creatable_items_handler_add_component  (EShellUserCreatableItemsHandler *handler,
720                                                     const char *id,
721                                                     EvolutionShellComponentClient   *shell_component_client)
722{
723        EShellUserCreatableItemsHandlerPrivate *priv;
724
725        g_return_if_fail (handler != NULL);
726        g_return_if_fail (E_IS_SHELL_USER_CREATABLE_ITEMS_HANDLER (handler));
727        g_return_if_fail (shell_component_client != NULL);
728        g_return_if_fail (EVOLUTION_IS_SHELL_COMPONENT_CLIENT (shell_component_client));
729
730        priv = handler->priv;
731
732        priv->components = g_slist_prepend (priv->components, component_new (id, shell_component_client));
733}
734
735
736/**
737 * e_shell_user_creatable_items_handler_attach_menus:
738 * @handler:
739 * @shell_view:
740 *
741 * Set up the menus and toolbar items for @shell_view.  When the shell changes
742 * view, the menu and the toolbar item will update automatically (i.e. the
743 * actions for the current folder will go on top etc.).
744 **/
745void
746e_shell_user_creatable_items_handler_attach_menus (EShellUserCreatableItemsHandler *handler,
747                                                   EShellView *shell_view)
748{
749        BonoboUIComponent *ui_component;
750        EShellUserCreatableItemsHandlerPrivate *priv;
751        char *menu_xml;
752
753        g_return_if_fail (handler != NULL);
754        g_return_if_fail (E_IS_SHELL_USER_CREATABLE_ITEMS_HANDLER (handler));
755        g_return_if_fail (shell_view != NULL);
756        g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
757
758        priv = handler->priv;
759
760        setup_toolbar_button (handler, shell_view);
761        gtk_signal_connect (GTK_OBJECT (shell_view), "view_changed",
762                            GTK_SIGNAL_FUNC (shell_view_view_changed_callback), handler);
763
764        add_verbs (handler, shell_view);
765        menu_xml = create_menu_xml (handler,
766                                    e_shell_view_get_current_component_id (shell_view),
767                                    e_shell_view_get_current_folder_type (shell_view));
768
769        ui_component = e_shell_view_get_bonobo_ui_component (shell_view);
770        bonobo_ui_component_set (ui_component, "/menu/File/New", menu_xml, NULL);
771        bonobo_ui_component_set (ui_component, "/popups/NewPopup", menu_xml, NULL);
772
773        g_free (menu_xml);
774}
775
776
777E_MAKE_TYPE (e_shell_user_creatable_items_handler,
778             "EShellUserCreatableItemsHandler", EShellUserCreatableItemsHandler,
779             class_init, init, PARENT_TYPE)
Note: See TracBrowser for help on using the repository browser.