summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdk/gdkcontentdeserializer.c23
-rw-r--r--gdk/gdkcontentformats.c16
-rw-r--r--gdk/gdkcontentformats.h6
-rw-r--r--gdk/gdkcontentserializer.c83
-rw-r--r--tests/testclipboard2.c27
5 files changed, 137 insertions, 18 deletions
diff --git a/gdk/gdkcontentdeserializer.c b/gdk/gdkcontentdeserializer.c
index b9a369f2ab..22f911d319 100644
--- a/gdk/gdkcontentdeserializer.c
+++ b/gdk/gdkcontentdeserializer.c
@@ -22,7 +22,6 @@
#include "gdkcontentdeserializer.h"
#include "gdkcontentformats.h"
-#include "gdkintl.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
@@ -532,6 +531,7 @@ file_uri_deserializer_finish (GObject *source,
GOutputStream *stream = G_OUTPUT_STREAM (source);
GError *error = NULL;
gssize written;
+ GValue *value;
char *str;
char **uris;
@@ -554,17 +554,21 @@ file_uri_deserializer_finish (GObject *source,
uris = g_uri_list_extract_uris (str);
g_free (str);
- if (uris == NULL || uris[0] == NULL)
+ value = gdk_content_deserializer_get_value (deserializer);
+ if (G_VALUE_HOLDS (value, G_TYPE_FILE))
{
- error = g_error_new (G_IO_ERROR, G_IO_ERROR, _("No file given"));
- gdk_content_deserializer_return_error (deserializer, error);
+ if (uris[0] != NULL)
+ g_value_take_object (value, g_file_new_for_uri (uris[0]));
}
else
{
- GFile *file = g_file_new_for_uri (uris[0]);
+ GSList *l = NULL;
+ gsize i;
+
+ for (i = 0; uris[i] != NULL; i++)
+ l = g_slist_prepend (l, g_file_new_for_uri (uris[i]));
- g_value_take_object (gdk_content_deserializer_get_value (deserializer), file);
- gdk_content_deserializer_return_success (deserializer);
+ g_value_take_boxed (value, g_slist_reverse (l));
}
g_strfreev (uris);
}
@@ -640,6 +644,11 @@ init (void)
g_slist_free (formats);
gdk_content_register_deserializer ("text/uri-list",
+ GDK_TYPE_FILE_LIST,
+ file_uri_deserializer,
+ NULL,
+ NULL);
+ gdk_content_register_deserializer ("text/uri-list",
G_TYPE_FILE,
file_uri_deserializer,
NULL,
diff --git a/gdk/gdkcontentformats.c b/gdk/gdkcontentformats.c
index 5e7d5ea2f5..d5d071f699 100644
--- a/gdk/gdkcontentformats.c
+++ b/gdk/gdkcontentformats.c
@@ -642,3 +642,19 @@ gdk_content_formats_builder_add_mime_type (GdkContentFormatsBuilder *builder,
builder->n_mime_types++;
}
+/* G_DEFINE_BOXED wants this */
+typedef gpointer GdkFileList;
+
+static gpointer
+gdk_file_list_copy (gpointer list)
+{
+ return g_slist_copy_deep (list, (GCopyFunc) g_object_ref, NULL);
+}
+
+static void
+gdk_file_list_free (gpointer list)
+{
+ g_slist_free_full (list, g_object_unref);
+}
+
+G_DEFINE_BOXED_TYPE (GdkFileList, gdk_file_list, gdk_file_list_copy, gdk_file_list_free)
diff --git a/gdk/gdkcontentformats.h b/gdk/gdkcontentformats.h
index 1e5f7147bb..58bbb103fd 100644
--- a/gdk/gdkcontentformats.h
+++ b/gdk/gdkcontentformats.h
@@ -93,6 +93,12 @@ GDK_AVAILABLE_IN_3_94
void gdk_content_formats_builder_add_gtype (GdkContentFormatsBuilder *builder,
GType type);
+/* dunno where else to put this */
+#define GDK_TYPE_FILE_LIST (gdk_file_list_get_type ())
+GDK_AVAILABLE_IN_3_94
+GType gdk_file_list_get_type (void) G_GNUC_CONST;
+
+
G_END_DECLS
#endif /* __GTK_CONTENT_FORMATS_H__ */
diff --git a/gdk/gdkcontentserializer.c b/gdk/gdkcontentserializer.c
index eddc8be64e..6153e82204 100644
--- a/gdk/gdkcontentserializer.c
+++ b/gdk/gdkcontentserializer.c
@@ -530,15 +530,39 @@ file_uri_serializer (GdkContentSerializer *serializer)
{
GFile *file;
GString *str;
+ const GValue *value;
char *uri;
str = g_string_new (NULL);
+ value = gdk_content_serializer_get_value (serializer);
- file = g_value_get_object (gdk_content_serializer_get_value (serializer));
- uri = g_file_get_uri (file);
- g_string_append (str, uri);
- g_free (uri);
- g_string_append (str, "\r\n");
+ if (G_VALUE_HOLDS (value, G_TYPE_FILE))
+ {
+ file = g_value_get_object (gdk_content_serializer_get_value (serializer));
+ if (file)
+ {
+ uri = g_file_get_uri (file);
+ g_string_append (str, uri);
+ g_free (uri);
+ }
+ else
+ {
+ g_string_append (str, "# GTK does not crash when copying a NULL GFile!");
+ }
+ g_string_append (str, "\r\n");
+ }
+ else if (G_VALUE_HOLDS (value, GDK_TYPE_FILE_LIST))
+ {
+ GSList *l;
+
+ for (l = g_value_get_boxed (value); l; l = l->next)
+ {
+ uri = g_file_get_uri (l->data);
+ g_string_append (str, uri);
+ g_free (uri);
+ g_string_append (str, "\r\n");
+ }
+ }
g_output_stream_write_all_async (gdk_content_serializer_get_output_stream (serializer),
str->str,
@@ -553,13 +577,42 @@ file_uri_serializer (GdkContentSerializer *serializer)
static void
file_text_serializer (GdkContentSerializer *serializer)
{
- GFile *file;
+ const GValue *value;
char *path;
- file = g_value_get_object (gdk_content_serializer_get_value (serializer));
- path = g_file_get_path (file);
- if (path == NULL)
- path = g_file_get_uri (file);
+ value = gdk_content_serializer_get_value (serializer);
+
+ if (G_VALUE_HOLDS (value, G_TYPE_FILE))
+ {
+ GFile *file;
+
+ file = g_value_get_object (value);
+ if (file)
+ {
+ path = g_file_get_path (file);
+ if (path == NULL)
+ path = g_file_get_uri (file);
+ }
+ }
+ else if (G_VALUE_HOLDS (value, GDK_TYPE_FILE_LIST))
+ {
+ GString *str;
+ GSList *l;
+
+ str = g_string_new (NULL);
+
+ for (l = g_value_get_boxed (value); l; l = l->next)
+ {
+ path = g_file_get_path (l->data);
+ if (path == NULL)
+ path = g_file_get_uri (l->data);
+ g_string_append (str, path);
+ g_free (path);
+ if (l->next)
+ g_string_append (str, " ");
+ }
+ path = g_string_free (str, FALSE);
+ }
g_output_stream_write_all_async (gdk_content_serializer_get_output_stream (serializer),
path,
@@ -637,6 +690,16 @@ init (void)
file_text_serializer,
NULL,
NULL);
+ gdk_content_register_serializer (GDK_TYPE_FILE_LIST,
+ "text/uri-list",
+ file_uri_serializer,
+ NULL,
+ NULL);
+ gdk_content_register_serializer (GDK_TYPE_FILE_LIST,
+ "text/plain;charset=utf-8",
+ file_text_serializer,
+ NULL,
+ NULL);
gdk_content_register_serializer (G_TYPE_STRING,
"text/plain;charset=utf-8",
diff --git a/tests/testclipboard2.c b/tests/testclipboard2.c
index 4baabf5f86..abc4751a30 100644
--- a/tests/testclipboard2.c
+++ b/tests/testclipboard2.c
@@ -102,7 +102,26 @@ visible_child_changed_cb (GtkWidget *stack,
label);
}
}
-
+
+static GList *
+get_file_list (const char *dir)
+{
+ GFileEnumerator *enumerator;
+ GFile *file;
+ GList *list = NULL;
+
+ file = g_file_new_for_path (dir);
+ enumerator = g_file_enumerate_children (file, "standard::name", 0, NULL, NULL);
+ g_object_unref (file);
+ if (enumerator == NULL)
+ return NULL;
+
+ while (g_file_enumerator_iterate (enumerator, NULL, &file, NULL, NULL) && file != NULL)
+ list = g_list_prepend (list, g_object_ref (file));
+
+ return g_list_reverse (list);
+}
+
static void
format_list_add_row (GtkWidget *list,
const char *format_name,
@@ -271,6 +290,12 @@ get_button_list (GdkClipboard *clipboard,
"home directory");
g_value_unset (&value);
+ g_value_init (&value, GDK_TYPE_FILE_LIST);
+ g_value_take_boxed (&value, get_file_list (g_get_home_dir ()));
+ add_provider_button (box,
+ gdk_content_provider_new_for_value (&value),
+ clipboard,
+ "files in home");
return box;
}