summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2016-06-02 13:45:00 +0200
committerDaniel Friesel <derf@finalrewind.org>2016-06-02 13:45:00 +0200
commit09c59148f8cdc1cb1cb83cb63f6edacec617a446 (patch)
tree36e759b0bd5d94fa4ef8817a746f43b6e6e9d5c4
parent315bac4637537654b4711867911458c3a6974c7e (diff)
parent36b09fa038a8b7996a12e45419c28821c5596308 (diff)
Merge branch 'guns-dirnav'
-rw-r--r--man/feh.pre14
-rw-r--r--src/feh.h4
-rw-r--r--src/filelist.c28
-rw-r--r--src/filelist.h14
-rw-r--r--src/keyevents.c14
-rw-r--r--src/menu.c57
-rw-r--r--src/options.c2
-rw-r--r--src/options.h2
-rw-r--r--src/slideshow.c38
9 files changed, 157 insertions, 16 deletions
diff --git a/man/feh.pre b/man/feh.pre
index 9d652b9..dfa5cae 100644
--- a/man/feh.pre
+++ b/man/feh.pre
@@ -600,10 +600,10 @@ in paused mode.
.
.It Cm -S , --sort Ar sort_type
.
-The file list may be sorted according to image parameters. Allowed sort
-types are: name, filename, mtime, width, height, pixels, size, format. For sort
-modes other than name, filename, or mtime, a preload run will be necessary,
-causing a delay proportional to the number of images in the list.
+The file list may be sorted according to image parameters. Allowed sort types
+are: name, filename, dirname, mtime, width, height, pixels, size, format. For
+sort modes other than name, filename, dirname, or mtime, a preload run will be
+necessary, causing a delay proportional to the number of images in the list.
.
.Pp
.
@@ -1284,6 +1284,12 @@ Close current window
.
Jump to a random position in the current filelist
.
+.It \&[, \&] Bq prev_dir, next_dir
+.
+Jump to the first image of the previous or next sequence of images sharing
+a directory name in the current filelist. Use --sort dirname if you would
+like to ensure that all images in a directory are grouped together.
+.
.It < , > Bq orient_3 , orient_1
.
In place editing - rotate the images 90 degrees (counter)clockwise.
diff --git a/src/feh.h b/src/feh.h
index a2a586a..73ef1f6 100644
--- a/src/feh.h
+++ b/src/feh.h
@@ -102,7 +102,9 @@ enum text_bg { TEXT_BG_CLEAR = 0, TEXT_BG_TINTED };
enum slide_change { SLIDE_NEXT, SLIDE_PREV, SLIDE_RAND, SLIDE_FIRST, SLIDE_LAST,
SLIDE_JUMP_FWD,
- SLIDE_JUMP_BACK
+ SLIDE_JUMP_BACK,
+ SLIDE_JUMP_NEXT_DIR,
+ SLIDE_JUMP_PREV_DIR
};
enum image_bg { IMAGE_BG_CHECKS = 1, IMAGE_BG_BLACK, IMAGE_BG_WHITE };
diff --git a/src/filelist.c b/src/filelist.c
index 7e9dcbe..8956238 100644
--- a/src/filelist.c
+++ b/src/filelist.c
@@ -383,6 +383,20 @@ int feh_file_info_load(feh_file * file, Imlib_Image im)
return(0);
}
+void feh_file_dirname(char *dst, feh_file * f, int maxlen)
+{
+ int n = strlen(f->filename) - strlen(f->name);
+
+ /* Give up on long dirnames */
+ if (n <= 0 || n >= maxlen) {
+ dst[0] = '\0';
+ return;
+ }
+
+ strncpy(dst, f->filename, n);
+ dst[n] = '\0';
+}
+
int feh_cmp_filename(void *file1, void *file2)
{
return(strcmp(FEH_FILE(file1)->filename, FEH_FILE(file2)->filename));
@@ -393,6 +407,17 @@ int feh_cmp_name(void *file1, void *file2)
return(strcmp(FEH_FILE(file1)->name, FEH_FILE(file2)->name));
}
+int feh_cmp_dirname(void *file1, void *file2)
+{
+ char dir1[FEH_MAX_DIRNAME_LEN], dir2[FEH_MAX_DIRNAME_LEN];
+ int cmp;
+ feh_file_dirname(dir1, FEH_FILE(file1), FEH_MAX_DIRNAME_LEN);
+ feh_file_dirname(dir2, FEH_FILE(file2), FEH_MAX_DIRNAME_LEN);
+ if ((cmp = strcmp(dir1, dir2)) != 0)
+ return(cmp);
+ return(feh_cmp_name(file1, file2));
+}
+
/* Return -1 if file1 is _newer_ than file2 */
int feh_cmp_mtime(void *file1, void *file2)
{
@@ -465,6 +490,9 @@ void feh_prepare_filelist(void)
case SORT_FILENAME:
filelist = gib_list_sort(filelist, feh_cmp_filename);
break;
+ case SORT_DIRNAME:
+ filelist = gib_list_sort(filelist, feh_cmp_dirname);
+ break;
case SORT_MTIME:
filelist = gib_list_sort(filelist, feh_cmp_mtime);
break;
diff --git a/src/filelist.h b/src/filelist.h
index 7bfd518..79d1e62 100644
--- a/src/filelist.h
+++ b/src/filelist.h
@@ -53,13 +53,21 @@ struct __feh_file_info {
};
#define FEH_FILE(l) ((feh_file *) l)
+#define FEH_MAX_DIRNAME_LEN 4096
enum filelist_recurse { FILELIST_FIRST, FILELIST_CONTINUE, FILELIST_LAST };
-enum sort_type { SORT_NONE, SORT_NAME, SORT_FILENAME, SORT_MTIME, SORT_WIDTH,
+enum sort_type {
+ SORT_NONE,
+ SORT_NAME,
+ SORT_FILENAME,
+ SORT_DIRNAME,
+ SORT_MTIME,
+ SORT_WIDTH,
SORT_HEIGHT,
SORT_PIXELS,
- SORT_SIZE, SORT_FORMAT
+ SORT_SIZE,
+ SORT_FORMAT
};
feh_file *feh_file_new(char *filename);
@@ -73,6 +81,7 @@ void add_file_to_rm_filelist(char *file);
void delete_rm_files(void);
gib_list *feh_file_info_preload(gib_list * list);
int feh_file_info_load(feh_file * file, Imlib_Image im);
+void feh_file_dirname(char *dst, feh_file * f, int maxlen);
void feh_prepare_filelist(void);
int feh_write_filelist(gib_list * list, char *filename);
gib_list *feh_read_filelist(char *filename);
@@ -81,6 +90,7 @@ gib_list *feh_file_remove_from_list(gib_list * list, gib_list * l);
void feh_save_filelist();
int feh_cmp_name(void *file1, void *file2);
+int feh_cmp_dirname(void *file1, void *file2);
int feh_cmp_filename(void *file1, void *file2);
int feh_cmp_mtime(void *file1, void *file2);
int feh_cmp_width(void *file1, void *file2);
diff --git a/src/keyevents.c b/src/keyevents.c
index 8977111..4837c0b 100644
--- a/src/keyevents.c
+++ b/src/keyevents.c
@@ -110,6 +110,8 @@ void init_keyevents(void) {
feh_set_kb(&keys.next_img , 0, XK_Right , 0, XK_n , 0, XK_space);
feh_set_kb(&keys.jump_back , 0, XK_Page_Up , 0, XK_KP_Page_Up, 0, 0);
feh_set_kb(&keys.jump_fwd , 0, XK_Page_Down , 0, XK_KP_Page_Down,0,0);
+ feh_set_kb(&keys.prev_dir , 0, XK_bracketleft, 0, 0 , 0, 0);
+ feh_set_kb(&keys.next_dir , 0, XK_bracketright, 0, 0 , 0, 0);
feh_set_kb(&keys.jump_random,0, XK_z , 0, 0 , 0, 0);
feh_set_kb(&keys.quit , 0, XK_Escape , 0, XK_q , 0, 0);
feh_set_kb(&keys.close , 0, XK_x , 0, 0 , 0, 0);
@@ -222,6 +224,10 @@ void init_keyevents(void) {
cur_kb = &keys.jump_back;
else if (!strcmp(action, "jump_fwd"))
cur_kb = &keys.jump_fwd;
+ else if (!strcmp(action, "prev_dir"))
+ cur_kb = &keys.prev_dir;
+ else if (!strcmp(action, "next_dir"))
+ cur_kb = &keys.next_dir;
else if (!strcmp(action, "jump_random"))
cur_kb = &keys.jump_random;
else if (!strcmp(action, "quit"))
@@ -532,6 +538,14 @@ void feh_event_handle_keypress(XEvent * ev)
else if (winwid->type == WIN_TYPE_THUMBNAIL)
feh_thumbnail_select_next(winwid, 10);
}
+ else if (feh_is_kp(&keys.next_dir, keysym, state)) {
+ if (opt.slideshow)
+ slideshow_change_image(winwid, SLIDE_JUMP_NEXT_DIR, 1);
+ }
+ else if (feh_is_kp(&keys.prev_dir, keysym, state)) {
+ if (opt.slideshow)
+ slideshow_change_image(winwid, SLIDE_JUMP_PREV_DIR, 1);
+ }
else if (feh_is_kp(&keys.quit, keysym, state)) {
winwidget_destroy_all();
}
diff --git a/src/menu.c b/src/menu.c
index 9a83f08..ddb2db1 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -49,14 +49,39 @@ void feh_menu_cb(feh_menu * m, feh_menu_item * i, int action, unsigned short dat
void feh_menu_cb_opt_fullscreen(feh_menu * m, feh_menu_item * i);
enum {
- CB_CLOSE = 1, CB_EXIT, CB_RELOAD, CB_REMOVE, CB_DELETE, CB_RESET,
- CB_REMOVE_THUMB, CB_DELETE_THUMB, CB_BG_TILED, CB_BG_SCALED,
- CB_BG_CENTERED, CB_BG_FILLED, CB_BG_TILED_NOFILE,
- CB_BG_SCALED_NOFILE, CB_BG_CENTERED_NOFILE, CB_BG_FILLED_NOFILE,
- CB_SORT_FILENAME, CB_SORT_IMAGENAME, CB_SORT_FILESIZE, CB_SORT_RANDOMIZE,
- CB_SAVE_IMAGE, CB_SAVE_FILELIST, CB_FIT, CB_OPT_DRAW_FILENAME,
- CB_OPT_DRAW_ACTIONS, CB_OPT_KEEP_HTTP, CB_OPT_FREEZE_WINDOW,
- CB_OPT_FULLSCREEN, CB_EDIT_ROTATE, CB_OPT_AUTO_ZOOM, CB_OPT_KEEP_ZOOM_VP
+ CB_CLOSE = 1,
+ CB_EXIT,
+ CB_RELOAD,
+ CB_REMOVE,
+ CB_DELETE,
+ CB_RESET,
+ CB_REMOVE_THUMB,
+ CB_DELETE_THUMB,
+ CB_BG_TILED,
+ CB_BG_SCALED,
+ CB_BG_CENTERED,
+ CB_BG_FILLED,
+ CB_BG_TILED_NOFILE,
+ CB_BG_SCALED_NOFILE,
+ CB_BG_CENTERED_NOFILE,
+ CB_BG_FILLED_NOFILE,
+ CB_SORT_FILENAME,
+ CB_SORT_IMAGENAME,
+ CB_SORT_DIRNAME,
+ CB_SORT_MTIME,
+ CB_SORT_FILESIZE,
+ CB_SORT_RANDOMIZE,
+ CB_SAVE_IMAGE,
+ CB_SAVE_FILELIST,
+ CB_FIT,
+ CB_OPT_DRAW_FILENAME,
+ CB_OPT_DRAW_ACTIONS,
+ CB_OPT_KEEP_HTTP,
+ CB_OPT_FREEZE_WINDOW,
+ CB_OPT_FULLSCREEN,
+ CB_EDIT_ROTATE,
+ CB_OPT_AUTO_ZOOM,
+ CB_OPT_KEEP_ZOOM_VP
};
feh_menu *feh_menu_new(void)
@@ -923,7 +948,9 @@ void feh_menu_init_common()
feh_menu_add_entry(m, "By File Name", NULL, CB_SORT_FILENAME, 0, NULL);
feh_menu_add_entry(m, "By Image Name", NULL, CB_SORT_IMAGENAME, 0, NULL);
- if (opt.preload || (opt.sort > SORT_FILENAME))
+ feh_menu_add_entry(m, "By Directory Name", NULL, CB_SORT_DIRNAME, 0, NULL);
+ feh_menu_add_entry(m, "By Modification Date", NULL, CB_SORT_MTIME, 0, NULL);
+ if (opt.preload || (opt.sort > SORT_MTIME))
feh_menu_add_entry(m, "By File Size", NULL, CB_SORT_FILESIZE, 0, NULL);
feh_menu_add_entry(m, "Randomize", NULL, CB_SORT_RANDOMIZE, 0, NULL);
@@ -1252,6 +1279,18 @@ void feh_menu_cb(feh_menu * m, feh_menu_item * i, int action, unsigned short dat
slideshow_change_image(m->fehwin, SLIDE_FIRST, 1);
}
break;
+ case CB_SORT_DIRNAME:
+ filelist = gib_list_sort(filelist, feh_cmp_dirname);
+ if (opt.jump_on_resort) {
+ slideshow_change_image(m->fehwin, SLIDE_FIRST, 1);
+ }
+ break;
+ case CB_SORT_MTIME:
+ filelist = gib_list_sort(filelist, feh_cmp_mtime);
+ if (opt.jump_on_resort) {
+ slideshow_change_image(m->fehwin, SLIDE_FIRST, 1);
+ }
+ break;
case CB_SORT_FILESIZE:
filelist = gib_list_sort(filelist, feh_cmp_size);
if (opt.jump_on_resort) {
diff --git a/src/options.c b/src/options.c
index b43db91..9e2ff5a 100644
--- a/src/options.c
+++ b/src/options.c
@@ -514,6 +514,8 @@ static void feh_parse_option_array(int argc, char **argv, int finalrun)
opt.sort = SORT_NAME;
else if (!strcasecmp(optarg, "filename"))
opt.sort = SORT_FILENAME;
+ else if (!strcasecmp(optarg, "dirname"))
+ opt.sort = SORT_DIRNAME;
else if (!strcasecmp(optarg, "mtime"))
opt.sort = SORT_MTIME;
else if (!strcasecmp(optarg, "width"))
diff --git a/src/options.h b/src/options.h
index 0052d5d..bbf129f 100644
--- a/src/options.h
+++ b/src/options.h
@@ -153,6 +153,8 @@ struct __fehkb {
struct __fehkey jump_back;
struct __fehkey quit;
struct __fehkey jump_fwd;
+ struct __fehkey prev_dir;
+ struct __fehkey next_dir;
struct __fehkey remove;
struct __fehkey delete;
struct __fehkey jump_first;
diff --git a/src/slideshow.c b/src/slideshow.c
index 7636d31..2af78c9 100644
--- a/src/slideshow.c
+++ b/src/slideshow.c
@@ -322,6 +322,44 @@ void slideshow_change_image(winwidget winwid, int change, int render)
try the previous file, not another jmp */
change = SLIDE_NEXT;
break;
+ case SLIDE_JUMP_NEXT_DIR:
+ {
+ char old_dir[FEH_MAX_DIRNAME_LEN], new_dir[FEH_MAX_DIRNAME_LEN];
+ int j;
+
+ feh_file_dirname(old_dir, FEH_FILE(current_file->data), FEH_MAX_DIRNAME_LEN);
+
+ for (j = 0; j < our_filelist_len; j++) {
+ current_file = feh_list_jump(filelist, current_file, FORWARD, 1);
+ feh_file_dirname(new_dir, FEH_FILE(current_file->data), FEH_MAX_DIRNAME_LEN);
+ if (strcmp(old_dir, new_dir) != 0)
+ break;
+ }
+ }
+ change = SLIDE_NEXT;
+ break;
+ case SLIDE_JUMP_PREV_DIR:
+ {
+ char old_dir[FEH_MAX_DIRNAME_LEN], new_dir[FEH_MAX_DIRNAME_LEN];
+ int j;
+
+ /* Start the search from the previous file in case we are on
+ the first file of a directory */
+ current_file = feh_list_jump(filelist, current_file, BACK, 1);
+ feh_file_dirname(old_dir, FEH_FILE(current_file->data), FEH_MAX_DIRNAME_LEN);
+
+ for (j = 0; j < our_filelist_len; j++) {
+ current_file = feh_list_jump(filelist, current_file, BACK, 1);
+ feh_file_dirname(new_dir, FEH_FILE(current_file->data), FEH_MAX_DIRNAME_LEN);
+ if (strcmp(old_dir, new_dir) != 0)
+ break;
+ }
+
+ /* Next file is the first entry of prev_dir */
+ current_file = feh_list_jump(filelist, current_file, FORWARD, 1);
+ }
+ change = SLIDE_NEXT;
+ break;
default:
eprintf("BUG!\n");
break;