From d40913660433e45d0c087dccb891d10b965e5eb9 Mon Sep 17 00:00:00 2001 From: Colin Clark Date: Fri, 29 Mar 2024 13:24:11 +0000 Subject: [PATCH] Fix 1302: Cut image to clipboard 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. --- doc/docbook/GuideMainWindowImagePane.xml | 6 ++++++ doc/docbook/GuideMainWindowMenus.xml | 20 +++++++++++++++++-- .../GuideReferenceMainWindowShortcuts.xml | 1 + src/collect-table.cc | 4 ++-- src/dupe.cc | 4 ++-- src/img-view.cc | 4 ++-- src/layout-image.cc | 16 +++++++++++---- src/layout-util.cc | 16 +++++++++++---- src/pan-view/pan-view.cc | 8 ++++---- src/search.cc | 4 ++-- src/ui/menu-classic.ui | 1 + src/ui/menu-hamburger.ui | 1 + src/utilops.cc | 20 ++++++++++++++++--- src/utilops.h | 4 ++-- src/view-dir.cc | 20 +++++++++++++++---- src/view-file/view-file.cc | 17 ++++++++++++---- 16 files changed, 111 insertions(+), 35 deletions(-) diff --git a/doc/docbook/GuideMainWindowImagePane.xml b/doc/docbook/GuideMainWindowImagePane.xml index 6ad4077e..f6e6f4f2 100644 --- a/doc/docbook/GuideMainWindowImagePane.xml +++ b/doc/docbook/GuideMainWindowImagePane.xml @@ -147,6 +147,12 @@ Controls the pause state of an active slide show, the text of the menu will change to reflect the action that will be performed. + + Copy image to clipboard + + Copy the pixbuf to the clipboard. This may be used by programs such as Gimp. + + diff --git a/doc/docbook/GuideMainWindowMenus.xml b/doc/docbook/GuideMainWindowMenus.xml index 5a7931e3..19157148 100644 --- a/doc/docbook/GuideMainWindowMenus.xml +++ b/doc/docbook/GuideMainWindowMenus.xml @@ -496,7 +496,7 @@ - Copy path + Copy to clipboard @@ -513,13 +513,29 @@ - Copy path unquoted + Copy to clipboard (unquoted) Copy selected item-path(s) to clipboard. The data will not be enclosed in quotes. + + + + + + Ctrl + X + + + Cut to clipboard + + + + Perform a standard control-X operation. + + diff --git a/doc/docbook/GuideReferenceMainWindowShortcuts.xml b/doc/docbook/GuideReferenceMainWindowShortcuts.xml index 949923b5..9aba0774 100644 --- a/doc/docbook/GuideReferenceMainWindowShortcuts.xml +++ b/doc/docbook/GuideReferenceMainWindowShortcuts.xml @@ -36,6 +36,7 @@ keyboard shortcuts Shift + KP_Subtract Connected Zoom out underscore Connected Zoom out Ctrl + C Copy + Ctrl + X Cut to clipboard Delete Move to Trash KP_Delete Move to Trash Ctrl + D Move to Trash diff --git a/src/collect-table.cc b/src/collect-table.cc index 0d3016fa..7f47ff75 100644 --- a/src/collect-table.cc +++ b/src/collect-table.cc @@ -791,14 +791,14 @@ static void collection_table_popup_copy_path_cb(GtkWidget *, gpointer data) { auto ct = static_cast(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(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) diff --git a/src/dupe.cc b/src/dupe.cc index dc86cb81..68e553f6 100644 --- a/src/dupe.cc +++ b/src/dupe.cc @@ -3419,14 +3419,14 @@ static void dupe_menu_copy_path_cb(GtkWidget *, gpointer data) { auto dw = static_cast(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(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) diff --git a/src/img-view.cc b/src/img-view.cc index e9e15d8d..f71e1b15 100644 --- a/src/img-view.cc +++ b/src/img-view.cc @@ -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) diff --git a/src/layout-image.cc b/src/layout-image.cc index 4745404a..1bf37468 100644 --- a/src/layout-image.cc +++ b/src/layout-image.cc @@ -598,14 +598,21 @@ static void li_pop_menu_copy_path_cb(GtkWidget *, gpointer data) { auto lw = static_cast(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(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(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); diff --git a/src/layout-util.cc b/src/layout-util.cc index 2f743c68..8d24c5d2 100644 --- a/src/layout-util.cc +++ b/src/layout-util.cc @@ -347,14 +347,21 @@ static void layout_menu_copy_path_cb(GtkAction *, gpointer data) { auto lw = static_cast(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(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(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"), "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..."), "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"), "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..."), "D", N_("Move to Trash..."), CB(layout_menu_move_to_trash_cb) }, diff --git a/src/pan-view/pan-view.cc b/src/pan-view/pan-view.cc index 077c3e27..3d398289 100644 --- a/src/pan-view/pan-view.cc +++ b/src/pan-view/pan-view.cc @@ -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); diff --git a/src/search.cc b/src/search.cc index a16851f0..79625e65 100644 --- a/src/search.cc +++ b/src/search.cc @@ -1097,14 +1097,14 @@ static void sr_menu_copy_path_cb(GtkWidget *, gpointer data) { auto sd = static_cast(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(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) diff --git a/src/ui/menu-classic.ui b/src/ui/menu-classic.ui index 286183db..223c26de 100644 --- a/src/ui/menu-classic.ui +++ b/src/ui/menu-classic.ui @@ -56,6 +56,7 @@ + diff --git a/src/ui/menu-hamburger.ui b/src/ui/menu-hamburger.ui index b8d1fc99..2412e16b 100644 --- a/src/ui/menu-hamburger.ui +++ b/src/ui/menu-hamburger.ui @@ -57,6 +57,7 @@ + diff --git a/src/utilops.cc b/src/utilops.cc index f65dabaf..3b7e074c 100644 --- a/src/utilops.cc +++ b/src/utilops.cc @@ -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) diff --git a/src/utilops.h b/src/utilops.h index 0a0ec6e8..316d9a8a 100644 --- a/src/utilops.h +++ b/src/utilops.h @@ -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 diff --git a/src/view-dir.cc b/src/view-dir.cc index 79473d1e..0c453aca 100644 --- a/src/view-dir.cc +++ b/src/view-dir.cc @@ -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(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); diff --git a/src/view-file/view-file.cc b/src/view-file/view-file.cc index fa842c57..bca025cc 100644 --- a/src/view-file/view-file.cc +++ b/src/view-file/view-file.cc @@ -441,14 +441,21 @@ static void vf_pop_menu_copy_path_cb(GtkWidget *, gpointer data) { auto vf = static_cast(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(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(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...") : -- 2.20.1