# HG changeset patch # User zas_ # Date 1229364282 0 # Node ID 8bf3fff49dddac1a8f542ad81c3f8460511e8302 # Parent c55a935b5e362e7cc0c1c97355a6c8d0c5e4f9f1 Allow to drag keywords on files in list or icon view. Dragged text is appended to keywords list of the destination file. diff -r c55a935b5e36 -r 8bf3fff49ddd src/dnd.c --- a/src/dnd.c Tue Dec 09 19:12:38 2008 +0000 +++ b/src/dnd.c Mon Dec 15 18:04:42 2008 +0000 @@ -27,9 +27,10 @@ GtkTargetEntry dnd_file_drop_types[] = { { TARGET_APP_COLLECTION_MEMBER_STRING, 0, TARGET_APP_COLLECTION_MEMBER }, - { "text/uri-list", 0, TARGET_URI_LIST } + { "text/uri-list", 0, TARGET_URI_LIST }, + { "text/plain", 0, TARGET_TEXT_PLAIN }, }; -gint dnd_file_drop_types_count = 2; +gint dnd_file_drop_types_count = 3; #define DND_ICON_SIZE (options->dnd_icon_size) diff -r c55a935b5e36 -r 8bf3fff49ddd src/view_file_icon.c --- a/src/view_file_icon.c Tue Dec 09 19:12:38 2008 +0000 +++ b/src/view_file_icon.c Mon Dec 15 18:04:42 2008 +0000 @@ -13,6 +13,7 @@ #include "main.h" #include "view_file_icon.h" +#include "bar_info.h" #include "cellrenderericon.h" #include "collect.h" #include "collect-io.h" @@ -25,6 +26,7 @@ #include "layout.h" #include "layout_image.h" #include "menu.h" +#include "metadata.h" #include "thumb.h" #include "utilops.h" #include "ui_fileops.h" @@ -551,6 +553,31 @@ g_free(uri_text); } +static void vficon_drag_data_received(GtkWidget *entry_widget, GdkDragContext *context, + int x, int y, GtkSelectionData *selection, + guint info, guint time, gpointer data) +{ + ViewFile *vf = data; + + if (info == TARGET_TEXT_PLAIN) { + IconData *id = vficon_find_data_by_coord(vf, x, y, NULL); + + if (id && id->fd) { + /* Add keywords to file */ + FileData *fd = id->fd; + gchar *str = g_strndup(selection->data, selection->length); + GList *kw_list = string_to_keywords_list(str); + + metadata_set(fd, kw_list, NULL, TRUE); + string_list_free(kw_list); + g_free(str); + if (vf->layout && vf->layout->bar_info) { + bar_info_set(vf->layout->bar_info, id->fd); + } + } + } +} + static void vficon_dnd_begin(GtkWidget *widget, GdkDragContext *context, gpointer data) { ViewFile *vf = data; @@ -589,12 +616,18 @@ gtk_drag_source_set(vf->listview, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, dnd_file_drag_types, dnd_file_drag_types_count, 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, + GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK); + g_signal_connect(G_OBJECT(vf->listview), "drag_data_get", G_CALLBACK(vficon_dnd_get), vf); g_signal_connect(G_OBJECT(vf->listview), "drag_begin", G_CALLBACK(vficon_dnd_begin), vf); g_signal_connect(G_OBJECT(vf->listview), "drag_end", G_CALLBACK(vficon_dnd_end), vf); + g_signal_connect(G_OBJECT(vf->listview), "drag_data_received", + G_CALLBACK(vficon_drag_data_received), vf); } /* diff -r c55a935b5e36 -r 8bf3fff49ddd src/view_file_list.c --- a/src/view_file_list.c Tue Dec 09 19:12:38 2008 +0000 +++ b/src/view_file_list.c Mon Dec 15 18:04:42 2008 +0000 @@ -13,6 +13,7 @@ #include "main.h" #include "view_file_list.h" +#include "bar_info.h" #include "cache_maint.h" #include "dnd.h" #include "editors.h" @@ -21,6 +22,7 @@ #include "layout.h" #include "layout_image.h" #include "menu.h" +#include "metadata.h" #include "thumb.h" #include "utilops.h" #include "ui_fileops.h" @@ -109,6 +111,28 @@ return -1; } +static FileData *vflist_find_data_by_coord(ViewFile *vf, gint x, gint y, GtkTreeIter *iter) +{ + GtkTreePath *tpath; + GtkTreeViewColumn *column; + + if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(vf->listview), x, y, + &tpath, &column, NULL, NULL)) + { + GtkTreeModel *store; + GtkTreeIter row; + FileData *fd; + + store = gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview)); + gtk_tree_model_get_iter(store, &row, tpath); + gtk_tree_path_free(tpath); + gtk_tree_model_get(store, &row, FILE_COLUMN_POINTER, &fd, -1); + + return fd; + } + + return NULL; +} #if 0 static gint vflist_find_sidecar_list_idx(GList *work, FileData *fd) @@ -285,17 +309,47 @@ } } +static void vflist_drag_data_received(GtkWidget *entry_widget, GdkDragContext *context, + int x, int y, GtkSelectionData *selection, + guint info, guint time, gpointer data) +{ + ViewFile *vf = data; + + if (info == TARGET_TEXT_PLAIN) { + FileData *fd = vflist_find_data_by_coord(vf, x, y, NULL); + + if (fd) { + /* Add keywords to file */ + gchar *str = g_strndup(selection->data, selection->length); + GList *kw_list = string_to_keywords_list(str); + + metadata_set(fd, kw_list, NULL, TRUE); + string_list_free(kw_list); + g_free(str); + if (vf->layout && vf->layout->bar_info) { + bar_info_set(vf->layout->bar_info, fd); + } + } + } +} + void vflist_dnd_init(ViewFile *vf) { gtk_drag_source_set(vf->listview, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, dnd_file_drag_types, dnd_file_drag_types_count, 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, + GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK); + g_signal_connect(G_OBJECT(vf->listview), "drag_data_get", G_CALLBACK(vflist_dnd_get), vf); g_signal_connect(G_OBJECT(vf->listview), "drag_begin", G_CALLBACK(vflist_dnd_begin), vf); g_signal_connect(G_OBJECT(vf->listview), "drag_end", G_CALLBACK(vflist_dnd_end), vf); + g_signal_connect(G_OBJECT(vf->listview), "drag_data_received", + G_CALLBACK(vflist_drag_data_received), vf); } /*