[gtk+] [filechooser] bgo#349502: Context menu option to copy selected files to the clipboard



commit c9023cadbfed9a4831287a366cc3367c7baa436c
Author: Arx Cruz <arxcruz gnome org>
Date:   Thu Aug 4 15:34:16 2011 -0300

    [filechooser] bgo#349502: Context menu option to copy selected files to the clipboard

 gtk/gtkfilechooserdefault.c |  126 +++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkfilechooserprivate.h |    1 +
 2 files changed, 127 insertions(+), 0 deletions(-)
---
diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c
index 15c0099..ae54d2a 100644
--- a/gtk/gtkfilechooserdefault.c
+++ b/gtk/gtkfilechooserdefault.c
@@ -86,6 +86,10 @@
 #include <io.h>
 #endif
 
+/* Values for GtkSelection-related "info" fields */
+#define SELECTION_TEXT 0
+#define SELECTION_URI  1
+
 /* Profiling stuff */
 #undef PROFILE_FILE_CHOOSER
 #ifdef PROFILE_FILE_CHOOSER
@@ -96,6 +100,7 @@
 #endif
 
 #define PROFILE_INDENT 4
+
 static int profile_indent;
 
 static void
@@ -3787,6 +3792,7 @@ popup_menu_detach_cb (GtkWidget *attach_widget,
   impl->browse_files_popup_menu = NULL;
   impl->browse_files_popup_menu_add_shortcut_item = NULL;
   impl->browse_files_popup_menu_hidden_files_item = NULL;
+  impl->browse_files_popup_menu_copy_file_location_item = NULL;
 }
 
 /* Callback used when the "Add to Bookmarks" menu item is activated */
@@ -3797,6 +3803,97 @@ add_to_shortcuts_cb (GtkMenuItem           *item,
   bookmarks_add_selected_folder (impl);
 }
 
+/* callback used to set data to clipboard */
+static void
+copy_file_get_cb  (GtkClipboard     *clipboard,
+                   GtkSelectionData *selection_data,
+                   guint             info,
+                   gpointer          data)
+{
+  GSList *selected_files = data;
+
+  if (selected_files)
+    {
+      gint num_files = g_slist_length (selected_files);
+      gchar **uris;
+      gint i;
+      GSList *l;
+
+      uris = g_new (gchar *, num_files + 1);
+      uris[num_files] = NULL; /* null terminator */
+
+      i = 0;
+
+      for (l = selected_files; l; l = l->next)
+        {
+          GFile *file = (GFile *) l->data;
+
+	  if (info == SELECTION_URI)
+	    uris[i] = g_file_get_uri (file);
+	  else /* if (info == SELECTION_TEXT) - let this be the fallback */
+	    uris[i] = g_file_get_parse_name (file);
+
+          i++;
+        }
+
+      if (info == SELECTION_URI)
+	gtk_selection_data_set_uris (selection_data, uris);
+      else /* if (info == SELECTION_TEXT) - let this be the fallback */
+	{
+	  char *str = g_strjoinv (" ", uris);
+	  gtk_selection_data_set_text (selection_data, str, -1);
+	  g_free (str);
+	}
+
+      g_strfreev (uris);
+    }
+}
+
+/* callback used to clear the clipboard data */
+static void
+copy_file_clear_cb (GtkClipboard *clipboard,
+                    gpointer      data)
+{
+  GSList *selected_files = data;
+
+  g_slist_foreach (selected_files, (GFunc) g_object_unref, NULL);
+  g_slist_free (selected_files);
+}
+
+/* Callback used when the "Copy file's location" menu item is activated */
+static void
+copy_file_location_cb (GtkMenuItem           *item,
+                       GtkFileChooserDefault *impl)
+{
+  GSList *selected_files = NULL;
+
+  selected_files = search_get_selected_files (impl);
+
+  if (selected_files)
+    {
+      GtkClipboard *clipboard;
+      GtkTargetList *target_list;
+      GtkTargetEntry *targets;
+      int n_targets;
+
+      clipboard = gtk_widget_get_clipboard (GTK_WIDGET (impl), GDK_SELECTION_CLIPBOARD);
+
+      target_list = gtk_target_list_new (NULL, 0);
+      gtk_target_list_add_text_targets (target_list, SELECTION_TEXT);
+      gtk_target_list_add_uri_targets (target_list, SELECTION_URI);
+
+      targets = gtk_target_table_new_from_list (target_list, &n_targets);
+      gtk_target_list_unref (target_list);
+
+      gtk_clipboard_set_with_data (clipboard, targets, n_targets,
+				   copy_file_get_cb,
+                                   copy_file_clear_cb,
+				   selected_files);
+
+      gtk_target_table_free (targets, n_targets);
+    }
+}
+
 /* Callback used when the "Show Hidden Files" menu item is toggled */
 static void
 show_hidden_toggled_cb (GtkCheckMenuItem      *item,
@@ -3984,6 +4081,24 @@ file_list_drag_motion_cb (GtkWidget             *widget,
   return TRUE;
 }
 
+/* Sensitizes the "Copy file's location" context menu item if there is actually
+ * a selection active.
+ */
+static void
+check_copy_file_location_sensitivity (GtkFileChooserDefault *impl)
+{
+  GtkTreeSelection *selection;
+  gboolean active;
+
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_files_tree_view));
+  if (gtk_tree_selection_count_selected_rows (selection) == 0)
+    active = FALSE;
+  else
+    active = TRUE;
+
+  gtk_widget_set_sensitive (impl->browse_files_popup_menu_copy_file_location_item, active);
+}
+
 /* Constructs the popup menu for the file list if needed */
 static void
 file_list_build_popup_menu (GtkFileChooserDefault *impl)
