From fd606fb2679c0c186e8fe7d5ba0105d0ade7b865 Mon Sep 17 00:00:00 2001 From: Vladimir Nadvornik Date: Fri, 10 Aug 2012 21:55:29 +0200 Subject: [PATCH] fixed dnd used glib functions for uri manipulation --- src/collect-table.c | 10 +- src/dupe.c | 7 +- src/img-view.c | 20 +--- src/layout_image.c | 20 +--- src/pan-view.c | 20 +--- src/search.c | 21 +--- src/ui_bookmark.c | 38 +++--- src/ui_pathsel.c | 20 +--- src/uri_utils.c | 269 ++++++++----------------------------------- src/uri_utils.h | 15 +-- src/view_dir.c | 11 +- src/view_file_icon.c | 7 +- src/view_file_list.c | 8 +- 13 files changed, 99 insertions(+), 367 deletions(-) diff --git a/src/collect-table.c b/src/collect-table.c index 77b19717..5e378a7d 100644 --- a/src/collect-table.c +++ b/src/collect-table.c @@ -2175,6 +2175,9 @@ static void collection_table_dnd_get(GtkWidget *widget, GdkDragContext *context, uri_text = collection_info_list_to_dnd_data(ct->cd, list, &total); g_list_free(list); } + gtk_selection_data_set(selection_data, gtk_selection_data_get_target(selection_data), + 8, (guchar *)uri_text, total); + g_free(uri_text); break; case TARGET_URI_LIST: case TARGET_TEXT_PLAIN: @@ -2189,13 +2192,10 @@ static void collection_table_dnd_get(GtkWidget *widget, GdkDragContext *context, } if (!list) return; - uri_text = uri_text_from_filelist(list, &total, (info == TARGET_TEXT_PLAIN)); + uri_selection_data_set_uris_from_filelist(selection_data, list); filelist_free(list); break; } - - gtk_selection_data_set_text(selection_data, uri_text, total); - g_free(uri_text); } @@ -2254,7 +2254,7 @@ static void collection_table_dnd_receive(GtkWidget *widget, GdkDragContext *cont } break; case TARGET_URI_LIST: - list = uri_filelist_from_text((gchar *)gtk_selection_data_get_data(selection_data), TRUE); + list = uri_filelist_from_gtk_selection_data(selection_data); work = list; while (work) { diff --git a/src/dupe.c b/src/dupe.c index dc67bab6..2c0df5d0 100644 --- a/src/dupe.c +++ b/src/dupe.c @@ -3404,16 +3404,13 @@ static void dupe_dnd_data_set(GtkWidget *widget, GdkDragContext *context, case TARGET_TEXT_PLAIN: list = dupe_listview_get_selection(dw, widget); if (!list) return; - uri_text = uri_text_from_filelist(list, &length, (info == TARGET_TEXT_PLAIN)); + uri_selection_data_set_uris_from_filelist(selection_data, list); filelist_free(list); break; default: uri_text = NULL; break; } - - if (uri_text) gtk_selection_data_set_text(selection_data, uri_text, length); - g_free(uri_text); } static void dupe_dnd_data_get(GtkWidget *widget, GdkDragContext *context, @@ -3437,7 +3434,7 @@ static void dupe_dnd_data_get(GtkWidget *widget, GdkDragContext *context, collection_from_dnd_data((gchar *)gtk_selection_data_get_data(selection_data), &list, NULL); break; case TARGET_URI_LIST: - list = uri_filelist_from_text((gchar *)gtk_selection_data_get_data(selection_data), TRUE); + list = uri_filelist_from_gtk_selection_data(selection_data); work = list; while (work) { diff --git a/src/img-view.c b/src/img-view.c index 6a1d9dfc..5ec79748 100644 --- a/src/img-view.c +++ b/src/img-view.c @@ -1487,7 +1487,7 @@ static void view_window_get_dnd_data(GtkWidget *widget, GdkDragContext *context, { GList *work; - list = uri_filelist_from_text((gchar *)gtk_selection_data_get_data(selection_data), TRUE); + list = uri_filelist_from_gtk_selection_data(selection_data); work = list; while (work) @@ -1558,27 +1558,11 @@ static void view_window_set_dnd_data(GtkWidget *widget, GdkDragContext *context, { gchar *text = NULL; gint len; - gboolean plain_text; GList *list; - switch (info) - { - case TARGET_URI_LIST: - plain_text = FALSE; - break; - case TARGET_TEXT_PLAIN: - default: - plain_text = TRUE; - break; - } list = g_list_append(NULL, fd); - text = uri_text_from_filelist(list, &len, plain_text); + uri_selection_data_set_uris_from_filelist(selection_data, list); g_list_free(list); - if (text) - { - gtk_selection_data_set_text(selection_data, text, len); - g_free(text); - } } else { diff --git a/src/layout_image.c b/src/layout_image.c index 0876674a..152f2817 100644 --- a/src/layout_image.c +++ b/src/layout_image.c @@ -614,7 +614,7 @@ static void layout_image_dnd_receive(GtkWidget *widget, GdkDragContext *context, if (info == TARGET_URI_LIST) { - list = uri_filelist_from_text((gchar *)gtk_selection_data_get_data(selection_data), TRUE); + list = uri_filelist_from_gtk_selection_data(selection_data); source = NULL; info_list = NULL; } @@ -694,27 +694,11 @@ static void layout_image_dnd_get(GtkWidget *widget, GdkDragContext *context, { gchar *text = NULL; gint len; - gboolean plain_text; GList *list; - switch (info) - { - case TARGET_URI_LIST: - plain_text = FALSE; - break; - case TARGET_TEXT_PLAIN: - default: - plain_text = TRUE; - break; - } list = g_list_append(NULL, fd); - text = uri_text_from_filelist(list, &len, plain_text); + uri_selection_data_set_uris_from_filelist(selection_data, list); g_list_free(list); - if (text) - { - gtk_selection_data_set_text(selection_data, text, len); - g_free(text); - } } else { diff --git a/src/pan-view.c b/src/pan-view.c index 82e118c7..84a013bf 100644 --- a/src/pan-view.c +++ b/src/pan-view.c @@ -2933,7 +2933,7 @@ static void pan_window_get_dnd_data(GtkWidget *widget, GdkDragContext *context, { GList *list; - list = uri_filelist_from_text((gchar *)gtk_selection_data_get_data(selection_data), TRUE); + list = uri_filelist_from_gtk_selection_data(selection_data); if (list && isdir(((FileData *)list->data)->path)) { FileData *fd = list->data; @@ -2957,27 +2957,11 @@ static void pan_window_set_dnd_data(GtkWidget *widget, GdkDragContext *context, { gchar *text = NULL; gint len; - gboolean plain_text; GList *list; - switch (info) - { - case TARGET_URI_LIST: - plain_text = FALSE; - break; - case TARGET_TEXT_PLAIN: - default: - plain_text = TRUE; - break; - } list = g_list_append(NULL, fd); - text = uri_text_from_filelist(list, &len, plain_text); + uri_selection_data_set_uris_from_filelist(selection_data, list); g_list_free(list); - if (text) - { - gtk_selection_data_set_text(selection_data, text, len); - g_free(text); - } } else { diff --git a/src/search.c b/src/search.c index 8842d827..8058ae81 100644 --- a/src/search.c +++ b/src/search.c @@ -1376,26 +1376,13 @@ static void search_dnd_data_set(GtkWidget *widget, GdkDragContext *context, guint time, gpointer data) { SearchData *sd = data; - gchar *uri_text; - gint length; GList *list; - switch (info) - { - case TARGET_URI_LIST: - case TARGET_TEXT_PLAIN: - list = search_result_selection_list(sd); - if (!list) return; - uri_text = uri_text_from_filelist(list, &length, (info == TARGET_TEXT_PLAIN)); - filelist_free(list); - break; - default: - uri_text = NULL; - break; - } + list = search_result_selection_list(sd); + if (!list) return; - if (uri_text) gtk_selection_data_set_text(selection_data, uri_text, length); - g_free(uri_text); + uri_selection_data_set_uris_from_filelist(selection_data, list); + filelist_free(list); } static void search_dnd_begin(GtkWidget *widget, GdkDragContext *context, gpointer data) diff --git a/src/ui_bookmark.c b/src/ui_bookmark.c index e807cfa3..0f392b52 100644 --- a/src/ui_bookmark.c +++ b/src/ui_bookmark.c @@ -470,33 +470,30 @@ static void bookmark_drag_set_data(GtkWidget *button, { BookMarkData *bm = data; BookButtonData *b; - gchar *uri_text = NULL; - gint length = 0; GList *list = NULL; -// if (context->dest_window == bm->widget->window) return; +#if GTK_CHECK_VERSION(3,0,0) + if (gdk_drag_context_get_dest_window(context) == gtk_widget_get_window(bm->widget)) return; +#else + if (context->dest_window == bm->widget->window) return; +#endif b = g_object_get_data(G_OBJECT(button), "bookbuttondata"); if (!b) return; list = g_list_append(list, b->path); - switch (info) + gchar **uris = uris_from_filelist(list); + gboolean ret = gtk_selection_data_set_uris(selection_data, uris); + if (!ret) { - case TARGET_URI_LIST: - uri_text = uri_text_from_list(list, &length, FALSE); - break; - case TARGET_TEXT_PLAIN: - uri_text = uri_text_from_list(list, &length, TRUE); - break; + char *str = g_strjoinv("\r\n", uris); + ret = gtk_selection_data_set_text(selection_data, str, -1); + g_free(str); } + g_strfreev(uris); g_list_free(list); - - if (!uri_text) return; - - gtk_selection_data_set_text(selection_data, uri_text, length); - g_free(uri_text); } static void bookmark_drag_begin(GtkWidget *button, GdkDragContext *context, gpointer data) @@ -686,16 +683,13 @@ static void bookmark_dnd_get_data(GtkWidget *widget, BookMarkData *bm = data; GList *list = NULL; GList *work; + gchar **uris; if (!bm->editable) return; - switch (info) - { - case TARGET_URI_LIST: - case TARGET_X_URL: - list = uri_list_from_text((gchar *)gtk_selection_data_get_data(selection_data), FALSE); - break; - } + uris = gtk_selection_data_get_uris(selection_data); + list = uri_filelist_from_uris(uris); + g_strfreev(uris); work = list; while (work) diff --git a/src/ui_pathsel.c b/src/ui_pathsel.c index 7593a214..60f9fd71 100644 --- a/src/ui_pathsel.c +++ b/src/ui_pathsel.c @@ -331,9 +331,7 @@ static void dest_dnd_set_data(GtkWidget *view, guint info, guint time, gpointer data) { gchar *path = NULL; - gchar *uri_text = NULL; GList *list = NULL; - gint length = 0; GtkTreeModel *model; GtkTreeSelection *selection; GtkTreeIter iter; @@ -346,22 +344,16 @@ static void dest_dnd_set_data(GtkWidget *view, list = g_list_append(list, path); - switch (info) + gchar **uris = uris_from_filelist(list); + gboolean ret = gtk_selection_data_set_uris(selection_data, uris); + if (!ret) { - case TARGET_URI_LIST: - uri_text = uri_text_from_list(list, &length, FALSE); - break; - case TARGET_TEXT_PLAIN: - uri_text = uri_text_from_list(list, &length, TRUE); - break; + char *str = g_strjoinv("\r\n", uris); + ret = gtk_selection_data_set_text(selection_data, str, -1); + g_free(str); } string_list_free(list); - - if (!uri_text) return; - - gtk_selection_data_set_text(selection_data, uri_text, length); - g_free(uri_text); } static void dest_dnd_init(Dest_Data *dd) diff --git a/src/uri_utils.c b/src/uri_utils.c index 7c1e107c..5b81223c 100644 --- a/src/uri_utils.c +++ b/src/uri_utils.c @@ -16,256 +16,87 @@ #include "filedata.h" #include "ui_fileops.h" -/* - *----------------------------------------------------------------------------- - * drag and drop uri utils - *----------------------------------------------------------------------------- - */ - -/* the following characters are allowed to be unencoded for pathnames: - * $ & + , / : = @ - */ -static gint escape_char_list[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 10 */ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 */ -/* spc ! " # $ % & ' */ - 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, /* 30 */ -/* ( ) * + , - . / 0 1 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40 */ -/* 2 3 4 5 6 7 8 9 : ; */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /* 50 */ -/* < = > ? @ A B C D E */ - 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, /* 60 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 */ -/* Z [ \ ] ^ _ ` a b c */ - 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, /* 90 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 100 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 110 */ -/* x y z { | } ~ del */ - 0, 0, 0, 1, 1, 1, 0, 0 /* 120, 127 is end */ -}; - -static gchar *hex_char = "0123456789ABCDEF"; - -static gboolean escape_test(guchar c) -{ - if (c < 32 || c > 127) return TRUE; - return (escape_char_list[c] != 0); -} - -static const gchar *escape_code(guchar c) +gchar **uris_from_pathlist(GList *list) { - static gchar text[4]; - - text[0] = '%'; - text[1] = hex_char[c>>4]; - text[2] = hex_char[c%16]; - text[3] = '\0'; - - return text; -} - -gchar *uri_text_escape(const gchar *text) -{ - GString *string; - gchar *result; - const gchar *p; - - if (!text) return NULL; - - string = g_string_new(""); - - p = text; - while (*p != '\0') - { - if (escape_test(*p)) - { - g_string_append(string, escape_code(*p)); - } - else - { - g_string_append_c(string, *p); - } - p++; - } - - result = string->str; - g_string_free(string, FALSE); + GList *work; + guint i = 0; + guint num = g_list_length(list); + gchar **uris = g_new0(gchar *, num + 1); - /* dropped filenames are expected to be utf-8 compatible */ - if (!g_utf8_validate(result, -1, NULL)) + work = list; + while (work) { - gchar *tmp; - - tmp = g_locale_to_utf8(result, -1, NULL, NULL, NULL); - if (tmp) - { - g_free(result); - result = tmp; - } + const gchar *path = work->data; + gchar *local_path = path_from_utf8(path); + uris[i] = g_filename_to_uri(local_path, NULL, NULL); + g_free(local_path); + + i++; + work = work->next; } - return result; + uris[i] = NULL; + return uris; } -/* this operates on the passed string, decoding escaped characters */ -void uri_text_decode(gchar *text) +gchar **uris_from_filelist(GList *list) { - if (strchr(text, '%')) - { - gchar *w; - gchar *r; - - w = r = text; - - while (*r != '\0') - { - if (*r == '%' && *(r + 1) != '\0' && *(r + 2) != '\0') - { - gchar t[3]; - gint n; - - r++; - t[0] = *r; - r++; - t[1] = *r; - t[2] = '\0'; - n = (gint)strtol(t, NULL, 16); - if (n > 0 && n < 256) - { - *w = (gchar)n; - } - else - { - /* invalid number, rewind and ignore this escape */ - r -= 2; - *w = *r; - } - } - else if (w != r) - { - *w = *r; - } - r++; - w++; - } - if (*w != '\0') *w = '\0'; - } + GList *path_list = filelist_to_path_list(list); + gchar **ret = uris_from_pathlist(path_list); + string_list_free(path_list); + return ret; } -static void uri_list_parse_encoded_chars(GList *list) +gboolean uri_selection_data_set_uris_from_filelist(GtkSelectionData *selection_data, GList *list) { - GList *work = list; - - while (work) + gchar **uris = uris_from_filelist(list); + gboolean ret = gtk_selection_data_set_uris(selection_data, uris); + if (!ret) { - gchar *text = work->data; - - uri_text_decode(text); - - work = work->next; + char *str = g_strjoinv("\r\n", uris); + ret = gtk_selection_data_set_text(selection_data, str, -1); + g_free(str); } + + g_strfreev(uris); + return ret; } -GList *uri_list_from_text(gchar *data, gboolean files_only) +GList *uri_pathlist_from_uris(gchar **uris) { GList *list = NULL; - gint b, e; - - b = e = 0; + guint i = 0; - while (data[b] != '\0') + while (uris[i]) { - while (data[e] != '\r' && data[e] != '\n' && data[e] != '\0') e++; - if (strncmp(data + b, "file:", 5) == 0) - { - gchar *path; - b += 5; - while (data[b] == '/' && data[b+1] == '/') b++; - path = g_strndup(data + b, e - b); - list = g_list_append(list, path_to_utf8(path)); - g_free(path); - } - else if (!files_only && strncmp(data + b, "http:", 5) == 0) - { - list = g_list_append(list, g_strndup(data + b, e - b)); - } - else if (!files_only && strncmp(data + b, "ftp:", 3) == 0) - { - list = g_list_append(list, g_strndup(data + b, e - b)); - } - while (data[e] == '\r' || data[e] == '\n') e++; - b = e; + gchar *local_path = g_filename_from_uri(uris[i], NULL, NULL); + gchar *path = path_to_utf8(local_path); + g_free(local_path); + list = g_list_prepend(list, path); + i++; } - uri_list_parse_encoded_chars(list); - - return list; + return g_list_reverse(list); } -GList *uri_filelist_from_text(gchar *data, gboolean files_only) + + +GList *uri_filelist_from_uris(gchar **uris) { - GList *path_list = uri_list_from_text(data, files_only); + GList *path_list = uri_pathlist_from_uris(uris); GList *filelist = filelist_from_path_list(path_list); string_list_free(path_list); return filelist; } -gchar *uri_text_from_list(GList *list, gint *len, gboolean plain_text) +GList *uri_filelist_from_gtk_selection_data(GtkSelectionData *selection_data) { - gchar *uri_text = NULL; - GString *string; - GList *work; - - if (!list) - { - if (len) *len = 0; - return NULL; - } - - string = g_string_new(""); - - work = list; - while (work) - { - const gchar *name8; /* dnd filenames are in utf-8 */ - - name8 = work->data; - - if (!plain_text) - { - gchar *escaped; - - escaped = uri_text_escape(name8); - g_string_append(string, "file:"); - g_string_append(string, escaped); - g_free(escaped); - - g_string_append(string, "\r\n"); - } - else - { - g_string_append(string, name8); - if (work->next) g_string_append(string, "\n"); - } - - work = work->next; - } + gchar **uris = gtk_selection_data_get_uris(selection_data); + GList *ret = uri_filelist_from_uris(uris); + g_strfreev(uris); + return ret; +} - uri_text = string->str; - if (len) *len = string->len; - g_string_free(string, FALSE); - return uri_text; -} -gchar *uri_text_from_filelist(GList *list, gint *len, gboolean plain_text) -{ - GList *path_list = filelist_to_path_list(list); - gchar *ret = uri_text_from_list(path_list, len, plain_text); - string_list_free(path_list); - return ret; -} /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ diff --git a/src/uri_utils.h b/src/uri_utils.h index 5473479a..5c3139a5 100644 --- a/src/uri_utils.h +++ b/src/uri_utils.h @@ -12,15 +12,12 @@ #ifndef URI_UTILS_H #define URI_UTILS_H -/* dnd data parsers (uris) */ - -gchar *uri_text_escape(const gchar *text); -void uri_text_decode(gchar *text); - -GList *uri_list_from_text(gchar *data, gboolean files_only); -GList *uri_filelist_from_text(gchar *data, gboolean files_only); -gchar *uri_text_from_list(GList *list, gint *len, gboolean plain_text); -gchar *uri_text_from_filelist(GList *list, gint *len, gboolean plain_text); +GList *uri_filelist_from_uris(gchar **uris); +gchar **uris_from_pathlist(GList *list); +gchar **uris_from_filelist(GList *list); +GList *uri_pathlist_from_uris(gchar **uris); +gboolean uri_selection_data_set_uris_from_filelist(GtkSelectionData *selection_data, GList *list); +GList *uri_filelist_from_gtk_selection_data(GtkSelectionData *selection_data); #endif /* URI_UTILS_H */ /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ diff --git a/src/view_dir.c b/src/view_dir.c index b11142ee..53e49812 100644 --- a/src/view_dir.c +++ b/src/view_dir.c @@ -728,8 +728,6 @@ static void vd_dnd_get(GtkWidget *widget, GdkDragContext *context, { ViewDir *vd = data; GList *list; - gchar *uritext = NULL; - gint length = 0; if (!vd->click_fd) return; @@ -738,15 +736,10 @@ static void vd_dnd_get(GtkWidget *widget, GdkDragContext *context, case TARGET_URI_LIST: case TARGET_TEXT_PLAIN: list = g_list_prepend(NULL, vd->click_fd); - uritext = uri_text_from_filelist(list, &length, (info == TARGET_TEXT_PLAIN)); + uri_selection_data_set_uris_from_filelist(selection_data, list); g_list_free(list); break; } - if (uritext) - { - gtk_selection_data_set_text(selection_data, uritext, length); - g_free(uritext); - } } static void vd_dnd_begin(GtkWidget *widget, GdkDragContext *context, gpointer data) @@ -796,7 +789,7 @@ static void vd_dnd_drop_receive(GtkWidget *widget, gint active; gboolean done = FALSE; - list = uri_filelist_from_text((gchar *)gtk_selection_data_get_data(selection_data), TRUE); + list = uri_filelist_from_gtk_selection_data(selection_data); if (!list) return; active = access_file(fd->path, W_OK | X_OK); diff --git a/src/view_file_icon.c b/src/view_file_icon.c index 0fc2307e..acf07d44 100644 --- a/src/view_file_icon.c +++ b/src/view_file_icon.c @@ -557,13 +557,8 @@ static void vficon_dnd_get(GtkWidget *widget, GdkDragContext *context, } if (!list) return; - uri_text = uri_text_from_filelist(list, &total, (info == TARGET_TEXT_PLAIN)); + uri_selection_data_set_uris_from_filelist(selection_data, list); filelist_free(list); - - DEBUG_1("%s", uri_text); - - gtk_selection_data_set_text(selection_data, uri_text, total); - g_free(uri_text); } static void vficon_drag_data_received(GtkWidget *entry_widget, GdkDragContext *context, diff --git a/src/view_file_list.c b/src/view_file_list.c index 8fa36c40..60742a0a 100644 --- a/src/view_file_list.c +++ b/src/view_file_list.c @@ -268,14 +268,8 @@ static void vflist_dnd_get(GtkWidget *widget, GdkDragContext *context, } if (!list) return; - - uri_text = uri_text_from_filelist(list, &total, (info == TARGET_TEXT_PLAIN)); + uri_selection_data_set_uris_from_filelist(selection_data, list); filelist_free(list); - - DEBUG_1("%s", uri_text); - - gtk_selection_data_set_text(selection_data, uri_text, total); - g_free(uri_text); } static void vflist_dnd_begin(GtkWidget *widget, GdkDragContext *context, gpointer data) -- 2.20.1