Commit 57c8b041 authored by Cosimo Cecchi's avatar Cosimo Cecchi

view: split DnD code into its own module

And use new method names in other classes
parent 1f734cce
......@@ -123,6 +123,8 @@ nautilus_SOURCES = \
nautilus-view-as-action.h \
nautilus-view.c \
nautilus-view.h \
nautilus-view-dnd.c \
nautilus-view-dnd.h \
nautilus-view-factory.c \
nautilus-view-factory.h \
nautilus-window-bookmarks.c \
......
......@@ -29,6 +29,7 @@
#include "fm-icon-container.h"
#include "fm-desktop-icon-view.h"
#include "fm-error-reporting.h"
#include "nautilus-view-dnd.h"
#include "nautilus-view-factory.h"
#include <stdlib.h>
......@@ -2664,13 +2665,13 @@ icon_view_move_copy_items (NautilusIconContainer *container,
const char *target_dir,
int copy_action,
int x, int y,
FMDirectoryView *view)
NautilusView *view)
{
nautilus_clipboard_clear_if_colliding_uris (GTK_WIDGET (view),
item_uris,
fm_directory_view_get_copied_files_atom (view));
fm_directory_view_move_copy_items (item_uris, relative_item_points, target_dir,
copy_action, x, y, view);
nautilus_view_move_copy_items (view, item_uris, relative_item_points, target_dir,
copy_action, x, y);
}
static void
......@@ -2833,8 +2834,8 @@ icon_view_handle_netscape_url (NautilusIconContainer *container, const char *enc
const char *target_uri,
GdkDragAction action, int x, int y, FMIconView *view)
{
fm_directory_view_handle_netscape_url_drop (FM_DIRECTORY_VIEW (view),
encoded_url, target_uri, action, x, y);
nautilus_view_handle_netscape_url_drop (NAUTILUS_VIEW (view),
encoded_url, target_uri, action, x, y);
}
static void
......@@ -2842,8 +2843,8 @@ icon_view_handle_uri_list (NautilusIconContainer *container, const char *item_ur
const char *target_uri,
GdkDragAction action, int x, int y, FMIconView *view)
{
fm_directory_view_handle_uri_list_drop (FM_DIRECTORY_VIEW (view),
item_uris, target_uri, action, x, y);
nautilus_view_handle_uri_list_drop (NAUTILUS_VIEW (view),
item_uris, target_uri, action, x, y);
}
static void
......@@ -2851,8 +2852,8 @@ icon_view_handle_text (NautilusIconContainer *container, const char *text,
const char *target_uri,
GdkDragAction action, int x, int y, FMIconView *view)
{
fm_directory_view_handle_text_drop (FM_DIRECTORY_VIEW (view),
text, target_uri, action, x, y);
nautilus_view_handle_text_drop (NAUTILUS_VIEW (view),
text, target_uri, action, x, y);
}
static void
......@@ -2860,8 +2861,8 @@ icon_view_handle_raw (NautilusIconContainer *container, const char *raw_data,
int length, const char *target_uri, const char *direct_save_uri,
GdkDragAction action, int x, int y, FMIconView *view)
{
fm_directory_view_handle_raw_drop (FM_DIRECTORY_VIEW (view),
raw_data, length, target_uri, direct_save_uri, action, x, y);
nautilus_view_handle_raw_drop (NAUTILUS_VIEW (view),
raw_data, length, target_uri, direct_save_uri, action, x, y);
}
static char *
......
......@@ -31,6 +31,7 @@
#include <string.h>
#include "fm-error-reporting.h"
#include "fm-list-model.h"
#include "nautilus-view-dnd.h"
#include "nautilus-view-factory.h"
#include <string.h>
......@@ -1285,8 +1286,8 @@ static void
list_view_handle_netscape_url (NautilusTreeViewDragDest *dest, const char *encoded_url,
const char *target_uri, GdkDragAction action, int x, int y, FMListView *view)
{
fm_directory_view_handle_netscape_url_drop (FM_DIRECTORY_VIEW (view),
encoded_url, target_uri, action, x, y);
nautilus_view_handle_netscape_url_drop (NAUTILUS_VIEW (view),
encoded_url, target_uri, action, x, y);
}
static void
......@@ -1294,8 +1295,8 @@ list_view_handle_uri_list (NautilusTreeViewDragDest *dest, const char *item_uris
const char *target_uri,
GdkDragAction action, int x, int y, FMListView *view)
{
fm_directory_view_handle_uri_list_drop (FM_DIRECTORY_VIEW (view),
item_uris, target_uri, action, x, y);
nautilus_view_handle_uri_list_drop (NAUTILUS_VIEW (view),
item_uris, target_uri, action, x, y);
}
static void
......@@ -1303,8 +1304,8 @@ list_view_handle_text (NautilusTreeViewDragDest *dest, const char *text,
const char *target_uri,
GdkDragAction action, int x, int y, FMListView *view)
{
fm_directory_view_handle_text_drop (FM_DIRECTORY_VIEW (view),
text, target_uri, action, x, y);
nautilus_view_handle_text_drop (NAUTILUS_VIEW (view),
text, target_uri, action, x, y);
}
static void
......@@ -1312,9 +1313,9 @@ list_view_handle_raw (NautilusTreeViewDragDest *dest, const char *raw_data,
int length, const char *target_uri, const char *direct_save_uri,
GdkDragAction action, int x, int y, FMListView *view)
{
fm_directory_view_handle_raw_drop (FM_DIRECTORY_VIEW (view),
raw_data, length, target_uri, direct_save_uri,
action, x, y);
nautilus_view_handle_raw_drop (NAUTILUS_VIEW (view),
raw_data, length, target_uri, direct_save_uri,
action, x, y);
}
static void
......@@ -1327,17 +1328,17 @@ move_copy_items_callback (NautilusTreeViewDragDest *dest,
gpointer user_data)
{
FMDirectoryView *view = user_data;
NautilusView *view = user_data;
nautilus_clipboard_clear_if_colliding_uris (GTK_WIDGET (view),
item_uris,
fm_directory_view_get_copied_files_atom (view));
fm_directory_view_move_copy_items (item_uris,
NULL,
target_uri,
action,
x, y,
view);
nautilus_view_move_copy_items (view,
item_uris,
NULL,
target_uri,
action,
x, y);
}
static void
......
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/*
* nautilus-view-dnd.c: DnD helpers for NautilusView
*
* Copyright (C) 1999, 2000 Free Software Foundaton
* Copyright (C) 2000, 2001 Eazel, Inc.
*
* 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 2 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, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Authors: Ettore Perazzoli
* Darin Adler <darin@bentspoon.com>
* John Sullivan <sullivan@eazel.com>
* Pavel Cisler <pavel@eazel.com>
*/
#include <config.h>
#include "nautilus-view-dnd.h"
#include "nautilus-view.h"
#include "file-manager/fm-desktop-icon-view.h"
#include <eel/eel-stock-dialogs.h>
#include <eel/eel-string.h>
#include <libnautilus-private/nautilus-clipboard.h>
#include <libnautilus-private/nautilus-dnd.h>
#define GET_ANCESTOR(obj) \
GTK_WINDOW (gtk_widget_get_ancestor (GTK_WIDGET (obj), GTK_TYPE_WINDOW))
static inline void
view_widget_to_file_operation_position (NautilusView *view,
GdkPoint *position)
{
NautilusViewClass *class = NAUTILUS_VIEW_GET_CLASS (view);
if (class->widget_to_file_operation_position != NULL) {
class->widget_to_file_operation_position (view, position);
}
}
static void
view_widget_to_file_operation_position_xy (NautilusView *view,
int *x, int *y)
{
GdkPoint position;
position.x = *x;
position.y = *y;
view_widget_to_file_operation_position (view, &position);
*x = position.x;
*y = position.y;
}
typedef struct {
FMDirectoryView *view;
GCancellable *cancellable;
char *encoded_url;
char *target_uri;
int x;
int y;
guint timeout;
} NetscapeUrlDropAsk;
static GdkDragAction
ask_link_action (NautilusView *view)
{
int button_pressed;
GdkDragAction result;
GtkWindow *parent_window;
GtkWidget *dialog;
parent_window = NULL;
/* Don't use desktop window as parent, since that means
we show up an all desktops etc */
if (! FM_IS_DESKTOP_ICON_VIEW (view)) {
parent_window = GTK_WINDOW (GET_ANCESTOR (view));
}
dialog = gtk_message_dialog_new (parent_window,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_NONE,
_("Download location?"));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
_("You can download it or make a link to it."));
gtk_dialog_add_button (GTK_DIALOG (dialog),
_("Make a _Link"), 0);
gtk_dialog_add_button (GTK_DIALOG (dialog),
GTK_STOCK_CANCEL, 1);
gtk_dialog_add_button (GTK_DIALOG (dialog),
_("_Download"), 2);
gtk_window_set_title (GTK_WINDOW (dialog), ""); /* as per HIG */
gtk_window_set_focus_on_map (GTK_WINDOW (dialog), TRUE);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), 2);
gtk_window_present (GTK_WINDOW (dialog));
button_pressed = gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
switch (button_pressed) {
case 0:
result = GDK_ACTION_LINK;
break;
case 1:
case GTK_RESPONSE_DELETE_EVENT:
result = 0;
break;
case 2:
result = GDK_ACTION_COPY;
break;
default:
g_assert_not_reached ();
result = 0;
}
return result;
}
static void
revert_slashes (char *string)
{
while (*string != 0) {
if (*string == '/') {
*string = '\\';
}
string++;
}
}
static void
handle_netscape_url_drop_ask_cb (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
NetscapeUrlDropAsk *data;
GdkDragAction action;
GFileInfo *info;
GFile *f;
const char *mime_type;
data = user_data;
f = G_FILE (source_object);
info = g_file_query_info_finish (f, res, NULL);
mime_type = NULL;
if (info) {
mime_type = g_file_info_get_content_type (info);
}
if (mime_type != NULL &&
(g_content_type_equals (mime_type, "text/html") ||
g_content_type_equals (mime_type, "text/xml") ||
g_content_type_equals (mime_type, "application/xhtml+xml"))) {
action = GDK_ACTION_LINK;
} else if (mime_type != NULL &&
g_content_type_equals (mime_type, "text/plain")) {
action = ask_link_action (data->view);
} else {
action = GDK_ACTION_COPY;
}
if (info) {
g_object_unref (info);
}
if (action != 0) {
nautilus_view_handle_netscape_url_drop (data->view,
data->encoded_url,
data->target_uri,
action,
data->x, data->y);
}
g_object_unref (data->view);
g_object_unref (data->cancellable);
if (data->timeout != 0) {
g_source_remove (data->timeout);
}
g_free (data->encoded_url);
g_free (data->target_uri);
g_free (data);
}
static gboolean
handle_netscape_url_drop_timeout (gpointer user_data)
{
NetscapeUrlDropAsk *data;
data = user_data;
g_cancellable_cancel (data->cancellable);
data->timeout = 0;
return FALSE;
}
void
nautilus_view_handle_netscape_url_drop (NautilusView *view,
const char *encoded_url,
const char *target_uri,
GdkDragAction action,
int x,
int y)
{
GdkPoint point;
GdkScreen *screen;
int screen_num;
char *url, *title;
char *link_name, *link_display_name;
char *container_uri;
GArray *points;
char **bits;
GList *uri_list = NULL;
GFile *f;
if (encoded_url == NULL) {
return;
}
container_uri = NULL;
if (target_uri == NULL) {
container_uri = nautilus_view_get_backing_uri (view);
g_assert (container_uri != NULL);
}
f = g_file_new_for_uri (target_uri != NULL ? target_uri : container_uri);
if (!g_file_is_native (f)) {
eel_show_warning_dialog (_("Drag and drop is not supported."),
_("Drag and drop is only supported on local file systems."),
GET_ANCESTOR (view));
g_object_unref (f);
g_free (container_uri);
return;
}
g_object_unref (f);
/* _NETSCAPE_URL_ works like this: $URL\n$TITLE */
bits = g_strsplit (encoded_url, "\n", 0);
switch (g_strv_length (bits)) {
case 0:
g_strfreev (bits);
g_free (container_uri);
return;
case 1:
url = bits[0];
title = NULL;
break;
default:
url = bits[0];
title = bits[1];
}
if (action == GDK_ACTION_ASK) {
NetscapeUrlDropAsk *data;
f = g_file_new_for_uri (url);
data = g_new0 (NetscapeUrlDropAsk, 1);
data->view = g_object_ref (view);
data->cancellable = g_cancellable_new ();
data->encoded_url = g_strdup (encoded_url);
data->target_uri = g_strdup (target_uri);
data->x = x;
data->y = y;
/* Ensure we wait at most 1 second for mimetype */
data->timeout = g_timeout_add (1000,
handle_netscape_url_drop_timeout,
data);
g_file_query_info_async (f,
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, 0,
0, data->cancellable,
handle_netscape_url_drop_ask_cb,
data);
g_free (container_uri);
return;
}
view_widget_to_file_operation_position_xy (view, &x, &y);
/* We don't support GDK_ACTION_ASK or GDK_ACTION_PRIVATE
* and we don't support combinations either. */
if ((action != GDK_ACTION_DEFAULT) &&
(action != GDK_ACTION_COPY) &&
(action != GDK_ACTION_MOVE) &&
(action != GDK_ACTION_LINK)) {
eel_show_warning_dialog (_("Drag and drop is not supported."),
_("An invalid drag type was used."),
GET_ANCESTOR (view));
g_free (container_uri);
return;
}
if (action == GDK_ACTION_LINK) {
if (eel_str_is_empty (title)) {
GFile *f;
f = g_file_new_for_uri (url);
link_name = g_file_get_basename (f);
g_object_unref (f);
} else {
link_name = g_strdup (title);
}
if (!eel_str_is_empty (link_name)) {
link_display_name = g_strdup_printf (_("Link to %s"), link_name);
/* The filename can't contain slashes, strip em.
(the basename of http://foo/ is http://foo/) */
revert_slashes (link_name);
point.x = x;
point.y = y;
screen = gtk_widget_get_screen (GTK_WIDGET (view));
screen_num = gdk_screen_get_number (screen);
nautilus_link_local_create (target_uri != NULL ? target_uri : container_uri,
link_name,
link_display_name,
"gnome-fs-bookmark",
url,
&point,
screen_num,
TRUE);
g_free (link_display_name);
}
g_free (link_name);
} else {
GdkPoint tmp_point = { 0, 0 };
/* pass in a 1-item array of icon positions, relative to x, y */
points = g_array_new (FALSE, TRUE, sizeof (GdkPoint));
g_array_append_val (points, tmp_point);
uri_list = g_list_append (uri_list, url);
nautilus_view_move_copy_items (view, uri_list, points,
target_uri != NULL ? target_uri : container_uri,
action, x, y);
g_list_free (uri_list);
g_array_free (points, TRUE);
}
g_strfreev (bits);
g_free (container_uri);
}
void
nautilus_view_handle_uri_list_drop (NautilusView *view,
const char *item_uris,
const char *target_uri,
GdkDragAction action,
int x,
int y)
{
gchar **uri_list;
GList *real_uri_list = NULL;
char *container_uri;
int n_uris, i;
GArray *points;
if (item_uris == NULL) {
return;
}
container_uri = NULL;
if (target_uri == NULL) {
container_uri = nautilus_view_get_backing_uri (view);
g_assert (container_uri != NULL);
}
if (action == GDK_ACTION_ASK) {
action = nautilus_drag_drop_action_ask
(GTK_WIDGET (view),
GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK);
if (action == 0) {
g_free (container_uri);
return;
}
}
/* We don't support GDK_ACTION_ASK or GDK_ACTION_PRIVATE
* and we don't support combinations either. */
if ((action != GDK_ACTION_DEFAULT) &&
(action != GDK_ACTION_COPY) &&
(action != GDK_ACTION_MOVE) &&
(action != GDK_ACTION_LINK)) {
eel_show_warning_dialog (_("Drag and drop is not supported."),
_("An invalid drag type was used."),
GET_ANCESTOR (view));
g_free (container_uri);
return;
}
n_uris = 0;
uri_list = g_uri_list_extract_uris (item_uris);
for (i = 0; uri_list[i] != NULL; i++) {
real_uri_list = g_list_append (real_uri_list, uri_list[i]);
n_uris++;
}
g_free (uri_list);
/* do nothing if no real uris are left */
if (n_uris == 0) {
g_free (container_uri);
return;
}
if (n_uris == 1) {
GdkPoint tmp_point = { 0, 0 };
/* pass in a 1-item array of icon positions, relative to x, y */
points = g_array_new (FALSE, TRUE, sizeof (GdkPoint));
g_array_append_val (points, tmp_point);
} else {
points = NULL;
}
view_widget_to_file_operation_position_xy (view, &x, &y);
nautilus_view_move_copy_items (view, real_uri_list, points,
target_uri != NULL ? target_uri : container_uri,
action, x, y);
g_list_free_full (real_uri_list, g_free);
if (points != NULL)
g_array_free (points, TRUE);
g_free (container_uri);
}
void
nautilus_view_handle_text_drop (NautilusView *view,
const char *text,
const char *target_uri,
GdkDragAction action,
int x,
int y)
{
int length;
char *container_uri;
GdkPoint pos;
if (text == NULL) {
return;
}
g_return_if_fail (action == GDK_ACTION_COPY);
container_uri = NULL;
if (target_uri == NULL) {
container_uri = nautilus_view_get_backing_uri (view);
g_assert (container_uri != NULL);
}
length = strlen (text);
pos.x = x;
pos.y = y;
view_widget_to_file_operation_position (view, &pos);
nautilus_view_new_file_with_initial_contents (
view, target_uri != NULL ? target_uri : container_uri,
/* Translator: This is the filename used for when you dnd text to a directory */
_("dropped text.txt"),
text, length, &pos);
g_free (container_uri);
}
void
nautilus_view_handle_raw_drop (NautilusView *view,
const char *raw_data,
int length,
const char *target_uri,
const char *direct_save_uri,
GdkDragAction action,
int x,
int y)
{
char *container_uri, *filename;
GFile *direct_save_full;
GdkPoint pos;
if (raw_data == NULL) {
return;
}
g_return_if_fail (action == GDK_ACTION_COPY);
container_uri = NULL;
if (target_uri == NULL) {
container_uri = nautilus_view_get_backing_uri (view);
g_assert (container_uri != NULL);
}
pos.x = x;
pos.y = y;
view_widget_to_file_operation_position (view, &pos);
filename = NULL;
if (direct_save_uri != NULL) {
direct_save_full = g_file_new_for_uri (direct_save_uri);
filename = g_file_get_basename (direct_save_full);
}
if (filename == NULL) {
/* Translator: This is the filename used for when you dnd raw
* data to a directory, if the source didn't supply a name.
*/
filename = g_strdup (_("dropped data"));
}
nautilus_view_new_file_with_initial_contents (
view, target_uri != NULL ? target_uri : container_uri,
filename, raw_data, length, &pos);
g_free (container_uri);
g_free (filename);
}
void
nautilus_view_drop_proxy_received_uris (NautilusView *view,
const GList *source_uri_list,
const char *target_uri,
GdkDragAction action)
{
char *container_uri;
container_uri = NULL;
if (target_uri == NULL) {
container_uri = nautilus_view_get_backing_uri (view);
g_assert (container_uri != NULL);
}
if (action == GDK_ACTION_ASK) {
action = nautilus_drag_drop_action_ask
(GTK_WIDGET (view),
GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK);
if (action == 0) {
return;
}
}
nautilus_clipboard_clear_if_colliding_uris (GTK_WIDGET (view),
source_uri_list,
fm_directory_view_get_copied_files_atom (view));
nautilus_view_move_copy_items (view, source_uri_list, NULL,
target_uri != NULL ? target_uri : container_uri,
action, 0, 0);
g_free (container_uri);
}
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/*
* nautilus-view-dnd.h: DnD helpers for NautilusView
*
* Copyright (C) 1999, 2000 Free Software Foundaton
* Copyright (C) 2000, 2001 Eazel, Inc.
*
* This program is free software; you can redistribute it and/or