[gthumb/ext] allow to copy files to the current location with drag & drop



commit 42ab2899dab025e4f4eb65388586bd2a039918eb
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sun Aug 23 17:12:53 2009 +0200

    allow to copy files to the current location with drag & drop

 extensions/file_manager/callbacks.c |   96 +++++++++++++++++++++++++++++++++++
 gthumb/glib-utils.c                 |   16 ++++++
 gthumb/glib-utils.h                 |    1 +
 3 files changed, 113 insertions(+), 0 deletions(-)
---
diff --git a/extensions/file_manager/callbacks.c b/extensions/file_manager/callbacks.c
index 387af9c..8b7cd25 100644
--- a/extensions/file_manager/callbacks.c
+++ b/extensions/file_manager/callbacks.c
@@ -27,6 +27,7 @@
 #include <gdk/gdkkeysyms.h>
 #include <gthumb.h>
 #include "actions.h"
+#include "gth-copy-task.h"
 
 
 #define BROWSER_DATA_KEY "file-manager-browser-data"
@@ -119,6 +120,11 @@ static const char *folder_popup_ui_info =
 "</ui>";
 
 
+static GtkTargetEntry drag_dest_targets[] = {
+        { "text/uri-list", 0, 0 }
+};
+
+
 static GtkActionEntry action_entries[] = {
 	{ "File_NewFolder", "folder-new",
 	  N_("Create _Folder"), "<control><shift>N",
@@ -212,10 +218,89 @@ set_action_sensitive (BrowserData *data,
 }
 
 
+static void
+gth_file_list_drag_data_received (GtkWidget        *widget,
+				  GdkDragContext   *context,
+				  int               x,
+				  int               y,
+				  GtkSelectionData *data,
+				  guint             info,
+				  guint             time,
+				  gpointer          extra_data)
+{
+	GthBrowser  *browser = extra_data;
+	gboolean     success = FALSE;
+	char       **uris;
+	GList       *file_list;
+
+	g_signal_stop_emission_by_name (widget, "drag-data-received");
+
+	if (gtk_drag_get_source_widget (context) == gth_file_list_get_view (GTH_FILE_LIST (gth_browser_get_file_list (browser)))) {
+		gtk_drag_finish (context, FALSE, FALSE, time);
+		return;
+	}
+
+	if ((context->suggested_action == GDK_ACTION_COPY)
+	    || (context->suggested_action == GDK_ACTION_MOVE))
+	{
+		success = TRUE;
+	}
+
+	gtk_drag_finish (context, success, FALSE, time);
+
+	uris = gtk_selection_data_get_uris (data);
+	file_list = _g_file_list_new_from_uriv (uris);
+	if (file_list != NULL) {
+		GthFileSource *file_source;
+		gboolean       cancel = FALSE;
+		gboolean       move;
+
+		file_source = gth_browser_get_location_source (browser);
+		move = context->suggested_action == GDK_ACTION_MOVE;
+		if (move && ! gth_file_source_can_cut (file_source)) {
+			GtkWidget *dialog;
+			int        response;
+
+			dialog = _gtk_message_dialog_new (GTK_WINDOW (browser),
+							  GTK_DIALOG_MODAL,
+							  GTK_STOCK_DIALOG_QUESTION,
+							  _("Could not move the files"),
+							  _("Files cannot be moved to the current location, as alternative you can choose to copy them."),
+							  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+							  GTK_STOCK_COPY, GTK_RESPONSE_OK,
+							  NULL);
+			response = gtk_dialog_run (GTK_DIALOG (dialog));
+			gtk_widget_destroy (dialog);
+
+			if (response == GTK_RESPONSE_CANCEL)
+				cancel = TRUE;
+
+			move = FALSE;
+		}
+
+		if (! cancel) {
+			GthTask *task;
+
+			task = gth_copy_task_new (file_source,
+						  gth_browser_get_location_data (browser),
+						  move,
+						  file_list);
+			gth_browser_exec_task (browser, task, FALSE);
+
+			g_object_unref (task);
+		}
+	}
+
+	_g_object_list_unref (file_list);
+	g_strfreev (uris);
+}
+
+
 void
 fm__gth_browser_construct_cb (GthBrowser *browser)
 {
 	BrowserData *data;
+	GtkWidget   *file_view;
 
 	g_return_if_fail (GTH_IS_BROWSER (browser));
 
@@ -230,6 +315,17 @@ fm__gth_browser_construct_cb (GthBrowser *browser)
 	gtk_ui_manager_insert_action_group (gth_browser_get_ui_manager (browser), data->action_group, 0);
 	set_action_sensitive (data, "Edit_PasteInFolder", FALSE);
 
+	file_view = gth_file_list_get_view (GTH_FILE_LIST (gth_browser_get_file_list (browser)));
+	gtk_drag_dest_set (file_view,
+                           GTK_DEST_DEFAULT_ALL,
+                           drag_dest_targets,
+                           G_N_ELEMENTS (drag_dest_targets),
+                           GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK);
+	g_signal_connect (G_OBJECT (file_view),
+                          "drag_data_received",
+                          G_CALLBACK (gth_file_list_drag_data_received),
+                          browser);
+
 	g_object_set_data_full (G_OBJECT (browser), BROWSER_DATA_KEY, data, (GDestroyNotify) browser_data_free);
 }
 
diff --git a/gthumb/glib-utils.c b/gthumb/glib-utils.c
index 485e9b5..0f6e01e 100644
--- a/gthumb/glib-utils.c
+++ b/gthumb/glib-utils.c
@@ -1726,6 +1726,22 @@ _g_file_list_new_from_uri_list (GList *uris)
 
 
 GList *
+_g_file_list_new_from_uriv (char **uris)
+{
+	GList *r = NULL;
+	int    i;
+
+	if (uris == NULL)
+		return NULL;
+
+	for (i = 0; uris[i] != NULL; i++)
+		r = g_list_prepend (r, g_file_new_for_uri (uris[i]));
+
+	return g_list_reverse (r);
+}
+
+
+GList *
 _g_file_list_find_file (GList *l,
 			GFile *file)
 {
diff --git a/gthumb/glib-utils.h b/gthumb/glib-utils.h
index bd901b3..72f03a6 100644
--- a/gthumb/glib-utils.h
+++ b/gthumb/glib-utils.h
@@ -225,6 +225,7 @@ GIcon *         _g_file_get_icon                 (GFile      *file);
 GList *         _g_file_list_dup                 (GList      *l);
 void            _g_file_list_free                (GList      *l);
 GList *         _g_file_list_new_from_uri_list   (GList      *uris);
+GList *         _g_file_list_new_from_uriv       (char      **uris);
 GList *         _g_file_list_find_file           (GList      *l,
 						  GFile      *file);
 const char*     _g_file_get_mime_type            (GFile      *file,



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