Browse Source

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 <il.smind@gmail.com>

Minor changes in goto_parent_dir()
many code optimization

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>

little fixup

Signed-off-by: Ilia Maslakov <il.smind@gmail.com>
Ilia Maslakov 13 years ago
parent
commit
5c252726f1

+ 1 - 0
lib/keybind.h

@@ -178,6 +178,7 @@ enum
     /* panels */
     CK_PanelOtherCd = 200,
     CK_PanelOtherCdLink,
+    CK_Panelize,
     CK_CopySingle,
     CK_MoveSingle,
     CK_DeleteSingle,

+ 5 - 5
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 ();
 }
 

+ 5 - 0
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 = &current_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);
         }
     }
 

+ 7 - 2
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 */

+ 33 - 3
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);
+    }
 }
 
 /* --------------------------------------------------------------------------------------------- */

+ 9 - 0
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;

+ 91 - 0
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);
@@ -396,10 +401,96 @@ do_external_panelize (char *command)
     panel_re_sort (current_panel);
 }
 
+/* --------------------------------------------------------------------------------------------- */
+
+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)
 {

+ 2 - 0
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 */

+ 6 - 1
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)