# HG changeset patch # User Colin Clark # Date 1534358586 -3600 # Node ID e6f95baec8b52d68574e4f089c2d4c956652676c # Parent e993f52f08a2954a58e19519e46f6fd4917b3bdc Fix #624: Filter files by shell or regular expression pattern https://github.com/BestImageViewer/geeqie/issues/624 An option on Select/Show File Filter (or the toolbar) to provide regular expression file-filtering of the currently displayed folder. diff -r e993f52f08a2 -r e6f95baec8b5 doc/docbook/GuideMainWindowFilePane.xml --- a/doc/docbook/GuideMainWindowFilePane.xml Tue Aug 14 21:28:02 2018 +0100 +++ b/doc/docbook/GuideMainWindowFilePane.xml Wed Aug 15 19:43:06 2018 +0100 @@ -57,6 +57,26 @@ +
+ File Filter + + A filter box can be opened by selecting + Show File Filter + from the View menu. + + + Characters you type into this box will be used for pattern matching to select the files displayed. + Regular expressions + are used in this field. + + For basic pattern matching "JPG" will match any filename containing those characters. + + To make a case-insensitive search, use "(?i)JPG" + + If you type a newline, the text will be saved in the dropdown box list. The last 10 items are saved. + + +
Multiple selection It is possible to select more than one image from the file pane. Multiple files can be selected with several methods: diff -r e993f52f08a2 -r e6f95baec8b5 src/filedata.c --- a/src/filedata.c Tue Aug 14 21:28:02 2018 +0100 +++ b/src/filedata.c Wed Aug 15 19:43:06 2018 +0100 @@ -1817,6 +1817,33 @@ return list; } +gboolean file_data_filter_file_filter(FileData *fd, GRegex *filter) +{ + return g_regex_match(filter, fd->name, 0, NULL); +} + +GList *file_data_filter_file_filter_list(GList *list, GRegex *filter) +{ + GList *work; + + work = list; + while (work) + { + FileData *fd = work->data; + GList *link = work; + work = work->next; + + if (!file_data_filter_file_filter(fd, filter)) + { + list = g_list_remove_link(list, link); + file_data_unref(fd); + g_list_free(link); + } + } + + return list; +} + static void file_data_notify_mark_func(gpointer key, gpointer value, gpointer user_data) { FileData *fd = value; diff -r e993f52f08a2 -r e6f95baec8b5 src/filedata.h --- a/src/filedata.h Tue Aug 14 21:28:02 2018 +0100 +++ b/src/filedata.h Wed Aug 15 19:43:06 2018 +0100 @@ -99,6 +99,9 @@ gboolean file_data_filter_marks(FileData *fd, guint filter); GList *file_data_filter_marks_list(GList *list, guint filter); +gboolean file_data_filter_file_filter(FileData *fd, GRegex *filter); +GList *file_data_filter_file_filter_list(GList *list, GRegex *filter); + gint file_data_get_user_orientation(FileData *fd); void file_data_set_user_orientation(FileData *fd, gint value); diff -r e993f52f08a2 -r e6f95baec8b5 src/icons/Makefile.am --- a/src/icons/Makefile.am Tue Aug 14 21:28:02 2018 +0100 +++ b/src/icons/Makefile.am Wed Aug 15 19:43:06 2018 +0100 @@ -39,7 +39,8 @@ icon_select_all.png \ icon_select_none.png \ icon_select_invert.png \ - icon_select_rectangle.png + icon_select_rectangle.png \ + icon_file_filter.png ICONS_INLINE_PAIRS = \ @@ -78,7 +79,8 @@ icon_select_all $(srcdir)/icon_select_all.png \ icon_select_none $(srcdir)/icon_select_none.png \ icon_select_invert $(srcdir)/icon_select_invert.png \ - icon_select_rectangle $(srcdir)/icon_select_rectangle.png + icon_select_rectangle $(srcdir)/icon_select_rectangle.png \ + icon_file_filter $(srcdir)/icon_file_filter.png icons_inline.h: $(ICONS_INLINE) Makefile.in @sh -ec "echo '/* Auto generated file, do not edit */'; echo; \ diff -r e993f52f08a2 -r e6f95baec8b5 src/icons/icon_file_filter.png Binary file src/icons/icon_file_filter.png has changed diff -r e993f52f08a2 -r e6f95baec8b5 src/layout.c --- a/src/layout.c Tue Aug 14 21:28:02 2018 +0100 +++ b/src/layout.c Wed Aug 15 19:43:06 2018 +0100 @@ -862,6 +862,11 @@ if (lw->vf) vf_thumb_set(lw->vf, lw->options.show_thumbnails); } +static void layout_list_sync_file_filter(LayoutWindow *lw) +{ + if (lw->vf) vf_file_filter_set(lw->vf, lw->options.show_file_filter); +} + static GtkWidget *layout_list_new(LayoutWindow *lw) { lw->vf = vf_new(lw->options.file_view_type, NULL); @@ -873,6 +878,7 @@ vf_marks_set(lw->vf, lw->options.show_marks); layout_list_sync_thumb(lw); + layout_list_sync_file_filter(lw); return lw->vf->widget; } @@ -1178,6 +1184,18 @@ layout_list_sync_thumb(lw); } +void layout_file_filter_set(LayoutWindow *lw, gboolean enable) +{ + if (!layout_valid(&lw)) return; + + if (lw->options.show_file_filter == enable) return; + + lw->options.show_file_filter = enable; + + layout_util_sync_file_filter(lw); + layout_list_sync_file_filter(lw); +} + void layout_marks_set(LayoutWindow *lw, gboolean enable) { if (!layout_valid(&lw)) return; @@ -2476,6 +2494,7 @@ WRITE_NL(); WRITE_UINT(*layout, dir_view_type); WRITE_NL(); WRITE_UINT(*layout, file_view_type); WRITE_NL(); WRITE_BOOL(*layout, show_marks); + WRITE_NL(); WRITE_BOOL(*layout, show_file_filter); WRITE_NL(); WRITE_BOOL(*layout, show_thumbnails); WRITE_NL(); WRITE_BOOL(*layout, show_directory_date); WRITE_NL(); WRITE_CHAR(*layout, home_path); @@ -2565,6 +2584,7 @@ if (READ_UINT(*layout, dir_view_type)) continue; if (READ_UINT(*layout, file_view_type)) continue; if (READ_BOOL(*layout, show_marks)) continue; + if (READ_BOOL(*layout, show_file_filter)) continue; if (READ_BOOL(*layout, show_thumbnails)) continue; if (READ_BOOL(*layout, show_directory_date)) continue; if (READ_CHAR(*layout, home_path)) continue; diff -r e993f52f08a2 -r e6f95baec8b5 src/layout.h --- a/src/layout.h Tue Aug 14 21:28:02 2018 +0100 +++ b/src/layout.h Wed Aug 15 19:43:06 2018 +0100 @@ -89,6 +89,8 @@ void layout_marks_set(LayoutWindow *lw, gboolean enable); gboolean layout_marks_get(LayoutWindow *lw); +void layout_file_filter_set(LayoutWindow *lw, gboolean enable); + void layout_sort_set(LayoutWindow *lw, SortType type, gboolean ascend); gboolean layout_sort_get(LayoutWindow *lw, SortType *type, gboolean *ascend); diff -r e993f52f08a2 -r e6f95baec8b5 src/layout_util.c --- a/src/layout_util.c Tue Aug 14 21:28:02 2018 +0100 +++ b/src/layout_util.c Wed Aug 15 19:43:06 2018 +0100 @@ -117,6 +117,15 @@ return TRUE; } } + + if (lw->vf->file_filter_combo && gtk_widget_has_focus(gtk_bin_get_child(GTK_BIN(lw->vf->file_filter_combo)))) + { + if (gtk_widget_event(gtk_bin_get_child(GTK_BIN(lw->vf->file_filter_combo)), (GdkEvent *)event)) + { + return TRUE; + } + } + if (lw->vd && lw->options.dir_view_type == DIRVIEW_TREE && gtk_widget_has_focus(lw->vd->view) && !layout_key_match(event->keyval) && gtk_widget_event(lw->vd->view, (GdkEvent *)event)) @@ -1387,6 +1396,13 @@ layout_select_invert(lw); } +static void layout_menu_file_filter_cb(GtkToggleAction *action, gpointer data) +{ + LayoutWindow *lw = data; + + layout_file_filter_set(lw, gtk_toggle_action_get_active(action)); +} + static void layout_menu_marks_cb(GtkToggleAction *action, gpointer data) { LayoutWindow *lw = data; @@ -1940,6 +1956,7 @@ static GtkToggleActionEntry menu_toggle_entries[] = { { "Thumbnails", PIXBUF_INLINE_ICON_THUMB,N_("Show _Thumbnails"), "T", N_("Show Thumbnails"), CB(layout_menu_thumb_cb), FALSE }, { "ShowMarks", PIXBUF_INLINE_ICON_MARKS, N_("Show _Marks"), "M", N_("Show Marks"), CB(layout_menu_marks_cb), FALSE }, + { "ShowFileFilter", PIXBUF_INLINE_ICON_FILE_FILTER, N_("Show File Filter"), NULL, N_("Show File Filter"), CB(layout_menu_file_filter_cb), FALSE }, { "ShowInfoPixel", GTK_STOCK_COLOR_PICKER, N_("Pi_xel Info"), NULL, N_("Show Pixel Info"), CB(layout_menu_info_pixel_cb), FALSE }, { "FloatTools", PIXBUF_INLINE_ICON_FLOAT,N_("_Float file list"), "L", N_("Float file list"), CB(layout_menu_float_cb), FALSE }, { "HideToolbar", NULL, N_("Hide tool_bar"), NULL, N_("Hide toolbar"), CB(layout_menu_toolbar_cb), FALSE }, @@ -2053,6 +2070,7 @@ " " " " " " +" " " " " " " " @@ -3004,6 +3022,16 @@ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), layout_image_get_desaturate(lw)); } +void layout_util_sync_file_filter(LayoutWindow *lw) +{ + GtkAction *action; + + if (!lw->action_group) return; + + action = gtk_action_group_get_action(lw->action_group, "ShowFileFilter"); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->options.show_file_filter); +} + void layout_util_sync_marks(LayoutWindow *lw) { GtkAction *action; @@ -3078,6 +3106,9 @@ action = gtk_action_group_get_action(lw->action_group, "RectangularSelection"); gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), options->collections.rectangular_selection); + action = gtk_action_group_get_action(lw->action_group, "ShowFileFilter"); + gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->options.show_file_filter); + if (osd_flags & OSD_SHOW_HISTOGRAM) { action = gtk_action_group_get_action(lw->action_group, "HistogramChanR"); diff -r e993f52f08a2 -r e6f95baec8b5 src/layout_util.h --- a/src/layout_util.h Tue Aug 14 21:28:02 2018 +0100 +++ b/src/layout_util.h Wed Aug 15 19:43:06 2018 +0100 @@ -29,6 +29,7 @@ void layout_util_sync_thumb(LayoutWindow *lw); void layout_util_sync_marks(LayoutWindow *lw); +void layout_util_sync_file_filter(LayoutWindow *lw); void layout_util_sync_color(LayoutWindow *lw); void layout_util_sync(LayoutWindow *lw); diff -r e993f52f08a2 -r e6f95baec8b5 src/options.c --- a/src/options.c Tue Aug 14 21:28:02 2018 +0100 +++ b/src/options.c Wed Aug 15 19:43:06 2018 +0100 @@ -273,6 +273,7 @@ options->order = g_strdup("123"); options->show_directory_date = FALSE; options->show_marks = FALSE; + options->show_file_filter = FALSE; options->show_thumbnails = FALSE; options->style = 0; options->show_info_pixel = FALSE; diff -r e993f52f08a2 -r e6f95baec8b5 src/pixbuf_util.c --- a/src/pixbuf_util.c Tue Aug 14 21:28:02 2018 +0100 +++ b/src/pixbuf_util.c Wed Aug 15 19:43:06 2018 +0100 @@ -138,6 +138,7 @@ { PIXBUF_INLINE_ICON_SELECT_NONE, icon_select_none }, { PIXBUF_INLINE_ICON_SELECT_INVERT, icon_select_invert }, { PIXBUF_INLINE_ICON_SELECT_RECTANGLE, icon_select_rectangle }, + { PIXBUF_INLINE_ICON_FILE_FILTER, icon_file_filter }, { NULL, NULL } }; diff -r e993f52f08a2 -r e6f95baec8b5 src/pixbuf_util.h --- a/src/pixbuf_util.h Tue Aug 14 21:28:02 2018 +0100 +++ b/src/pixbuf_util.h Wed Aug 15 19:43:06 2018 +0100 @@ -72,6 +72,7 @@ #define PIXBUF_INLINE_ICON_SELECT_NONE "icon_select_none" #define PIXBUF_INLINE_ICON_SELECT_INVERT "icon_select_invert" #define PIXBUF_INLINE_ICON_SELECT_RECTANGLE "icon_select_rectangle" +#define PIXBUF_INLINE_ICON_FILE_FILTER "icon_file_filter" GdkPixbuf *pixbuf_copy_rotate_90(GdkPixbuf *src, gboolean counter_clockwise); GdkPixbuf *pixbuf_copy_mirror(GdkPixbuf *src, gboolean mirror, gboolean flip); diff -r e993f52f08a2 -r e6f95baec8b5 src/toolbar.c --- a/src/toolbar.c Tue Aug 14 21:28:02 2018 +0100 +++ b/src/toolbar.c Wed Aug 15 19:43:06 2018 +0100 @@ -94,6 +94,7 @@ {"SelectAll", N_("Select all"), PIXBUF_INLINE_ICON_SELECT_ALL}, {"SelectNone", N_("Select none"), PIXBUF_INLINE_ICON_SELECT_NONE}, {"SelectInvert", N_("Select invert"), PIXBUF_INLINE_ICON_SELECT_INVERT}, + {"ShowFileFilter", N_("Show file filter"), PIXBUF_INLINE_ICON_FILE_FILTER}, {"RectangularSelection", N_("Select rectangle"), PIXBUF_INLINE_ICON_SELECT_RECTANGLE}, {"Print", N_("Print"), GTK_STOCK_PRINT}, {"Preferences", N_("Preferences"), GTK_STOCK_PREFERENCES}, diff -r e993f52f08a2 -r e6f95baec8b5 src/typedefs.h --- a/src/typedefs.h Tue Aug 14 21:28:02 2018 +0100 +++ b/src/typedefs.h Wed Aug 15 19:43:06 2018 +0100 @@ -619,6 +619,7 @@ gboolean show_thumbnails; gboolean show_marks; + gboolean show_file_filter; gboolean show_directory_date; gboolean show_info_pixel; @@ -861,6 +862,8 @@ GtkWidget *scrolled; GtkWidget *filter; GtkWidget *filter_check[FILEDATA_MARKS_SIZE]; + GtkWidget *file_filter_combo; + GtkWidget *file_filter_frame; FileData *dir_fd; GList *list; diff -r e993f52f08a2 -r e6f95baec8b5 src/view_file.h --- a/src/view_file.h Tue Aug 14 21:28:02 2018 +0100 +++ b/src/view_file.h Wed Aug 15 19:43:06 2018 +0100 @@ -74,5 +74,7 @@ void vf_thumb_cleanup(ViewFile *vf); void vf_thumb_stop(ViewFile *vf); void vf_read_metadata_in_idle(ViewFile *vf); +void vf_file_filter_set(ViewFile *vf, gboolean enable); +GRegex *vf_file_filter_get_filter(ViewFile *vf); #endif /* VIEW_FILE_H */ /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ diff -r e993f52f08a2 -r e6f95baec8b5 src/view_file/view_file.c --- a/src/view_file/view_file.c Tue Aug 14 21:28:02 2018 +0100 +++ b/src/view_file/view_file.c Wed Aug 15 19:43:06 2018 +0100 @@ -25,6 +25,7 @@ #include "collect.h" #include "collect-table.h" #include "editors.h" +#include "history_list.h" #include "layout.h" #include "menu.h" #include "thumb.h" @@ -844,6 +845,35 @@ return FALSE; } +static void vf_file_filter_save_cb(GtkWidget *widget, gpointer data) +{ + ViewFile *vf = data; + gchar *entry_text; + + entry_text = g_strdup(gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(vf->file_filter_combo))))); + + history_list_add_to_key("file_filter", entry_text, 10); + + vf_refresh(vf); + + g_free(entry_text); +} + +static void vf_file_filter_cb(GtkWidget *widget, gpointer data) +{ + ViewFile *vf = data; + + vf_refresh(vf); +} + +static gboolean vf_file_filter_press_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data) +{ + ViewFile *vf = data; + + gtk_widget_grab_focus(widget); + + return TRUE; +} static GtkWidget *vf_marks_filter_init(ViewFile *vf) { @@ -870,6 +900,61 @@ return frame; } +void vf_file_filter_set(ViewFile *vf, gboolean enable) +{ + if (enable) + { + gtk_widget_show(vf->file_filter_combo); + gtk_widget_show(vf->file_filter_frame); + } + else + { + gtk_widget_hide(vf->file_filter_combo); + gtk_widget_hide(vf->file_filter_frame); + } + + vf_refresh(vf); +} + +static GtkWidget *vf_file_filter_init(ViewFile *vf) +{ + GtkWidget *frame = gtk_frame_new(NULL); + GtkWidget *hbox = gtk_hbox_new(FALSE, 0); + GList *work; + gint n = 0; + GtkWidget *combo_entry; + + vf->file_filter_combo = gtk_combo_box_text_new_with_entry(); + combo_entry = gtk_bin_get_child(GTK_BIN(vf->file_filter_combo)); + gtk_widget_show(gtk_bin_get_child(GTK_BIN(vf->file_filter_combo))); + gtk_widget_show((GTK_WIDGET(vf->file_filter_combo))); + + work = history_list_get_by_key("file_filter"); + while (work) + { + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(vf->file_filter_combo), (gchar *)work->data); + work = work->next; + n++; + } + gtk_combo_box_set_active(GTK_COMBO_BOX(vf->file_filter_combo), 0); + + g_signal_connect(G_OBJECT(combo_entry), "activate", + G_CALLBACK(vf_file_filter_save_cb), vf); + + g_signal_connect(G_OBJECT(vf->file_filter_combo), "changed", + G_CALLBACK(vf_file_filter_cb), vf); + + g_signal_connect(G_OBJECT(combo_entry), "button_press_event", + G_CALLBACK(vf_file_filter_press_cb), vf); + + gtk_box_pack_start(GTK_BOX(hbox), vf->file_filter_combo, FALSE, FALSE, 0); + gtk_widget_show(vf->file_filter_combo); + gtk_container_add(GTK_CONTAINER(frame), hbox); + gtk_widget_show(hbox); + + return frame; +} + void vf_mark_filter_toggle(ViewFile *vf, gint mark) { gint n = mark - 1; @@ -894,9 +979,11 @@ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); vf->filter = vf_marks_filter_init(vf); + vf->file_filter_frame = vf_file_filter_init(vf); vf->widget = gtk_vbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vf->widget), vf->filter, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(vf->widget), vf->file_filter_frame, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vf->widget), vf->scrolled, TRUE, TRUE, 0); gtk_widget_show(vf->scrolled); @@ -1171,6 +1258,39 @@ return ret; } +GRegex *vf_file_filter_get_filter(ViewFile *vf) +{ + GRegex *ret = NULL; + GError *error = NULL; + gchar *file_filter_text = NULL; + + if (!gtk_widget_get_visible(vf->file_filter_combo)) + { + return g_regex_new("", 0, 0, NULL); + } + + file_filter_text = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(vf->file_filter_combo)); + + if (file_filter_text[0] != '\0') + { + ret = g_regex_new(file_filter_text, 0, 0, &error); + if (error) + { + log_printf("Error: could not compile regular expression %s\n%s\n", file_filter_text, error->message); + g_error_free(error); + error = NULL; + ret = g_regex_new("", 0, 0, NULL); + } + g_free(file_filter_text); + } + else + { + ret = g_regex_new("", 0, 0, NULL); + } + + return ret; +} + void vf_set_layout(ViewFile *vf, LayoutWindow *layout) { vf->layout = layout; diff -r e993f52f08a2 -r e6f95baec8b5 src/view_file/view_file_icon.c --- a/src/view_file/view_file_icon.c Tue Aug 14 21:28:02 2018 +0100 +++ b/src/view_file/view_file_icon.c Wed Aug 15 19:43:06 2018 +0100 @@ -1842,6 +1842,8 @@ { ret = filelist_read(vf->dir_fd, &new_filelist, NULL); new_filelist = file_data_filter_marks_list(new_filelist, vf_marks_get_filter(vf)); + new_filelist = g_list_first(new_filelist); + new_filelist = file_data_filter_file_filter_list(new_filelist, vf_file_filter_get_filter(vf)); } vf->list = filelist_sort(vf->list, vf->sort_method, vf->sort_ascend); /* the list might not be sorted if there were renames */ diff -r e993f52f08a2 -r e6f95baec8b5 src/view_file/view_file_list.c --- a/src/view_file/view_file_list.c Tue Aug 14 21:28:02 2018 +0100 +++ b/src/view_file/view_file_list.c Wed Aug 15 19:43:06 2018 +0100 @@ -1801,6 +1801,8 @@ } vf->list = file_data_filter_marks_list(vf->list, vf_marks_get_filter(vf)); + vf->list = g_list_first(vf->list); + vf->list = file_data_filter_file_filter_list(vf->list, vf_file_filter_get_filter(vf)); file_data_register_notify_func(vf_notify_cb, vf, NOTIFY_PRIORITY_MEDIUM); DEBUG_1("%s vflist_refresh: sort", get_exec_time()); diff -r e993f52f08a2 -r e6f95baec8b5 web/help/GuideMainWindowFilePane.html --- a/web/help/GuideMainWindowFilePane.html Tue Aug 14 21:28:02 2018 +0100 +++ b/web/help/GuideMainWindowFilePane.html Wed Aug 15 19:43:06 2018 +0100 @@ -468,16 +468,19 @@ 2.1.2. Icon view
  • -2.1.3. Multiple selection +2.1.3. File Filter +
  • +
  • +2.1.4. Multiple selection
  • -2.1.4. Sorting +2.1.5. Sorting
  • -2.1.5. Context menu +2.1.6. Context menu
  • -2.1.6. Drag and Drop +2.1.7. Drag and Drop
  • @@ -530,19 +533,39 @@

    -

    2.1.3. Multiple selection

    +

    2.1.3. File Filter

    +

    + A filter box can be opened by selecting + Show File Filter + from the View menu. +

    +

    + Characters you type into this box will be used for pattern matching to select the files displayed. + Regular expressions + are used in this field. +

    + For basic pattern matching "JPG" will match any filename containing those characters. +

    + To make a case-insensitive search, use "(?i)JPG" +

    + If you type a newline, the text will be saved in the dropdown box list. The last 10 items are saved. +

    +

    +
    +
    +

    2.1.4. Multiple selection

    It is possible to select more than one image from the file pane. Multiple files can be selected with several methods:

    -

    2.1.3.1. Mouse

    +

    2.1.4.1. Mouse

    • Ctrl + Primary mouse button will add or remove the file from the selection. @@ -560,7 +583,7 @@

    -

    2.1.3.2. Keyboard

    +

    2.1.4.2. Keyboard

    • Ctrl + Arrows will move the focus without changing the selection. @@ -593,13 +616,13 @@
    -

    2.1.4. Sorting

    +

    2.1.5. Sorting

    The order of the images can be changed by clicking the sort area of the status bar or from the context menu. The sort methods are by file name, number, file date, or file size. The number method will sort file names by their natural order, for example files with names of file_10, file_12, and file_9 will appear in order file_9, file_10, and file_12.

    Selecting the ascending menu item will toggle between increasing and decreasing sort order.

    -

    2.1.5. Context menu

    +

    2.1.6. Context menu

    Right clicking the mouse or pressing the menu key while the file pane has focus will display a menu. The menu functions will perform the same as those that match the window's menu bar @@ -646,7 +669,7 @@

    -

    2.1.6. Drag and Drop

    +

    2.1.7. Drag and Drop

    Drag and drop can be initialized with the primary or middle mouse buttons in the file pane. Dragging a file that is selected will include all selected files in the drag. Dragging a file that is not selected will first change the selection to the dragged file, and clear the previous selection.