Ticket #1581: mc-tabs.patch

File mc-tabs.patch, 60.8 KB (added by cosminadrianpopescu, 10 years ago)

Tabs patch

  • acinclude.m4

    diff --git a/acinclude.m4 b/acinclude.m4
    index b156296..9f071a7 100644
    a b m4_include([m4.include/mc-use-termcap.m4]) 
    1313m4_include([m4.include/mc-with-screen.m4]) 
    1414m4_include([m4.include/mc-with-internal-edit.m4]) 
    1515m4_include([m4.include/mc-subshell.m4]) 
     16m4_include([m4.include/mc-tabs.m4]) 
    1617m4_include([m4.include/mc-background.m4]) 
    1718m4_include([m4.include/ac-glib.m4]) 
    1819m4_include([m4.include/mc-vfs.m4]) 
  • configure.ac

    diff --git a/configure.ac b/configure.ac
    index c82fdd0..9d40560 100644
    a b else 
    400400fi 
    401401 
    402402MC_SUBSHELL 
     403MC_TABS 
    403404MC_BACKGROUND 
    404405AC_MC_VFS_CHECKS 
    405406 
    Configuration: 
    653654  Mouse support:              ${mouse_lib} 
    654655  X11 events support:         ${textmode_x11_support} 
    655656  With subshell support:      ${subshell} 
     657  With tabs support:          ${tabs} 
    656658  With background operations: ${enable_background} 
    657659  Internal editor:            ${edit_msg} 
    658660  Diff viewer:                ${diff_msg} 
  • lib/fileloc.h

    diff --git a/lib/fileloc.h b/lib/fileloc.h
    index d0ca28b..2b5a9c5 100644
    a b  
    6060#define MC_USERMENU_FILE        "menu" 
    6161#define MC_TREESTORE_FILE       "Tree" 
    6262#define MC_PANELS_FILE          "panels.ini" 
     63#ifdef WITH_TABS 
     64#define MC_TABS_SESSION_SUBDIR  "tabs.sessions" 
     65#endif 
    6366#define MC_FHL_INI_FILE         "filehighlight.ini" 
    6467#define MC_SKINS_SUBDIR         "skins" 
    6568 
  • lib/keybind.c

    diff --git a/lib/keybind.c b/lib/keybind.c
    index 4a7b62a..e980465 100644
    a b static name_keymap_t command_names[] = { 
    7272    {"Delete", CK_Delete}, 
    7373    {"MakeDir", CK_MakeDir}, 
    7474    {"ChangeMode", CK_ChangeMode}, 
     75#ifdef WITH_TABS 
     76    {"CreateTab", CK_CreateTab}, 
     77    {"CloseTab", CK_CloseTab}, 
     78    {"RenameTab", CK_RenameTab}, 
     79    {"NextTab", CK_NextTab}, 
     80    {"MoveTab", CK_MoveTab}, 
     81    {"CopyTab", CK_CopyTab}, 
     82    {"MoveTabLeft", CK_MoveTabLeft}, 
     83    {"MoveTabRight", CK_MoveTabRight}, 
     84    {"SwapTab", CK_SwapTab}, 
     85    {"PreviousTab", CK_PreviousTab}, 
     86    {"TabsOptions", CK_TabsOptions}, 
     87    {"GoToTab", CK_GoToTab}, 
     88    {"TabsSaveSession", CK_TabsSaveSession}, 
     89    {"TabsRestoreSession", CK_TabsRestoreSession}, 
     90#endif 
    7591    {"ChangeOwn", CK_ChangeOwn}, 
    7692    {"ChangeOwnAdvanced", CK_ChangeOwnAdvanced}, 
    7793    {"Remove", CK_Remove}, 
  • lib/keybind.h

    diff --git a/lib/keybind.h b/lib/keybind.h
    index d5031ae..85b4289 100644
    a b enum 
    9191    CK_SaveAs, 
    9292    CK_Goto, 
    9393    CK_Reread, 
     94#ifdef WITH_TABS 
     95    CK_CreateTab, 
     96    CK_CloseTab, 
     97    CK_RenameTab, 
     98    CK_NextTab, 
     99    CK_PreviousTab, 
     100    CK_TabsOptions, 
     101    CK_TabsSaveSession, 
     102    CK_TabsRestoreSession, 
     103    CK_GoToTab, 
     104    CK_MoveTab, 
     105    CK_CopyTab, 
     106    CK_MoveTabLeft = 800, 
     107    CK_MoveTabRight = 801, 
     108    CK_SwapTab, 
     109#endif 
    94110    CK_Refresh, 
    95111    CK_Suspend, 
    96112    CK_Swap, 
  • lib/mcconfig.h

    diff --git a/lib/mcconfig.h b/lib/mcconfig.h
    index cc68992..5574e61 100644
    a b  
    99#define CONFIG_PANELS_SECTION "Panels" 
    1010#define CONFIG_LAYOUT_SECTION "Layout" 
    1111#define CONFIG_MISC_SECTION "Misc" 
     12#ifdef WITH_TABS 
     13#define CONFIG_TABS_SECTION "Tabs" 
     14#endif 
    1215#define CONFIG_EXT_EDITOR_VIEWER_SECTION "External editor or viewer parameters" 
    1316 
    1417/*** enums ***************************************************************************************/ 
  • lib/mcconfig/paths.c

    diff --git a/lib/mcconfig/paths.c b/lib/mcconfig/paths.c
    index c2aefa9..cfafc69 100644
    a b static const struct 
    8383 
    8484    /* data */ 
    8585    { "skins",                                 &mc_data_str, MC_SKINS_SUBDIR}, 
     86#ifdef WITH_TABS 
     87    { "tabs.sessions",                         &mc_config_str, MC_TABS_SESSION_SUBDIR},  
     88#endif 
    8689    { "fish",                                  &mc_data_str, FISH_PREFIX}, 
    8790    { "bashrc",                                &mc_data_str, "bashrc"}, 
    8891    { "inputrc",                               &mc_data_str, "inputrc"}, 
  • new file m4.include/mc-tabs.m4

    diff --git a/m4.include/mc-tabs.m4 b/m4.include/mc-tabs.m4
    new file mode 100644
    index 0000000..3ece8a0
    - +  
     1dnl 
     2dnl Tabs support 
     3dnl 
     4dnl @author Cosmin Popescu <cosminadrianpopescu@gmail.com> 
     5dnl @copyright Free Software Foundation, Inc. 
     6AC_DEFUN([MC_TABS], [ 
     7 
     8    AC_MSG_CHECKING([for tabs support]) 
     9    AC_ARG_WITH(tabs, 
     10            [  --with-tabs          Compile with tabs support @<:@yes@:>@ 
     11  --with-tabs=no Do not compile tab support @<:@no@:>@], 
     12            [ 
     13                result=no 
     14                if test x$withval = xyes; then 
     15                    AC_DEFINE(WITH_TABS, 1,  [Define to make tabs support optional]) 
     16                    result="yes" 
     17                fi 
     18                if test x$withval = xyes; then 
     19                    result="yes" 
     20                fi 
     21            ], 
     22            [ 
     23                dnl Default: enable the tabs support 
     24                result="no" 
     25            ]) 
     26 
     27    AC_MSG_RESULT([$result]) 
     28    tabs="$result" 
     29 
     30]) 
  • src/filemanager/boxes.c

    diff --git a/src/filemanager/boxes.c b/src/filemanager/boxes.c
    index 28bf221..ea5636e 100644
    a b panel_options_box (void) 
    732732    update_panels (UP_RELOAD, UP_KEEPSEL); 
    733733} 
    734734 
     735#ifdef WITH_TABS 
     736void 
     737tabs_options_box (void) 
     738{ 
     739    const char *open_where_options[] = { 
     740        N_("&Before current tab"), 
     741        N_("&After current tab"), 
     742        N_("At &end of tab bar"), 
     743        N_("At be&ginning of tab bar") 
     744    }; 
     745 
     746    const char *bar_position_options[] = { 
     747        N_("&Top"), 
     748        N_("&Bottom") 
     749    }; 
     750 
     751    { 
     752        quick_widget_t quick_widgets[] = { 
     753            /* *INDENT-OFF* */ 
     754            QUICK_START_GROUPBOX (N_("Open tabs")), 
     755                QUICK_RADIO (TABS_NUM, open_where_options, (int *) &tabs_options.open_where, 
     756                             NULL), 
     757            QUICK_STOP_GROUPBOX, 
     758            QUICK_START_GROUPBOX (N_("Tabs bar position")), 
     759                QUICK_RADIO (POS_NUM, bar_position_options, (int *) &tabs_options.bar_position, 
     760                             NULL), 
     761            QUICK_STOP_GROUPBOX, 
     762            QUICK_CHECKBOX (N_("H&ighlight current tab in the other panel"), &tabs_options.highlight_current_tab, NULL), 
     763            QUICK_CHECKBOX (N_("&Hide tab bar if only one tab"), &tabs_options.hide_tabs, NULL), 
     764            QUICK_CHECKBOX (N_("&Restore tabs when starting"), &tabs_options.restore_on_load, NULL), 
     765            QUICK_BUTTONS_OK_CANCEL, 
     766            QUICK_END 
     767            /* *INDENT-ON* */ 
     768        }; 
     769 
     770        quick_dialog_t qdlg = { 
     771            -1, -1, 60, 
     772            N_("Tabs options"), "[Tabs options]", 
     773            quick_widgets, NULL, NULL 
     774        }; 
     775 
     776        if (quick_dialog (&qdlg) != B_ENTER) 
     777            return; 
     778    } 
     779 
     780    update_panels (UP_RELOAD, UP_KEEPSEL); 
     781} 
     782#endif 
     783 
    735784/* --------------------------------------------------------------------------------------------- */ 
    736785 
    737786/* return list type */ 
  • src/filemanager/boxes.h

    diff --git a/src/filemanager/boxes.h b/src/filemanager/boxes.h
    index 9859a73..5561f87 100644
    a b  
    2121void configure_box (void); 
    2222void appearance_box (void); 
    2323void panel_options_box (void); 
     24#ifdef WITH_TABS 
     25void tabs_options_box (void); 
     26#endif 
    2427int panel_listing_box (WPanel * p, char **user, char **mini, int *use_msformat, int num); 
    2528const panel_field_t *sort_box (dir_sort_options_t * op, const panel_field_t * sort_field); 
    2629void confirm_box (void); 
  • src/filemanager/layout.c

    diff --git a/src/filemanager/layout.c b/src/filemanager/layout.c
    index 96bdd19..54a6ad7 100644
    a b set_display_type (int num, panel_view_mode_t type) 
    983983                    x = panels_layout.left_panel_size; 
    984984            } 
    985985        } 
     986#ifdef WITH_TABS 
     987        if (old_type == view_listing) 
     988        { 
     989            Widget *_w = panels[num].widget; 
     990            WPanel *_p = PANEL (_w); 
     991            _p->tabs.do_not_delete = 1; 
     992            change_tab (_p, dir_absolute, _p->tabs.list); 
     993        } 
     994#endif 
    986995    } 
    987996 
    988997    /* Restoring saved path from panels.ini for nonlist panel */ 
    swap_panels (void) 
    11201129        panelswap (selected); 
    11211130        panelswap (is_panelized); 
    11221131        panelswap (dir_stat); 
     1132#ifdef WITH_TABS 
     1133        panelswap (tabs.list); 
     1134        panelswap (tabs.current); 
     1135#endif 
    11231136#undef panelswapstr 
    11241137#undef panelswap 
    11251138 
    update_xterm_title_path (void) 
    14061419    } 
    14071420} 
    14081421 
     1422#ifdef WITH_TABS 
     1423WPanel * 
     1424get_target_panel (int menu) 
     1425{ 
     1426    WPanel *p = PANEL (panels[menu].widget); 
     1427    if (menu == -1) 
     1428    { 
     1429        return current_panel; 
     1430    } 
     1431    return p; 
     1432} 
     1433#endif 
     1434 
    14091435/* --------------------------------------------------------------------------------------------- */ 
  • src/filemanager/layout.h

    diff --git a/src/filemanager/layout.h b/src/filemanager/layout.h
    index 958549d..1dc649d 100644
    a b panel_view_mode_t get_current_type (void); 
    6666panel_view_mode_t get_other_type (void); 
    6767int get_current_index (void); 
    6868int get_other_index (void); 
     69#ifdef WITH_TABS 
     70WPanel *get_target_panel (int menu); 
     71#endif 
    6972const char *get_nth_panel_name (int num); 
    7073 
    7174struct Widget *get_panel_widget (int idx); 
  • src/filemanager/midnight.c

    diff --git a/src/filemanager/midnight.c b/src/filemanager/midnight.c
    index da25d75..ee8cb5c 100644
    a b create_panel_menu (void) 
    226226    entries = g_list_prepend (entries, menu_separator_create ()); 
    227227    entries = g_list_prepend (entries, menu_entry_create (_("&Rescan"), CK_Reread)); 
    228228 
     229#ifdef WITH_TABS 
     230    entries = g_list_prepend (entries, menu_separator_create ()); 
     231    entries = g_list_prepend (entries, menu_entry_create (_("&Create tab"), CK_CreateTab)); 
     232    entries = g_list_prepend (entries, menu_entry_create (_("Cl&ose tab"), CK_CloseTab)); 
     233    entries = g_list_prepend (entries, menu_entry_create (_("Re&name tab"), CK_RenameTab)); 
     234    entries = g_list_prepend (entries, menu_entry_create (_("Ne&xt tab"), CK_NextTab)); 
     235    entries = g_list_prepend (entries, menu_entry_create (_("Pre&vious tab"), CK_PreviousTab)); 
     236    entries = g_list_prepend (entries, menu_entry_create (_("&Move tab left"), CK_MoveTabLeft)); 
     237    entries = g_list_prepend (entries, menu_entry_create (_("Move tab ri&ght"), CK_MoveTabRight)); 
     238    entries = g_list_prepend (entries, menu_entry_create (_("Go to ta&b"), CK_GoToTab)); 
     239#endif 
    229240    return g_list_reverse (entries); 
    230241} 
    231242 
    create_command_menu (void) 
    289300    entries = 
    290301        g_list_prepend (entries, menu_entry_create (_("E&xternal panelize"), CK_ExternalPanelize)); 
    291302    entries = g_list_prepend (entries, menu_entry_create (_("Show directory s&izes"), CK_DirSize)); 
     303#ifdef WITH_TABS 
     304    entries = g_list_prepend (entries, menu_separator_create ()); 
     305    entries = 
     306        g_list_prepend (entries, menu_entry_create (_("Move tab to the other pane&l"), CK_MoveTab)); 
     307    entries = 
     308        g_list_prepend (entries, menu_entry_create (_("Copy tab to the other pa&nel"), CK_CopyTab)); 
     309    entries = g_list_prepend (entries, menu_entry_create (_("&Swap tabs"), CK_SwapTab)); 
     310#endif 
    292311    entries = g_list_prepend (entries, menu_separator_create ()); 
    293312    entries = g_list_prepend (entries, menu_entry_create (_("Command &history"), CK_History)); 
    294313    entries = g_list_prepend (entries, menu_entry_create (_("Di&rectory hotlist"), CK_HotList)); 
    create_options_menu (void) 
    333352    entries = g_list_prepend (entries, menu_entry_create (_("&Configuration..."), CK_Options)); 
    334353    entries = g_list_prepend (entries, menu_entry_create (_("&Layout..."), CK_OptionsLayout)); 
    335354    entries = g_list_prepend (entries, menu_entry_create (_("&Panel options..."), CK_OptionsPanel)); 
     355#ifdef WITH_TABS 
     356    entries = g_list_prepend (entries, menu_entry_create (_("&Tabs options..."), CK_TabsOptions)); 
     357#endif 
    336358    entries = 
    337359        g_list_prepend (entries, menu_entry_create (_("C&onfirmation..."), CK_OptionsConfirm)); 
    338360    entries = 
    create_options_menu (void) 
    345367#endif 
    346368    entries = g_list_prepend (entries, menu_separator_create ()); 
    347369    entries = g_list_prepend (entries, menu_entry_create (_("&Save setup"), CK_SaveSetup)); 
     370#ifdef WITH_TABS 
     371    entries = 
     372        g_list_prepend (entries, menu_entry_create (_("Save tabs sessio&n"), CK_TabsSaveSession)); 
     373    entries = 
     374        g_list_prepend (entries, 
     375                        menu_entry_create (_("Restore tabs sessi&on"), CK_TabsRestoreSession)); 
     376#endif 
    348377 
    349378    return g_list_reverse (entries); 
    350379} 
    create_panels_and_run_mc (void) 
    957986    midnight_set_buttonbar (the_bar); 
    958987 
    959988    /* Run the Midnight Commander if no file was specified in the command line */ 
     989#ifdef WITH_TABS 
     990    saved_tabs = NULL; 
     991    if (tabs_options.restore_on_load) 
     992    { 
     993        char *title = g_new0 (char, 255); 
     994        strcpy (title, "default"); 
     995        restore_tabs_session (title); 
     996        g_free (title); 
     997    } 
     998#endif 
    960999    dlg_run (midnight_dlg); 
    9611000} 
    9621001 
    midnight_execute_cmd (Widget * sender, unsigned long command) 
    12821321    case CK_OptionsPanel: 
    12831322        panel_options_box (); 
    12841323        break; 
     1324#ifdef WITH_TABS 
     1325    case CK_TabsOptions: 
     1326        tabs_options_box (); 
     1327        break; 
     1328    case CK_TabsSaveSession: 
     1329        save_tabs_session_custom (); 
     1330        break; 
     1331    case CK_TabsRestoreSession: 
     1332        restore_tabs_session_custom (); 
     1333        break; 
     1334    case CK_CreateTab: 
     1335        new_tab (TARGET_PANEL); 
     1336        break; 
     1337    case CK_CloseTab: 
     1338        close_tab (TARGET_PANEL); 
     1339        break; 
     1340    case CK_RenameTab: 
     1341        rename_tab (TARGET_PANEL); 
     1342        break; 
     1343    case CK_NextTab: 
     1344        // If the sender if the menu bar, then do next tab in the corresponding menu panel.  
     1345        // Otherwise, do it in the current panel (-1) 
     1346        change_tab (TARGET_PANEL, dir_next, NULL); 
     1347        break; 
     1348    case CK_CopyTab: 
     1349        copy_tab_to_other_panel (); 
     1350        break; 
     1351    case CK_MoveTabLeft: 
     1352        move_tab (TARGET_PANEL, dir_previous); 
     1353        break; 
     1354    case CK_MoveTabRight: 
     1355        move_tab (TARGET_PANEL, dir_next); 
     1356        break; 
     1357    case CK_SwapTab: 
     1358        swap_tabs (); 
     1359        break; 
     1360    case CK_MoveTab: 
     1361        move_tab_to_other_panel (); 
     1362        break; 
     1363    case CK_PreviousTab: 
     1364        change_tab (TARGET_PANEL, dir_previous, NULL); 
     1365        break; 
     1366    case CK_GoToTab: 
     1367        goto_tab (TARGET_PANEL); 
     1368        break; 
     1369#endif 
    12851370#ifdef HAVE_CHARSET 
    12861371    case CK_SelectCodepage: 
    12871372        encoding_cmd (); 
    do_nc (void) 
    17301815{ 
    17311816    gboolean ret; 
    17321817 
     1818#ifdef WITH_TABS 
     1819    char *title = g_new0 (char, 255); 
     1820#endif 
    17331821#ifdef USE_INTERNAL_EDIT 
    17341822    edit_stack_init (); 
    17351823#endif 
    do_nc (void) 
    17671855 
    17681856    /* Program end */ 
    17691857    mc_global.midnight_shutdown = TRUE; 
     1858#ifdef WITH_TABS 
     1859    strcpy (title, "default"); 
     1860    save_tabs_session (title); 
     1861    g_free (title); 
     1862#endif 
    17701863    dialog_switch_shutdown (); 
    17711864    done_mc (); 
    17721865    dlg_destroy (midnight_dlg); 
  • src/filemanager/midnight.h

    diff --git a/src/filemanager/midnight.h b/src/filemanager/midnight.h
    index 4ad3629..8c7db2c 100644
    a b  
    1414 
    1515/*** typedefs(not structures) and defined constants **********************************************/ 
    1616 
     17#ifdef WITH_TABS 
     18#define TARGET_PANEL get_target_panel(sender == WIDGET (the_menubar) ? MENU_PANEL_IDX : -1) 
     19#endif 
    1720#define MENU_PANEL (mc_global.widget.is_right ? right_panel : left_panel) 
    1821#define MENU_PANEL_IDX  (mc_global.widget.is_right ? 1 : 0) 
    1922#define SELECTED_IS_PANEL (get_display_type (MENU_PANEL_IDX) == view_listing) 
  • src/filemanager/panel.c

    diff --git a/src/filemanager/panel.c b/src/filemanager/panel.c
    index 3879bb1..da774fa 100644
    a b extern int saving_setup; 
    321321#define STATUS          5 
    322322 
    323323/* This macro extracts the number of available lines in a panel */ 
     324#ifdef WITH_TABS 
     325#define llines(p) (WIDGET (p)->lines - (TABS_UP(p) ? 4 : 3) - (panels_options.show_mini_info ? 4 : 2) + (TABS_UP(p) ? 0 : (TABS_VISIBLE(p) ? 0 : 2))) 
     326#else 
    324327#define llines(p) (WIDGET (p)->lines - 3 - (panels_options.show_mini_info ? 2 : 0)) 
     328#endif 
     329 
    325330 
    326331/*** file scope type declarations ****************************************************************/ 
    327332 
    repaint_file (WPanel * panel, int file_index, gboolean mv, int attr, gboolean is 
    927932            ypos = pos; 
    928933 
    929934        ypos += 2; 
     935#ifdef WITH_TABS 
     936        ypos += TABS_UP (panel) ? 3 : 0; 
     937#endif 
    930938        widget_move (w, ypos, offset + 1); 
    931939    } 
    932940 
    display_mini_info (WPanel * panel) 
    979987    if (!panels_options.show_mini_info) 
    980988        return; 
    981989 
     990#ifdef WITH_TABS 
     991    widget_move (w, llines (panel) + 3 + (TABS_UP (panel) ? 3 : 0), 1); 
     992#else 
    982993    widget_move (w, llines (panel) + 3, 1); 
     994#endif 
     995 
    983996 
    984997    if (panel->searching) 
    985998    { 
    mini_info_separator (WPanel * panel) 
    11041117    if (panels_options.show_mini_info) 
    11051118    { 
    11061119        Widget *w = WIDGET (panel); 
     1120#ifdef WITH_TABS 
     1121        const int y = llines (panel) + 2 + (TABS_UP (panel) ? 3 : 0); 
     1122#else 
    11071123        const int y = llines (panel) + 2; 
     1124#endif 
    11081125 
    11091126        tty_setcolor (NORMAL_COLOR); 
    11101127        tty_draw_hline (w->y + y, w->x + 1, ACS_HLINE, w->cols - 2); 
    show_dir (WPanel * panel) 
    12551272 
    12561273    if (panels_options.show_mini_info) 
    12571274    { 
     1275#ifdef WITH_TABS 
     1276        widget_move (w, llines (panel) + 2 + (TABS_UP (panel) ? 3 : 0), 0); 
     1277#else 
    12581278        widget_move (w, llines (panel) + 2, 0); 
     1279#endif 
    12591280        tty_print_alt_char (ACS_LTEE, FALSE); 
     1281#ifdef WITH_TABS 
     1282        widget_move (w, llines (panel) + 2 + (TABS_UP (panel) ? 3 : 0), w->cols - 1); 
     1283#else 
    12601284        widget_move (w, llines (panel) + 2, w->cols - 1); 
     1285#endif 
    12611286        tty_print_alt_char (ACS_RTEE, FALSE); 
    12621287    } 
    12631288 
    panel_destroy (WPanel * p) 
    14621487{ 
    14631488    size_t i; 
    14641489 
     1490#ifdef WITH_TABS 
     1491    destroy_tabs (p); 
     1492#endif 
     1493 
    14651494    if (panels_options.auto_save_setup) 
    14661495    { 
    14671496        char *name; 
    panel_paint_sort_info (WPanel * panel) 
    15161545        char *str; 
    15171546 
    15181547        str = g_strdup_printf ("%s%s", sort_sign, Q_ (panel->sort_field->hotkey)); 
     1548#ifdef WITH_TABS 
     1549        widget_move (panel, TABS_UP (panel) ? 4 : 1, 1); 
     1550#else 
    15191551        widget_move (panel, 1, 1); 
     1552#endif 
    15201553        tty_print_string (str); 
    15211554        g_free (str); 
    15221555    } 
    paint_frame (WPanel * panel) 
    15591592    widget_erase (w); 
    15601593    show_dir (panel); 
    15611594 
     1595#ifdef WITH_TABS 
     1596    widget_move (w, TABS_UP (panel) ? 4 : 1, 1); 
     1597#else 
    15621598    widget_move (w, 1, 1); 
     1599#endif 
    15631600 
    15641601    for (side = 0; side <= panel->split; side++) 
    15651602    { 
    panel_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *d 
    35913628    case MSG_DRAW: 
    35923629        /* Repaint everything, including frame and separator */ 
    35933630        paint_frame (panel);    /* including show_dir */ 
     3631#ifdef WITH_TABS 
     3632        draw_tabs (get_other_type () != view_listing 
     3633                   || get_current_type () != view_listing ? panel : NULL); 
     3634#endif 
    35943635        paint_dir (panel); 
    35953636        mini_info_separator (panel); 
    35963637        display_mini_info (panel); 
    panel_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *d 
    36233664        bb = find_buttonbar (w->owner); 
    36243665        midnight_set_buttonbar (bb); 
    36253666        widget_redraw (WIDGET (bb)); 
     3667#ifdef WITH_TABS 
     3668        draw_tabs (get_other_type () != view_listing 
     3669                   || get_current_type () != view_listing ? panel : NULL); 
     3670#endif 
    36263671        return MSG_HANDLED; 
    36273672 
    36283673    case MSG_UNFOCUS: 
    panel_event (Gpm_Event * event, void *data) 
    38103855    } 
    38113856 
    38123857    /* sort on clicked column; don't handle wheel events */ 
     3858#ifdef WITH_TABS 
     3859    if (mouse_down && (local.buttons & (GPM_B_UP | GPM_B_DOWN)) == 0 
     3860        && local.y == (TABS_UP (panel) ? 5 : 2)) 
     3861#else 
    38133862    if (mouse_down && (local.buttons & (GPM_B_UP | GPM_B_DOWN)) == 0 && local.y == 2) 
     3863#endif 
    38143864    { 
    38153865        mouse_sort_col (panel, local.x); 
    38163866        goto finish; 
    38173867    } 
    38183868 
     3869#ifdef WITH_TABS 
     3870    if (mouse_down && (local.buttons & (GPM_B_UP | GPM_B_DOWN)) == 0 
     3871        && local.y == (TABS_UP (panel) ? 3 : w->lines - 1)) 
     3872    { 
     3873        process_tab_click (local.x); 
     3874    } 
     3875#endif 
    38193876    /* Mouse wheel events */ 
    38203877    if (mouse_down && (local.buttons & GPM_B_UP) != 0) 
    38213878    { 
    panel_event (Gpm_Event * event, void *data) 
    38423899        goto finish; 
    38433900    } 
    38443901 
     3902#ifdef WITH_TABS 
     3903    local.y -= (TABS_UP (panel) ? 5 : 2); 
     3904#else 
    38453905    local.y -= 2; 
     3906#endif 
    38463907    if ((local.type & (GPM_DOWN | GPM_DRAG)) != 0) 
    38473908    { 
    38483909        int my_index; 
    panel_new_with_dir (const char *panel_name, const vfs_path_t * vpath) 
    42794340        section = g_strdup (panel->panel_name); 
    42804341    } 
    42814342    panel_load_setup (panel, section); 
     4343#ifdef WITH_TABS 
     4344    if (saved_tabs != NULL) 
     4345    { 
     4346        panel->tabs.list = saved_tabs; 
     4347        panel->tabs.current = saved_tabs; 
     4348        saved_tabs = NULL; 
     4349    } 
     4350    else 
     4351    { 
     4352        create_tab (panel, dir_next, NULL); 
     4353    } 
     4354    panel->tabs.do_not_delete = 0; 
     4355#endif 
    42824356    g_free (section); 
    42834357 
    42844358    /* Load format strings */ 
    do_cd (const vfs_path_t * new_dir_vpath, enum cd_enum exact) 
    49985072    return res; 
    49995073} 
    50005074 
     5075#ifdef WITH_TABS 
     5076/** 
     5077 * Gets the new tabs direction from preferences 
     5078 */ 
     5079enum tabs_direction 
     5080get_new_tabs_direction () 
     5081{ 
     5082    if (tabs_options.open_where == BEFORE_CURRENT) 
     5083    { 
     5084        return dir_previous; 
     5085    } 
     5086    else if (tabs_options.open_where == AFTER_CURRENT) 
     5087    { 
     5088        return dir_next; 
     5089    } 
     5090    else if (tabs_options.open_where == AT_END) 
     5091    { 
     5092        return dir_last; 
     5093    } 
     5094    else if (tabs_options.open_where == AT_BEGINNING) 
     5095    { 
     5096        return dir_first; 
     5097    } 
     5098 
     5099    return dir_last; 
     5100} 
     5101 
     5102/** 
     5103 * This function will create a new tab in the current panel 
     5104 */ 
     5105void 
     5106new_tab (WPanel * panel) 
     5107{ 
     5108    enum tabs_direction d = get_new_tabs_direction (); 
     5109    create_tab (panel, d, NULL); 
     5110    change_tab (panel, d, NULL); 
     5111    draw_tabs (panel); 
     5112    panel->dirty = 1; 
     5113} 
     5114 
     5115/** 
     5116 * Copies the current tab from the current panel to the other Panel 
     5117 */ 
     5118void 
     5119copy_tab_to_other_panel (void) 
     5120{ 
     5121    WPanel *opanel = (WPanel *) other_panel; 
     5122    WPanel *cpanel = (WPanel *) current_panel; 
     5123    Tab *tc, *to; 
     5124    enum tabs_direction d = get_new_tabs_direction (); 
     5125 
     5126    tc = cpanel->tabs.current->data; 
     5127    create_tab (opanel, d, NULL); 
     5128    change_tab (opanel, d, NULL); 
     5129    to = opanel->tabs.current->data; 
     5130 
     5131    if (tc->name != NULL) 
     5132    { 
     5133        to->name = g_new0 (char, strlen (tc->name) + 1); 
     5134        strcpy (to->name, tc->name); 
     5135    } 
     5136    to->path = vfs_path_clone (cpanel->cwd_vpath); 
     5137    do_panel_cd (opanel, to->path, cd_exact); 
     5138    draw_tabs (opanel); 
     5139} 
     5140 
     5141void 
     5142swap_tabs (void) 
     5143{ 
     5144    WPanel *panel1 = (WPanel *) other_panel; 
     5145    WPanel *panel2 = (WPanel *) current_panel; 
     5146    GList *b, *e, *d, *f; 
     5147    // We consider the tabs on the current panel a, b, c 
     5148    // and the tabs on the other panel d, e, f 
     5149    // We try to change b and e.  
     5150    // If we have only one tab on each panel, then we do switch panel.  
     5151    // We have a special case if we have only one tab on only one of the panels.  
     5152    // Then this algorithm will work if panel1 is the panel with only one tab 
     5153    // If we changed the first tab of any of the panel, we have to also change the panel->tabs.list pointer 
     5154 
     5155    if (panel1->tabs.current->next == panel1->tabs.current 
     5156        && panel2->tabs.current->next == panel2->tabs.current) 
     5157    { 
     5158        swap_panels (); 
     5159        tty_touch_screen (); 
     5160        repaint_screen (); 
     5161        return; 
     5162    } 
     5163    else 
     5164    { 
     5165        if (panel2->tabs.current->next == panel2->tabs.current) 
     5166        { 
     5167            panel1 = (WPanel *) current_panel; 
     5168            panel2 = (WPanel *) other_panel; 
     5169        } 
     5170    } 
     5171 
     5172    b = panel1->tabs.current; 
     5173    ((Tab *) b->data)->path = vfs_path_clone (panel1->cwd_vpath); 
     5174    e = panel2->tabs.current; 
     5175    ((Tab *) e->data)->path = vfs_path_clone (panel2->cwd_vpath); 
     5176    d = e->prev; 
     5177    f = e->next; 
     5178 
     5179    if (b->prev != b) 
     5180    { 
     5181        b->prev->next = e; 
     5182    } 
     5183    e->next = b->next == b ? e : b->next; 
     5184    if (b->next != b) 
     5185    { 
     5186        b->next->prev = e; 
     5187    } 
     5188    e->prev = b->prev == b ? e : b->prev; 
     5189 
     5190    d->next = b; 
     5191    b->next = f; 
     5192    f->prev = b; 
     5193    b->prev = d; 
     5194 
     5195    panel1->tabs.current = e; 
     5196    if (panel1->tabs.list == b) 
     5197    { 
     5198        panel1->tabs.list = e; 
     5199    } 
     5200    panel2->tabs.current = b; 
     5201    if (panel2->tabs.list == e) 
     5202    { 
     5203        panel2->tabs.list = b; 
     5204    } 
     5205    do_panel_cd (panel1, ((Tab *) e->data)->path, cd_exact); 
     5206    do_panel_cd (panel2, ((Tab *) b->data)->path, cd_exact); 
     5207    change_panel (); 
     5208    repaint_screen (); 
     5209} 
     5210 
     5211/** 
     5212 * Moves the current tab from the current panel to the other Panel 
     5213 */ 
     5214void 
     5215move_tab_to_other_panel (void) 
     5216{ 
     5217    WPanel *opanel = (WPanel *) other_panel; 
     5218    WPanel *cpanel = (WPanel *) current_panel; 
     5219    Tab *t; 
     5220    GList *i; 
     5221    enum tabs_direction d = get_new_tabs_direction (); 
     5222    int first_tab = 0; 
     5223 
     5224    if (cpanel->tabs.list->next == cpanel->tabs.list) 
     5225    { 
     5226        message (D_ERROR, MSG_ERROR, _("The current tab is the only one.\nYou cannot move it.")); 
     5227    } 
     5228    else 
     5229    { 
     5230        if (cpanel->tabs.list == cpanel->tabs.current) 
     5231        { 
     5232            cpanel->tabs.list = cpanel->tabs.list->next; 
     5233            first_tab = 1; 
     5234        } 
     5235        t = cpanel->tabs.current->data; 
     5236        create_tab (opanel, d, (Tab *) t); 
     5237        i = cpanel->tabs.current; 
     5238        change_tab (cpanel, dir_previous, NULL); 
     5239        i->prev->next = i->next; 
     5240        i->next->prev = i->prev; 
     5241        g_free (i); 
     5242        i = opanel->tabs.current->next; 
     5243        while (i != opanel->tabs.current) 
     5244        { 
     5245            if (i->data == t) 
     5246            { 
     5247                break; 
     5248            } 
     5249 
     5250            i = i->next; 
     5251        } 
     5252        change_tab (opanel, dir_absolute, i); 
     5253        change_panel (); 
     5254        if (first_tab) 
     5255        { 
     5256            change_tab (cpanel, dir_absolute, cpanel->tabs.list); 
     5257        } 
     5258        repaint_screen (); 
     5259    } 
     5260} 
     5261 
     5262/** 
     5263 * This function will close a tab 
     5264 * @return void 
     5265 */ 
     5266void 
     5267close_tab (WPanel * p) 
     5268{ 
     5269    if (p->tabs.list->next == p->tabs.list) 
     5270    { 
     5271        message (D_ERROR, MSG_ERROR, _("The current tab is the only one.\nYou cannot close it.")); 
     5272    } 
     5273    else 
     5274    { 
     5275        int first = p->tabs.current == p->tabs.list; 
     5276        GList *b = p->tabs.current->prev; 
     5277        GList *c = p->tabs.current; 
     5278        GList *d = p->tabs.current->next; 
     5279        change_tab (p, dir_previous, NULL); 
     5280        b->next = d; 
     5281        d->prev = b; 
     5282 
     5283        destroy_tab (c->data); 
     5284        g_free (c); 
     5285 
     5286        if (first) 
     5287        { 
     5288            p->tabs.list = d; 
     5289        } 
     5290    } 
     5291} 
     5292 
     5293/** 
     5294 * This function renames a tab 
     5295 * @return void 
     5296 */ 
     5297void 
     5298rename_tab (WPanel * p) 
     5299{ 
     5300    Tab *t = (Tab *) p->tabs.current->data; 
     5301    char *title = TAB_TITLE (p, t); 
     5302 
     5303    char *name = input_dialog (_("Tab rename"), _("Please enter the new name:"), NULL, title, 
     5304                               INPUT_COMPLETE_NONE); 
     5305    if (name) 
     5306    { 
     5307        if (strlen (name)) 
     5308        { 
     5309            t->name = g_new0 (char, strlen (name) + 1); 
     5310            strcpy (t->name, name); 
     5311            g_free (name); 
     5312            g_free (title); 
     5313        } 
     5314    } 
     5315    widget_redraw ((Widget *) p); 
     5316} 
     5317 
     5318int 
     5319get_tab_index (WPanel * p, GList * t) 
     5320{ 
     5321    int result = 0; 
     5322    GList *i = p->tabs.list; 
     5323    do 
     5324    { 
     5325        if (i == t) 
     5326        { 
     5327            return result; 
     5328        } 
     5329        result++; 
     5330        i = i->next; 
     5331    } 
     5332    while (i != p->tabs.list); 
     5333 
     5334    return 0; 
     5335} 
     5336 
     5337/** 
     5338 * This function goes to an arbitrary choosen tab 
     5339 * @return void 
     5340 */ 
     5341void 
     5342goto_tab (WPanel * p) 
     5343{ 
     5344    Listbox *listbox = 
     5345        create_listbox_window (15, 60, _("Available Tabs"), "[Available Tabs Selector]"); 
     5346    GList *it = p->tabs.list; 
     5347    int items = 0; 
     5348    int result; 
     5349 
     5350    do 
     5351    { 
     5352        char *title = TAB_TITLE (p, it->data); 
     5353        listbox_add_item (listbox->list, LISTBOX_APPEND_AT_END, 0, title, (void *) it); 
     5354        it = it->next; 
     5355        items++; 
     5356    } 
     5357    while (it != p->tabs.list); 
     5358 
     5359    listbox_select_entry (listbox->list, get_tab_index (current_panel, p->tabs.current)); 
     5360 
     5361    result = run_listbox (listbox); 
     5362 
     5363    if (result >= 0) 
     5364    { 
     5365        GList *t; 
     5366        t = g_list_nth ((GList *) p->tabs.list, result); 
     5367        change_tab (p, dir_absolute, t); 
     5368    } 
     5369} 
     5370 
     5371void 
     5372create_tab (WPanel * p, enum tabs_direction direction, Tab * t) 
     5373{ 
     5374    GList *b = NULL; 
     5375    GList *c = g_new0 (GList, 1); 
     5376 
     5377    if (t == NULL) 
     5378    { 
     5379        t = g_new0 (Tab, 1); 
     5380        t->path = NULL; 
     5381        t->name = NULL; 
     5382    } 
     5383 
     5384    if (direction == dir_next) 
     5385    { 
     5386        b = p->tabs.current; 
     5387    } 
     5388    else if (direction == dir_previous) 
     5389    { 
     5390        b = p->tabs.current->prev; 
     5391    } 
     5392    else if (direction == dir_last || direction == dir_first) 
     5393    { 
     5394        b = p->tabs.list->prev; 
     5395    } 
     5396    c->data = t; 
     5397 
     5398    if (b) 
     5399    { 
     5400        GList *d = b->next; 
     5401        b->next = c; 
     5402        c->next = d; 
     5403        d->prev = c; 
     5404        c->prev = b; 
     5405    } 
     5406    else 
     5407    { 
     5408        c->next = c; 
     5409        c->prev = c; 
     5410        p->tabs.current = c; 
     5411    } 
     5412 
     5413    if (!p->tabs.list) 
     5414    { 
     5415        p->tabs.list = c; 
     5416    } 
     5417 
     5418    if (direction == dir_first) 
     5419    { 
     5420        p->tabs.list = c; 
     5421    } 
     5422 
     5423} 
     5424 
     5425GList * 
     5426get_tab_by_index (WPanel * p, int idx) 
     5427{ 
     5428    int i = 0; 
     5429    GList *t = p->tabs.list; 
     5430 
     5431    while (i++ < idx) 
     5432    { 
     5433        t = t->next; 
     5434    } 
     5435 
     5436    return t; 
     5437} 
     5438 
     5439RestoredTabs 
     5440_restore_tabs (FILE * f) 
     5441{ 
     5442    RestoredTabs result; 
     5443    Tab *t; 
     5444    int idx = 0; 
     5445    int crt_idx; 
     5446    GList *i; 
     5447    GList *j = NULL; 
     5448    char *line = g_new0 (char, 1024); 
     5449 
     5450    result.error = 0; 
     5451    result.list = NULL; 
     5452    fscanf (f, "%d\n%d\n", &result.idx, &crt_idx); 
     5453 
     5454    if (crt_idx == -1) 
     5455    { 
     5456        return result; 
     5457    } 
     5458 
     5459    do 
     5460    { 
     5461        read_line (line, 1024, f); 
     5462        if (strcmp (line, "") && !feof (f)) 
     5463        { 
     5464            t = g_new0 (Tab, 1); 
     5465            if (!strcmp (line, "(null)")) 
     5466            { 
     5467                t->name = NULL; 
     5468            } 
     5469            else 
     5470            { 
     5471                t->name = g_new0 (char, strlen (line) + 1); 
     5472                memcpy (t->name, line, strlen (line) + 1); 
     5473            } 
     5474 
     5475            read_line (line, 1024, f); 
     5476            if (!strcmp (line, "")) 
     5477            { 
     5478                result.error = 1; 
     5479                return result; 
     5480            } 
     5481            t->path = vfs_path_from_str (line); 
     5482 
     5483            i = g_new0 (GList, 1); 
     5484            i->data = (void *) t; 
     5485 
     5486            if (result.list == NULL) 
     5487            { 
     5488                result.list = i; 
     5489                result.list->prev = result.list; 
     5490                j = i; 
     5491            } 
     5492            i->next = result.list; 
     5493            result.list->prev = i; 
     5494            i->prev = j; 
     5495            j->next = i; 
     5496            j = i; 
     5497 
     5498            if (idx++ == crt_idx) 
     5499            { 
     5500                result.current = j; 
     5501            } 
     5502        } 
     5503    } 
     5504    while (!feof (f) && strcmp (line, "") && !result.error); 
     5505 
     5506    g_free (line); 
     5507 
     5508    return result; 
     5509} 
     5510 
     5511void 
     5512abort_restore (RestoredTabs restored) 
     5513{ 
     5514    WPanel *tmp = g_new0 (WPanel, 1); 
     5515    tmp->tabs.list = restored.list; 
     5516    destroy_tabs (tmp); 
     5517    message (D_ERROR, MSG_ERROR, _("Error restoring the tabs.")); 
     5518    g_free (tmp); 
     5519} 
     5520 
     5521void 
     5522read_line (char *line, int max, FILE * f) 
     5523{ 
     5524    fgets (line, max, f); 
     5525    if (line[strlen (line) - 1] == '\n') 
     5526    { 
     5527        line[strlen (line) - 1] = '\0'; 
     5528    } 
     5529} 
     5530 
     5531void 
     5532restore_tabs_session (char *title) 
     5533{ 
     5534    char *file_name = g_new0 (char, strlen (tabs_options.sessions_folder) + 1 + strlen (title) + 1); 
     5535    RestoredTabs restored1, restored2; 
     5536    char *line = g_new0 (char, 1024); 
     5537    Tab *t; 
     5538 
     5539    restored1.list = restored1.current = restored2.list = restored2.current = NULL; 
     5540 
     5541    sprintf (file_name, "%s/%s", tabs_options.sessions_folder, title); 
     5542 
     5543    if (exist_file (file_name)) 
     5544    { 
     5545        FILE *f = fopen (file_name, "rt"); 
     5546        read_line (line, 1024, f); 
     5547        if (strcmp (line, "[Current Panel]")) 
     5548        { 
     5549            abort_restore (restored1); 
     5550            g_free (line); 
     5551            g_free (file_name); 
     5552            return; 
     5553        } 
     5554 
     5555        restored1 = _restore_tabs (f); 
     5556        if (restored1.error) 
     5557        { 
     5558            abort_restore (restored1); 
     5559            g_free (line); 
     5560            g_free (file_name); 
     5561            return; 
     5562        } 
     5563        read_line (line, 1024, f); 
     5564        if (strcmp (line, "[Other Panel]")) 
     5565        { 
     5566            abort_restore (restored1); 
     5567            g_free (line); 
     5568            g_free (file_name); 
     5569            return; 
     5570        } 
     5571        restored2 = _restore_tabs (f); 
     5572        if (restored2.error) 
     5573        { 
     5574            abort_restore (restored1); 
     5575            abort_restore (restored2); 
     5576            g_free (line); 
     5577            g_free (file_name); 
     5578            return; 
     5579        } 
     5580 
     5581        fclose (f); 
     5582        if (restored1.list && get_display_type (get_current_index ()) == view_listing) 
     5583        { 
     5584            destroy_tabs (current_panel); 
     5585            current_panel->tabs.list = restored1.list; 
     5586            current_panel->tabs.current = restored1.current; 
     5587 
     5588            t = (Tab *) current_panel->tabs.current->data; 
     5589            do_panel_cd (current_panel, t->path, cd_exact); 
     5590 
     5591        } 
     5592        if (restored2.list && get_display_type (get_other_index ()) == view_listing) 
     5593        { 
     5594            destroy_tabs (other_panel); 
     5595            other_panel->tabs.list = restored2.list; 
     5596            other_panel->tabs.current = restored2.current; 
     5597            t = (Tab *) other_panel->tabs.current->data; 
     5598            do_panel_cd (other_panel, t->path, cd_exact); 
     5599        } 
     5600 
     5601        if (get_current_index () != restored1.idx) 
     5602        { 
     5603            swap_panels (); 
     5604            if (restored1.idx != 0) 
     5605            { 
     5606                //change_panel(); 
     5607            } 
     5608        } 
     5609    } 
     5610    g_free (line); 
     5611    g_free (file_name); 
     5612} 
     5613 
     5614void 
     5615_write_tabs (FILE * f, WPanel * p) 
     5616{ 
     5617    GList *i = p->tabs.list; 
     5618    Tab *t; 
     5619    int crt = get_tab_index (p, p->tabs.current); 
     5620    fprintf (f, "%d\n", crt); 
     5621    do 
     5622    { 
     5623        t = (Tab *) i->data; 
     5624        fprintf (f, "%s\n%s\n", t->name ? t->name : "(null)", 
     5625                 vfs_path_as_str (i == p->tabs.current ? p->cwd_vpath : t->path)); 
     5626        i = i->next; 
     5627    } 
     5628    while (i != p->tabs.list); 
     5629} 
     5630 
     5631void 
     5632save_tabs_session (char *title) 
     5633{ 
     5634    char *file_name = g_new0 (char, strlen (tabs_options.sessions_folder) + 1 + strlen (title) + 1); 
     5635    FILE *f; 
     5636    panel_view_mode_t t; 
     5637    int i; 
     5638    sprintf (file_name, "%s/%s", tabs_options.sessions_folder, title); 
     5639 
     5640    f = fopen (file_name, "wt"); 
     5641 
     5642    i = get_current_index (); 
     5643    t = get_display_type (i); 
     5644    fprintf (f, "[Current Panel]\n%d\n", i); 
     5645    if (t == view_listing) 
     5646    { 
     5647        _write_tabs (f, current_panel); 
     5648    } 
     5649    else 
     5650    { 
     5651        fprintf (f, "-1\n"); 
     5652    } 
     5653    i = get_other_index (); 
     5654    t = get_display_type (i); 
     5655    fprintf (f, "\n[Other Panel]\n%d\n", i); 
     5656    if (t == view_listing) 
     5657    { 
     5658        _write_tabs (f, other_panel); 
     5659    } 
     5660    else 
     5661    { 
     5662        fprintf (f, "-1\n"); 
     5663    } 
     5664    fclose (f); 
     5665    g_free (file_name); 
     5666} 
     5667 
     5668void 
     5669save_tabs_session_custom (void) 
     5670{ 
     5671    char *name = 
     5672        input_dialog (_("Save custom tabs session"), _("Please enter the session name:"), NULL, "", 
     5673                      INPUT_COMPLETE_NONE); 
     5674    if (name) 
     5675    { 
     5676        if (strlen (name)) 
     5677        { 
     5678            save_tabs_session (name); 
     5679        } 
     5680 
     5681        g_free (name); 
     5682    } 
     5683} 
     5684 
     5685void 
     5686restore_tabs_session_custom (void) 
     5687{ 
     5688    Listbox *listbox = 
     5689        create_listbox_window (15, 60, _("Available Sessions"), "[Available Sessions Selector]"); 
     5690    struct dirent *entry; 
     5691    DIR *dir; 
     5692    char *name; 
     5693    GList *items, *last, *current; 
     5694    int result; 
     5695    GList *t; 
     5696    GList *i; 
     5697 
     5698    dir = opendir (tabs_options.sessions_folder); 
     5699 
     5700    items = NULL; 
     5701 
     5702    while ((entry = readdir (dir)) != NULL) 
     5703    { 
     5704        if (strcmp (entry->d_name, ".") && strcmp (entry->d_name, "..")) 
     5705        { 
     5706            name = g_new0 (char, 255); 
     5707            memmove (name, entry->d_name, strlen (entry->d_name) + 1); 
     5708            last = g_new0 (GList, 1); 
     5709            last->data = name; 
     5710            last->next = NULL; 
     5711            if (items == NULL) 
     5712            { 
     5713                items = last; 
     5714                current = last; 
     5715            } 
     5716            else 
     5717            { 
     5718                current->next = last; 
     5719            } 
     5720            current = last; 
     5721            listbox_add_item (listbox->list, LISTBOX_APPEND_AT_END, 0, entry->d_name, 
     5722                              (void *) name); 
     5723        } 
     5724    } 
     5725 
     5726    result = run_listbox (listbox); 
     5727 
     5728    if (result >= 0) 
     5729    { 
     5730        t = g_list_nth ((GList *) items, result); 
     5731        restore_tabs_session ((char *) t->data); 
     5732    } 
     5733 
     5734    i = items; 
     5735    while (i) 
     5736    { 
     5737        name = (char *) i->data; 
     5738        i = i->next; 
     5739        g_free (name); 
     5740    } 
     5741} 
     5742 
     5743void 
     5744change_tab (WPanel * p, enum tabs_direction d, GList * tab) 
     5745{ 
     5746    if (p->tabs.current) 
     5747    { 
     5748        Tab *t = (Tab *) p->tabs.current->data; 
     5749        if (t->path) 
     5750        { 
     5751            vfs_path_free (t->path); 
     5752        } 
     5753 
     5754        //t->path = (vfs_path_t *) g_memdup(p->cwd_vpath, sizeof(vfs_path_t)); 
     5755        t->path = vfs_path_clone (p->cwd_vpath); 
     5756 
     5757        if (d == dir_next) 
     5758        { 
     5759            p->tabs.current = p->tabs.current->next; 
     5760        } 
     5761        else if (d == dir_previous) 
     5762        { 
     5763            p->tabs.current = p->tabs.current->prev; 
     5764        } 
     5765        else if (d == dir_first) 
     5766        { 
     5767            p->tabs.current = p->tabs.list; 
     5768        } 
     5769        else if (d == dir_last) 
     5770        { 
     5771            p->tabs.current = p->tabs.list->prev; 
     5772        } 
     5773        else if (tab != NULL) 
     5774        { 
     5775            p->tabs.current = tab; 
     5776        } 
     5777 
     5778        t = (Tab *) p->tabs.current->data; 
     5779        if (t->path) 
     5780        { 
     5781            do_panel_cd (p, t->path, cd_exact); 
     5782        } 
     5783    } 
     5784} 
     5785 
     5786void 
     5787destroy_tab (Tab * t) 
     5788{ 
     5789    if (t->path) 
     5790    { 
     5791        vfs_path_free (t->path); 
     5792    } 
     5793    if (t->name) 
     5794    { 
     5795        g_free (t->name); 
     5796    } 
     5797    g_free (t); 
     5798} 
     5799 
     5800void 
     5801destroy_tabs (WPanel * p) 
     5802{ 
     5803    GList *i; 
     5804    Tab *t; 
     5805    int loop; 
     5806    if (p->tabs.list == NULL || p->tabs.do_not_delete) 
     5807    { 
     5808        saved_tabs = p->tabs.list; 
     5809        p->tabs.do_not_delete = 0; 
     5810        return; 
     5811    } 
     5812 
     5813    loop = p->tabs.list != p->tabs.list->next; 
     5814 
     5815    p->tabs.list->prev->next = NULL; 
     5816 
     5817    do 
     5818    { 
     5819        i = p->tabs.list; 
     5820        if (i) 
     5821        { 
     5822            t = (Tab *) i->data; 
     5823            p->tabs.list = p->tabs.list->next; 
     5824            destroy_tab (t); 
     5825            g_free (i); 
     5826        } 
     5827    } 
     5828    while (p->tabs.list && loop); 
     5829    p->tabs.list = NULL; 
     5830    p->tabs.current = NULL; 
     5831} 
     5832 
     5833int 
     5834draw_tab (char *title, int selected) 
     5835{ 
     5836    if (selected) 
     5837    { 
     5838        tty_setcolor (SELECTED_COLOR); 
     5839    } 
     5840    tty_print_string (" "); 
     5841    tty_print_string (title); 
     5842    tty_print_string (" "); 
     5843    tty_setcolor (NORMAL_COLOR); 
     5844    tty_print_one_vline (TRUE); 
     5845 
     5846    return strlen (title) + 3; 
     5847} 
     5848 
     5849void 
     5850cut_title (char *title, int max) 
     5851{ 
     5852    title[max] = '\0'; 
     5853    title[max - 1] = '.'; 
     5854    title[max - 2] = '.'; 
     5855    title[max - 3] = '.'; 
     5856} 
     5857 
     5858char * 
     5859get_tab_title (WPanel * p, Tab * t, unsigned int max) 
     5860{ 
     5861    char *result = g_new0 (char, 255); 
     5862    vfs_path_t *path; 
     5863    size_t c; 
     5864    Widget *w = (Widget *) p; 
     5865 
     5866    if (max > (unsigned int) w->cols - 5 || max == 0) 
     5867    { 
     5868        max = w->cols - 5; 
     5869    } 
     5870 
     5871    if (HIGHLIGHT_TAB) 
     5872    { 
     5873        max -= 1; 
     5874    } 
     5875 
     5876    if (t->name) 
     5877    { 
     5878        memcpy (result, t->name, strlen (t->name) + 1); 
     5879        if (max != 0 && strlen (t->name) > max) 
     5880        { 
     5881            cut_title (result, max - (HIGHLIGHT_TAB ? 1 : 0)); 
     5882        } 
     5883        if (HIGHLIGHT_TAB) 
     5884        { 
     5885            strcat (result, "*"); 
     5886        } 
     5887        return result; 
     5888    } 
     5889 
     5890    if (t != p->tabs.current->data) 
     5891    { 
     5892        if (!t->path) 
     5893        { 
     5894            strcpy (result, "Error"); 
     5895            return result; 
     5896        } 
     5897        path = t->path; 
     5898    } 
     5899    else 
     5900    { 
     5901        path = p->cwd_vpath; 
     5902    } 
     5903 
     5904    c = vfs_path_tokens_count (path); 
     5905    if (c == 0) 
     5906    { 
     5907        strcpy (result, "/"); 
     5908        if (HIGHLIGHT_TAB) 
     5909        { 
     5910            strcat (result, "*"); 
     5911        } 
     5912        return result; 
     5913    } 
     5914    g_free (result); 
     5915    result = vfs_path_tokens_get (path, c - 1, 1); 
     5916    if (max != 0 && strlen (result) > max) 
     5917    { 
     5918        cut_title (result, max - (HIGHLIGHT_TAB ? 1 : 0)); 
     5919    } 
     5920    if (HIGHLIGHT_TAB) 
     5921    { 
     5922        strcat (result, "*"); 
     5923    } 
     5924    return result; 
     5925} 
     5926 
     5927TabDisplayInfo * 
     5928display_info (WPanel * p, Widget * w) 
     5929{ 
     5930    int max_length = w->cols - 2; 
     5931    TabDisplayInfo *result = g_new0 (TabDisplayInfo, 1); 
     5932    GList *i; 
     5933    int length = 0, dir = -1; 
     5934    char *title; 
     5935    char *buffer, *current = NULL, *j, *k; 
     5936 
     5937    result->start_tab = result->end_tab = p->tabs.current; 
     5938    result->start_idx = 0; 
     5939    result->end_idx = -1; 
     5940    result->scroll = NO_SCROLL; 
     5941 
     5942    if (p->tabs.list->next == p->tabs.list) 
     5943    { 
     5944        return result; 
     5945    } 
     5946 
     5947    i = p->tabs.list; 
     5948    do 
     5949    { 
     5950        title = TAB_TITLE (p, i->data); 
     5951        length += strlen (title) + 3; 
     5952        g_free (title); 
     5953        i = i->next; 
     5954    } 
     5955    while (i != p->tabs.list); 
     5956 
     5957    i = p->tabs.list; 
     5958    buffer = g_new0 (char, length); 
     5959 
     5960    i = p->tabs.list; 
     5961    j = buffer; 
     5962    do 
     5963    { 
     5964        title = TAB_TITLE (p, i->data); 
     5965        if (p->tabs.current == i) 
     5966        { 
     5967            current = j; 
     5968        } 
     5969        k = g_new0 (char, 2 + strlen (title)); 
     5970        strcpy (k, " "); 
     5971        strcat (k, title); 
     5972        strcpy (title, k); 
     5973        strcat (title, " "); 
     5974        memcpy (j, title, strlen (title)); 
     5975        g_free (k); 
     5976        j += strlen (title); 
     5977        j[0] = 0; 
     5978        j++; 
     5979        g_free (title); 
     5980        i = i->next; 
     5981    } 
     5982    while (i != p->tabs.list); 
     5983 
     5984    length = strlen (current) + 3; 
     5985    j = current; 
     5986    k = current + strlen (j); 
     5987 
     5988    while (length < max_length) 
     5989    { 
     5990        if (dir == -1) 
     5991        { 
     5992            if (j != buffer) 
     5993            { 
     5994                length++; 
     5995                j--; 
     5996                if (*j == 0) 
     5997                { 
     5998                    result->start_tab = result->start_tab->prev; 
     5999                } 
     6000            } 
     6001        } 
     6002        else if (dir == 1) 
     6003        { 
     6004            if (*k != 0 || result->end_tab->next != p->tabs.list) 
     6005            { 
     6006                if (*k == 0) 
     6007                { 
     6008                    result->end_tab = result->end_tab->next; 
     6009                } 
     6010                k++; 
     6011                length++; 
     6012            } 
     6013        } 
     6014 
     6015        dir *= -1; 
     6016 
     6017        if (j == buffer && *k == 0 && result->end_tab->next == p->tabs.list) 
     6018        { 
     6019            break; 
     6020        } 
     6021    } 
     6022 
     6023    if (*j == 0) 
     6024    { 
     6025        result->start_idx = 0; 
     6026        if (result->start_tab != result->end_tab) 
     6027        { 
     6028            result->start_tab = result->start_tab->next; 
     6029        } 
     6030    } 
     6031    else 
     6032    { 
     6033        title = TAB_TITLE (p, result->start_tab->data); 
     6034        if (strcmp (j, " ") == 0) 
     6035        { 
     6036            result->start_idx = strlen (title) - 1; 
     6037        } 
     6038        else 
     6039        { 
     6040            result->start_idx = strlen (title) - strlen (j) + 1; 
     6041            if (strlen (title) == strlen (j) - 1 && result->start_tab != p->tabs.list) 
     6042            { 
     6043                result->scroll = result->scroll | SCROLL_LEFT; 
     6044            } 
     6045        } 
     6046        g_free (title); 
     6047    } 
     6048 
     6049    if (*k == 0) 
     6050    { 
     6051        result->end_idx = -1; 
     6052    } 
     6053    else 
     6054    { 
     6055        title = TAB_TITLE (p, result->end_tab->data); 
     6056        if (strcmp (k, " ") == 0) 
     6057        { 
     6058            result->end_idx = strlen (title); 
     6059            result->scroll = result->scroll | SCROLL_RIGHT; 
     6060        } 
     6061        else 
     6062        { 
     6063            result->end_idx = strlen (title) - strlen (k) + 1; 
     6064            if (result->end_idx < 0) 
     6065            { 
     6066                result->end_idx = 0; 
     6067            } 
     6068        } 
     6069        g_free (title); 
     6070    } 
     6071 
     6072    if (result->start_tab != p->tabs.list || result->start_idx > 0) 
     6073    { 
     6074        result->scroll = result->scroll | SCROLL_LEFT; 
     6075    } 
     6076 
     6077    if (result->end_tab->next != p->tabs.list || result->end_idx != -1) 
     6078    { 
     6079        result->scroll = result->scroll | SCROLL_RIGHT; 
     6080    } 
     6081 
     6082    g_free (buffer); 
     6083 
     6084    return result; 
     6085} 
     6086 
     6087void 
     6088draw_tabs (WPanel * panel) 
     6089{ 
     6090    WPanel *p = (panel == NULL ? current_panel : panel); 
     6091    Widget *w; 
     6092    char *title; 
     6093    int x, y, length; 
     6094    GList *i; 
     6095    TabDisplayInfo *info; 
     6096 
     6097    do 
     6098    { 
     6099        // if (current_panel->frame_size == frame_full && p != current_panel){ 
     6100        //     break;  
     6101        // } 
     6102        if (TABS_VISIBLE (p)) 
     6103        { 
     6104            if (p->tabs.list == NULL) 
     6105            { 
     6106                break; 
     6107            } 
     6108            tty_setcolor (NORMAL_COLOR); 
     6109            w = (Widget *) p; 
     6110 
     6111            x = w->x + 1; 
     6112            if (!TABS_UP (p)) 
     6113            { 
     6114                y = w->y + w->lines - 3;        //w->lines - (the_menubar->is_visible ? 2 : 3); 
     6115                tty_draw_hline (y, x, ACS_HLINE, w->cols - 2); 
     6116                tty_gotoyx (y, w->x); 
     6117                tty_print_alt_char (ACS_LTEE, FALSE); 
     6118                tty_gotoyx (y, w->x + w->cols - 1); 
     6119                tty_print_alt_char (ACS_RTEE, FALSE); 
     6120                tty_gotoyx (y + 1, x); 
     6121            } 
     6122            else 
     6123            { 
     6124                y = w->y; 
     6125                tty_draw_hline (y + 1, x, ACS_HLINE, w->cols - 2); 
     6126                tty_draw_hline (y + 3, x, ACS_HLINE, w->cols - 2); 
     6127                tty_gotoyx (y + 1, w->x); 
     6128                tty_print_alt_char (ACS_LTEE, FALSE); 
     6129                tty_gotoyx (y + 1, w->x + w->cols - 1); 
     6130                tty_print_alt_char (ACS_RTEE, FALSE); 
     6131                tty_gotoyx (y + 3, w->x); 
     6132                tty_print_alt_char (ACS_LTEE, FALSE); 
     6133                tty_gotoyx (y + 3, w->x + w->cols - 1); 
     6134                tty_print_alt_char (ACS_RTEE, FALSE); 
     6135                tty_gotoyx (y + 2, x); 
     6136            } 
     6137            length = w->cols - 2; 
     6138 
     6139            info = display_info (p, w); 
     6140            i = info->start_tab; 
     6141            if (i) 
     6142            { 
     6143                do 
     6144                { 
     6145                    title = TAB_TITLE (p, i->data); 
     6146                    if (i == info->start_tab && info->start_idx != 0) 
     6147                    { 
     6148                        int l = strlen (title) - info->start_idx; 
     6149                        char *title2 = g_new0 (char, l + 1); 
     6150                        memcpy (title2, title + info->start_idx, l + 1); 
     6151                        memcpy (title, title2, strlen (title2)); 
     6152                        title[l] = '\0'; 
     6153                        g_free (title2); 
     6154                    } 
     6155                    if (i == info->end_tab && info->end_idx != -1) 
     6156                    { 
     6157                        title[info->end_idx] = '\0'; 
     6158                    } 
     6159                    if (*title != 0) 
     6160                    { 
     6161                        length -= draw_tab (title, i == p->tabs.current && p == current_panel); 
     6162                    } 
     6163                    g_free (title); 
     6164                    i = i->next; 
     6165                } 
     6166                while (i != info->end_tab->next); 
     6167            } 
     6168            g_free (info); 
     6169 
     6170            tty_print_string (str_fit_to_term (" ", length, J_LEFT)); 
     6171 
     6172            // Draw the scroll signs 
     6173            if ((info->scroll & SCROLL_LEFT) == SCROLL_LEFT) 
     6174            { 
     6175                tty_gotoyx ((TABS_UP (p) ? w->y + 2 : w->lines - 1), w->x + 1); 
     6176                tty_print_string (panel_history_prev_item_sign); 
     6177            } 
     6178 
     6179            if ((info->scroll & SCROLL_RIGHT) == SCROLL_RIGHT) 
     6180            { 
     6181                tty_gotoyx ((TABS_UP (p) ? w->y + 2 : w->lines - 1), w->x + w->cols - 2); 
     6182                tty_print_string (panel_history_next_item_sign); 
     6183            } 
     6184        } 
     6185 
     6186        if (panel != NULL) 
     6187        { 
     6188            break; 
     6189        } 
     6190 
     6191        if (p == other_panel) 
     6192        { 
     6193            p = NULL; 
     6194        } 
     6195        else 
     6196        { 
     6197            p = other_panel; 
     6198        } 
     6199    } 
     6200    while (p); 
     6201} 
     6202 
     6203void 
     6204hide_tabs (void) 
     6205{ 
     6206    WPanel *p = current_panel; 
     6207    Widget *w = WIDGET (p); 
     6208 
     6209    int x = w->x + 1, y = w->lines - (the_menubar->is_visible ? 2 : 3); 
     6210 
     6211    tty_gotoyx (y, x); 
     6212    tty_print_string (str_fit_to_term (" ", w->cols - 2, J_LEFT)); 
     6213    tty_gotoyx (y + 1, x); 
     6214    tty_print_string (str_fit_to_term (" ", w->cols - 2, J_LEFT)); 
     6215} 
     6216 
     6217/* 
     6218 * Processes a click on the tabbar 
     6219 */ 
     6220void 
     6221process_tab_click (unsigned int x) 
     6222{ 
     6223    Widget *w = (Widget *) current_panel; 
     6224    TabDisplayInfo *info = display_info (current_panel, w); 
     6225    GList *i; 
     6226    char *title, *j; 
     6227    unsigned int n; 
     6228    if (x == 2 && ((info->scroll & SCROLL_LEFT) == SCROLL_LEFT)) 
     6229    { 
     6230        change_tab (current_panel, dir_previous, NULL); 
     6231    } 
     6232    else if (x == (unsigned int) (w->cols - 1) && ((info->scroll & SCROLL_RIGHT) == SCROLL_RIGHT)) 
     6233    { 
     6234        change_tab (current_panel, dir_next, NULL); 
     6235    } 
     6236    else 
     6237    { 
     6238        n = 2; 
     6239        for (i = info->start_tab; i != info->end_tab; i = i->next) 
     6240        { 
     6241            title = TAB_TITLE (current_panel, i->data); 
     6242            j = title; 
     6243            if (i == info->start_tab && info->start_idx != 0) 
     6244            { 
     6245                j = title + info->start_idx; 
     6246            } 
     6247            if (x < strlen (j) + 2 + n) 
     6248            { 
     6249                g_free (title); 
     6250                break; 
     6251            } 
     6252 
     6253            n += strlen (j) + 3; 
     6254            g_free (title); 
     6255        } 
     6256 
     6257        change_tab (current_panel, dir_absolute, i); 
     6258    } 
     6259    g_free (info); 
     6260} 
     6261 
     6262void 
     6263move_tab (WPanel * p, enum tabs_direction d) 
     6264{ 
     6265    gpointer i; 
     6266    if (p->tabs.list == p->tabs.list->next) 
     6267    { 
     6268        return; 
     6269    } 
     6270 
     6271    if (d == dir_previous && p->tabs.current == p->tabs.list) 
     6272    { 
     6273        p->tabs.list = p->tabs.list->next; 
     6274        draw_tabs (p); 
     6275        return; 
     6276    } 
     6277 
     6278    if (d == dir_next && p->tabs.current->next == p->tabs.list) 
     6279    { 
     6280        p->tabs.list = p->tabs.current; 
     6281        draw_tabs (p); 
     6282        return; 
     6283    } 
     6284 
     6285    change_tab (p, dir_absolute, p->tabs.current); 
     6286    i = p->tabs.current->data; 
     6287    if (d == dir_next) 
     6288    { 
     6289        p->tabs.current->data = p->tabs.current->next->data; 
     6290        p->tabs.current->next->data = i; 
     6291    } 
     6292    else 
     6293    { 
     6294        p->tabs.current->data = p->tabs.current->prev->data; 
     6295        p->tabs.current->prev->data = i; 
     6296    } 
     6297 
     6298    do_panel_cd (p, ((Tab *) p->tabs.current->data)->path, cd_exact); 
     6299    change_tab (p, d, NULL); 
     6300    draw_tabs (p); 
     6301} 
     6302 
     6303#endif 
    50016304/* --------------------------------------------------------------------------------------------- */ 
  • src/filemanager/panel.h

    diff --git a/src/filemanager/panel.h b/src/filemanager/panel.h
    index 6892a32..9debf08 100644
    a b  
    1717 
    1818/*** typedefs(not structures) and defined constants **********************************************/ 
    1919 
     20#ifdef WITH_TABS 
     21#define MAX_TAB_TITLE 30        /* 0 means full title */ 
     22#define TABS_VISIBLE(p) (((p->tabs.list->next != p->tabs.list) || !tabs_options.hide_tabs) && ((current_panel->list_type != list_long && other_panel->list_type != list_long) || p == current_panel)) 
     23#define TABS_UP(p) (tabs_options.bar_position == TOP && TABS_VISIBLE(p)) 
     24#define HIGHLIGHT_TAB (t == p->tabs.current->data && p != current_panel && tabs_options.highlight_current_tab) 
     25#define TAB_TITLE(p, tab) get_tab_title(p, (Tab *) tab, MAX_TAB_TITLE) 
     26#endif 
     27 
    2028#define PANEL(x) ((WPanel *)(x)) 
    2129#define selection(p) (&(p->dir.list[p->selected])) 
    2230#define DEFAULT_USER_FORMAT "half type name | size | perm" 
     
    2735 
    2836/*** enums ***************************************************************************************/ 
    2937 
     38#ifdef WITH_TABS 
     39enum tabs_direction 
     40{ 
     41    dir_next, 
     42    dir_previous, 
     43    dir_first, 
     44    dir_last, 
     45    dir_absolute 
     46}; 
     47 
     48enum tabs_scroll_flags 
     49{ 
     50    NO_SCROLL = 0, 
     51    SCROLL_LEFT = 1, 
     52    SCROLL_RIGHT = 2, 
     53    SCROLL_BOTH = 3 
     54}; 
     55#endif 
     56 
    3057enum list_types 
    3158{ 
    3259    list_full,                  /* Name, size, perm/date */ 
    enum cd_enum 
    6693 
    6794/*** structures declarations (and typedefs of structures)*****************************************/ 
    6895 
     96#ifdef WITH_TABS 
     97typedef struct TabDisplayInfo 
     98{ 
     99    GList *start_tab; 
     100    GList *end_tab; 
     101    int start_idx, end_idx; 
     102    enum tabs_scroll_flags scroll; 
     103} TabDisplayInfo; 
     104 
     105typedef struct Tab 
     106{ 
     107    char *name; 
     108    vfs_path_t *path; 
     109} Tab; 
     110 
     111typedef struct TabsInfo 
     112{ 
     113    GList *list; 
     114    GList *current; 
     115    int do_not_delete; 
     116} TabsInfo; 
     117 
     118typedef struct RestoredTabs 
     119{ 
     120    GList *list; 
     121    GList *current; 
     122    int idx; 
     123    int error; 
     124} RestoredTabs; 
     125#endif 
     126 
    69127struct format_e; 
    70128 
    71129typedef struct panel_field_struct 
    typedef struct 
    99157    vfs_path_t *lwd_vpath;      /* Last Working Directory */ 
    100158    GList *dir_history;         /* directory history */ 
    101159    GList *dir_history_current; /* pointer to the current history item */ 
     160#ifdef WITH_TABS 
     161    TabsInfo tabs; 
     162#endif 
    102163    char *hist_name;            /* directory history name for history file */ 
    103164    int marked;                 /* Count of marked files */ 
    104165    int dirs_marked;            /* Count of marked directories */ 
    extern hook_t *select_file_hook; 
    151212 
    152213extern mc_fhl_t *mc_filehighlight; 
    153214 
     215#ifdef WITH_TABS 
     216GList *saved_tabs; 
     217#endif 
     218 
    154219/*** declarations of public functions ************************************************************/ 
    155220 
     221#ifdef WITH_TABS 
     222/*Tabs functions */ 
     223void draw_tabs (WPanel * panel); 
     224void hide_tabs (void); 
     225void create_tab (WPanel * p, enum tabs_direction d, Tab * t); 
     226void change_tab (WPanel * p, enum tabs_direction d, 
     227                 GList * tab /*used only for absolute direction */ ); 
     228void destroy_tab (Tab * t); 
     229void destroy_tabs (WPanel * p); 
     230char *get_tab_title (WPanel * p, Tab * t, unsigned int max); 
     231void save_tabs_session (char *title); 
     232void restore_tabs_session (char *title); 
     233void save_tabs_session_custom (); 
     234void restore_tabs_session_custom (); 
     235void move_tab_to_other_panel (void); 
     236void copy_tab_to_other_panel (void); 
     237void swap_tabs (void); 
     238void process_tab_click (unsigned int x); 
     239void move_tab (WPanel * p, enum tabs_direction d); 
     240 
     241enum tabs_direction get_new_tabs_direction (void); 
     242void new_tab (WPanel * panel); 
     243void close_tab (WPanel * p); 
     244void rename_tab (WPanel * p); 
     245int get_tab_index (WPanel * p, GList * t); 
     246GList *get_tab_by_index (WPanel * p, int idx); 
     247RestoredTabs _restore_tabs (FILE * f); 
     248void abort_restore (RestoredTabs restored); 
     249void save_tabs_session_custom (void); 
     250void restore_tabs_session_custom (void); 
     251void _write_tabs (FILE * f, WPanel * p); 
     252void read_line (char *line, int max, FILE * f); 
     253void goto_tab (WPanel * p); 
     254void cut_title (char *title, int max); 
     255TabDisplayInfo *display_info (WPanel * p, Widget * w); 
     256int draw_tab (char *title, int selected); 
     257/*End tabs functions */ 
     258#endif 
     259 
    156260WPanel *panel_new_with_dir (const char *panel_name, const vfs_path_t * vpath); 
    157261void panel_clean_dir (WPanel * panel); 
    158262 
  • src/setup.c

    diff --git a/src/setup.c b/src/setup.c
    index 6e5465c..4ba3028 100644
    a b panels_options_t panels_options = { 
    147147    .select_flags = SELECT_MATCH_CASE | SELECT_SHELL_PATTERNS 
    148148}; 
    149149 
     150#ifdef WITH_TABS 
     151tabs_options_t tabs_options = { 
     152    .open_where = AFTER_CURRENT, 
     153    .hide_tabs = FALSE, 
     154    .restore_on_load = TRUE, 
     155    .sessions_folder = NULL, 
     156    .bar_position = TOP, 
     157    .highlight_current_tab = TRUE 
     158}; 
     159#endif 
     160 
    150161int easy_patterns = 1; 
    151162 
    152163/* It true saves the setup when quitting */ 
    GArray *macros_list; 
    224235static char *profile_name = NULL;       /* ${XDG_CONFIG_HOME}/mc/ini */ 
    225236static char *panels_profile_name = NULL;        /* ${XDG_CACHE_HOME}/mc/panels.ini */ 
    226237 
     238#ifdef WITH_TABS 
     239static char *tabs_sessions_folder = NULL;       /*${XDG_CONFIG_HOME}/mc/tabs.sessions */ 
     240#endif 
     241 
    227242/* *INDENT-OFF* */ 
    228243static const struct 
    229244{ 
    static const struct 
    404419    { "torben_fj_mode", &panels_options.torben_fj_mode }, 
    405420    { NULL, NULL } 
    406421}; 
     422#ifdef WITH_TABS 
     423static const struct 
     424{ 
     425    const char *opt_name; 
     426    gboolean *opt_addr; 
     427} tabs_ini_options[] = { 
     428    { "hide_tabs", &tabs_options.hide_tabs }, 
     429    { "highlight_current_tab", &tabs_options.highlight_current_tab }, 
     430    { "restore_on_load", &tabs_options.restore_on_load }, 
     431    { NULL, NULL } 
     432}; 
     433#endif 
    407434/* *INDENT-ON* */ 
    408435 
    409436/*** file scope functions ************************************************************************/ 
    load_setup (void) 
    928955    } 
    929956 
    930957    panels_profile_name = mc_config_get_full_path (MC_PANELS_FILE); 
     958#ifdef WITH_TABS 
     959    tabs_sessions_folder = mc_config_get_full_path (MC_TABS_SESSION_SUBDIR); 
     960 
     961    tabs_options.sessions_folder = tabs_sessions_folder; 
     962    //memcpy(tabs_options.sessions_folder, tabs_sessions_folder, strlen(tabs_sessions_folder) + 1); 
     963 
     964    if (!exist_file (tabs_sessions_folder)) 
     965    { 
     966        mkdir (tabs_sessions_folder, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); 
     967    } 
     968#endif 
    931969 
    932970    mc_main_config = mc_config_init (profile, FALSE); 
    933971 
    load_setup (void) 
    9671005 
    9681006    load_layout (); 
    9691007    panels_load_options (); 
     1008#ifdef WITH_TABS 
     1009    tabs_load_options (); 
     1010#endif 
    9701011    load_panelize (); 
    9711012 
    9721013    startup_left_mode = setup__load_panel_state ("New Left Panel"); 
    save_setup (gboolean save_options, gboolean save_panel_options) 
    10671108        save_config (); 
    10681109        save_layout (); 
    10691110        panels_save_options (); 
     1111#ifdef WITH_TABS 
     1112        tabs_save_options (); 
     1113#endif 
    10701114        save_panelize (); 
    10711115        /* directory_history_save (); */ 
    10721116 
    done_setup (void) 
    11221166    g_free (mc_global.tty.setup_color_string); 
    11231167    g_free (profile_name); 
    11241168    g_free (panels_profile_name); 
     1169#ifdef WITH_TABS 
     1170    g_free (tabs_sessions_folder); 
     1171#endif 
    11251172    mc_config_deinit (mc_main_config); 
    11261173    mc_config_deinit (mc_panels_config); 
    11271174 
    panels_save_options (void) 
    14801527                       "select_flags", (int) panels_options.select_flags); 
    14811528} 
    14821529 
     1530#ifdef WITH_TABS 
     1531/** 
     1532  Load tabs options from [Tabs] section. 
     1533*/ 
     1534void 
     1535tabs_load_options (void) 
     1536{ 
     1537    if (mc_config_has_group (mc_main_config, CONFIG_TABS_SECTION)) 
     1538    { 
     1539        size_t i; 
     1540 
     1541        for (i = 0; tabs_ini_options[i].opt_name != NULL; i++) 
     1542            *tabs_ini_options[i].opt_addr = 
     1543                mc_config_get_bool (mc_main_config, CONFIG_TABS_SECTION, 
     1544                                    tabs_ini_options[i].opt_name, *tabs_ini_options[i].opt_addr); 
     1545 
     1546        tabs_options.open_where = mc_config_get_int (mc_main_config, CONFIG_TABS_SECTION, 
     1547                                                     "open_where", (int) tabs_options.open_where); 
     1548 
     1549        tabs_options.bar_position = mc_config_get_int (mc_main_config, CONFIG_TABS_SECTION, 
     1550                                                       "bar_position", 
     1551                                                       (int) tabs_options.bar_position); 
     1552    } 
     1553} 
     1554 
     1555void 
     1556tabs_save_options (void) 
     1557{ 
     1558    size_t i; 
     1559 
     1560    for (i = 0; tabs_ini_options[i].opt_name != NULL; i++) 
     1561        mc_config_set_bool (mc_main_config, CONFIG_TABS_SECTION, 
     1562                            tabs_ini_options[i].opt_name, *tabs_ini_options[i].opt_addr); 
     1563 
     1564    mc_config_set_int (mc_main_config, CONFIG_TABS_SECTION, 
     1565                       "open_where", (int) tabs_options.open_where); 
     1566 
     1567    mc_config_set_int (mc_main_config, CONFIG_TABS_SECTION, 
     1568                       "bar_position", (int) tabs_options.bar_position); 
     1569} 
     1570#endif 
    14831571/* --------------------------------------------------------------------------------------------- */ 
  • src/setup.h

    diff --git a/src/setup.h b/src/setup.h
    index ea4cbff..677918e 100644
    a b typedef enum 
    2929    QSEARCH_NUM 
    3030} qsearch_mode_t; 
    3131 
     32#ifdef WITH_TABS 
     33typedef enum 
     34{ 
     35    BEFORE_CURRENT = 0, 
     36    AFTER_CURRENT = 1, 
     37    AT_END = 2, 
     38    AT_BEGINNING = 3, 
     39    TABS_NUM 
     40} tabs_open_t; 
     41 
     42typedef enum 
     43{ 
     44    TOP = 0, 
     45    BOTTOM = 1, 
     46    POS_NUM 
     47} bar_position_t; 
     48#endif 
    3249/*** structures declarations (and typedefs of structures)*****************************************/ 
    3350 
    3451/* panels ini options; [Panels] section */ 
    typedef struct 
    5673    panel_select_flags_t select_flags;  /* Select/unselect file flags */ 
    5774} panels_options_t; 
    5875 
     76#ifdef WITH_TABS 
     77typedef struct 
     78{ 
     79    tabs_open_t open_where;     /* Where to open a new tab */ 
     80    gboolean hide_tabs;         /* If TRUE, hide the tabs when only one tab */ 
     81    gboolean restore_on_load;   /* If TRUE, restore tabs when starting mc */ 
     82    gboolean highlight_current_tab;     /* If TRUE, highlight with an * the current tab in the other panel */ 
     83    char *sessions_folder;      /* If TRUE, restore tabs when starting mc */ 
     84    bar_position_t bar_position;        /* Where to place the tabs bar */ 
     85} tabs_options_t; 
     86#endif 
     87 
    5988typedef struct macro_action_t 
    6089{ 
    6190    unsigned long action; 
    extern int file_op_compute_totals; 
    99128extern int editor_ask_filename_before_edit; 
    100129 
    101130extern panels_options_t panels_options; 
     131#ifdef WITH_TABS 
     132extern tabs_options_t tabs_options; 
     133#endif 
    102134 
    103135extern panel_view_mode_t startup_left_mode; 
    104136extern panel_view_mode_t startup_right_mode; 
    void panel_save_setup (WPanel * panel, const char *section); 
    159191void panels_load_options (void); 
    160192void panels_save_options (void); 
    161193 
     194#ifdef WITH_TABS 
     195void tabs_save_options (void); 
     196void tabs_load_options (void); 
     197#endif 
     198 
    162199/*** inline functions ****************************************************************************/ 
    163200 
    164201#endif /* MC__SETUP_H */