Fix 1302: Cut image to clipboard
authorColin Clark <colin.clark@cclark.uk>
Fri, 29 Mar 2024 13:24:11 +0000 (13:24 +0000)
committerColin Clark <colin.clark@cclark.uk>
Fri, 29 Mar 2024 13:24:11 +0000 (13:24 +0000)
https://github.com/BestImageViewer/geeqie/issues/1302

Shortcut key Control-X and menu item Cut To Clipboard function as in
other programs.

This feature is only available in the main window.

16 files changed:
doc/docbook/GuideMainWindowImagePane.xml
doc/docbook/GuideMainWindowMenus.xml
doc/docbook/GuideReferenceMainWindowShortcuts.xml
src/collect-table.cc
src/dupe.cc
src/img-view.cc
src/layout-image.cc
src/layout-util.cc
src/pan-view/pan-view.cc
src/search.cc
src/ui/menu-classic.ui
src/ui/menu-hamburger.ui
src/utilops.cc
src/utilops.h
src/view-dir.cc
src/view-file/view-file.cc

index 6ad4077..f6e6f4f 100644 (file)
           <para>Controls the pause state of an active slide show, the text of the menu will change to reflect the action that will be performed.</para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term>Copy image to clipboard</term>
+        <listitem>
+          <para>Copy the pixbuf to the clipboard. This may be used by programs such as Gimp.</para>
+        </listitem>
+      </varlistentry>
     </variablelist>
     <para />
   </section>
index 5a7931e..1915714 100644 (file)
       <varlistentry>
         <term>
           <menuchoice>
-            <guimenu>Copy path</guimenu>
+            <guimenu>Copy to clipboard</guimenu>
           </menuchoice>
         </term>
         <listitem>
       <varlistentry>
         <term>
           <menuchoice>
-            <guimenu>Copy path unquoted</guimenu>
+            <guimenu>Copy to clipboard (unquoted)</guimenu>
           </menuchoice>
         </term>
         <listitem>
           <para>Copy selected item-path(s) to clipboard. The data will not be enclosed in quotes.</para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term>
+          <menuchoice>
+            <shortcut>
+              <keycombo>
+                <keycap>Ctrl</keycap>
+                <keycap>X</keycap>
+              </keycombo>
+            </shortcut>
+            <guimenu>Cut to clipboard</guimenu>
+          </menuchoice>
+        </term>
+        <listitem>
+          <para>Perform a standard control-X operation.</para>
+        </listitem>
+      </varlistentry>
       <varlistentry>
         <term>
           <menuchoice>
index 949923b..9aba077 100644 (file)
@@ -36,6 +36,7 @@ keyboard shortcuts
 <row> <entry> <code> <keycap> Shift + KP_Subtract </keycap> </code> </entry> <entry> Connected Zoom out </entry> </row>
 <row> <entry> <code> <keycap> underscore </keycap> </code> </entry> <entry> Connected Zoom out </entry> </row>
 <row> <entry> <code> <keycap> Ctrl + C </keycap> </code> </entry> <entry> Copy </entry> </row>
+<row> <entry> <code> <keycap> Ctrl + X </keycap> </code> </entry> <entry> Cut to clipboard </entry> </row>
 <row> <entry> <code> <keycap> Delete </keycap> </code> </entry> <entry> Move to Trash </entry> </row>
 <row> <entry> <code> <keycap> KP_Delete </keycap> </code> </entry> <entry> Move to Trash </entry> </row>
 <row> <entry> <code> <keycap> Ctrl + D </keycap> </code> </entry> <entry> Move to Trash </entry> </row>
index 0d3016f..7f47ff7 100644 (file)
@@ -791,14 +791,14 @@ static void collection_table_popup_copy_path_cb(GtkWidget *, gpointer data)
 {
        auto ct = static_cast<CollectTable *>(data);
 
-       file_util_copy_path_list_to_clipboard(collection_table_popup_file_list(ct), TRUE);
+       file_util_path_list_to_clipboard(collection_table_popup_file_list(ct), TRUE, TRUE);
 }
 
 static void collection_table_popup_copy_path_unquoted_cb(GtkWidget *, gpointer data)
 {
        auto ct = static_cast<CollectTable *>(data);
 
-       file_util_copy_path_list_to_clipboard(collection_table_popup_file_list(ct), FALSE);
+       file_util_path_list_to_clipboard(collection_table_popup_file_list(ct), FALSE, TRUE);
 }
 
 static void collection_table_popup_sort_cb(GtkWidget *widget, gpointer data)
