From efdb64546892d0bc5ba83759846d4fcffa886687 Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Mon, 2 Nov 2009 17:01:08 +0300 Subject: [PATCH] Implemeted keybindings for Tree widget Signed-off-by: Andrew Borodin --- misc/mc.keymap.default | 21 +- misc/mc.keymap.emacs | 19 ++ src/boxes.c | 1 + src/cmddef.h | 20 ++ src/keybind.c | 80 +++++- src/keybind.h | 3 + src/main.c | 12 +- src/main.h | 2 + src/setup.c | 4 + src/tree.c | 583 ++++++++++++++++++++++------------------- src/tree.h | 16 +- 11 files changed, 455 insertions(+), 306 deletions(-) diff --git a/misc/mc.keymap.default b/misc/mc.keymap.default index f571d0d61..0c9e02873 100644 --- a/misc/mc.keymap.default +++ b/misc/mc.keymap.default @@ -298,7 +298,7 @@ InputBackwardDelete = backspace InputDeleteChar = delete InputKillWord = alt-d InputBackwardKillWord = alt-backspace -InputSetMark = +InputSetMark = InputKillRegion = ctrl-w InputXStore = alt-w InputXPaste = @@ -309,3 +309,22 @@ InputHistoryNext = alt-n; ctrl-up InputHistoryShow = alt-h InputComplete = alt-tab InputClearLine = + +[tree] +TreeHelp = f1 +TreeForget = f3 +TreeToggleNav = f4 +TreeCopy = f5 +TreeMove = f6 +TreeMoveUp = up; ctrl-p +TreeMoveDown = down; ctrl-n +TreeMoveLeft = left +TreeMoveRight = right +TreeMoveHome = home; alt-lt +TreeMoveEnd = end; alt-gt +TreeMovePgUp = pgup; alt-v +TreeMovePgDn = pgdn; ctrl-v +TreeOpen = enter +TreeRescan = f2; ctrl-r +TreeStartSearch = ctrl-s; alt-s +TreeRemove = f8; delete diff --git a/misc/mc.keymap.emacs b/misc/mc.keymap.emacs index 1acb5cd99..47c06a60e 100644 --- a/misc/mc.keymap.emacs +++ b/misc/mc.keymap.emacs @@ -313,3 +313,22 @@ InputHistoryNext = alt-n; ctrl-up InputHistoryShow = alt-h InputComplete = alt-tab InputClearLine = + +[tree] +TreeHelp = f1 +TreeForget = f3 +TreeToggleNav = f4 +TreeCopy = f5 +TreeMove = f6 +TreeMoveUp = up; ctrl-p +TreeMoveDown = down; ctrl-n +TreeMoveLeft = left +TreeMoveRight = right +TreeMoveHome = home; alt-lt +TreeMoveEnd = end; alt-gt +TreeMovePgUp = pgup; alt-v +TreeMovePgDn = pgdn; ctrl-v +TreeOpen = enter +TreeRescan = f2; ctrl-r +TreeStartSearch = ctrl-s; alt-s +TreeRemove = f8; delete diff --git a/src/boxes.c b/src/boxes.c index b1ab84607..5bfd1b991 100644 --- a/src/boxes.c +++ b/src/boxes.c @@ -674,6 +674,7 @@ tree_box (const char *current_dir) add_widget (dlg, mytree); bar = buttonbar_new(1); add_widget (dlg, bar); + /* restore ButtonBar coordinates after add_widget() */ ((Widget *) bar)->x = 0; ((Widget *) bar)->y = LINES - 1; diff --git a/src/cmddef.h b/src/cmddef.h index 26441300c..c42dab903 100644 --- a/src/cmddef.h +++ b/src/cmddef.h @@ -251,6 +251,26 @@ #define CK_HexViewToggleNavigationMode 5018 #define CK_ViewQuit 5020 +/* Tree */ +#define CK_TreeHelp 6001 +#define CK_TreeForget 6003 +#define CK_TreeToggleNav 6004 +#define CK_TreeCopy 6005 +#define CK_TreeMove 6006 +#define CK_TreeMake 6007 +#define CK_TreeMoveUp 6011 +#define CK_TreeMoveDown 6012 +#define CK_TreeMoveLeft 6013 +#define CK_TreeMoveRight 6014 +#define CK_TreeMoveHome 6015 +#define CK_TreeMoveEnd 6016 +#define CK_TreeMovePgUp 6017 +#define CK_TreeMovePgDn 6018 +#define CK_TreeOpen 6019 +#define CK_TreeRescan 6020 +#define CK_TreeStartSearch 6021 +#define CK_TreeRemove 6022 + /* main commands */ #define CK_AddHotlist 7001 #define CK_ChmodCmd 7002 diff --git a/src/keybind.c b/src/keybind.c index ef0d15f81..115ed64b7 100644 --- a/src/keybind.c +++ b/src/keybind.c @@ -215,7 +215,7 @@ static name_keymap_t command_names[] = { { "EditMaximize", CK_Maximize }, #endif -#endif +#endif /* USE_INTERNAL_EDIT */ /* viewer */ { "ViewSearch", CK_ViewSearch }, @@ -238,6 +238,26 @@ static name_keymap_t command_names[] = { { "HexViewToggleNavigationMode", CK_HexViewToggleNavigationMode }, { "ViewQuit", CK_ViewQuit }, + /* tree */ + { "TreeHelp", CK_TreeHelp }, + { "TreeForget", CK_TreeForget }, + { "TreeToggleNav", CK_TreeToggleNav }, + { "TreeCopy", CK_TreeCopy }, + { "TreeMove", CK_TreeMove }, + { "TreeMake", CK_TreeMake }, + { "TreeMoveUp", CK_TreeMoveUp }, + { "TreeMoveDown", CK_TreeMoveDown }, + { "TreeMoveLeft", CK_TreeMoveLeft }, + { "TreeMoveRight", CK_TreeMoveRight }, + { "TreeMoveHome", CK_TreeMoveHome }, + { "TreeMoveEnd", CK_TreeMoveEnd }, + { "TreeMovePgUp", CK_TreeMovePgUp }, + { "TreeMovePgDn", CK_TreeMovePgDn }, + { "TreeOpen", CK_TreeOpen }, + { "TreeRescan", CK_TreeRescan }, + { "TreeStartSearch", CK_TreeStartSearch }, + { "TreeRemove", CK_TreeRemove }, + /* main commands */ { "CmdChmod", CK_ChmodCmd }, { "CmdMenuLastSelected", CK_MenuLastSelectedCmd }, @@ -398,7 +418,7 @@ static name_keymap_t command_names[] = { { "ShowCommandLine", CK_ShowCommandLine }, { "SelectCodepage", CK_SelectCodepage }, - { NULL, 0 } + { NULL, CK_Ignore_Key } }; static const size_t num_command_names = sizeof (command_names) / @@ -458,7 +478,7 @@ const global_keymap_t default_viewer_keymap[] = { { ALT ('e'), CK_SelectCodepage, "M-e" }, { XCTRL ('o'), CK_ShowCommandLine, "C-o" }, - { 0, 0, "" } + { 0, CK_Ignore_Key, "" } }; const global_keymap_t default_viewer_hex_keymap[] = { @@ -480,7 +500,7 @@ const global_keymap_t default_viewer_hex_keymap[] = { { KEY_DOWN, CK_ViewMoveDown, "Down" }, { KEY_DC, CK_ViewMoveDown, "Delete" }, - { 0, 0, "" } + { 0, CK_Ignore_Key, "" } }; #ifdef USE_INTERNAL_EDIT @@ -604,17 +624,52 @@ const global_keymap_t default_editor_keymap[] = { { XCTRL ('x'), CK_Ext_Mode, "C-x" }, - { 0, 0, "" } + { 0, CK_Ignore_Key, "" } }; /* emacs keyboard layout emulation */ const global_keymap_t default_editor_x_keymap[] = { { 'k', CK_New, "k"}, { 'e', CK_Execute_Macro, "e"}, - { 0, 0, "" } + { 0, CK_Ignore_Key, "" } }; #endif +/* tree */ +const global_keymap_t default_tree_keymap[] = { + { KEY_F (1), CK_TreeHelp, "F1"}, + { KEY_F (2), CK_TreeRescan, "F2" }, + { KEY_F (3), CK_TreeForget, "F3" }, + { KEY_F (4), CK_TreeToggleNav, "F4" }, + { KEY_F (5), CK_TreeCopy, "F5" }, + { KEY_F (6), CK_TreeMove, "F6" }, +#if 0 + { KEY_F (7), CK_TreeMake, "F7" }, +#endif + { KEY_F (8), CK_TreeRemove, "F8" }, + { KEY_UP, CK_TreeMoveUp, "Up" }, + { XCTRL ('p'), CK_TreeMoveUp, "C-p" }, + { KEY_DOWN, CK_TreeMoveDown, "Down" }, + { XCTRL ('n'), CK_TreeMoveDown, "C-n" }, + { KEY_LEFT, CK_TreeMoveLeft, "Left" }, + { KEY_RIGHT, CK_TreeMoveRight, "Right" }, + { KEY_HOME, CK_TreeMoveHome, "Home" }, + { ALT ('<'), CK_TreeMoveHome, "M-<" }, + { KEY_END, CK_TreeMoveEnd , "End" }, + { ALT ('>'), CK_TreeMoveEnd , "M->" }, + { KEY_PPAGE, CK_TreeMovePgUp, "PgUp" }, + { ALT ('v'), CK_TreeMovePgUp, "M-v" }, + { KEY_NPAGE, CK_TreeMovePgDn, "PnDn" }, + { XCTRL ('v'), CK_TreeMovePgDn, "C-v" }, + { '\n', CK_TreeOpen, "Enter" }, + { KEY_ENTER, CK_TreeOpen, "Enter" }, + { XCTRL ('r'), CK_TreeRescan, "C-r" }, + { XCTRL ('s'), CK_TreeStartSearch, "C-s" }, + { ALT ('s'), CK_TreeStartSearch, "M-s" }, + { KEY_DC, CK_TreeRemove, "Delete" }, + { 0, CK_Ignore_Key, ""} +}; + /* screen.c */ const global_keymap_t default_panel_keymap[] = { { ALT ('o'), CK_PanelChdirOtherPanel, "M-o" }, @@ -651,8 +706,7 @@ const global_keymap_t default_panel_keymap[] = { { XCTRL ('s'), CK_PanelStartSearch, "C-s" }, { ALT ('s'), CK_PanelStartSearch, "M-s" }, { ALT ('i'), CK_PanelSyncOtherPanel, "M-i" }, - - { 0, 0 , "" } + { 0, CK_Ignore_Key , "" } }; /* main.c */ @@ -696,8 +750,7 @@ const global_keymap_t default_main_map[] = { { ALT ('*'), CK_SelectCmd, "M-*" }, { KEY_KP_ADD, CK_UnselectCmd, "Gray+" }, { KEY_KP_SUBTRACT, CK_ReverseSelectionCmd, "Gray-" }, - - { 0, 0, "" } + { 0, CK_Ignore_Key, "" } }; const global_keymap_t default_main_x_map[] = { @@ -725,8 +778,7 @@ const global_keymap_t default_main_x_map[] = { #ifdef WITH_BACKGROUND { 'j', CK_JobsCmd, "j" }, #endif /* WITH_BACKGROUND */ - - { 0, 0, "" } + { 0, CK_Ignore_Key, "" } }; const global_keymap_t default_input_keymap[] = { @@ -769,7 +821,7 @@ const global_keymap_t default_input_keymap[] = { /* Completion */ { ALT ('\t'), CK_InputComplete, "M-tab" }, - { 0, 0, "" } + { 0, CK_Ignore_Key, "" } }; static int @@ -804,7 +856,7 @@ lookup_action (const char *keyname) res = bsearch (&key, command_names, num_command_names, sizeof (command_names[0]), name_keymap_comparator); - return (res != NULL) ? res->val : 0; + return (res != NULL) ? res->val : CK_Ignore_Key; } static void diff --git a/src/keybind.h b/src/keybind.h index 3a771bf1c..2a1d3e0e9 100644 --- a/src/keybind.h +++ b/src/keybind.h @@ -38,6 +38,9 @@ extern const global_keymap_t default_editor_keymap[]; extern const global_keymap_t default_editor_x_keymap[]; #endif +/* tree.c */ +extern const global_keymap_t default_tree_keymap[]; + /* screen.c */ extern const global_keymap_t default_panel_keymap[]; diff --git a/src/main.c b/src/main.c index 3d4feeb25..37dfae393 100644 --- a/src/main.c +++ b/src/main.c @@ -316,6 +316,7 @@ GArray *main_keymap = NULL; GArray *main_x_keymap = NULL; GArray *panel_keymap = NULL; GArray *input_keymap = NULL; +GArray *tree_keymap = NULL; const global_keymap_t *main_map; const global_keymap_t *main_x_map; @@ -1879,26 +1880,25 @@ do_nc (void) check_codeset (); main_map = default_main_map; - if (main_keymap && main_keymap->len > 0) main_map = (global_keymap_t *) main_keymap->data; main_x_map = default_main_x_map; - if (main_x_keymap && main_x_keymap->len > 0) main_x_map = (global_keymap_t *) main_x_keymap->data; panel_map = default_panel_keymap; - - if (panel_keymap && panel_keymap->len > 0) { + if (panel_keymap && panel_keymap->len > 0) panel_map = (global_keymap_t *) panel_keymap->data; - } input_map = default_input_keymap; - if (input_keymap && input_keymap->len > 0) input_map = (global_keymap_t *) input_keymap->data; + tree_map = default_tree_keymap; + if (tree_keymap && tree_keymap->len > 0) + tree_map = (global_keymap_t *) tree_keymap->data; + /* Check if we were invoked as an editor or file viewer */ if (!mc_maybe_editor_or_viewer ()) { setup_panels_and_run_mc (); diff --git a/src/main.h b/src/main.h index 1c195ff0d..ea94e394b 100644 --- a/src/main.h +++ b/src/main.h @@ -83,11 +83,13 @@ extern GArray *viewer_keymap; extern GArray *viewer_hex_keymap; extern GArray *main_keymap; extern GArray *main_x_keymap; +extern GArray *tree_keymap; extern GArray *panel_keymap; extern GArray *input_keymap; extern const global_keymap_t *panel_map; extern const global_keymap_t *input_map; +extern const global_keymap_t *tree_map; #ifdef HAVE_SUBSHELL_SUPPORT void do_update_prompt (void); diff --git a/src/setup.c b/src/setup.c index 720fb5170..bc5b1f853 100644 --- a/src/setup.c +++ b/src/setup.c @@ -1011,6 +1011,9 @@ load_keymap_defs (void) input_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t)); load_keymap_from_section ("input", input_keymap, mc_global_keymap); + tree_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t)); + load_keymap_from_section ("tree", tree_keymap, mc_global_keymap); + mc_config_deinit (mc_global_keymap); } } @@ -1028,6 +1031,7 @@ free_keymap_defs (void) g_array_free (main_x_keymap, TRUE); g_array_free (panel_keymap, TRUE); g_array_free (input_keymap, TRUE); + g_array_free (tree_keymap, TRUE); } void diff --git a/src/tree.c b/src/tree.c index e85ebd126..a2e4fa24b 100644 --- a/src/tree.c +++ b/src/tree.c @@ -54,23 +54,26 @@ #include "main-widgets.h" /* the_menubar */ #include "menu.h" /* menubar_visible */ #include "file.h" /* copy_dir_dir(), move_dir_dir(), erase_dir() */ +#include "layout.h" /* command_prompt */ #include "help.h" #include "treestore.h" #include "cmd.h" +#include "cmddef.h" +#include "keybind.h" #include "history.h" #include "strutil.h" -#include "tree.h" #include "fileloc.h" +#include "tree.h" -#define tlines(t) (t->is_panel ? t->widget.lines-2 - (show_mini_info ? 2 : 0) : t->widget.lines) +const global_keymap_t *tree_map; -extern int command_prompt; +#define tlines(t) (t->is_panel ? t->widget.lines - 2 - (show_mini_info ? 2 : 0) : t->widget.lines) /* Use the color of the parent widget for the unselected entries */ #define TREE_NORMALC(h) (DLG_NORMALC (h)) /* Specifies the display mode: 1d or 2d */ -static int tree_navigation_flag; +static gboolean tree_navigation_flag = FALSE; struct WTree { Widget widget; @@ -86,10 +89,11 @@ struct WTree { }; /* Forwards */ -static void save_tree (WTree *tree); -static void tree_rescan_cmd (WTree *); +static void tree_rescan (void *data); +static void tree_toggle_f4 (void *data); -static tree_entry *back_ptr (tree_entry *ptr, int *count) +static tree_entry * +back_ptr (tree_entry *ptr, int *count) { int i = 0; @@ -101,7 +105,8 @@ static tree_entry *back_ptr (tree_entry *ptr, int *count) return ptr; } -static tree_entry *forw_ptr (tree_entry *ptr, int *count) +static tree_entry * +forw_ptr (tree_entry *ptr, int *count) { int i = 0; @@ -116,23 +121,45 @@ static tree_entry *forw_ptr (tree_entry *ptr, int *count) static void remove_callback (tree_entry *entry, void *data) { - WTree *tree = data; + WTree *tree = data; - if (tree->selected_ptr == entry){ - if (tree->selected_ptr->next) - tree->selected_ptr = tree->selected_ptr->next; - else - tree->selected_ptr = tree->selected_ptr->prev; - } + if (tree->selected_ptr == entry){ + if (tree->selected_ptr->next) + tree->selected_ptr = tree->selected_ptr->next; + else + tree->selected_ptr = tree->selected_ptr->prev; + } } -static void tree_remove_entry (WTree *tree, char *name) +/* Save the ~/.mc/Tree file */ +static void +save_tree (WTree *tree) +{ + int error; + char *tree_name; + + (void) tree; + error = tree_store_save (); + + + if (error){ + tree_name = g_build_filename (home_dir, MC_USERCONF_DIR, + MC_TREESTORE_FILE, (char *) NULL); + fprintf (stderr, _("Cannot open the %s file for writing:\n%s\n"), tree_name, + unix_error_string (error)); + g_free (tree_name); + } +} + +static void +tree_remove_entry (WTree *tree, char *name) { (void) tree; tree_store_remove_entry (name); } -static void tree_destroy (WTree *tree) +static void +tree_destroy (WTree *tree) { tree_store_remove_entry_remove_hook (remove_callback); save_tree (tree); @@ -143,7 +170,8 @@ static void tree_destroy (WTree *tree) } /* Loads the .mc.tree file */ -static void load_tree (WTree *tree) +static void +load_tree (WTree *tree) { tree_store_load (); @@ -151,25 +179,8 @@ static void load_tree (WTree *tree) tree_chdir (tree, home_dir); } -/* Save the .mc.tree file */ -static void save_tree (WTree *tree) -{ - int error; - char *tree_name; - - (void) tree; - error = tree_store_save (); - - - if (error){ - tree_name = g_build_filename (home_dir, MC_USERCONF_DIR, MC_TREESTORE_FILE, NULL); - fprintf (stderr, _("Cannot open the %s file for writing:\n%s\n"), tree_name, - unix_error_string (error)); - g_free(tree_name); - } -} - -static void tree_show_mini_info (WTree *tree, int tree_lines, int tree_cols) +static void +tree_show_mini_info (WTree *tree, int tree_lines, int tree_cols) { Dlg_head *h = tree->widget.parent; int line; @@ -202,7 +213,8 @@ static void tree_show_mini_info (WTree *tree, int tree_lines, int tree_cols) } } -static void show_tree (WTree *tree) +static void +show_tree (WTree *tree) { Dlg_head *h = tree->widget.parent; tree_entry *current; @@ -238,7 +250,9 @@ static void show_tree (WTree *tree) current = tree->selected_ptr; /* Calculate the directory which is to be shown on the topmost line */ - if (tree_navigation_flag){ + if (!tree_navigation_flag) + current = back_ptr (current, &tree->topdiff); + else { i = 0; while (current->prev && i < tree->topdiff){ current = current->prev; @@ -258,8 +272,7 @@ static void show_tree (WTree *tree) } } tree->topdiff = i; - } else - current = back_ptr (current, &tree->topdiff); + } /* Loop for every line */ for (i = 0; i < tree_lines; i++){ @@ -348,7 +361,8 @@ static void show_tree (WTree *tree) tree_show_mini_info (tree, tree_lines, tree_cols); } -static void check_focus (WTree *tree) +static void +tree_check_focus (WTree *tree) { if (tree->topdiff < 3) tree->topdiff = 3; @@ -356,34 +370,40 @@ static void check_focus (WTree *tree) tree->topdiff = tlines (tree) - 3 - 1; } -static void tree_move_backward (WTree *tree, int i) +static void +tree_move_backward (WTree *tree, int i) { - tree_entry *current; - int j = 0; + if (!tree_navigation_flag) + tree->selected_ptr = back_ptr (tree->selected_ptr, &i); + else { + tree_entry *current; + int j = 0; - if (tree_navigation_flag){ current = tree->selected_ptr; while (j < i && current->prev && current->prev->sublevel >= tree->selected_ptr->sublevel){ current = current->prev; if (current->sublevel == tree->selected_ptr->sublevel){ tree->selected_ptr = current; - j ++; + j++; } } i = j; - } else - tree->selected_ptr = back_ptr (tree->selected_ptr, &i); + } + tree->topdiff -= i; - check_focus (tree); + tree_check_focus (tree); } -static void tree_move_forward (WTree *tree, int i) +static void +tree_move_forward (WTree *tree, int i) { - tree_entry *current; - int j = 0; + if (!tree_navigation_flag) + tree->selected_ptr = forw_ptr (tree->selected_ptr, &i); + else { + tree_entry *current; + int j = 0; - if (tree_navigation_flag){ current = tree->selected_ptr; while (j < i && current->next && current->next->sublevel >= tree->selected_ptr->sublevel){ @@ -394,13 +414,14 @@ static void tree_move_forward (WTree *tree, int i) } } i = j; - } else - tree->selected_ptr = forw_ptr (tree->selected_ptr, &i); + } + tree->topdiff += i; - check_focus (tree); + tree_check_focus (tree); } -static void tree_move_to_child (WTree *tree) +static void +tree_move_to_child (WTree *tree) { tree_entry *current; @@ -414,26 +435,28 @@ static void tree_move_to_child (WTree *tree) /* Yes -> select this entry */ tree->selected_ptr = current; tree->topdiff++; - check_focus (tree); + tree_check_focus (tree); } else { /* No -> rescan and try again */ - tree_rescan_cmd (tree); + tree_rescan (tree); current = tree->selected_ptr->next; if (current && current->sublevel > tree->selected_ptr->sublevel){ tree->selected_ptr = current; tree->topdiff++; - check_focus (tree); + tree_check_focus (tree); } } } -static int tree_move_to_parent (WTree *tree) +static gboolean +tree_move_to_parent (WTree *tree) { tree_entry *current; tree_entry *old; if (!tree->selected_ptr) - return 0; + return FALSE; + old = tree->selected_ptr; current = tree->selected_ptr->prev; while (current && current->sublevel >= tree->selected_ptr->sublevel){ @@ -443,39 +466,24 @@ static int tree_move_to_parent (WTree *tree) if (!current) current = tree->store->tree_first; tree->selected_ptr = current; - check_focus (tree); + tree_check_focus (tree); return tree->selected_ptr != old; } -static void tree_move_to_top (WTree *tree) +static void +tree_move_to_top (WTree *tree) { tree->selected_ptr = tree->store->tree_first; tree->topdiff = 0; } -static void tree_move_to_bottom (WTree *tree) +static void +tree_move_to_bottom (WTree *tree) { tree->selected_ptr = tree->store->tree_last; tree->topdiff = tlines (tree) - 3 - 1; } -void tree_chdir (WTree *tree, const char *dir) -{ - tree_entry *current; - - current = tree_store_whereis (dir); - if (current){ - tree->selected_ptr = current; - check_focus (tree); - } -} - -void -sync_tree (const char *path) -{ - tree_chdir (the_tree, path); -} - /* Handle mouse click */ static void tree_event (WTree *tree, int y) @@ -487,14 +495,29 @@ tree_event (WTree *tree, int y) show_tree (tree); } -static void chdir_sel (WTree *tree); - -static void maybe_chdir (WTree *tree) +static void +tree_chdir_sel (WTree *tree) { - if (!(xtree_mode && tree->is_panel)) + if (!tree->is_panel) return; - if (is_idle ()) - chdir_sel (tree); + + change_panel (); + + if (do_cd (tree->selected_ptr->name, cd_exact)) + select_item (current_panel); + else + message (D_ERROR, MSG_ERROR, _(" Cannot chdir to \"%s\" \n %s "), + tree->selected_ptr->name, unix_error_string (errno)); + + change_panel (); + show_tree (tree); +} + +static void +maybe_chdir (WTree *tree) +{ + if (xtree_mode && tree->is_panel && is_idle ()) + tree_chdir_sel (tree); } /* Mouse callback */ @@ -524,21 +547,21 @@ event_callback (Gpm_Event *event, void *data) if (event->y < 0){ tree_move_backward (tree, tlines (tree) - 1); show_tree (tree); - } - else if (event->y >= tlines (tree)){ + } else if (event->y >= tlines (tree)){ tree_move_forward (tree, tlines (tree) - 1); show_tree (tree); } else { tree_event (tree, event->y); if ((event->type & (GPM_UP|GPM_DOUBLE)) == (GPM_UP|GPM_DOUBLE)){ - chdir_sel (tree); + tree_chdir_sel (tree); } } return MOU_NORMAL; } /* Search tree for text */ -static int search_tree (WTree *tree, char *text) +static int +search_tree (WTree *tree, char *text) { tree_entry *current; int len; @@ -561,23 +584,21 @@ static int search_tree (WTree *tree, char *text) } tree->topdiff++; } - check_focus (tree); + tree_check_focus (tree); return found; } -static void tree_do_search (WTree *tree, int key) +static void +tree_do_search (WTree *tree, int key) { size_t l; l = strlen (tree->search_buffer); - if (l && (key == KEY_BACKSPACE)) - tree->search_buffer [--l] = 0; - else { - if (key && l < sizeof (tree->search_buffer)){ - tree->search_buffer [l] = key; - tree->search_buffer [l+1] = 0; - l++; - } + if ((l != 0) && (key == KEY_BACKSPACE)) + tree->search_buffer [--l] = '\0'; + else if (key && l < sizeof (tree->search_buffer)){ + tree->search_buffer [l] = key; + tree->search_buffer [++l] = '\0'; } if (!search_tree (tree, tree->search_buffer)) @@ -588,9 +609,10 @@ static void tree_do_search (WTree *tree, int key) } static void -tree_rescan_cmd (WTree *tree) +tree_rescan (void *data) { char old_dir [MC_MAXPATHLEN]; + WTree *tree = data; if (!tree->selected_ptr || !mc_get_current_wd (old_dir, MC_MAXPATHLEN) || mc_chdir (tree->selected_ptr->name)) @@ -601,7 +623,7 @@ tree_rescan_cmd (WTree *tree) } static void -tree_forget_cmd (void *data) +tree_forget (void *data) { WTree *tree = data; if (tree->selected_ptr) @@ -634,19 +656,6 @@ tree_copy (WTree *tree, const char *default_dest) g_free (dest); } -static void -tree_help_cmd (void) -{ - interactive_display (NULL, "[Directory Tree]"); -} - -static void -tree_copy_cmd (void *data) -{ - WTree *tree = data; - tree_copy (tree, ""); -} - static void tree_move (WTree *tree, const char *default_dest) { @@ -675,6 +684,7 @@ tree_move (WTree *tree, const char *default_dest) g_free (dest); return; } + if (!S_ISDIR (buf.st_mode)){ file_error (_(" Destination \"%s\" must be a directory \n %s "), dest); @@ -690,16 +700,9 @@ tree_move (WTree *tree, const char *default_dest) g_free (dest); } -static void -tree_move_cmd (void *data) -{ - WTree *tree = data; - tree_move (tree, ""); -} - #if 0 static void -tree_mkdir_cmd (WTree *tree) +tree_mkdir (WTree *tree) { char old_dir [MC_MAXPATHLEN]; @@ -712,14 +715,15 @@ tree_mkdir_cmd (WTree *tree) /* FIXME mkdir_cmd (tree); */ - tree_rescan_cmd (tree); + tree_rescan (tree); chdir (old_dir); } #endif static void -tree_rmdir_cmd (WTree *tree) +tree_rmdir (void *data) { + WTree *tree = data; off_t count = 0; double bytes = 0; FileOpContext *ctx; @@ -743,91 +747,55 @@ tree_rmdir_cmd (WTree *tree) ctx = file_op_context_new (OP_DELETE); file_op_context_create_ui (ctx, FALSE); - if (erase_dir (ctx, tree->selected_ptr->name, &count, &bytes) == - FILE_CONT) - tree_forget_cmd (tree); + if (erase_dir (ctx, tree->selected_ptr->name, &count, &bytes) == FILE_CONT) + tree_forget (tree); file_op_context_destroy (ctx); } -static void set_navig_label (WTree *tree); - static void -tree_toggle_navig (void *data) -{ - WTree *tree = data; - /* FIXME: invalid use of boolean variable */ - tree_navigation_flag = 1 - tree_navigation_flag; - set_navig_label (tree); -} - -static void -set_navig_label (WTree *tree) +tree_toggle_navig (WTree *tree) { + tree_navigation_flag = !tree_navigation_flag; buttonbar_set_label_data (tree->widget.parent, 4, - tree_navigation_flag ? Q_("ButtonBar|Static") : Q_("ButtonBar|Dynamc"), - tree_toggle_navig, tree); + tree_navigation_flag ? Q_("ButtonBar|Static") + : Q_("ButtonBar|Dynamc"), + tree_toggle_f4, tree); } -static void -move_down (WTree *tree) -{ - tree_move_forward (tree, 1); - show_tree (tree); - maybe_chdir (tree); -} - -static void -move_up (WTree *tree) +static inline void +tree_move_up (WTree *tree) { tree_move_backward (tree, 1); show_tree (tree); maybe_chdir (tree); } -static void -move_home (WTree *tree) +static inline void +tree_move_down (WTree *tree) +{ + tree_move_forward (tree, 1); + show_tree (tree); + maybe_chdir (tree); +} + +static inline void +tree_move_home (WTree *tree) { tree_move_to_top (tree); show_tree (tree); maybe_chdir (tree); } -static void -move_end (WTree *tree) +static inline void +tree_move_end (WTree *tree) { tree_move_to_bottom (tree); show_tree (tree); maybe_chdir (tree); } -static int -move_left (WTree *tree) -{ - int v; - - if (tree_navigation_flag){ - v = tree_move_to_parent (tree); - show_tree (tree); - maybe_chdir (tree); - return v; - } - return 0; -} - -static int -move_right (WTree *tree) -{ - if (tree_navigation_flag){ - tree_move_to_child (tree); - show_tree (tree); - maybe_chdir (tree); - return 1; - } - return 0; -} - static void -move_prevp (WTree *tree) +tree_move_pgup (WTree *tree) { tree_move_backward (tree, tlines (tree) - 1); show_tree (tree); @@ -835,40 +803,50 @@ move_prevp (WTree *tree) } static void -move_nextp (WTree *tree) +tree_move_pgdn (WTree *tree) { tree_move_forward (tree, tlines (tree) - 1); show_tree (tree); maybe_chdir (tree); } -static void -chdir_sel (WTree *tree) +static gboolean +tree_move_left (WTree *tree) { - if (!tree->is_panel) { - return; + gboolean v = FALSE; + + if (tree_navigation_flag) { + v = tree_move_to_parent (tree); + show_tree (tree); + maybe_chdir (tree); } - change_panel (); - if (do_cd (tree->selected_ptr->name, cd_exact)) { - select_item (current_panel); - } else { - message (D_ERROR, MSG_ERROR, _(" Cannot chdir to \"%s\" \n %s "), - tree->selected_ptr->name, unix_error_string (errno)); + + return v; +} + +static gboolean +tree_move_right (WTree *tree) +{ + gboolean v = FALSE; + + if (tree_navigation_flag) { + tree_move_to_child (tree); + show_tree (tree); + maybe_chdir (tree); + v = TRUE; } - change_panel (); - show_tree (tree); - return; + + return v; } static void tree_start_search (WTree *tree) { - int i; - - if (tree->searching){ + gboolean i; + if (tree->searching) { if (tree->selected_ptr == tree->store->tree_last) - tree_move_to_top(tree); + tree_move_to_top (tree); else { /* set navigation mode temporarily to 'Static' because in * dynamic navigation mode tree_move_forward will not move @@ -881,67 +859,116 @@ tree_start_search (WTree *tree) tree_navigation_flag = i; } tree_do_search (tree, 0); - } - else { + } else { tree->searching = 1; tree->search_buffer[0] = 0; } } -typedef void (*tree_key_action) (WTree *); -typedef struct { - int key_code; - tree_key_action fn; -} tree_key_map; +static cb_ret_t +tree_execute_cmd (WTree *tree, int command) +{ + cb_ret_t res = MSG_HANDLED; -static const tree_key_map tree_keymap [] = { - { XCTRL('n'), move_down }, - { XCTRL('p'), move_up }, - { KEY_DOWN, move_down }, - { KEY_UP, move_up }, - { '\n', chdir_sel }, - { KEY_ENTER, chdir_sel }, - { KEY_HOME, move_home }, - { KEY_A1, move_home }, - { ALT ('<'), move_home }, - { KEY_END, move_end }, - { KEY_C1, move_end }, - { ALT ('>'), move_end }, - { KEY_NPAGE, move_nextp }, - { KEY_PPAGE, move_prevp }, - { XCTRL('v'), move_nextp }, - { ALT('v'), move_prevp }, - { XCTRL('p'), move_up }, - { XCTRL('p'), move_down }, - { XCTRL('s'), tree_start_search }, - { ALT('s'), tree_start_search }, - { XCTRL('r'), tree_rescan_cmd }, - { KEY_DC, tree_rmdir_cmd }, - { 0, 0 } - }; + if (command != CK_TreeStartSearch) + tree->searching = 0; + + switch (command) { + case CK_TreeHelp: + interactive_display (NULL, "[Directory Tree]"); + break; + case CK_TreeForget: + tree_forget (tree); + break; + case CK_TreeToggleNav: + tree_toggle_navig (tree); + break; + case CK_TreeCopy: + tree_copy (tree, ""); + break; + case CK_TreeMove: + tree_move (tree, ""); + break; + case CK_TreeMoveUp: + tree_move_up (tree); + break; + case CK_TreeMoveDown: + tree_move_down (tree); + break; + case CK_TreeMoveHome: + tree_move_home (tree); + break; + case CK_TreeMoveEnd: + tree_move_end (tree); + break; + case CK_TreeMovePgUp: + tree_move_pgup (tree); + break; + case CK_TreeMovePgDn: + tree_move_pgdn (tree); + break; + case CK_TreeOpen: + tree_chdir_sel (tree); + break; + case CK_TreeRescan: + tree_rescan (tree); + break; + case CK_TreeStartSearch: + tree_start_search (tree); + break; + case CK_TreeRemove: + tree_rmdir (tree); + break; + default: + res = MSG_NOT_HANDLED; + } + + show_tree (tree); + + return res; +} + +/* temporary wrappers */ +void +tree_help (void *data) +{ + tree_execute_cmd ((WTree *) data, CK_TreeHelp); +} + +void +tree_toggle_f4 (void *data) +{ + tree_execute_cmd ((WTree *) data, CK_TreeToggleNav); +} + +void +tree_copy_cmd (void *data) +{ + tree_execute_cmd ((WTree *) data, CK_TreeCopy); +} + +void +tree_move_cmd (void *data) +{ + tree_execute_cmd ((WTree *) data, CK_TreeMove); +} static cb_ret_t tree_key (WTree *tree, int key) { int i; - for (i = 0; tree_keymap [i].key_code; i++){ - if (key == tree_keymap [i].key_code){ - if (tree_keymap [i].fn != tree_start_search) - tree->searching = 0; - (*tree_keymap [i].fn)(tree); - show_tree (tree); - return MSG_HANDLED; - } - } - - /* We do not want to use them if we do not need to */ - /* Input line may want to take the motion key event */ - if (key == KEY_LEFT) - return move_left (tree) ? MSG_HANDLED : MSG_NOT_HANDLED; - - if (key == KEY_RIGHT) - return move_right (tree) ? MSG_HANDLED : MSG_NOT_HANDLED; + for (i = 0; tree_map [i].key != 0; i++) + if (key == tree_map [i].key) + switch (tree_map [i].command) { + case CK_TreeMoveLeft: + return tree_move_left (tree) ? MSG_HANDLED : MSG_NOT_HANDLED; + case CK_TreeMoveRight: + return tree_move_right (tree) ? MSG_HANDLED : MSG_NOT_HANDLED; + default: + tree_execute_cmd (tree, tree_map [i].command); + return MSG_HANDLED; + } if (is_abort_char (key)) { if (tree->is_panel) { @@ -989,20 +1016,6 @@ tree_frame (Dlg_head *h, WTree *tree) } } -static void -tree_rescan_command (void *data) -{ - WTree *tree = data; - tree_rescan_cmd (tree); -} - -static void -tree_rmdir_command (void *data) -{ - WTree *tree = data; - tree_rmdir_cmd (tree); -} - static cb_ret_t tree_callback (Widget *w, widget_msg_t msg, int parm) { @@ -1020,23 +1033,23 @@ tree_callback (Widget *w, widget_msg_t msg, int parm) case WIDGET_FOCUS: tree->active = 1; - buttonbar_set_label (h, 1, Q_("ButtonBar|Help"), tree_help_cmd); - buttonbar_set_label_data (h, 2, Q_("ButtonBar|Rescan"), - tree_rescan_command, tree); - buttonbar_set_label_data (h, 3, Q_("ButtonBar|Forget"), tree_forget_cmd, tree); + buttonbar_set_label_data (h, 1, Q_("ButtonBar|Help"), tree_help, tree); + buttonbar_set_label_data (h, 2, Q_("ButtonBar|Rescan"), tree_rescan, tree); + buttonbar_set_label_data (h, 3, Q_("ButtonBar|Forget"), tree_forget, tree); + buttonbar_set_label_data (h, 4, tree_navigation_flag ? Q_("ButtonBar|Static") + : Q_("ButtonBar|Dynamc"), + tree_toggle_f4, tree); buttonbar_set_label_data (h, 5, Q_("ButtonBar|Copy"), tree_copy_cmd, tree); buttonbar_set_label_data (h, 6, Q_("ButtonBar|RenMov"), tree_move_cmd, tree); #if 0 /* FIXME: mkdir is currently defunct */ - buttonbar_set_label_data (h, 7, Q_("ButtonBar|Mkdir"), tree_mkdir_cmd, tree); + buttonbar_set_label_data (h, 7, Q_("ButtonBar|Mkdir"), tree_mkdir, tree); #else buttonbar_clear_label (h, 7); #endif - buttonbar_set_label_data (h, 8, Q_("ButtonBar|Rmdir"), tree_rmdir_command, tree); - set_navig_label (tree); + buttonbar_set_label_data (h, 8, Q_("ButtonBar|Rmdir"), tree_rmdir, tree); buttonbar_redraw (h); - /* FIXME: Should find a better way of only displaying the currently selected item */ show_tree (tree); @@ -1083,10 +1096,28 @@ tree_new (int is_panel, int y, int x, int lines, int cols) return tree; } +void +tree_chdir (WTree *tree, const char *dir) +{ + tree_entry *current; + + current = tree_store_whereis (dir); + + if (current != NULL) { + tree->selected_ptr = current; + tree_check_focus (tree); + } +} + /* Return name of the currently selected entry */ char * -tree_selected_name (WTree *tree) +tree_selected_name (const WTree *tree) { return tree->selected_ptr->name; } +void +sync_tree (const char *path) +{ + tree_chdir (the_tree, path); +} diff --git a/src/tree.h b/src/tree.h index d0aee811a..5420d9b72 100644 --- a/src/tree.h +++ b/src/tree.h @@ -6,18 +6,16 @@ #ifndef MC_TREE_H #define MC_TREE_H -struct WTree; typedef struct WTree WTree; -int tree_init (const char *current_dir, int lines); -void tree_chdir (WTree *tree, const char *dir); -char *tree_selected_name (WTree *tree); - -void sync_tree (const char *pathname); - +extern WTree *the_tree; extern int xtree_mode; WTree *tree_new (int is_panel, int y, int x, int lines, int cols); -extern WTree *the_tree; -#endif +void tree_chdir (WTree *tree, const char *dir); +char *tree_selected_name (const WTree *tree); + +void sync_tree (const char *pathname); + +#endif /* MC_TREE_H */