@@ -3998,6 +4113,15 @@ file_list_build_popup_menu (GtkFileChooserDefault *impl)
 			     impl->browse_files_tree_view,
 			     popup_menu_detach_cb);
 
+  item = gtk_image_menu_item_new_with_mnemonic (_("_Copy file's location"));
+  impl->browse_files_popup_menu_copy_file_location_item = item;
+  gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
+                                 gtk_image_new_from_stock (GTK_STOCK_COPY, GTK_ICON_SIZE_MENU));
+  g_signal_connect (item, "activate",
+                    G_CALLBACK (copy_file_location_cb), impl);
+  gtk_widget_show (item);
+  gtk_menu_shell_append (GTK_MENU_SHELL (impl->browse_files_popup_menu), item);
+
   item = gtk_image_menu_item_new_with_mnemonic (_("_Add to Bookmarks"));
   impl->browse_files_popup_menu_add_shortcut_item = item;
   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
@@ -4026,6 +4150,7 @@ file_list_build_popup_menu (GtkFileChooserDefault *impl)
   gtk_menu_shell_append (GTK_MENU_SHELL (impl->browse_files_popup_menu), item);
 
   bookmarks_check_add_sensitivity (impl);
+  check_copy_file_location_sensitivity (impl);
 }
 
 /* Updates the popup menu for the file list, creating it if necessary */
@@ -9969,6 +10094,7 @@ list_selection_changed (GtkTreeSelection      *selection,
 
   check_preview_change (impl);
   bookmarks_check_add_sensitivity (impl);
+  check_copy_file_location_sensitivity (impl);
 
   g_signal_emit_by_name (impl, "selection-changed", 0);
 }
diff --git a/gtk/gtkfilechooserprivate.h b/gtk/gtkfilechooserprivate.h
index dd4bccb..81fc3b2 100644
--- a/gtk/gtkfilechooserprivate.h
+++ b/gtk/gtkfilechooserprivate.h
@@ -180,6 +180,7 @@ struct _GtkFileChooserDefault
   GtkWidget *browse_files_popup_menu_add_shortcut_item;
   GtkWidget *browse_files_popup_menu_hidden_files_item;
   GtkWidget *browse_files_popup_menu_size_column_item;
+  GtkWidget *browse_files_popup_menu_copy_file_location_item;
   GtkWidget *browse_new_folder_button;
   GtkWidget *browse_path_bar_hbox;
   GtkSizeGroup *browse_path_bar_size_group;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]