index dc86cb8..68e553f 100644 (file)
@@ -3419,14 +3419,14 @@ static void dupe_menu_copy_path_cb(GtkWidget *, gpointer data)
 {
        auto dw = static_cast<DupeWindow *>(data);
 
-       file_util_copy_path_list_to_clipboard(dupe_listview_get_selection(dw, dw->listview), TRUE);
+       file_util_path_list_to_clipboard(dupe_listview_get_selection(dw, dw->listview), TRUE, TRUE);
 }
 
 static void dupe_menu_copy_path_unquoted_cb(GtkWidget *, gpointer data)
 {
        auto dw = static_cast<DupeWindow *>(data);
 
-       file_util_copy_path_list_to_clipboard(dupe_listview_get_selection(dw, dw->listview), FALSE);
+       file_util_path_list_to_clipboard(dupe_listview_get_selection(dw, dw->listview), FALSE, TRUE);
 }
 
 static void dupe_menu_remove_cb(GtkWidget *, gpointer data)
index e9e15d8..f71e1b1 100644 (file)
@@ -1282,7 +1282,7 @@ static void view_copy_path_cb(GtkWidget *, gpointer data)
        ImageWindow *imd;
 
        imd = view_window_active_image(vw);
-       file_util_copy_path_to_clipboard(image_get_fd(imd), TRUE);
+       file_util_copy_path_to_clipboard(image_get_fd(imd), TRUE, TRUE);
 }
 
 static void view_copy_path_unquoted_cb(GtkWidget *, gpointer data)
@@ -1291,7 +1291,7 @@ static void view_copy_path_unquoted_cb(GtkWidget *, gpointer data)
        ImageWindow *imd;
 
        imd = view_window_active_image(vw);
-       file_util_copy_path_to_clipboard(image_get_fd(imd), FALSE);
+       file_util_copy_path_to_clipboard(image_get_fd(imd), FALSE, TRUE);
 }
 
 static void view_fullscreen_cb(GtkWidget *, gpointer data)
index 4745404..1bf3746 100644 (file)
@@ -598,14 +598,21 @@ static void li_pop_menu_copy_path_cb(GtkWidget *, gpointer data)
 {
        auto lw = static_cast<LayoutWindow *>(data);
 
-       file_util_copy_path_to_clipboard(layout_image_get_fd(lw), TRUE);
+       file_util_copy_path_to_clipboard(layout_image_get_fd(lw), TRUE, TRUE);
 }
 
 static void li_pop_menu_copy_path_unquoted_cb(GtkWidget *, gpointer data)
 {
        auto lw = static_cast<LayoutWindow *>(data);
 
-       file_util_copy_path_to_clipboard(layout_image_get_fd(lw), FALSE);
+       file_util_copy_path_to_clipboard(layout_image_get_fd(lw), FALSE, TRUE);
+}
+
+static void li_pop_menu_cut_path_cb(GtkWidget *, gpointer data)
+{
+       auto lw = static_cast<LayoutWindow *>(data);
+
+       file_util_copy_path_to_clipboard(layout_image_get_fd(lw), FALSE, FALSE);
 }
 
 #if HAVE_GTK4
@@ -845,9 +852,10 @@ static GtkWidget *layout_image_pop_menu(LayoutWindow *lw)
        if (!path) gtk_widget_set_sensitive(item, FALSE);
        item = menu_item_add(menu, _("_Rename..."), G_CALLBACK(li_pop_menu_rename_cb), lw);
        if (!path) gtk_widget_set_sensitive(item, FALSE);
-       item = menu_item_add(menu, _("_Copy path to clipboard"), G_CALLBACK(li_pop_menu_copy_path_cb), lw);
-       item = menu_item_add(menu, _("_Copy path unquoted to clipboard"), G_CALLBACK(li_pop_menu_copy_path_unquoted_cb), lw);
+       item = menu_item_add(menu, _("_Copy to clipboard"), G_CALLBACK(li_pop_menu_copy_path_cb), lw);
+       item = menu_item_add(menu, _("_Copy to clipboard (unquoted)"), G_CALLBACK(li_pop_menu_copy_path_unquoted_cb), lw);
        item = menu_item_add(menu, _("Copy _image to clipboard"), G_CALLBACK(li_pop_menu_copy_image_cb), lw);
