[gthumb] drag&drop: move files by default
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] drag&drop: move files by default
- Date: Sun, 15 Mar 2015 17:37:04 +0000 (UTC)
commit 318da5793e151eca463454854206b2951d7216f7
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sun Mar 15 14:45:54 2015 +0100
drag&drop: move files by default
extensions/file_manager/callbacks.c | 86 +++++++++++++++++----
gthumb/gth-browser.c | 143 ++++++++++++++++++++++++++++++++++-
gthumb/gth-file-list.c | 59 +++++++++------
gthumb/gth-file-list.h | 5 +
4 files changed, 251 insertions(+), 42 deletions(-)
---
diff --git a/extensions/file_manager/callbacks.c b/extensions/file_manager/callbacks.c
index 5b3936e..5f200d0 100644
--- a/extensions/file_manager/callbacks.c
+++ b/extensions/file_manager/callbacks.c
@@ -34,6 +34,7 @@
#define BROWSER_DATA_KEY "file-manager-browser-data"
#define URI_LIST_ATOM (gdk_atom_intern_static_string ("text/uri-list"))
#define XDND_ACTION_DIRECT_SAVE_ATOM (gdk_atom_intern_static_string ("XdndDirectSave0"))
+#define GTHUMB_REORDERABLE_LIST_ATOM (gdk_atom_intern_static_string ("gthumb/reorderable-list"))
#define TEXT_PLAIN_ATOM (gdk_atom_intern_static_string ("text/plain"))
#define SCROLL_TIMEOUT 30 /* autoscroll timeout in milliseconds */
@@ -125,7 +126,13 @@ static const GthAccelerator accelerators[] = {
static GtkTargetEntry reorderable_drag_dest_targets[] = {
{ "text/uri-list", 0, 0 },
- { "text/uri-list", GTK_TARGET_SAME_WIDGET, 0 }
+ { "text/uri-list", GTK_TARGET_SAME_WIDGET, 0 },
+ { "gthumb/reorderable-list", 0, 0 }
+};
+
+
+static GtkTargetEntry reorderable_drag_source_targets[] = {
+ { "gthumb/reorderable-list", 0, 0 }
};
@@ -175,8 +182,6 @@ gth_file_list_drag_data_received (GtkWidget *file_view,
GList *selected_files;
GdkDragAction action;
- g_signal_stop_emission_by_name (file_view, "drag-data-received");
-
action = gdk_drag_context_get_suggested_action (context);
if (action == GDK_ACTION_COPY || action == GDK_ACTION_MOVE) {
success = TRUE;
@@ -435,10 +440,27 @@ gth_file_list_drag_motion (GtkWidget *file_view,
data->scroll_event = 0;
}
}
- else if (gdk_drag_context_get_suggested_action (context) == GDK_ACTION_ASK)
+ else if (gdk_drag_context_get_suggested_action (context) == GDK_ACTION_ASK) {
gdk_drag_status (context, GDK_ACTION_ASK, time);
- else
- gdk_drag_status (context, GDK_ACTION_COPY, time);
+ }
+ else {
+ gboolean source_is_reorderable = FALSE;
+ GList *targets = gdk_drag_context_list_targets (context);
+ GList *scan;
+
+ /* use COPY when dragging a file from a catalog to a directory */
+
+ for (scan = targets; scan; scan = scan->next) {
+ GdkAtom target = scan->data;
+
+ if (target == GTHUMB_REORDERABLE_LIST_ATOM) {
+ source_is_reorderable = TRUE;
+ break;
+ }
+ }
+
+ gdk_drag_status (context, source_is_reorderable ? GDK_ACTION_COPY : GDK_ACTION_MOVE, time);
+ }
return TRUE;
}
@@ -596,8 +618,13 @@ fm__gth_browser_load_location_after_cb (GthBrowser *browser,
GthFileData *location_data,
const GError *error)
{
- BrowserData *data;
- GtkWidget *file_view;
+ BrowserData *data;
+ GtkWidget *file_list;
+ GtkWidget *file_view;
+ GtkTargetList *source_target_list;
+ GtkTargetEntry *source_targets;
+ int n_source_targets;
+ GdkDragAction source_actions;
if ((location_data == NULL) || (error != NULL))
return;
@@ -605,38 +632,65 @@ fm__gth_browser_load_location_after_cb (GthBrowser *browser,
data = g_object_get_data (G_OBJECT (browser), BROWSER_DATA_KEY);
file_manager_update_ui (data, browser);
+ source_target_list = gtk_target_list_new (NULL, 0);
+ gtk_target_list_add_uri_targets (source_target_list, 0);
+ gtk_target_list_add_text_targets (source_target_list, 0);
+ source_actions = GDK_ACTION_PRIVATE;
+
+ file_list = gth_browser_get_file_list (browser);
if (! g_file_info_get_attribute_boolean (location_data->info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE)) {
- file_view = gth_file_list_get_view (GTH_FILE_LIST (gth_browser_get_file_list (browser)));
+ file_view = gth_file_list_get_view (GTH_FILE_LIST (file_list));
gth_file_view_unset_drag_dest (GTH_FILE_VIEW (file_view));
- file_view = gth_file_list_get_empty_view (GTH_FILE_LIST (gth_browser_get_file_list
(browser)));
+ file_view = gth_file_list_get_empty_view (GTH_FILE_LIST (file_list));
gtk_drag_dest_unset (file_view);
+
+ source_actions = GDK_ACTION_COPY;
}
else if (gth_file_source_is_reorderable (gth_browser_get_location_source (browser))) {
- file_view = gth_file_list_get_view (GTH_FILE_LIST (gth_browser_get_file_list (browser)));
+ file_view = gth_file_list_get_view (GTH_FILE_LIST (file_list));
gth_file_view_enable_drag_dest (GTH_FILE_VIEW (file_view),
reorderable_drag_dest_targets,
G_N_ELEMENTS (reorderable_drag_dest_targets),
GDK_ACTION_COPY | GDK_ACTION_MOVE);
- file_view = gth_file_list_get_empty_view (GTH_FILE_LIST (gth_browser_get_file_list
(browser)));
+ file_view = gth_file_list_get_empty_view (GTH_FILE_LIST (file_list));
gtk_drag_dest_set (file_view,
0,
reorderable_drag_dest_targets,
G_N_ELEMENTS (reorderable_drag_dest_targets),
GDK_ACTION_COPY | GDK_ACTION_MOVE);
+
+ gtk_target_list_add_table (source_target_list,
+ reorderable_drag_source_targets,
+ G_N_ELEMENTS (reorderable_drag_source_targets));
+ source_actions = GDK_ACTION_COPY | GDK_ACTION_MOVE;
}
else {
- file_view = gth_file_list_get_view (GTH_FILE_LIST (gth_browser_get_file_list (browser)));
+ file_view = gth_file_list_get_view (GTH_FILE_LIST (file_list));
gth_file_view_enable_drag_dest (GTH_FILE_VIEW (file_view),
non_reorderable_drag_dest_targets,
G_N_ELEMENTS (non_reorderable_drag_dest_targets),
- GDK_ACTION_COPY);
- file_view = gth_file_list_get_empty_view (GTH_FILE_LIST (gth_browser_get_file_list
(browser)));
+ GDK_ACTION_COPY | GDK_ACTION_MOVE);
+ file_view = gth_file_list_get_empty_view (GTH_FILE_LIST (file_list));
gtk_drag_dest_set (file_view,
0,
non_reorderable_drag_dest_targets,
G_N_ELEMENTS (non_reorderable_drag_dest_targets),
- GDK_ACTION_COPY);
+ GDK_ACTION_COPY | GDK_ACTION_MOVE);
+
+ source_actions = GDK_ACTION_MOVE | GDK_ACTION_ASK;
}
+
+ /* set the drag source targets */
+
+ source_targets = gtk_target_table_new_from_list (source_target_list, &n_source_targets);
+ gth_file_view_enable_drag_source (GTH_FILE_VIEW (gth_file_list_get_view (GTH_FILE_LIST (file_list))),
+ GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
+ source_targets,
+ n_source_targets,
+ source_actions);
+
+ gtk_target_list_unref (source_target_list);
+ gtk_target_table_free (source_targets, n_source_targets);
}
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index 386bcef..307ac6f 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -73,11 +73,10 @@
#define MIN_SIDEBAR_SIZE 100
#define MIN_VIEWER_SIZE 256
#define STATUSBAR_SEPARATOR " ยท "
-#define SHIRNK_WRAP_WIDTH_OFFSET 100
-#define SHIRNK_WRAP_HEIGHT_OFFSET 125
#define FILE_PROPERTIES_MINIMUM_HEIGHT 100
#define HISTORY_FILE "history.xbel"
#define OVERLAY_MARGIN 10
+#define AUTO_OPEN_FOLDER_DELAY 500
G_DEFINE_TYPE (GthBrowser, gth_browser, GTH_TYPE_WINDOW)
@@ -182,6 +181,8 @@ struct _GthBrowserPrivate {
GthSidebarState viewer_sidebar;
BrowserState state;
GthICCProfile screen_profile;
+ GtkTreePath *folder_tree_last_dest_row; /* used to open a folder during D&D */
+ guint folder_tree_open_folder_id;
/* settings */
@@ -2172,6 +2173,11 @@ _gth_browser_real_close (GthBrowser *browser)
browser->priv->selection_changed_event = 0;
}
+ if (browser->priv->folder_tree_open_folder_id != 0) {
+ g_source_remove (browser->priv->folder_tree_open_folder_id);
+ browser->priv->folder_tree_open_folder_id = 0;
+ }
+
/* cancel async operations */
_gth_browser_cancel (browser, _gth_browser_close_step3, browser);
@@ -2602,6 +2608,7 @@ gth_browser_finalize (GObject *object)
_g_object_unref (browser->priv->folder_popup_file_data);
_g_object_unref (browser->priv->history_menu);
gth_icc_profile_free (browser->priv->screen_profile);
+ gtk_tree_path_free (browser->priv->folder_tree_last_dest_row);
G_OBJECT_CLASS (gth_browser_parent_class)->finalize (object);
}
@@ -2672,6 +2679,130 @@ viewer_container_get_child_position_cb (GtkOverlay *overlay,
}
+static gboolean
+folder_tree_open_folder_cb (gpointer user_data)
+{
+ GthBrowser *browser = user_data;
+
+ if (browser->priv->folder_tree_open_folder_id != 0) {
+ g_source_remove (browser->priv->folder_tree_open_folder_id);
+ browser->priv->folder_tree_open_folder_id = 0;
+ }
+
+ gtk_tree_view_expand_row (GTK_TREE_VIEW (browser->priv->folder_tree),
+ browser->priv->folder_tree_last_dest_row,
+ FALSE);
+
+ return FALSE;
+}
+
+
+static gboolean
+folder_tree_drag_motion_cb (GtkWidget *file_view,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time,
+ gpointer user_data)
+{
+ 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);
+ return FALSE;
+ }
+
+ if (! gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (file_view),
+ x,
+ y,
+ &path,
+ &pos))
+ {
+ gtk_tree_path_free (browser->priv->folder_tree_last_dest_row);
+ browser->priv->folder_tree_last_dest_row = NULL;
+
+ if (browser->priv->folder_tree_open_folder_id != 0) {
+ g_source_remove (browser->priv->folder_tree_open_folder_id);
+ browser->priv->folder_tree_open_folder_id = 0;
+ }
+
+ gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (file_view), NULL, 0);
+ gdk_drag_status (context, 0, time);
+ return TRUE;
+ }
+
+ if (pos == GTK_TREE_VIEW_DROP_BEFORE)
+ pos = GTK_TREE_VIEW_DROP_INTO_OR_BEFORE;
+ if (pos == GTK_TREE_VIEW_DROP_AFTER)
+ pos = GTK_TREE_VIEW_DROP_INTO_OR_AFTER;
+
+ 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);
+
+ if (browser->priv->folder_tree_open_folder_id != 0)
+ g_source_remove (browser->priv->folder_tree_open_folder_id);
+ 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;
+ GthFileSource *file_source;
+
+ destination = gth_folder_tree_get_file (GTH_FOLDER_TREE (browser->priv->folder_tree), path);
+ if (destination != NULL) {
+ 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;
+ }
+ 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);
+ gtk_tree_path_free (path);
+
+ return TRUE;
+}
+
+
static void
folder_tree_drag_data_received (GtkWidget *tree_view,
GdkDragContext *context,
@@ -2757,7 +2888,7 @@ folder_tree_drag_data_get_cb (GtkWidget *widget,
if (file_source == NULL)
return;
- if (gdk_drag_context_get_actions (drag_context) && GDK_ACTION_MOVE) {
+ if (gdk_drag_context_get_actions (drag_context) & GDK_ACTION_MOVE) {
GdkDragAction action =
gth_file_source_can_cut (file_source, file_data->file) ?
GDK_ACTION_MOVE : GDK_ACTION_COPY;
@@ -4131,6 +4262,8 @@ gth_browser_init (GthBrowser *browser)
browser->priv->file_properties_on_the_right = g_settings_get_boolean
(browser->priv->browser_settings, PREF_BROWSER_PROPERTIES_ON_THE_RIGHT);
browser->priv->menu_managers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
g_object_unref);
browser->priv->screen_profile = NULL;
+ browser->priv->folder_tree_last_dest_row = NULL;
+ browser->priv->folder_tree_open_folder_id = 0;
browser_state_init (&browser->priv->state);
@@ -4547,6 +4680,10 @@ gth_browser_init (GthBrowser *browser)
n_targets,
GDK_ACTION_MOVE | GDK_ACTION_COPY);
g_signal_connect (browser->priv->folder_tree,
+ "drag_motion",
+ G_CALLBACK (folder_tree_drag_motion_cb),
+ browser);
+ g_signal_connect (browser->priv->folder_tree,
"drag-data-received",
G_CALLBACK (folder_tree_drag_data_received),
browser);
diff --git a/gthumb/gth-file-list.c b/gthumb/gth-file-list.c
index 299b814..1457d1a 100644
--- a/gthumb/gth-file-list.c
+++ b/gthumb/gth-file-list.c
@@ -660,30 +660,13 @@ gth_file_list_construct (GthFileList *file_list,
"rows-reordered",
G_CALLBACK (file_store_rows_reordered_cb),
file_list);
+ g_signal_connect (G_OBJECT (file_list->priv->view),
+ "drag-data-get",
+ G_CALLBACK (file_view_drag_data_get_cb),
+ file_list);
- if (enable_drag_drop) {
- 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);
- gth_file_view_enable_drag_source (GTH_FILE_VIEW (file_list->priv->view),
- GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
- targets,
- n_targets,
- GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK);
-
- gtk_target_list_unref (target_list);
- gtk_target_table_free (targets, n_targets);
-
- g_signal_connect (G_OBJECT (file_list->priv->view),
- "drag-data-get",
- G_CALLBACK (file_view_drag_data_get_cb),
- file_list);
- }
+ if (enable_drag_drop)
+ gth_file_list_enable_drag_source (file_list, GDK_ACTION_COPY | GDK_ACTION_MOVE |
GDK_ACTION_ASK);
gth_file_list_set_mode (file_list, list_type);
@@ -2150,3 +2133,33 @@ gth_file_list_prev_file (GthFileList *file_list,
return (scan != NULL) ? pos : -1;
}
+
+
+void
+gth_file_list_enable_drag_source (GthFileList *file_list,
+ GdkDragAction actions)
+{
+ 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);
+ gth_file_view_enable_drag_source (GTH_FILE_VIEW (file_list->priv->view),
+ GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
+ targets,
+ n_targets,
+ actions);
+
+ gtk_target_list_unref (target_list);
+ gtk_target_table_free (targets, n_targets);
+}
+
+
+void
+gth_file_list_unset_drag_source (GthFileList *file_list)
+{
+ gth_file_view_unset_drag_source (GTH_FILE_VIEW (file_list->priv->view));
+}
diff --git a/gthumb/gth-file-list.h b/gthumb/gth-file-list.h
index 18c68af..02962de 100644
--- a/gthumb/gth-file-list.h
+++ b/gthumb/gth-file-list.h
@@ -128,6 +128,11 @@ int gth_file_list_prev_file (GthFileList *file_li
gboolean only_selected,
gboolean wrap);
+void gth_file_list_enable_drag_source (GthFileList *file_list,
+ GdkDragAction actions);
+void gth_file_list_unset_drag_source (GthFileList *file_list);
+
+
G_END_DECLS
#endif /* GTH_FILE_LIST_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]