summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2011-02-27 21:41:18 +0100
committerGravatar waker <wakeroid@gmail.com>2011-02-27 21:41:18 +0100
commitda1faaf258338f3d2d91ce0ffe9d013336407339 (patch)
treed81fc3087fe5685a0611c1dd516337b818cff719
parentfefa370d326db32638bd9d1818ff6031e759d9c5 (diff)
display info for all selected tracks in track properties
-rw-r--r--playlist.c4
-rw-r--r--plugins/gtkui/callbacks.c1
-rw-r--r--plugins/gtkui/callbacks.h5
-rw-r--r--plugins/gtkui/ddbtabstrip.c7
-rw-r--r--plugins/gtkui/deadbeef.glade7
-rw-r--r--plugins/gtkui/interface.c71
-rw-r--r--plugins/gtkui/interface.h2
-rw-r--r--plugins/gtkui/trkproperties.c236
8 files changed, 289 insertions, 44 deletions
diff --git a/playlist.c b/playlist.c
index 2f2a9097..3bd6af64 100644
--- a/playlist.c
+++ b/playlist.c
@@ -60,8 +60,8 @@
#define PLAYLIST_MAJOR_VER 1
#define PLAYLIST_MINOR_VER 2
-#define trace(...) { fprintf(stderr, __VA_ARGS__); }
-//#define trace(fmt,...)
+//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+#define trace(fmt,...)
#define SKIP_BLANK_CUE_TRACKS 0
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;
+}
+