diff options
author | 2011-02-27 21:41:18 +0100 | |
---|---|---|
committer | 2011-02-27 21:41:18 +0100 | |
commit | da1faaf258338f3d2d91ce0ffe9d013336407339 (patch) | |
tree | d81fc3087fe5685a0611c1dd516337b818cff719 /plugins/gtkui | |
parent | fefa370d326db32638bd9d1818ff6031e759d9c5 (diff) |
display info for all selected tracks in track properties
Diffstat (limited to 'plugins/gtkui')
-rw-r--r-- | plugins/gtkui/callbacks.c | 1 | ||||
-rw-r--r-- | plugins/gtkui/callbacks.h | 5 | ||||
-rw-r--r-- | plugins/gtkui/ddbtabstrip.c | 7 | ||||
-rw-r--r-- | plugins/gtkui/deadbeef.glade | 7 | ||||
-rw-r--r-- | plugins/gtkui/interface.c | 71 | ||||
-rw-r--r-- | plugins/gtkui/interface.h | 2 | ||||
-rw-r--r-- | plugins/gtkui/trkproperties.c | 236 |
7 files changed, 287 insertions, 42 deletions
diff --git a/plugins/gtkui/callbacks.c b/plugins/gtkui/callbacks.c index 709fce40..bfe87d63 100644 --- a/plugins/gtkui/callbacks.c +++ b/plugins/gtkui/callbacks.c @@ -1204,3 +1204,4 @@ create_plugin_weblink (gchar *widget_name, gchar *string1, gchar *string2, return link; } + diff --git a/plugins/gtkui/callbacks.h b/plugins/gtkui/callbacks.h index 297a605a..7ff5c38a 100644 --- a/plugins/gtkui/callbacks.h +++ b/plugins/gtkui/callbacks.h @@ -1066,3 +1066,8 @@ on_plug_copyright_clicked (GtkButton *button, GtkWidget* create_plugin_weblink (gchar *widget_name, gchar *string1, gchar *string2, gint int1, gint int2); + +gboolean +on_metalist_button_press_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data); diff --git a/plugins/gtkui/ddbtabstrip.c b/plugins/gtkui/ddbtabstrip.c index ddda3414..1567b916 100644 --- a/plugins/gtkui/ddbtabstrip.c +++ b/plugins/gtkui/ddbtabstrip.c @@ -621,10 +621,13 @@ void on_rename_playlist1_activate (GtkMenuItem *menuitem, gpointer user_data) { - GtkWidget *dlg = create_editplaylistdlg (); + 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 = lookup_widget (dlg, "title"); + GtkWidget *e; + e = lookup_widget (dlg, "title_label"); + gtk_label_set_text (GTK_LABEL(e), _("Title:")); + e = lookup_widget (dlg, "title"); char t[100]; plt_get_title_wrapper (tab_clicked, t, sizeof (t)); gtk_entry_set_text (GTK_ENTRY (e), t); diff --git a/plugins/gtkui/deadbeef.glade b/plugins/gtkui/deadbeef.glade index c9ef1312..682954e7 100644 --- a/plugins/gtkui/deadbeef.glade +++ b/plugins/gtkui/deadbeef.glade @@ -1447,6 +1447,7 @@ <property name="fixed_height_mode">False</property> <property name="hover_selection">False</property> <property name="hover_expand">False</property> + <signal name="button_press_event" handler="on_metalist_button_press_event" last_modification_time="Sun, 27 Feb 2011 18:14:41 GMT"/> </widget> </child> </widget> @@ -5370,10 +5371,10 @@ SOCKS5_HOSTNAME</property> </child> </widget> -<widget class="GtkDialog" id="editplaylistdlg"> +<widget class="GtkDialog" id="entrydialog"> <property name="border_width">8</property> <property name="visible">True</property> - <property name="title" translatable="yes">editplaylistdlg</property> + <property name="title" translatable="yes">EntryDialog</property> <property name="type">GTK_WINDOW_TOPLEVEL</property> <property name="window_position">GTK_WIN_POS_NONE</property> <property name="modal">False</property> @@ -5571,7 +5572,7 @@ SOCKS5_HOSTNAME</property> <property name="spacing">8</property> <child> - <widget class="GtkLabel" id="label40"> + <widget class="GtkLabel" id="title_label"> <property name="visible">True</property> <property name="label" translatable="yes">Title:</property> <property name="use_underline">False</property> diff --git a/plugins/gtkui/interface.c b/plugins/gtkui/interface.c index 214cca9b..a525d46e 100644 --- a/plugins/gtkui/interface.c +++ b/plugins/gtkui/interface.c @@ -1345,6 +1345,9 @@ create_trackproperties (void) g_signal_connect ((gpointer) trackproperties, "delete_event", G_CALLBACK (on_trackproperties_delete_event), NULL); + g_signal_connect ((gpointer) metalist, "button_press_event", + G_CALLBACK (on_metalist_button_press_event), + NULL); g_signal_connect ((gpointer) write_tags, "clicked", G_CALLBACK (on_write_tags_clicked), NULL); @@ -2947,13 +2950,13 @@ create_prefwin (void) } GtkWidget* -create_editplaylistdlg (void) +create_entrydialog (void) { - GtkWidget *editplaylistdlg; + GtkWidget *entrydialog; GtkWidget *dialog_vbox3; GtkWidget *vbox15; GtkWidget *hbox33; - GtkWidget *label40; + GtkWidget *title_label; GtkWidget *title; GtkWidget *dialog_action_area3; GtkWidget *cancelbutton2; @@ -2967,13 +2970,13 @@ create_editplaylistdlg (void) GtkWidget *image395; GtkWidget *label93; - editplaylistdlg = gtk_dialog_new (); - gtk_container_set_border_width (GTK_CONTAINER (editplaylistdlg), 8); - gtk_window_set_title (GTK_WINDOW (editplaylistdlg), _("editplaylistdlg")); - gtk_window_set_destroy_with_parent (GTK_WINDOW (editplaylistdlg), TRUE); - gtk_window_set_type_hint (GTK_WINDOW (editplaylistdlg), GDK_WINDOW_TYPE_HINT_DIALOG); + entrydialog = gtk_dialog_new (); + gtk_container_set_border_width (GTK_CONTAINER (entrydialog), 8); + gtk_window_set_title (GTK_WINDOW (entrydialog), _("EntryDialog")); + gtk_window_set_destroy_with_parent (GTK_WINDOW (entrydialog), TRUE); + gtk_window_set_type_hint (GTK_WINDOW (entrydialog), GDK_WINDOW_TYPE_HINT_DIALOG); - dialog_vbox3 = GTK_DIALOG (editplaylistdlg)->vbox; + dialog_vbox3 = GTK_DIALOG (entrydialog)->vbox; gtk_widget_show (dialog_vbox3); vbox15 = gtk_vbox_new (FALSE, 0); @@ -2985,9 +2988,9 @@ create_editplaylistdlg (void) gtk_widget_show (hbox33); gtk_box_pack_start (GTK_BOX (vbox15), hbox33, TRUE, TRUE, 0); - label40 = gtk_label_new (_("Title:")); - gtk_widget_show (label40); - gtk_box_pack_start (GTK_BOX (hbox33), label40, FALSE, FALSE, 0); + title_label = gtk_label_new (_("Title:")); + gtk_widget_show (title_label); + gtk_box_pack_start (GTK_BOX (hbox33), title_label, FALSE, FALSE, 0); title = gtk_entry_new (); gtk_widget_show (title); @@ -2995,13 +2998,13 @@ create_editplaylistdlg (void) gtk_entry_set_invisible_char (GTK_ENTRY (title), 8226); gtk_entry_set_activates_default (GTK_ENTRY (title), TRUE); - dialog_action_area3 = GTK_DIALOG (editplaylistdlg)->action_area; + dialog_action_area3 = GTK_DIALOG (entrydialog)->action_area; gtk_widget_show (dialog_action_area3); gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area3), GTK_BUTTONBOX_END); cancelbutton2 = gtk_button_new (); gtk_widget_show (cancelbutton2); - gtk_dialog_add_action_widget (GTK_DIALOG (editplaylistdlg), cancelbutton2, GTK_RESPONSE_CANCEL); + gtk_dialog_add_action_widget (GTK_DIALOG (entrydialog), cancelbutton2, GTK_RESPONSE_CANCEL); GTK_WIDGET_SET_FLAGS (cancelbutton2, GTK_CAN_DEFAULT); alignment17 = gtk_alignment_new (0.5, 0.5, 0, 0); @@ -3022,7 +3025,7 @@ create_editplaylistdlg (void) okbutton2 = gtk_button_new (); gtk_widget_show (okbutton2); - gtk_dialog_add_action_widget (GTK_DIALOG (editplaylistdlg), okbutton2, GTK_RESPONSE_OK); + gtk_dialog_add_action_widget (GTK_DIALOG (entrydialog), okbutton2, GTK_RESPONSE_OK); GTK_WIDGET_SET_FLAGS (okbutton2, GTK_CAN_DEFAULT); alignment16 = gtk_alignment_new (0.5, 0.5, 0, 0); @@ -3042,25 +3045,25 @@ create_editplaylistdlg (void) gtk_box_pack_start (GTK_BOX (hbox57), label93, FALSE, FALSE, 0); /* Store pointers to all widgets, for use by lookup_widget(). */ - GLADE_HOOKUP_OBJECT_NO_REF (editplaylistdlg, editplaylistdlg, "editplaylistdlg"); - GLADE_HOOKUP_OBJECT_NO_REF (editplaylistdlg, dialog_vbox3, "dialog_vbox3"); - GLADE_HOOKUP_OBJECT (editplaylistdlg, vbox15, "vbox15"); - GLADE_HOOKUP_OBJECT (editplaylistdlg, hbox33, "hbox33"); - GLADE_HOOKUP_OBJECT (editplaylistdlg, label40, "label40"); - GLADE_HOOKUP_OBJECT (editplaylistdlg, title, "title"); - GLADE_HOOKUP_OBJECT_NO_REF (editplaylistdlg, dialog_action_area3, "dialog_action_area3"); - GLADE_HOOKUP_OBJECT (editplaylistdlg, cancelbutton2, "cancelbutton2"); - GLADE_HOOKUP_OBJECT (editplaylistdlg, alignment17, "alignment17"); - GLADE_HOOKUP_OBJECT (editplaylistdlg, hbox58, "hbox58"); - GLADE_HOOKUP_OBJECT (editplaylistdlg, image396, "image396"); - GLADE_HOOKUP_OBJECT (editplaylistdlg, label94, "label94"); - GLADE_HOOKUP_OBJECT (editplaylistdlg, okbutton2, "okbutton2"); - GLADE_HOOKUP_OBJECT (editplaylistdlg, alignment16, "alignment16"); - GLADE_HOOKUP_OBJECT (editplaylistdlg, hbox57, "hbox57"); - GLADE_HOOKUP_OBJECT (editplaylistdlg, image395, "image395"); - GLADE_HOOKUP_OBJECT (editplaylistdlg, label93, "label93"); - - return editplaylistdlg; + GLADE_HOOKUP_OBJECT_NO_REF (entrydialog, entrydialog, "entrydialog"); + GLADE_HOOKUP_OBJECT_NO_REF (entrydialog, dialog_vbox3, "dialog_vbox3"); + GLADE_HOOKUP_OBJECT (entrydialog, vbox15, "vbox15"); + GLADE_HOOKUP_OBJECT (entrydialog, hbox33, "hbox33"); + GLADE_HOOKUP_OBJECT (entrydialog, title_label, "title_label"); + GLADE_HOOKUP_OBJECT (entrydialog, title, "title"); + GLADE_HOOKUP_OBJECT_NO_REF (entrydialog, dialog_action_area3, "dialog_action_area3"); + GLADE_HOOKUP_OBJECT (entrydialog, cancelbutton2, "cancelbutton2"); + GLADE_HOOKUP_OBJECT (entrydialog, alignment17, "alignment17"); + GLADE_HOOKUP_OBJECT (entrydialog, hbox58, "hbox58"); + GLADE_HOOKUP_OBJECT (entrydialog, image396, "image396"); + GLADE_HOOKUP_OBJECT (entrydialog, label94, "label94"); + GLADE_HOOKUP_OBJECT (entrydialog, okbutton2, "okbutton2"); + GLADE_HOOKUP_OBJECT (entrydialog, alignment16, "alignment16"); + GLADE_HOOKUP_OBJECT (entrydialog, hbox57, "hbox57"); + GLADE_HOOKUP_OBJECT (entrydialog, image395, "image395"); + GLADE_HOOKUP_OBJECT (entrydialog, label93, "label93"); + + return entrydialog; } GtkWidget* diff --git a/plugins/gtkui/interface.h b/plugins/gtkui/interface.h index fdd08f3e..01e488c0 100644 --- a/plugins/gtkui/interface.h +++ b/plugins/gtkui/interface.h @@ -10,7 +10,7 @@ GtkWidget* create_helpwindow (void); GtkWidget* create_trackproperties (void); GtkWidget* create_editcolumndlg (void); GtkWidget* create_prefwin (void); -GtkWidget* create_editplaylistdlg (void); +GtkWidget* create_entrydialog (void); GtkWidget* create_addlocationdlg (void); GtkWidget* create_groupbydlg (void); GtkWidget* create_sortbydlg (void); diff --git a/plugins/gtkui/trkproperties.c b/plugins/gtkui/trkproperties.c index cf6af9a8..66eb24e8 100644 --- a/plugins/gtkui/trkproperties.c +++ b/plugins/gtkui/trkproperties.c @@ -23,6 +23,7 @@ #include <gdk/gdkkeysyms.h> #include <string.h> #include <math.h> +#include <assert.h> #include "../../gettext.h" #include "ddblistview.h" #include "trkproperties.h" @@ -37,12 +38,71 @@ //#define trace(...) { fprintf(stderr, __VA_ARGS__); } #define trace(fmt,...) +#define min(x,y) ((x)<(y)?(x):(y)) + static GtkWidget *trackproperties; static DB_playItem_t *track; static GtkCellRenderer *rend_text2; static GtkListStore *store; static GtkListStore *propstore; static int trkproperties_modified; +static DB_playItem_t **tracks; +static int numtracks; + +static void +build_key_list () { +} + +static int +get_field_value (char *out, int size, const char *key) { + int multiple = 0; + *out = 0; + if (numtracks == 0) { + return 0; + } + char *p = out; + deadbeef->pl_lock (); + const char **prev = malloc (sizeof (const char *) * numtracks); + memset (prev, 0, sizeof (const char *) * numtracks); + for (int i = 0; i < numtracks; i++) { + const char *val = deadbeef->pl_find_meta (tracks[i], key); + if (val && val[0] == 0) { + val = NULL; + } + if (i > 0) { + int n = 0; + for (; n < i; n++) { + if (prev[n] == val) { + break; + } + } + if (n == i) { + size_t l; + l = snprintf (out, size, "; %s", val ? val : ""); + multiple = 1; + l = min (l, size); + out += l; + size -= l; + } + } + else { + size_t l = snprintf (out, size, "%s", val ? val : ""); + l = min (l, size); + out += l; + size -= l; + } + prev[i] = val; + if (size <= 1) { + break; + } + } + if (size <= 1) { + strcpy (out-2, "…"); + } + free (prev); + deadbeef->pl_unlock (); + return multiple; +} gboolean on_trackproperties_delete_event (GtkWidget *widget, @@ -68,6 +128,14 @@ on_trackproperties_delete_event (GtkWidget *widget, deadbeef->pl_item_unref (track); track = NULL; } + if (tracks) { + for (int i = 0; i < numtracks; i++) { + deadbeef->pl_item_unref (tracks[i]); + } + free (tracks); + tracks = NULL; + numtracks = 0; + } return TRUE; } @@ -143,6 +211,8 @@ trkproperties_fill_metadata (void) { gtk_list_store_clear (store); deadbeef->pl_lock (); + struct timeval tm1; + gettimeofday (&tm1, NULL); // add "standard" fields int i = 0; while (types[i]) { @@ -150,9 +220,15 @@ trkproperties_fill_metadata (void) { if (!value) { value = ""; } + const char mult[] = _("[Multiple values] "); + char val[1000]; + size_t ml = strlen (mult); + memcpy (val, mult, ml+1); + int n = get_field_value (val + ml, sizeof (val) - ml, types[i]); + GtkTreeIter iter; gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, _(types[i+1]), 1, value, 2, types[i], -1); + gtk_list_store_set (store, &iter, 0, _(types[i+1]), 1, n ? val : val + ml, 2, types[i], -1); i += 2; } @@ -222,6 +298,13 @@ trkproperties_fill_metadata (void) { snprintf (title, sizeof (title), "<%s>", meta->key); const char *value = meta->value; const char *key = meta->key; + + const char mult[] = _("[Multiple values] "); + char val[1000]; + size_t ml = strlen (mult); + memcpy (val, mult, ml+1); + int n = get_field_value (val + ml, sizeof (val) - ml, meta->key); + meta = meta->next; if (!value) { @@ -230,14 +313,58 @@ trkproperties_fill_metadata (void) { GtkTreeIter iter; gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, _(title), 1, value, 2, key, -1); + gtk_list_store_set (store, &iter, 0, _(title), 1, n ? val : val + ml, 2, key, -1); } + struct timeval tm2; + gettimeofday (&tm2, NULL); + int ms = (tm2.tv_sec*1000+tm2.tv_usec/1000) - (tm1.tv_sec*1000+tm1.tv_usec/1000); deadbeef->pl_unlock (); } void show_track_properties_dlg (DB_playItem_t *it) { + + deadbeef->plt_lock (); + deadbeef->pl_lock (); + + if (tracks) { + for (int i = 0; i < numtracks; i++) { + deadbeef->pl_item_unref (tracks[i]); + } + free (tracks); + tracks = NULL; + numtracks = 0; + } + + int nsel = deadbeef->pl_getselcount (); + if (0 < nsel) { + tracks = malloc (sizeof (DB_playItem_t *) * nsel); + if (tracks) { + int n = 0; + DB_playItem_t *it = deadbeef->pl_get_first (PL_MAIN); + while (it) { + if (deadbeef->pl_is_selected (it)) { + assert (n < nsel); + deadbeef->pl_item_ref (it); + tracks[n++] = it; + } + DB_playItem_t *next = deadbeef->pl_get_next (it, PL_MAIN); + deadbeef->pl_item_unref (it); + it = next; + } + numtracks = nsel; + } + else { + deadbeef->pl_unlock (); + deadbeef->plt_unlock (); + return; + } + } + + deadbeef->pl_unlock (); + deadbeef->plt_unlock (); + if (track) { deadbeef->pl_item_unref (track); track = NULL; @@ -377,3 +504,108 @@ on_write_tags_clicked (GtkButton *button, } trkproperties_modified = 0; } + +void +on_add_field_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), _("Name:")); + int res = gtk_dialog_run (GTK_DIALOG (dlg)); + if (res == GTK_RESPONSE_OK) { + e = lookup_widget (dlg, "title"); + const char *text = gtk_entry_get_text (GTK_ENTRY(e)); + + int l = strlen (text); + char title[l+3]; + snprintf (title, sizeof (title), "<%s>", text); + const char *value = ""; + const char *key = text; + + GtkTreeIter iter; + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, 0, title, 1, value, 2, key, -1); + trkproperties_modified = 1; + + } + gtk_widget_destroy (dlg); +} + +void +on_remove_field_activate (GtkMenuItem *menuitem, + gpointer user_data) { + + GtkTreePath *path; + GtkTreeViewColumn *col; + GtkTreeView *treeview = GTK_TREE_VIEW (lookup_widget (trackproperties, "metalist")); + gtk_tree_view_get_cursor (treeview, &path, &col); + if (!path || !col) { + return; + } + + GtkWidget *dlg = gtk_message_dialog_new (GTK_WINDOW (mainwin), GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, _("Really remove selected field?")); +// gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dlg), _("Files will be lost. Proceed?\n(This dialog can be turned off in GTKUI plugin settings)")); + gtk_window_set_title (GTK_WINDOW (dlg), _("Warning")); + + int response = gtk_dialog_run (GTK_DIALOG (dlg)); + gtk_widget_destroy (dlg); + if (response != GTK_RESPONSE_YES) { + return; + } + + GtkTreeIter iter; + gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path); + GValue value = {0,}; + gtk_tree_model_get_value (GTK_TREE_MODEL (store), &iter, 2, &value); + const char *svalue = g_value_get_string (&value); + + // delete unknown fields completely; otherwise just clear + int i = 0; + for (; types[i]; i += 2) { + if (!strcmp (svalue, types[i])) { + break; + } + } + if (types[i]) { // known val, clear + gtk_list_store_set (store, &iter, 1, "", -1); + } + else { + gtk_list_store_remove (store, &iter); + } + gtk_tree_path_free (path); + trkproperties_modified = 1; +} + +gboolean +on_metalist_button_press_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data) +{ + if (event->button == 3) { + GtkWidget *menu; + GtkWidget *add; + GtkWidget *remove; + menu = gtk_menu_new (); + add = gtk_menu_item_new_with_mnemonic (_("Add field")); + gtk_widget_show (add); + gtk_container_add (GTK_CONTAINER (menu), add); + remove = gtk_menu_item_new_with_mnemonic (_("Remove field")); + gtk_widget_show (remove); + gtk_container_add (GTK_CONTAINER (menu), remove); + + g_signal_connect ((gpointer) add, "activate", + G_CALLBACK (on_add_field_activate), + NULL); + + g_signal_connect ((gpointer) remove, "activate", + G_CALLBACK (on_remove_field_activate), + NULL); + + gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, widget, event->button, gtk_get_current_event_time()); + } + return FALSE; +} + |