Ticket #2814: handle CK_FileNext/CK_FilePrev inside mcviewer.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
Andrew Borodin 2012-05-11 13:06:38 +04:00
parent 50f8b5bf58
commit c83c3f7052
3 changed files with 142 additions and 4 deletions

View File

@ -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 = &current_panel->dir;
view->dir_count = &current_panel->count;
view->dir_idx = &current_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);

View File

@ -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

View File

@ -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;
}
/* --------------------------------------------------------------------------------------------- */