summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nautilus-canvas-view.c13
-rw-r--r--src/nautilus-clipboard.c116
-rw-r--r--src/nautilus-clipboard.h5
-rw-r--r--src/nautilus-files-view.c113
-rw-r--r--src/nautilus-list-view.c13
5 files changed, 153 insertions, 107 deletions
diff --git a/src/nautilus-canvas-view.c b/src/nautilus-canvas-view.c
index 144deb06b..c4e747e3c 100644
--- a/src/nautilus-canvas-view.c
+++ b/src/nautilus-canvas-view.c
@@ -540,9 +540,9 @@ nautilus_canvas_view_begin_loading (NautilusFilesView *view)
}
static void
-on_clipboard_contents_received (GtkClipboard *clipboard,
- const gchar *selection_data,
- gpointer user_data)
+on_clipboard_contents_received (GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ gpointer user_data)
{
NautilusCanvasView *canvas_view;
@@ -581,9 +581,10 @@ static void
update_clipboard_status (NautilusCanvasView *view)
{
g_object_ref (view); /* Need to keep the object alive until we get the reply */
- gtk_clipboard_request_text (nautilus_clipboard_get (GTK_WIDGET (view)),
- on_clipboard_contents_received,
- view);
+ gtk_clipboard_request_contents (nautilus_clipboard_get (GTK_WIDGET (view)),
+ nautilus_clipboard_get_atom (),
+ on_clipboard_contents_received,
+ view);
}
static void
diff --git a/src/nautilus-clipboard.c b/src/nautilus-clipboard.c
index fb7e96d4b..02bf05497 100644
--- a/src/nautilus-clipboard.c
+++ b/src/nautilus-clipboard.c
@@ -33,6 +33,8 @@
#include <gtk/gtk.h>
#include <string.h>
+static GdkAtom copied_files_atom;
+
typedef struct
{
gboolean cut;
@@ -40,31 +42,21 @@ typedef struct
} ClipboardInfo;
static GList *
-convert_selection_data_to_str_list (const gchar *data)
+convert_lines_to_str_list (char **lines)
{
- g_auto (GStrv) lines = NULL;
- guint number_of_lines;
+ int i;
GList *result;
- lines = g_strsplit (data, "\n", 0);
- number_of_lines = g_strv_length (lines);
- if (number_of_lines == 0)
+ if (lines[0] == NULL)
{
- /* An empty string will result in g_strsplit() returning an empty
- * array, so, naturally, 0 - 1 = UINT_MAX and we read all sorts
- * of invalid memory.
- */
return NULL;
}
- result = NULL;
- /* Also, this skips the last line, since it would be an
- * empty string from the split */
- for (guint i = 0; i < number_of_lines - 1; i++)
+ result = NULL;
+ for (i = 0; lines[i] != NULL; i++)
{
result = g_list_prepend (result, g_strdup (lines[i]));
}
-
return g_list_reverse (result);
}
@@ -85,8 +77,7 @@ convert_file_list_to_string (ClipboardInfo *info,
}
else
{
- uris = g_string_new ("x-special/nautilus-clipboard\n");
- g_string_append (uris, info->cut ? "cut\n" : "copy\n");
+ uris = g_string_new (info->cut ? "cut" : "copy");
}
for (i = 0, l = info->files; l != NULL; l = l->next, i++)
@@ -109,12 +100,16 @@ convert_file_list_to_string (ClipboardInfo *info,
g_string_append (uris, uri);
}
- g_string_append_c (uris, '\n');
+ /* skip newline for last element */
+ if (i + 1 < g_list_length (info->files))
+ {
+ g_string_append_c (uris, '\n');
+ }
}
else
{
- g_string_append (uris, uri);
g_string_append_c (uris, '\n');
+ g_string_append (uris, uri);
}
g_free (uri);
@@ -125,60 +120,43 @@ convert_file_list_to_string (ClipboardInfo *info,
}
static GList *
-get_item_list_from_selection_data (const gchar *selection_data)
+get_item_list_from_selection_data (GtkSelectionData *selection_data)
{
- GList *items = NULL;
+ GList *items;
+ char **lines;
- if (selection_data != NULL)
+ if (gtk_selection_data_get_data_type (selection_data) != copied_files_atom
+ || gtk_selection_data_get_length (selection_data) <= 0)
+ {
+ items = NULL;
+ }
+ else
{
- gboolean valid_data = TRUE;
+ gchar *data;
/* Not sure why it's legal to assume there's an extra byte
* past the end of the selection data that it's safe to write
* to. But gtk_editable_selection_received does this, so I
* think it is OK.
*/
- items = convert_selection_data_to_str_list (selection_data);
- if (items == NULL || g_strcmp0 (items->data, "x-special/nautilus-clipboard") != 0)
- {
- valid_data = FALSE;
- }
- else if (items->next == NULL)
- {
- valid_data = FALSE;
- }
- else if (g_strcmp0 (items->next->data, "cut") != 0 &&
- g_strcmp0 (items->next->data, "copy") != 0)
- {
- valid_data = FALSE;
- }
-
- if (!valid_data)
- {
- g_list_free_full (items, g_free);
- items = NULL;
- }
+ data = (gchar *) gtk_selection_data_get_data (selection_data);
+ data[gtk_selection_data_get_length (selection_data)] = '\0';
+ lines = g_strsplit (data, "\n", 0);
+ items = convert_lines_to_str_list (lines);
+ g_strfreev (lines);
}
return items;
}
-gboolean
-nautilus_clipboard_is_data_valid_from_selection_data (const gchar *selection_data)
-{
- return nautilus_clipboard_get_uri_list_from_selection_data (selection_data) != NULL;
-}
-
GList *
-nautilus_clipboard_get_uri_list_from_selection_data (const gchar *selection_data)
+nautilus_clipboard_get_uri_list_from_selection_data (GtkSelectionData *selection_data)
{
GList *items;
items = get_item_list_from_selection_data (selection_data);
if (items)
{
- /* Line 0 is x-special/nautilus-clipboard. */
- items = g_list_remove (items, items->data);
- /* Line 1 is "cut" or "copy", so uris start at line 2. */
+ /* Line 0 is "cut" or "copy", so uris start at line 1. */
items = g_list_remove (items, items->data);
}
@@ -196,12 +174,13 @@ void
nautilus_clipboard_clear_if_colliding_uris (GtkWidget *widget,
const GList *item_uris)
{
- g_autofree gchar *data = NULL;
+ GtkSelectionData *data;
GList *clipboard_item_uris, *l;
gboolean collision;
collision = FALSE;
- data = gtk_clipboard_wait_for_text (nautilus_clipboard_get (widget));
+ data = gtk_clipboard_wait_for_contents (nautilus_clipboard_get (widget),
+ copied_files_atom);
if (data == NULL)
{
return;
@@ -231,14 +210,14 @@ nautilus_clipboard_clear_if_colliding_uris (GtkWidget *widget,
}
gboolean
-nautilus_clipboard_is_cut_from_selection_data (const gchar *selection_data)
+nautilus_clipboard_is_cut_from_selection_data (GtkSelectionData *selection_data)
{
GList *items;
gboolean is_cut_from_selection_data;
items = get_item_list_from_selection_data (selection_data);
is_cut_from_selection_data = items != NULL &&
- g_strcmp0 ((gchar *) items->next->data, "cut") == 0;
+ g_strcmp0 ((gchar *) items->data, "cut") == 0;
g_list_free_full (items, g_free);
@@ -283,10 +262,19 @@ on_get_clipboard (GtkClipboard *clipboard,
char *str;
gsize len;
- str = convert_file_list_to_string (clipboard_info, FALSE, &len);
+ str = convert_file_list_to_string (clipboard_info, TRUE, &len);
gtk_selection_data_set_text (selection_data, str, len);
g_free (str);
}
+ else if (target == copied_files_atom)
+ {
+ char *str;
+ gsize len;
+
+ str = convert_file_list_to_string (clipboard_info, FALSE, &len);
+ gtk_selection_data_set (selection_data, copied_files_atom, 8, (guchar *) str, len);
+ g_free (str);
+ }
}
static void
@@ -315,6 +303,7 @@ nautilus_clipboard_prepare_for_files (GtkClipboard *clipboard,
clipboard_info->files = nautilus_file_list_copy (files);
target_list = gtk_target_list_new (NULL, 0);
+ gtk_target_list_add (target_list, copied_files_atom, 0, 0);
gtk_target_list_add_uri_targets (target_list, 0);
gtk_target_list_add_text_targets (target_list, 0);
@@ -327,3 +316,14 @@ nautilus_clipboard_prepare_for_files (GtkClipboard *clipboard,
clipboard_info);
gtk_target_table_free (targets, n_targets);
}
+
+GdkAtom
+nautilus_clipboard_get_atom (void)
+{
+ if (!copied_files_atom)
+ {
+ copied_files_atom = gdk_atom_intern_static_string ("x-special/gnome-copied-files");
+ }
+
+ return copied_files_atom;
+}
diff --git a/src/nautilus-clipboard.h b/src/nautilus-clipboard.h
index 61810c154..1dd26d7c2 100644
--- a/src/nautilus-clipboard.h
+++ b/src/nautilus-clipboard.h
@@ -27,10 +27,9 @@
void nautilus_clipboard_clear_if_colliding_uris (GtkWidget *widget,
const GList *item_uris);
GtkClipboard* nautilus_clipboard_get (GtkWidget *widget);
-GList* nautilus_clipboard_get_uri_list_from_selection_data (const gchar *selection_data);
-gboolean nautilus_clipboard_is_cut_from_selection_data (const gchar *selection_data);
+GList* nautilus_clipboard_get_uri_list_from_selection_data (GtkSelectionData *selection_data);
+gboolean nautilus_clipboard_is_cut_from_selection_data (GtkSelectionData *selection_data);
void nautilus_clipboard_prepare_for_files (GtkClipboard *clipboard,
GList *files,
gboolean cut);
GdkAtom nautilus_clipboard_get_atom (void);
-gboolean nautilus_clipboard_is_data_valid_from_selection_data (const gchar *selection_data);
diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c
index 9282e96ca..250c37264 100644
--- a/src/nautilus-files-view.c
+++ b/src/nautilus-files-view.c
@@ -2643,7 +2643,7 @@ action_open_item_new_window (GSimpleAction *action,
static void
handle_clipboard_data (NautilusFilesView *view,
- const gchar *selection_data,
+ GtkSelectionData *selection_data,
char *destination_uri,
GdkDragAction action)
{
@@ -2668,7 +2668,7 @@ handle_clipboard_data (NautilusFilesView *view,
static void
paste_clipboard_data (NautilusFilesView *view,
- const gchar *selection_data,
+ GtkSelectionData *selection_data,
char *destination_uri)
{
GdkDragAction action;
@@ -2686,9 +2686,9 @@ paste_clipboard_data (NautilusFilesView *view,
}
static void
-paste_clipboard_text_received_callback (GtkClipboard *clipboard,
- const gchar *selection_data,
- gpointer data)
+paste_clipboard_received_callback (GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ gpointer data)
{
NautilusFilesView *view;
NautilusFilesViewPrivate *priv;
@@ -2720,10 +2720,10 @@ paste_files (NautilusFilesView *view)
* is in the callback.
*/
g_object_ref (view);
-
- gtk_clipboard_request_text (clipboard,
- paste_clipboard_text_received_callback,
- view);
+ gtk_clipboard_request_contents (clipboard,
+ nautilus_clipboard_get_atom (),
+ paste_clipboard_received_callback,
+ view);
}
static void
@@ -2761,9 +2761,9 @@ action_paste_files_accel (GSimpleAction *action,
}
static void
-create_links_clipboard_received_callback (GtkClipboard *clipboard,
- const gchar *selection_data,
- gpointer data)
+create_links_clipboard_received_callback (GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ gpointer data)
{
NautilusFilesView *view;
NautilusFilesViewPrivate *priv;
@@ -2796,9 +2796,10 @@ action_create_links (GSimpleAction *action,
view = NAUTILUS_FILES_VIEW (user_data);
g_object_ref (view);
- gtk_clipboard_request_text (nautilus_clipboard_get (GTK_WIDGET (view)),
- create_links_clipboard_received_callback,
- view);
+ gtk_clipboard_request_contents (nautilus_clipboard_get (GTK_WIDGET (view)),
+ nautilus_clipboard_get_atom (),
+ create_links_clipboard_received_callback,
+ view);
}
static void
@@ -6182,9 +6183,9 @@ typedef struct
} PasteIntoData;
static void
-paste_into_clipboard_received_callback (GtkClipboard *clipboard,
- const gchar *selection_data,
- gpointer callback_data)
+paste_into_clipboard_received_callback (GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ gpointer callback_data)
{
NautilusFilesViewPrivate *priv;
PasteIntoData *data;
@@ -6224,9 +6225,10 @@ paste_into (NautilusFilesView *view,
data->view = g_object_ref (view);
data->target = nautilus_file_ref (target);
- gtk_clipboard_request_text (nautilus_clipboard_get (GTK_WIDGET (view)),
- paste_into_clipboard_received_callback,
- data);
+ gtk_clipboard_request_contents (nautilus_clipboard_get (GTK_WIDGET (view)),
+ nautilus_clipboard_get_atom (),
+ paste_into_clipboard_received_callback,
+ data);
}
static void
@@ -7235,9 +7237,9 @@ can_paste_into_file (NautilusFile *file)
}
static void
-on_clipboard_contents_received (GtkClipboard *clipboard,
- const gchar *selection_data,
- gpointer user_data)
+on_clipboard_contents_received (GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ gpointer user_data)
{
NautilusFilesViewPrivate *priv;
NautilusFilesView *view;
@@ -7247,7 +7249,6 @@ on_clipboard_contents_received (GtkClipboard *clipboard,
gboolean selection_contains_recent;
gboolean selection_contains_starred;
GAction *action;
- gboolean is_data_valid;
view = NAUTILUS_FILES_VIEW (user_data);
priv = nautilus_files_view_get_instance_private (view);
@@ -7260,7 +7261,6 @@ on_clipboard_contents_received (GtkClipboard *clipboard,
return;
}
- is_data_valid = nautilus_clipboard_is_data_valid_from_selection_data (selection_data);
settings_show_create_link = g_settings_get_boolean (nautilus_preferences,
NAUTILUS_PREFERENCES_SHOW_CREATE_LINK);
is_read_only = nautilus_files_view_is_read_only (view);
@@ -7268,7 +7268,7 @@ on_clipboard_contents_received (GtkClipboard *clipboard,
selection_contains_starred = showing_starred_directory (view);
can_link_from_copied_files = !nautilus_clipboard_is_cut_from_selection_data (selection_data) &&
!selection_contains_recent && !selection_contains_starred &&
- !is_read_only && selection_data != NULL;
+ !is_read_only && gtk_selection_data_get_length (selection_data) > 0;
action = g_action_map_lookup_action (G_ACTION_MAP (priv->view_action_group),
"create-link");
@@ -7276,25 +7276,62 @@ on_clipboard_contents_received (GtkClipboard *clipboard,
can_link_from_copied_files &&
settings_show_create_link);
+ g_object_unref (view);
+}
+
+static void
+on_clipboard_targets_received (GtkClipboard *clipboard,
+ GdkAtom *targets,
+ int n_targets,
+ gpointer user_data)
+{
+ NautilusFilesViewPrivate *priv;
+ NautilusFilesView *view;
+ gboolean is_data_copied;
+ int i;
+ GAction *action;
+
+ view = NAUTILUS_FILES_VIEW (user_data);
+ priv = nautilus_files_view_get_instance_private (view);
+ is_data_copied = FALSE;
+
+ if (priv->slot == NULL ||
+ !priv->active)
+ {
+ /* We've been destroyed or became inactive since call */
+ g_object_unref (view);
+ return;
+ }
+
+ if (targets)
+ {
+ for (i = 0; i < n_targets; i++)
+ {
+ if (targets[i] == nautilus_clipboard_get_atom ())
+ {
+ is_data_copied = TRUE;
+ }
+ }
+ }
+
action = g_action_map_lookup_action (G_ACTION_MAP (priv->view_action_group),
"paste");
/* Take into account if the action was previously disabled for other reasons,
* like the directory not being writabble */
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- is_data_valid && g_action_get_enabled (action));
+ is_data_copied && g_action_get_enabled (action));
action = g_action_map_lookup_action (G_ACTION_MAP (priv->view_action_group),
"paste-into");
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- is_data_valid && g_action_get_enabled (action));
+ is_data_copied && g_action_get_enabled (action));
action = g_action_map_lookup_action (G_ACTION_MAP (priv->view_action_group),
"create-link");
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
- is_data_valid && g_action_get_enabled (action));
-
+ is_data_copied && g_action_get_enabled (action));
g_object_unref (view);
}
@@ -7845,10 +7882,18 @@ real_update_actions_state (NautilusFilesView *view)
!selection_contains_starred &&
priv->templates_present);
+ /* Actions that are related to the clipboard need request, request the data
+ * and update them once we have the data */
+ g_object_ref (view); /* Need to keep the object alive until we get the reply */
+ gtk_clipboard_request_targets (nautilus_clipboard_get (GTK_WIDGET (view)),
+ on_clipboard_targets_received,
+ view);
+
g_object_ref (view); /* Need to keep the object alive until we get the reply */
- gtk_clipboard_request_text (nautilus_clipboard_get (GTK_WIDGET (view)),
- on_clipboard_contents_received,
- view);
+ gtk_clipboard_request_contents (nautilus_clipboard_get (GTK_WIDGET (view)),
+ nautilus_clipboard_get_atom (),
+ on_clipboard_contents_received,
+ view);
action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
"select-all");
diff --git a/src/nautilus-list-view.c b/src/nautilus-list-view.c
index 63e54d11c..e3c0b81f6 100644
--- a/src/nautilus-list-view.c
+++ b/src/nautilus-list-view.c
@@ -3845,9 +3845,9 @@ list_view_scroll_to_file (NautilusFilesView *view,
}
static void
-on_clipboard_contents_received (GtkClipboard *clipboard,
- const gchar *selection_data,
- gpointer user_data)
+on_clipboard_contents_received (GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ gpointer user_data)
{
NautilusListView *view = NAUTILUS_LIST_VIEW (user_data);
@@ -3882,9 +3882,10 @@ static void
update_clipboard_status (NautilusListView *view)
{
g_object_ref (view); /* Need to keep the object alive until we get the reply */
- gtk_clipboard_request_text (nautilus_clipboard_get (GTK_WIDGET (view)),
- on_clipboard_contents_received,
- view);
+ gtk_clipboard_request_contents (nautilus_clipboard_get (GTK_WIDGET (view)),
+ nautilus_clipboard_get_atom (),
+ on_clipboard_contents_received,
+ view);
}
static void