diff options
Diffstat (limited to 'plugins/gtkui/pltmenu.c')
-rw-r--r-- | plugins/gtkui/pltmenu.c | 288 |
1 files changed, 288 insertions, 0 deletions
diff --git a/plugins/gtkui/pltmenu.c b/plugins/gtkui/pltmenu.c new file mode 100644 index 00000000..abfe7885 --- /dev/null +++ b/plugins/gtkui/pltmenu.c @@ -0,0 +1,288 @@ +/* + DeaDBeeF -- the music player + Copyright (C) 2009-2012 Alexey Yakovenko and other contributors + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source distribution. +*/ +#include "../../deadbeef.h" +#include <gtk/gtk.h> +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif +#include "../../gettext.h" +#include <string.h> +#include <stdlib.h> +#include "gtkui.h" +#include "interface.h" +#include "support.h" + +// selected playlist for the context menu +static int pltmenu_idx; + +void +plt_get_title_wrapper (int plt, char *buffer, int len) { + if (plt == -1) { + strcpy (buffer, ""); + return; + } + ddb_playlist_t *p = deadbeef->plt_get_for_idx (plt); + deadbeef->plt_get_title (p, buffer, len); + deadbeef->plt_unref (p); + char *end; + if (!g_utf8_validate (buffer, -1, (const gchar **)&end)) { + *end = 0; + } +} + +static void +on_rename_playlist1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + GtkWidget *dlg = create_entrydialog (); + gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK); + gtk_window_set_title (GTK_WINDOW (dlg), _("Edit playlist")); + GtkWidget *e; + e = lookup_widget (dlg, "title_label"); + gtk_label_set_text (GTK_LABEL(e), _("Title:")); + e = lookup_widget (dlg, "title"); + char t[1000]; + plt_get_title_wrapper (pltmenu_idx, t, sizeof (t)); + gtk_entry_set_text (GTK_ENTRY (e), t); + int res = gtk_dialog_run (GTK_DIALOG (dlg)); + if (res == GTK_RESPONSE_OK) { + const char *text = gtk_entry_get_text (GTK_ENTRY (e)); + deadbeef->pl_lock (); + ddb_playlist_t *p = deadbeef->plt_get_for_idx (pltmenu_idx); + deadbeef->plt_set_title (p, text); + deadbeef->plt_unref (p); + deadbeef->pl_unlock (); + } + gtk_widget_destroy (dlg); +} + +static void +on_remove_playlist1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + if (pltmenu_idx != -1) { + deadbeef->plt_remove (pltmenu_idx); + search_refresh (); + int playlist = deadbeef->plt_get_curr_idx (); + deadbeef->conf_set_int ("playlist.current", playlist); + } +} + +static void +on_add_new_playlist1_activate (GtkMenuItem *menuitem, + gpointer user_data) +{ + int playlist = gtkui_add_new_playlist (); + if (playlist != -1) { + gtkui_playlist_set_curr (playlist); + } +} + +static void +on_actionitem_activate (GtkMenuItem *menuitem, + DB_plugin_action_t *action) +{ + if (action->flags & DB_ACTION_USING_API_14) { + ddb_playlist_t *plt = NULL; + if (pltmenu_idx != -1) { + plt = deadbeef->plt_get_for_idx (pltmenu_idx); + } + typedef int (*action_callback_14_t)(struct DB_plugin_action_s *action, void *userdata); + ((action_callback_14_t)action->callback) (action, plt); + if (plt) { + deadbeef->plt_unref (plt); + } + } + else { + action->callback (action, DDB_ACTION_CTX_PLAYLIST); + } +} + +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 = gtk_widget_get_parent (widget); + 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; +} + +static void +add_tab_actions (GtkWidget *menu) { + DB_plugin_t **plugins = deadbeef->plug_get_list(); + int i; + + int added_entries = 0; + for (i = 0; plugins[i]; i++) + { + if (!plugins[i]->get_actions) + continue; + + DB_plugin_action_t *actions = plugins[i]->get_actions (NULL); + DB_plugin_action_t *action; + + int count = 0; + for (action = actions; action; action = action->next) + { + char *tmp = NULL; + if (!(action->flags & DB_ACTION_MULTIPLE_TRACKS)) + 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 : 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; + + // 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 (popup ? GTK_CONTAINER (popup) : GTK_CONTAINER (menu), actionitem); + + g_signal_connect ((gpointer) actionitem, "activate", + G_CALLBACK (on_actionitem_activate), + action); + } + } +} + +GtkWidget* +gtkui_create_pltmenu (int plt_idx) { + GtkWidget *plmenu; + GtkWidget *rename_playlist1; + GtkWidget *remove_playlist1; + GtkWidget *add_new_playlist1; + GtkWidget *separator11; + GtkWidget *load_playlist1; + GtkWidget *save_playlist1; + GtkWidget *save_all_playlists1; + + plmenu = gtk_menu_new (); + pltmenu_idx = plt_idx; + + rename_playlist1 = gtk_menu_item_new_with_mnemonic (_("Rename Playlist")); + if (pltmenu_idx == -1) { + gtk_widget_set_sensitive (rename_playlist1, FALSE); + } + gtk_widget_show (rename_playlist1); + gtk_container_add (GTK_CONTAINER (plmenu), rename_playlist1); + + remove_playlist1 = gtk_menu_item_new_with_mnemonic (_("Remove Playlist")); + if (pltmenu_idx == -1) { + gtk_widget_set_sensitive (remove_playlist1, FALSE); + } + gtk_widget_show (remove_playlist1); + gtk_container_add (GTK_CONTAINER (plmenu), remove_playlist1); + + add_new_playlist1 = gtk_menu_item_new_with_mnemonic (_("Add New Playlist")); + gtk_widget_show (add_new_playlist1); + gtk_container_add (GTK_CONTAINER (plmenu), add_new_playlist1); + + g_signal_connect ((gpointer) rename_playlist1, "activate", + G_CALLBACK (on_rename_playlist1_activate), + NULL); + g_signal_connect ((gpointer) remove_playlist1, "activate", + G_CALLBACK (on_remove_playlist1_activate), + NULL); + g_signal_connect ((gpointer) add_new_playlist1, "activate", + G_CALLBACK (on_add_new_playlist1_activate), + NULL); + + add_tab_actions (plmenu); + + return plmenu; +} + |