diff options
author | Benjamin Otte <otte@redhat.com> | 2017-11-29 09:37:50 +0100 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2017-12-03 05:46:48 +0100 |
commit | 6b326b14c00e7b030e8f09aac94637250e506df1 (patch) | |
tree | 5c31540eab39a4236698f923397871e313eeccf7 | |
parent | 928c98a84efd2c72bc3ff9fe139ad5296091110a (diff) | |
download | gtk+-6b326b14c00e7b030e8f09aac94637250e506df1.tar.gz |
gdk: Add GDK_TYPE_FILE_LIST with serializers
This is a GSList of GFile and we want it so we can operate with lists of
files and text/uri-list.
I chose GSList over GList because that's what the GtkFileChooser API
uses, too.
-rw-r--r-- | gdk/gdkcontentdeserializer.c | 23 | ||||
-rw-r--r-- | gdk/gdkcontentformats.c | 16 | ||||
-rw-r--r-- | gdk/gdkcontentformats.h | 6 | ||||
-rw-r--r-- | gdk/gdkcontentserializer.c | 83 | ||||
-rw-r--r-- | tests/testclipboard2.c | 27 |
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; } |