From 5c252726f1b52863a75b0118603a0e053923eded Mon Sep 17 00:00:00 2001 From: Ilia Maslakov Date: Sat, 30 Jul 2011 19:32:46 +0000 Subject: [PATCH] Ticket #275 (panelize enhancement) added ".." at the top of file list (after external panelization) added ".." at the top of file list (after 'find' panelization) disable ctrl-r (refresh) for panelized content added menu entry Left\Panelize, to restore panelized panel Signed-off-by: Ilia Maslakov Minor changes in goto_parent_dir() many code optimization Signed-off-by: Andrew Borodin little fixup Signed-off-by: Ilia Maslakov --- lib/keybind.h | 1 + src/filemanager/cmd.c | 10 ++--- src/filemanager/find.c | 5 +++ src/filemanager/midnight.c | 9 ++++- src/filemanager/panel.c | 36 ++++++++++++++++-- src/filemanager/panel.h | 9 +++++ src/filemanager/panelize.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++ src/filemanager/panelize.h | 2 + src/main.c | 7 +++- 9 files changed, 159 insertions(+), 11 deletions(-) diff --git a/lib/keybind.h b/lib/keybind.h index 42fb04daf..33b8cfe91 100644 --- a/lib/keybind.h +++ b/lib/keybind.h @@ -178,6 +178,7 @@ enum /* panels */ CK_PanelOtherCd = 200, CK_PanelOtherCdLink, + CK_Panelize, CK_CopySingle, CK_MoveSingle, CK_DeleteSingle, diff --git a/src/filemanager/cmd.c b/src/filemanager/cmd.c index d9bd66591..e0da422dc 100644 --- a/src/filemanager/cmd.c +++ b/src/filemanager/cmd.c @@ -995,13 +995,13 @@ filter_cmd (void) void reread_cmd (void) { - panel_update_flags_t flag = UP_ONLY_CURRENT; + panel_update_flags_t flag = UP_OPTIMIZE; - if (get_current_type () == view_listing && get_other_type () == view_listing - && strcmp (current_panel->cwd, other_panel->cwd) == 0) - flag = UP_OPTIMIZE; + if (!current_panel->is_panelized && get_current_type () == view_listing && + get_other_type () == view_listing && strcmp (current_panel->cwd, other_panel->cwd) == 0) + flag |= UP_RELOAD | UP_ONLY_CURRENT; - update_panels (UP_RELOAD | flag, UP_KEEPSEL); + update_panels (flag, UP_KEEPSEL); repaint_screen (); } diff --git a/src/filemanager/find.c b/src/filemanager/find.c index 2634f5115..60ffca917 100644 --- a/src/filemanager/find.c +++ b/src/filemanager/find.c @@ -57,6 +57,7 @@ #include "cmd.h" /* view_file_at_line */ #include "midnight.h" /* current_panel */ #include "boxes.h" +#include "panelize.h" #include "find.h" @@ -1612,6 +1613,9 @@ do_find (const char *start_dir, ssize_t start_dir_len, const char *ignore_dirs, dir_list *list = ¤t_panel->dir; char *name = NULL; + if (set_zero_dir (list)) + next_free++; + for (i = 0, entry = find_list->list; entry != NULL; i++, entry = g_list_next (entry)) { const char *lc_filename = NULL; @@ -1687,6 +1691,7 @@ do_find (const char *start_dir, ssize_t start_dir_len, const char *ignore_dirs, strcpy (current_panel->cwd, PATH_SEP_STR); ret = chdir (PATH_SEP_STR); } + panelize_save_panel (current_panel); } } diff --git a/src/filemanager/midnight.c b/src/filemanager/midnight.c index 48eca29f1..c92fe539b 100644 --- a/src/filemanager/midnight.c +++ b/src/filemanager/midnight.c @@ -70,6 +70,7 @@ #include "hotlist.h" #include "panelize.h" #include "command.h" /* cmdline */ +#include "dir.h" /* clean_dir() */ #include "chmod.h" #include "chown.h" @@ -200,7 +201,6 @@ create_panel_menu (void) #ifdef HAVE_CHARSET entries = g_list_append (entries, menu_entry_create (_("&Encoding..."), CK_SelectCodepage)); #endif -#ifdef ENABLE_VFS_NET entries = g_list_append (entries, menu_separator_create ()); #ifdef ENABLE_VFS_FTP entries = g_list_append (entries, menu_entry_create (_("FT&P link..."), CK_ConnectFtp)); @@ -211,7 +211,7 @@ create_panel_menu (void) #ifdef ENABLE_VFS_SMB entries = g_list_append (entries, menu_entry_create (_("SM&B link..."), CK_ConnectSmb)); #endif -#endif /* ENABLE_VFS_NET */ + entries = g_list_append (entries, menu_entry_create (_("Panelize"), CK_Panelize)); entries = g_list_append (entries, menu_separator_create ()); entries = g_list_append (entries, menu_entry_create (_("&Rescan"), CK_Reread)); @@ -1167,6 +1167,9 @@ midnight_execute_cmd (Widget * sender, unsigned long command) smblink_cmd (); break; #endif /* ENABLE_VFS_SMB */ + case CK_Panelize: + cd_panelize_cmd (); + break; case CK_Help: help_cmd (); break; @@ -1661,6 +1664,8 @@ do_nc (void) /* don't handle VFS timestamps for dirs opened in panels */ mc_event_destroy (MCEVENT_GROUP_CORE, "vfs_timestamp"); + + clean_dir (&panelized_panel.list, panelized_panel.count); } /* Program end */ diff --git a/src/filemanager/panel.c b/src/filemanager/panel.c index 45d9f6222..15895ae6c 100644 --- a/src/filemanager/panel.c +++ b/src/filemanager/panel.c @@ -80,6 +80,8 @@ /* The hook list for the select file function */ hook_t *select_file_hook = NULL; +panelized_panel_t panelized_panel = { {NULL, 0}, -1, {'\0'} }; + static const char *string_file_name (file_entry *, int); static const char *string_file_size (file_entry *, int); static const char *string_file_size_brief (file_entry *, int); @@ -799,6 +801,7 @@ format_file (char *dest, int limit, WPanel * panel, int file_index, int width, i tty_lowlevel_setcolor (-color); preperad_text = (char *) str_fit_to_term (txt, len, format->just_mode); + if (perm) add_permission_string (preperad_text, format->field_len, fe, attr, color, perm - 1); else @@ -1097,7 +1100,10 @@ show_dir (WPanel * panel) widget_move (&panel->widget, 0, 3); - tty_printf (" %s ", + if (panel->is_panelized) + tty_printf (" %s ", _("Panelize")); + else + tty_printf (" %s ", str_term_trim (strip_home_and_password (panel->cwd), min (max (panel->widget.cols - 12, 0), panel->widget.cols))); @@ -1895,8 +1901,32 @@ prev_page (WPanel * panel) static void goto_parent_dir (WPanel * panel) { - (void) panel; - do_cd ("..", cd_exact); + if (!panel->is_panelized) + do_cd ("..", cd_exact); + else + { + char *fname = panel->dir.list[panel->selected].fname; + const char *bname; + char *dname; + + if (g_path_is_absolute (fname)) + fname = g_strdup (fname); + else + fname = mc_build_filename (panelized_panel.root, fname, (char *) NULL); + + bname = x_basename (fname); + + if (bname == fname) + dname = g_strdup ("."); + else + dname = g_strndup (fname, bname - fname); + + do_cd (dname, cd_exact); + try_to_select (panel, bname); + + g_free (dname); + g_free (fname); + } } /* --------------------------------------------------------------------------------------------- */ diff --git a/src/filemanager/panel.h b/src/filemanager/panel.h index 93d00c2d0..7e8e3c9c7 100644 --- a/src/filemanager/panel.h +++ b/src/filemanager/panel.h @@ -75,6 +75,13 @@ typedef struct panel_field_struct sortfn *sort_routine; /* used by mouse_sort_col() */ } panel_field_t; +typedef struct +{ + dir_list list; + int count; + char root[MC_MAXPATHLEN]; +} panelized_panel_t; + typedef struct panel_sort_info_struct { gboolean reverse; /* Show listing in reverse? */ @@ -131,6 +138,8 @@ typedef struct WPanel /*** global variables defined in .c file *********************************************************/ +extern panelized_panel_t panelized_panel; + extern panel_field_t panel_fields[]; extern hook_t *select_file_hook; diff --git a/src/filemanager/panelize.c b/src/filemanager/panelize.c index 5b52ff495..48ecc2a00 100644 --- a/src/filemanager/panelize.c +++ b/src/filemanager/panelize.c @@ -337,6 +337,11 @@ do_external_panelize (char *command) /* Clear the counters and the directory list */ panel_clean_dir (current_panel); + g_strlcpy (panelized_panel.root, current_panel->cwd, MC_MAXPATHLEN); + + if (set_zero_dir (list)) + next_free++; + while (1) { clearerr (external); @@ -397,10 +402,96 @@ do_external_panelize (char *command) } /* --------------------------------------------------------------------------------------------- */ + +static void +do_panelize_cd (struct WPanel *panel) +{ + int i; + dir_list *list = &panel->dir; + + clean_dir (list, panel->count); + if (panelized_panel.root[0] == '\0') + g_strlcpy (panelized_panel.root, panel->cwd, MC_MAXPATHLEN); + + if (panelized_panel.count < 1) + { + if (set_zero_dir (&panelized_panel.list)) + panelized_panel.count = 1; + } + else if (panelized_panel.count >= list->size) + { + list->list = g_try_realloc (list->list, sizeof (file_entry) * (panelized_panel.count)); + list->size = panelized_panel.count; + } + panel->count = panelized_panel.count; + panel->is_panelized = 1; + + for (i = 0; i < panelized_panel.count; i++) + { + list->list[i].fnamelen = panelized_panel.list.list[i].fnamelen; + list->list[i].fname = g_strdup (panelized_panel.list.list[i].fname); + list->list[i].f.link_to_dir = panelized_panel.list.list[i].f.link_to_dir; + list->list[i].f.stale_link = panelized_panel.list.list[i].f.stale_link; + list->list[i].f.dir_size_computed = panelized_panel.list.list[i].f.dir_size_computed; + list->list[i].f.marked = panelized_panel.list.list[i].f.marked; + list->list[i].st = panelized_panel.list.list[i].st; + list->list[i].sort_key = panelized_panel.list.list[i].sort_key; + list->list[i].second_sort_key = panelized_panel.list.list[i].second_sort_key; + } + try_to_select (panel, NULL); +} + +/* --------------------------------------------------------------------------------------------- */ /*** public functions ****************************************************************************/ /* --------------------------------------------------------------------------------------------- */ void +panelize_save_panel (struct WPanel *panel) +{ + int i; + dir_list *list = &panel->dir; + + g_strlcpy (panelized_panel.root, panel->cwd, MC_MAXPATHLEN); + + if (panelized_panel.count > 0) + clean_dir (&panelized_panel.list, panelized_panel.count); + if (panel->count < 1) + return; + + panelized_panel.count = panel->count; + if (panel->count >= panelized_panel.list.size) + { + panelized_panel.list.list = g_try_realloc (panelized_panel.list.list, + sizeof (file_entry) * panel->count); + panelized_panel.list.size = panel->count; + } + for (i = 0; i < panel->count; i++) + { + panelized_panel.list.list[i].fnamelen = list->list[i].fnamelen; + panelized_panel.list.list[i].fname = g_strdup (list->list[i].fname); + panelized_panel.list.list[i].f.link_to_dir = list->list[i].f.link_to_dir; + panelized_panel.list.list[i].f.stale_link = list->list[i].f.stale_link; + panelized_panel.list.list[i].f.dir_size_computed = list->list[i].f.dir_size_computed; + panelized_panel.list.list[i].f.marked = list->list[i].f.marked; + panelized_panel.list.list[i].st = list->list[i].st; + panelized_panel.list.list[i].sort_key = list->list[i].sort_key; + panelized_panel.list.list[i].second_sort_key = list->list[i].second_sort_key; + } +} + +/* --------------------------------------------------------------------------------------------- */ + +void +cd_panelize_cmd (void) +{ + WPanel *panel = MENU_PANEL_IDX == 0 ? left_panel : right_panel; + + do_panelize_cd (panel); +} + +/* --------------------------------------------------------------------------------------------- */ + +void external_panelize (void) { char *target = NULL; diff --git a/src/filemanager/panelize.h b/src/filemanager/panelize.h index 313d488c3..e7f47dada 100644 --- a/src/filemanager/panelize.h +++ b/src/filemanager/panelize.h @@ -19,6 +19,8 @@ void external_panelize (void); void load_panelize (void); void save_panelize (void); void done_panelize (void); +void cd_panelize_cmd (void); +void panelize_save_panel (struct WPanel *panel); /*** inline functions ****************************************************************************/ #endif /* MC__PANELIZE_H */ diff --git a/src/main.c b/src/main.c index 9d442f2fb..e5d95dea9 100644 --- a/src/main.c +++ b/src/main.c @@ -59,6 +59,7 @@ #include "filemanager/layout.h" /* command_prompt */ #include "filemanager/ext.h" /* flush_extension_file() */ #include "filemanager/command.h" /* cmdline */ +#include "filemanager/panel.h" /* panalized_panel */ #include "vfs/plugins_init.h" @@ -261,8 +262,12 @@ int do_cd (const char *new_dir, enum cd_enum exact) { gboolean res; + const char *_new_dir = new_dir; - res = do_panel_cd (current_panel, new_dir, exact); + if (current_panel->is_panelized && _new_dir[0] == '.' && _new_dir[1] == '.' && _new_dir[2] == 0) + _new_dir = panelized_panel.root; + + res = do_panel_cd (current_panel, _new_dir, exact); #if HAVE_CHARSET if (res) -- 2.11.4.GIT