Skip to content

Commit

Permalink
Allow the copy of file paths to clipboard.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Laurent Monin committed Apr 23, 2008
1 parent b022edd commit 3a71a78
Show file tree
Hide file tree
Showing 16 changed files with 185 additions and 2 deletions.
10 changes: 10 additions & 0 deletions src/collect-table.c
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,13 @@ static void collection_table_popup_delete_cb(GtkWidget *widget, gpointer data)
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;
Expand Down Expand Up @@ -799,6 +806,9 @@ static GtkWidget *collection_table_popup_menu(CollectTable *ct, gint over_icon)
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);
Expand Down
10 changes: 10 additions & 0 deletions src/dupe.c
Original file line number Diff line number Diff line change
Expand Up @@ -2197,6 +2197,13 @@ static void dupe_menu_delete_cb(GtkWidget *widget, gpointer data)
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;
Expand Down Expand Up @@ -2258,6 +2265,9 @@ static GtkWidget *dupe_menu_popup_main(DupeWindow *dw, DupeItem *di)
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);
Expand Down
1 change: 1 addition & 0 deletions src/globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ ConfOptions *init_options(ConfOptions *options)
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;
Expand Down
11 changes: 11 additions & 0 deletions src/img-view.c
Original file line number Diff line number Diff line change
Expand Up @@ -1183,6 +1183,15 @@ static void view_delete_cb(GtkWidget *widget, gpointer data)
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;
Expand Down Expand Up @@ -1279,6 +1288,8 @@ static GtkWidget *view_popup_menu(ViewWindow *vw)
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);

Expand Down
13 changes: 13 additions & 0 deletions src/layout_image.c
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,13 @@ static void li_pop_menu_copy_cb(GtkWidget *widget, gpointer data)
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;
Expand Down Expand Up @@ -765,6 +772,12 @@ static GtkWidget *layout_image_pop_menu(LayoutWindow *lw)
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);

Expand Down
44 changes: 43 additions & 1 deletion src/layout_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,13 @@ static void layout_menu_copy_cb(GtkAction *action, gpointer data)
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;
Expand Down Expand Up @@ -985,6 +992,38 @@ void layout_recent_add_path(const gchar *path)
layout_recent_update_all();
}

/*
*-----------------------------------------------------------------------------
* 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
Expand Down Expand Up @@ -1030,6 +1069,7 @@ static GtkActionEntry menu_entries[] = {
{ "Delete", GTK_STOCK_DELETE, N_("_Delete..."), "<control>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"), "<control>W", NULL, CB(layout_menu_close_cb) },
{ "Quit", GTK_STOCK_QUIT, N_("_Quit"), "<control>Q", NULL, CB(layout_menu_exit_cb) },

Expand Down Expand Up @@ -1146,6 +1186,7 @@ static const char *menu_ui_description =
" <menuitem action='Move'/>"
" <menuitem action='Rename'/>"
" <menuitem action='Delete'/>"
" <menuitem action='CopyPath'/>"
" <separator/>"
" <menuitem action='CloseWindow'/>"
" <menuitem action='Quit'/>"
Expand Down Expand Up @@ -1387,8 +1428,9 @@ void layout_actions_setup(LayoutWindow *lw)
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)
Expand Down
2 changes: 2 additions & 0 deletions src/layout_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ void layout_edit_update_all(void);
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);
Expand Down
12 changes: 12 additions & 0 deletions src/pan-view.c
Original file line number Diff line number Diff line change
Expand Up @@ -2737,6 +2737,15 @@ static void pan_delete_cb(GtkWidget *widget, gpointer data)
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;
Expand Down Expand Up @@ -2812,6 +2821,9 @@ static GtkWidget *pan_popup_menu(PanWindow *pw)
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,
Expand Down
10 changes: 10 additions & 0 deletions src/preferences.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,12 @@ static void config_window_apply(void)

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;
Expand Down Expand Up @@ -1396,6 +1402,7 @@ static void config_tab_advanced(GtkWidget *notebook)
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"),
Expand All @@ -1407,6 +1414,9 @@ static void config_tab_advanced(GtkWidget *notebook)
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);

Expand Down
2 changes: 2 additions & 0 deletions src/rcfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ void save_options(void)
WRITE_SUBTITLE("General Options");

WRITE_BOOL(show_icon_names);
WRITE_BOOL(show_copy_path);
WRITE_SEPARATOR();

WRITE_BOOL(tree_descend_subdirs);
Expand Down Expand Up @@ -614,6 +615,7 @@ void load_options(void)

/* general options */
READ_BOOL(show_icon_names);
READ_BOOL(show_copy_path);

READ_BOOL(tree_descend_subdirs);
READ_BOOL(lazy_image_sync);
Expand Down
10 changes: 10 additions & 0 deletions src/search.c
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,13 @@ static void sr_menu_delete_cb(GtkWidget *widget, gpointer data)
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;
Expand Down Expand Up @@ -993,6 +1000,9 @@ static GtkWidget *search_result_menu(SearchData *sd, gint on_row, gint empty)
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);
Expand Down
1 change: 1 addition & 0 deletions src/typedefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,7 @@ struct _ConfOptions
gint place_dialogs_under_mouse;
gint mousewheel_scrolls;
gint show_icon_names;
gint show_copy_path;

/* various */
gint startup_path_enable;
Expand Down
34 changes: 34 additions & 0 deletions src/utilops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,40 @@ void file_util_copy(FileData *source_fd, GList *source_list, const gchar *dest_p
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;
Expand Down
3 changes: 3 additions & 0 deletions src/utilops.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,7 @@ gint copy_file_ext(FileData *fd);
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
12 changes: 12 additions & 0 deletions src/view_file_icon.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,13 @@ static void vficon_pop_menu_delete_cb(GtkWidget *widget, gpointer data)
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;
Expand Down Expand Up @@ -336,6 +343,11 @@ static GtkWidget *vficon_pop_menu(ViewFileIcon *vfi, gint active)
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);

Expand Down
Loading

0 comments on commit 3a71a78

Please sign in to comment.