X-Git-Url: http://geeqie.org/cgi-bin/gitweb.cgi?p=geeqie.git;a=blobdiff_plain;f=src%2Fview-file%2Fview-file.cc;fp=src%2Fview-file%2Fview-file.cc;h=68c6e52cca9d98584c043f2e98e503a7cdc8b10a;hp=7be8736488e77342ca9df73c392132afb1c03dca;hb=3000a47a8792e0a3cae6b4c166cb14be8a7697b1;hpb=831dd3383c7b7be041b03b614f0ad04b763c4728 diff --git a/src/view-file/view-file.cc b/src/view-file/view-file.cc index 7be87364..68c6e52c 100644 --- a/src/view-file/view-file.cc +++ b/src/view-file/view-file.cc @@ -26,6 +26,7 @@ #include "archives.h" #include "compat.h" #include "debug.h" +#include "dnd.h" #include "dupe.h" #include "filedata.h" #include "history-list.h" @@ -34,6 +35,7 @@ #include "main-defines.h" #include "main.h" #include "menu.h" +#include "metadata.h" #include "misc.h" #include "options.h" #include "thumb.h" @@ -41,6 +43,7 @@ #include "ui-menu.h" #include "ui-misc.h" #include "ui-utildlg.h" +#include "uri-utils.h" #include "utilops.h" #include "view-file/view-file-icon.h" #include "view-file/view-file-list.h" @@ -310,16 +313,115 @@ void vf_selection_to_mark(ViewFile *vf, gint mark, SelectionToMarkMode mode) *----------------------------------------------------------------------------- */ +static gboolean vf_is_selected(ViewFile *vf, FileData *fd) +{ + switch (vf->type) + { + case FILEVIEW_LIST: return vflist_is_selected(vf, fd); + case FILEVIEW_ICON: return vficon_is_selected(vf, fd); + } -static void vf_dnd_init(ViewFile *vf) + return FALSE; +} + +static void vf_dnd_get(GtkWidget *, GdkDragContext *, + GtkSelectionData *selection_data, guint, + guint, gpointer data) { + auto *vf = static_cast(data); + + if (!vf->click_fd) return; + + GList *list = nullptr; + + if (vf_is_selected(vf, vf->click_fd)) + { + list = vf_selection_get_list(vf); + } + else + { + list = g_list_append(nullptr, file_data_ref(vf->click_fd)); + } + + if (!list) return; + + uri_selection_data_set_uris_from_filelist(selection_data, list); + filelist_free(list); +} + +static void vf_dnd_begin(GtkWidget *widget, GdkDragContext *context, gpointer data) +{ + auto *vf = static_cast(data); + switch (vf->type) { - case FILEVIEW_LIST: vflist_dnd_init(vf); break; - case FILEVIEW_ICON: vficon_dnd_init(vf); break; + case FILEVIEW_LIST: vflist_dnd_begin(vf, widget, context); break; + case FILEVIEW_ICON: vficon_dnd_begin(vf, widget, context); break; } } +static void vf_dnd_end(GtkWidget *, GdkDragContext *context, gpointer data) +{ + auto *vf = static_cast(data); + + switch (vf->type) + { + case FILEVIEW_LIST: vflist_dnd_end(vf, context); break; + case FILEVIEW_ICON: vficon_dnd_end(vf, context); break; + } +} + +static FileData *vf_find_data_by_coord(ViewFile *vf, gint x, gint y, GtkTreeIter *iter) +{ + switch (vf->type) + { + case FILEVIEW_LIST: return vflist_find_data_by_coord(vf, x, y, iter); + case FILEVIEW_ICON: return vficon_find_data_by_coord(vf, x, y, iter); + } + + return nullptr; +} + +static void vf_drag_data_received(GtkWidget *, GdkDragContext *, + int x, int y, GtkSelectionData *selection, + guint info, guint, gpointer data) +{ + if (info != TARGET_TEXT_PLAIN) return; + + auto *vf = static_cast(data); + + FileData *fd = vf_find_data_by_coord(vf, x, y, nullptr); + if (!fd) return; + + /* Add keywords to file */ + auto str = reinterpret_cast(gtk_selection_data_get_text(selection)); + GList *kw_list = string_to_keywords_list(str); + + metadata_append_list(fd, KEYWORD_KEY, kw_list); + + g_list_free_full(kw_list, g_free); + g_free(str); +} + +static void vf_dnd_init(ViewFile *vf) +{ + gtk_drag_source_set(vf->listview, static_cast(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK), + dnd_file_drag_types, dnd_file_drag_types_count, + static_cast(GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK)); + gtk_drag_dest_set(vf->listview, GTK_DEST_DEFAULT_ALL, + dnd_file_drag_types, dnd_file_drag_types_count, + static_cast(GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK)); + + g_signal_connect(G_OBJECT(vf->listview), "drag_data_get", + G_CALLBACK(vf_dnd_get), vf); + g_signal_connect(G_OBJECT(vf->listview), "drag_begin", + G_CALLBACK(vf_dnd_begin), vf); + g_signal_connect(G_OBJECT(vf->listview), "drag_end", + G_CALLBACK(vf_dnd_end), vf); + g_signal_connect(G_OBJECT(vf->listview), "drag_data_received", + G_CALLBACK(vf_drag_data_received), vf); +} + /* *----------------------------------------------------------------------------- * pop-up menu