Deduplicate ViewFile dnd
authorArkadiy Illarionov <qarkai@gmail.com>
Sun, 21 Apr 2024 12:14:03 +0000 (15:14 +0300)
committerColin Clark <colin.clark@cclark.uk>
Sun, 21 Apr 2024 13:34:17 +0000 (14:34 +0100)
src/view-file/view-file-icon.cc
src/view-file/view-file-icon.h
src/view-file/view-file-list.cc
src/view-file/view-file-list.h
src/view-file/view-file.cc

index 3582f44..7a43146 100644 (file)
 #include "intl.h"
 #include "layout-image.h"
 #include "main-defines.h"
-#include "metadata.h"
 #include "misc.h"
 #include "options.h"
 #include "ui-fileops.h"
 #include "ui-menu.h"
 #include "ui-misc.h"
 #include "ui-tree-edit.h"
-#include "uri-utils.h"
 #include "utilops.h"
 #include "view-file.h"
 
@@ -278,7 +276,7 @@ static FileData *vficon_find_data(ViewFile *vf, gint row, gint col, GtkTreeIter
        return nullptr;
 }
 
-static FileData *vficon_find_data_by_coord(ViewFile *vf, gint x, gint y, GtkTreeIter *iter)
+FileData *vficon_find_data_by_coord(ViewFile *vf, gint x, gint y, GtkTreeIter *iter)
 {
        GtkTreePath *tpath;
        GtkTreeViewColumn *column;
@@ -476,54 +474,8 @@ static void tip_update(ViewFile *vf, FileData *fd)
  *-------------------------------------------------------------------
  */
 
-static void vficon_dnd_get(GtkWidget *, GdkDragContext *,
-                          GtkSelectionData *selection_data, guint,
-                          guint, gpointer data)
+void vficon_dnd_begin(ViewFile *vf, GtkWidget *widget, GdkDragContext *context)
 {
-       auto vf = static_cast<ViewFile *>(data);
-       GList *list = nullptr;
-
-       if (!vf->click_fd) return;
-
-       if (vf->click_fd->selected & SELECTION_SELECTED)
-               {
-               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 vficon_drag_data_received(GtkWidget *, GdkDragContext *,
-                                     int x, int y, GtkSelectionData *selection,
-                                     guint info, guint, gpointer data)
-{
-       auto vf = static_cast<ViewFile *>(data);
-
-       if (info == TARGET_TEXT_PLAIN) {
-               FileData *fd = vficon_find_data_by_coord(vf, x, y, nullptr);
-
-               if (fd) {
-                       /* Add keywords to file */
-                       auto str = reinterpret_cast<gchar *>(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 vficon_dnd_begin(GtkWidget *widget, GdkDragContext *context, gpointer data)
-{
-       auto vf = static_cast<ViewFile *>(data);
-
        tip_unschedule(vf);
 
        if (vf->click_fd && vf->click_fd->thumb_pixbuf)
@@ -539,10 +491,8 @@ static void vficon_dnd_begin(GtkWidget *widget, GdkDragContext *context, gpointe
                }
 }
 
-static void vficon_dnd_end(GtkWidget *, GdkDragContext *context, gpointer data)
+void vficon_dnd_end(ViewFile *vf, GdkDragContext *context)
 {
-       auto vf = static_cast<ViewFile *>(data);
-
        vficon_selection_remove(vf, vf->click_fd, SELECTION_PRELIGHT, nullptr);
 
        if (gdk_drag_context_get_selected_action(context) == GDK_ACTION_MOVE)
@@ -553,25 +503,6 @@ static void vficon_dnd_end(GtkWidget *, GdkDragContext *context, gpointer data)
        tip_unschedule(vf);
 }
 
-void vficon_dnd_init(ViewFile *vf)
-{
-       gtk_drag_source_set(vf->listview, static_cast<GdkModifierType>(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK),
-                           dnd_file_drag_types, dnd_file_drag_types_count,
-                           static_cast<GdkDragAction>(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<GdkDragAction>(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);
-}
-
 /*
  *-------------------------------------------------------------------
  * cell updates
@@ -823,10 +754,15 @@ gboolean vficon_index_is_selected_unused(ViewFile *vf, gint row)
 
        if (!fd) return FALSE;
 
-       return (fd->selected & SELECTION_SELECTED);
+       return vficon_is_selected(vf, fd);
 }
 #pragma GCC diagnostic pop
 
+gboolean vficon_is_selected(ViewFile *, FileData *fd)
+{
+       return (fd->selected & SELECTION_SELECTED);
+}
+
 guint vficon_selection_count(ViewFile *vf, gint64 *bytes)
 {
        if (bytes)
index 8822823..b9ff01f 100644 (file)
@@ -57,7 +57,10 @@ gboolean vficon_press_key_cb(ViewFile *vf, GtkWidget *widget, GdkEventKey *event
 gboolean vficon_press_cb(ViewFile *vf, GtkWidget *widget, GdkEventButton *bevent);
 gboolean vficon_release_cb(ViewFile *vf, GtkWidget *widget, GdkEventButton *bevent);
 
-void vficon_dnd_init(ViewFile *vf);
+FileData *vficon_find_data_by_coord(ViewFile *vf, gint x, gint y, GtkTreeIter *iter);
+
+void vficon_dnd_begin(ViewFile *vf, GtkWidget *widget, GdkDragContext *context);
+void vficon_dnd_end(ViewFile *vf, GdkDragContext *context);
 
 void vficon_destroy_cb(ViewFile *vf);
 ViewFile *vficon_new(ViewFile *vf);
@@ -81,6 +84,7 @@ void vficon_popup_destroy_cb(ViewFile *vf);
 
 gint vficon_index_by_fd(const ViewFile *vf, const FileData *fd);
 
+gboolean vficon_is_selected(ViewFile *vf, FileData *fd);
 guint vficon_selection_count(ViewFile *vf, gint64 *bytes);
 GList *vficon_selection_get_list(ViewFile *vf);
 GList *vficon_selection_get_list_by_index(ViewFile *vf);
index f1c0281..a8c19a3 100644 (file)
@@ -43,7 +43,6 @@
 #include "ui-menu.h"
 #include "ui-misc.h"
 #include "ui-tree-edit.h"
-#include "uri-utils.h"
 #include "utilops.h"
 #include "view-file.h"
 
@@ -132,7 +131,7 @@ static gint vflist_find_row(const ViewFile *vf, const FileData *fd, GtkTreeIter
        return -1;
 }
 
-static FileData *vflist_find_data_by_coord(ViewFile *vf, gint x, gint y, GtkTreeIter *)
+FileData *vflist_find_data_by_coord(ViewFile *vf, gint x, gint y, GtkTreeIter *)
 {
        GtkTreePath *tpath;
        GtkTreeViewColumn *column;
@@ -221,33 +220,8 @@ static void vflist_move_cursor(ViewFile *vf, GtkTreeIter *iter)
  *-----------------------------------------------------------------------------
  */
 
-static void vflist_dnd_get(GtkWidget *, GdkDragContext *,
-                          GtkSelectionData *selection_data, guint,
-                          guint, gpointer data)
+void vflist_dnd_begin(ViewFile *vf, GtkWidget *widget, GdkDragContext *context)
 {
-       auto vf = static_cast<ViewFile *>(data);
-       GList *list = nullptr;
-
-       if (!vf->click_fd) return;
-
-       if (vflist_row_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 vflist_dnd_begin(GtkWidget *widget, GdkDragContext *context, gpointer data)
-{
-       auto vf = static_cast<ViewFile *>(data);
-
        vflist_color_set(vf, vf->click_fd, TRUE);
 
        if (VFLIST(vf)->thumbs_enabled &&
@@ -264,10 +238,8 @@ static void vflist_dnd_begin(GtkWidget *widget, GdkDragContext *context, gpointe
                }
 }
 
-static void vflist_dnd_end(GtkWidget *, GdkDragContext *context, gpointer data)
+void vflist_dnd_end(ViewFile *vf, GdkDragContext *context)
 {
-       auto vf = static_cast<ViewFile *>(data);
-
        vflist_color_set(vf, vf->click_fd, FALSE);
 
        if (gdk_drag_context_get_selected_action(context) == GDK_ACTION_MOVE)
@@ -276,46 +248,6 @@ static void vflist_dnd_end(GtkWidget *, GdkDragContext *context, gpointer data)
                }
 }
 
-static void vflist_drag_data_received(GtkWidget *, GdkDragContext *,
-                                     int x, int y, GtkSelectionData *selection,
-                                     guint info, guint, gpointer data)
-{
-       auto vf = static_cast<ViewFile *>(data);
-
-       if (info == TARGET_TEXT_PLAIN) {
-               FileData *fd = vflist_find_data_by_coord(vf, x, y, nullptr);
-
-               if (fd) {
-                       /* Add keywords to file */
-                       auto str = reinterpret_cast<gchar *>(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);
-               }
-       }
-}
-
-void vflist_dnd_init(ViewFile *vf)
-{
-       gtk_drag_source_set(vf->listview, static_cast<GdkModifierType>(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK),
-                           dnd_file_drag_types, dnd_file_drag_types_count,
-                           static_cast<GdkDragAction>(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<GdkDragAction>(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);
-}
-
 /*
  *-----------------------------------------------------------------------------
  * pop-up menu
@@ -1414,6 +1346,11 @@ gboolean vflist_index_is_selected_unused(ViewFile *vf, gint row)
 }
 #pragma GCC diagnostic pop
 
+gboolean vflist_is_selected(ViewFile *vf, FileData *fd)
+{
+       return vflist_row_is_selected(vf, fd);
+}
+
 guint vflist_selection_count(ViewFile *vf, gint64 *bytes)
 {
        GtkTreeModel *store;
index d726f07..0b63d77 100644 (file)
@@ -46,7 +46,10 @@ gboolean vflist_press_key_cb(ViewFile *vf, GtkWidget *widget, GdkEventKey *event
 gboolean vflist_press_cb(ViewFile *vf, GtkWidget *widget, GdkEventButton *bevent);
 gboolean vflist_release_cb(ViewFile *vf, GtkWidget *widget, GdkEventButton *bevent);
 
-void vflist_dnd_init(ViewFile *vf);
+FileData *vflist_find_data_by_coord(ViewFile *vf, gint x, gint y, GtkTreeIter *iter);
+
+void vflist_dnd_begin(ViewFile *vf, GtkWidget *widget, GdkDragContext *context);
+void vflist_dnd_end(ViewFile *vf, GdkDragContext *context);
 
 void vflist_destroy_cb(ViewFile *vf);
 ViewFile *vflist_new(ViewFile *vf);
@@ -70,6 +73,7 @@ void vflist_popup_destroy_cb(ViewFile *vf);
 
 gint vflist_index_by_fd(const ViewFile *vf, const FileData *fd);
 
+gboolean vflist_is_selected(ViewFile *vf, FileData *fd);
 guint vflist_selection_count(ViewFile *vf, gint64 *bytes);
 GList *vflist_selection_get_list(ViewFile *vf);
 GList *vflist_selection_get_list_by_index(ViewFile *vf);
index 7be8736..68c6e52 100644 (file)
@@ -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<ViewFile *>(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<ViewFile *>(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<ViewFile *>(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<ViewFile *>(data);
+
+       FileData *fd = vf_find_data_by_coord(vf, x, y, nullptr);
+       if (!fd) return;
+
+       /* Add keywords to file */
+       auto str = reinterpret_cast<gchar *>(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<GdkModifierType>(GDK_BUTTON1_MASK | GDK_BUTTON2_MASK),
+                           dnd_file_drag_types, dnd_file_drag_types_count,
+                           static_cast<GdkDragAction>(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<GdkDragAction>(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