From cb10c6d3c4ee7c568575870d627f3b707d79b3f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D1=83=D1=81=D0=BB=D0=B0=D0=BD=20=D0=98=D0=B6=D0=B1=D1?= =?UTF-8?q?=83=D0=BB=D0=B0=D1=82=D0=BE=D0=B2?= Date: Fri, 16 Dec 2011 13:13:59 +0400 Subject: [PATCH 2/3] Make metadata copyable --- contrib/gnunet_fs_gtk_main_window.glade | 16 +++ src/fs/gnunet-fs-gtk-event_handler.c | 176 +++++++++++++++++++++++++++++++ src/fs/gnunet-fs-gtk.c | 6 + 3 files changed, 198 insertions(+), 0 deletions(-) diff --git a/contrib/gnunet_fs_gtk_main_window.glade b/contrib/gnunet_fs_gtk_main_window.glade index c741281..a47a445 100644 --- a/contrib/gnunet_fs_gtk_main_window.glade +++ b/contrib/gnunet_fs_gtk_main_window.glade @@ -604,6 +604,8 @@ 0 True both + + autosize @@ -849,6 +851,20 @@ + + True + False + + + False + True + False + Copy selection + True + + + + False GDK_LEAVE_NOTIFY_MASK | GDK_STRUCTURE_MASK diff --git a/src/fs/gnunet-fs-gtk-event_handler.c b/src/fs/gnunet-fs-gtk-event_handler.c index 74c3ab5..8565bd0 100644 --- a/src/fs/gnunet-fs-gtk-event_handler.c +++ b/src/fs/gnunet-fs-gtk-event_handler.c @@ -1934,6 +1934,182 @@ GNUNET_GTK_main_window_notebook_switch_page_cb (GtkWidget * dummy, gtk_list_store_clear (ms); } +static void +copy_metadata_to_clipboard (GtkTreeModel *model, GtkTreePath *path, + GtkTreeIter *iter, gpointer user_data) +{ + gchar *type, *value; + GList **l = (GList **) user_data; + + gtk_tree_model_get (model, iter, 2, &type, 3, &value, -1); + + *l = g_list_prepend (*l, type); + *l = g_list_prepend (*l, value); +} + +void +metadata_copy_selection_activated (GtkMenuItem *menuitem, gpointer user_data) +{ + GtkBuilder *builder; + GtkTreeView *tree; + GtkClipboard *cb; + GList *pairs = NULL, *l, *next, *value, *type; + guint total_len; + gchar *s, *p; + + builder = GTK_BUILDER (user_data); + tree = GTK_TREE_VIEW (gtk_builder_get_object (builder, + "GNUNET_GTK_main_window_metadata_treeview")); + + gtk_tree_selection_selected_foreach (gtk_tree_view_get_selection (tree), + copy_metadata_to_clipboard, &pairs); + + total_len = 0; + pairs = g_list_reverse (pairs); + for (l = pairs; l; l = next) + { + type = l; + value = l->next; + if (!value) + break; + next = value->next; + total_len += strlen ((gchar *) type->data) + + strlen ((gchar *) value->data) + 2 /* ": " */ + (next ? 1 : 0) /* "\n" */; + } + if (total_len > 0) + { + total_len += 1; /* "\0" */ + s = g_new0 (gchar, total_len); + p = s; + for (l = pairs; l; l = next) + { + type = l; + value = l->next; + if (value) + { + next = value->next; + p = g_stpcpy (p, (gchar *) type->data); + p = g_stpcpy (p, ": "); + p = g_stpcpy (p, (gchar *) value->data); + if (next) + p = g_stpcpy (p, "\n"); + } + else + next = NULL; + } + } + g_list_foreach (pairs, (GFunc) g_free, NULL); + g_list_free (pairs); + pairs = NULL; + + if (total_len > 0) + { + cb = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); + gtk_clipboard_set_text (cb, s, -1); + gtk_clipboard_store (cb); + g_free (s); + } +} + +void +metadata_menu_popup_position (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, + gpointer user_data) +{ + GtkBuilder *builder; + GtkTreeView *tree; + GtkTreeSelection *sel; + GList *rows; + GtkTreePath *p; + GtkAllocation tree_allocation; + GdkWindow *main_window_gdk; + gint mwg_x, mwg_y, t_x, t_y, popup_x, popup_y; + + builder = GTK_BUILDER (user_data); + + tree = GTK_TREE_VIEW (gtk_builder_get_object (builder, + "GNUNET_GTK_main_window_metadata_treeview")); + + gtk_widget_get_allocation (GTK_WIDGET (tree), &tree_allocation); + + main_window_gdk = gtk_widget_get_window (GTK_WIDGET (tree)); + + gdk_window_get_origin (main_window_gdk, &mwg_x, &mwg_y); + + t_x = mwg_x + tree_allocation.x; + t_y = mwg_y + tree_allocation.y; + popup_x = t_x; + popup_y = t_y; + + sel = gtk_tree_view_get_selection (tree); + + rows = gtk_tree_selection_get_selected_rows (sel, NULL); + + if (rows->data) + { + GdkRectangle r; + p = (GtkTreePath *) rows->data; + gtk_tree_view_get_cell_area (tree, p, NULL, &r); + popup_x += r.x; + popup_y += r.y; + } + + g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL); + g_list_free (rows); + *x = popup_x; + *y = popup_y; + *push_in = FALSE; +} + +static void +do_metadata_popup_menu (GtkWidget *widget, GdkEventButton *event, + gpointer user_data) +{ + GtkMenu *menu; + GtkBuilder *builder; + int button, event_time; + GtkMenuPositionFunc mpf = NULL; + + builder = GTK_BUILDER (user_data); + + menu = GTK_MENU (gtk_builder_get_object (builder, "metadata_popup_menu")); + + if (event) + { + button = event->button; + event_time = event->time; + } + else + { + button = 0; + event_time = gtk_get_current_event_time (); + } + + gtk_menu_attach_to_widget (menu, widget, NULL); + gtk_menu_popup (menu, NULL, NULL, mpf, user_data, + button, event_time); +} + +gboolean +GNUNET_GTK_main_window_metadata_treeview_button_press_event_cb (GtkWidget *widget, + GdkEventButton *event, gpointer user_data) +{ + /* Ignore double-clicks and triple-clicks */ + if (event->button == 3 && event->type == GDK_BUTTON_PRESS) + { + do_metadata_popup_menu (widget, event, user_data); + return TRUE; + } + + return FALSE; +} + +gboolean +GNUNET_GTK_main_window_metadata_treeview_popup_menu_cb (GtkWidget *widget, + gpointer user_data) +{ + do_metadata_popup_menu (widget, NULL, user_data); + return TRUE; +} /* end of gnunet-fs-gtk-event_handler.c */ diff --git a/src/fs/gnunet-fs-gtk.c b/src/fs/gnunet-fs-gtk.c index e115395..dd4c951 100644 --- a/src/fs/gnunet-fs-gtk.c +++ b/src/fs/gnunet-fs-gtk.c @@ -572,6 +572,7 @@ GNUNET_GTK_main_window_realize_cb (GtkWidget *widget, gpointer user_data) GtkTreeStore *namespace_treestore; GtkBuilder *builder; GtkWidget *namespace_selector_window; + GtkTreeView *metadata_tree; builder = GTK_BUILDER (user_data); @@ -579,6 +580,11 @@ GNUNET_GTK_main_window_realize_cb (GtkWidget *widget, gpointer user_data) ("main_window_search_namespace_treestore")); namespace_tree = GTK_TREE_VIEW (GNUNET_FS_GTK_get_main_window_object ("namespace_selector_treeview")); + metadata_tree = GTK_TREE_VIEW (GNUNET_FS_GTK_get_main_window_object + ("GNUNET_GTK_main_window_metadata_treeview")); + + /* Allow multiple selection in metadata view */ + gtk_tree_selection_set_mode (gtk_tree_view_get_selection (metadata_tree), GTK_SELECTION_MULTIPLE); /* FIXME: find a way to manage pseudonyms. * Right now the list will be filled with ALL and ANY pseudonyms that we -- 1.7.4