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.
44 #include "file.h" /* For copy_dir_dir(), move_dir_dir(), erase_dir() */
45 #include "fileopctx.h"
47 #include "key.h" /* For mi_getch() */
50 #include "../vfs/vfs.h"
52 extern int command_prompt
;
54 /* Use the color of the parent widget for the unselected entries */
55 #define TREE_NORMALC NORMALC
57 /* Specifies the display mode: 1d or 2d */
58 int tree_navigation_flag
;
61 static void save_tree (WTree
*tree
);
62 static void tree_rescan_cmd (WTree
*tree
);
63 static int tree_callback (Dlg_head
*h
, WTree
*tree
, int msg
, int par
);
64 #define tcallback (callback_fn) tree_callback
68 static tree_entry
*back_ptr (tree_entry
*ptr
, int *count
)
72 while (ptr
&& ptr
->prev
&& i
< *count
){
80 static tree_entry
*forw_ptr (tree_entry
*ptr
, int *count
)
84 while (ptr
&& ptr
->next
&& i
< *count
){
93 /* Add a directory to the list of directories */
94 static tree_entry
*tree_add_entry (WTree
*tree
, char *name
)
99 return tree_store_add_entry (name
);
102 /* Append a directory to the list of directories */
103 static tree_entry
*tree_append_entry (WTree
*tree
, char *name
)
105 tree_entry
*current
, *new;
109 /* We assume the directory is not yet in the list */
111 new = g_new (tree_entry
, 1);
112 if (!tree
->store
->tree_first
){
114 tree
->store
->tree_first
= new;
117 tree
->tree_last
->next
= new;
118 new->prev
= tree
->tree_last
;
121 tree
->store
->tree_last
= new;
123 /* Calculate attributes */
124 new->name
= g_strdup (name
);
125 len
= strlen (new->name
);
127 for (i
= 0; i
< len
; i
++)
128 if (new->name
[i
] == PATH_SEP
){
130 new->subname
= new->name
+ i
+ 1;
132 submask
= 1 << new->sublevel
;
133 submask
&= (2 << new->sublevel
) - 1;
134 new->submask
= submask
;
137 /* Correct the submasks of the previous entries */
139 while (current
&& current
->sublevel
> new->sublevel
){
140 current
->submask
|= 1 << new->sublevel
;
141 current
= current
->prev
;
144 /* The entry has now been appended */
150 remove_callback (tree_entry
*entry
, void *data
)
154 if (tree
->selected_ptr
== entry
){
155 if (tree
->selected_ptr
->next
)
156 tree
->selected_ptr
= tree
->selected_ptr
->next
;
158 tree
->selected_ptr
= tree
->selected_ptr
->prev
;
162 static void tree_remove_entry (WTree
*tree
, char *name
)
164 tree_store_remove_entry (name
);
167 static void tree_destroy (WTree
*tree
)
169 tree_store_remove_entry_remove_hook (remove_callback
);
172 if (tree
->tree_shown
){
173 g_free (tree
->tree_shown
);
174 tree
->tree_shown
= 0;
176 tree
->selected_ptr
= NULL
;
179 /* Loads the .mc.tree file */
180 static void load_tree (WTree
*tree
)
184 tree
->selected_ptr
= tree
->store
->tree_first
;
185 tree_chdir (tree
, home_dir
);
188 /* Save the .mc.tree file */
189 static void save_tree (WTree
*tree
)
193 error
= tree_store_save ();
196 fprintf (stderr
, _("Cannot open the %s file for writing:\n%s\n"), MC_TREE
,
197 unix_error_string (error
));
202 static void tree_show_mini_info (WTree
*tree
, int tree_lines
, int tree_cols
)
204 Dlg_head
*h
= tree
->widget
.parent
;
215 widget_move (&tree
->widget
, line
, 1);
216 hline (' ', tree_cols
);
217 widget_move (&tree
->widget
, line
, 1);
219 if (tree
->searching
){
220 /* Show search string */
221 attrset (TREE_NORMALC
);
225 addstr (name_trunc (tree
->search_buffer
, tree_cols
-2));
229 /* Show full name of selected directory */
230 addstr (name_trunc (tree
->selected_ptr
->name
, tree_cols
));
234 static void show_tree (WTree
*tree
)
236 Dlg_head
*h
= tree
->widget
.parent
;
238 int i
, j
, topsublevel
;
240 int tree_lines
, tree_cols
;
244 tree_lines
= tlines (tree
);
245 tree_cols
= tree
->widget
.cols
;
247 attrset (TREE_NORMALC
);
248 widget_move ((Widget
*)tree
, y
, x
);
254 if (tree
->tree_shown
)
255 g_free (tree
->tree_shown
);
256 tree
->tree_shown
= g_new (tree_entry
*, tree_lines
);
258 for (i
= 0; i
< tree_lines
; i
++)
259 tree
->tree_shown
[i
] = NULL
;
260 if (tree
->store
->tree_first
)
261 topsublevel
= tree
->store
->tree_first
->sublevel
;
264 if (!tree
->selected_ptr
){
265 tree
->selected_ptr
= tree
->store
->tree_first
;
268 current
= tree
->selected_ptr
;
270 /* Calculate the directory which is to be shown on the topmost line */
271 if (tree_navigation_flag
){
273 while (current
->prev
&& i
< tree
->topdiff
){
274 current
= current
->prev
;
275 if (current
->sublevel
< tree
->selected_ptr
->sublevel
){
276 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
277 strlen (current
->name
)) == 0)
279 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
280 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
281 if (strncmp (current
->name
, tree
->selected_ptr
->name
, j
) == 0)
283 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+ 1
284 && strlen (tree
->selected_ptr
->name
) > 1){
285 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
286 strlen (tree
->selected_ptr
->name
)) == 0)
292 current
= back_ptr (current
, &tree
->topdiff
);
294 /* Loop for every line */
295 for (i
= 0; i
< tree_lines
; i
++){
296 /* Move to the beginning of the line */
297 widget_move (&tree
->widget
, y
+i
, x
);
299 hline (' ', tree_cols
);
300 widget_move (&tree
->widget
, y
+i
, x
);
305 tree
->tree_shown
[i
] = current
;
306 if (current
->sublevel
== topsublevel
){
308 /* Top level directory */
309 if (tree
->active
&& current
== tree
->selected_ptr
) {
310 if (!use_colors
&& !tree
->is_panel
)
311 attrset (MARKED_COLOR
);
313 attrset (SELECTED_COLOR
);
317 addstr (name_trunc (current
->name
, tree_cols
- 6));
319 /* Sub level directory */
322 /* Output branch parts */
323 for (j
= 0; j
< current
->sublevel
- topsublevel
- 1; j
++){
324 if (tree_cols
- 8 - 3 * j
< 9)
327 if (current
->submask
& (1 << (j
+ topsublevel
+ 1)))
334 if (!current
->next
|| !(current
->next
->submask
& (1 << current
->sublevel
)))
335 addch (ACS_LLCORNER
);
341 if (tree
->active
&& current
== tree
->selected_ptr
) {
342 /* Selected directory -> change color */
343 if (!use_colors
&& !tree
->is_panel
)
344 attrset (MARKED_COLOR
);
346 attrset (SELECTED_COLOR
);
351 addstr (name_trunc (current
->subname
,
352 tree_cols
- 2 - 4 - 3 * j
));
356 /* Return to normal color */
357 attrset (TREE_NORMALC
);
359 /* Calculate the next value for current */
360 current
= current
->next
;
361 if (tree_navigation_flag
){
363 if (current
->sublevel
< tree
->selected_ptr
->sublevel
){
364 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
365 strlen (current
->name
)) == 0)
367 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
368 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
369 if (strncmp (current
->name
,tree
->selected_ptr
->name
,j
)== 0)
371 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+1
372 && strlen (tree
->selected_ptr
->name
) > 1){
373 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
374 strlen (tree
->selected_ptr
->name
)) == 0)
377 current
= current
->next
;
381 tree_show_mini_info (tree
, tree_lines
, tree_cols
);
384 static void check_focus (WTree
*tree
)
386 if (tree
->topdiff
< 3)
388 else if (tree
->topdiff
>= tlines (tree
) - 3)
389 tree
->topdiff
= tlines (tree
) - 3 - 1;
392 static void tree_move_backward (WTree
*tree
, int i
)
397 if (tree_navigation_flag
){
398 current
= tree
->selected_ptr
;
399 while (j
< i
&& current
->prev
400 && current
->prev
->sublevel
>= tree
->selected_ptr
->sublevel
){
401 current
= current
->prev
;
402 if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
403 tree
->selected_ptr
= current
;
409 tree
->selected_ptr
= back_ptr (tree
->selected_ptr
, &i
);
414 static void tree_move_forward (WTree
*tree
, int i
)
419 if (tree_navigation_flag
){
420 current
= tree
->selected_ptr
;
421 while (j
< i
&& current
->next
422 && current
->next
->sublevel
>= tree
->selected_ptr
->sublevel
){
423 current
= current
->next
;
424 if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
425 tree
->selected_ptr
= current
;
431 tree
->selected_ptr
= forw_ptr (tree
->selected_ptr
, &i
);
436 static void tree_move_to_child (WTree
*tree
)
440 /* Do we have a starting point? */
441 if (!tree
->selected_ptr
)
443 /* Take the next entry */
444 current
= tree
->selected_ptr
->next
;
445 /* Is it the child of the selected entry */
446 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
){
447 /* Yes -> select this entry */
448 tree
->selected_ptr
= current
;
452 /* No -> rescan and try again */
453 tree_rescan_cmd (tree
);
454 current
= tree
->selected_ptr
->next
;
455 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
){
456 tree
->selected_ptr
= current
;
463 static int tree_move_to_parent (WTree
*tree
)
468 if (!tree
->selected_ptr
)
470 old
= tree
->selected_ptr
;
471 current
= tree
->selected_ptr
->prev
;
472 while (current
&& current
->sublevel
>= tree
->selected_ptr
->sublevel
){
473 current
= current
->prev
;
477 current
= tree
->store
->tree_first
;
478 tree
->selected_ptr
= current
;
480 return tree
->selected_ptr
!= old
;
483 static void tree_move_to_top (WTree
*tree
)
485 tree
->selected_ptr
= tree
->store
->tree_first
;
489 static void tree_move_to_bottom (WTree
*tree
)
491 tree
->selected_ptr
= tree
->store
->tree_last
;
492 tree
->topdiff
= tlines (tree
) - 3 - 1;
495 void tree_chdir (WTree
*tree
, char *dir
)
499 current
= tree_store_whereis (dir
);
501 tree
->selected_ptr
= current
;
507 sync_tree (char *path
)
509 tree_chdir (the_tree
, path
);
512 /* Handle mouse click */
513 static void tree_event (WTree
*tree
, int y
)
515 if (tree
->tree_shown
[y
]){
516 tree
->selected_ptr
= tree
->tree_shown
[y
];
522 static void chdir_sel (WTree
*tree
);
524 static void maybe_chdir (WTree
*tree
)
526 if (!(xtree_mode
&& tree
->is_panel
))
533 static int event_callback (Gpm_Event
*event
, WTree
*tree
)
535 if (!(event
->type
& GPM_UP
))
547 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
)){
562 /* Search tree for text */
563 static int 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
;
590 static void tree_do_search (WTree
*tree
, int key
)
594 l
= strlen (tree
->search_buffer
);
595 if (l
&& (key
== 8 || key
== 0177 || key
== KEY_BACKSPACE
))
596 tree
->search_buffer
[--l
] = 0;
598 if (key
&& l
< sizeof (tree
->search_buffer
)){
599 tree
->search_buffer
[l
] = key
;
600 tree
->search_buffer
[l
+1] = 0;
605 if (!search_tree (tree
, tree
->search_buffer
))
606 tree
->search_buffer
[--l
] = 0;
612 static void tree_rescan_cmd (WTree
*tree
)
614 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
);
624 static int tree_forget_cmd (WTree
*tree
)
626 if (tree
->selected_ptr
)
627 tree_remove_entry (tree
, tree
->selected_ptr
->name
);
631 static void tree_copy (WTree
*tree
, char *default_dest
)
638 if (!tree
->selected_ptr
)
640 g_snprintf (cmd_buf
, sizeof(cmd_buf
), _("Copy \"%s\" directory to:"),
641 name_trunc (tree
->selected_ptr
->name
, 50));
642 dest
= input_expand_dialog (_(" Copy "), cmd_buf
, default_dest
);
652 ctx
= file_op_context_new ();
653 file_op_context_create_ui (ctx
, OP_COPY
, FALSE
);
654 copy_dir_dir (ctx
, tree
->selected_ptr
->name
, dest
, 1, 0, 0, 0, &count
, &bytes
);
655 file_op_context_destroy (ctx
);
660 static void tree_help_cmd (void)
662 interactive_display (NULL
, "[Directory Tree]");
665 static int tree_copy_cmd (WTree
*tree
)
667 tree_copy (tree
, "");
671 static void tree_move (WTree
*tree
, char *default_dest
)
679 if (!tree
->selected_ptr
)
681 g_snprintf (cmd_buf
, sizeof (cmd_buf
), _("Move \"%s\" directory to:"),
682 name_trunc (tree
->selected_ptr
->name
, 50));
683 dest
= input_expand_dialog (_(" Move "), cmd_buf
, default_dest
);
690 if (stat (dest
, &buf
)){
691 message (1, MSG_ERROR
, _(" Cannot stat the destination \n %s "),
692 unix_error_string (errno
));
696 if (!S_ISDIR (buf
.st_mode
)){
697 message (1, MSG_ERROR
, _(" The destination isn't a directory "));
702 ctx
= file_op_context_new ();
703 file_op_context_create_ui (ctx
, OP_MOVE
, FALSE
);
704 move_dir_dir (ctx
, tree
->selected_ptr
->name
, dest
, &count
, &bytes
);
705 file_op_context_destroy (ctx
);
711 tree_move_cmd (WTree
*tree
)
713 tree_move (tree
, "");
719 tree_mkdir_cmd (WTree
*tree
)
721 char old_dir
[MC_MAXPATHLEN
];
723 if (!tree
->selected_ptr
)
725 if (!mc_get_current_wd (old_dir
, MC_MAXPATHLEN
))
727 if (chdir (tree
->selected_ptr
->name
))
732 tree_rescan_cmd (tree
);
739 tree_rmdir_cmd (WTree
*tree
)
741 char old_dir
[MC_MAXPATHLEN
];
746 if (tree
->selected_ptr
){
747 if (!mc_get_current_wd (old_dir
, MC_MAXPATHLEN
))
749 if (mc_chdir (PATH_SEP_STR
))
755 buf
= g_strdup_printf (_(" Delete %s? "), tree
->selected_ptr
->name
);
756 result
= query_dialog (_(" Delete "), buf
, 3, 2, _("&Yes"), _("&No"));
763 ctx
= file_op_context_new ();
764 file_op_context_create_ui (ctx
, OP_DELETE
, FALSE
);
765 if (erase_dir (ctx
, tree
->selected_ptr
->name
, &count
, &bytes
) == FILE_CONT
)
766 tree_forget_cmd (tree
);
767 file_op_context_destroy (ctx
);
774 static void set_navig_label (WTree
*tree
);
777 tree_toggle_navig (WTree
*tree
)
779 tree_navigation_flag
= 1 - tree_navigation_flag
;
780 set_navig_label (tree
);
784 set_navig_label (WTree
*tree
)
786 define_label_data (tree
->widget
.parent
, (Widget
*) tree
,
787 4, tree_navigation_flag
? _("Static") : _("Dynamc"),
788 (buttonbarfn
) tree_toggle_navig
, tree
);
792 move_down (WTree
*tree
)
794 tree_move_forward (tree
, 1);
800 move_up (WTree
*tree
)
802 tree_move_backward (tree
, 1);
808 move_home (WTree
*tree
)
810 tree_move_to_top (tree
);
816 move_end (WTree
*tree
)
818 tree_move_to_bottom (tree
);
824 move_left (WTree
*tree
)
828 if (tree_navigation_flag
){
829 v
= tree_move_to_parent (tree
);
838 move_right (WTree
*tree
)
840 if (tree_navigation_flag
){
841 tree_move_to_child (tree
);
850 move_prevp (WTree
*tree
)
852 tree_move_backward (tree
, tlines (tree
) - 1);
858 move_nextp (WTree
*tree
)
860 tree_move_forward (tree
, tlines (tree
) - 1);
866 chdir_sel (WTree
*tree
)
868 if (!tree
->is_panel
){
873 if (do_cd (tree
->selected_ptr
->name
, cd_exact
)){
874 paint_panel (cpanel
);
875 select_item (cpanel
);
877 message (1, MSG_ERROR
, _(" Cannot chdir to \"%s\" \n %s "),
878 tree
->selected_ptr
->name
, unix_error_string (errno
));
886 tree_start_search (WTree
*tree
)
890 if (tree
->searching
){
892 if (tree
->selected_ptr
== tree
->store
->tree_last
)
893 tree_move_to_top(tree
);
895 /* set navigation mode temporarily to 'Static' because in
896 * dynamic navigation mode tree_move_forward will not move
897 * to a lower sublevel if necessary (sequent searches must
898 * start with the directory followed the last found directory)
900 i
= tree_navigation_flag
;
901 tree_navigation_flag
= 0;
902 tree_move_forward (tree
, 1);
903 tree_navigation_flag
= i
;
905 tree_do_search (tree
, 0);
909 tree
->search_buffer
[0] = 0;
913 static const key_map tree_keymap
[] = {
914 { XCTRL('n'), move_down
},
915 { XCTRL('p'), move_up
},
916 { KEY_DOWN
, move_down
},
919 { KEY_ENTER
, chdir_sel
},
920 { KEY_HOME
, move_home
},
921 { KEY_C1
, move_end
},
922 { KEY_END
, move_end
},
923 { KEY_A1
, move_home
},
924 { KEY_NPAGE
, move_nextp
},
925 { KEY_PPAGE
, move_prevp
},
926 { XCTRL('v'), move_nextp
},
927 { ALT('v'), move_prevp
},
928 { XCTRL('p'), move_up
},
929 { XCTRL('p'), move_down
},
930 { XCTRL('s'), tree_start_search
},
931 { ALT('s'), tree_start_search
},
932 { XCTRL('r'), tree_rescan_cmd
},
933 { KEY_DC
, tree_rmdir_cmd
},
938 tree_key (WTree
*tree
, int key
)
942 for (i
= 0; tree_keymap
[i
].key_code
; i
++){
943 if (key
== tree_keymap
[i
].key_code
){
944 if (tree_keymap
[i
].fn
!= tree_start_search
)
946 (*tree_keymap
[i
].fn
)(tree
);
952 /* We do not want to use them if we do not need to */
953 /* Input line may want to take the motion key event */
955 return move_left (tree
);
957 if (key
== KEY_RIGHT
)
958 return move_right (tree
);
960 if (is_abort_char (key
)) {
961 if (tree
->is_panel
) {
964 return 1; /* eat abort char */
966 return 0; /* modal tree dialog: let upper layer see the
967 abort character and close the dialog */
970 /* Do not eat characters not meant for the tree below ' ' (e.g. C-l). */
971 if ((key
>= ' '&& key
<= 255) || key
== 8 || key
== KEY_BACKSPACE
) {
972 if (tree
->searching
){
973 tree_do_search (tree
, key
);
978 if (!command_prompt
) {
979 tree_start_search (tree
);
980 tree_do_search (tree
, key
);
983 return tree
->is_panel
;
990 tree_frame (Dlg_head
*h
, WTree
*tree
)
992 attrset (NORMAL_COLOR
);
993 widget_erase ((Widget
*) tree
);
995 draw_double_box (h
, tree
->widget
.y
, tree
->widget
.x
, tree
->widget
.lines
,
998 if (show_mini_info
&& tree
->is_panel
){
999 widget_move (tree
, tlines (tree
) + 1, 1);
1000 hline (ACS_HLINE
, tree
->widget
.cols
- 2);
1006 tree_callback (Dlg_head
*h
, WTree
*tree
, int msg
, int par
)
1010 tree_frame (h
, tree
);
1015 return tree_key (tree
, par
);
1019 define_label (h
, (Widget
*)tree
, 1, _("Help"), (voidfn
) tree_help_cmd
);
1020 define_label_data (h
, (Widget
*)tree
,
1021 2, _("Rescan"), (buttonbarfn
)tree_rescan_cmd
, tree
);
1022 define_label_data (h
, (Widget
*)tree
,
1023 3, _("Forget"), (buttonbarfn
)tree_forget_cmd
, tree
);
1024 define_label_data (h
, (Widget
*)tree
,
1025 5, _("Copy"), (buttonbarfn
) tree_copy_cmd
, tree
);
1026 define_label_data (h
, (Widget
*)tree
,
1027 6, _("RenMov"), (buttonbarfn
) tree_move_cmd
, tree
);
1029 /* FIXME: mkdir is currently defunct */
1030 define_label_data (h
, (Widget
*)tree
,
1031 7, _("Mkdir"), (buttonbarfn
) tree_mkdir_cmd
, tree
);
1033 define_label (h
, (Widget
*)tree
, 7, "", 0);
1035 define_label_data (h
, (Widget
*)tree
,
1036 8, _("Rmdir"), (buttonbarfn
) tree_rmdir_cmd
, tree
);
1037 set_navig_label (tree
);
1038 redraw_labels (h
, (Widget
*)tree
);
1041 /* FIXME: Should find a better way of only displaying the
1042 currently selected item */
1046 /* FIXME: Should find a better way of changing the color of the
1048 case WIDGET_UNFOCUS
:
1053 return default_proc (h
, msg
, par
);
1057 tree_new (int is_panel
, int y
, int x
, int lines
, int cols
)
1059 WTree
*tree
= g_new (WTree
, 1);
1061 init_widget (&tree
->widget
, y
, x
, lines
, cols
, tcallback
,
1062 (destroy_fn
) tree_destroy
, (mouse_h
) event_callback
, NULL
);
1063 tree
->is_panel
= is_panel
;
1064 tree
->selected_ptr
= 0;
1066 tree
->store
= tree_store_get ();
1067 tree_store_add_entry_remove_hook (remove_callback
, tree
);
1068 tree
->tree_shown
= 0;
1069 tree
->search_buffer
[0] = 0;
1070 tree
->topdiff
= tree
->widget
.lines
/ 2;
1071 tree
->searching
= 0;
1075 /* We do not want to keep the cursor */
1076 widget_want_cursor (tree
->widget
, 0);