1 /* Directory tree browser for the Midnight Commander
2 Copyright (C) 1994, 1995, 1996, 1997 The Free Software Foundation
4 Written: 1994, 1996 Janne Kukonlehto
6 1996, 1999 Miguel de Icaza
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 This module has been converted to be a widget.
24 The program load and saves the tree each time the tree widget is
25 created and destroyed. This is required for the future vfs layer,
26 it will be possible to have tree views over virtual file systems.
37 #include "wtools.h" /* message() */
44 #include "file.h" /* For copy_dir_dir(), move_dir_dir(), erase_dir() */
46 #include "key.h" /* For mi_getch() */
50 extern int command_prompt
;
52 /* Use the color of the parent widget for the unselected entries */
53 #define TREE_NORMALC NORMALC
55 /* Specifies the display mode: 1d or 2d */
56 static int tree_navigation_flag
;
61 tree_entry
*selected_ptr
; /* The selected directory */
62 char search_buffer
[256]; /* Current search string */
63 tree_entry
**tree_shown
; /* Entries currently on screen */
64 int is_panel
; /* panel or plain widget flag */
65 int active
; /* if it's currently selected */
66 int searching
; /* Are we on searching mode? */
67 int topdiff
; /* The difference between the topmost
68 shown and the selected */
72 static void save_tree (WTree
*tree
);
73 static void tree_rescan_cmd (WTree
*tree
);
74 static int tree_callback (WTree
*tree
, int msg
, int par
);
76 static tree_entry
*back_ptr (tree_entry
*ptr
, int *count
)
80 while (ptr
&& ptr
->prev
&& i
< *count
){
88 static tree_entry
*forw_ptr (tree_entry
*ptr
, int *count
)
92 while (ptr
&& ptr
->next
&& i
< *count
){
101 /* Add a directory to the list of directories */
102 static tree_entry
*tree_add_entry (WTree
*tree
, char *name
)
107 return tree_store_add_entry (name
);
110 /* Append a directory to the list of directories */
111 static tree_entry
*tree_append_entry (WTree
*tree
, char *name
)
113 tree_entry
*current
, *new;
117 /* We assume the directory is not yet in the list */
119 new = g_new (tree_entry
, 1);
120 if (!tree
->store
->tree_first
){
122 tree
->store
->tree_first
= new;
125 tree
->tree_last
->next
= new;
126 new->prev
= tree
->tree_last
;
129 tree
->store
->tree_last
= new;
131 /* Calculate attributes */
132 new->name
= g_strdup (name
);
133 len
= strlen (new->name
);
135 for (i
= 0; i
< len
; i
++)
136 if (new->name
[i
] == PATH_SEP
){
138 new->subname
= new->name
+ i
+ 1;
140 submask
= 1 << new->sublevel
;
141 submask
&= (2 << new->sublevel
) - 1;
142 new->submask
= submask
;
145 /* Correct the submasks of the previous entries */
147 while (current
&& current
->sublevel
> new->sublevel
){
148 current
->submask
|= 1 << new->sublevel
;
149 current
= current
->prev
;
152 /* The entry has now been appended */
158 remove_callback (tree_entry
*entry
, void *data
)
162 if (tree
->selected_ptr
== entry
){
163 if (tree
->selected_ptr
->next
)
164 tree
->selected_ptr
= tree
->selected_ptr
->next
;
166 tree
->selected_ptr
= tree
->selected_ptr
->prev
;
170 static void tree_remove_entry (WTree
*tree
, char *name
)
172 tree_store_remove_entry (name
);
175 static void tree_destroy (WTree
*tree
)
177 tree_store_remove_entry_remove_hook (remove_callback
);
180 if (tree
->tree_shown
){
181 g_free (tree
->tree_shown
);
182 tree
->tree_shown
= 0;
184 tree
->selected_ptr
= NULL
;
187 /* Loads the .mc.tree file */
188 static void load_tree (WTree
*tree
)
192 tree
->selected_ptr
= tree
->store
->tree_first
;
193 tree_chdir (tree
, home_dir
);
196 /* Save the .mc.tree file */
197 static void save_tree (WTree
*tree
)
201 error
= tree_store_save ();
204 fprintf (stderr
, _("Cannot open the %s file for writing:\n%s\n"), MC_TREE
,
205 unix_error_string (error
));
210 static void tree_show_mini_info (WTree
*tree
, int tree_lines
, int tree_cols
)
212 Dlg_head
*h
= tree
->widget
.parent
;
223 widget_move (&tree
->widget
, line
, 1);
224 hline (' ', tree_cols
);
225 widget_move (&tree
->widget
, line
, 1);
227 if (tree
->searching
){
228 /* Show search string */
229 attrset (TREE_NORMALC
);
233 addstr (name_trunc (tree
->search_buffer
, tree_cols
-2));
237 /* Show full name of selected directory */
238 addstr (name_trunc (tree
->selected_ptr
->name
, tree_cols
));
242 static void show_tree (WTree
*tree
)
244 Dlg_head
*h
= tree
->widget
.parent
;
246 int i
, j
, topsublevel
;
248 int tree_lines
, tree_cols
;
252 tree_lines
= tlines (tree
);
253 tree_cols
= tree
->widget
.cols
;
255 attrset (TREE_NORMALC
);
256 widget_move ((Widget
*)tree
, y
, x
);
262 if (tree
->tree_shown
)
263 g_free (tree
->tree_shown
);
264 tree
->tree_shown
= g_new (tree_entry
*, tree_lines
);
266 for (i
= 0; i
< tree_lines
; i
++)
267 tree
->tree_shown
[i
] = NULL
;
268 if (tree
->store
->tree_first
)
269 topsublevel
= tree
->store
->tree_first
->sublevel
;
272 if (!tree
->selected_ptr
){
273 tree
->selected_ptr
= tree
->store
->tree_first
;
276 current
= tree
->selected_ptr
;
278 /* Calculate the directory which is to be shown on the topmost line */
279 if (tree_navigation_flag
){
281 while (current
->prev
&& i
< tree
->topdiff
){
282 current
= current
->prev
;
283 if (current
->sublevel
< tree
->selected_ptr
->sublevel
){
284 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
285 strlen (current
->name
)) == 0)
287 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
288 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
289 if (strncmp (current
->name
, tree
->selected_ptr
->name
, j
) == 0)
291 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+ 1
292 && strlen (tree
->selected_ptr
->name
) > 1){
293 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
294 strlen (tree
->selected_ptr
->name
)) == 0)
300 current
= back_ptr (current
, &tree
->topdiff
);
302 /* Loop for every line */
303 for (i
= 0; i
< tree_lines
; i
++){
304 /* Move to the beginning of the line */
305 widget_move (&tree
->widget
, y
+i
, x
);
307 hline (' ', tree_cols
);
308 widget_move (&tree
->widget
, y
+i
, x
);
313 tree
->tree_shown
[i
] = current
;
314 if (current
->sublevel
== topsublevel
){
316 /* Top level directory */
317 if (tree
->active
&& current
== tree
->selected_ptr
) {
318 if (!use_colors
&& !tree
->is_panel
)
319 attrset (MARKED_COLOR
);
321 attrset (SELECTED_COLOR
);
325 addstr (name_trunc (current
->name
, tree_cols
- 6));
327 /* Sub level directory */
330 /* Output branch parts */
331 for (j
= 0; j
< current
->sublevel
- topsublevel
- 1; j
++){
332 if (tree_cols
- 8 - 3 * j
< 9)
335 if (current
->submask
& (1 << (j
+ topsublevel
+ 1)))
342 if (!current
->next
|| !(current
->next
->submask
& (1 << current
->sublevel
)))
343 addch (ACS_LLCORNER
);
349 if (tree
->active
&& current
== tree
->selected_ptr
) {
350 /* Selected directory -> change color */
351 if (!use_colors
&& !tree
->is_panel
)
352 attrset (MARKED_COLOR
);
354 attrset (SELECTED_COLOR
);
359 addstr (name_trunc (current
->subname
,
360 tree_cols
- 2 - 4 - 3 * j
));
364 /* Return to normal color */
365 attrset (TREE_NORMALC
);
367 /* Calculate the next value for current */
368 current
= current
->next
;
369 if (tree_navigation_flag
){
371 if (current
->sublevel
< tree
->selected_ptr
->sublevel
){
372 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
373 strlen (current
->name
)) == 0)
375 } 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)
379 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+1
380 && strlen (tree
->selected_ptr
->name
) > 1){
381 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
382 strlen (tree
->selected_ptr
->name
)) == 0)
385 current
= current
->next
;
389 tree_show_mini_info (tree
, tree_lines
, tree_cols
);
392 static void check_focus (WTree
*tree
)
394 if (tree
->topdiff
< 3)
396 else if (tree
->topdiff
>= tlines (tree
) - 3)
397 tree
->topdiff
= tlines (tree
) - 3 - 1;
400 static void tree_move_backward (WTree
*tree
, int i
)
405 if (tree_navigation_flag
){
406 current
= tree
->selected_ptr
;
407 while (j
< i
&& current
->prev
408 && current
->prev
->sublevel
>= tree
->selected_ptr
->sublevel
){
409 current
= current
->prev
;
410 if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
411 tree
->selected_ptr
= current
;
417 tree
->selected_ptr
= back_ptr (tree
->selected_ptr
, &i
);
422 static void tree_move_forward (WTree
*tree
, int i
)
427 if (tree_navigation_flag
){
428 current
= tree
->selected_ptr
;
429 while (j
< i
&& current
->next
430 && current
->next
->sublevel
>= tree
->selected_ptr
->sublevel
){
431 current
= current
->next
;
432 if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
433 tree
->selected_ptr
= current
;
439 tree
->selected_ptr
= forw_ptr (tree
->selected_ptr
, &i
);
444 static void tree_move_to_child (WTree
*tree
)
448 /* Do we have a starting point? */
449 if (!tree
->selected_ptr
)
451 /* Take the next entry */
452 current
= tree
->selected_ptr
->next
;
453 /* Is it the child of the selected entry */
454 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
){
455 /* Yes -> select this entry */
456 tree
->selected_ptr
= current
;
460 /* No -> rescan and try again */
461 tree_rescan_cmd (tree
);
462 current
= tree
->selected_ptr
->next
;
463 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
){
464 tree
->selected_ptr
= current
;
471 static int tree_move_to_parent (WTree
*tree
)
476 if (!tree
->selected_ptr
)
478 old
= tree
->selected_ptr
;
479 current
= tree
->selected_ptr
->prev
;
480 while (current
&& current
->sublevel
>= tree
->selected_ptr
->sublevel
){
481 current
= current
->prev
;
485 current
= tree
->store
->tree_first
;
486 tree
->selected_ptr
= current
;
488 return tree
->selected_ptr
!= old
;
491 static void tree_move_to_top (WTree
*tree
)
493 tree
->selected_ptr
= tree
->store
->tree_first
;
497 static void tree_move_to_bottom (WTree
*tree
)
499 tree
->selected_ptr
= tree
->store
->tree_last
;
500 tree
->topdiff
= tlines (tree
) - 3 - 1;
503 void tree_chdir (WTree
*tree
, char *dir
)
507 current
= tree_store_whereis (dir
);
509 tree
->selected_ptr
= current
;
515 sync_tree (char *path
)
517 tree_chdir (the_tree
, path
);
520 /* Handle mouse click */
521 static void tree_event (WTree
*tree
, int y
)
523 if (tree
->tree_shown
[y
]){
524 tree
->selected_ptr
= tree
->tree_shown
[y
];
530 static void chdir_sel (WTree
*tree
);
532 static void maybe_chdir (WTree
*tree
)
534 if (!(xtree_mode
&& tree
->is_panel
))
541 static int event_callback (Gpm_Event
*event
, WTree
*tree
)
543 if (!(event
->type
& GPM_UP
))
555 tree_move_backward (tree
, tlines (tree
) - 1);
558 else if (event
->y
>= tlines (tree
)){
559 tree_move_forward (tree
, tlines (tree
) - 1);
562 tree_event (tree
, event
->y
);
563 if ((event
->type
& (GPM_UP
|GPM_DOUBLE
)) == (GPM_UP
|GPM_DOUBLE
)){
570 /* Search tree for text */
571 static int search_tree (WTree
*tree
, char *text
)
579 current
= tree
->selected_ptr
;
581 while (!wrapped
|| current
!= tree
->selected_ptr
){
582 if (strncmp (current
->subname
, text
, len
) == 0){
583 tree
->selected_ptr
= current
;
587 current
= current
->next
;
589 current
= tree
->store
->tree_first
;
598 static void tree_do_search (WTree
*tree
, int key
)
602 l
= strlen (tree
->search_buffer
);
603 if (l
&& (key
== KEY_BACKSPACE
))
604 tree
->search_buffer
[--l
] = 0;
606 if (key
&& l
< sizeof (tree
->search_buffer
)){
607 tree
->search_buffer
[l
] = key
;
608 tree
->search_buffer
[l
+1] = 0;
613 if (!search_tree (tree
, tree
->search_buffer
))
614 tree
->search_buffer
[--l
] = 0;
620 static void tree_rescan_cmd (WTree
*tree
)
622 char old_dir
[MC_MAXPATHLEN
];
624 if (!tree
->selected_ptr
|| !mc_get_current_wd (old_dir
, MC_MAXPATHLEN
) ||
625 mc_chdir (tree
->selected_ptr
->name
))
628 tree_store_rescan (tree
->selected_ptr
->name
);
632 static int tree_forget_cmd (WTree
*tree
)
634 if (tree
->selected_ptr
)
635 tree_remove_entry (tree
, tree
->selected_ptr
->name
);
639 static void tree_copy (WTree
*tree
, char *default_dest
)
646 if (!tree
->selected_ptr
)
648 g_snprintf (cmd_buf
, sizeof(cmd_buf
), _("Copy \"%s\" directory to:"),
649 name_trunc (tree
->selected_ptr
->name
, 50));
650 dest
= input_expand_dialog (_(" Copy "), cmd_buf
, default_dest
);
660 ctx
= file_op_context_new ();
661 file_op_context_create_ui (ctx
, OP_COPY
, FALSE
);
662 copy_dir_dir (ctx
, tree
->selected_ptr
->name
, dest
, 1, 0, 0, 0, &count
, &bytes
);
663 file_op_context_destroy (ctx
);
668 static void tree_help_cmd (void)
670 interactive_display (NULL
, "[Directory Tree]");
673 static int tree_copy_cmd (WTree
*tree
)
675 tree_copy (tree
, "");
679 static void tree_move (WTree
*tree
, char *default_dest
)
687 if (!tree
->selected_ptr
)
689 g_snprintf (cmd_buf
, sizeof (cmd_buf
), _("Move \"%s\" directory to:"),
690 name_trunc (tree
->selected_ptr
->name
, 50));
691 dest
= input_expand_dialog (_(" Move "), cmd_buf
, default_dest
);
698 if (stat (dest
, &buf
)){
699 message (1, MSG_ERROR
, _(" Cannot stat the destination \n %s "),
700 unix_error_string (errno
));
704 if (!S_ISDIR (buf
.st_mode
)){
705 file_error (_(" Destination \"%s\" must be a directory \n %s "),
711 ctx
= file_op_context_new ();
712 file_op_context_create_ui (ctx
, OP_MOVE
, FALSE
);
713 move_dir_dir (ctx
, tree
->selected_ptr
->name
, dest
, &count
, &bytes
);
714 file_op_context_destroy (ctx
);
720 tree_move_cmd (WTree
*tree
)
722 tree_move (tree
, "");
728 tree_mkdir_cmd (WTree
*tree
)
730 char old_dir
[MC_MAXPATHLEN
];
732 if (!tree
->selected_ptr
)
734 if (!mc_get_current_wd (old_dir
, MC_MAXPATHLEN
))
736 if (chdir (tree
->selected_ptr
->name
))
741 tree_rescan_cmd (tree
);
748 tree_rmdir_cmd (WTree
*tree
)
750 char old_dir
[MC_MAXPATHLEN
];
755 if (tree
->selected_ptr
){
756 if (!mc_get_current_wd (old_dir
, MC_MAXPATHLEN
))
758 if (mc_chdir (PATH_SEP_STR
))
764 buf
= g_strdup_printf (_(" Delete %s? "), tree
->selected_ptr
->name
);
765 result
= query_dialog (_(" Delete "), buf
, 3, 2, _("&Yes"), _("&No"));
772 ctx
= file_op_context_new ();
773 file_op_context_create_ui (ctx
, OP_DELETE
, FALSE
);
774 if (erase_dir (ctx
, tree
->selected_ptr
->name
, &count
, &bytes
) == FILE_CONT
)
775 tree_forget_cmd (tree
);
776 file_op_context_destroy (ctx
);
783 static void set_navig_label (WTree
*tree
);
786 tree_toggle_navig (WTree
*tree
)
788 tree_navigation_flag
= 1 - tree_navigation_flag
;
789 set_navig_label (tree
);
793 set_navig_label (WTree
*tree
)
795 define_label_data (tree
->widget
.parent
, 4,
796 tree_navigation_flag
? _("Static") : _("Dynamc"),
797 (buttonbarfn
) tree_toggle_navig
, tree
);
801 move_down (WTree
*tree
)
803 tree_move_forward (tree
, 1);
809 move_up (WTree
*tree
)
811 tree_move_backward (tree
, 1);
817 move_home (WTree
*tree
)
819 tree_move_to_top (tree
);
825 move_end (WTree
*tree
)
827 tree_move_to_bottom (tree
);
833 move_left (WTree
*tree
)
837 if (tree_navigation_flag
){
838 v
= tree_move_to_parent (tree
);
847 move_right (WTree
*tree
)
849 if (tree_navigation_flag
){
850 tree_move_to_child (tree
);
859 move_prevp (WTree
*tree
)
861 tree_move_backward (tree
, tlines (tree
) - 1);
867 move_nextp (WTree
*tree
)
869 tree_move_forward (tree
, tlines (tree
) - 1);
875 chdir_sel (WTree
*tree
)
877 if (!tree
->is_panel
) {
881 if (do_cd (tree
->selected_ptr
->name
, cd_exact
)) {
882 paint_panel (cpanel
);
883 select_item (cpanel
);
885 message (1, MSG_ERROR
, _(" Cannot chdir to \"%s\" \n %s "),
886 tree
->selected_ptr
->name
, unix_error_string (errno
));
894 tree_start_search (WTree
*tree
)
898 if (tree
->searching
){
900 if (tree
->selected_ptr
== tree
->store
->tree_last
)
901 tree_move_to_top(tree
);
903 /* set navigation mode temporarily to 'Static' because in
904 * dynamic navigation mode tree_move_forward will not move
905 * to a lower sublevel if necessary (sequent searches must
906 * start with the directory followed the last found directory)
908 i
= tree_navigation_flag
;
909 tree_navigation_flag
= 0;
910 tree_move_forward (tree
, 1);
911 tree_navigation_flag
= i
;
913 tree_do_search (tree
, 0);
917 tree
->search_buffer
[0] = 0;
921 static const key_map tree_keymap
[] = {
922 { XCTRL('n'), move_down
},
923 { XCTRL('p'), move_up
},
924 { KEY_DOWN
, move_down
},
927 { KEY_ENTER
, chdir_sel
},
928 { KEY_HOME
, move_home
},
929 { KEY_C1
, move_end
},
930 { KEY_END
, move_end
},
931 { KEY_A1
, move_home
},
932 { KEY_NPAGE
, move_nextp
},
933 { KEY_PPAGE
, move_prevp
},
934 { XCTRL('v'), move_nextp
},
935 { ALT('v'), move_prevp
},
936 { XCTRL('p'), move_up
},
937 { XCTRL('p'), move_down
},
938 { XCTRL('s'), tree_start_search
},
939 { ALT('s'), tree_start_search
},
940 { XCTRL('r'), tree_rescan_cmd
},
941 { KEY_DC
, tree_rmdir_cmd
},
946 tree_key (WTree
*tree
, int key
)
950 for (i
= 0; tree_keymap
[i
].key_code
; i
++){
951 if (key
== tree_keymap
[i
].key_code
){
952 if (tree_keymap
[i
].fn
!= tree_start_search
)
954 (*tree_keymap
[i
].fn
)(tree
);
960 /* We do not want to use them if we do not need to */
961 /* Input line may want to take the motion key event */
963 return move_left (tree
);
965 if (key
== KEY_RIGHT
)
966 return move_right (tree
);
968 if (is_abort_char (key
)) {
969 if (tree
->is_panel
) {
972 return 1; /* eat abort char */
974 return 0; /* modal tree dialog: let upper layer see the
975 abort character and close the dialog */
978 /* Do not eat characters not meant for the tree below ' ' (e.g. C-l). */
979 if ((key
>= ' ' && key
<= 255) || key
== KEY_BACKSPACE
) {
980 if (tree
->searching
){
981 tree_do_search (tree
, key
);
986 if (!command_prompt
) {
987 tree_start_search (tree
);
988 tree_do_search (tree
, key
);
991 return tree
->is_panel
;
998 tree_frame (Dlg_head
*h
, WTree
*tree
)
1000 attrset (NORMAL_COLOR
);
1001 widget_erase ((Widget
*) tree
);
1003 draw_double_box (h
, tree
->widget
.y
, tree
->widget
.x
, tree
->widget
.lines
,
1006 if (show_mini_info
&& tree
->is_panel
){
1007 widget_move (tree
, tlines (tree
) + 1, 1);
1008 hline (ACS_HLINE
, tree
->widget
.cols
- 2);
1014 tree_callback (WTree
*tree
, int msg
, int par
)
1016 Dlg_head
*h
= tree
->widget
.parent
;
1020 tree_frame (h
, tree
);
1025 return tree_key (tree
, par
);
1029 define_label (h
, 1, _("Help"), (voidfn
) tree_help_cmd
);
1030 define_label_data (h
, 2, _("Rescan"),
1031 (buttonbarfn
) tree_rescan_cmd
, tree
);
1032 define_label_data (h
, 3, _("Forget"),
1033 (buttonbarfn
) tree_forget_cmd
, tree
);
1034 define_label_data (h
, 5, _("Copy"), (buttonbarfn
) tree_copy_cmd
,
1036 define_label_data (h
, 6, _("RenMov"), (buttonbarfn
) tree_move_cmd
,
1039 /* FIXME: mkdir is currently defunct */
1040 define_label_data (h
, 7, _("Mkdir"), (buttonbarfn
) tree_mkdir_cmd
,
1043 define_label (h
, 7, "", 0);
1045 define_label_data (h
, 8, _("Rmdir"), (buttonbarfn
) tree_rmdir_cmd
,
1047 set_navig_label (tree
);
1051 /* FIXME: Should find a better way of only displaying the
1052 currently selected item */
1056 /* FIXME: Should find a better way of changing the color of the
1058 case WIDGET_UNFOCUS
:
1063 return default_proc (msg
, par
);
1067 tree_new (int is_panel
, int y
, int x
, int lines
, int cols
)
1069 WTree
*tree
= g_new (WTree
, 1);
1071 init_widget (&tree
->widget
, y
, x
, lines
, cols
,
1072 (callback_fn
) tree_callback
, (destroy_fn
) tree_destroy
,
1073 (mouse_h
) event_callback
, NULL
);
1074 tree
->is_panel
= is_panel
;
1075 tree
->selected_ptr
= 0;
1077 tree
->store
= tree_store_get ();
1078 tree_store_add_entry_remove_hook (remove_callback
, tree
);
1079 tree
->tree_shown
= 0;
1080 tree
->search_buffer
[0] = 0;
1081 tree
->topdiff
= tree
->widget
.lines
/ 2;
1082 tree
->searching
= 0;
1085 /* We do not want to keep the cursor */
1086 widget_want_cursor (tree
->widget
, 0);
1091 /* Return name of the currently selected entry */
1093 tree_selected_name (WTree
*tree
)
1095 return tree
->selected_ptr
->name
;