diff options
author | Carlos Soriano <csoriano@gnome.org> | 2015-10-05 13:57:51 +0200 |
---|---|---|
committer | Carlos Soriano <csoriano@gnome.org> | 2015-10-06 19:22:09 +0200 |
commit | ef14edf6343c2fbc7a24c4df343eae5b68a7d3b3 (patch) | |
tree | 83cc0163ed0ef8b4d9323b9ffb5558578beeb5aa | |
parent | f4f23383aca4bbba38ab5050c7fea1a88192ff04 (diff) | |
download | nautilus-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.am | 3 | ||||
-rw-r--r-- | src/nautilus-list-view-dnd.c | 222 | ||||
-rw-r--r-- | src/nautilus-list-view-dnd.h | 29 | ||||
-rw-r--r-- | src/nautilus-list-view-private.h | 68 | ||||
-rw-r--r-- | src/nautilus-list-view.c | 247 |
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", |