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>
44 #include "../src/tty/tty.h"
45 #include "../src/skin/skin.h"
46 #include "../src/tty/mouse.h"
47 #include "../src/tty/key.h"
49 #include "wtools.h" /* message() */
55 #include "main-widgets.h" /* the_menubar */
56 #include "menu.h" /* menubar_visible */
57 #include "file.h" /* copy_dir_dir(), move_dir_dir(), erase_dir() */
58 #include "layout.h" /* command_prompt */
60 #include "treestore.h"
69 const global_keymap_t
*tree_map
;
71 #define tlines(t) (t->is_panel ? t->widget.lines - 2 - (show_mini_info ? 2 : 0) : t->widget.lines)
73 /* Use the color of the parent widget for the unselected entries */
74 #define TREE_NORMALC(h) (DLG_NORMALC (h))
76 /* Specifies the display mode: 1d or 2d */
77 static gboolean tree_navigation_flag
= FALSE
;
81 struct TreeStore
*store
;
82 tree_entry
*selected_ptr
; /* The selected directory */
83 char search_buffer
[256]; /* Current search string */
84 tree_entry
**tree_shown
; /* Entries currently on screen */
85 int is_panel
; /* panel or plain widget flag */
86 int active
; /* if it's currently selected */
87 int searching
; /* Are we on searching mode? */
88 int topdiff
; /* The difference between the topmost
89 shown and the selected */
93 static void tree_rescan (void *data
);
96 back_ptr (tree_entry
*ptr
, int *count
)
100 while (ptr
&& ptr
->prev
&& i
< *count
){
109 forw_ptr (tree_entry
*ptr
, int *count
)
113 while (ptr
&& ptr
->next
&& i
< *count
){
122 remove_callback (tree_entry
*entry
, void *data
)
126 if (tree
->selected_ptr
== entry
){
127 if (tree
->selected_ptr
->next
)
128 tree
->selected_ptr
= tree
->selected_ptr
->next
;
130 tree
->selected_ptr
= tree
->selected_ptr
->prev
;
134 /* Save the ~/.mc/Tree file */
136 save_tree (WTree
*tree
)
142 error
= tree_store_save ();
146 tree_name
= g_build_filename (home_dir
, MC_USERCONF_DIR
,
147 MC_TREESTORE_FILE
, (char *) NULL
);
148 fprintf (stderr
, _("Cannot open the %s file for writing:\n%s\n"), tree_name
,
149 unix_error_string (error
));
155 tree_remove_entry (WTree
*tree
, char *name
)
158 tree_store_remove_entry (name
);
162 tree_destroy (WTree
*tree
)
164 tree_store_remove_entry_remove_hook (remove_callback
);
167 g_free (tree
->tree_shown
);
168 tree
->tree_shown
= 0;
169 tree
->selected_ptr
= NULL
;
172 /* Loads the .mc.tree file */
174 load_tree (WTree
*tree
)
178 tree
->selected_ptr
= tree
->store
->tree_first
;
179 tree_chdir (tree
, home_dir
);
183 tree_show_mini_info (WTree
*tree
, int tree_lines
, int tree_cols
)
185 Dlg_head
*h
= tree
->widget
.parent
;
196 tty_draw_hline (tree
->widget
.y
+ line
, tree
->widget
.x
+ 1, ' ', tree_cols
);
197 widget_move (&tree
->widget
, line
, 1);
199 if (tree
->searching
){
200 /* Show search string */
201 tty_setcolor (TREE_NORMALC (h
));
202 tty_setcolor (DLG_FOCUSC (h
));
203 tty_print_char (PATH_SEP
);
205 tty_print_string (str_fit_to_term (tree
->search_buffer
,
206 tree_cols
- 2, J_LEFT_FIT
));
207 tty_print_char (' ');
208 tty_setcolor (DLG_FOCUSC (h
));
210 /* Show full name of selected directory */
211 tty_print_string (str_fit_to_term (tree
->selected_ptr
->name
,
212 tree_cols
, J_LEFT_FIT
));
217 show_tree (WTree
*tree
)
219 Dlg_head
*h
= tree
->widget
.parent
;
221 int i
, j
, topsublevel
;
223 int tree_lines
, tree_cols
;
227 tree_lines
= tlines (tree
);
228 tree_cols
= tree
->widget
.cols
;
230 tty_setcolor (TREE_NORMALC (h
));
231 widget_move ((Widget
*)tree
, y
, x
);
237 g_free (tree
->tree_shown
);
238 tree
->tree_shown
= g_new0 (tree_entry
*, tree_lines
);
240 if (tree
->store
->tree_first
)
241 topsublevel
= tree
->store
->tree_first
->sublevel
;
244 if (!tree
->selected_ptr
){
245 tree
->selected_ptr
= tree
->store
->tree_first
;
248 current
= tree
->selected_ptr
;
250 /* Calculate the directory which is to be shown on the topmost line */
251 if (!tree_navigation_flag
)
252 current
= back_ptr (current
, &tree
->topdiff
);
255 while (current
->prev
&& i
< tree
->topdiff
){
256 current
= current
->prev
;
257 if (current
->sublevel
< tree
->selected_ptr
->sublevel
){
258 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
259 strlen (current
->name
)) == 0)
261 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
262 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
263 if (strncmp (current
->name
, tree
->selected_ptr
->name
, j
) == 0)
265 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+ 1
266 && strlen (tree
->selected_ptr
->name
) > 1){
267 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
268 strlen (tree
->selected_ptr
->name
)) == 0)
275 /* Loop for every line */
276 for (i
= 0; i
< tree_lines
; i
++){
277 /* Move to the beginning of the line */
278 tty_draw_hline (tree
->widget
.y
+ y
+ i
, tree
->widget
.x
+ x
, ' ', tree_cols
);
283 tree
->tree_shown
[i
] = current
;
284 if (current
->sublevel
== topsublevel
){
286 /* Top level directory */
287 if (tree
->active
&& current
== tree
->selected_ptr
) {
288 if (!tty_use_colors () && !tree
->is_panel
)
289 tty_setcolor (MARKED_COLOR
);
291 tty_setcolor (SELECTED_COLOR
);
295 tty_print_string (str_fit_to_term (current
->name
, tree_cols
- 6, J_LEFT_FIT
));
297 /* Sub level directory */
299 tty_set_alt_charset (TRUE
);
300 /* Output branch parts */
301 for (j
= 0; j
< current
->sublevel
- topsublevel
- 1; j
++){
302 if (tree_cols
- 8 - 3 * j
< 9)
304 tty_print_char (' ');
305 if (current
->submask
& (1 << (j
+ topsublevel
+ 1)))
306 tty_print_char (ACS_VLINE
);
308 tty_print_char (' ');
309 tty_print_char (' ');
311 tty_print_char (' '); j
++;
312 if (!current
->next
|| !(current
->next
->submask
& (1 << current
->sublevel
)))
313 tty_print_char (ACS_LLCORNER
);
315 tty_print_char (ACS_LTEE
);
316 tty_print_char (ACS_HLINE
);
317 tty_set_alt_charset (FALSE
);
319 if (tree
->active
&& current
== tree
->selected_ptr
) {
320 /* Selected directory -> change color */
321 if (!tty_use_colors () && !tree
->is_panel
)
322 tty_setcolor (MARKED_COLOR
);
324 tty_setcolor (SELECTED_COLOR
);
328 tty_print_char (' ');
329 tty_print_string (str_fit_to_term (current
->subname
,
330 tree_cols
- 2 - 4 - 3 * j
, J_LEFT_FIT
));
332 tty_print_char (' ');
334 /* Return to normal color */
335 tty_setcolor (TREE_NORMALC (h
));
337 /* Calculate the next value for current */
338 current
= current
->next
;
339 if (tree_navigation_flag
){
341 if (current
->sublevel
< tree
->selected_ptr
->sublevel
){
342 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
343 strlen (current
->name
)) == 0)
345 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
346 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
347 if (strncmp (current
->name
,tree
->selected_ptr
->name
,j
)== 0)
349 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+1
350 && strlen (tree
->selected_ptr
->name
) > 1){
351 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
352 strlen (tree
->selected_ptr
->name
)) == 0)
355 current
= current
->next
;
359 tree_show_mini_info (tree
, tree_lines
, tree_cols
);
363 tree_check_focus (WTree
*tree
)
365 if (tree
->topdiff
< 3)
367 else if (tree
->topdiff
>= tlines (tree
) - 3)
368 tree
->topdiff
= tlines (tree
) - 3 - 1;
372 tree_move_backward (WTree
*tree
, int i
)
374 if (!tree_navigation_flag
)
375 tree
->selected_ptr
= back_ptr (tree
->selected_ptr
, &i
);
380 current
= tree
->selected_ptr
;
381 while (j
< i
&& current
->prev
382 && current
->prev
->sublevel
>= tree
->selected_ptr
->sublevel
){
383 current
= current
->prev
;
384 if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
385 tree
->selected_ptr
= current
;
393 tree_check_focus (tree
);
397 tree_move_forward (WTree
*tree
, int i
)
399 if (!tree_navigation_flag
)
400 tree
->selected_ptr
= forw_ptr (tree
->selected_ptr
, &i
);
405 current
= tree
->selected_ptr
;
406 while (j
< i
&& current
->next
407 && current
->next
->sublevel
>= tree
->selected_ptr
->sublevel
){
408 current
= current
->next
;
409 if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
410 tree
->selected_ptr
= current
;
418 tree_check_focus (tree
);
422 tree_move_to_child (WTree
*tree
)
426 /* Do we have a starting point? */
427 if (!tree
->selected_ptr
)
429 /* Take the next entry */
430 current
= tree
->selected_ptr
->next
;
431 /* Is it the child of the selected entry */
432 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
){
433 /* Yes -> select this entry */
434 tree
->selected_ptr
= current
;
436 tree_check_focus (tree
);
438 /* No -> rescan and try again */
440 current
= tree
->selected_ptr
->next
;
441 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
){
442 tree
->selected_ptr
= current
;
444 tree_check_focus (tree
);
450 tree_move_to_parent (WTree
*tree
)
455 if (!tree
->selected_ptr
)
458 old
= tree
->selected_ptr
;
459 current
= tree
->selected_ptr
->prev
;
460 while (current
&& current
->sublevel
>= tree
->selected_ptr
->sublevel
){
461 current
= current
->prev
;
465 current
= tree
->store
->tree_first
;
466 tree
->selected_ptr
= current
;
467 tree_check_focus (tree
);
468 return tree
->selected_ptr
!= old
;
472 tree_move_to_top (WTree
*tree
)
474 tree
->selected_ptr
= tree
->store
->tree_first
;
479 tree_move_to_bottom (WTree
*tree
)
481 tree
->selected_ptr
= tree
->store
->tree_last
;
482 tree
->topdiff
= tlines (tree
) - 3 - 1;
485 /* Handle mouse click */
487 tree_event (WTree
*tree
, int y
)
489 if (tree
->tree_shown
[y
]){
490 tree
->selected_ptr
= tree
->tree_shown
[y
];
497 tree_chdir_sel (WTree
*tree
)
504 if (do_cd (tree
->selected_ptr
->name
, cd_exact
))
505 select_item (current_panel
);
507 message (D_ERROR
, MSG_ERROR
, _(" Cannot chdir to \"%s\" \n %s "),
508 tree
->selected_ptr
->name
, unix_error_string (errno
));
515 maybe_chdir (WTree
*tree
)
517 if (xtree_mode
&& tree
->is_panel
&& is_idle ())
518 tree_chdir_sel (tree
);
523 event_callback (Gpm_Event
*event
, void *data
)
527 /* rest of the upper frame, the menu is invisible - call menu */
528 if (tree
->is_panel
&& (event
->type
& GPM_DOWN
)
529 && event
->y
== 1 && !menubar_visible
) {
530 event
->x
+= tree
->widget
.x
;
531 return the_menubar
->widget
.mouse (event
, the_menubar
);
534 if (!(event
->type
& GPM_UP
))
546 tree_move_backward (tree
, tlines (tree
) - 1);
548 } else if (event
->y
>= tlines (tree
)){
549 tree_move_forward (tree
, tlines (tree
) - 1);
552 tree_event (tree
, event
->y
);
553 if ((event
->type
& (GPM_UP
|GPM_DOUBLE
)) == (GPM_UP
|GPM_DOUBLE
)){
554 tree_chdir_sel (tree
);
560 /* Search tree for text */
562 search_tree (WTree
*tree
, char *text
)
570 current
= tree
->selected_ptr
;
572 while (!wrapped
|| current
!= tree
->selected_ptr
){
573 if (strncmp (current
->subname
, text
, len
) == 0){
574 tree
->selected_ptr
= current
;
578 current
= current
->next
;
580 current
= tree
->store
->tree_first
;
585 tree_check_focus (tree
);
590 tree_do_search (WTree
*tree
, int key
)
594 l
= strlen (tree
->search_buffer
);
595 if ((l
!= 0) && (key
== KEY_BACKSPACE
))
596 tree
->search_buffer
[--l
] = '\0';
597 else if (key
&& l
< sizeof (tree
->search_buffer
)){
598 tree
->search_buffer
[l
] = key
;
599 tree
->search_buffer
[++l
] = '\0';
602 if (!search_tree (tree
, tree
->search_buffer
))
603 tree
->search_buffer
[--l
] = 0;
610 tree_rescan (void *data
)
612 char old_dir
[MC_MAXPATHLEN
];
615 if (!tree
->selected_ptr
|| !mc_get_current_wd (old_dir
, MC_MAXPATHLEN
) ||
616 mc_chdir (tree
->selected_ptr
->name
))
619 tree_store_rescan (tree
->selected_ptr
->name
);
624 tree_forget (void *data
)
627 if (tree
->selected_ptr
)
628 tree_remove_entry (tree
, tree
->selected_ptr
->name
);
632 tree_copy (WTree
*tree
, const char *default_dest
)
634 char msg
[BUF_MEDIUM
];
640 if (tree
->selected_ptr
== NULL
)
643 g_snprintf (msg
, sizeof (msg
), _("Copy \"%s\" directory to:"),
644 str_trunc (tree
->selected_ptr
->name
, 50));
645 dest
= input_expand_dialog (Q_("DialogTitle|Copy"), msg
, MC_HISTORY_FM_TREE_COPY
, default_dest
);
647 if (dest
!= NULL
&& *dest
!= '\0') {
648 ctx
= file_op_context_new (OP_COPY
);
649 file_op_context_create_ui (ctx
, FALSE
);
650 copy_dir_dir (ctx
, tree
->selected_ptr
->name
, dest
, 1, 0, 0, 0, &count
, &bytes
);
651 file_op_context_destroy (ctx
);
658 tree_move (WTree
*tree
, const char *default_dest
)
660 char msg
[BUF_MEDIUM
];
667 if (tree
->selected_ptr
== NULL
)
670 g_snprintf (msg
, sizeof (msg
), _("Move \"%s\" directory to:"),
671 str_trunc (tree
->selected_ptr
->name
, 50));
672 dest
= input_expand_dialog (Q_("DialogTitle|Move"), msg
, MC_HISTORY_FM_TREE_MOVE
, default_dest
);
674 if (dest
== NULL
|| *dest
== '\0') {
679 if (stat (dest
, &buf
)){
680 message (D_ERROR
, MSG_ERROR
, _(" Cannot stat the destination \n %s "),
681 unix_error_string (errno
));
686 if (!S_ISDIR (buf
.st_mode
)){
687 file_error (_(" Destination \"%s\" must be a directory \n %s "),
693 ctx
= file_op_context_new (OP_MOVE
);
694 file_op_context_create_ui (ctx
, FALSE
);
695 move_dir_dir (ctx
, tree
->selected_ptr
->name
, dest
, &count
, &bytes
);
696 file_op_context_destroy (ctx
);
703 tree_mkdir (WTree
*tree
)
705 char old_dir
[MC_MAXPATHLEN
];
707 if (!tree
->selected_ptr
)
709 if (!mc_get_current_wd (old_dir
, MC_MAXPATHLEN
))
711 if (chdir (tree
->selected_ptr
->name
))
722 tree_rmdir (void *data
)
729 if (!tree
->selected_ptr
)
732 if (confirm_delete
) {
737 g_strdup_printf (_(" Delete %s? "),
738 tree
->selected_ptr
->name
);
740 query_dialog (Q_("DialogTitle|Delete"), buf
, D_ERROR
, 2, _("&Yes"), _("&No"));
746 ctx
= file_op_context_new (OP_DELETE
);
747 file_op_context_create_ui (ctx
, FALSE
);
748 if (erase_dir (ctx
, tree
->selected_ptr
->name
, &count
, &bytes
) == FILE_CONT
)
750 file_op_context_destroy (ctx
);
754 tree_move_up (WTree
*tree
)
756 tree_move_backward (tree
, 1);
762 tree_move_down (WTree
*tree
)
764 tree_move_forward (tree
, 1);
770 tree_move_home (WTree
*tree
)
772 tree_move_to_top (tree
);
778 tree_move_end (WTree
*tree
)
780 tree_move_to_bottom (tree
);
786 tree_move_pgup (WTree
*tree
)
788 tree_move_backward (tree
, tlines (tree
) - 1);
794 tree_move_pgdn (WTree
*tree
)
796 tree_move_forward (tree
, tlines (tree
) - 1);
802 tree_move_left (WTree
*tree
)
806 if (tree_navigation_flag
) {
807 v
= tree_move_to_parent (tree
);
816 tree_move_right (WTree
*tree
)
820 if (tree_navigation_flag
) {
821 tree_move_to_child (tree
);
831 tree_start_search (WTree
*tree
)
835 if (tree
->searching
) {
836 if (tree
->selected_ptr
== tree
->store
->tree_last
)
837 tree_move_to_top (tree
);
839 /* set navigation mode temporarily to 'Static' because in
840 * dynamic navigation mode tree_move_forward will not move
841 * to a lower sublevel if necessary (sequent searches must
842 * start with the directory followed the last found directory)
844 i
= tree_navigation_flag
;
845 tree_navigation_flag
= 0;
846 tree_move_forward (tree
, 1);
847 tree_navigation_flag
= i
;
849 tree_do_search (tree
, 0);
852 tree
->search_buffer
[0] = 0;
857 tree_toggle_navig (WTree
*tree
)
859 tree_navigation_flag
= !tree_navigation_flag
;
860 buttonbar_set_label (find_buttonbar (tree
->widget
.parent
), 4,
861 tree_navigation_flag
? Q_("ButtonBar|Static")
862 : Q_("ButtonBar|Dynamc"),
863 tree_map
, (Widget
*) tree
);
867 tree_execute_cmd (WTree
*tree
, unsigned long command
)
869 cb_ret_t res
= MSG_HANDLED
;
871 if (command
!= CK_TreeStartSearch
)
876 interactive_display (NULL
, "[Directory Tree]");
881 case CK_TreeToggleNav
:
882 tree_toggle_navig (tree
);
885 tree_copy (tree
, "");
888 tree_move (tree
, "");
893 case CK_TreeMoveDown
:
894 tree_move_down (tree
);
896 case CK_TreeMoveHome
:
897 tree_move_home (tree
);
900 tree_move_end (tree
);
902 case CK_TreeMovePgUp
:
903 tree_move_pgup (tree
);
905 case CK_TreeMovePgDn
:
906 tree_move_pgdn (tree
);
909 tree_chdir_sel (tree
);
914 case CK_TreeStartSearch
:
915 tree_start_search (tree
);
921 res
= MSG_NOT_HANDLED
;
930 tree_key (WTree
*tree
, int key
)
934 for (i
= 0; tree_map
[i
].key
!= 0; i
++)
935 if (key
== tree_map
[i
].key
)
936 switch (tree_map
[i
].command
) {
937 case CK_TreeMoveLeft
:
938 return tree_move_left (tree
) ? MSG_HANDLED
: MSG_NOT_HANDLED
;
939 case CK_TreeMoveRight
:
940 return tree_move_right (tree
) ? MSG_HANDLED
: MSG_NOT_HANDLED
;
942 tree_execute_cmd (tree
, tree_map
[i
].command
);
946 if (is_abort_char (key
)) {
947 if (tree
->is_panel
) {
950 return MSG_HANDLED
; /* eat abort char */
952 /* modal tree dialog: let upper layer see the
953 abort character and close the dialog */
954 return MSG_NOT_HANDLED
;
957 /* Do not eat characters not meant for the tree below ' ' (e.g. C-l). */
958 if ((key
>= ' ' && key
<= 255) || key
== KEY_BACKSPACE
) {
959 if (tree
->searching
){
960 tree_do_search (tree
, key
);
965 if (!command_prompt
) {
966 tree_start_search (tree
);
967 tree_do_search (tree
, key
);
970 return tree
->is_panel
? MSG_HANDLED
: MSG_NOT_HANDLED
;
973 return MSG_NOT_HANDLED
;
977 tree_frame (Dlg_head
*h
, WTree
*tree
)
979 tty_setcolor (NORMAL_COLOR
);
980 widget_erase ((Widget
*) tree
);
981 if (tree
->is_panel
) {
982 draw_box (h
, tree
->widget
.y
, tree
->widget
.x
, tree
->widget
.lines
,
986 tty_draw_hline (tree
->widget
.y
+ tlines (tree
) + 1,
988 ACS_HLINE
, tree
->widget
.cols
- 2);
993 tree_callback (Widget
*w
, widget_msg_t msg
, int parm
)
995 WTree
*tree
= (WTree
*) w
;
996 Dlg_head
*h
= tree
->widget
.parent
;
997 WButtonBar
*b
= find_buttonbar (h
);
1001 tree_frame (h
, tree
);
1007 buttonbar_set_label (b
, 1, Q_("ButtonBar|Help"), tree_map
, (Widget
*) tree
);
1008 buttonbar_set_label (b
, 2, Q_("ButtonBar|Rescan"), tree_map
, (Widget
*) tree
);
1009 buttonbar_set_label (b
, 3, Q_("ButtonBar|Forget"), tree_map
, (Widget
*) tree
);
1010 buttonbar_set_label (b
, 4, tree_navigation_flag
? Q_("ButtonBar|Static")
1011 : Q_("ButtonBar|Dynamc"),
1012 tree_map
, (Widget
*) tree
);
1013 buttonbar_set_label (b
, 5, Q_("ButtonBar|Copy"), tree_map
, (Widget
*) tree
);
1014 buttonbar_set_label (b
, 6, Q_("ButtonBar|RenMov"), tree_map
, (Widget
*) tree
);
1016 /* FIXME: mkdir is currently defunct */
1017 buttonbar_set_label (b
, 7, Q_("ButtonBar|Mkdir"), tree_map
, (Widget
*) tree
);
1019 buttonbar_clear_label (b
, 7, (Widget
*) tree
);
1021 buttonbar_set_label (b
, 8, Q_("ButtonBar|Rmdir"), tree_map
, (Widget
*) tree
);
1022 buttonbar_redraw (b
);
1024 /* FIXME: Should find a better way of only displaying the
1025 currently selected item */
1029 /* FIXME: Should find a better way of changing the color of the
1032 case WIDGET_UNFOCUS
:
1038 return tree_key (tree
, parm
);
1040 case WIDGET_COMMAND
:
1041 /* command from buttonbar */
1042 return tree_execute_cmd (tree
, parm
);
1044 case WIDGET_DESTROY
:
1045 tree_destroy (tree
);
1049 return default_proc (msg
, parm
);
1054 tree_new (int is_panel
, int y
, int x
, int lines
, int cols
)
1056 WTree
*tree
= g_new (WTree
, 1);
1058 init_widget (&tree
->widget
, y
, x
, lines
, cols
,
1059 tree_callback
, event_callback
);
1060 tree
->is_panel
= is_panel
;
1061 tree
->selected_ptr
= 0;
1063 tree
->store
= tree_store_get ();
1064 tree_store_add_entry_remove_hook (remove_callback
, tree
);
1065 tree
->tree_shown
= 0;
1066 tree
->search_buffer
[0] = 0;
1067 tree
->topdiff
= tree
->widget
.lines
/ 2;
1068 tree
->searching
= 0;
1071 /* We do not want to keep the cursor */
1072 widget_want_cursor (tree
->widget
, 0);
1078 tree_chdir (WTree
*tree
, const char *dir
)
1080 tree_entry
*current
;
1082 current
= tree_store_whereis (dir
);
1084 if (current
!= NULL
) {
1085 tree
->selected_ptr
= current
;
1086 tree_check_focus (tree
);
1090 /* Return name of the currently selected entry */
1092 tree_selected_name (const WTree
*tree
)
1094 return tree
->selected_ptr
->name
;
1098 sync_tree (const char *path
)
1100 tree_chdir (the_tree
, path
);
1104 find_tree (struct Dlg_head
*h
)
1106 return (WTree
*) find_widget_type (h
, tree_callback
);