[gthumb: 5/9] added drag&drop support to the folder tree
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb: 5/9] added drag&drop support to the folder tree
- Date: Tue, 27 Apr 2010 19:29:12 +0000 (UTC)
commit e485f71b82859a6ea8d63eb6b5d9a510aeb34838
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sun Apr 25 21:03:00 2010 +0200
added drag&drop support to the folder tree
[bug #593431]
extensions/file_manager/callbacks.c | 45 +++++++++++++++
extensions/file_manager/callbacks.h | 31 ++++++-----
extensions/file_manager/main.c | 1 +
gthumb/gth-browser.c | 107 +++++++++++++++++++++++++++++++++++
gthumb/gth-file-list.c | 6 +-
gthumb/gth-folder-tree.c | 28 +++++++++
gthumb/gth-folder-tree.h | 2 +
gthumb/gth-hook.c | 31 ++++++++++-
gthumb/gth-main-default-hooks.c | 11 ++++
9 files changed, 244 insertions(+), 18 deletions(-)
---
diff --git a/extensions/file_manager/callbacks.c b/extensions/file_manager/callbacks.c
index 51ce37d..a895f5d 100644
--- a/extensions/file_manager/callbacks.c
+++ b/extensions/file_manager/callbacks.c
@@ -673,6 +673,51 @@ fm__gth_browser_folder_tree_popup_before_cb (GthBrowser *browser,
}
+void
+fm__gth_browser_folder_tree_drag_data_received_cb (GthBrowser *browser,
+ GthFileData *destination,
+ GList *file_list,
+ GdkDragAction action)
+{
+ GthFileSource *file_source;
+ GthTask *task;
+
+ file_source = gth_main_get_file_source (destination->file);
+ if (file_source == NULL)
+ return;
+
+ if ((action == GDK_ACTION_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)
+ return;
+
+ action = GDK_ACTION_COPY;
+ }
+
+ task = gth_copy_task_new (file_source,
+ destination,
+ (action == GDK_ACTION_MOVE),
+ file_list);
+ gth_browser_exec_task (browser, task, FALSE);
+
+ g_object_unref (task);
+ g_object_unref (file_source);
+}
+
+
static void
clipboard_targets_received_cb (GtkClipboard *clipboard,
GdkAtom *atoms,
diff --git a/extensions/file_manager/callbacks.h b/extensions/file_manager/callbacks.h
index d891600..fbe71f0 100644
--- a/extensions/file_manager/callbacks.h
+++ b/extensions/file_manager/callbacks.h
@@ -25,19 +25,22 @@
#include <gthumb.h>
-void fm__gth_browser_construct_cb (GthBrowser *browser);
-void fm__gth_browser_update_sensitivity_cb (GthBrowser *browser);
-void fm__gth_browser_set_current_page_cb (GthBrowser *browser);
-void fm__gth_browser_load_location_after_cb (GthBrowser *browser,
- GFile *location,
- GError *error);
-void fm__gth_browser_folder_tree_popup_before_cb (GthBrowser *browser,
- GthFileSource *file_source,
- GFile *folder);
-void fm__gth_browser_selection_changed_cb (GthBrowser *browser);
-void fm__gth_browser_realize_cb (GthBrowser *browser);
-void fm__gth_browser_unrealize_cb (GthBrowser *browser);
-gpointer fm__gth_browser_file_list_key_press_cb (GthBrowser *browser,
- GdkEventKey *event);
+void fm__gth_browser_construct_cb (GthBrowser *browser);
+void fm__gth_browser_update_sensitivity_cb (GthBrowser *browser);
+void fm__gth_browser_set_current_page_cb (GthBrowser *browser);
+void fm__gth_browser_load_location_after_cb (GthBrowser *browser,
+ GFile *location,
+ GError *error);
+void fm__gth_browser_folder_tree_popup_before_cb (GthBrowser *browser,
+ GthFileSource *file_source,
+ GFile *folder);
+void fm__gth_browser_folder_tree_drag_data_received_cb (GthBrowser *browser,
+ GList *file_list,
+ GdkDragAction action);
+void fm__gth_browser_selection_changed_cb (GthBrowser *browser);
+void fm__gth_browser_realize_cb (GthBrowser *browser);
+void fm__gth_browser_unrealize_cb (GthBrowser *browser);
+gpointer fm__gth_browser_file_list_key_press_cb (GthBrowser *browser,
+ GdkEventKey *event);
#endif /* CALLBACKS_H */
diff --git a/extensions/file_manager/main.c b/extensions/file_manager/main.c
index a2a6d2d..0f78a5d 100644
--- a/extensions/file_manager/main.c
+++ b/extensions/file_manager/main.c
@@ -34,6 +34,7 @@ gthumb_extension_activate (void)
gth_hook_add_callback ("gth-browser-load-location-after", 10, G_CALLBACK (fm__gth_browser_load_location_after_cb), NULL);
gth_hook_add_callback ("gth-browser-set-current-page", 10, G_CALLBACK (fm__gth_browser_set_current_page_cb), NULL);
gth_hook_add_callback ("gth-browser-folder-tree-popup-before", 10, G_CALLBACK (fm__gth_browser_folder_tree_popup_before_cb), NULL);
+ gth_hook_add_callback ("gth-browser-folder-tree-drag-data-received", 10, G_CALLBACK (fm__gth_browser_folder_tree_drag_data_received_cb), NULL);
gth_hook_add_callback ("gth-browser-update-sensitivity", 10, G_CALLBACK (fm__gth_browser_update_sensitivity_cb), NULL);
gth_hook_add_callback ("gth-browser-realize", 10, G_CALLBACK (fm__gth_browser_realize_cb), NULL);
gth_hook_add_callback ("gth-browser-unrealize", 10, G_CALLBACK (fm__gth_browser_unrealize_cb), NULL);
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index 5d675b7..5cb0a2c 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -2270,6 +2270,80 @@ connect_proxy_cb (GtkUIManager *manager,
static void
+folder_tree_drag_data_received (GtkWidget *tree_view,
+ GdkDragContext *context,
+ int x,
+ int y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ gpointer user_data)
+{
+ GthBrowser *browser = user_data;
+ gboolean success = FALSE;
+ GtkTreePath *path;
+ GthFileData *destination;
+ char **uris;
+ GList *file_list;
+
+ if ((context->suggested_action == GDK_ACTION_COPY)
+ || (context->suggested_action == GDK_ACTION_MOVE))
+ {
+ success = TRUE;
+ }
+
+ if (! gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (browser->priv->folder_tree),
+ x, y,
+ &path,
+ NULL))
+ {
+ success = FALSE;
+ }
+
+ gtk_drag_finish (context, success, FALSE, time);
+
+ if (! success)
+ return;
+
+ destination = gth_folder_tree_get_file (GTH_FOLDER_TREE (browser->priv->folder_tree), path);
+ uris = gtk_selection_data_get_uris (selection_data);
+ file_list = _g_file_list_new_from_uriv (uris);
+ if (file_list != NULL)
+ gth_hook_invoke ("gth-browser-folder-tree-drag-data-received", browser, destination, file_list, context->suggested_action);
+
+ _g_object_list_unref (file_list);
+ g_strfreev (uris);
+ g_object_unref (destination);
+}
+
+
+static void
+folder_tree_drag_data_get_cb (GtkWidget *widget,
+ GdkDragContext *drag_context,
+ GtkSelectionData *data,
+ guint info,
+ guint time,
+ gpointer user_data)
+{
+ GthBrowser *browser = user_data;
+ GthFileData *file_data;
+ char **uris;
+
+ file_data = gth_folder_tree_get_selected (GTH_FOLDER_TREE (browser->priv->folder_tree));
+ if (file_data == NULL)
+ return;
+
+ uris = g_new (char *, 2);
+ uris[0] = g_file_get_uri (file_data->file);
+ uris[1] = NULL;
+ gtk_selection_data_set_uris (data, uris);
+
+ g_strfreev (uris);
+ g_object_unref (file_data);
+}
+
+
+static void
folder_tree_open_cb (GthFolderTree *folder_tree,
GFile *file,
GthBrowser *browser)
@@ -3637,6 +3711,39 @@ _gth_browser_construct (GthBrowser *browser)
gtk_container_add (GTK_CONTAINER (scrolled_window), browser->priv->folder_tree);
gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 0);
+ {
+ GtkTargetList *target_list;
+ GtkTargetEntry *targets;
+ int n_targets;
+
+ target_list = gtk_target_list_new (NULL, 0);
+ gtk_target_list_add_uri_targets (target_list, 0);
+ gtk_target_list_add_text_targets (target_list, 0);
+ targets = gtk_target_table_new_from_list (target_list, &n_targets);
+
+ gtk_tree_view_enable_model_drag_dest (GTK_TREE_VIEW (browser->priv->folder_tree),
+ targets,
+ n_targets,
+ GDK_ACTION_MOVE | GDK_ACTION_COPY);
+ gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (browser->priv->folder_tree),
+ GDK_BUTTON1_MASK,
+ targets,
+ n_targets,
+ GDK_ACTION_MOVE | GDK_ACTION_COPY);
+
+ g_signal_connect (browser->priv->folder_tree,
+ "drag-data-received",
+ G_CALLBACK (folder_tree_drag_data_received),
+ browser);
+ g_signal_connect (browser->priv->folder_tree,
+ "drag-data-get",
+ G_CALLBACK (folder_tree_drag_data_get_cb),
+ browser);
+
+ gtk_target_list_unref (target_list);
+ gtk_target_table_free (targets, n_targets);
+ }
+
g_signal_connect (browser->priv->folder_tree,
"open",
G_CALLBACK (folder_tree_open_cb),
diff --git a/gthumb/gth-file-list.c b/gthumb/gth-file-list.c
index 420f0a7..e828e62 100644
--- a/gthumb/gth-file-list.c
+++ b/gthumb/gth-file-list.c
@@ -581,9 +581,9 @@ gth_file_list_construct (GthFileList *file_list,
gth_file_selection_set_selection_mode (GTH_FILE_SELECTION (file_list->priv->view), GTK_SELECTION_MULTIPLE);
if (enable_drag_drop) {
- GtkTargetList *target_list;
- GtkTargetEntry *targets;
- int n_targets;
+ GtkTargetList *target_list;
+ GtkTargetEntry *targets;
+ int n_targets;
target_list = gtk_target_list_new (NULL, 0);
gtk_target_list_add_uri_targets (target_list, 0);
diff --git a/gthumb/gth-folder-tree.c b/gthumb/gth-folder-tree.c
index 637ffe5..3135af4 100644
--- a/gthumb/gth-folder-tree.c
+++ b/gthumb/gth-folder-tree.c
@@ -1400,6 +1400,34 @@ gth_folder_tree_expand_row (GthFolderTree *folder_tree,
}
+GthFileData *
+gth_folder_tree_get_file (GthFolderTree *folder_tree,
+ GtkTreePath *path)
+{
+ GtkTreeModel *tree_model;
+ GtkTreeIter iter;
+ EntryType entry_type;
+ GthFileData *file_data;
+
+ tree_model = GTK_TREE_MODEL (folder_tree->priv->tree_store);
+ if (! gtk_tree_model_get_iter (tree_model, &iter, path))
+ return NULL;
+
+ file_data = NULL;
+ gtk_tree_model_get (tree_model,
+ &iter,
+ COLUMN_TYPE, &entry_type,
+ COLUMN_FILE_DATA, &file_data,
+ -1);
+ if (entry_type != ENTRY_TYPE_FILE) {
+ _g_object_unref (file_data);
+ file_data = NULL;
+ }
+
+ return file_data;
+}
+
+
void
gth_folder_tree_select_path (GthFolderTree *folder_tree,
GtkTreePath *path)
diff --git a/gthumb/gth-folder-tree.h b/gthumb/gth-folder-tree.h
index 346dc05..6263725 100644
--- a/gthumb/gth-folder-tree.h
+++ b/gthumb/gth-folder-tree.h
@@ -101,6 +101,8 @@ void gth_folder_tree_expand_row (GthFolderTree *folder_tree,
void gth_folder_tree_select_path (GthFolderTree *folder_tree,
GtkTreePath *path);
GFile * gth_folder_tree_get_root (GthFolderTree *folder_tree);
+GthFileData * gth_folder_tree_get_file (GthFolderTree *folder_tree,
+ GtkTreePath *path);
GthFileData * gth_folder_tree_get_selected (GthFolderTree *folder_tree);
GthFileData * gth_folder_tree_get_selected_or_parent
(GthFolderTree *folder_tree);
diff --git a/gthumb/gth-hook.c b/gthumb/gth-hook.c
index afd2f54..dd859f2 100644
--- a/gthumb/gth-hook.c
+++ b/gthumb/gth-hook.c
@@ -85,7 +85,7 @@ gth_hook_register (const char *name,
GthHook *hook;
g_return_if_fail (name != NULL);
- g_return_if_fail ((n_args >= 0) || (n_args <= 3));
+ g_return_if_fail ((n_args >= 0) || (n_args <= 4));
if (g_hash_table_lookup (hooks, name) != NULL) {
g_warning ("hook '%s' already registered", name);
@@ -168,6 +168,7 @@ typedef void (*GthMarshaller0Args) (gpointer);
typedef void (*GthMarshaller1Arg) (gpointer, gpointer);
typedef void (*GthMarshaller2Args) (gpointer, gpointer, gpointer);
typedef void (*GthMarshaller3Args) (gpointer, gpointer, gpointer, gpointer);
+typedef void (*GthMarshaller4Args) (gpointer, gpointer, gpointer, gpointer, gpointer);
static void
@@ -208,6 +209,16 @@ invoke_marshaller_3 (GHook *hook,
}
+static void
+invoke_marshaller_4 (GHook *hook,
+ gpointer data)
+{
+ gpointer *marshal_data = data;
+
+ ((GthMarshaller4Args) hook->func) (marshal_data[0], marshal_data[1], marshal_data[2], marshal_data[3], hook->data);
+}
+
+
void
gth_hook_invoke (const char *name,
gpointer first_data,
@@ -243,6 +254,9 @@ gth_hook_invoke (const char *name,
case 3:
invoke_marshaller = invoke_marshaller_3;
break;
+ case 4:
+ invoke_marshaller = invoke_marshaller_4;
+ break;
default:
invoke_marshaller = NULL;
break;
@@ -259,6 +273,7 @@ typedef void * (*GthMarshaller0ArgsGet) (gpointer);
typedef void * (*GthMarshaller1ArgGet) (gpointer, gpointer);
typedef void * (*GthMarshaller2ArgsGet) (gpointer, gpointer, gpointer);
typedef void * (*GthMarshaller3ArgsGet) (gpointer, gpointer, gpointer, gpointer);
+typedef void * (*GthMarshaller4ArgsGet) (gpointer, gpointer, gpointer, gpointer, gpointer);
static void
@@ -305,6 +320,17 @@ invoke_marshaller_3_get (GHook *hook,
}
+static void
+invoke_marshaller_4_get (GHook *hook,
+ gpointer data)
+{
+ gpointer *marshal_data = data;
+
+ if (marshal_data[4] == NULL)
+ marshal_data[4] = ((GthMarshaller4ArgsGet) hook->func) (marshal_data[0], marshal_data[1], marshal_data[2], marshal_data[3], hook->data);
+}
+
+
void *
gth_hook_invoke_get (const char *name,
gpointer first_data,
@@ -340,6 +366,9 @@ gth_hook_invoke_get (const char *name,
case 3:
invoke_marshaller = invoke_marshaller_3_get;
break;
+ case 4:
+ invoke_marshaller = invoke_marshaller_4_get;
+ break;
default:
invoke_marshaller = NULL;
break;
diff --git a/gthumb/gth-main-default-hooks.c b/gthumb/gth-main-default-hooks.c
index 2456236..9905703 100644
--- a/gthumb/gth-main-default-hooks.c
+++ b/gthumb/gth-main-default-hooks.c
@@ -140,6 +140,17 @@ gth_main_register_default_hooks (void)
gth_hook_register ("gth-browser-folder-tree-popup-before", 3);
/**
+ * Called after a drag-data-received event on the folder tree
+ *
+ * @browser (GthBrowser *): the relative window.
+ * @destination (GthFileData *): the drop destination.
+ * @file_list (GList *): the GFile list of the dropped files
+ * @action (GdkDragAction): the drag action
+ * pressed in an empty area.
+ **/
+ gth_hook_register ("gth-browser-folder-tree-drag-data-received", 4);
+
+ /**
* Called to view file
*
* @browser (GthBrowser*): the relative window.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]