Allow to drag keywords on files in list or icon view. Dragged text is appended to...
authorLaurent Monin <geeqie@norz.org>
Mon, 15 Dec 2008 18:04:42 +0000 (18:04 +0000)
committerLaurent Monin <geeqie@norz.org>
Mon, 15 Dec 2008 18:04:42 +0000 (18:04 +0000)
src/dnd.c
src/view_file_icon.c
src/view_file_list.c

index 7c609d0..2294851 100644 (file)
--- a/src/dnd.c
+++ b/src/dnd.c
@@ -27,9 +27,10 @@ gint dnd_file_drag_types_count = 2;
 
 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)
index 3ac6d3b..e0fe6f3 100644 (file)
@@ -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 @@ static void vficon_dnd_get(GtkWidget *widget, GdkDragContext *context,
        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 @@ void vficon_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(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);
 }
 
 /*
index 1b9171c..2f313f4 100644 (file)
@@ -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 @@ static gint vflist_find_row(ViewFile *vf, FileData *fd, GtkTreeIter *iter)
        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_dnd_end(GtkWidget *widget, GdkDragContext *context, gpointer
                }
 }
 
+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);
 }
 
 /*