From c83c3f705277242bf287961310d8808af9916b51 Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Fri, 11 May 2012 13:06:38 +0400 Subject: [PATCH] Ticket #2814: handle CK_FileNext/CK_FilePrev inside mcviewer. Signed-off-by: Andrew Borodin --- src/viewer/actions_cmd.c | 111 +++++++++++++++++++++++++++++++++++++++++++++-- src/viewer/internal.h | 8 ++++ src/viewer/lib.c | 27 +++++++++++- 3 files changed, 142 insertions(+), 4 deletions(-) diff --git a/src/viewer/actions_cmd.c b/src/viewer/actions_cmd.c index ac28fa5d0..5401a9c18 100644 --- a/src/viewer/actions_cmd.c +++ b/src/viewer/actions_cmd.c @@ -242,6 +242,112 @@ mcview_handle_editkey (mcview_t * view, int key) /* --------------------------------------------------------------------------------------------- */ +static void +mcview_load_next_prev_init (mcview_t * view) +{ + if (mc_global.mc_run_mode != MC_RUN_VIEWER) + { + /* get file list from current panel. Update it each time */ + view->dir = ¤t_panel->dir; + view->dir_count = ¤t_panel->count; + view->dir_idx = ¤t_panel->selected; + } + else if (view->dir == NULL) + { + /* Run from command line */ + /* Run 1st time. Load/get directory */ + + /* TODO: check mtime of directory to reload it */ + + char *full_fname; + const char *fname; + size_t fname_len; + int i; + + /* load directory where requested file is */ + view->dir = g_new0 (dir_list, 1); + view->dir_count = g_new (int, 1); + view->dir_idx = g_new (int, 1); + + *view->dir_count = do_load_dir (view->workdir_vpath, view->dir, (sortfn *) sort_name, FALSE, + TRUE, FALSE, NULL); + + full_fname = vfs_path_to_str (view->filename_vpath); + fname = x_basename (full_fname); + fname_len = strlen (fname); + + /* search current file in the list */ + for (i = 0; i != *view->dir_count; i++) + { + const file_entry *fe = &view->dir->list[i]; + + if (fname_len == fe->fnamelen && strncmp (fname, fe->fname, fname_len) == 0) + break; + } + + g_free (full_fname); + + *view->dir_idx = i; + } +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +mcview_scan_for_file (mcview_t * view, int direction) +{ + int i; + + for (i = *view->dir_idx + direction; i != *view->dir_idx; i += direction) + { + if (i < 0) + i = *view->dir_count - 1; + if (i == *view->dir_count) + i = 0; + if (!S_ISDIR (view->dir->list[i].st.st_mode)) + break; + } + + *view->dir_idx = i; +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +mcview_load_next_prev (mcview_t * view, int direction) +{ + dir_list *dir; + int *dir_count, *dir_idx; + vfs_path_t *vfile; + char *file; + + mcview_load_next_prev_init (view); + mcview_scan_for_file (view, direction); + + /* reinit view */ + dir = view->dir; + dir_count = view->dir_count; + dir_idx = view->dir_idx; + view->dir = NULL; + view->dir_count = NULL; + view->dir_idx = NULL; + vfile = vfs_path_append_new (view->workdir_vpath, dir->list[*dir_idx].fname, (char *) NULL); + file = vfs_path_to_str (vfile); + vfs_path_free (vfile); + mcview_done (view); + mcview_init (view); + mcview_load (view, NULL, file, 0); + g_free (file); + view->dir = dir; + view->dir_count = dir_count; + view->dir_idx = dir_idx; + + view->dpy_bbar_dirty = FALSE; /* FIXME */ + view->dirty++; +} + +/* --------------------------------------------------------------------------------------------- */ + static cb_ret_t mcview_execute_cmd (mcview_t * view, unsigned long command) { @@ -383,11 +489,10 @@ mcview_execute_cmd (mcview_t * view, unsigned long command) #endif case CK_FileNext: case CK_FilePrev: - /* Use to indicate parent that we want to see the next/previous file */ /* Does not work in panel mode */ if (!mcview_is_in_panel (view)) - view->move_dir = (command == CK_FileNext) ? 1 : -1; - /* fallthrough */ + mcview_load_next_prev (view, command == CK_FileNext ? 1 : -1); + break; case CK_Quit: if (!mcview_is_in_panel (view)) dlg_stop (view->widget.owner); diff --git a/src/viewer/internal.h b/src/viewer/internal.h index 056ff46f8..c044bc8f2 100644 --- a/src/viewer/internal.h +++ b/src/viewer/internal.h @@ -12,6 +12,7 @@ #include "lib/vfs/vfs.h" /* vfs_path_t */ #include "src/keybind-defaults.h" /* global_keymap_t */ +#include "src/filemanager/dir.h" /* dir_list */ /*** typedefs(not structures) and defined constants **********************************************/ @@ -184,6 +185,13 @@ typedef struct mcview_struct int search_numNeedSkipChar; GArray *saved_bookmarks; + + dir_list *dir; /* List of current directory files + * to handle CK_FileNext and CK_FilePrev commands */ + int *dir_count; /* Number of files in dir structure. + * Pointer is used here as reference to WPanel::count */ + int *dir_idx; /* Index of current file in dir structure. + * Pointer is used here as reference to WPanel::count */ } mcview_t; typedef struct mcview_nroff_struct diff --git a/src/viewer/lib.c b/src/viewer/lib.c index 3cddb52a9..257e2bcc4 100644 --- a/src/viewer/lib.c +++ b/src/viewer/lib.c @@ -75,17 +75,30 @@ void mcview_toggle_magic_mode (mcview_t * view) { char *filename, *command; + dir_list *dir; + int *dir_count, *dir_idx; mcview_altered_magic_flag = 1; view->magic_mode = !view->magic_mode; + + /* reinit view */ filename = vfs_path_to_str (view->filename_vpath); command = g_strdup (view->command); - + dir = view->dir; + dir_count = view->dir_count; + dir_idx = view->dir_idx; + view->dir = NULL; + view->dir_count = NULL; + view->dir_idx = NULL; mcview_done (view); mcview_init (view); mcview_load (view, command, filename, 0); + view->dir = dir; + view->dir_count = dir_count; + view->dir_idx = dir_idx; g_free (filename); g_free (command); + view->dpy_bbar_dirty = TRUE; view->dirty++; } @@ -276,6 +289,18 @@ mcview_done (mcview_t * view) view->last_search_string = NULL; mcview_nroff_seq_free (&view->search_nroff_seq); mcview_hexedit_free_change_list (view); + + if (mc_global.mc_run_mode == MC_RUN_VIEWER && view->dir != NULL) + { + /* mcviewer is the owner of file list */ + clean_dir (view->dir, *view->dir_count); + g_free (view->dir->list); + g_free (view->dir_count); + g_free (view->dir_idx); + g_free (view->dir); + } + + view->dir = NULL; } /* --------------------------------------------------------------------------------------------- */ -- 2.11.4.GIT