summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Soriano <csoriano@gnome.org>2015-10-05 13:57:51 +0200
committerCarlos Soriano <csoriano@gnome.org>2015-10-06 19:22:09 +0200
commitef14edf6343c2fbc7a24c4df343eae5b68a7d3b3 (patch)
tree83cc0163ed0ef8b4d9323b9ffb5558578beeb5aa
parentf4f23383aca4bbba38ab5050c7fea1a88192ff04 (diff)
downloadnautilus-ef14edf6343c2fbc7a24c4df343eae5b68a7d3b3.tar.gz
list-view: move dnd handling to a separate file
Following what canvas-dnd, slot-dnd and other widgets on nautilus does. Code will be much better for upcoming patches.
-rw-r--r--src/Makefile.am3
-rw-r--r--src/nautilus-list-view-dnd.c222
-rw-r--r--src/nautilus-list-view-dnd.h29
-rw-r--r--src/nautilus-list-view-private.h68
-rw-r--r--src/nautilus-list-view.c247
5 files changed, 330 insertions, 239 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 11dd3864f..6ebc32089 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -181,6 +181,9 @@ nautilus_SOURCES = \
nautilus-list-model.h \
nautilus-list-view.c \
nautilus-list-view.h \
+ nautilus-list-view-private.h \
+ nautilus-list-view-dnd.c \
+ nautilus-list-view-dnd.h \
nautilus-location-entry.c \
nautilus-location-entry.h \
nautilus-main.c \
diff --git a/src/nautilus-list-view-dnd.c b/src/nautilus-list-view-dnd.c
new file mode 100644
index 000000000..67dffa1ad
--- /dev/null
+++ b/src/nautilus-list-view-dnd.c
@@ -0,0 +1,222 @@
+/* nautilus-list-view-dnd.c
+ *
+ * Copyright (C) 2015 Carlos Soriano <csoriano@gnome.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "nautilus-list-view-dnd.h"
+#include "nautilus-list-view-private.h"
+
+#include "nautilus-dnd.h"
+
+static GtkTargetList * source_target_list = NULL;
+
+static void
+drag_data_get_callback (GtkWidget *widget,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time)
+{
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
+ GList *selection_cache;
+
+ tree_view = GTK_TREE_VIEW (widget);
+
+ model = gtk_tree_view_get_model (tree_view);
+
+ if (model == NULL)
+ return;
+
+ selection_cache = g_object_get_data (G_OBJECT (context), "drag-info");
+ if (selection_cache == NULL)
+ return;
+
+ nautilus_drag_drag_data_get_from_cache (selection_cache, context, selection_data, info, time);
+}
+
+static cairo_surface_t *
+get_drag_surface (NautilusListView *view)
+{
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ cairo_surface_t *ret;
+ GdkRectangle cell_area;
+
+ ret = NULL;
+
+ if (gtk_tree_view_get_path_at_pos (view->details->tree_view,
+ view->details->drag_x,
+ view->details->drag_y,
+ &path, NULL, NULL, NULL))
+ {
+ model = gtk_tree_view_get_model (view->details->tree_view);
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_model_get (model, &iter,
+ nautilus_list_model_get_column_id_from_zoom_level (view->details->zoom_level),
+ &ret,
+ -1);
+ }
+
+ gtk_tree_view_get_cell_area (view->details->tree_view,
+ path,
+ view->details->file_name_column,
+ &cell_area);
+
+ gtk_tree_path_free (path);
+
+ return ret;
+}
+
+/* iteration glue struct */
+typedef struct {
+ NautilusListView *view;
+ NautilusDragEachSelectedItemDataGet iteratee;
+ gpointer iteratee_data;
+} ListGetDataBinderContext;
+
+static void
+item_get_data_binder (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ ListGetDataBinderContext *context = data;
+ NautilusFile *file;
+ GtkTreeView *treeview;
+ GtkTreeViewColumn *column;
+ GdkRectangle cell_area;
+ int drag_begin_y = 0;
+ char *uri;
+
+ treeview = nautilus_list_model_get_drag_view (context->view->details->model,
+ NULL,
+ &drag_begin_y);
+ column = gtk_tree_view_get_column (treeview, 0);
+
+ file = nautilus_list_model_file_for_path (NAUTILUS_LIST_MODEL (model), path);
+ if (file == NULL)
+ return;
+
+ gtk_tree_view_get_cell_area (treeview,
+ path,
+ column,
+ &cell_area);
+
+ if (nautilus_file_is_nautilus_link (file))
+ uri = nautilus_file_get_uri (file);
+ else
+ uri = nautilus_file_get_activation_uri (file);
+
+ nautilus_file_unref (file);
+
+ /* pass the uri, mouse-relative x/y and icon width/height */
+ context->iteratee (uri,
+ 0,
+ cell_area.y - drag_begin_y,
+ cell_area.width,
+ cell_area.height,
+ context->iteratee_data);
+
+ g_free (uri);
+}
+
+static void
+each_item_get_data_binder (NautilusDragEachSelectedItemDataGet iteratee,
+ gpointer iterator_context,
+ gpointer data)
+{
+ NautilusListView *view = NAUTILUS_LIST_VIEW (iterator_context);
+ ListGetDataBinderContext context;
+ GtkTreeSelection *selection;
+
+ context.view = view;
+ context.iteratee = iteratee;
+ context.iteratee_data = data;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view->details->tree_view));
+ gtk_tree_selection_selected_foreach (selection, item_get_data_binder, &context);
+}
+
+static void
+drag_begin_callback (GtkWidget *widget,
+ GdkDragContext *context,
+ NautilusListView *view)
+{
+ GList *selection_cache;
+ cairo_surface_t *surface;
+
+ surface = get_drag_surface (view);
+ if (surface)
+ {
+ gtk_drag_set_icon_surface (context, surface);
+ cairo_surface_destroy (surface);
+ }
+ else
+ {
+ gtk_drag_set_icon_default (context);
+ }
+
+ view->details->drag_button = 0;
+ view->details->drag_started = TRUE;
+
+ selection_cache = nautilus_drag_create_selection_cache (view,
+ each_item_get_data_binder);
+
+ g_object_set_data_full (G_OBJECT (context),
+ "drag-info",
+ selection_cache,
+ (GDestroyNotify)nautilus_drag_destroy_selection_list);
+}
+
+void
+nautilus_list_view_dnd_init (NautilusListView *list_view)
+{
+ g_signal_connect_object (list_view->details->tree_view, "drag-begin",
+ G_CALLBACK (drag_begin_callback), list_view, 0);
+ g_signal_connect_object (list_view->details->tree_view, "drag-data-get",
+ G_CALLBACK (drag_data_get_callback), list_view, 0);
+}
+
+gboolean
+nautilus_list_view_dnd_drag_begin (NautilusListView *list_view,
+ GdkEventMotion *event)
+{
+ if (list_view->details->drag_button != 0)
+ {
+ if (!source_target_list)
+ source_target_list = nautilus_list_model_get_drag_target_list ();
+
+ if (gtk_drag_check_threshold (GTK_WIDGET (list_view->details->tree_view),
+ list_view->details->drag_x,
+ list_view->details->drag_y,
+ event->x,
+ event->y))
+ {
+ gtk_drag_begin (GTK_WIDGET (list_view->details->tree_view),
+ source_target_list,
+ GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_ASK,
+ list_view->details->drag_button,
+ (GdkEvent*)event);
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/src/nautilus-list-view-dnd.h b/src/nautilus-list-view-dnd.h
new file mode 100644
index 000000000..24500eb31
--- /dev/null
+++ b/src/nautilus-list-view-dnd.h
@@ -0,0 +1,29 @@
+/* nautilus-list-view-dnd.h
+ *
+ * Copyright (C) 2015 Carlos Soriano <csoriano@gnome.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef NAUTILUS_LIST_VIEW_DND_H
+#define NAUTILUS_LIST_VIEW_DND_H
+
+#include <gdk/gdk.h>
+
+#include "nautilus-list-view.h"
+
+void nautilus_list_view_dnd_init (NautilusListView *list_view);
+gboolean nautilus_list_view_dnd_drag_begin (NautilusListView *list_view,
+ GdkEventMotion *event);
+
+#endif /* NAUTILUS_LIST_VIEW_DND_H */
diff --git a/src/nautilus-list-view-private.h b/src/nautilus-list-view-private.h
new file mode 100644
index 000000000..8a24f2dde
--- /dev/null
+++ b/src/nautilus-list-view-private.h
@@ -0,0 +1,68 @@
+/* nautilus-list-view-private.h
+ *
+ * Copyright (C) 2015 Carlos Soriano <csoriano@gnome.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Data and functions shared between list view and list view dnd */
+
+#include "nautilus-list-model.h"
+#include "nautilus-tree-view-drag-dest.h"
+
+struct NautilusListViewDetails {
+ GtkTreeView *tree_view;
+ NautilusListModel *model;
+
+ GtkTreeViewColumn *file_name_column;
+ int file_name_column_num;
+
+ GtkCellRendererPixbuf *pixbuf_cell;
+ GtkCellRendererText *file_name_cell;
+ GList *cells;
+
+ NautilusListZoomLevel zoom_level;
+
+ NautilusTreeViewDragDest *drag_dest;
+
+ GtkTreePath *double_click_path[2]; /* Both clicks in a double click need to be on the same row */
+
+ GtkTreePath *new_selection_path; /* Path of the new selection after removing a file */
+
+ GtkTreePath *hover_path;
+
+ gint last_event_button_x;
+ gint last_event_button_y;
+
+ guint drag_button;
+ int drag_x;
+ int drag_y;
+
+ gboolean drag_started;
+ gboolean ignore_button_release;
+ gboolean row_selected_on_button_down;
+ gboolean active;
+
+ GHashTable *columns;
+ GtkWidget *column_editor;
+
+ char *original_name;
+
+ gulong clipboard_handler_id;
+
+ GQuark last_sort_attr;
+
+ GIcon *icon;
+};
+
diff --git a/src/nautilus-list-view.c b/src/nautilus-list-view.c
index 50e76a44f..0fa519f3c 100644
--- a/src/nautilus-list-view.c
+++ b/src/nautilus-list-view.c
@@ -26,11 +26,13 @@
#include <config.h>
#include "nautilus-list-view.h"
+#include "nautilus-list-view-private.h"
#include "nautilus-list-model.h"
#include "nautilus-error-reporting.h"
#include "nautilus-files-view-dnd.h"
#include "nautilus-toolbar.h"
+#include "nautilus-list-view-dnd.h"
#include <string.h>
#include <eel/eel-vfs-extensions.h>
@@ -65,51 +67,6 @@
* in the edges if the window is small */
#define RENAME_POPOVER_RELATIVE_TO_RECTANGLE_WIDTH 40
-struct NautilusListViewDetails {
- GtkTreeView *tree_view;
- NautilusListModel *model;
-
- GtkTreeViewColumn *file_name_column;
- int file_name_column_num;
-
- GtkCellRendererPixbuf *pixbuf_cell;
- GtkCellRendererText *file_name_cell;
- GList *cells;
-
- NautilusListZoomLevel zoom_level;
-
- NautilusTreeViewDragDest *drag_dest;
-
- GtkTreePath *double_click_path[2]; /* Both clicks in a double click need to be on the same row */
-
- GtkTreePath *new_selection_path; /* Path of the new selection after removing a file */
-
- GtkTreePath *hover_path;
-
- gint last_event_button_x;
- gint last_event_button_y;
-
- guint drag_button;
- int drag_x;
- int drag_y;
-
- gboolean drag_started;
- gboolean ignore_button_release;
- gboolean row_selected_on_button_down;
- gboolean active;
-
- GHashTable *columns;
- GtkWidget *column_editor;
-
- char *original_name;
-
- gulong clipboard_handler_id;
-
- GQuark last_sort_attr;
-
- GIcon *icon;
-};
-
struct SelectionForeachData {
GList *list;
GtkTreeSelection *selection;
@@ -127,8 +84,6 @@ struct SelectionForeachData {
static GdkCursor * hand_cursor = NULL;
-static GtkTargetList * source_target_list = NULL;
-
static GList *nautilus_list_view_get_selection (NautilusFilesView *view);
static GList *nautilus_list_view_get_selection_for_file_transfer (NautilusFilesView *view);
static void nautilus_list_view_set_zoom_level (NautilusListView *view,
@@ -342,179 +297,14 @@ nautilus_list_view_did_not_drag (NautilusListView *view,
}
-static void
-drag_data_get_callback (GtkWidget *widget,
- GdkDragContext *context,
- GtkSelectionData *selection_data,
- guint info,
- guint time)
-{
- GtkTreeView *tree_view;
- GtkTreeModel *model;
- GList *selection_cache;
-
- tree_view = GTK_TREE_VIEW (widget);
-
- model = gtk_tree_view_get_model (tree_view);
-
- if (model == NULL) {
- return;
- }
-
- selection_cache = g_object_get_data (G_OBJECT (context), "drag-info");
- if (selection_cache == NULL) {
- return;
- }
-
- nautilus_drag_drag_data_get_from_cache (selection_cache, context, selection_data, info, time);
-}
-
-static void
-stop_drag_check (NautilusListView *view)
-{
- view->details->drag_button = 0;
-}
-
-static cairo_surface_t *
-get_drag_surface (NautilusListView *view)
-{
- GtkTreeModel *model;
- GtkTreePath *path;
- GtkTreeIter iter;
- cairo_surface_t *ret;
- GdkRectangle cell_area;
-
- ret = NULL;
-
- if (gtk_tree_view_get_path_at_pos (view->details->tree_view,
- view->details->drag_x,
- view->details->drag_y,
- &path, NULL, NULL, NULL)) {
- model = gtk_tree_view_get_model (view->details->tree_view);
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_model_get (model, &iter,
- nautilus_list_model_get_column_id_from_zoom_level (view->details->zoom_level),
- &ret,
- -1);
-
- gtk_tree_view_get_cell_area (view->details->tree_view,
- path,
- view->details->file_name_column,
- &cell_area);
-
- gtk_tree_path_free (path);
- }
-
- return ret;
-}
-
-/* iteration glue struct */
-typedef struct {
- NautilusListView *view;
- NautilusDragEachSelectedItemDataGet iteratee;
- gpointer iteratee_data;
-} ListGetDataBinderContext;
-
-static void
-item_get_data_binder (GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data)
-{
- ListGetDataBinderContext *context = data;
- NautilusFile *file;
- GtkTreeView *treeview;
- GtkTreeViewColumn *column;
- GdkRectangle cell_area;
- int drag_begin_y = 0;
- char *uri;
-
- treeview = nautilus_list_model_get_drag_view (context->view->details->model,
- NULL,
- &drag_begin_y);
- column = gtk_tree_view_get_column (treeview, 0);
-
- file = nautilus_list_model_file_for_path (NAUTILUS_LIST_MODEL (model), path);
- if (file == NULL) {
- return;
- }
-
- gtk_tree_view_get_cell_area (treeview,
- path,
- column,
- &cell_area);
-
- if (nautilus_file_is_nautilus_link (file)) {
- uri = nautilus_file_get_uri (file);
- } else {
- uri = nautilus_file_get_activation_uri (file);
- }
- nautilus_file_unref (file);
-
- /* pass the uri, mouse-relative x/y and icon width/height */
- context->iteratee (uri,
- 0,
- cell_area.y - drag_begin_y,
- cell_area.width,
- cell_area.height,
- context->iteratee_data);
-
- g_free (uri);
-}
-
-static void
-each_item_get_data_binder (NautilusDragEachSelectedItemDataGet iteratee,
- gpointer iterator_context,
- gpointer data)
-{
- NautilusListView *view = NAUTILUS_LIST_VIEW (iterator_context);
- ListGetDataBinderContext context;
- GtkTreeSelection *selection;
-
- context.view = view;
- context.iteratee = iteratee;
- context.iteratee_data = data;
-
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view->details->tree_view));
- gtk_tree_selection_selected_foreach (selection, item_get_data_binder, &context);
-}
-
-
-static void
-drag_begin_callback (GtkWidget *widget,
- GdkDragContext *context,
- NautilusListView *view)
-{
- GList *selection_cache;
- cairo_surface_t *surface;
-
- surface = get_drag_surface (view);
- if (surface) {
- gtk_drag_set_icon_surface (context, surface);
- cairo_surface_destroy (surface);
- } else {
- gtk_drag_set_icon_default (context);
- }
-
- stop_drag_check (view);
- view->details->drag_started = TRUE;
-
- selection_cache = nautilus_drag_create_selection_cache (view,
- each_item_get_data_binder);
-
- g_object_set_data_full (G_OBJECT (context),
- "drag-info",
- selection_cache,
- (GDestroyNotify)nautilus_drag_destroy_selection_list);
-}
-
static gboolean
motion_notify_callback (GtkWidget *widget,
GdkEventMotion *event,
gpointer callback_data)
{
NautilusListView *view;
-
+ gboolean handled = FALSE;
+
view = NAUTILUS_LIST_VIEW (callback_data);
if (event->window != gtk_tree_view_get_bin_window (GTK_TREE_VIEW (widget))) {
@@ -543,27 +333,9 @@ motion_notify_callback (GtkWidget *widget,
}
}
- if (view->details->drag_button != 0) {
- if (!source_target_list) {
- source_target_list = nautilus_list_model_get_drag_target_list ();
- }
+ handled = nautilus_list_view_dnd_drag_begin (view, event);
- if (gtk_drag_check_threshold (widget,
- view->details->drag_x,
- view->details->drag_y,
- event->x,
- event->y)) {
- gtk_drag_begin
- (widget,
- source_target_list,
- GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_ASK,
- view->details->drag_button,
- (GdkEvent*)event);
- }
- return TRUE;
- }
-
- return FALSE;
+ return handled;
}
static gboolean
@@ -846,7 +618,7 @@ button_release_callback (GtkWidget *widget,
view = NAUTILUS_LIST_VIEW (callback_data);
if (event->button == view->details->drag_button) {
- stop_drag_check (view);
+ view->details->drag_button = 0;
if (!view->details->drag_started &&
!view->details->ignore_button_release) {
nautilus_list_view_did_not_drag (view, event);
@@ -1849,10 +1621,7 @@ create_and_set_up_tree_view (NautilusListView *view)
"changed",
G_CALLBACK (list_selection_changed_callback), view, 0);
- g_signal_connect_object (view->details->tree_view, "drag-begin",
- G_CALLBACK (drag_begin_callback), view, 0);
- g_signal_connect_object (view->details->tree_view, "drag-data-get",
- G_CALLBACK (drag_data_get_callback), view, 0);
+ nautilus_list_view_dnd_init (view);
g_signal_connect_object (view->details->tree_view, "motion-notify-event",
G_CALLBACK (motion_notify_callback), view, 0);
g_signal_connect_object (view->details->tree_view, "enter-notify-event",