diff options
author | waker <wakeroid@gmail.com> | 2011-05-05 22:31:09 +0200 |
---|---|---|
committer | waker <wakeroid@gmail.com> | 2011-05-05 22:31:09 +0200 |
commit | e773e777343ce971d80c55522b293d83cddae478 (patch) | |
tree | e1b3fcc532235f16744c2f89a9b8c3d28df7fb71 /plugins/gtkui/plcommon.c | |
parent | 87c204d3ba97043ed11a052aec55ea956c4e9e68 (diff) |
added context submenu generation from plugin actions titles with slashes
for example, "Utils/Converter" action will give a popup "Utils" with subitem "Converter"
while "Utils\/Converter" action will give an item "Utils/Converter"
Diffstat (limited to 'plugins/gtkui/plcommon.c')
-rw-r--r-- | plugins/gtkui/plcommon.c | 95 |
1 files changed, 93 insertions, 2 deletions
diff --git a/plugins/gtkui/plcommon.c b/plugins/gtkui/plcommon.c index 136d340f..b8192667 100644 --- a/plugins/gtkui/plcommon.c +++ b/plugins/gtkui/plcommon.c @@ -377,6 +377,34 @@ actionitem_activate (GtkMenuItem *menuitem, } } +#define HOOKUP_OBJECT(component,widget,name) \ + g_object_set_data_full (G_OBJECT (component), name, \ + gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref) + + +static GtkWidget* +find_popup (GtkWidget *widget, + const gchar *widget_name) +{ + GtkWidget *parent, *found_widget; + + for (;;) + { + if (GTK_IS_MENU (widget)) + parent = gtk_menu_get_attach_widget (GTK_MENU (widget)); + else + parent = widget->parent; + if (!parent) + parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey"); + if (parent == NULL) + break; + widget = parent; + } + + found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget), + widget_name); + return found_widget; +} void list_context_menu (DdbListview *listview, DdbListviewIter it, int idx) { clicked_idx = deadbeef->pl_get_idx_of (it); @@ -466,12 +494,75 @@ list_context_menu (DdbListview *listview, DdbListviewIter it, int idx) { { if (action->flags & DB_ACTION_COMMON) continue; + + // create submenus (separated with '/') + const char *prev = action->title; + while (*prev && *prev == '/') { + prev++; + } + + GtkWidget *popup = NULL; + + for (;;) { + const char *slash = strchr (prev, '/'); + if (slash && *(slash-1) != '\\') { + char name[slash-prev+1]; + // replace \/ with / + const char *p = prev; + char *t = name; + while (*p && p < slash) { + if (*p == '\\' && *(p+1) == '/') { + *t++ = '/'; + p += 2; + } + else { + *t++ = *p++; + } + } + *t = 0; + + // add popup + GtkWidget *prev_menu = popup ? popup : playlist_menu; + + popup = find_popup (prev_menu, name); + if (!popup) { + GtkWidget *item = gtk_image_menu_item_new_with_mnemonic (_(name)); + gtk_widget_show (item); + gtk_container_add (GTK_CONTAINER (prev_menu), item); + popup = gtk_menu_new (); + HOOKUP_OBJECT (prev_menu, popup, name); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), popup); + } + } + else { + break; + } + prev = slash+1; + } + + count++; added_entries++; GtkWidget *actionitem; - actionitem = gtk_menu_item_new_with_mnemonic (_(action->title)); + + // replace \/ with / + const char *p = popup ? prev : action->title; + char title[strlen (p)+1]; + char *t = title; + while (*p) { + if (*p == '\\' && *(p+1) == '/') { + *t++ = '/'; + p += 2; + } + else { + *t++ = *p++; + } + } + *t = 0; + + actionitem = gtk_menu_item_new_with_mnemonic (_(title)); gtk_widget_show (actionitem); - gtk_container_add (GTK_CONTAINER (playlist_menu), actionitem); + gtk_container_add (popup ? GTK_CONTAINER (popup) : GTK_CONTAINER (playlist_menu), actionitem); g_object_set_data (G_OBJECT (actionitem), "ps", listview); g_signal_connect ((gpointer) actionitem, "activate", |