From 5d498956659bfe5016aa46190507203fee694ddd Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 11 Aug 2009 22:19:16 -0400 Subject: Kill EMenu. --- e-util/Makefile.am | 2 - e-util/e-menu.c | 925 ----------------------------------------------------- e-util/e-menu.h | 319 ------------------ 3 files changed, 1246 deletions(-) delete mode 100644 e-util/e-menu.c delete mode 100644 e-util/e-menu.h (limited to 'e-util') diff --git a/e-util/Makefile.am b/e-util/Makefile.am index 558d899d94..80b8d945c8 100644 --- a/e-util/Makefile.am +++ b/e-util/Makefile.am @@ -57,7 +57,6 @@ eutilinclude_HEADERS = \ e-import.h \ e-logger.h \ e-marshal.h \ - e-menu.h \ e-mktemp.h \ e-module.h \ e-non-intrusive-error-dialog.h \ @@ -101,7 +100,6 @@ libeutil_la_SOURCES = \ e-import.c \ e-logger.c \ e-marshal.c \ - e-menu.c \ e-mktemp.c \ e-module.c \ e-non-intrusive-error-dialog.c \ diff --git a/e-util/e-menu.c b/e-util/e-menu.c deleted file mode 100644 index 76c41b62f5..0000000000 --- a/e-util/e-menu.c +++ /dev/null @@ -1,925 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see - * - * - * Authors: - * Michael Zucchi - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include - -#include -#include - -#include - -#include "e-menu.h" -#include "e-icon-factory.h" - -#define d(x) - -struct _EMenuFactory { - struct _EMenuFactory *next, *prev; - - gchar *menuid; - EMenuFactoryFunc factory; - gpointer factory_data; -}; - -struct _item_node { - struct _item_node *next; - - EMenuItem *item; - struct _menu_node *menu; -}; - -struct _menu_node { - struct _menu_node *next, *prev; - - EMenu *parent; - - GSList *items; - GSList *uis; - GSList *pixmaps; - - EMenuItemsFunc freefunc; - gpointer data; - - /* a copy of items wrapped in an item_node, for bonobo - * callback mapping */ - struct _item_node *menu; -}; - -struct _EMenuPrivate { - EDList menus; -}; - -static GObjectClass *em_parent; - -static void -em_init(GObject *o) -{ - EMenu *emp = (EMenu *)o; - struct _EMenuPrivate *p; - - p = emp->priv = g_malloc0(sizeof(struct _EMenuPrivate)); - - e_dlist_init(&p->menus); -} - -static void -em_finalise(GObject *o) -{ - EMenu *em = (EMenu *)o; - struct _EMenuPrivate *p = em->priv; - struct _menu_node *mnode; - - if (em->target) - e_menu_target_free(em, em->target); - g_free(em->menuid); - - while ((mnode = (struct _menu_node *)e_dlist_remhead(&p->menus))) { - struct _item_node *inode; - - if (mnode->freefunc) - mnode->freefunc(em, mnode->items, mnode->uis, mnode->pixmaps, mnode->data); - - inode = mnode->menu; - while (inode) { - struct _item_node *nnode = inode->next; - - g_free(inode); - inode = nnode; - } - - g_free(mnode); - } - - g_free(p); - - ((GObjectClass *)em_parent)->finalize(o); -} - -static void -em_target_free(EMenu *ep, EMenuTarget *t) -{ - g_free(t); - /* look funny but t has a reference to us */ - g_object_unref(ep); -} - -static void -em_class_init(GObjectClass *klass) -{ - d(printf("EMenu class init %p '%s'\n", klass, g_type_name(((GObjectClass *)klass)->g_type_class.g_type))); - - klass->finalize = em_finalise; - ((EMenuClass *)klass)->target_free = em_target_free; -} - -static void -em_base_init(GObjectClass *klass) -{ - /* each class instance must have its own list, it isn't inherited */ - d(printf("%p: list init\n", klass)); - e_dlist_init(&((EMenuClass *)klass)->factories); -} - -/** - * e_menu_get_type: - * - * Standard GObject type function. Used to subclass this type only. - * - * Return value: The EMenu object type. - **/ -GType -e_menu_get_type(void) -{ - static GType type = 0; - - if (type == 0) { - static const GTypeInfo info = { - sizeof(EMenuClass), - (GBaseInitFunc)em_base_init, NULL, - (GClassInitFunc)em_class_init, - NULL, NULL, - sizeof(EMenu), 0, - (GInstanceInitFunc)em_init - }; - em_parent = g_type_class_ref(G_TYPE_OBJECT); - type = g_type_register_static(G_TYPE_OBJECT, "EMenu", &info, 0); - } - - return type; -} - -/** - * e_menu_construct: - * @em: An instantiated but uninitislied EPopup. - * @menuid: The unique identifier for this menu. - * - * Construct the base menu instance based on the parameters. - * - * Return value: Returns @em. - **/ -EMenu *e_menu_construct(EMenu *em, const gchar *menuid) -{ - struct _EMenuFactory *f; - EMenuClass *klass; - - d(printf("constructing menu '%s'\n", menuid)); - - klass = (EMenuClass *)G_OBJECT_GET_CLASS(em); - - d(printf(" class is %p '%s'\n", klass, g_type_name(((GObjectClass *)klass)->g_type_class.g_type))); - - em->menuid = g_strdup(menuid); - - /* setup the menu itself based on factories */ - f = (struct _EMenuFactory *)klass->factories.head; - if (f->next == NULL) { - d(printf("%p no factories registered on menu\n", klass)); - } - - while (f->next) { - if (f->menuid == NULL - || !strcmp(f->menuid, em->menuid)) { - d(printf(" calling factory\n")); - f->factory(em, f->factory_data); - } - f = f->next; - } - - return em; -} - -/** - * e_menu_add_items: - * @emp: An initialised EMenu. - * @items: A list of EMenuItems or derived structures defining a group - * of menu items for this menu. - * @uifiles: A list of EMenuUIFile objects describing all ui files - * associated with the items. - * @pixmaps: A list of EMenuPixmap objects describing all pixmaps - * associated with the menus. - * @freefunc: If supplied, called when the menu items are no longer needed. - * @data: user-data passed to @freefunc and activate callbacks. - * - * Add new EMenuItems to the menu's. This may be called any number of - * times before the menu is first activated to hook onto any of the - * menu items defined for that view. - * - * Return value: A handle that can be passed to remove_items as required. - **/ -gpointer -e_menu_add_items(EMenu *emp, GSList *items, GSList *uifiles, GSList *pixmaps, EMenuItemsFunc freefunc, gpointer data) -{ - struct _menu_node *node; - GSList *l; - - node = g_malloc0(sizeof(*node)); - node->parent = emp; - node->items = items; - node->uis = uifiles; - node->pixmaps = pixmaps; - node->freefunc = freefunc; - node->data = data; - - for (l=items;l;l=g_slist_next(l)) { - struct _item_node *inode = g_malloc0(sizeof(*inode)); - EMenuItem *item = l->data; - - inode->item = item; - inode->menu = node; - inode->next = node->menu; - node->menu = inode; - } - - for (l=pixmaps;l;l=g_slist_next(l)) { - EMenuPixmap *pixmap = l->data; - - if (pixmap->pixmap == NULL) { - GdkPixbuf *pixbuf; - - pixbuf = e_icon_factory_get_icon(pixmap->name, pixmap->size); - if (pixbuf == NULL) { - g_warning("Unable to load icon '%s'", pixmap->name); - } else { - pixmap->pixmap = bonobo_ui_util_pixbuf_to_xml(pixbuf); - g_object_unref(pixbuf); - } - } - } - - e_dlist_addtail(&emp->priv->menus, (EDListNode *)node); - - /* FIXME: add the menu's to a running menu if it is there? */ - - return (gpointer)node; -} - -/** - * e_menu_remove_items: - * @emp: - * @handle: - * - * Remove menu items previously added. - **/ -void -e_menu_remove_items(EMenu *emp, gpointer handle) -{ - struct _menu_node *node = handle; - struct _item_node *inode; - GSList *l; - - e_dlist_remove((EDListNode *)node); - - if (emp->uic) { - for (l = node->items;l;l=g_slist_next(l)) { - EMenuItem *item = l->data; - - bonobo_ui_component_remove_verb(emp->uic, item->verb); - } - } - - if (node->freefunc) - node->freefunc(emp, node->items, node->uis, node->pixmaps, node->data); - - inode = node->menu; - while (inode) { - struct _item_node *nnode = inode->next; - - g_free(inode); - inode = nnode; - } - - g_free(node); -} - -static void -em_activate_toggle(BonoboUIComponent *component, const gchar *path, Bonobo_UIComponent_EventType type, const gchar *state, gpointer data) -{ - struct _item_node *inode = data; - - if (type != Bonobo_UIComponent_STATE_CHANGED) - return; - - ((EMenuToggleActivateFunc)inode->item->activate)(inode->menu->parent, inode->item, state[0] != '0', inode->menu->data); -} - -static void -em_activate(BonoboUIComponent *uic, gpointer data, const gchar *cname) -{ - struct _item_node *inode = data; - - ((EMenuActivateFunc)inode->item->activate)(inode->menu->parent, inode->item, inode->menu->data); -} - -/** - * e_menu_activate: - * @em: An initialised EMenu. - * @uic: The BonoboUI component for this views menu's. - * @act: If %TRUE, then the control is being activated. - * - * This is called by the owner of the component, control, or view to - * pass on the activate or deactivate control signals. If the view is - * being activated then the callbacks and menu items are setup, - * otherwise they are removed. - * - * This should always be called in the strict sequence of activate, then - * deactivate, repeated any number of times. - **/ -void e_menu_activate(EMenu *em, struct _BonoboUIComponent *uic, gint act) -{ - struct _EMenuPrivate *p = em->priv; - struct _menu_node *mw; - GSList *l; - - if (act) { - GArray *verbs; - gint i; - - em->uic = uic; - - verbs = g_array_new(TRUE, FALSE, sizeof(BonoboUIVerb)); - for (mw = (struct _menu_node *)p->menus.head;mw->next;mw=mw->next) { - struct _item_node *inode; - - for (l = mw->uis; l; l = g_slist_next(l)) { - EMenuUIFile *ui = l->data; - - bonobo_ui_util_set_ui(uic, ui->appdir, ui->filename, ui->appname, NULL); - } - - for (l = mw->pixmaps; l; l = g_slist_next(l)) { - EMenuPixmap *pm = l->data; - - if (pm->pixmap) - bonobo_ui_component_set_prop(uic, pm->command, "pixmap", pm->pixmap, NULL); - } - - for (inode = mw->menu; inode; inode=inode->next) { - EMenuItem *item = inode->item; - BonoboUIVerb *verb; - - d(printf("adding menu verb '%s'\n", item->verb)); - - switch (item->type & E_MENU_TYPE_MASK) { - case E_MENU_ITEM: - i = verbs->len; - verbs = g_array_set_size(verbs, i+1); - verb = &((BonoboUIVerb *)verbs->data)[i]; - - verb->cname = item->verb; - verb->cb = em_activate; - verb->user_data = inode; - break; - case E_MENU_TOGGLE: - bonobo_ui_component_set_prop(uic, item->path, "state", item->type & E_MENU_ACTIVE?"1":"0", NULL); - bonobo_ui_component_add_listener(uic, item->verb, em_activate_toggle, inode); - break; - } - } - } - - if (verbs->len) - bonobo_ui_component_add_verb_list(uic, (BonoboUIVerb *)verbs->data); - - g_array_free(verbs, TRUE); - } else { - for (mw = (struct _menu_node *)p->menus.head;mw->next;mw=mw->next) { - for (l = mw->items;l;l=g_slist_next(l)) { - EMenuItem *item = l->data; - - bonobo_ui_component_remove_verb(uic, item->verb); - } - } - - em->uic = NULL; - } -} - -/** - * e_menu_update_target: - * @em: An initialised EMenu. - * @tp: Target, after this call the menu owns the target. - * - * Change the target for the menu. Once the target is changed, the - * sensitivity state of the menu items managed by @em is re-evaluated - * and the physical menu's updated to reflect it. - * - * This is used by the owner of the menu and view to update the menu - * system based on user input or changed system state. - **/ -void e_menu_update_target(EMenu *em, gpointer tp) -{ - struct _EMenuPrivate *p = em->priv; - EMenuTarget *t = tp; - guint32 mask = ~0; - struct _menu_node *mw; - GSList *l; - - if (em->target && em->target != t) - e_menu_target_free(em, em->target); - - /* if we unset the target, should we disable/hide all the menu items? */ - em->target = t; - if (t == NULL) - return; - - mask = t->mask; - - /* canna do any more capt'n */ - if (em->uic == NULL) - return; - - for (mw = (struct _menu_node *)p->menus.head;mw->next;mw=mw->next) { - for (l = mw->items;l;l=g_slist_next(l)) { - EMenuItem *item = l->data; - gint state; - - d(printf("checking item '%s' mask %08x against target %08x\n", item->verb, item->enable, mask)); - - state = (item->enable & mask) == 0; - bonobo_ui_component_set_prop(em->uic, item->path, "sensitive", state?"1":"0", NULL); - /* visible? */ - } - } -} - -/* ********************************************************************** */ - -/** - * e_menu_class_add_factory: - * @klass: An EMenuClass type to which this factory applies. - * @menuid: The identifier of the menu for this factory, or NULL to be - * called on all menus. - * @func: An EMenuFactoryFunc callback. - * @data: Callback data for @func. - * - * Add a menu factory which will be called when the menu @menuid is - * created. The factory is free to add new items as it wishes to the - * menu provided in the callback. - * - * TODO: Make the menuid a pattern? - * - * Return value: A handle to the factory. - **/ -EMenuFactory * -e_menu_class_add_factory(EMenuClass *klass, const gchar *menuid, EMenuFactoryFunc func, gpointer data) -{ - struct _EMenuFactory *f = g_malloc0(sizeof(*f)); - - d(printf("%p adding factory '%s' to class '%s'\n", klass, menuid?menuid:"", g_type_name(((GObjectClass *)klass)->g_type_class.g_type))); - - f->menuid = g_strdup(menuid); - f->factory = func; - f->factory_data = data; - e_dlist_addtail(&klass->factories, (EDListNode *)f); - - /* setup the menu itself based on factories */ - { - struct _EMenuFactory *j; - - j = (struct _EMenuFactory *)klass->factories.head; - if (j->next == NULL) { - d(printf("%p no factories registered on menu???\n", klass)); - } - } - - return f; -} - -/** - * e_menu_class_remove_factory: - * @klass: Class on which the factory was originally added. - * @f: Factory handle. - * - * Remove a popup factory. This must only be called once, and must - * only be called using a valid factory handle @f. After this call, - * @f is undefined. - **/ -void -e_menu_class_remove_factory(EMenuClass *klass, EMenuFactory *f) -{ - e_dlist_remove((EDListNode *)f); - g_free(f->menuid); - g_free(f); -} - -/** - * e_menu_target_new: - * @ep: An EMenu to which this target applies. - * @type: Target type, up to implementation. - * @size: Size of memory to allocate. Must be >= sizeof(EMenuTarget). - * - * Allocate a new menu target suitable for this class. @size is used - * to specify the actual target size, which may vary depending on the - * implementing class. - **/ -gpointer e_menu_target_new(EMenu *ep, gint type, gsize size) -{ - EMenuTarget *t; - - if (size < sizeof(EMenuTarget)) { - g_warning ("size less than size of EMenuTarget\n"); - size = sizeof (EMenuTarget); - } - - t = g_malloc0(size); - t->menu = ep; - g_object_ref(ep); - t->type = type; - - return t; -} - -/** - * e_menu_target_free: - * @ep: EMenu on which the target was allocated. - * @o: Tareget to free. - * - * Free a target. - **/ -void -e_menu_target_free(EMenu *ep, gpointer o) -{ - EMenuTarget *t = o; - - ((EMenuClass *)G_OBJECT_GET_CLASS(ep))->target_free(ep, t); -} - -/* ********************************************************************** */ - -/* Main menu plugin handler */ - -/* NB: This has significant overlap with EPopupHook */ - -/* - - - - - - - - - - - -*/ - -static gpointer emph_parent_class; -#define emph ((EMenuHook *)eph) - -/* must have 1:1 correspondence with e-menu types in order */ -static const EPluginHookTargetKey emph_item_types[] = { - { "item", E_MENU_ITEM }, - { "toggle", E_MENU_TOGGLE }, - { "radio", E_MENU_RADIO }, - { NULL } -}; - -/* 1:1 with e-icon-factory sizes */ -static const EPluginHookTargetKey emph_pixmap_sizes[] = { - { "menu", 0 }, - { "button", 1}, - { "small_toolbar", 2}, - { "large_toolbar", 3}, - { "dnd", 4}, - { "dialog", 5}, - { NULL } -}; - -static void -emph_menu_activate(EMenu *em, EMenuItem *item, gpointer data) -{ - EMenuHook *hook = data; - - d(printf("invoking plugin hook '%s' %p\n", (gchar *)item->user_data, em->target)); - - e_plugin_invoke(hook->hook.plugin, item->user_data, em->target); -} - -static void -emph_menu_toggle_activate(EMenu *em, EMenuItem *item, gint state, gpointer data) -{ - EMenuHook *hook = data; - - /* FIXME: where does the toggle state go? */ - d(printf("invoking plugin hook '%s' %p\n", (gchar *)item->user_data, em->target)); - - e_plugin_invoke(hook->hook.plugin, item->user_data, em->target); -} - -static void -emph_menu_factory(EMenu *emp, gpointer data) -{ - struct _EMenuHookMenu *menu = data; - - d(printf("menu factory, adding %d items\n", g_slist_length(menu->items))); - - if (menu->items) - e_menu_add_items(emp, menu->items, menu->uis, menu->pixmaps, NULL, menu->hook); -} - -static void -emph_free_item(struct _EMenuItem *item) -{ - g_free(item->path); - g_free(item->verb); - g_free(item->user_data); - g_free(item); -} - -static void -emph_free_ui(struct _EMenuUIFile *ui) -{ - g_free(ui->appdir); - g_free(ui->appname); - g_free(ui->filename); -} - -static void -emph_free_pixmap(struct _EMenuPixmap *pixmap) -{ - g_free(pixmap->command); - g_free(pixmap->name); - g_free(pixmap->pixmap); - g_free(pixmap); -} - -static void -emph_free_menu(struct _EMenuHookMenu *menu) -{ - g_slist_foreach(menu->items, (GFunc)emph_free_item, NULL); - g_slist_free(menu->items); - g_slist_foreach(menu->uis, (GFunc)emph_free_ui, NULL); - g_slist_free(menu->uis); - g_slist_foreach(menu->pixmaps, (GFunc)emph_free_pixmap, NULL); - g_slist_free(menu->pixmaps); - - g_free(menu->id); - g_free(menu); -} - -static struct _EMenuItem * -emph_construct_item(EPluginHook *eph, EMenuHookMenu *menu, xmlNodePtr root, EMenuHookTargetMap *map) -{ - struct _EMenuItem *item; - - d(printf(" loading menu item\n")); - item = g_malloc0(sizeof(*item)); - item->type = e_plugin_hook_id(root, emph_item_types, "type"); - item->path = e_plugin_xml_prop(root, "path"); - item->verb = e_plugin_xml_prop(root, "verb"); - item->visible = e_plugin_hook_mask(root, map->mask_bits, "visible"); - item->enable = e_plugin_hook_mask(root, map->mask_bits, "enable"); - item->user_data = e_plugin_xml_prop(root, "activate"); - if ((item->type & E_MENU_TYPE_MASK) == E_MENU_TOGGLE) - item->activate = G_CALLBACK(emph_menu_toggle_activate); - else - item->activate = G_CALLBACK(emph_menu_activate); - - if (item->type == -1 || item->user_data == NULL) - goto error; - - d(printf(" path=%s\n", item->path)); - d(printf(" verb=%s\n", item->verb)); - - return item; -error: - d(printf("error!\n")); - emph_free_item(item); - return NULL; -} - -static struct _EMenuPixmap * -emph_construct_pixmap(EPluginHook *eph, EMenuHookMenu *menu, xmlNodePtr root) -{ - struct _EMenuPixmap *pixmap; - - d(printf(" loading menu pixmap\n")); - pixmap = g_malloc0(sizeof(*pixmap)); - pixmap->command = e_plugin_xml_prop(root, "command"); - pixmap->name = e_plugin_xml_prop(root, "pixmap"); - pixmap->size = e_plugin_hook_id(root, emph_pixmap_sizes, "size"); - - if (pixmap->command == NULL || pixmap->name == NULL || pixmap->size == -1) - goto error; - - return pixmap; -error: - d(printf("error!\n")); - emph_free_pixmap(pixmap); - return NULL; -} - -static struct _EMenuHookMenu * -emph_construct_menu(EPluginHook *eph, xmlNodePtr root) -{ - struct _EMenuHookMenu *menu; - xmlNodePtr node; - EMenuHookTargetMap *map; - EMenuHookClass *klass = (EMenuHookClass *)G_OBJECT_GET_CLASS(eph); - gchar *tmp; - - d(printf(" loading menu\n")); - menu = g_malloc0(sizeof(*menu)); - menu->hook = (EMenuHook *)eph; - - tmp = (gchar *)xmlGetProp(root, (const guchar *)"target"); - if (tmp == NULL) - goto error; - map = g_hash_table_lookup(klass->target_map, tmp); - xmlFree(tmp); - if (map == NULL) - goto error; - - menu->target_type = map->id; - menu->id = e_plugin_xml_prop(root, "id"); - if (menu->id == NULL) { - g_warning("Plugin '%s' missing 'id' field in menu for '%s'\n", eph->plugin->name, - ((EPluginHookClass *)G_OBJECT_GET_CLASS(eph))->id); - goto error; - } - node = root->children; - while (node) { - if (0 == strcmp((gchar *)node->name, "item")) { - struct _EMenuItem *item; - - item = emph_construct_item(eph, menu, node, map); - if (item) - menu->items = g_slist_append(menu->items, item); - } else if (0 == strcmp((gchar *)node->name, "ui")) { - tmp = (gchar *)xmlGetProp(node, (const guchar *)"file"); - if (tmp) { - EMenuUIFile *ui = g_malloc0(sizeof(*ui)); - - ui->filename = g_strdup(tmp); - xmlFree(tmp); -#ifdef G_OS_WIN32 - { - gchar *mapped_location = - e_util_replace_prefix (EVOLUTION_PREFIX, - e_util_get_prefix (), - ui->filename); - g_free (ui->filename); - ui->filename = mapped_location; - } -#endif - ui->appdir = g_strdup(g_get_tmp_dir()); - ui->appname = g_strdup("Evolution"); - menu->uis = g_slist_append(menu->uis, ui); - } - } else if (0 == strcmp((gchar *)node->name, "pixmap")) { - struct _EMenuPixmap *pixmap; - - pixmap = emph_construct_pixmap(eph, menu, node); - if (pixmap) - menu->pixmaps = g_slist_append(menu->pixmaps, pixmap); - } - node = node->next; - } - - return menu; -error: - d(printf("error loading menu hook\n")); - emph_free_menu(menu); - return NULL; -} - -static gint -emph_construct(EPluginHook *eph, EPlugin *ep, xmlNodePtr root) -{ - xmlNodePtr node; - EMenuClass *klass; - - d(printf("loading menu hook\n")); - - if (!ep->enabled) - return 0; - - if (((EPluginHookClass *)emph_parent_class)->construct(eph, ep, root) == -1) - return -1; - - klass = ((EMenuHookClass *)G_OBJECT_GET_CLASS(eph))->menu_class; - - node = root->children; - while (node) { - if (strcmp((gchar *)node->name, "menu") == 0) { - struct _EMenuHookMenu *menu; - - menu = emph_construct_menu(eph, node); - if (menu) { - d(printf(" plugin adding factory %p\n", klass)); - e_menu_class_add_factory(klass, menu->id, emph_menu_factory, menu); - emph->menus = g_slist_append(emph->menus, menu); - } - } - - node = node->next; - } - - eph->plugin = ep; - - return 0; -} - -static void -emph_finalise(GObject *o) -{ - EPluginHook *eph = (EPluginHook *)o; - - g_slist_foreach(emph->menus, (GFunc)emph_free_menu, NULL); - g_slist_free(emph->menus); - - ((GObjectClass *)emph_parent_class)->finalize(o); -} - -static void -emph_class_init(EPluginHookClass *klass) -{ - d(printf("EMenuHook class init %p '%s'\n", klass, g_type_name(((GObjectClass *)klass)->g_type_class.g_type))); - - ((GObjectClass *)klass)->finalize = emph_finalise; - klass->construct = emph_construct; - - /* this is actually an abstract implementation but list it anyway */ - klass->id = "org.gnome.evolution.bonobomenu:1.0"; - - ((EMenuHookClass *)klass)->target_map = g_hash_table_new(g_str_hash, g_str_equal); - ((EMenuHookClass *)klass)->menu_class = g_type_class_ref(e_menu_get_type()); -} - -/** - * e_menu_hook_get_type: - * - * Standard GObject function to get the object type. Used to subclass - * EMenuHook. - * - * Return value: The type of the menu hook class. - **/ -GType -e_menu_hook_get_type(void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof(EMenuHookClass), NULL, NULL, (GClassInitFunc) emph_class_init, NULL, NULL, - sizeof(EMenuHook), 0, (GInstanceInitFunc) NULL, - }; - - emph_parent_class = g_type_class_ref(e_plugin_hook_get_type()); - type = g_type_register_static(e_plugin_hook_get_type(), "EMenuHook", &info, 0); - } - - return type; -} - -/** - * e_menu_hook_class_add_target_map: - * @klass: The derived EMenuHook class. - * @map: A map used to describe a single EMenuTarget for this class. - * - * Adds a target map to a concrete derived class of EMenu. The target - * map enumerates a single target type, and the enable mask bit names, - * so that the type can be loaded automatically by the EMenu class. - **/ -void e_menu_hook_class_add_target_map(EMenuHookClass *klass, const EMenuHookTargetMap *map) -{ - g_hash_table_insert(klass->target_map, (gpointer)map->type, (gpointer)map); -} diff --git a/e-util/e-menu.h b/e-util/e-menu.h deleted file mode 100644 index 3b2416e46a..0000000000 --- a/e-util/e-menu.h +++ /dev/null @@ -1,319 +0,0 @@ -/* - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see - * - * - * Authors: - * Michel Zucchi - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __E_MENU_H__ -#define __E_MENU_H__ - -#include -#include - -G_BEGIN_DECLS - -/* This is an abstract popup menu management/merging class. - - To implement your own popup menu system, just create your own - target types and implement the target free method. */ - -typedef struct _EMenu EMenu; -typedef struct _EMenuClass EMenuClass; - -typedef struct _EMenuItem EMenuItem; -typedef struct _EMenuUIFile EMenuUIFile; -typedef struct _EMenuPixmap EMenuPixmap; - -typedef struct _EMenuFactory EMenuFactory; /* anonymous type */ -typedef struct _EMenuTarget EMenuTarget; - -typedef void (*EMenuFactoryFunc)(EMenu *emp, gpointer data); -typedef void (*EMenuActivateFunc)(EMenu *, EMenuItem *, gpointer data); -typedef void (*EMenuToggleActivateFunc)(EMenu *, EMenuItem *, gint state, gpointer data); -typedef void (*EMenuItemsFunc)(EMenu *, GSList *items, GSList *uifiles, GSList *pixmaps, gpointer data); - -/** - * enum _e_menu_t - Menu item type. - * - * @E_MENU_ITEM: Normal menu item. - * @E_MENU_TOGGLE: Toggle menu item. - * @E_MENU_RADIO: unimplemented. - * @E_MENU_TYPE_MASK: Mask used to separate item type from option bits. - * @E_MENU_ACTIVE: Whether a toggle item is active. - * - * The type of menu items which are supported by the menu system. - **/ -enum _e_menu_t { - E_MENU_ITEM = 0, - E_MENU_TOGGLE, - E_MENU_RADIO, - E_MENU_TYPE_MASK = 0xffff, - E_MENU_ACTIVE = 0x10000 -}; - -/** - * struct _EMenuItem - A BonoboUI menu item. - * - * @type: Menu item type. %E_MENU_ITEM or %E_MENU_TOGGLE. - * @path: BonoboUI Path to the menu item. - * @verb: BonoboUI verb for the menu item. - * @activate: Callback when the menu item is selected. This will be a - * EMenuToggleActivateFunc for toggle items or EMenuActivateFunc for - * normal items. - * @user_data: User data for item. - * @visible: Visibility mask, unimplemented. - * @enable: Sensitivity mask, combined with the target mask. - * - * An EMenuItem defines a single menu item. This menu item is used to - * hook onto callbacks from the bonobo menus, but not to build or - * merge the menu itself. - **/ -struct _EMenuItem { - enum _e_menu_t type; - gchar *path; /* full path? can we just create it from verb? */ - gchar *verb; /* command verb */ - GCallback activate; /* depends on type, the bonobo activate callback */ - gpointer user_data; /* up to caller to use */ - guint32 visible; /* is visible mask */ - guint32 enable; /* is enable mask */ -}; - -/** - * struct _EMenuPixmap - A menu icon holder. - * - * @command: The path to the command or verb to which this pixmap belongs. - * @name: The name of the icon. Either an icon-theme name or the full - * pathname of the icon. - * @size: The e-icon-factory icon size. - * @pixmap: The pixmap converted to XML format. If not set, then EMenu will - * create it as required. This must be freed if set in the free function. - * - * Used to track all pixmap items used in menus. These need to be - * supplied separately from the menu definition. - **/ -struct _EMenuPixmap { - gchar *command; - gchar *name; - gint size; - gchar *pixmap; -}; - -/** - * struct _EMenuUIFile - A meu UI file holder. - * - * @appdir: TODO; should this be handled internally. - * @appname: TODO; should this be handled internally. - * @filename: The filename of the BonoboUI XML menu definition. - * - * These values are passed directly to bonobo_ui_util_set_ui() when - * the menu is activated. - **/ -struct _EMenuUIFile { - gchar *appdir; - gchar *appname; - gchar *filename; -}; - -/** - * struct _EMenuTarget - A BonoboUI menu target definition. - * - * @menu: The parent menu object, used for virtual methods on the target. - * @widget: The parent widget where available. In some cases the type - * of this object is part of the published api for the target, in - * others it is merely a GtkWidget from which you can find the - * toplevel widget. - * @type: Target type. This will be defined by the implementation. - * @mask: Target mask. This is used to sensitise show items based on - * their definition in EMenuItem. - * - * An EMenuTarget defines the context for a specific view instance. - * It is used to enable and show menu items, and to provide contextual - * data to menu invocations. - **/ -struct _EMenuTarget { - struct _EMenu *menu; /* used for virtual methods */ - - GtkWidget *widget; /* used if you need a parent toplevel, if available */ - guint32 type; /* for implementors */ - - guint32 mask; /* enable/visible mask */ - - /* implementation fields follow */ -}; - -/** - * struct _EMenu - A BonoboUI menu manager object. - * - * @object: Superclass. - * @priv: Private data. - * @menuid: The id of this menu instance. - * @uic: The current BonoboUIComponent which stores the actual menu - * items this object manages. - * @target: The current target for the view. - * - * The EMenu manager object manages the mappings between EMenuItems - * and the BonoboUI menus loaded from UI files. - **/ -struct _EMenu { - GObject object; - struct _EMenuPrivate *priv; - - gchar *menuid; - struct _BonoboUIComponent *uic; - EMenuTarget *target; -}; - -/** - * struct _EMenuClass - - * - * @object_class: Superclass type. - * @factories: A list of factories for this particular class of main menu. - * @target_free: Virtual method to free the menu target. The base - * class free method frees the allocation and unrefs the EMenu parent - * pointer. - * - * The EMenu class definition. This should be sub-classed for each - * component that wants to provide hookable main menus. The subclass - * only needs to know how to allocate and free the various target - * types it supports. - **/ -struct _EMenuClass { - GObjectClass object_class; - - EDList factories; - - void (*target_free)(EMenu *ep, EMenuTarget *t); -}; - -GType e_menu_get_type(void); - -/* Static class methods */ -EMenuFactory *e_menu_class_add_factory(EMenuClass *klass, const gchar *menuid, EMenuFactoryFunc func, gpointer data); -void e_menu_class_remove_factory(EMenuClass *klass, EMenuFactory *f); - -EMenu *e_menu_construct(EMenu *menu, const gchar *menuid); - -void e_menu_add_ui(EMenu *, const gchar *appdir, const gchar *appname, const gchar *filename); -void e_menu_add_pixmap(EMenu *, const gchar *cmd, const gchar *name, gint size); - -gpointer e_menu_add_items(EMenu *emp, GSList *items, GSList *uifiles, GSList *pixmaps, EMenuItemsFunc freefunc, gpointer data); -void e_menu_remove_items(EMenu *emp, gpointer handle); - -void e_menu_activate(EMenu *, struct _BonoboUIComponent *uic, gint act); -void e_menu_update_target(EMenu *, gpointer ); - -gpointer e_menu_target_new(EMenu *, gint type, gsize size); -void e_menu_target_free(EMenu *, gpointer ); - -/* ********************************************************************** */ - -/* menu plugin, they are closely integrated */ - -/* To implement a basic menu plugin, you just need to subclass - this and initialise the class target type tables */ - -#include "e-util/e-plugin.h" - -typedef struct _EMenuHookPixmap EMenuHookPixmap; -typedef struct _EMenuHookMenu EMenuHookMenu; -typedef struct _EMenuHook EMenuHook; -typedef struct _EMenuHookClass EMenuHookClass; - -typedef struct _EPluginHookTargetMap EMenuHookTargetMap; -typedef struct _EPluginHookTargetKey EMenuHookTargetMask; - -typedef void (*EMenuHookFunc)(struct _EPlugin *plugin, EMenuTarget *target); - -/** - * struct _EMenuHookMenu - A group of items targetting a specific menu. - * - * @hook: Parent pointer. - * @id: The identifier of the menu or view to which these items belong. - * @target_type: The target number of the type of target these menu - * items expect. This will be defined by menu itself. - * @items: A list of EMenuItems. - * @uis: A list of filenames of the BonoboUI files that need to be - * loaded for an active view. - * @pixmaps: A list of EMenuHookPixmap structures for the menus. - * - * This structure is used to keep track of all of the items that a - * plugin wishes to add to specific menu. This is used internally by - * a factory method defined by the EMenuHook to add the right menu - * items to a given view. - **/ -struct _EMenuHookMenu { - struct _EMenuHook *hook; /* parent pointer */ - gchar *id; /* target menu id for these menu items */ - gint target_type; /* target type, not used */ - GSList *items; /* items to add to menu */ - GSList *uis; /* ui files */ - GSList *pixmaps; /* pixmap descriptors */ -}; - -/** - * struct _EMenuHook - A BonoboUI menu hook. - * - * @hook: Superclass. - * @menus: A list of EMenuHookMenus for all menus registered on this - * hook type. - * - * The EMenuHook class loads and manages the meta-data to required to - * map plugin definitions to physical menus. - **/ -struct _EMenuHook { - EPluginHook hook; - - GSList *menus; -}; - -/** - * struct _EMenuHookClass - Menu hook type. - * - * @hook_class: Superclass type. - * @target_map: Table of EluginHookTargetMaps which enumerate the - * target types and enable bits of the implementing class. - * @menu_class: The EMenuClass of the corresponding popup manager for - * implementing the class. - * - * The EMenuHookClass is an empty concrete class. It must be - * subclassed and initialised appropriately to perform useful work. - * - * The EPluginHookClass.id must be set to the name and version of the - * hook handler the implementation defines. The @target_map must be - * initialised with the data required to enumerate the target types - * and enable flags supported by the implementing class. - **/ -struct _EMenuHookClass { - EPluginHookClass hook_class; - - /* EMenuHookTargetMap by .type */ - GHashTable *target_map; - /* the menu class these menus belong to */ - EMenuClass *menu_class; -}; - -GType e_menu_hook_get_type(void); - -/* for implementors */ -void e_menu_hook_class_add_target_map(EMenuHookClass *klass, const EMenuHookTargetMap *); - -G_END_DECLS - -#endif /* __E_MENU_H__ */ -- cgit