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"
70 const global_keymap_t
*tree_map
;
72 #define tlines(t) (t->is_panel ? t->widget.lines - 2 - (show_mini_info ? 2 : 0) : t->widget.lines)
74 /* Use the color of the parent widget for the unselected entries */
75 #define TREE_NORMALC(h) (DLG_NORMALC (h))
77 /* Specifies the display mode: 1d or 2d */
78 static gboolean tree_navigation_flag
= FALSE
;
82 struct TreeStore
*store
;
83 tree_entry
*selected_ptr
; /* The selected directory */
84 char search_buffer
[256]; /* Current search string */
85 tree_entry
**tree_shown
; /* Entries currently on screen */
86 int is_panel
; /* panel or plain widget flag */
87 int active
; /* if it's currently selected */
88 int searching
; /* Are we on searching mode? */
89 int topdiff
; /* The difference between the topmost
90 shown and the selected */
94 static void tree_rescan (void *data
);
97 back_ptr (tree_entry
*ptr
, int *count
)
101 while (ptr
&& ptr
->prev
&& i
< *count
){
110 forw_ptr (tree_entry
*ptr
, int *count
)
114 while (ptr
&& ptr
->next
&& i
< *count
){
123 remove_callback (tree_entry
*entry
, void *data
)
127 if (tree
->selected_ptr
== entry
){
128 if (tree
->selected_ptr
->next
)
129 tree
->selected_ptr
= tree
->selected_ptr
->next
;
131 tree
->selected_ptr
= tree
->selected_ptr
->prev
;
135 /* Save the ~/.mc/Tree file */
137 save_tree (WTree
*tree
)
143 error
= tree_store_save ();
147 tree_name
= g_build_filename (home_dir
, MC_USERCONF_DIR
,
148 MC_TREESTORE_FILE
, (char *) NULL
);
149 fprintf (stderr
, _("Cannot open the %s file for writing:\n%s\n"), tree_name
,
150 unix_error_string (error
));
156 tree_remove_entry (WTree
*tree
, char *name
)
159 tree_store_remove_entry (name
);
163 tree_destroy (WTree
*tree
)
165 tree_store_remove_entry_remove_hook (remove_callback
);
168 g_free (tree
->tree_shown
);
169 tree
->tree_shown
= 0;
170 tree
->selected_ptr
= NULL
;
173 /* Loads the .mc.tree file */
175 load_tree (WTree
*tree
)
179 tree
->selected_ptr
= tree
->store
->tree_first
;
180 tree_chdir (tree
, home_dir
);
184 tree_show_mini_info (WTree
*tree
, int tree_lines
, int tree_cols
)
186 Dlg_head
*h
= tree
->widget
.parent
;
197 tty_draw_hline (tree
->widget
.y
+ line
, tree
->widget
.x
+ 1, ' ', tree_cols
);
198 widget_move (&tree
->widget
, line
, 1);
200 if (tree
->searching
){
201 /* Show search string */
202 tty_setcolor (TREE_NORMALC (h
));
203 tty_setcolor (DLG_FOCUSC (h
));
204 tty_print_char (PATH_SEP
);
206 tty_print_string (str_fit_to_term (tree
->search_buffer
,
207 tree_cols
- 2, J_LEFT_FIT
));
208 tty_print_char (' ');
209 tty_setcolor (DLG_FOCUSC (h
));
211 /* Show full name of selected directory */
212 tty_print_string (str_fit_to_term (tree
->selected_ptr
->name
,
213 tree_cols
, J_LEFT_FIT
));
218 show_tree (WTree
*tree
)
220 Dlg_head
*h
= tree
->widget
.parent
;
222 int i
, j
, topsublevel
;
224 int tree_lines
, tree_cols
;
228 tree_lines
= tlines (tree
);
229 tree_cols
= tree
->widget
.cols
;
231 tty_setcolor (TREE_NORMALC (h
));
232 widget_move ((Widget
*)tree
, y
, x
);
238 g_free (tree
->tree_shown
);
239 tree
->tree_shown
= g_new0 (tree_entry
*, tree_lines
);
241 if (tree
->store
->tree_first
)
242 topsublevel
= tree
->store
->tree_first
->sublevel
;
245 if (!tree
->selected_ptr
){
246 tree
->selected_ptr
= tree
->store
->tree_first
;
249 current
= tree
->selected_ptr
;
251 /* Calculate the directory which is to be shown on the topmost line */
252 if (!tree_navigation_flag
)
253 current
= back_ptr (current
, &tree
->topdiff
);
256 while (current
->prev
&& i
< tree
->topdiff
){
257 current
= current
->prev
;
258 if (current
->sublevel
< tree
->selected_ptr
->sublevel
){
259 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
260 strlen (current
->name
)) == 0)
262 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
263 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
264 if (strncmp (current
->name
, tree
->selected_ptr
->name
, j
) == 0)
266 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+ 1
267 && strlen (tree
->selected_ptr
->name
) > 1){
268 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
269 strlen (tree
->selected_ptr
->name
)) == 0)
276 /* Loop for every line */
277 for (i
= 0; i
< tree_lines
; i
++){
278 /* Move to the beginning of the line */
279 tty_draw_hline (tree
->widget
.y
+ y
+ i
, tree
->widget
.x
+ x
, ' ', tree_cols
);
284 tree
->tree_shown
[i
] = current
;
285 if (current
->sublevel
== topsublevel
){
287 /* Top level directory */
288 if (tree
->active
&& current
== tree
->selected_ptr
) {
289 if (!tty_use_colors () && !tree
->is_panel
)
290 tty_setcolor (MARKED_COLOR
);
292 tty_setcolor (SELECTED_COLOR
);
296 tty_print_string (str_fit_to_term (current
->name
, tree_cols
- 6, J_LEFT_FIT
));
298 /* Sub level directory */
300 tty_set_alt_charset (TRUE
);
301 /* Output branch parts */
302 for (j
= 0; j
< current
->sublevel
- topsublevel
- 1; j
++){
303 if (tree_cols
- 8 - 3 * j
< 9)
305 tty_print_char (' ');
306 if (current
->submask
& (1 << (j
+ topsublevel
+ 1)))
307 tty_print_char (ACS_VLINE
);
309 tty_print_char (' ');
310 tty_print_char (' ');
312 tty_print_char (' '); j
++;
313 if (!current
->next
|| !(current
->next
->submask
& (1 << current
->sublevel
)))
314 tty_print_char (ACS_LLCORNER
);
316 tty_print_char (ACS_LTEE
);
317 tty_print_char (ACS_HLINE
);
318 tty_set_alt_charset (FALSE
);
320 if (tree
->active
&& current
== tree
->selected_ptr
) {
321 /* Selected directory -> change color */
322 if (!tty_use_colors () && !tree
->is_panel
)
323 tty_setcolor (MARKED_COLOR
);
325 tty_setcolor (SELECTED_COLOR
);
329 tty_print_char (' ');
330 tty_print_string (str_fit_to_term (current
->subname
,
331 tree_cols
- 2 - 4 - 3 * j
, J_LEFT_FIT
));
333 tty_print_char (' ');
335 /* Return to normal color */
336 tty_setcolor (TREE_NORMALC (h
));
338 /* Calculate the next value for current */
339 current
= current
->next
;
340 if (tree_navigation_flag
){
342 if (current
->sublevel
< tree
->selected_ptr
->sublevel
){
343 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
344 strlen (current
->name
)) == 0)
346 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
347 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
348 if (strncmp (current
->name
,tree
->selected_ptr
->name
,j
)== 0)
350 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+1
351 && strlen (tree
->selected_ptr
->name
) > 1){
352 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
353 strlen (tree
->selected_ptr
->name
)) == 0)
356 current
= current
->next
;
360 tree_show_mini_info (tree
, tree_lines
, tree_cols
);
364 tree_check_focus (WTree
*tree
)
366 if (tree
->topdiff
< 3)
368 else if (tree
->topdiff
>= tlines (tree
) - 3)
369 tree
->topdiff
= tlines (tree
) - 3 - 1;
373 tree_move_backward (WTree
*tree
, int i
)
375 if (!tree_navigation_flag
)
376 tree
->selected_ptr
= back_ptr (tree
->selected_ptr
, &i
);
381 current
= tree
->selected_ptr
;
382 while (j
< i
&& current
->prev
383 && current
->prev
->sublevel
>= tree
->selected_ptr
->sublevel
){
384 current
= current
->prev
;
385 if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
386 tree
->selected_ptr
= current
;
394 tree_check_focus (tree
);
398 tree_move_forward (WTree
*tree
, int i
)
400 if (!tree_navigation_flag
)
401 tree
->selected_ptr
= forw_ptr (tree
->selected_ptr
, &i
);
406 current
= tree
->selected_ptr
;
407 while (j
< i
&& current
->next
408 && current
->next
->sublevel
>= tree
->selected_ptr
->sublevel
){
409 current
= current
->next
;
410 if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
411 tree
->selected_ptr
= current
;
419 tree_check_focus (tree
);
423 tree_move_to_child (WTree
*tree
)
427 /* Do we have a starting point? */
428 if (!tree
->selected_ptr
)
430 /* Take the next entry */
431 current
= tree
->selected_ptr
->next
;
432 /* Is it the child of the selected entry */
433 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
){
434 /* Yes -> select this entry */
435 tree
->selected_ptr
= current
;
437 tree_check_focus (tree
);
439 /* No -> rescan and try again */
441 current
= tree
->selected_ptr
->next
;
442 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
){
443 tree
->selected_ptr
= current
;
445 tree_check_focus (tree
);
451 tree_move_to_parent (WTree
*tree
)
456 if (!tree
->selected_ptr
)
459 old
= tree
->selected_ptr
;
460 current
= tree
->selected_ptr
->prev
;
461 while (current
&& current
->sublevel
>= tree
->selected_ptr
->sublevel
){
462 current
= current
->prev
;
466 current
= tree
->store
->tree_first
;
467 tree
->selected_ptr
= current
;
468 tree_check_focus (tree
);
469 return tree
->selected_ptr
!= old
;
473 tree_move_to_top (WTree
*tree
)
475 tree
->selected_ptr
= tree
->store
->tree_first
;
480 tree_move_to_bottom (WTree
*tree
)
482 tree
->selected_ptr
= tree
->store
->tree_last
;
483 tree
->topdiff
= tlines (tree
) - 3 - 1;
486 /* Handle mouse click */
488 tree_event (WTree
*tree
, int y
)
490 if (tree
->tree_shown
[y
]){
491 tree
->selected_ptr
= tree
->tree_shown
[y
];
498 tree_chdir_sel (WTree
*tree
)
505 if (do_cd (tree
->selected_ptr
->name
, cd_exact
))
506 select_item (current_panel
);
508 message (D_ERROR
, MSG_ERROR
, _(" Cannot chdir to \"%s\" \n %s "),
509 tree
->selected_ptr
->name
, unix_error_string (errno
));
516 maybe_chdir (WTree
*tree
)
518 if (xtree_mode
&& tree
->is_panel
&& is_idle ())
519 tree_chdir_sel (tree
);
524 event_callback (Gpm_Event
*event
, void *data
)
528 /* rest of the upper frame, the menu is invisible - call menu */
529 if (tree
->is_panel
&& (event
->type
& GPM_DOWN
)
530 && event
->y
== 1 && !menubar_visible
) {
531 event
->x
+= tree
->widget
.x
;
532 return the_menubar
->widget
.mouse (event
, the_menubar
);
535 if (!(event
->type
& GPM_UP
))
547 tree_move_backward (tree
, tlines (tree
) - 1);
549 } else if (event
->y
>= tlines (tree
)){
550 tree_move_forward (tree
, tlines (tree
) - 1);
553 tree_event (tree
, event
->y
);
554 if ((event
->type
& (GPM_UP
|GPM_DOUBLE
)) == (GPM_UP
|GPM_DOUBLE
)){
555 tree_chdir_sel (tree
);
561 /* Search tree for text */
563 search_tree (WTree
*tree
, char *text
)
571 current
= tree
->selected_ptr
;
573 while (!wrapped
|| current
!= tree
->selected_ptr
){
574 if (strncmp (current
->subname
, text
, len
) == 0){
575 tree
->selected_ptr
= current
;
579 current
= current
->next
;
581 current
= tree
->store
->tree_first
;
586 tree_check_focus (tree
);
591 tree_do_search (WTree
*tree
, int key
)
595 l
= strlen (tree
->search_buffer
);
596 if ((l
!= 0) && (key
== KEY_BACKSPACE
))
597 tree
->search_buffer
[--l
] = '\0';
598 else if (key
&& l
< sizeof (tree
->search_buffer
)){
599 tree
->search_buffer
[l
] = key
;
600 tree
->search_buffer
[++l
] = '\0';
603 if (!search_tree (tree
, tree
->search_buffer
))
604 tree
->search_buffer
[--l
] = 0;
611 tree_rescan (void *data
)
613 char old_dir
[MC_MAXPATHLEN
];
616 if (!tree
->selected_ptr
|| !mc_get_current_wd (old_dir
, MC_MAXPATHLEN
) ||
617 mc_chdir (tree
->selected_ptr
->name
))
620 tree_store_rescan (tree
->selected_ptr
->name
);
625 tree_forget (void *data
)
628 if (tree
->selected_ptr
)
629 tree_remove_entry (tree
, tree
->selected_ptr
->name
);
633 tree_copy (WTree
*tree
, const char *default_dest
)
635 char msg
[BUF_MEDIUM
];
641 if (tree
->selected_ptr
== NULL
)
644 g_snprintf (msg
, sizeof (msg
), _("Copy \"%s\" directory to:"),
645 str_trunc (tree
->selected_ptr
->name
, 50));
646 dest
= input_expand_dialog (Q_("DialogTitle|Copy"), msg
, MC_HISTORY_FM_TREE_COPY
, default_dest
);
648 if (dest
!= NULL
&& *dest
!= '\0') {
649 ctx
= file_op_context_new (OP_COPY
);
650 file_op_context_create_ui (ctx
, FALSE
);
651 copy_dir_dir (ctx
, tree
->selected_ptr
->name
, dest
, 1, 0, 0, 0, &count
, &bytes
);
652 file_op_context_destroy (ctx
);
659 tree_move (WTree
*tree
, const char *default_dest
)
661 char msg
[BUF_MEDIUM
];
668 if (tree
->selected_ptr
== NULL
)
671 g_snprintf (msg
, sizeof (msg
), _("Move \"%s\" directory to:"),
672 str_trunc (tree
->selected_ptr
->name
, 50));
673 dest
= input_expand_dialog (Q_("DialogTitle|Move"), msg
, MC_HISTORY_FM_TREE_MOVE
, default_dest
);
675 if (dest
== NULL
|| *dest
== '\0') {
680 if (stat (dest
, &buf
)){
681 message (D_ERROR
, MSG_ERROR
, _(" Cannot stat the destination \n %s "),
682 unix_error_string (errno
));
687 if (!S_ISDIR (buf
.st_mode
)){
688 file_error (_(" Destination \"%s\" must be a directory \n %s "),
694 ctx
= file_op_context_new (OP_MOVE
);
695 file_op_context_create_ui (ctx
, FALSE
);
696 move_dir_dir (ctx
, tree
->selected_ptr
->name
, dest
, &count
, &bytes
);
697 file_op_context_destroy (ctx
);
704 tree_mkdir (WTree
*tree
)
706 char old_dir
[MC_MAXPATHLEN
];
708 if (!tree
->selected_ptr
)
710 if (!mc_get_current_wd (old_dir
, MC_MAXPATHLEN
))
712 if (chdir (tree
->selected_ptr
->name
))
723 tree_rmdir (void *data
)
730 if (!tree
->selected_ptr
)
733 if (confirm_delete
) {
738 g_strdup_printf (_(" Delete %s? "),
739 tree
->selected_ptr
->name
);
741 query_dialog (Q_("DialogTitle|Delete"), buf
, D_ERROR
, 2, _("&Yes"), _("&No"));
747 ctx
= file_op_context_new (OP_DELETE
);
748 file_op_context_create_ui (ctx
, FALSE
);
749 if (erase_dir (ctx
, tree
->selected_ptr
->name
, &count
, &bytes
) == FILE_CONT
)
751 file_op_context_destroy (ctx
);
755 tree_move_up (WTree
*tree
)
757 tree_move_backward (tree
, 1);
763 tree_move_down (WTree
*tree
)
765 tree_move_forward (tree
, 1);
771 tree_move_home (WTree
*tree
)
773 tree_move_to_top (tree
);
779 tree_move_end (WTree
*tree
)
781 tree_move_to_bottom (tree
);
787 tree_move_pgup (WTree
*tree
)
789 tree_move_backward (tree
, tlines (tree
) - 1);
795 tree_move_pgdn (WTree
*tree
)
797 tree_move_forward (tree
, tlines (tree
) - 1);
803 tree_move_left (WTree
*tree
)
807 if (tree_navigation_flag
) {
808 v
= tree_move_to_parent (tree
);
817 tree_move_right (WTree
*tree
)
821 if (tree_navigation_flag
) {
822 tree_move_to_child (tree
);
832 tree_start_search (WTree
*tree
)
836 if (tree
->searching
) {
837 if (tree
->selected_ptr
== tree
->store
->tree_last
)
838 tree_move_to_top (tree
);
840 /* set navigation mode temporarily to 'Static' because in
841 * dynamic navigation mode tree_move_forward will not move
842 * to a lower sublevel if necessary (sequent searches must
843 * start with the directory followed the last found directory)
845 i
= tree_navigation_flag
;
846 tree_navigation_flag
= 0;
847 tree_move_forward (tree
, 1);
848 tree_navigation_flag
= i
;
850 tree_do_search (tree
, 0);
853 tree
->search_buffer
[0] = 0;
858 tree_toggle_navig (WTree
*tree
)
860 tree_navigation_flag
= !tree_navigation_flag
;
861 buttonbar_set_label (find_buttonbar (tree
->widget
.parent
), 4,
862 tree_navigation_flag
? Q_("ButtonBar|Static")
863 : Q_("ButtonBar|Dynamc"),
864 tree_map
, (Widget
*) tree
);
868 tree_execute_cmd (WTree
*tree
, unsigned long command
)
870 cb_ret_t res
= MSG_HANDLED
;
872 if (command
!= CK_TreeStartSearch
)
877 interactive_display (NULL
, "[Directory Tree]");
882 case CK_TreeToggleNav
:
883 tree_toggle_navig (tree
);
886 tree_copy (tree
, "");
889 tree_move (tree
, "");
894 case CK_TreeMoveDown
:
895 tree_move_down (tree
);
897 case CK_TreeMoveHome
:
898 tree_move_home (tree
);
901 tree_move_end (tree
);
903 case CK_TreeMovePgUp
:
904 tree_move_pgup (tree
);
906 case CK_TreeMovePgDn
:
907 tree_move_pgdn (tree
);
910 tree_chdir_sel (tree
);
915 case CK_TreeStartSearch
:
916 tree_start_search (tree
);
922 res
= MSG_NOT_HANDLED
;
931 tree_key (WTree
*tree
, int key
)
935 for (i
= 0; tree_map
[i
].key
!= 0; i
++)
936 if (key
== tree_map
[i
].key
)
937 switch (tree_map
[i
].command
) {
938 case CK_TreeMoveLeft
:
939 return tree_move_left (tree
) ? MSG_HANDLED
: MSG_NOT_HANDLED
;
940 case CK_TreeMoveRight
:
941 return tree_move_right (tree
) ? MSG_HANDLED
: MSG_NOT_HANDLED
;
943 tree_execute_cmd (tree
, tree_map
[i
].command
);
947 if (is_abort_char (key
)) {
948 if (tree
->is_panel
) {
951 return MSG_HANDLED
; /* eat abort char */
953 /* modal tree dialog: let upper layer see the
954 abort character and close the dialog */
955 return MSG_NOT_HANDLED
;
958 /* Do not eat characters not meant for the tree below ' ' (e.g. C-l). */
959 if ((key
>= ' ' && key
<= 255) || key
== KEY_BACKSPACE
) {
960 if (tree
->searching
){
961 tree_do_search (tree
, key
);
966 if (!command_prompt
) {
967 tree_start_search (tree
);
968 tree_do_search (tree
, key
);
971 return tree
->is_panel
? MSG_HANDLED
: MSG_NOT_HANDLED
;
974 return MSG_NOT_HANDLED
;
978 tree_frame (Dlg_head
*h
, WTree
*tree
)
980 tty_setcolor (NORMAL_COLOR
);
981 widget_erase ((Widget
*) tree
);
982 if (tree
->is_panel
) {
983 draw_box (h
, tree
->widget
.y
, tree
->widget
.x
, tree
->widget
.lines
,
987 tty_draw_hline (tree
->widget
.y
+ tlines (tree
) + 1,
989 ACS_HLINE
, tree
->widget
.cols
- 2);
994 tree_callback (Widget
*w
, widget_msg_t msg
, int parm
)
996 WTree
*tree
= (WTree
*) w
;
997 Dlg_head
*h
= tree
->widget
.parent
;
998 WButtonBar
*b
= find_buttonbar (h
);
1002 tree_frame (h
, tree
);
1008 buttonbar_set_label (b
, 1, Q_("ButtonBar|Help"), tree_map
, (Widget
*) tree
);
1009 buttonbar_set_label (b
, 2, Q_("ButtonBar|Rescan"), tree_map
, (Widget
*) tree
);
1010 buttonbar_set_label (b
, 3, Q_("ButtonBar|Forget"), tree_map
, (Widget
*) tree
);
1011 buttonbar_set_label (b
, 4, tree_navigation_flag
? Q_("ButtonBar|Static")
1012 : Q_("ButtonBar|Dynamc"),
1013 tree_map
, (Widget
*) tree
);
1014 buttonbar_set_label (b
, 5, Q_("ButtonBar|Copy"), tree_map
, (Widget
*) tree
);
1015 buttonbar_set_label (b
, 6, Q_("ButtonBar|RenMov"), tree_map
, (Widget
*) tree
);
1017 /* FIXME: mkdir is currently defunct */
1018 buttonbar_set_label (b
, 7, Q_("ButtonBar|Mkdir"), tree_map
, (Widget
*) tree
);
1020 buttonbar_clear_label (b
, 7, (Widget
*) tree
);
1022 buttonbar_set_label (b
, 8, Q_("ButtonBar|Rmdir"), tree_map
, (Widget
*) tree
);
1023 buttonbar_redraw (b
);
1025 /* FIXME: Should find a better way of only displaying the
1026 currently selected item */
1030 /* FIXME: Should find a better way of changing the color of the
1033 case WIDGET_UNFOCUS
:
1039 return tree_key (tree
, parm
);
1041 case WIDGET_COMMAND
:
1042 /* command from buttonbar */
1043 return tree_execute_cmd (tree
, parm
);
1045 case WIDGET_DESTROY
:
1046 tree_destroy (tree
);
1050 return default_proc (msg
, parm
);
1055 tree_new (int is_panel
, int y
, int x
, int lines
, int cols
)
1057 WTree
*tree
= g_new (WTree
, 1);
1059 init_widget (&tree
->widget
, y
, x
, lines
, cols
,
1060 tree_callback
, event_callback
);
1061 tree
->is_panel
= is_panel
;
1062 tree
->selected_ptr
= 0;
1064 tree
->store
= tree_store_get ();
1065 tree_store_add_entry_remove_hook (remove_callback
, tree
);
1066 tree
->tree_shown
= 0;
1067 tree
->search_buffer
[0] = 0;
1068 tree
->topdiff
= tree
->widget
.lines
/ 2;
1069 tree
->searching
= 0;
1072 /* We do not want to keep the cursor */
1073 widget_want_cursor (tree
->widget
, 0);
1079 tree_chdir (WTree
*tree
, const char *dir
)
1081 tree_entry
*current
;
1083 current
= tree_store_whereis (dir
);
1085 if (current
!= NULL
) {
1086 tree
->selected_ptr
= current
;
1087 tree_check_focus (tree
);
1091 /* Return name of the currently selected entry */
1093 tree_selected_name (const WTree
*tree
)
1095 return tree
->selected_ptr
->name
;
1099 sync_tree (const char *path
)
1101 tree_chdir (the_tree
, path
);
1105 find_tree (struct Dlg_head
*h
)
1107 return (WTree
*) find_widget_type (h
, tree_callback
);