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.
39 #include "wtools.h" /* message() */
46 #include "file.h" /* For copy_dir_dir(), move_dir_dir(), erase_dir() */
48 #include "key.h" /* For mi_getch() */
50 #include "treestore.h"
54 #define tlines(t) (t->is_panel ? t->widget.lines-2 - (show_mini_info ? 2 : 0) : t->widget.lines)
56 extern int command_prompt
;
58 /* Use the color of the parent widget for the unselected entries */
59 #define TREE_NORMALC(h) (DLG_NORMALC (h))
61 /* Specifies the display mode: 1d or 2d */
62 static int tree_navigation_flag
;
66 struct TreeStore
*store
;
67 tree_entry
*selected_ptr
; /* The selected directory */
68 char search_buffer
[256]; /* Current search string */
69 tree_entry
**tree_shown
; /* Entries currently on screen */
70 int is_panel
; /* panel or plain widget flag */
71 int active
; /* if it's currently selected */
72 int searching
; /* Are we on searching mode? */
73 int topdiff
; /* The difference between the topmost
74 shown and the selected */
78 static void save_tree (WTree
*tree
);
79 static void tree_rescan_cmd (WTree
*);
81 static tree_entry
*back_ptr (tree_entry
*ptr
, int *count
)
85 while (ptr
&& ptr
->prev
&& i
< *count
){
93 static tree_entry
*forw_ptr (tree_entry
*ptr
, int *count
)
97 while (ptr
&& ptr
->next
&& i
< *count
){
106 remove_callback (tree_entry
*entry
, void *data
)
110 if (tree
->selected_ptr
== entry
){
111 if (tree
->selected_ptr
->next
)
112 tree
->selected_ptr
= tree
->selected_ptr
->next
;
114 tree
->selected_ptr
= tree
->selected_ptr
->prev
;
118 static void tree_remove_entry (WTree
*tree
, char *name
)
121 tree_store_remove_entry (name
);
124 static void tree_destroy (WTree
*tree
)
126 tree_store_remove_entry_remove_hook (remove_callback
);
129 g_free (tree
->tree_shown
);
130 tree
->tree_shown
= 0;
131 tree
->selected_ptr
= NULL
;
134 /* Loads the .mc.tree file */
135 static void load_tree (WTree
*tree
)
139 tree
->selected_ptr
= tree
->store
->tree_first
;
140 tree_chdir (tree
, home_dir
);
143 /* Save the .mc.tree file */
144 static void save_tree (WTree
*tree
)
149 error
= tree_store_save ();
152 fprintf (stderr
, _("Cannot open the %s file for writing:\n%s\n"), MC_TREE
,
153 unix_error_string (error
));
157 static void tree_show_mini_info (WTree
*tree
, int tree_lines
, int tree_cols
)
159 Dlg_head
*h
= tree
->widget
.parent
;
170 widget_move (&tree
->widget
, line
, 1);
171 hline (' ', tree_cols
);
172 widget_move (&tree
->widget
, line
, 1);
174 if (tree
->searching
){
175 /* Show search string */
176 attrset (TREE_NORMALC (h
));
177 attrset (DLG_FOCUSC (h
));
180 addstr ((char *) name_trunc (tree
->search_buffer
, tree_cols
-2));
182 attrset (DLG_FOCUSC (h
));
184 /* Show full name of selected directory */
185 addstr ((char *) name_trunc (tree
->selected_ptr
->name
, tree_cols
));
189 static void show_tree (WTree
*tree
)
191 Dlg_head
*h
= tree
->widget
.parent
;
193 int i
, j
, topsublevel
;
195 int tree_lines
, tree_cols
;
199 tree_lines
= tlines (tree
);
200 tree_cols
= tree
->widget
.cols
;
202 attrset (TREE_NORMALC (h
));
203 widget_move ((Widget
*)tree
, y
, x
);
209 g_free (tree
->tree_shown
);
210 tree
->tree_shown
= g_new (tree_entry
*, tree_lines
);
212 for (i
= 0; i
< tree_lines
; i
++)
213 tree
->tree_shown
[i
] = NULL
;
214 if (tree
->store
->tree_first
)
215 topsublevel
= tree
->store
->tree_first
->sublevel
;
218 if (!tree
->selected_ptr
){
219 tree
->selected_ptr
= tree
->store
->tree_first
;
222 current
= tree
->selected_ptr
;
224 /* Calculate the directory which is to be shown on the topmost line */
225 if (tree_navigation_flag
){
227 while (current
->prev
&& i
< tree
->topdiff
){
228 current
= current
->prev
;
229 if (current
->sublevel
< tree
->selected_ptr
->sublevel
){
230 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
231 strlen (current
->name
)) == 0)
233 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
234 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
235 if (strncmp (current
->name
, tree
->selected_ptr
->name
, j
) == 0)
237 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+ 1
238 && strlen (tree
->selected_ptr
->name
) > 1){
239 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
240 strlen (tree
->selected_ptr
->name
)) == 0)
246 current
= back_ptr (current
, &tree
->topdiff
);
248 /* Loop for every line */
249 for (i
= 0; i
< tree_lines
; i
++){
250 /* Move to the beginning of the line */
251 widget_move (&tree
->widget
, y
+i
, x
);
253 hline (' ', tree_cols
);
254 widget_move (&tree
->widget
, y
+i
, x
);
259 tree
->tree_shown
[i
] = current
;
260 if (current
->sublevel
== topsublevel
){
262 /* Top level directory */
263 if (tree
->active
&& current
== tree
->selected_ptr
) {
264 if (!use_colors
&& !tree
->is_panel
)
265 attrset (MARKED_COLOR
);
267 attrset (SELECTED_COLOR
);
271 addstr ((char *) name_trunc (current
->name
, tree_cols
- 6));
273 /* Sub level directory */
276 /* Output branch parts */
277 for (j
= 0; j
< current
->sublevel
- topsublevel
- 1; j
++){
278 if (tree_cols
- 8 - 3 * j
< 9)
281 if (current
->submask
& (1 << (j
+ topsublevel
+ 1)))
288 if (!current
->next
|| !(current
->next
->submask
& (1 << current
->sublevel
)))
289 addch (ACS_LLCORNER
);
295 if (tree
->active
&& current
== tree
->selected_ptr
) {
296 /* Selected directory -> change color */
297 if (!use_colors
&& !tree
->is_panel
)
298 attrset (MARKED_COLOR
);
300 attrset (SELECTED_COLOR
);
305 addstr ((char *) name_trunc (current
->subname
,
306 tree_cols
- 2 - 4 - 3 * j
));
310 /* Return to normal color */
311 attrset (TREE_NORMALC (h
));
313 /* Calculate the next value for current */
314 current
= current
->next
;
315 if (tree_navigation_flag
){
317 if (current
->sublevel
< tree
->selected_ptr
->sublevel
){
318 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
319 strlen (current
->name
)) == 0)
321 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
322 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
323 if (strncmp (current
->name
,tree
->selected_ptr
->name
,j
)== 0)
325 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+1
326 && strlen (tree
->selected_ptr
->name
) > 1){
327 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
328 strlen (tree
->selected_ptr
->name
)) == 0)
331 current
= current
->next
;
335 tree_show_mini_info (tree
, tree_lines
, tree_cols
);
338 static void check_focus (WTree
*tree
)
340 if (tree
->topdiff
< 3)
342 else if (tree
->topdiff
>= tlines (tree
) - 3)
343 tree
->topdiff
= tlines (tree
) - 3 - 1;
346 static void tree_move_backward (WTree
*tree
, int i
)
351 if (tree_navigation_flag
){
352 current
= tree
->selected_ptr
;
353 while (j
< i
&& current
->prev
354 && current
->prev
->sublevel
>= tree
->selected_ptr
->sublevel
){
355 current
= current
->prev
;
356 if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
357 tree
->selected_ptr
= current
;
363 tree
->selected_ptr
= back_ptr (tree
->selected_ptr
, &i
);
368 static void tree_move_forward (WTree
*tree
, int i
)
373 if (tree_navigation_flag
){
374 current
= tree
->selected_ptr
;
375 while (j
< i
&& current
->next
376 && current
->next
->sublevel
>= tree
->selected_ptr
->sublevel
){
377 current
= current
->next
;
378 if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
379 tree
->selected_ptr
= current
;
385 tree
->selected_ptr
= forw_ptr (tree
->selected_ptr
, &i
);
390 static void tree_move_to_child (WTree
*tree
)
394 /* Do we have a starting point? */
395 if (!tree
->selected_ptr
)
397 /* Take the next entry */
398 current
= tree
->selected_ptr
->next
;
399 /* Is it the child of the selected entry */
400 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
){
401 /* Yes -> select this entry */
402 tree
->selected_ptr
= current
;
406 /* No -> rescan and try again */
407 tree_rescan_cmd (tree
);
408 current
= tree
->selected_ptr
->next
;
409 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
){
410 tree
->selected_ptr
= current
;
417 static int tree_move_to_parent (WTree
*tree
)
422 if (!tree
->selected_ptr
)
424 old
= tree
->selected_ptr
;
425 current
= tree
->selected_ptr
->prev
;
426 while (current
&& current
->sublevel
>= tree
->selected_ptr
->sublevel
){
427 current
= current
->prev
;
431 current
= tree
->store
->tree_first
;
432 tree
->selected_ptr
= current
;
434 return tree
->selected_ptr
!= old
;
437 static void tree_move_to_top (WTree
*tree
)
439 tree
->selected_ptr
= tree
->store
->tree_first
;
443 static void tree_move_to_bottom (WTree
*tree
)
445 tree
->selected_ptr
= tree
->store
->tree_last
;
446 tree
->topdiff
= tlines (tree
) - 3 - 1;
449 void tree_chdir (WTree
*tree
, const char *dir
)
453 current
= tree_store_whereis (dir
);
455 tree
->selected_ptr
= current
;
461 sync_tree (const char *path
)
463 tree_chdir (the_tree
, path
);
466 /* Handle mouse click */
468 tree_event (WTree
*tree
, int y
)
470 if (tree
->tree_shown
[y
]){
471 tree
->selected_ptr
= tree
->tree_shown
[y
];
477 static void chdir_sel (WTree
*tree
);
479 static void maybe_chdir (WTree
*tree
)
481 if (!(xtree_mode
&& tree
->is_panel
))
489 event_callback (Gpm_Event
*event
, void *data
)
493 if (!(event
->type
& GPM_UP
))
505 tree_move_backward (tree
, tlines (tree
) - 1);
508 else if (event
->y
>= tlines (tree
)){
509 tree_move_forward (tree
, tlines (tree
) - 1);
512 tree_event (tree
, event
->y
);
513 if ((event
->type
& (GPM_UP
|GPM_DOUBLE
)) == (GPM_UP
|GPM_DOUBLE
)){
520 /* Search tree for text */
521 static int search_tree (WTree
*tree
, char *text
)
529 current
= tree
->selected_ptr
;
531 while (!wrapped
|| current
!= tree
->selected_ptr
){
532 if (strncmp (current
->subname
, text
, len
) == 0){
533 tree
->selected_ptr
= current
;
537 current
= current
->next
;
539 current
= tree
->store
->tree_first
;
548 static void tree_do_search (WTree
*tree
, int key
)
552 l
= strlen (tree
->search_buffer
);
553 if (l
&& (key
== KEY_BACKSPACE
))
554 tree
->search_buffer
[--l
] = 0;
556 if (key
&& l
< sizeof (tree
->search_buffer
)){
557 tree
->search_buffer
[l
] = key
;
558 tree
->search_buffer
[l
+1] = 0;
563 if (!search_tree (tree
, tree
->search_buffer
))
564 tree
->search_buffer
[--l
] = 0;
571 tree_rescan_cmd (WTree
*tree
)
573 char old_dir
[MC_MAXPATHLEN
];
575 if (!tree
->selected_ptr
|| !mc_get_current_wd (old_dir
, MC_MAXPATHLEN
) ||
576 mc_chdir (tree
->selected_ptr
->name
))
579 tree_store_rescan (tree
->selected_ptr
->name
);
584 tree_forget_cmd (void *data
)
587 if (tree
->selected_ptr
)
588 tree_remove_entry (tree
, tree
->selected_ptr
->name
);
591 static void tree_copy (WTree
*tree
, const char *default_dest
)
598 if (!tree
->selected_ptr
)
600 g_snprintf (cmd_buf
, sizeof(cmd_buf
), _("Copy \"%s\" directory to:"),
601 name_trunc (tree
->selected_ptr
->name
, 50));
602 dest
= input_expand_dialog (_(" Copy "), cmd_buf
, MC_HISTORY_FM_TREE_COPY
, default_dest
);
612 ctx
= file_op_context_new (OP_COPY
);
613 file_op_context_create_ui (ctx
, FALSE
);
614 copy_dir_dir (ctx
, tree
->selected_ptr
->name
, dest
, 1, 0, 0, 0, &count
, &bytes
);
615 file_op_context_destroy (ctx
);
623 interactive_display (NULL
, "[Directory Tree]");
627 tree_copy_cmd (void *data
)
630 tree_copy (tree
, "");
633 static void tree_move (WTree
*tree
, const char *default_dest
)
641 if (!tree
->selected_ptr
)
643 g_snprintf (cmd_buf
, sizeof (cmd_buf
), _("Move \"%s\" directory to:"),
644 name_trunc (tree
->selected_ptr
->name
, 50));
645 dest
= input_expand_dialog (_(" Move "), cmd_buf
, MC_HISTORY_FM_TREE_MOVE
, default_dest
);
652 if (stat (dest
, &buf
)){
653 message (D_ERROR
, MSG_ERROR
, _(" Cannot stat the destination \n %s "),
654 unix_error_string (errno
));
658 if (!S_ISDIR (buf
.st_mode
)){
659 file_error (_(" Destination \"%s\" must be a directory \n %s "),
665 ctx
= file_op_context_new (OP_MOVE
);
666 file_op_context_create_ui (ctx
, FALSE
);
667 move_dir_dir (ctx
, tree
->selected_ptr
->name
, dest
, &count
, &bytes
);
668 file_op_context_destroy (ctx
);
674 tree_move_cmd (void *data
)
677 tree_move (tree
, "");
682 tree_mkdir_cmd (WTree
*tree
)
684 char old_dir
[MC_MAXPATHLEN
];
686 if (!tree
->selected_ptr
)
688 if (!mc_get_current_wd (old_dir
, MC_MAXPATHLEN
))
690 if (chdir (tree
->selected_ptr
->name
))
695 tree_rescan_cmd (tree
);
701 tree_rmdir_cmd (WTree
*tree
)
707 if (!tree
->selected_ptr
)
710 if (confirm_delete
) {
715 g_strdup_printf (_(" Delete %s? "),
716 tree
->selected_ptr
->name
);
718 query_dialog (_(" Delete "), buf
, D_ERROR
, 2, _("&Yes"), _("&No"));
724 ctx
= file_op_context_new (OP_DELETE
);
725 file_op_context_create_ui (ctx
, FALSE
);
726 if (erase_dir (ctx
, tree
->selected_ptr
->name
, &count
, &bytes
) ==
728 tree_forget_cmd (tree
);
729 file_op_context_destroy (ctx
);
732 static void set_navig_label (WTree
*tree
);
735 tree_toggle_navig (void *data
)
738 /* FIXME: invalid use of boolean variable */
739 tree_navigation_flag
= 1 - tree_navigation_flag
;
740 set_navig_label (tree
);
744 set_navig_label (WTree
*tree
)
746 buttonbar_set_label_data (tree
->widget
.parent
, 4,
747 tree_navigation_flag
? _("Static") : _("Dynamc"),
748 tree_toggle_navig
, tree
);
752 move_down (WTree
*tree
)
754 tree_move_forward (tree
, 1);
760 move_up (WTree
*tree
)
762 tree_move_backward (tree
, 1);
768 move_home (WTree
*tree
)
770 tree_move_to_top (tree
);
776 move_end (WTree
*tree
)
778 tree_move_to_bottom (tree
);
784 move_left (WTree
*tree
)
788 if (tree_navigation_flag
){
789 v
= tree_move_to_parent (tree
);
798 move_right (WTree
*tree
)
800 if (tree_navigation_flag
){
801 tree_move_to_child (tree
);
810 move_prevp (WTree
*tree
)
812 tree_move_backward (tree
, tlines (tree
) - 1);
818 move_nextp (WTree
*tree
)
820 tree_move_forward (tree
, tlines (tree
) - 1);
826 chdir_sel (WTree
*tree
)
828 if (!tree
->is_panel
) {
832 if (do_cd (tree
->selected_ptr
->name
, cd_exact
)) {
833 select_item (current_panel
);
835 message (D_ERROR
, MSG_ERROR
, _(" Cannot chdir to \"%s\" \n %s "),
836 tree
->selected_ptr
->name
, unix_error_string (errno
));
844 tree_start_search (WTree
*tree
)
848 if (tree
->searching
){
850 if (tree
->selected_ptr
== tree
->store
->tree_last
)
851 tree_move_to_top(tree
);
853 /* set navigation mode temporarily to 'Static' because in
854 * dynamic navigation mode tree_move_forward will not move
855 * to a lower sublevel if necessary (sequent searches must
856 * start with the directory followed the last found directory)
858 i
= tree_navigation_flag
;
859 tree_navigation_flag
= 0;
860 tree_move_forward (tree
, 1);
861 tree_navigation_flag
= i
;
863 tree_do_search (tree
, 0);
867 tree
->search_buffer
[0] = 0;
871 typedef void (*tree_key_action
) (WTree
*);
877 static const tree_key_map tree_keymap
[] = {
878 { XCTRL('n'), move_down
},
879 { XCTRL('p'), move_up
},
880 { KEY_DOWN
, move_down
},
883 { KEY_ENTER
, chdir_sel
},
884 { KEY_HOME
, move_home
},
885 { KEY_A1
, move_home
},
886 { ALT ('<'), move_home
},
887 { KEY_END
, move_end
},
888 { KEY_C1
, move_end
},
889 { ALT ('>'), move_end
},
890 { KEY_NPAGE
, move_nextp
},
891 { KEY_PPAGE
, move_prevp
},
892 { XCTRL('v'), move_nextp
},
893 { ALT('v'), move_prevp
},
894 { XCTRL('p'), move_up
},
895 { XCTRL('p'), move_down
},
896 { XCTRL('s'), tree_start_search
},
897 { ALT('s'), tree_start_search
},
898 { XCTRL('r'), tree_rescan_cmd
},
899 { KEY_DC
, tree_rmdir_cmd
},
903 static inline cb_ret_t
904 tree_key (WTree
*tree
, int key
)
908 for (i
= 0; tree_keymap
[i
].key_code
; i
++){
909 if (key
== tree_keymap
[i
].key_code
){
910 if (tree_keymap
[i
].fn
!= tree_start_search
)
912 (*tree_keymap
[i
].fn
)(tree
);
918 /* We do not want to use them if we do not need to */
919 /* Input line may want to take the motion key event */
921 return move_left (tree
) ? MSG_HANDLED
: MSG_NOT_HANDLED
;
923 if (key
== KEY_RIGHT
)
924 return move_right (tree
) ? MSG_HANDLED
: MSG_NOT_HANDLED
;
926 if (is_abort_char (key
)) {
927 if (tree
->is_panel
) {
930 return MSG_HANDLED
; /* eat abort char */
932 /* modal tree dialog: let upper layer see the
933 abort character and close the dialog */
934 return MSG_NOT_HANDLED
;
937 /* Do not eat characters not meant for the tree below ' ' (e.g. C-l). */
938 if ((key
>= ' ' && key
<= 255) || key
== KEY_BACKSPACE
) {
939 if (tree
->searching
){
940 tree_do_search (tree
, key
);
945 if (!command_prompt
) {
946 tree_start_search (tree
);
947 tree_do_search (tree
, key
);
950 return tree
->is_panel
? MSG_HANDLED
: MSG_NOT_HANDLED
;
953 return MSG_NOT_HANDLED
;
957 tree_frame (Dlg_head
*h
, WTree
*tree
)
959 attrset (NORMAL_COLOR
);
960 widget_erase ((Widget
*) tree
);
962 draw_double_box (h
, tree
->widget
.y
, tree
->widget
.x
, tree
->widget
.lines
,
965 if (show_mini_info
&& tree
->is_panel
){
966 widget_move (tree
, tlines (tree
) + 1, 1);
967 hline (ACS_HLINE
, tree
->widget
.cols
- 2);
972 tree_rescan_command (void *data
)
975 tree_rescan_cmd (tree
);
979 tree_rmdir_command (void *data
)
982 tree_rmdir_cmd (tree
);
986 tree_callback (Widget
*w
, widget_msg_t msg
, int parm
)
988 WTree
*tree
= (WTree
*) w
;
989 Dlg_head
*h
= tree
->widget
.parent
;
993 tree_frame (h
, tree
);
998 return tree_key (tree
, parm
);
1002 buttonbar_set_label (h
, 1, _("Help"), tree_help_cmd
);
1003 buttonbar_set_label_data (h
, 2, _("Rescan"),
1004 tree_rescan_command
, tree
);
1005 buttonbar_set_label_data (h
, 3, _("Forget"), tree_forget_cmd
, tree
);
1006 buttonbar_set_label_data (h
, 5, _("Copy"), tree_copy_cmd
, tree
);
1007 buttonbar_set_label_data (h
, 6, _("RenMov"), tree_move_cmd
, tree
);
1009 /* FIXME: mkdir is currently defunct */
1010 buttonbar_set_label_data (h
, 7, _("Mkdir"), tree_mkdir_cmd
, tree
);
1012 buttonbar_clear_label (h
, 7);
1014 buttonbar_set_label_data (h
, 8, _("Rmdir"), tree_rmdir_command
, tree
);
1015 set_navig_label (tree
);
1016 buttonbar_redraw (h
);
1019 /* FIXME: Should find a better way of only displaying the
1020 currently selected item */
1024 /* FIXME: Should find a better way of changing the color of the
1027 case WIDGET_UNFOCUS
:
1032 case WIDGET_DESTROY
:
1033 tree_destroy (tree
);
1037 return default_proc (msg
, parm
);
1042 tree_new (int is_panel
, int y
, int x
, int lines
, int cols
)
1044 WTree
*tree
= g_new (WTree
, 1);
1046 init_widget (&tree
->widget
, y
, x
, lines
, cols
,
1047 tree_callback
, event_callback
);
1048 tree
->is_panel
= is_panel
;
1049 tree
->selected_ptr
= 0;
1051 tree
->store
= tree_store_get ();
1052 tree_store_add_entry_remove_hook (remove_callback
, tree
);
1053 tree
->tree_shown
= 0;
1054 tree
->search_buffer
[0] = 0;
1055 tree
->topdiff
= tree
->widget
.lines
/ 2;
1056 tree
->searching
= 0;
1059 /* We do not want to keep the cursor */
1060 widget_want_cursor (tree
->widget
, 0);
1065 /* Return name of the currently selected entry */
1067 tree_selected_name (WTree
*tree
)
1069 return tree
->selected_ptr
->name
;