[gthumb] folder tree: better drag&drop support
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] folder tree: better drag&drop support
- Date: Sun, 24 Nov 2019 12:27:40 +0000 (UTC)
commit 45e2d19a6cafebafc06588246e2f7d6789037b77
Author: Paolo Bacchilega <paobac src gnome org>
Date: Mon Nov 4 08:58:19 2019 +0100
folder tree: better drag&drop support
Allow to move a catalog into a library, and a library into
another library; show an error if the drop operation is
not possible.
extensions/catalogs/gth-file-source-catalogs.c | 59 ++++++++++
extensions/file_manager/callbacks.c | 127 ++++++++++++---------
extensions/selections/gth-file-source-selections.c | 32 ++++++
gthumb/gth-browser.c | 50 +-------
gthumb/gth-file-source-vfs.c | 19 +++
gthumb/gth-file-source.c | 19 +++
gthumb/gth-file-source.h | 6 +
7 files changed, 207 insertions(+), 105 deletions(-)
---
diff --git a/extensions/catalogs/gth-file-source-catalogs.c b/extensions/catalogs/gth-file-source-catalogs.c
index 0646b342..85d12cf7 100644
--- a/extensions/catalogs/gth-file-source-catalogs.c
+++ b/extensions/catalogs/gth-file-source-catalogs.c
@@ -1445,6 +1445,64 @@ gth_file_source_catalogs_deleted_from_disk (GthFileSource *file_source,
}
+static GdkDragAction
+gth_file_source_catalogs_get_drop_actions (GthFileSource *file_source,
+ GFile *destination,
+ GFile *file)
+{
+ GdkDragAction actions = 0;
+ char *dest_uri;
+ char *dest_scheme;
+ const char *dest_ext;
+ gboolean dest_is_catalog;
+ char *file_uri;
+ char *file_scheme;
+ const char *file_ext;
+ gboolean file_is_catalog;
+
+ dest_uri = g_file_get_uri (destination);
+ dest_scheme = _g_uri_get_scheme (dest_uri);
+ dest_ext = _g_uri_get_file_extension (dest_uri);
+ dest_is_catalog = (g_strcmp0 (dest_ext, ".catalog") == 0) || (g_strcmp0 (dest_ext, ".search") == 0);
+
+ file_uri = g_file_get_uri (file);
+ file_scheme = _g_uri_get_scheme (file_uri);
+ file_ext = _g_uri_get_file_extension (file_uri);
+ file_is_catalog = (g_strcmp0 (file_ext, ".catalog") == 0) || (g_strcmp0 (file_ext, ".search") == 0);
+
+ if ((g_strcmp0 (dest_scheme, "catalog://") == 0)
+ && dest_is_catalog
+ && (g_strcmp0 (file_scheme, "file://") == 0))
+ {
+ /* Copy files into a catalog. */
+ actions = GDK_ACTION_COPY;
+ }
+
+ else if ((g_strcmp0 (file_scheme, "catalog://") == 0)
+ && file_is_catalog
+ && (g_strcmp0 (dest_scheme, "catalog://") == 0)
+ && ! dest_is_catalog)
+ {
+ /* Move a catalog into a library. */
+ actions = GDK_ACTION_MOVE;
+ }
+
+ else if ((g_strcmp0 (file_scheme, "catalog://") == 0)
+ && ! file_is_catalog
+ && (g_strcmp0 (dest_scheme, "catalog://") == 0)
+ && ! dest_is_catalog)
+ {
+ /* Move a library into another library. */
+ actions = GDK_ACTION_MOVE;
+ }
+
+ g_free (file_uri);
+ g_free (dest_uri);
+
+ return actions;
+}
+
+
static void
gth_file_source_catalogs_finalize (GObject *object)
{
@@ -1481,6 +1539,7 @@ gth_file_source_catalogs_class_init (GthFileSourceCatalogsClass *class)
file_source_class->reorder = gth_file_source_catalogs_reorder;
file_source_class->remove = gth_file_source_catalogs_remove;
file_source_class->deleted_from_disk = gth_file_source_catalogs_deleted_from_disk;
+ file_source_class->get_drop_actions = gth_file_source_catalogs_get_drop_actions;
}
diff --git a/extensions/file_manager/callbacks.c b/extensions/file_manager/callbacks.c
index b557db46..6f31fcf4 100644
--- a/extensions/file_manager/callbacks.c
+++ b/extensions/file_manager/callbacks.c
@@ -945,86 +945,101 @@ fm__gth_browser_folder_tree_drag_data_received_cb (GthBrowser *browser,
GList *file_list,
GdkDragAction action)
{
- GthFileSource *file_source;
+ int n_files;
+ GthFileSource *destination_source;
+ GFile *first_file;
+ GthFileSource *file_list_source;
+ gboolean move_files;
GtkWidget *dialog;
GthTask *task;
+ char *message;
int response;
if (destination == NULL)
return;
- file_source = gth_main_get_file_source (destination->file);
- if (file_source == NULL)
+ n_files = g_list_length (file_list);
+ if (n_files == 0)
+ return;
+
+ if ((action != GDK_ACTION_MOVE) && (action != GDK_ACTION_COPY))
+ return;
+
+ destination_source = gth_main_get_file_source (destination->file);
+ if (destination_source == NULL)
+ return;
+
+ first_file = G_FILE (file_list->data);
+ file_list_source = gth_main_get_file_source (first_file);
+ if (file_list_source == NULL)
return;
+ if (action == GDK_ACTION_MOVE)
+ action |= GDK_ACTION_COPY;
+
+ action = action & gth_file_source_get_drop_actions (destination_source, destination->file,
first_file);
+ if (action == 0) {
+ _gtk_error_dialog_run (GTK_WINDOW (browser),
+ "%s",
+ _("Could not perform the operation"));
+ return;
+ }
+
+ move_files = (action & GDK_ACTION_MOVE) != 0;
+
/* ask confirmation */
response = GTK_RESPONSE_OK;
- if ((action == GDK_ACTION_MOVE) || (action == GDK_ACTION_COPY)) {
- int n_files;
- char *message;
-
- n_files = g_list_length (file_list);
- g_return_if_fail (n_files >= 1);
-
- if (n_files == 1) {
- char *filename = _g_file_get_display_name ((GFile *) file_list->data);
- if (action == GDK_ACTION_MOVE)
- message = g_strdup_printf (_("Do you want to move “%s” to “%s”?"), filename,
g_file_info_get_display_name (destination->info));
- else
- message = g_strdup_printf (_("Do you want to copy “%s” to “%s”?"), filename,
g_file_info_get_display_name (destination->info));
- g_free (filename);
- }
- else {
- if (action == GDK_ACTION_MOVE)
- message = g_strdup_printf (_("Do you want to move the dragged files to
“%s”?"), g_file_info_get_display_name (destination->info));
- else
- message = g_strdup_printf (_("Do you want to copy the dragged files to
“%s”?"), g_file_info_get_display_name (destination->info));
- }
- dialog = _gtk_message_dialog_new (GTK_WINDOW (browser),
- GTK_DIALOG_MODAL,
- _GTK_ICON_NAME_DIALOG_QUESTION,
- message,
- NULL,
- _GTK_LABEL_CANCEL, GTK_RESPONSE_CANCEL,
- ((action == GDK_ACTION_MOVE) ? _("Move") : _("_Copy")),
GTK_RESPONSE_OK,
- NULL);
- response = gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
-
- g_free (message);
+ if (n_files == 1) {
+ GFileInfo *info;
+ char *filename;
+
+ info = gth_file_source_get_file_info (file_list_source, first_file,
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
+ if (info != NULL)
+ filename = g_strdup (g_file_info_get_display_name (info));
+ else
+ filename = _g_file_get_display_name (first_file);
+
+ if (move_files)
+ message = g_strdup_printf (_("Do you want to move “%s” to “%s”?"), filename,
g_file_info_get_display_name (destination->info));
+ else
+ message = g_strdup_printf (_("Do you want to copy “%s” to “%s”?"), filename,
g_file_info_get_display_name (destination->info));
+
+ g_free (filename);
+ _g_object_unref (info);
+ }
+ else {
+ if (move_files)
+ message = g_strdup_printf (_("Do you want to move the dragged files to “%s”?"),
g_file_info_get_display_name (destination->info));
+ else
+ message = g_strdup_printf (_("Do you want to copy the dragged files to “%s”?"),
g_file_info_get_display_name (destination->info));
}
+ dialog = _gtk_message_dialog_new (GTK_WINDOW (browser),
+ GTK_DIALOG_MODAL,
+ _GTK_ICON_NAME_DIALOG_QUESTION,
+ message,
+ NULL,
+ _GTK_LABEL_CANCEL, GTK_RESPONSE_CANCEL,
+ (move_files ? _("Move") : _("_Copy")), GTK_RESPONSE_OK,
+ NULL);
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ g_free (message);
if (response != GTK_RESPONSE_OK)
return;
- if ((action == GDK_ACTION_MOVE) && ! gth_file_source_can_cut (file_source, (GFile *)
file_list->data)) {
- dialog = _gtk_message_dialog_new (GTK_WINDOW (browser),
- GTK_DIALOG_MODAL,
- _GTK_ICON_NAME_DIALOG_QUESTION,
- _("Could not move the files"),
- _("Files cannot be moved to the current location, as
alternative you can choose to copy them."),
- _GTK_LABEL_CANCEL, GTK_RESPONSE_CANCEL,
- _GTK_LABEL_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;
- }
+ /* exec task */
- task = gth_copy_task_new (file_source,
+ task = gth_copy_task_new (destination_source,
destination,
- (action == GDK_ACTION_MOVE),
+ move_files,
file_list,
-1);
gth_browser_exec_task (browser, task, GTH_TASK_FLAGS_DEFAULT);
g_object_unref (task);
- g_object_unref (file_source);
+ g_object_unref (destination_source);
}
diff --git a/extensions/selections/gth-file-source-selections.c
b/extensions/selections/gth-file-source-selections.c
index 8fff091d..45c96c04 100644
--- a/extensions/selections/gth-file-source-selections.c
+++ b/extensions/selections/gth-file-source-selections.c
@@ -284,6 +284,37 @@ gth_file_source_selections_shows_extra_widget (GthFileSource *file_source)
}
+static GdkDragAction
+gth_file_source_selections_get_drop_actions (GthFileSource *file_source,
+ GFile *destination,
+ GFile *file)
+{
+ GdkDragAction actions = 0;
+ char *dest_uri;
+ char *dest_scheme;
+ char *file_uri;
+ char *file_scheme;
+
+ dest_uri = g_file_get_uri (destination);
+ dest_scheme = _g_uri_get_scheme (dest_uri);
+
+ file_uri = g_file_get_uri (file);
+ file_scheme = _g_uri_get_scheme (file_uri);
+
+ if ((g_strcmp0 (dest_scheme, "selection://") == 0)
+ && (g_strcmp0 (file_scheme, "file://") == 0))
+ {
+ /* Copy files into a selection. */
+ actions = GDK_ACTION_COPY;
+ }
+
+ g_free (file_uri);
+ g_free (dest_uri);
+
+ return actions;
+}
+
+
static void
gth_file_source_selections_class_init (GthFileSourceSelectionsClass *class)
{
@@ -304,6 +335,7 @@ gth_file_source_selections_class_init (GthFileSourceSelectionsClass *class)
file_source_class->remove = gth_file_source_selections_remove;
file_source_class->deleted_from_disk = gth_file_source_selections_deleted_from_disk;
file_source_class->shows_extra_widget = gth_file_source_selections_shows_extra_widget;
+ file_source_class->get_drop_actions = gth_file_source_selections_get_drop_actions;
}
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index 522ef839..89b8c524 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -2661,7 +2661,6 @@ folder_tree_drag_motion_cb (GtkWidget *file_view,
GthBrowser *browser = user_data;
GtkTreePath *path;
GtkTreeViewDropPosition pos;
- GdkDragAction action;
if (gdk_drag_context_get_suggested_action (context) == GDK_ACTION_ASK) {
gdk_drag_status (context, GDK_ACTION_ASK, time);
@@ -2694,8 +2693,6 @@ folder_tree_drag_motion_cb (GtkWidget *file_view,
gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (file_view), path, pos);
- action = GDK_ACTION_MOVE;
-
if ((browser->priv->folder_tree_last_dest_row == NULL) || gtk_tree_path_compare (path,
browser->priv->folder_tree_last_dest_row) != 0) {
gtk_tree_path_free (browser->priv->folder_tree_last_dest_row);
browser->priv->folder_tree_last_dest_row = gtk_tree_path_copy (path);
@@ -2705,52 +2702,7 @@ folder_tree_drag_motion_cb (GtkWidget *file_view,
browser->priv->folder_tree_open_folder_id = g_timeout_add (AUTO_OPEN_FOLDER_DELAY,
folder_tree_open_folder_cb, browser);
}
- /* use COPY if dropping a file in a catalog */
-
- if (action == GDK_ACTION_MOVE) {
- GthFileData *destination;
-
- destination = gth_folder_tree_get_file (GTH_FOLDER_TREE (browser->priv->folder_tree), path);
- if (destination != NULL) {
- GthFileSource *file_source = gth_main_get_file_source (destination->file);
-
- _g_object_unref (destination);
- if (file_source != NULL) {
- if (gth_file_source_is_reorderable (file_source))
- action = GDK_ACTION_COPY;
- }
- else
- action = 0;
-
- _g_object_unref (file_source);
- }
- else
- action = 0;
- }
-
- /* use COPY when dragging a file from a catalog to a directory */
-
- if (action == GDK_ACTION_MOVE) {
- gboolean source_is_reorderable;
- GList *targets;
- GList *scan;
-
- source_is_reorderable = FALSE;
- targets = gdk_drag_context_list_targets (context);
- for (scan = targets; scan; scan = scan->next) {
- GdkAtom target = scan->data;
-
- if (target == gdk_atom_intern_static_string ("gthumb/reorderable-list")) {
- source_is_reorderable = TRUE;
- break;
- }
- }
-
- if (source_is_reorderable)
- action = GDK_ACTION_COPY;
- }
-
- gdk_drag_status (context, action, time);
+ gdk_drag_status (context, GDK_ACTION_MOVE, time);
gtk_tree_path_free (path);
return TRUE;
diff --git a/gthumb/gth-file-source-vfs.c b/gthumb/gth-file-source-vfs.c
index dfa4275b..dcc1c4e7 100644
--- a/gthumb/gth-file-source-vfs.c
+++ b/gthumb/gth-file-source-vfs.c
@@ -883,6 +883,24 @@ gth_file_source_vfs_remove (GthFileSource *file_source,
}
+static GdkDragAction
+gth_file_source_vfs_get_drop_actions (GthFileSource *file_source,
+ GFile *destination,
+ GFile *file)
+{
+ char *dest_scheme;
+ char *file_scheme;
+
+ dest_scheme = g_file_get_uri_scheme(destination);
+ file_scheme = g_file_get_uri_scheme(file);
+
+ if ((g_strcmp0 (dest_scheme, "file") == 0) && (g_strcmp0 (file_scheme, "file") == 0))
+ return GDK_ACTION_COPY | GDK_ACTION_MOVE;
+ else
+ return 0;
+}
+
+
static void
gth_file_source_vfs_finalize (GObject *object)
{
@@ -926,6 +944,7 @@ gth_file_source_vfs_class_init (GthFileSourceVfsClass *class)
file_source_class->monitor_entry_points = gth_file_source_vfs_monitor_entry_points;
file_source_class->monitor_directory = gth_file_source_vfs_monitor_directory;
file_source_class->remove = gth_file_source_vfs_remove;
+ file_source_class->get_drop_actions = gth_file_source_vfs_get_drop_actions;
}
diff --git a/gthumb/gth-file-source.c b/gthumb/gth-file-source.c
index 40db3d66..504de529 100644
--- a/gthumb/gth-file-source.c
+++ b/gthumb/gth-file-source.c
@@ -900,6 +900,15 @@ base_shows_extra_widget (GthFileSource *file_source)
}
+static GdkDragAction
+base_get_drop_actions (GthFileSource *file_source,
+ GFile *destination,
+ GFile *file)
+{
+ return 0; /* no action supported by default. */
+}
+
+
static void
gth_file_source_finalize (GObject *object)
{
@@ -938,6 +947,7 @@ gth_file_source_class_init (GthFileSourceClass *class)
class->deleted_from_disk = base_deleted_from_disk;
class->get_free_space = base_get_free_space;
class->shows_extra_widget = base_shows_extra_widget;
+ class->get_drop_actions = base_get_drop_actions;
}
@@ -1436,3 +1446,12 @@ gth_file_source_shows_extra_widget (GthFileSource *file_source)
{
return GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->shows_extra_widget (file_source);
}
+
+
+GdkDragAction
+gth_file_source_get_drop_actions (GthFileSource *file_source,
+ GFile *destination,
+ GFile *file)
+{
+ return GTH_FILE_SOURCE_GET_CLASS (G_OBJECT (file_source))->get_drop_actions (file_source,
destination, file);
+}
diff --git a/gthumb/gth-file-source.h b/gthumb/gth-file-source.h
index 717f94a4..67fbbd66 100644
--- a/gthumb/gth-file-source.h
+++ b/gthumb/gth-file-source.h
@@ -139,6 +139,9 @@ struct _GthFileSourceClass
SpaceReadyCallback callback,
gpointer data);
gboolean (*shows_extra_widget) (GthFileSource *file_source);
+ GdkDragAction(*get_drop_actions) (GthFileSource *file_source,
+ GFile *destination,
+ GFile *file);
};
GType gth_file_source_get_type (void) G_GNUC_CONST;
@@ -230,6 +233,9 @@ void gth_file_source_get_free_space (GthFileSource *file
SpaceReadyCallback callback,
gpointer data);
gboolean gth_file_source_shows_extra_widget (GthFileSource *file_source);
+GdkDragAction gth_file_source_get_drop_actions (GthFileSource *file_source,
+ GFile *destination,
+ GFile *file);
/*< protected >*/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]