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_new (tree_entry
*, tree_lines
);
240 for (i
= 0; i
< tree_lines
; i
++)
241 tree
->tree_shown
[i
] = NULL
;
242 if (tree
->store
->tree_first
)
243 topsublevel
= tree
->store
->tree_first
->sublevel
;
246 if (!tree
->selected_ptr
){
247 tree
->selected_ptr
= tree
->store
->tree_first
;
250 current
= tree
->selected_ptr
;
252 /* Calculate the directory which is to be shown on the topmost line */
253 if (!tree_navigation_flag
)
254 current
= back_ptr (current
, &tree
->topdiff
);
257 while (current
->prev
&& i
< tree
->topdiff
){
258 current
= current
->prev
;
259 if (current
->sublevel
< tree
->selected_ptr
->sublevel
){
260 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
261 strlen (current
->name
)) == 0)
263 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
264 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
265 if (strncmp (current
->name
, tree
->selected_ptr
->name
, j
) == 0)
267 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+ 1
268 && strlen (tree
->selected_ptr
->name
) > 1){
269 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
270 strlen (tree
->selected_ptr
->name
)) == 0)
277 /* Loop for every line */
278 for (i
= 0; i
< tree_lines
; i
++){
279 /* Move to the beginning of the line */
280 tty_draw_hline (tree
->widget
.y
+ y
+ i
, tree
->widget
.x
+ x
, ' ', tree_cols
);
285 tree
->tree_shown
[i
] = current
;
286 if (current
->sublevel
== topsublevel
){
288 /* Top level directory */
289 if (tree
->active
&& current
== tree
->selected_ptr
) {
290 if (!tty_use_colors () && !tree
->is_panel
)
291 tty_setcolor (MARKED_COLOR
);
293 tty_setcolor (SELECTED_COLOR
);
297 tty_print_string (str_fit_to_term (current
->name
, tree_cols
- 6, J_LEFT_FIT
));
299 /* Sub level directory */
301 tty_set_alt_charset (TRUE
);
302 /* Output branch parts */
303 for (j
= 0; j
< current
->sublevel
- topsublevel
- 1; j
++){
304 if (tree_cols
- 8 - 3 * j
< 9)
306 tty_print_char (' ');
307 if (current
->submask
& (1 << (j
+ topsublevel
+ 1)))
308 tty_print_char (ACS_VLINE
);
310 tty_print_char (' ');
311 tty_print_char (' ');
313 tty_print_char (' '); j
++;
314 if (!current
->next
|| !(current
->next
->submask
& (1 << current
->sublevel
)))
315 tty_print_char (ACS_LLCORNER
);
317 tty_print_char (ACS_LTEE
);
318 tty_print_char (ACS_HLINE
);
319 tty_set_alt_charset (FALSE
);
321 if (tree
->active
&& current
== tree
->selected_ptr
) {
322 /* Selected directory -> change color */
323 if (!tty_use_colors () && !tree
->is_panel
)
324 tty_setcolor (MARKED_COLOR
);
326 tty_setcolor (SELECTED_COLOR
);
330 tty_print_char (' ');
331 tty_print_string (str_fit_to_term (current
->subname
,
332 tree_cols
- 2 - 4 - 3 * j
, J_LEFT_FIT
));
334 tty_print_char (' ');
336 /* Return to normal color */
337 tty_setcolor (TREE_NORMALC (h
));
339 /* Calculate the next value for current */
340 current
= current
->next
;
341 if (tree_navigation_flag
){
343 if (current
->sublevel
< tree
->selected_ptr
->sublevel
){
344 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
345 strlen (current
->name
)) == 0)
347 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
348 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
349 if (strncmp (current
->name
,tree
->selected_ptr
->name
,j
)== 0)
351 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+1
352 && strlen (tree
->selected_ptr
->name
) > 1){
353 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
354 strlen (tree
->selected_ptr
->name
)) == 0)
357 current
= current
->next
;
361 tree_show_mini_info (tree
, tree_lines
, tree_cols
);
365 tree_check_focus (WTree
*tree
)
367 if (tree
->topdiff
< 3)
369 else if (tree
->topdiff
>= tlines (tree
) - 3)
370 tree
->topdiff
= tlines (tree
) - 3 - 1;
374 tree_move_backward (WTree
*tree
, int i
)
376 if (!tree_navigation_flag
)
377 tree
->selected_ptr
= back_ptr (tree
->selected_ptr
, &i
);
382 current
= tree
->selected_ptr
;
383 while (j
< i
&& current
->prev
384 && current
->prev
->sublevel
>= tree
->selected_ptr
->sublevel
){
385 current
= current
->prev
;
386 if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
387 tree
->selected_ptr
= current
;
395 tree_check_focus (tree
);
399 tree_move_forward (WTree
*tree
, int i
)
401 if (!tree_navigation_flag
)
402 tree
->selected_ptr
= forw_ptr (tree
->selected_ptr
, &i
);
407 current
= tree
->selected_ptr
;
408 while (j
< i
&& current
->next
409 && current
->next
->sublevel
>= tree
->selected_ptr
->sublevel
){
410 current
= current
->next
;
411 if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
412 tree
->selected_ptr
= current
;
420 tree_check_focus (tree
);
424 tree_move_to_child (WTree
*tree
)
428 /* Do we have a starting point? */
429 if (!tree
->selected_ptr
)
431 /* Take the next entry */
432 current
= tree
->selected_ptr
->next
;
433 /* Is it the child of the selected entry */
434 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
){
435 /* Yes -> select this entry */
436 tree
->selected_ptr
= current
;
438 tree_check_focus (tree
);
440 /* No -> rescan and try again */
442 current
= tree
->selected_ptr
->next
;
443 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
){
444 tree
->selected_ptr
= current
;
446 tree_check_focus (tree
);
452 tree_move_to_parent (WTree
*tree
)
457 if (!tree
->selected_ptr
)
460 old
= tree
->selected_ptr
;
461 current
= tree
->selected_ptr
->prev
;
462 while (current
&& current
->sublevel
>= tree
->selected_ptr
->sublevel
){
463 current
= current
->prev
;
467 current
= tree
->store
->tree_first
;
468 tree
->selected_ptr
= current
;
469 tree_check_focus (tree
);
470 return tree
->selected_ptr
!= old
;
474 tree_move_to_top (WTree
*tree
)
476 tree
->selected_ptr
= tree
->store
->tree_first
;
481 tree_move_to_bottom (WTree
*tree
)
483 tree
->selected_ptr
= tree
->store
->tree_last
;
484 tree
->topdiff
= tlines (tree
) - 3 - 1;
487 /* Handle mouse click */
489 tree_event (WTree
*tree
, int y
)
491 if (tree
->tree_shown
[y
]){
492 tree
->selected_ptr
= tree
->tree_shown
[y
];
499 tree_chdir_sel (WTree
*tree
)
506 if (do_cd (tree
->selected_ptr
->name
, cd_exact
))
507 select_item (current_panel
);
509 message (D_ERROR
, MSG_ERROR
, _(" Cannot chdir to \"%s\" \n %s "),
510 tree
->selected_ptr
->name
, unix_error_string (errno
));
517 maybe_chdir (WTree
*tree
)
519 if (xtree_mode
&& tree
->is_panel
&& is_idle ())
520 tree_chdir_sel (tree
);
525 event_callback (Gpm_Event
*event
, void *data
)
529 /* rest of the upper frame, the menu is invisible - call menu */
530 if (tree
->is_panel
&& (event
->type
& GPM_DOWN
)
531 && event
->y
== 1 && !menubar_visible
) {
532 event
->x
+= tree
->widget
.x
;
533 return the_menubar
->widget
.mouse (event
, the_menubar
);
536 if (!(event
->type
& GPM_UP
))
548 tree_move_backward (tree
, tlines (tree
) - 1);
550 } else if (event
->y
>= tlines (tree
)){
551 tree_move_forward (tree
, tlines (tree
) - 1);
554 tree_event (tree
, event
->y
);
555 if ((event
->type
& (GPM_UP
|GPM_DOUBLE
)) == (GPM_UP
|GPM_DOUBLE
)){
556 tree_chdir_sel (tree
);
562 /* Search tree for text */
564 search_tree (WTree
*tree
, char *text
)
572 current
= tree
->selected_ptr
;
574 while (!wrapped
|| current
!= tree
->selected_ptr
){
575 if (strncmp (current
->subname
, text
, len
) == 0){
576 tree
->selected_ptr
= current
;
580 current
= current
->next
;
582 current
= tree
->store
->tree_first
;
587 tree_check_focus (tree
);
592 tree_do_search (WTree
*tree
, int key
)
596 l
= strlen (tree
->search_buffer
);
597 if ((l
!= 0) && (key
== KEY_BACKSPACE
))
598 tree
->search_buffer
[--l
] = '\0';
599 else if (key
&& l
< sizeof (tree
->search_buffer
)){
600 tree
->search_buffer
[l
] = key
;
601 tree
->search_buffer
[++l
] = '\0';
604 if (!search_tree (tree
, tree
->search_buffer
))
605 tree
->search_buffer
[--l
] = 0;
612 tree_rescan (void *data
)
614 char old_dir
[MC_MAXPATHLEN
];
617 if (!tree
->selected_ptr
|| !mc_get_current_wd (old_dir
, MC_MAXPATHLEN
) ||
618 mc_chdir (tree
->selected_ptr
->name
))
621 tree_store_rescan (tree
->selected_ptr
->name
);
626 tree_forget (void *data
)
629 if (tree
->selected_ptr
)
630 tree_remove_entry (tree
, tree
->selected_ptr
->name
);
634 tree_copy (WTree
*tree
, const char *default_dest
)
636 char msg
[BUF_MEDIUM
];
642 if (tree
->selected_ptr
== NULL
)
645 g_snprintf (msg
, sizeof (msg
), _("Copy \"%s\" directory to:"),
646 str_trunc (tree
->selected_ptr
->name
, 50));
647 dest
= input_expand_dialog (Q_("DialogTitle|Copy"), msg
, MC_HISTORY_FM_TREE_COPY
, default_dest
);
649 if (dest
!= NULL
&& *dest
!= '\0') {
650 ctx
= file_op_context_new (OP_COPY
);
651 file_op_context_create_ui (ctx
, FALSE
);
652 copy_dir_dir (ctx
, tree
->selected_ptr
->name
, dest
, 1, 0, 0, 0, &count
, &bytes
);
653 file_op_context_destroy (ctx
);
660 tree_move (WTree
*tree
, const char *default_dest
)
662 char msg
[BUF_MEDIUM
];
669 if (tree
->selected_ptr
== NULL
)
672 g_snprintf (msg
, sizeof (msg
), _("Move \"%s\" directory to:"),
673 str_trunc (tree
->selected_ptr
->name
, 50));
674 dest
= input_expand_dialog (Q_("DialogTitle|Move"), msg
, MC_HISTORY_FM_TREE_MOVE
, default_dest
);
676 if (dest
== NULL
|| *dest
== '\0') {
681 if (stat (dest
, &buf
)){
682 message (D_ERROR
, MSG_ERROR
, _(" Cannot stat the destination \n %s "),
683 unix_error_string (errno
));
688 if (!S_ISDIR (buf
.st_mode
)){
689 file_error (_(" Destination \"%s\" must be a directory \n %s "),
695 ctx
= file_op_context_new (OP_MOVE
);
696 file_op_context_create_ui (ctx
, FALSE
);
697 move_dir_dir (ctx
, tree
->selected_ptr
->name
, dest
, &count
, &bytes
);
698 file_op_context_destroy (ctx
);
705 tree_mkdir (WTree
*tree
)
707 char old_dir
[MC_MAXPATHLEN
];
709 if (!tree
->selected_ptr
)
711 if (!mc_get_current_wd (old_dir
, MC_MAXPATHLEN
))
713 if (chdir (tree
->selected_ptr
->name
))
724 tree_rmdir (void *data
)
731 if (!tree
->selected_ptr
)
734 if (confirm_delete
) {
739 g_strdup_printf (_(" Delete %s? "),
740 tree
->selected_ptr
->name
);
742 query_dialog (Q_("DialogTitle|Delete"), buf
, D_ERROR
, 2, _("&Yes"), _("&No"));
748 ctx
= file_op_context_new (OP_DELETE
);
749 file_op_context_create_ui (ctx
, FALSE
);
750 if (erase_dir (ctx
, tree
->selected_ptr
->name
, &count
, &bytes
) == FILE_CONT
)
752 file_op_context_destroy (ctx
);
756 tree_move_up (WTree
*tree
)
758 tree_move_backward (tree
, 1);
764 tree_move_down (WTree
*tree
)
766 tree_move_forward (tree
, 1);
772 tree_move_home (WTree
*tree
)
774 tree_move_to_top (tree
);
780 tree_move_end (WTree
*tree
)
782 tree_move_to_bottom (tree
);
788 tree_move_pgup (WTree
*tree
)
790 tree_move_backward (tree
, tlines (tree
) - 1);
796 tree_move_pgdn (WTree
*tree
)
798 tree_move_forward (tree
, tlines (tree
) - 1);
804 tree_move_left (WTree
*tree
)
808 if (tree_navigation_flag
) {
809 v
= tree_move_to_parent (tree
);
818 tree_move_right (WTree
*tree
)
822 if (tree_navigation_flag
) {
823 tree_move_to_child (tree
);
833 tree_start_search (WTree
*tree
)
837 if (tree
->searching
) {
838 if (tree
->selected_ptr
== tree
->store
->tree_last
)
839 tree_move_to_top (tree
);
841 /* set navigation mode temporarily to 'Static' because in
842 * dynamic navigation mode tree_move_forward will not move
843 * to a lower sublevel if necessary (sequent searches must
844 * start with the directory followed the last found directory)
846 i
= tree_navigation_flag
;
847 tree_navigation_flag
= 0;
848 tree_move_forward (tree
, 1);
849 tree_navigation_flag
= i
;
851 tree_do_search (tree
, 0);
854 tree
->search_buffer
[0] = 0;
859 tree_toggle_navig (WTree
*tree
)
861 tree_navigation_flag
= !tree_navigation_flag
;
862 buttonbar_set_label (find_buttonbar (tree
->widget
.parent
), 4,
863 tree_navigation_flag
? Q_("ButtonBar|Static")
864 : Q_("ButtonBar|Dynamc"),
865 tree_map
, (Widget
*) tree
);
869 tree_execute_cmd (WTree
*tree
, unsigned long command
)
871 cb_ret_t res
= MSG_HANDLED
;
873 if (command
!= CK_TreeStartSearch
)
878 interactive_display (NULL
, "[Directory Tree]");
883 case CK_TreeToggleNav
:
884 tree_toggle_navig (tree
);
887 tree_copy (tree
, "");
890 tree_move (tree
, "");
895 case CK_TreeMoveDown
:
896 tree_move_down (tree
);
898 case CK_TreeMoveHome
:
899 tree_move_home (tree
);
902 tree_move_end (tree
);
904 case CK_TreeMovePgUp
:
905 tree_move_pgup (tree
);
907 case CK_TreeMovePgDn
:
908 tree_move_pgdn (tree
);
911 tree_chdir_sel (tree
);
916 case CK_TreeStartSearch
:
917 tree_start_search (tree
);
923 res
= MSG_NOT_HANDLED
;
932 tree_key (WTree
*tree
, int key
)
936 for (i
= 0; tree_map
[i
].key
!= 0; i
++)
937 if (key
== tree_map
[i
].key
)
938 switch (tree_map
[i
].command
) {
939 case CK_TreeMoveLeft
:
940 return tree_move_left (tree
) ? MSG_HANDLED
: MSG_NOT_HANDLED
;
941 case CK_TreeMoveRight
:
942 return tree_move_right (tree
) ? MSG_HANDLED
: MSG_NOT_HANDLED
;
944 tree_execute_cmd (tree
, tree_map
[i
].command
);
948 if (is_abort_char (key
)) {
949 if (tree
->is_panel
) {
952 return MSG_HANDLED
; /* eat abort char */
954 /* modal tree dialog: let upper layer see the
955 abort character and close the dialog */
956 return MSG_NOT_HANDLED
;
959 /* Do not eat characters not meant for the tree below ' ' (e.g. C-l). */
960 if ((key
>= ' ' && key
<= 255) || key
== KEY_BACKSPACE
) {
961 if (tree
->searching
){
962 tree_do_search (tree
, key
);
967 if (!command_prompt
) {
968 tree_start_search (tree
);
969 tree_do_search (tree
, key
);
972 return tree
->is_panel
? MSG_HANDLED
: MSG_NOT_HANDLED
;
975 return MSG_NOT_HANDLED
;
979 tree_frame (Dlg_head
*h
, WTree
*tree
)
981 tty_setcolor (NORMAL_COLOR
);
982 widget_erase ((Widget
*) tree
);
983 if (tree
->is_panel
) {
984 draw_box (h
, tree
->widget
.y
, tree
->widget
.x
, tree
->widget
.lines
,
988 tty_draw_hline (tree
->widget
.y
+ tlines (tree
) + 1,
990 ACS_HLINE
, tree
->widget
.cols
- 2);
995 tree_callback (Widget
*w
, widget_msg_t msg
, int parm
)
997 WTree
*tree
= (WTree
*) w
;
998 Dlg_head
*h
= tree
->widget
.parent
;
999 WButtonBar
*b
= find_buttonbar (h
);
1003 tree_frame (h
, tree
);
1009 buttonbar_set_label (b
, 1, Q_("ButtonBar|Help"), tree_map
, (Widget
*) tree
);
1010 buttonbar_set_label (b
, 2, Q_("ButtonBar|Rescan"), tree_map
, (Widget
*) tree
);
1011 buttonbar_set_label (b
, 3, Q_("ButtonBar|Forget"), tree_map
, (Widget
*) tree
);
1012 buttonbar_set_label (b
, 4, tree_navigation_flag
? Q_("ButtonBar|Static")
1013 : Q_("ButtonBar|Dynamc"),
1014 tree_map
, (Widget
*) tree
);
1015 buttonbar_set_label (b
, 5, Q_("ButtonBar|Copy"), tree_map
, (Widget
*) tree
);
1016 buttonbar_set_label (b
, 6, Q_("ButtonBar|RenMov"), tree_map
, (Widget
*) tree
);
1018 /* FIXME: mkdir is currently defunct */
1019 buttonbar_set_label (b
, 7, Q_("ButtonBar|Mkdir"), tree_map
, (Widget
*) tree
);
1021 buttonbar_clear_label (b
, 7, (Widget
*) tree
);
1023 buttonbar_set_label (b
, 8, Q_("ButtonBar|Rmdir"), tree_map
, (Widget
*) tree
);
1024 buttonbar_redraw (b
);
1026 /* FIXME: Should find a better way of only displaying the
1027 currently selected item */
1031 /* FIXME: Should find a better way of changing the color of the
1034 case WIDGET_UNFOCUS
:
1040 return tree_key (tree
, parm
);
1042 case WIDGET_COMMAND
:
1043 /* command from buttonbar */
1044 return tree_execute_cmd (tree
, parm
);
1046 case WIDGET_DESTROY
:
1047 tree_destroy (tree
);
1051 return default_proc (msg
, parm
);
1056 tree_new (int is_panel
, int y
, int x
, int lines
, int cols
)
1058 WTree
*tree
= g_new (WTree
, 1);
1060 init_widget (&tree
->widget
, y
, x
, lines
, cols
,
1061 tree_callback
, event_callback
);
1062 tree
->is_panel
= is_panel
;
1063 tree
->selected_ptr
= 0;
1065 tree
->store
= tree_store_get ();
1066 tree_store_add_entry_remove_hook (remove_callback
, tree
);
1067 tree
->tree_shown
= 0;
1068 tree
->search_buffer
[0] = 0;
1069 tree
->topdiff
= tree
->widget
.lines
/ 2;
1070 tree
->searching
= 0;
1073 /* We do not want to keep the cursor */
1074 widget_want_cursor (tree
->widget
, 0);
1080 tree_chdir (WTree
*tree
, const char *dir
)
1082 tree_entry
*current
;
1084 current
= tree_store_whereis (dir
);
1086 if (current
!= NULL
) {
1087 tree
->selected_ptr
= current
;
1088 tree_check_focus (tree
);
1092 /* Return name of the currently selected entry */
1094 tree_selected_name (const WTree
*tree
)
1096 return tree
->selected_ptr
->name
;
1100 sync_tree (const char *path
)
1102 tree_chdir (the_tree
, path
);
1106 find_tree (struct Dlg_head
*h
)
1108 return (WTree
*) find_widget_type (h
, tree_callback
);