if (state->menus) {
if (parse_attr_string("label", node, &label)) {
GSList *acts = NULL;
-
+
for (node = node->xmlChildrenNode; node; node = node->next)
if (!xmlStrcasecmp(node->name, (const xmlChar*) "action"))
- acts = g_slist_append(acts, action_parse(doc, node));
- menu_add_normal(state->menus->data, label, acts);
+ acts = g_slist_append(acts, action_parse(i, doc, node));
+ menu_add_normal(state->menus->data, 0, label, acts);
g_free(label);
}
}
gpointer data)
{
ObMenuParseState *state = data;
-
+
if (state->menus)
- menu_add_separator(state->menus->data);
+ menu_add_separator(state->menus->data, 0);
+}
+
+gboolean menu_open_plugin(ObParseInst *i, gchar *name, gchar *plugin)
+{
+ gboolean ret = FALSE;
+
+ if (plugin_open(plugin, i)) {
+ plugin_start(plugin);
+ if (g_hash_table_lookup(menu_hash, name))
+ ret = TRUE;
+ else
+ g_warning("Specified plugin '%s' did not provide the "
+ "menu '%s'", plugin, name);
+ }
+ return ret;
}
static void parse_menu(ObParseInst *i, xmlDocPtr doc, xmlNodePtr node,
gpointer data)
{
ObMenuParseState *state = data;
- gchar *name = NULL, *title = NULL;
+ gchar *name = NULL, *title = NULL, *plugin = NULL;
if (!parse_attr_string("id", node, &name))
goto parse_menu_fail;
if (!g_hash_table_lookup(menu_hash, name)) {
- if (!parse_attr_string("label", node, &title))
- goto parse_menu_fail;
-
- if (menu_new(name, title, NULL)) {
- state->menus = g_slist_prepend(state->menus, name);
- parse_tree(i, doc, node->xmlChildrenNode);
- state->menus = g_slist_delete_link(state->menus, state->menus);
+ if (parse_attr_string("plugin", node, &plugin)) {
+ menu_open_plugin(i, name, plugin);
+ } else {
+ if (!parse_attr_string("label", node, &title))
+ goto parse_menu_fail;
+
+ if (menu_new(name, title, NULL)) {
+ state->menus = g_slist_prepend(state->menus, name);
+ parse_tree(i, doc, node->xmlChildrenNode);
+ state->menus = g_slist_delete_link(state->menus, state->menus);
+ }
}
}
if (state->menus)
- menu_add_submenu(state->menus->data, name);
+ menu_add_submenu(state->menus->data, 0, name);
parse_menu_fail:
g_free(name);
g_free(title);
+ g_free(plugin);
}
void menu_destroy_hash_value(ObMenu *self)
{
+ /* XXX make sure its not visible */
+
+ if (self->destroy_func)
+ self->destroy_func(self, self->data);
+
menu_clear_entries_internal(self);
g_free(self->name);
g_free(self->title);
{
menu_frame_hide_all();
g_hash_table_destroy(menu_hash);
+ menu_hash = NULL;
}
void menu_parse()
return TRUE;
}
+void menu_free(gchar *name)
+{
+ ObMenu *self;
+
+ if (!(self = menu_from_name(name))) return;
+ g_hash_table_remove(menu_hash, self->name);
+}
+
void menu_show(gchar *name, gint x, gint y, ObClient *client)
{
ObMenu *self;
if (!(self = menu_from_name(name))) return;
- /* XXX update entries */
-
frame = menu_frame_new(self, client);
menu_frame_move(frame, x, y);
menu_frame_show(frame, NULL);
}
-static ObMenuEntry* menu_entry_new(ObMenu *menu, ObMenuEntryType type)
+static ObMenuEntry* menu_entry_new(ObMenu *menu, ObMenuEntryType type, gint id)
{
ObMenuEntry *self;
self = g_new0(ObMenuEntry, 1);
self->type = type;
self->menu = menu;
- self->enabled = TRUE;
+ self->id = id;
+
+ switch (type) {
+ case OB_MENU_ENTRY_TYPE_NORMAL:
+ self->data.normal.enabled = TRUE;
+ break;
+ case OB_MENU_ENTRY_TYPE_SUBMENU:
+ case OB_MENU_ENTRY_TYPE_SEPARATOR:
+ break;
+ }
+
return self;
}
}
break;
case OB_MENU_ENTRY_TYPE_SUBMENU:
+ g_free(self->data.submenu.name);
+ break;
case OB_MENU_ENTRY_TYPE_SEPARATOR:
break;
}
}
}
-void menu_add_normal(gchar *name, gchar *label, GSList *actions)
+void menu_add_normal(gchar *name, gint id, gchar *label, GSList *actions)
{
ObMenu *self;
ObMenuEntry *e;
if (!(self = menu_from_name(name))) return;
- e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_NORMAL);
+ e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_NORMAL, id);
e->data.normal.label = g_strdup(label);
e->data.normal.actions = actions;
self->entries = g_list_append(self->entries, e);
}
-void menu_add_submenu(gchar *name, gchar *submenu)
+void menu_add_submenu(gchar *name, gint id, gchar *submenu)
{
- ObMenu *self, *sub;
+ ObMenu *self;
ObMenuEntry *e;
if (!(self = menu_from_name(name))) return;
- if (!(sub = menu_from_name(submenu))) return;
- e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_SUBMENU);
- e->data.submenu.submenu = sub;
+ e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_SUBMENU, id);
+ e->data.submenu.name = g_strdup(submenu);
self->entries = g_list_append(self->entries, e);
}
-void menu_add_separator(gchar *name)
+void menu_add_separator(gchar *name, gint id)
{
ObMenu *self;
ObMenuEntry *e;
if (!(self = menu_from_name(name))) return;
- e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_SEPARATOR);
+ e = menu_entry_new(self, OB_MENU_ENTRY_TYPE_SEPARATOR, id);
self->entries = g_list_append(self->entries, e);
}
+
+void menu_set_update_func(gchar *name, ObMenuUpdateFunc func)
+{
+ ObMenu *self;
+
+ if (!(self = menu_from_name(name))) return;
+ self->update_func = func;
+}
+
+void menu_set_execute_func(gchar *name, ObMenuExecuteFunc func)
+{
+ ObMenu *self;
+
+ if (!(self = menu_from_name(name))) return;
+ self->execute_func = func;
+}
+
+void menu_set_destroy_func(gchar *name, ObMenuDestroyFunc func)
+{
+ ObMenu *self;
+
+ if (!(self = menu_from_name(name))) return;
+ self->destroy_func = func;
+}
+
+ObMenuEntry* menu_find_entry_id(ObMenu *self, gint id)
+{
+ ObMenuEntry *ret = NULL;
+ GList *it;
+
+ for (it = self->entries; it; it = g_list_next(it)) {
+ ObMenuEntry *e = it->data;
+
+ if (e->id == id) {
+ ret = e;
+ break;
+ }
+ }
+ return ret;
+}
+
+void menu_find_submenus(ObMenu *self)
+{
+ GList *it;
+
+ for (it = self->entries; it; it = g_list_next(it)) {
+ ObMenuEntry *e = it->data;
+
+ if (e->type == OB_MENU_ENTRY_TYPE_SUBMENU)
+ e->data.submenu.submenu = menu_from_name(e->data.submenu.name);
+ }
+}