# HG changeset patch # User zas_ # Date 1208989041 0 # Node ID a33badd85f16b6df51551656b1e912490e031719 # Parent a1f13fab6686e8feedf574adeb8dbcd3270339a1 Allow the copy of file paths to clipboard. This feature is disabled by default, it can be set through Preferences > Advanced > Behavior > Show "Copy path" ... When enabled, it adds a menu entry "Copy path" that let the user copies current selection's paths to X clipboard. It is very convenient to paste paths to xterm for example. Patch by Carles Pina i Estany and me. diff -r a1f13fab6686 -r a33badd85f16 src/collect-table.c --- a/src/collect-table.c Wed Apr 23 21:08:29 2008 +0000 +++ b/src/collect-table.c Wed Apr 23 22:17:21 2008 +0000 @@ -625,6 +625,13 @@ file_util_delete(NULL, collection_table_popup_file_list(ct), ct->listview); } +static void collection_table_popup_copy_path_cb(GtkWidget *widget, gpointer data) +{ + CollectTable *ct = data; + + file_util_copy_path_list_to_clipboard(collection_table_popup_file_list(ct)); +} + static void collection_table_popup_sort_cb(GtkWidget *widget, gpointer data) { CollectTable *ct; @@ -799,6 +806,9 @@ G_CALLBACK(collection_table_popup_rename_cb), ct); menu_item_add_stock_sensitive(menu, _("_Delete..."), GTK_STOCK_DELETE, over_icon, G_CALLBACK(collection_table_popup_delete_cb), ct); + if (options->show_copy_path) + menu_item_add_sensitive(menu, _("_Copy path"), over_icon, + G_CALLBACK(collection_table_popup_copy_path_cb), ct); menu_item_add_divider(menu); submenu_add_sort(menu, G_CALLBACK(collection_table_popup_sort_cb), ct, FALSE, TRUE, FALSE, 0); diff -r a1f13fab6686 -r a33badd85f16 src/dupe.c --- a/src/dupe.c Wed Apr 23 21:08:29 2008 +0000 +++ b/src/dupe.c Wed Apr 23 22:17:21 2008 +0000 @@ -2197,6 +2197,13 @@ file_util_delete(NULL, dupe_listview_get_selection(dw, dw->listview), dw->window); } +static void dupe_menu_copy_path_cb(GtkWidget *widget, gpointer data) +{ + DupeWindow *dw = data; + + file_util_copy_path_list_to_clipboard(dupe_listview_get_selection(dw, dw->listview)); +} + static void dupe_menu_remove_cb(GtkWidget *widget, gpointer data) { DupeWindow *dw = data; @@ -2258,6 +2265,9 @@ G_CALLBACK(dupe_menu_rename_cb), dw); menu_item_add_stock_sensitive(menu, _("_Delete..."), GTK_STOCK_DELETE, on_row, G_CALLBACK(dupe_menu_delete_cb), dw); + if (options->show_copy_path) + menu_item_add_sensitive(menu, _("_Copy path"), on_row, + G_CALLBACK(dupe_menu_copy_path_cb), dw); menu_item_add_divider(menu); menu_item_add_stock_sensitive(menu, _("Rem_ove"), GTK_STOCK_REMOVE, on_row, G_CALLBACK(dupe_menu_remove_cb), dw); diff -r a1f13fab6686 -r a33badd85f16 src/globals.c --- a/src/globals.c Wed Apr 23 21:08:29 2008 +0000 +++ b/src/globals.c Wed Apr 23 22:17:21 2008 +0000 @@ -117,6 +117,7 @@ options->panels.sort.selection_state = 0; options->progressive_key_scrolling = FALSE; + options->show_copy_path = FALSE; options->show_icon_names = TRUE; options->slideshow.delay = 150; diff -r a1f13fab6686 -r a33badd85f16 src/img-view.c --- a/src/img-view.c Wed Apr 23 21:08:29 2008 +0000 +++ b/src/img-view.c Wed Apr 23 22:17:21 2008 +0000 @@ -1183,6 +1183,15 @@ file_util_delete(image_get_fd(imd), NULL, imd->widget); } +static void view_copy_path_cb(GtkWidget *widget, gpointer data) +{ + ViewWindow *vw = data; + ImageWindow *imd; + + imd = view_window_active_image(vw); + file_util_copy_path_to_clipboard(image_get_fd(imd)); +} + static void view_fullscreen_cb(GtkWidget *widget, gpointer data) { ViewWindow *vw = data; @@ -1279,6 +1288,8 @@ menu_item_add(menu, _("_Move..."), G_CALLBACK(view_move_cb), vw); menu_item_add(menu, _("_Rename..."), G_CALLBACK(view_rename_cb), vw); menu_item_add_stock(menu, _("_Delete..."), GTK_STOCK_DELETE, G_CALLBACK(view_delete_cb), vw); + if (options->show_copy_path) + menu_item_add(menu, _("_Copy path"), G_CALLBACK(view_copy_path_cb), vw); menu_item_add_divider(menu); diff -r a1f13fab6686 -r a33badd85f16 src/layout_image.c --- a/src/layout_image.c Wed Apr 23 21:08:29 2008 +0000 +++ b/src/layout_image.c Wed Apr 23 22:17:21 2008 +0000 @@ -637,6 +637,13 @@ li_pop_menu_click_parent(widget, lw)); } +static void li_pop_menu_copy_path_cb(GtkWidget *widget, gpointer data) +{ + LayoutWindow *lw = data; + + file_util_copy_path_to_clipboard(layout_image_get_fd(lw)); +} + static void li_pop_menu_move_cb(GtkWidget *widget, gpointer data) { LayoutWindow *lw = data; @@ -765,6 +772,12 @@ if (!path) gtk_widget_set_sensitive(item, FALSE); item = menu_item_add_stock(menu, _("_Delete..."), GTK_STOCK_DELETE, G_CALLBACK(li_pop_menu_delete_cb), lw); if (!path) gtk_widget_set_sensitive(item, FALSE); + + if (options->show_copy_path) + { + item = menu_item_add(menu, _("_Copy path"), G_CALLBACK(li_pop_menu_copy_path_cb), lw); + if (!path) gtk_widget_set_sensitive(item, FALSE); + } menu_item_add_divider(menu); diff -r a1f13fab6686 -r a33badd85f16 src/layout_util.c --- a/src/layout_util.c Wed Apr 23 21:08:29 2008 +0000 +++ b/src/layout_util.c Wed Apr 23 22:17:21 2008 +0000 @@ -261,6 +261,13 @@ file_util_copy(NULL, layout_selection_list(lw), NULL, layout_window(lw)); } +static void layout_menu_copy_path_cb(GtkAction *action, gpointer data) +{ + LayoutWindow *lw = data; + + file_util_copy_path_list_to_clipboard(layout_selection_list(lw)); +} + static void layout_menu_move_cb(GtkAction *action, gpointer data) { LayoutWindow *lw = data; @@ -987,6 +994,38 @@ /* *----------------------------------------------------------------------------- + * copy path + *----------------------------------------------------------------------------- + */ + +static void layout_copy_path_update(LayoutWindow *lw) +{ + GtkWidget *item = gtk_ui_manager_get_widget(lw->ui_manager, "/MainMenu/FileMenu/CopyPath"); + + if (!item) return; + + if (options->show_copy_path) + gtk_widget_show(item); + else + gtk_widget_hide(item); +} + +void layout_copy_path_update_all(void) +{ + GList *work; + + work = layout_window_list; + while (work) + { + LayoutWindow *lw = work->data; + work = work->next; + + layout_copy_path_update(lw); + } +} + +/* + *----------------------------------------------------------------------------- * menu *----------------------------------------------------------------------------- */ @@ -1030,6 +1069,7 @@ { "Delete", GTK_STOCK_DELETE, N_("_Delete..."), "D", NULL, CB(layout_menu_delete_cb) }, { "DeleteAlt1",GTK_STOCK_DELETE, N_("_Delete..."), "Delete", NULL, CB(layout_menu_delete_cb) }, { "DeleteAlt2",GTK_STOCK_DELETE, N_("_Delete..."), "KP_Delete", NULL, CB(layout_menu_delete_cb) }, + { "CopyPath", NULL, N_("_Copy path"), NULL, NULL, CB(layout_menu_copy_path_cb) }, { "CloseWindow", GTK_STOCK_CLOSE,N_("C_lose window"), "W", NULL, CB(layout_menu_close_cb) }, { "Quit", GTK_STOCK_QUIT, N_("_Quit"), "Q", NULL, CB(layout_menu_exit_cb) }, @@ -1146,6 +1186,7 @@ " " " " " " +" " " " " " " " @@ -1387,8 +1428,9 @@ g_error_free (error); exit (EXIT_FAILURE); } - + layout_actions_setup_marks(lw); + layout_copy_path_update(lw); } void layout_actions_add_window(LayoutWindow *lw, GtkWidget *window) diff -r a1f13fab6686 -r a33badd85f16 src/layout_util.h --- a/src/layout_util.h Wed Apr 23 21:08:29 2008 +0000 +++ b/src/layout_util.h Wed Apr 23 22:17:21 2008 +0000 @@ -28,6 +28,8 @@ void layout_recent_update_all(void); void layout_recent_add_path(const gchar *path); +void layout_copy_path_update_all(void); + void layout_actions_setup(LayoutWindow *lw); void layout_actions_add_window(LayoutWindow *lw, GtkWidget *window); GtkWidget *layout_actions_menu_bar(LayoutWindow *lw); diff -r a1f13fab6686 -r a33badd85f16 src/pan-view.c --- a/src/pan-view.c Wed Apr 23 21:08:29 2008 +0000 +++ b/src/pan-view.c Wed Apr 23 22:17:21 2008 +0000 @@ -2737,6 +2737,15 @@ if (fd) file_util_delete(fd, NULL, pw->imd->widget); } +static void pan_copy_path_cb(GtkWidget *widget, gpointer data) +{ + PanWindow *pw = data; + FileData *fd; + + fd = pan_menu_click_fd(pw); + if (fd) file_util_copy_path_to_clipboard(fd); +} + static void pan_exif_date_toggle_cb(GtkWidget *widget, gpointer data) { PanWindow *pw = data; @@ -2812,6 +2821,9 @@ G_CALLBACK(pan_rename_cb), pw); menu_item_add_stock_sensitive(menu, _("_Delete..."), GTK_STOCK_DELETE, active, G_CALLBACK(pan_delete_cb), pw); + if (options->show_copy_path) + menu_item_add_sensitive(menu, _("_Copy path"), active, + G_CALLBACK(pan_copy_path_cb), pw); menu_item_add_divider(menu); item = menu_item_add_check(menu, _("Sort by E_xif date"), pw->exif_date_enable, diff -r a1f13fab6686 -r a33badd85f16 src/preferences.c --- a/src/preferences.c Wed Apr 23 21:08:29 2008 +0000 +++ b/src/preferences.c Wed Apr 23 22:17:21 2008 +0000 @@ -270,6 +270,12 @@ options->open_recent_list_maxsize = c_options->open_recent_list_maxsize; options->dnd_icon_size = c_options->dnd_icon_size; + + if (options->show_copy_path != c_options->show_copy_path) + { + options->show_copy_path = c_options->show_copy_path; + layout_copy_path_update_all(); + } #ifdef DEBUG debug = debug_c; @@ -1396,6 +1402,7 @@ gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); gtk_widget_show(button); + group = pref_group_new(vbox, FALSE, _("Behavior"), GTK_ORIENTATION_VERTICAL); pref_checkbox_new_int(group, _("Rectangular selection in icon view"), @@ -1407,6 +1414,9 @@ pref_checkbox_new_int(group, _("In place renaming"), options->file_ops.enable_in_place_rename, &c_options->file_ops.enable_in_place_rename); + pref_checkbox_new_int(group, _("Show \"Copy path\" menu item which write the path of selected files to clipboard"), + options->show_copy_path, &c_options->show_copy_path); + pref_spin_new_int(group, _("Open recent list maximum size"), NULL, 1, 50, 1, options->open_recent_list_maxsize, &c_options->open_recent_list_maxsize); diff -r a1f13fab6686 -r a33badd85f16 src/rcfile.c --- a/src/rcfile.c Wed Apr 23 21:08:29 2008 +0000 +++ b/src/rcfile.c Wed Apr 23 22:17:21 2008 +0000 @@ -301,6 +301,7 @@ WRITE_SUBTITLE("General Options"); WRITE_BOOL(show_icon_names); + WRITE_BOOL(show_copy_path); WRITE_SEPARATOR(); WRITE_BOOL(tree_descend_subdirs); @@ -614,6 +615,7 @@ /* general options */ READ_BOOL(show_icon_names); + READ_BOOL(show_copy_path); READ_BOOL(tree_descend_subdirs); READ_BOOL(lazy_image_sync); diff -r a1f13fab6686 -r a33badd85f16 src/search.c --- a/src/search.c Wed Apr 23 21:08:29 2008 +0000 +++ b/src/search.c Wed Apr 23 22:17:21 2008 +0000 @@ -946,6 +946,13 @@ file_util_delete(NULL, search_result_selection_list(sd), sd->window); } +static void sr_menu_copy_path_cb(GtkWidget *widget, gpointer data) +{ + SearchData *sd = data; + + file_util_copy_path_list_to_clipboard(search_result_selection_list(sd)); +} + static void sr_menu_remove_cb(GtkWidget *widget, gpointer data) { SearchData *sd = data; @@ -993,6 +1000,9 @@ G_CALLBACK(sr_menu_rename_cb), sd); menu_item_add_stock_sensitive(menu, _("_Delete..."), GTK_STOCK_DELETE, on_row, G_CALLBACK(sr_menu_delete_cb), sd); + if (options->show_copy_path) + menu_item_add_sensitive(menu, _("_Copy path"), on_row, + G_CALLBACK(sr_menu_copy_path_cb), sd); menu_item_add_divider(menu); menu_item_add_stock_sensitive(menu, _("Rem_ove"), GTK_STOCK_REMOVE, on_row, G_CALLBACK(sr_menu_remove_cb), sd); diff -r a1f13fab6686 -r a33badd85f16 src/typedefs.h --- a/src/typedefs.h Wed Apr 23 21:08:29 2008 +0000 +++ b/src/typedefs.h Wed Apr 23 22:17:21 2008 +0000 @@ -749,6 +749,7 @@ gint place_dialogs_under_mouse; gint mousewheel_scrolls; gint show_icon_names; + gint show_copy_path; /* various */ gint startup_path_enable; diff -r a1f13fab6686 -r a33badd85f16 src/utilops.c --- a/src/utilops.c Wed Apr 23 21:08:29 2008 +0000 +++ b/src/utilops.c Wed Apr 23 22:17:21 2008 +0000 @@ -1238,6 +1238,40 @@ real_file_util_move(source_fd, source_list, dest_path, TRUE, parent); } +void file_util_copy_path_to_clipboard(FileData *fd) +{ + GtkClipboard *clipboard; + + if (!fd || !*fd->path) return; + + clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); + gtk_clipboard_set_text(clipboard, g_shell_quote(fd->path), -1); +} + +void file_util_copy_path_list_to_clipboard(GList *list) +{ + GtkClipboard *clipboard; + GList *work; + GString *new; + + clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); + + new = g_string_new(""); + work = list; + while (work) { + FileData *fd = work->data; + work = work->next; + + if (!fd || !*fd->path) continue; + + g_string_append(new, g_shell_quote(fd->path)); + if (work) g_string_append_c(new, ' '); + } + + gtk_clipboard_set_text(clipboard, new->str, new->len); + g_string_free(new, TRUE); +} + void file_util_move_simple(GList *list, const gchar *dest_path) { if (!list) return; diff -r a1f13fab6686 -r a33badd85f16 src/utilops.h --- a/src/utilops.h Wed Apr 23 21:08:29 2008 +0000 +++ b/src/utilops.h Wed Apr 23 22:17:21 2008 +0000 @@ -57,4 +57,7 @@ gint move_file_ext(FileData *fd); gint rename_file_ext(FileData *fd); +void file_util_copy_path_to_clipboard(FileData *fd); +void file_util_copy_path_list_to_clipboard(GList *list); + #endif diff -r a1f13fab6686 -r a33badd85f16 src/view_file_icon.c --- a/src/view_file_icon.c Wed Apr 23 21:08:29 2008 +0000 +++ b/src/view_file_icon.c Wed Apr 23 22:17:21 2008 +0000 @@ -242,6 +242,13 @@ file_util_delete(NULL, vficon_pop_menu_file_list(vfi), vfi->listview); } +static void vficon_pop_menu_copy_path_cb(GtkWidget *widget, gpointer data) +{ + ViewFileIcon *vfi = data; + + file_util_copy_path_list_to_clipboard(vficon_pop_menu_file_list(vfi)); +} + static void vficon_pop_menu_sort_cb(GtkWidget *widget, gpointer data) { ViewFileIcon *vfi; @@ -336,6 +343,11 @@ gtk_widget_set_sensitive(item, active); item = menu_item_add_stock(menu, _("_Delete..."), GTK_STOCK_DELETE, G_CALLBACK(vficon_pop_menu_delete_cb), vfi); gtk_widget_set_sensitive(item, active); + if (options->show_copy_path) + { + item = menu_item_add(menu, _("_Copy path"), G_CALLBACK(vficon_pop_menu_copy_path_cb), vfi); + gtk_widget_set_sensitive(item, active); + } menu_item_add_divider(menu); diff -r a1f13fab6686 -r a33badd85f16 src/view_file_list.c --- a/src/view_file_list.c Wed Apr 23 21:08:29 2008 +0000 +++ b/src/view_file_list.c Wed Apr 23 22:17:21 2008 +0000 @@ -344,6 +344,13 @@ file_util_copy(NULL, vflist_pop_menu_file_list(vfl), NULL, vfl->listview); } +static void vflist_pop_menu_copy_path_cb(GtkWidget *widget, gpointer data) +{ + ViewFileList *vfl = data; + + file_util_copy_path_list_to_clipboard(vflist_pop_menu_file_list(vfl)); +} + static void vflist_pop_menu_move_cb(GtkWidget *widget, gpointer data) { ViewFileList *vfl = data; @@ -581,7 +588,10 @@ menu_item_add_sensitive(menu, _("_Rename..."), active, G_CALLBACK(vflist_pop_menu_rename_cb), vfl); menu_item_add_stock_sensitive(menu, _("_Delete..."), GTK_STOCK_DELETE, active, - G_CALLBACK(vflist_pop_menu_delete_cb), vfl); + G_CALLBACK(vflist_pop_menu_delete_cb), vfl); + if (options->show_copy_path) + menu_item_add_sensitive(menu, _("_Copy path"), active, + G_CALLBACK(vflist_pop_menu_copy_path_cb), vfl); menu_item_add_divider(menu);