1 /* Directory tree browser for the Midnight Commander
2 Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
3 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
5 Written: 1994, 1996 Janne Kukonlehto
7 1996, 1999 Miguel de Icaza
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 This module has been converted to be a widget.
25 The program load and saves the tree each time the tree widget is
26 created and destroyed. This is required for the future vfs layer,
27 it will be possible to have tree views over virtual file systems.
32 * \brief Source: directory tree browser
40 #include <sys/types.h>
42 #include "lib/global.h"
44 #include "lib/tty/tty.h"
46 #include "lib/tty/mouse.h"
47 #include "lib/tty/key.h"
48 #include "lib/vfs/mc-vfs/vfs.h"
49 #include "lib/fileloc.h"
50 #include "lib/strutil.h"
52 #include "wtools.h" /* message() */
58 #include "main-widgets.h" /* the_menubar */
59 #include "menu.h" /* menubar_visible */
60 #include "file.h" /* copy_dir_dir(), move_dir_dir(), erase_dir() */
61 #include "layout.h" /* command_prompt */
63 #include "treestore.h"
71 const global_keymap_t
*tree_map
;
73 #define tlines(t) (t->is_panel ? t->widget.lines - 2 - (show_mini_info ? 2 : 0) : t->widget.lines)
75 /* Use the color of the parent widget for the unselected entries */
76 #define TREE_NORMALC(h) (DLG_NORMALC (h))
78 /* Specifies the display mode: 1d or 2d */
79 static gboolean tree_navigation_flag
= FALSE
;
84 struct TreeStore
*store
;
85 tree_entry
*selected_ptr
; /* The selected directory */
86 char search_buffer
[256]; /* Current search string */
87 tree_entry
**tree_shown
; /* Entries currently on screen */
88 int is_panel
; /* panel or plain widget flag */
89 int active
; /* if it's currently selected */
90 int searching
; /* Are we on searching mode? */
91 int topdiff
; /* The difference between the topmost
92 shown and the selected */
96 static void tree_rescan (void *data
);
99 back_ptr (tree_entry
* ptr
, int *count
)
103 while (ptr
&& ptr
->prev
&& i
< *count
)
113 forw_ptr (tree_entry
* ptr
, int *count
)
117 while (ptr
&& ptr
->next
&& i
< *count
)
127 remove_callback (tree_entry
* entry
, void *data
)
131 if (tree
->selected_ptr
== entry
)
133 if (tree
->selected_ptr
->next
)
134 tree
->selected_ptr
= tree
->selected_ptr
->next
;
136 tree
->selected_ptr
= tree
->selected_ptr
->prev
;
140 /* Save the ~/.mc/Tree file */
142 save_tree (WTree
* tree
)
148 error
= tree_store_save ();
153 tree_name
= g_build_filename (home_dir
, MC_USERCONF_DIR
, MC_TREESTORE_FILE
, (char *) NULL
);
154 fprintf (stderr
, _("Cannot open the %s file for writing:\n%s\n"), tree_name
,
155 unix_error_string (error
));
161 tree_remove_entry (WTree
* tree
, char *name
)
164 tree_store_remove_entry (name
);
168 tree_destroy (WTree
* tree
)
170 tree_store_remove_entry_remove_hook (remove_callback
);
173 g_free (tree
->tree_shown
);
174 tree
->tree_shown
= 0;
175 tree
->selected_ptr
= NULL
;
178 /* Loads the .mc.tree file */
180 load_tree (WTree
* tree
)
184 tree
->selected_ptr
= tree
->store
->tree_first
;
185 tree_chdir (tree
, home_dir
);
189 tree_show_mini_info (WTree
* tree
, int tree_lines
, int tree_cols
)
191 Dlg_head
*h
= tree
->widget
.parent
;
199 line
= tree_lines
+ 2;
202 line
= tree_lines
+ 1;
204 tty_draw_hline (tree
->widget
.y
+ line
, tree
->widget
.x
+ 1, ' ', tree_cols
);
205 widget_move (&tree
->widget
, line
, 1);
209 /* Show search string */
210 tty_setcolor (TREE_NORMALC (h
));
211 tty_setcolor (DLG_FOCUSC (h
));
212 tty_print_char (PATH_SEP
);
214 tty_print_string (str_fit_to_term (tree
->search_buffer
, tree_cols
- 2, J_LEFT_FIT
));
215 tty_print_char (' ');
216 tty_setcolor (DLG_FOCUSC (h
));
220 /* Show full name of selected directory */
221 tty_print_string (str_fit_to_term (tree
->selected_ptr
->name
, tree_cols
, J_LEFT_FIT
));
226 show_tree (WTree
* tree
)
228 Dlg_head
*h
= tree
->widget
.parent
;
230 int i
, j
, topsublevel
;
232 int tree_lines
, tree_cols
;
236 tree_lines
= tlines (tree
);
237 tree_cols
= tree
->widget
.cols
;
239 tty_setcolor (TREE_NORMALC (h
));
240 widget_move ((Widget
*) tree
, y
, x
);
247 g_free (tree
->tree_shown
);
248 tree
->tree_shown
= g_new0 (tree_entry
*, tree_lines
);
250 if (tree
->store
->tree_first
)
251 topsublevel
= tree
->store
->tree_first
->sublevel
;
254 if (!tree
->selected_ptr
)
256 tree
->selected_ptr
= tree
->store
->tree_first
;
259 current
= tree
->selected_ptr
;
261 /* Calculate the directory which is to be shown on the topmost line */
262 if (!tree_navigation_flag
)
263 current
= back_ptr (current
, &tree
->topdiff
);
267 while (current
->prev
&& i
< tree
->topdiff
)
269 current
= current
->prev
;
270 if (current
->sublevel
< tree
->selected_ptr
->sublevel
)
272 if (strncmp (current
->name
, tree
->selected_ptr
->name
, strlen (current
->name
)) == 0)
275 else if (current
->sublevel
== tree
->selected_ptr
->sublevel
)
277 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
278 if (strncmp (current
->name
, tree
->selected_ptr
->name
, j
) == 0)
281 else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+ 1
282 && strlen (tree
->selected_ptr
->name
) > 1)
284 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
285 strlen (tree
->selected_ptr
->name
)) == 0)
292 /* Loop for every line */
293 for (i
= 0; i
< tree_lines
; i
++)
295 /* Move to the beginning of the line */
296 tty_draw_hline (tree
->widget
.y
+ y
+ i
, tree
->widget
.x
+ x
, ' ', tree_cols
);
301 tree
->tree_shown
[i
] = current
;
302 if (current
->sublevel
== topsublevel
)
305 /* Top level directory */
306 if (tree
->active
&& current
== tree
->selected_ptr
)
308 if (!tty_use_colors () && !tree
->is_panel
)
309 tty_setcolor (MARKED_COLOR
);
311 tty_setcolor (SELECTED_COLOR
);
315 tty_print_string (str_fit_to_term (current
->name
, tree_cols
- 6, J_LEFT_FIT
));
319 /* Sub level directory */
321 tty_set_alt_charset (TRUE
);
322 /* Output branch parts */
323 for (j
= 0; j
< current
->sublevel
- topsublevel
- 1; j
++)
325 if (tree_cols
- 8 - 3 * j
< 9)
327 tty_print_char (' ');
328 if (current
->submask
& (1 << (j
+ topsublevel
+ 1)))
329 tty_print_char (ACS_VLINE
);
331 tty_print_char (' ');
332 tty_print_char (' ');
334 tty_print_char (' ');
336 if (!current
->next
|| !(current
->next
->submask
& (1 << current
->sublevel
)))
337 tty_print_char (ACS_LLCORNER
);
339 tty_print_char (ACS_LTEE
);
340 tty_print_char (ACS_HLINE
);
341 tty_set_alt_charset (FALSE
);
343 if (tree
->active
&& current
== tree
->selected_ptr
)
345 /* Selected directory -> change color */
346 if (!tty_use_colors () && !tree
->is_panel
)
347 tty_setcolor (MARKED_COLOR
);
349 tty_setcolor (SELECTED_COLOR
);
353 tty_print_char (' ');
354 tty_print_string (str_fit_to_term (current
->subname
,
355 tree_cols
- 2 - 4 - 3 * j
, J_LEFT_FIT
));
357 tty_print_char (' ');
359 /* Return to normal color */
360 tty_setcolor (TREE_NORMALC (h
));
362 /* Calculate the next value for current */
363 current
= current
->next
;
364 if (tree_navigation_flag
)
368 if (current
->sublevel
< tree
->selected_ptr
->sublevel
)
370 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
371 strlen (current
->name
)) == 0)
374 else if (current
->sublevel
== tree
->selected_ptr
->sublevel
)
376 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
377 if (strncmp (current
->name
, tree
->selected_ptr
->name
, j
) == 0)
380 else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+ 1
381 && strlen (tree
->selected_ptr
->name
) > 1)
383 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
384 strlen (tree
->selected_ptr
->name
)) == 0)
387 current
= current
->next
;
391 tree_show_mini_info (tree
, tree_lines
, tree_cols
);
395 tree_check_focus (WTree
* tree
)
397 if (tree
->topdiff
< 3)
399 else if (tree
->topdiff
>= tlines (tree
) - 3)
400 tree
->topdiff
= tlines (tree
) - 3 - 1;
404 tree_move_backward (WTree
* tree
, int i
)
406 if (!tree_navigation_flag
)
407 tree
->selected_ptr
= back_ptr (tree
->selected_ptr
, &i
);
413 current
= tree
->selected_ptr
;
414 while (j
< i
&& current
->prev
&& current
->prev
->sublevel
>= tree
->selected_ptr
->sublevel
)
416 current
= current
->prev
;
417 if (current
->sublevel
== tree
->selected_ptr
->sublevel
)
419 tree
->selected_ptr
= current
;
427 tree_check_focus (tree
);
431 tree_move_forward (WTree
* tree
, int i
)
433 if (!tree_navigation_flag
)
434 tree
->selected_ptr
= forw_ptr (tree
->selected_ptr
, &i
);
440 current
= tree
->selected_ptr
;
441 while (j
< i
&& current
->next
&& current
->next
->sublevel
>= tree
->selected_ptr
->sublevel
)
443 current
= current
->next
;
444 if (current
->sublevel
== tree
->selected_ptr
->sublevel
)
446 tree
->selected_ptr
= current
;
454 tree_check_focus (tree
);
458 tree_move_to_child (WTree
* tree
)
462 /* Do we have a starting point? */
463 if (!tree
->selected_ptr
)
465 /* Take the next entry */
466 current
= tree
->selected_ptr
->next
;
467 /* Is it the child of the selected entry */
468 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
)
470 /* Yes -> select this entry */
471 tree
->selected_ptr
= current
;
473 tree_check_focus (tree
);
477 /* No -> rescan and try again */
479 current
= tree
->selected_ptr
->next
;
480 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
)
482 tree
->selected_ptr
= current
;
484 tree_check_focus (tree
);
490 tree_move_to_parent (WTree
* tree
)
495 if (!tree
->selected_ptr
)
498 old
= tree
->selected_ptr
;
499 current
= tree
->selected_ptr
->prev
;
500 while (current
&& current
->sublevel
>= tree
->selected_ptr
->sublevel
)
502 current
= current
->prev
;
506 current
= tree
->store
->tree_first
;
507 tree
->selected_ptr
= current
;
508 tree_check_focus (tree
);
509 return tree
->selected_ptr
!= old
;
513 tree_move_to_top (WTree
* tree
)
515 tree
->selected_ptr
= tree
->store
->tree_first
;
520 tree_move_to_bottom (WTree
* tree
)
522 tree
->selected_ptr
= tree
->store
->tree_last
;
523 tree
->topdiff
= tlines (tree
) - 3 - 1;
526 /* Handle mouse click */
528 tree_event (WTree
* tree
, int y
)
530 if (tree
->tree_shown
[y
])
532 tree
->selected_ptr
= tree
->tree_shown
[y
];
539 tree_chdir_sel (WTree
* tree
)
546 if (do_cd (tree
->selected_ptr
->name
, cd_exact
))
547 select_item (current_panel
);
549 message (D_ERROR
, MSG_ERROR
, _(" Cannot chdir to \"%s\" \n %s "),
550 tree
->selected_ptr
->name
, unix_error_string (errno
));
557 maybe_chdir (WTree
* tree
)
559 if (xtree_mode
&& tree
->is_panel
&& is_idle ())
560 tree_chdir_sel (tree
);
565 event_callback (Gpm_Event
* event
, void *data
)
569 /* rest of the upper frame, the menu is invisible - call menu */
570 if (tree
->is_panel
&& (event
->type
& GPM_DOWN
) && event
->y
== 1 && !menubar_visible
)
572 event
->x
+= tree
->widget
.x
;
573 return the_menubar
->widget
.mouse (event
, the_menubar
);
576 if (!(event
->type
& GPM_UP
))
589 tree_move_backward (tree
, tlines (tree
) - 1);
592 else if (event
->y
>= tlines (tree
))
594 tree_move_forward (tree
, tlines (tree
) - 1);
599 tree_event (tree
, event
->y
);
600 if ((event
->type
& (GPM_UP
| GPM_DOUBLE
)) == (GPM_UP
| GPM_DOUBLE
))
602 tree_chdir_sel (tree
);
608 /* Search tree for text */
610 search_tree (WTree
* tree
, char *text
)
618 current
= tree
->selected_ptr
;
620 while (!wrapped
|| current
!= tree
->selected_ptr
)
622 if (strncmp (current
->subname
, text
, len
) == 0)
624 tree
->selected_ptr
= current
;
628 current
= current
->next
;
631 current
= tree
->store
->tree_first
;
636 tree_check_focus (tree
);
641 tree_do_search (WTree
* tree
, int key
)
645 l
= strlen (tree
->search_buffer
);
646 if ((l
!= 0) && (key
== KEY_BACKSPACE
))
647 tree
->search_buffer
[--l
] = '\0';
648 else if (key
&& l
< sizeof (tree
->search_buffer
))
650 tree
->search_buffer
[l
] = key
;
651 tree
->search_buffer
[++l
] = '\0';
654 if (!search_tree (tree
, tree
->search_buffer
))
655 tree
->search_buffer
[--l
] = 0;
662 tree_rescan (void *data
)
664 char old_dir
[MC_MAXPATHLEN
];
668 if (!tree
->selected_ptr
|| !mc_get_current_wd (old_dir
, MC_MAXPATHLEN
) ||
669 mc_chdir (tree
->selected_ptr
->name
))
672 tree_store_rescan (tree
->selected_ptr
->name
);
673 ret
= mc_chdir (old_dir
);
677 tree_forget (void *data
)
680 if (tree
->selected_ptr
)
681 tree_remove_entry (tree
, tree
->selected_ptr
->name
);
685 tree_copy (WTree
* tree
, const char *default_dest
)
687 char msg
[BUF_MEDIUM
];
690 if (tree
->selected_ptr
== NULL
)
693 g_snprintf (msg
, sizeof (msg
), _("Copy \"%s\" directory to:"),
694 str_trunc (tree
->selected_ptr
->name
, 50));
695 dest
= input_expand_dialog (Q_ ("DialogTitle|Copy"),
696 msg
, MC_HISTORY_FM_TREE_COPY
, default_dest
);
698 if (dest
!= NULL
&& *dest
!= '\0')
701 FileOpTotalContext
*tctx
;
703 ctx
= file_op_context_new (OP_COPY
);
704 tctx
= file_op_total_context_new ();
705 file_op_context_create_ui (ctx
, FALSE
, FILEGUI_DIALOG_MULTI_ITEM
);
706 tctx
->ask_overwrite
= FALSE
;
707 tctx
->is_toplevel_file
= FALSE
;
708 copy_dir_dir (tctx
, ctx
, tree
->selected_ptr
->name
, dest
, TRUE
, FALSE
, FALSE
, NULL
);
709 file_op_total_context_destroy (tctx
);
710 file_op_context_destroy (ctx
);
717 tree_move (WTree
* tree
, const char *default_dest
)
719 char msg
[BUF_MEDIUM
];
723 FileOpTotalContext
*tctx
;
725 if (tree
->selected_ptr
== NULL
)
728 g_snprintf (msg
, sizeof (msg
), _("Move \"%s\" directory to:"),
729 str_trunc (tree
->selected_ptr
->name
, 50));
731 input_expand_dialog (Q_ ("DialogTitle|Move"), msg
, MC_HISTORY_FM_TREE_MOVE
, default_dest
);
733 if (dest
== NULL
|| *dest
== '\0')
739 if (stat (dest
, &buf
))
741 message (D_ERROR
, MSG_ERROR
, _(" Cannot stat the destination \n %s "),
742 unix_error_string (errno
));
747 if (!S_ISDIR (buf
.st_mode
))
749 file_error (_(" Destination \"%s\" must be a directory \n %s "), dest
);
754 ctx
= file_op_context_new (OP_MOVE
);
755 tctx
= file_op_total_context_new ();
756 file_op_context_create_ui (ctx
, FALSE
, FILEGUI_DIALOG_ONE_ITEM
);
757 move_dir_dir (tctx
, ctx
, tree
->selected_ptr
->name
, dest
);
758 file_op_total_context_destroy (tctx
);
759 file_op_context_destroy (ctx
);
766 tree_mkdir (WTree
* tree
)
768 char old_dir
[MC_MAXPATHLEN
];
770 if (!tree
->selected_ptr
)
772 if (!mc_get_current_wd (old_dir
, MC_MAXPATHLEN
))
774 if (chdir (tree
->selected_ptr
->name
))
785 tree_rmdir (void *data
)
789 FileOpTotalContext
*tctx
;
791 if (!tree
->selected_ptr
)
799 buf
= g_strdup_printf (_(" Delete %s? "), tree
->selected_ptr
->name
);
800 result
= query_dialog (Q_ ("DialogTitle|Delete"), buf
, D_ERROR
, 2, _("&Yes"), _("&No"));
806 ctx
= file_op_context_new (OP_DELETE
);
807 tctx
= file_op_total_context_new ();
809 file_op_context_create_ui (ctx
, FALSE
, FILEGUI_DIALOG_ONE_ITEM
);
810 if (erase_dir (tctx
, ctx
, tree
->selected_ptr
->name
) == FILE_CONT
)
812 file_op_total_context_destroy (tctx
);
813 file_op_context_destroy (ctx
);
817 tree_move_up (WTree
* tree
)
819 tree_move_backward (tree
, 1);
825 tree_move_down (WTree
* tree
)
827 tree_move_forward (tree
, 1);
833 tree_move_home (WTree
* tree
)
835 tree_move_to_top (tree
);
841 tree_move_end (WTree
* tree
)
843 tree_move_to_bottom (tree
);
849 tree_move_pgup (WTree
* tree
)
851 tree_move_backward (tree
, tlines (tree
) - 1);
857 tree_move_pgdn (WTree
* tree
)
859 tree_move_forward (tree
, tlines (tree
) - 1);
865 tree_move_left (WTree
* tree
)
869 if (tree_navigation_flag
)
871 v
= tree_move_to_parent (tree
);
880 tree_move_right (WTree
* tree
)
884 if (tree_navigation_flag
)
886 tree_move_to_child (tree
);
896 tree_start_search (WTree
* tree
)
902 if (tree
->selected_ptr
== tree
->store
->tree_last
)
903 tree_move_to_top (tree
);
906 /* set navigation mode temporarily to 'Static' because in
907 * dynamic navigation mode tree_move_forward will not move
908 * to a lower sublevel if necessary (sequent searches must
909 * start with the directory followed the last found directory)
911 i
= tree_navigation_flag
;
912 tree_navigation_flag
= 0;
913 tree_move_forward (tree
, 1);
914 tree_navigation_flag
= i
;
916 tree_do_search (tree
, 0);
921 tree
->search_buffer
[0] = 0;
926 tree_toggle_navig (WTree
* tree
)
928 tree_navigation_flag
= !tree_navigation_flag
;
929 buttonbar_set_label (find_buttonbar (tree
->widget
.parent
), 4,
930 tree_navigation_flag
? Q_ ("ButtonBar|Static")
931 : Q_ ("ButtonBar|Dynamc"), tree_map
, (Widget
*) tree
);
935 tree_execute_cmd (WTree
* tree
, unsigned long command
)
937 cb_ret_t res
= MSG_HANDLED
;
939 if (command
!= CK_TreeStartSearch
)
945 interactive_display (NULL
, "[Directory Tree]");
950 case CK_TreeToggleNav
:
951 tree_toggle_navig (tree
);
954 tree_copy (tree
, "");
957 tree_move (tree
, "");
962 case CK_TreeMoveDown
:
963 tree_move_down (tree
);
965 case CK_TreeMoveHome
:
966 tree_move_home (tree
);
969 tree_move_end (tree
);
971 case CK_TreeMovePgUp
:
972 tree_move_pgup (tree
);
974 case CK_TreeMovePgDn
:
975 tree_move_pgdn (tree
);
978 tree_chdir_sel (tree
);
983 case CK_TreeStartSearch
:
984 tree_start_search (tree
);
990 res
= MSG_NOT_HANDLED
;
999 tree_key (WTree
* tree
, int key
)
1003 for (i
= 0; tree_map
[i
].key
!= 0; i
++)
1004 if (key
== tree_map
[i
].key
)
1005 switch (tree_map
[i
].command
)
1007 case CK_TreeMoveLeft
:
1008 return tree_move_left (tree
) ? MSG_HANDLED
: MSG_NOT_HANDLED
;
1009 case CK_TreeMoveRight
:
1010 return tree_move_right (tree
) ? MSG_HANDLED
: MSG_NOT_HANDLED
;
1012 tree_execute_cmd (tree
, tree_map
[i
].command
);
1016 if (is_abort_char (key
))
1020 tree
->searching
= 0;
1022 return MSG_HANDLED
; /* eat abort char */
1024 /* modal tree dialog: let upper layer see the
1025 abort character and close the dialog */
1026 return MSG_NOT_HANDLED
;
1029 /* Do not eat characters not meant for the tree below ' ' (e.g. C-l). */
1030 if ((key
>= ' ' && key
<= 255) || key
== KEY_BACKSPACE
)
1032 if (tree
->searching
)
1034 tree_do_search (tree
, key
);
1039 if (!command_prompt
)
1041 tree_start_search (tree
);
1042 tree_do_search (tree
, key
);
1045 return tree
->is_panel
? MSG_HANDLED
: MSG_NOT_HANDLED
;
1048 return MSG_NOT_HANDLED
;
1052 tree_frame (Dlg_head
* h
, WTree
* tree
)
1054 tty_setcolor (NORMAL_COLOR
);
1055 widget_erase ((Widget
*) tree
);
1058 draw_box (h
, tree
->widget
.y
, tree
->widget
.x
, tree
->widget
.lines
, tree
->widget
.cols
, FALSE
);
1061 tty_draw_hline (tree
->widget
.y
+ tlines (tree
) + 1,
1062 tree
->widget
.x
+ 1, ACS_HLINE
, tree
->widget
.cols
- 2);
1067 tree_callback (Widget
* w
, widget_msg_t msg
, int parm
)
1069 WTree
*tree
= (WTree
*) w
;
1070 Dlg_head
*h
= tree
->widget
.parent
;
1071 WButtonBar
*b
= find_buttonbar (h
);
1076 tree_frame (h
, tree
);
1082 buttonbar_set_label (b
, 1, Q_ ("ButtonBar|Help"), tree_map
, (Widget
*) tree
);
1083 buttonbar_set_label (b
, 2, Q_ ("ButtonBar|Rescan"), tree_map
, (Widget
*) tree
);
1084 buttonbar_set_label (b
, 3, Q_ ("ButtonBar|Forget"), tree_map
, (Widget
*) tree
);
1085 buttonbar_set_label (b
, 4, tree_navigation_flag
? Q_ ("ButtonBar|Static")
1086 : Q_ ("ButtonBar|Dynamc"), tree_map
, (Widget
*) tree
);
1087 buttonbar_set_label (b
, 5, Q_ ("ButtonBar|Copy"), tree_map
, (Widget
*) tree
);
1088 buttonbar_set_label (b
, 6, Q_ ("ButtonBar|RenMov"), tree_map
, (Widget
*) tree
);
1090 /* FIXME: mkdir is currently defunct */
1091 buttonbar_set_label (b
, 7, Q_ ("ButtonBar|Mkdir"), tree_map
, (Widget
*) tree
);
1093 buttonbar_clear_label (b
, 7, (Widget
*) tree
);
1095 buttonbar_set_label (b
, 8, Q_ ("ButtonBar|Rmdir"), tree_map
, (Widget
*) tree
);
1096 buttonbar_redraw (b
);
1098 /* FIXME: Should find a better way of only displaying the
1099 currently selected item */
1103 /* FIXME: Should find a better way of changing the color of the
1106 case WIDGET_UNFOCUS
:
1112 return tree_key (tree
, parm
);
1114 case WIDGET_COMMAND
:
1115 /* command from buttonbar */
1116 return tree_execute_cmd (tree
, parm
);
1118 case WIDGET_DESTROY
:
1119 tree_destroy (tree
);
1123 return default_proc (msg
, parm
);
1128 tree_new (int is_panel
, int y
, int x
, int lines
, int cols
)
1130 WTree
*tree
= g_new (WTree
, 1);
1132 init_widget (&tree
->widget
, y
, x
, lines
, cols
, tree_callback
, event_callback
);
1133 tree
->is_panel
= is_panel
;
1134 tree
->selected_ptr
= 0;
1136 tree
->store
= tree_store_get ();
1137 tree_store_add_entry_remove_hook (remove_callback
, tree
);
1138 tree
->tree_shown
= 0;
1139 tree
->search_buffer
[0] = 0;
1140 tree
->topdiff
= tree
->widget
.lines
/ 2;
1141 tree
->searching
= 0;
1144 /* We do not want to keep the cursor */
1145 widget_want_cursor (tree
->widget
, 0);
1151 tree_chdir (WTree
* tree
, const char *dir
)
1153 tree_entry
*current
;
1155 current
= tree_store_whereis (dir
);
1157 if (current
!= NULL
)
1159 tree
->selected_ptr
= current
;
1160 tree_check_focus (tree
);
1164 /* Return name of the currently selected entry */
1166 tree_selected_name (const WTree
* tree
)
1168 return tree
->selected_ptr
->name
;
1172 sync_tree (const char *path
)
1174 tree_chdir (the_tree
, path
);
1178 find_tree (struct Dlg_head
*h
)
1180 return (WTree
*) find_widget_type (h
, tree_callback
);