+       item = menu_item_add(menu, _("Cut to clipboard"), G_CALLBACK(li_pop_menu_cut_path_cb), lw);
        if (!path) gtk_widget_set_sensitive(item, FALSE);
        menu_item_add_divider(menu);
 
index 2f743c6..8d24c5d 100644 (file)
@@ -347,14 +347,21 @@ static void layout_menu_copy_path_cb(GtkAction *, gpointer data)
 {
        auto lw = static_cast<LayoutWindow *>(data);
 
-       file_util_copy_path_list_to_clipboard(layout_selection_list(lw), TRUE);
+       file_util_path_list_to_clipboard(layout_selection_list(lw), TRUE, TRUE);
 }
 
 static void layout_menu_copy_path_unquoted_cb(GtkAction *, gpointer data)
 {
        auto lw = static_cast<LayoutWindow *>(data);
 
-       file_util_copy_path_list_to_clipboard(layout_selection_list(lw), FALSE);
+       file_util_path_list_to_clipboard(layout_selection_list(lw), FALSE, TRUE);
+}
+
+static void layout_menu_cut_path_cb(GtkAction *, gpointer data)
+{
+       auto lw = static_cast<LayoutWindow *>(data);
+
+       file_util_path_list_to_clipboard(layout_selection_list(lw), FALSE, FALSE);
 }
 
 static void layout_menu_move_cb(GtkAction *, gpointer data)
@@ -2657,8 +2664,9 @@ static GtkActionEntry menu_entries[] = {
   { "ConnectZoomOutAlt1",    GQ_ICON_ZOOM_OUT,                  N_("Zoom _out"),                                        "<shift>KP_Subtract",  N_("Connected Zoom out"),                              CB(layout_menu_connect_zoom_out_cb) },                 
   { "ConnectZoomOut",        GQ_ICON_ZOOM_OUT,                  N_("Zoom _out"),                                        "underscore",          N_("Connected Zoom out"),                              CB(layout_menu_connect_zoom_out_cb) },
   { "Copy",                  GQ_ICON_COPY,                      N_("_Copy..."),                                         "<control>C",          N_("Copy..."),                                         CB(layout_menu_copy_cb) },
-  { "CopyPath",              nullptr,                           N_("_Copy path to clipboard"),                          nullptr,               N_("Copy path to clipboard"),                          CB(layout_menu_copy_path_cb) },
-  { "CopyPathUnquoted",      nullptr,                           N_("_Copy path unquoted to clipboard"),                 nullptr,               N_("Copy path unquoted to clipboard"),                 CB(layout_menu_copy_path_unquoted_cb) },
+  { "CopyPath",              nullptr,                           N_("_Copy to clipboard"),                          nullptr,               N_("Copy to clipboard"),                          CB(layout_menu_copy_path_cb) },
+  { "CopyPathUnquoted",      nullptr,                           N_("_Copy to clipboard (unquoted)"),                 nullptr,               N_("Copy to clipboard (unquoted)"),                 CB(layout_menu_copy_path_unquoted_cb) },
+  { "CutPath",               nullptr,                           N_("_Cut to clipboard"),                           "<control>X",          N_("Cut to clipboard"),                           CB(layout_menu_cut_path_cb) },
   { "DeleteAlt1",            GQ_ICON_USER_TRASH,                N_("Move to Trash..."),                                 "Delete",              N_("Move to Trash..."),                                CB(layout_menu_move_to_trash_key_cb) },                
   { "DeleteAlt2",            GQ_ICON_USER_TRASH,                N_("Move to Trash..."),                                 "KP_Delete",           N_("Move to Trash..."),                                CB(layout_menu_move_to_trash_key_cb) },                
   { "Delete",                GQ_ICON_USER_TRASH,                N_("Move to Trash..."),                                 "<control>D",          N_("Move to Trash..."),                                CB(layout_menu_move_to_trash_cb) },
index 077c3e2..3d39828 100644 (file)
@@ -2262,7 +2262,7 @@ static void pan_copy_path_cb(GtkWidget *, gpointer data)
        FileData *fd;
 
        fd = pan_menu_click_fd(pw);
-       if (fd) file_util_copy_path_to_clipboard(fd, TRUE);
+       if (fd) file_util_copy_path_to_clipboard(fd, TRUE, TRUE);
 }
 
 static void pan_copy_path_unquoted_cb(GtkWidget *, gpointer data)
@@ -2271,7 +2271,7 @@ static void pan_copy_path_unquoted_cb(GtkWidget *, gpointer data)
        FileData *fd;
 
        fd = pan_menu_click_fd(pw);
-       if (fd) file_util_copy_path_to_clipboard(fd, FALSE);
+       if (fd) file_util_copy_path_to_clipboard(fd, FALSE, TRUE);
 }
 
 static void pan_exif_date_toggle_cb(GtkWidget *widget, gpointer data)
@@ -2406,9 +2406,9 @@ static GtkWidget *pan_popup_menu(PanWindow *pw)
                                G_CALLBACK(pan_move_cb), pw);
        menu_item_add_sensitive(menu, _("_Rename..."), active,
                                G_CALLBACK(pan_rename_cb), pw);
-       menu_item_add_sensitive(menu, _("_Copy path to clipboard"), active,
+       menu_item_add_sensitive(menu, _("_Copy to clipboard"), active,
                                G_CALLBACK(pan_copy_path_cb), pw);
-       menu_item_add_sensitive(menu, _("_Copy path unquoted to clipboard"), active,
+       menu_item_add_sensitive(menu, _("_Copy to clipboard (unquoted)"), active,
                                G_CALLBACK(pan_copy_path_unquoted_cb), pw);
 
        menu_item_add_divider(menu);
index a16851f..79625e6 100644 (file)
@@ -1097,14 +1097,14 @@ static void sr_menu_copy_path_cb(GtkWidget *, gpointer data)
 {
        auto sd = static_cast<SearchData *>(data);
 
-       file_util_copy_path_list_to_clipboard(search_result_selection_list(sd), TRUE);
+       file_util_path_list_to_clipboard(search_result_selection_list(sd), TRUE, TRUE);
 }
 
 static void sr_menu_copy_path_unquoted_cb(GtkWidget *, gpointer data)
 {
        auto sd = static_cast<SearchData *>(data);
 
-       file_util_copy_path_list_to_clipboard(search_result_selection_list(sd), FALSE);
+       file_util_path_list_to_clipboard(search_result_selection_list(sd), FALSE, TRUE);
 }
 
 static void sr_menu_play_cb(GtkWidget *, gpointer data)
index 286183d..223c26d 100644 (file)
@@ -56,6 +56,7 @@
         <separator/>
         <menuitem action="CopyPath"/>
         <menuitem action="CopyPathUnquoted"/>
+        <menuitem action="CutPath"/>
         <placeholder name="ClipboardSection"/>
         <separator/>
         <menuitem action="ShowMarks"/>
index b8d1fc9..2412e16 100644 (file)
@@ -57,6 +57,7 @@
         <separator/>
         <menuitem action="CopyPath"/>
         <menuitem action="CopyPathUnquoted"/>
+        <menuitem action="CutPath"/>
         <placeholder name="ClipboardSection"/>
         <separator/>
         <menuitem action="ShowMarks"/>
index f65daba..3b7e074 100644 (file)
@@ -121,6 +121,7 @@ struct ClipboardData
 {
        GList *path_list; /**< g_strdup(fd->path) */
        gboolean quoted;
+       gboolean action_copy;
 };
 
 /*
@@ -3188,7 +3189,7 @@ static void clipboard_get_func(GtkClipboard *clipboard, GtkSelectionData *select
 
        if (clipboard == gtk_clipboard_get(GDK_SELECTION_CLIPBOARD) && info == CLIPBOARD_X_SPECIAL_GNOME_COPIED_FILES)
                {
-               g_string_append(path_list_str, "copy");
+               g_string_append(path_list_str, cbd->action_copy ? "copy" : "cut");
 
                while (work)
                        {
@@ -3247,7 +3248,15 @@ static void clipboard_clear_func(GtkClipboard *, gpointer data)
        g_free(cbd);
 }
 
-void file_util_copy_path_to_clipboard(FileData *fd, gboolean quoted)
+/**
+ * @brief
+ * @param fd
+ * @param quoted
+ * @param action_copy True: action is "copy". False: action is "cut"
+ *
+ *
+ */
+void file_util_copy_path_to_clipboard(FileData *fd, gboolean quoted, gboolean action_copy)
 {
        ClipboardData *cbd;
 
@@ -3259,6 +3268,7 @@ void file_util_copy_path_to_clipboard(FileData *fd, gboolean quoted)
                cbd = g_new0(ClipboardData, 1);
                cbd->path_list = nullptr;
                cbd->quoted = quoted;
+               cbd->action_copy = action_copy;
                cbd->path_list = g_list_append(cbd->path_list, g_strdup(fd->path));
 
                gtk_clipboard_set_with_data(gtk_clipboard_get(GDK_SELECTION_PRIMARY), target_types, target_types_n, clipboard_get_func, clipboard_clear_func, cbd);
@@ -3269,6 +3279,7 @@ void file_util_copy_path_to_clipboard(FileData *fd, gboolean quoted)
                cbd = g_new0(ClipboardData, 1);
                cbd->path_list = nullptr;
                cbd->quoted = quoted;
+               cbd->action_copy = action_copy;
                cbd->path_list = g_list_append(cbd->path_list, g_strdup(fd->path));
 
                gtk_clipboard_set_with_data(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), target_types, target_types_n, clipboard_get_func, clipboard_clear_func, cbd);
@@ -3279,10 +3290,11 @@ void file_util_copy_path_to_clipboard(FileData *fd, gboolean quoted)
  * @brief
  * @param fd_list List of fd
  * @param quoted
+ * @param action_copy True: action is "copy". False: action is "cut"
  *
  *
  */
-void file_util_copy_path_list_to_clipboard(GList *fd_list, gboolean quoted)
+void file_util_path_list_to_clipboard(GList *fd_list, gboolean quoted, gboolean action_copy)
 {
        ClipboardData *cbd;
        FileData *fd;
@@ -3293,6 +3305,7 @@ void file_util_copy_path_list_to_clipboard(GList *fd_list, gboolean quoted)
                cbd = g_new0(ClipboardData, 1);
                cbd->path_list = nullptr;
                cbd->quoted = quoted;
+               cbd->action_copy = action_copy;
                work = fd_list;
 
                while (work)
@@ -3313,6 +3326,7 @@ void file_util_copy_path_list_to_clipboard(GList *fd_list, gboolean quoted)
                cbd = g_new0(ClipboardData, 1);
                cbd->path_list = nullptr;
                cbd->quoted = quoted;
+               cbd->action_copy = action_copy;
                work = fd_list;
 
                while (work)
index 0a0ec6e..316d9a8 100644 (file)
@@ -74,8 +74,8 @@ void file_util_start_filter_from_filelist(const gchar *key, GList *list, const g
 
 void file_util_delete_dir(FileData *source_fd, GtkWidget *parent);
 
-void file_util_copy_path_to_clipboard(FileData *fd, gboolean quoted);
-void file_util_copy_path_list_to_clipboard(GList *list, gboolean quoted);
+void file_util_copy_path_to_clipboard(FileData *fd, gboolean quoted, gboolean action_copy);
+void file_util_path_list_to_clipboard(GList *list, gboolean quoted, gboolean action_copy);
 
 gchar *new_folder(GtkWindow *window, gchar *path);
 #endif
index 79473d1..0c453ac 100644 (file)
@@ -593,7 +593,7 @@ static void vd_pop_menu_copy_path_cb(GtkWidget *, gpointer data)
 
        if (!vd->click_fd) return;
 
-       file_util_copy_path_to_clipboard(vd->click_fd, TRUE);
+       file_util_copy_path_to_clipboard(vd->click_fd, TRUE, TRUE);
 }
 
 static void vd_pop_menu_copy_path_unquoted_cb(GtkWidget *, gpointer data)
@@ -602,7 +602,16 @@ static void vd_pop_menu_copy_path_unquoted_cb(GtkWidget *, gpointer data)
 
        if (!vd->click_fd) return;
 
-       file_util_copy_path_to_clipboard(vd->click_fd, FALSE);
+       file_util_copy_path_to_clipboard(vd->click_fd, FALSE, TRUE);
+}
+
+static void vd_pop_menu_cut_path_cb(GtkWidget *, gpointer data)
+{
+       auto vd = static_cast<ViewDir *>(data);
+
+       if (!vd->click_fd) return;
+
+       file_util_copy_path_to_clipboard(vd->click_fd, FALSE, FALSE);
 }
 
 static void vd_pop_submenu_dir_view_as_cb(GtkWidget *widget, gpointer data)
@@ -810,12 +819,15 @@ GtkWidget *vd_pop_menu(ViewDir *vd, FileData *fd)
        menu_item_add_sensitive(menu, _("_Rename..."), rename_delete_active,
                                G_CALLBACK(vd_pop_menu_rename_cb), vd);
 
-       menu_item_add(menu, _("_Copy path"),
+       menu_item_add(menu, _("_Copy to clipboard"),
                      G_CALLBACK(vd_pop_menu_copy_path_cb), vd);
 
-       menu_item_add(menu, _("_Copy path unquoted"),
+       menu_item_add(menu, _("_Copy to clipboard (unquoted)"),
                      G_CALLBACK(vd_pop_menu_copy_path_unquoted_cb), vd);
 
+       menu_item_add(menu, _("_Cut to clipboard"),
+                     G_CALLBACK(vd_pop_menu_cut_path_cb), vd);
+
        menu_item_add_icon_sensitive(menu, _("_Delete..."), GQ_ICON_DELETE, rename_delete_active,
                                      G_CALLBACK(vd_pop_menu_delete_cb), vd);
        menu_item_add_divider(menu);
index fa842c5..bca025c 100644 (file)
@@ -441,14 +441,21 @@ static void vf_pop_menu_copy_path_cb(GtkWidget *, gpointer data)
 {
        auto vf = static_cast<ViewFile *>(data);
 
-       file_util_copy_path_list_to_clipboard(vf_pop_menu_file_list(vf), TRUE);
+       file_util_path_list_to_clipboard(vf_pop_menu_file_list(vf), TRUE, TRUE);
 }
 
 static void vf_pop_menu_copy_path_unquoted_cb(GtkWidget *, gpointer data)
 {
        auto vf = static_cast<ViewFile *>(data);
 
-       file_util_copy_path_list_to_clipboard(vf_pop_menu_file_list(vf), FALSE);
+       file_util_path_list_to_clipboard(vf_pop_menu_file_list(vf), FALSE, TRUE);
+}
+
+static void vf_pop_menu_cut_path_cb(GtkWidget *, gpointer data)
+{
+       auto vf = static_cast<ViewFile *>(data);
+
+       file_util_path_list_to_clipboard(vf_pop_menu_file_list(vf), FALSE, FALSE);
 }
 
 static void vf_pop_menu_enable_grouping_cb(GtkWidget *, gpointer data)
@@ -720,10 +727,12 @@ GtkWidget *vf_pop_menu(ViewFile *vf)
                                G_CALLBACK(vf_pop_menu_move_cb), vf);
        menu_item_add_sensitive(menu, _("_Rename..."), active,
                                G_CALLBACK(vf_pop_menu_rename_cb), vf);
-       menu_item_add_sensitive(menu, _("_Copy path to clipboard"), active,
+       menu_item_add_sensitive(menu, _("_Copy to clipboard"), active,
                                G_CALLBACK(vf_pop_menu_copy_path_cb), vf);
-       menu_item_add_sensitive(menu, _("_Copy path unquoted to clipboard"), active,
+       menu_item_add_sensitive(menu, _("_Copy to clipboard (unquoted)"), active,
                                G_CALLBACK(vf_pop_menu_copy_path_unquoted_cb), vf);
+       menu_item_add_sensitive(menu, _("_Cut to clipboard"), active,
+                               G_CALLBACK(vf_pop_menu_cut_path_cb), vf);
        menu_item_add_divider(menu);
        menu_item_add_icon_sensitive(menu,
                                options->file_ops.confirm_move_to_trash ? _("Move to Trash...") :