📄 tree.c
字号:
for (dp = readdir (dirp); dp; dp = readdir (dirp)){
lstat (dp->d_name, &buf);
if (S_ISDIR (buf.st_mode))
do_tree_check (tree, dp->d_name);
}
closedir (dirp);
}
end_tree_check (tree);
mc_chdir (old_dir);
}
int tree_forget_cmd (WTree *tree)
{
if (tree->selected_ptr)
tree_remove_entry (tree, tree->selected_ptr->name);
return 1;
}
#if 0
static int toggle_nav_mode (void)
{
tree_navigation_flag = 1 - tree_navigation_flag;
return 1;
}
#endif
void tree_copy (WTree *tree, char *default_dest)
{
char *dest;
if (!tree->selected_ptr)
return;
sprintf (cmd_buf, _("Copy \"%s\" directory to:"),
name_trunc (tree->selected_ptr->name, 50));
dest = input_expand_dialog (_(" Copy "), cmd_buf, default_dest);
if (!dest || !*dest){
return;
}
create_op_win (OP_COPY, 0);
file_mask_defaults ();
copy_dir_dir (tree->selected_ptr->name, dest, 1, 0, 0, 0);
destroy_op_win ();
free (dest);
}
static void tree_help_cmd (void)
{
char *hlpfile = concat_dir_and_file (mc_home, "mc.hlp");
interactive_display (hlpfile, "[Directory Tree]");
free (hlpfile);
}
static int tree_copy_cmd (WTree *tree)
{
tree_copy (tree, "");
return 1;
}
void tree_move (WTree *tree, char *default_dest)
{
char *dest;
struct stat buf;
if (!tree->selected_ptr)
return;
sprintf (cmd_buf, _("Move \"%s\" directory to:"),
name_trunc (tree->selected_ptr->name, 50));
dest = input_expand_dialog (_(" Move "), cmd_buf, default_dest);
if (!dest || !*dest){
return;
}
if (stat (dest, &buf)){
message (1, _(" Error "), _(" Can't stat the destination \n %s "),
unix_error_string (errno));
free (dest);
return;
}
if (!S_ISDIR (buf.st_mode)){
message (1, _(" Error "), _(" The destination isn't a directory "));
free (dest);
return;
}
create_op_win (OP_MOVE, 0);
file_mask_defaults ();
move_dir_dir (tree->selected_ptr->name, dest);
destroy_op_win ();
free (dest);
}
static int tree_move_cmd (WTree *tree)
{
tree_move (tree, "");
return 1;
}
static int tree_mkdir_cmd (WTree *tree)
{
char old_dir [MC_MAXPATHLEN];
if (!tree->selected_ptr)
return 0;
if (!mc_get_current_wd (old_dir, MC_MAXPATHLEN))
return 0;
if (chdir (tree->selected_ptr->name))
return 0;
/* FIXME
mkdir_cmd (tree);
*/
tree_rescan_cmd (tree);
chdir (old_dir);
return 1;
}
static void tree_rmdir_cmd (WTree *tree)
{
char old_dir [MC_MAXPATHLEN];
if (tree->selected_ptr){
if (!mc_get_current_wd (old_dir, MC_MAXPATHLEN))
return;
if (mc_chdir (PATH_SEP_STR))
return;
if (confirm_delete){
char *cmd_buf;
int result;
cmd_buf = xmalloc (strlen (tree->selected_ptr->name) + 20,
"tree, rmdir_cmd");
sprintf (cmd_buf, _(" Delete %s? "), tree->selected_ptr->name);
result = query_dialog (_(" Delete "), cmd_buf, 3, 2, _("&Yes"), _("&No"));
free (cmd_buf);
if (result != 0){
return;
}
}
create_op_win (OP_DELETE, 0);
if (erase_dir (tree->selected_ptr->name) == FILE_CONT)
tree_forget_cmd (tree);
destroy_op_win ();
mc_chdir (old_dir);
return;
} else
return;
}
#if 0
static int tree_quit_cmd (void)
{
/*
FIXME
return done = 1;
*/
return 1;
}
#endif
static void set_navig_label (Dlg_head *h);
static void tree_toggle_navig (Dlg_head *h)
{
tree_navigation_flag = 1 - tree_navigation_flag;
set_navig_label (h);
}
void set_navig_label (Dlg_head *h)
{
define_label_data (h, (Widget *)tree,
4, tree_navigation_flag ? _("Static") : _("Dynamc"),
(void (*)(void *))tree_toggle_navig, h);
}
static void move_down (WTree *tree)
{
tree_move_forward (tree, 1);
show_tree (tree);
maybe_chdir (tree);
}
static void move_up (WTree *tree)
{
tree_move_backward (tree, 1);
show_tree (tree);
maybe_chdir (tree);
}
static void move_home (WTree *tree)
{
tree_move_to_top (tree);
show_tree (tree);
maybe_chdir (tree);
}
static void 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_backward (tree, tlines (tree) - 1);
show_tree (tree);
maybe_chdir (tree);
}
static void move_nextp (WTree *tree)
{
tree_move_forward (tree, tlines (tree) - 1);
show_tree (tree);
maybe_chdir (tree);
}
static void chdir_sel (WTree *tree)
{
if (!tree->is_panel){
tree->done = 1;
return;
}
change_panel ();
if (do_cd (tree->selected_ptr->name, cd_exact)){
paint_panel (cpanel);
select_item (cpanel);
} else {
message (1, MSG_ERROR, _(" Can't chdir to \"%s\" \n %s "),
tree->selected_ptr->name, unix_error_string (errno));
}
change_panel ();
show_tree (tree);
return;
}
static void start_search (WTree *tree)
{
int i;
if (tree->searching){
if (tree->selected_ptr == tree->tree_last)
tree_move_to_top(tree);
else {
/* set navigation mode temporarily to 'Static' because in
* dynamic navigation mode tree_move_forward will not move
* to a lower sublevel if necessary (sequent searches must
* start with the directory followed the last found directory)
*/
i = tree_navigation_flag;
tree_navigation_flag = 0;
tree_move_forward (tree, 1);
tree_navigation_flag = i;
}
tree_do_search (tree, 0);
}
else {
tree->searching = 1;
tree->search_buffer[0] = 0;
}
}
static 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_C1, move_end },
{ KEY_END, move_end },
{ KEY_A1, move_home },
{ 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'), start_search },
{ ALT('s'), start_search },
{ XCTRL('r'), tree_rescan_cmd },
{ KEY_DC, tree_rmdir_cmd },
{ 0, 0 }
};
static inline int 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 != start_search)
tree->searching = 0;
(*tree_keymap [i].fn)(tree);
show_tree (tree);
return 1;
}
}
/* 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);
if (key == KEY_RIGHT)
return move_right (tree);
if (is_abort_char (key)) {
if (tree->is_panel) {
tree->searching = 0;
show_tree (tree);
return 1; /* eat abort char */
}
return 0; /* modal tree dialog: let upper layer see the
abort character and close the dialog */
}
/* Do not eat characters not meant for the tree below ' ' (e.g. C-l). */
if ((key >= ' '&& key <= 255) || key == 8 || key == KEY_BACKSPACE) {
if (tree->searching){
tree_do_search (tree, key);
show_tree (tree);
return 1;
}
if (!command_prompt) {
start_search (tree);
tree_do_search (tree, key);
return 1;
}
return tree->is_panel;
}
return 0;
}
static void tree_frame (Dlg_head *h, WTree *tree)
{
attrset (NORMAL_COLOR);
widget_erase ((Widget*) tree);
if (tree->is_panel)
draw_double_box (h, tree->widget.y, tree->widget.x, tree->widget.lines,
tree->widget.cols);
if (show_mini_info && tree->is_panel){
widget_move (tree, tlines (tree) + 1, 1);
hline (ACS_HLINE, tree->widget.cols - 2);
}
}
static int tree_callback (Dlg_head *h, WTree *tree, int msg, int par)
{
switch (msg){
case WIDGET_DRAW:
tree_frame (h, tree);
show_tree (tree);
return 1;
case WIDGET_KEY:
return tree_key (tree, par);
case WIDGET_FOCUS:
tree->active = 1;
define_label (h, (Widget *)tree, 1, _("Help"), (voidfn) tree_help_cmd);
define_label_data (h, (Widget *)tree,
2, _("Rescan"), (buttonbarfn)tree_rescan_cmd, tree);
define_label_data (h, (Widget *)tree,
3, _("Forget"), (buttonbarfn)tree_forget_cmd, tree);
define_label_data (h, (Widget *)tree,
5, _("Copy"), (buttonbarfn) tree_copy_cmd, tree);
define_label_data (h, (Widget *)tree,
6, _("RenMov"), (buttonbarfn) tree_move_cmd, tree);
#if 0
/* FIXME: mkdir is currently defunct */
define_label_data (h, (Widget *)tree,
7, _("Mkdir"), (buttonbarfn) tree_mkdir_cmd, tree);
#else
define_label (h, (Widget *)tree, 7, "", 0);
#endif
define_label_data (h, (Widget *)tree,
8, _("Rmdir"), (buttonbarfn) tree_rmdir_cmd, tree);
set_navig_label (h);
redraw_labels (h, (Widget *)tree);
/* FIXME: Should find a better way of only displaying the
currently selected item */
show_tree (tree);
return 1;
/* FIXME: Should find a better way of changing the color of the
selected item */
case WIDGET_UNFOCUS:
tree->active = 0;
show_tree (tree);
return 1;
}
return default_proc (h, msg, par);
}
WTree *tree_new (int is_panel, int y, int x, int lines, int cols)
{
WTree *tree = xmalloc (sizeof (WTree), "tree_new");
init_widget (&tree->widget, y, x, lines, cols, tcallback,
(destroy_fn) tree_destroy, (mouse_h) event_callback, NULL);
tree->is_panel = is_panel;
tree->selected_ptr = 0;
tree->tree_shown = 0;
tree->search_buffer [0] = 0;
tree->tree_first = tree->tree_last = 0;
tree->topdiff = tree->widget.lines / 2;
tree->searching = 0;
tree->done = 0;
tree->active = 0;
/* We do not want to keep the cursor */
widget_want_cursor (tree->widget, 0);
load_tree (tree);
return tree;
}
static char *get_absolute_name (char *file)
{
char dir [MC_MAXPATHLEN];
if (file [0] == PATH_SEP)
return strdup (file);
mc_get_current_wd (dir, MC_MAXPATHLEN);
return get_full_name (dir, file);
}
static int my_mkdir_rec (char *s, mode_t mode)
{
char *p, *q;
int result;
if (!mc_mkdir (s, mode))
return 0;
/* FIXME: should check instead if s is at the root of that filesystem */
if (!vfs_file_is_local (s))
return -1;
if (!strcmp (vfs_path(s), PATH_SEP_STR))
return ENOTDIR;
p = concat_dir_and_file (s, "..");
q = vfs_canon (p);
free (p);
if (!(result = my_mkdir_rec (q, mode))) {
result = mc_mkdir (s, mode);
}
free (q);
return result;
}
int my_mkdir (char *s, mode_t mode)
{
int result;
#if FIXME
WTree *tree = 0;
#endif
result = mc_mkdir (s, mode);
#ifdef OS2_NT
/* .ado: it will be disabled in OS/2 and NT */
/* otherwise crash if directory already exists. */
return result;
#endif
if (result) {
char *p = vfs_canon (s);
result = my_mkdir_rec (p, mode);
free (p);
}
if (result == 0){
s = get_absolute_name (s);
#if FIXME
/* FIXME: Should receive a Wtree! */
tree_add_entry (tree, s);
#endif
free (s);
}
return result;
}
int my_rmdir (char *s)
{
int result;
#if FIXME
WTree *tree = 0;
#endif
/* FIXME: Should receive a Wtree! */
result = mc_rmdir (s);
if (result == 0){
s = get_absolute_name (s);
#if FIXME
tree_remove_entry (tree, s);
#endif
free (s);
}
return result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -