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 static 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
66 static tree_entry
*back_ptr (tree_entry
*ptr
, int *count
)
70 while (ptr
&& ptr
->prev
&& i
< *count
){
78 static tree_entry
*forw_ptr (tree_entry
*ptr
, int *count
)
82 while (ptr
&& ptr
->next
&& i
< *count
){
91 /* Add a directory to the list of directories */
92 static tree_entry
*tree_add_entry (WTree
*tree
, char *name
)
97 return tree_store_add_entry (name
);
100 /* Append a directory to the list of directories */
101 static tree_entry
*tree_append_entry (WTree
*tree
, char *name
)
103 tree_entry
*current
, *new;
107 /* We assume the directory is not yet in the list */
109 new = g_new (tree_entry
, 1);
110 if (!tree
->store
->tree_first
){
112 tree
->store
->tree_first
= new;
115 tree
->tree_last
->next
= new;
116 new->prev
= tree
->tree_last
;
119 tree
->store
->tree_last
= new;
121 /* Calculate attributes */
122 new->name
= g_strdup (name
);
123 len
= strlen (new->name
);
125 for (i
= 0; i
< len
; i
++)
126 if (new->name
[i
] == PATH_SEP
){
128 new->subname
= new->name
+ i
+ 1;
130 submask
= 1 << new->sublevel
;
131 submask
&= (2 << new->sublevel
) - 1;
132 new->submask
= submask
;
135 /* Correct the submasks of the previous entries */
137 while (current
&& current
->sublevel
> new->sublevel
){
138 current
->submask
|= 1 << new->sublevel
;
139 current
= current
->prev
;
142 /* The entry has now been appended */
148 remove_callback (tree_entry
*entry
, void *data
)
152 if (tree
->selected_ptr
== entry
){
153 if (tree
->selected_ptr
->next
)
154 tree
->selected_ptr
= tree
->selected_ptr
->next
;
156 tree
->selected_ptr
= tree
->selected_ptr
->prev
;
160 static void tree_remove_entry (WTree
*tree
, char *name
)
162 tree_store_remove_entry (name
);
165 static void tree_destroy (WTree
*tree
)
167 tree_store_remove_entry_remove_hook (remove_callback
);
170 if (tree
->tree_shown
){
171 g_free (tree
->tree_shown
);
172 tree
->tree_shown
= 0;
174 tree
->selected_ptr
= NULL
;
177 /* Loads the .mc.tree file */
178 static void load_tree (WTree
*tree
)
182 tree
->selected_ptr
= tree
->store
->tree_first
;
183 tree_chdir (tree
, home_dir
);
186 /* Save the .mc.tree file */
187 static void save_tree (WTree
*tree
)
191 error
= tree_store_save ();
194 fprintf (stderr
, _("Cannot open the %s file for writing:\n%s\n"), MC_TREE
,
195 unix_error_string (error
));
200 static void tree_show_mini_info (WTree
*tree
, int tree_lines
, int tree_cols
)
202 Dlg_head
*h
= tree
->widget
.parent
;
213 widget_move (&tree
->widget
, line
, 1);
214 hline (' ', tree_cols
);
215 widget_move (&tree
->widget
, line
, 1);
217 if (tree
->searching
){
218 /* Show search string */
219 attrset (TREE_NORMALC
);
223 addstr (name_trunc (tree
->search_buffer
, tree_cols
-2));
227 /* Show full name of selected directory */
228 addstr (name_trunc (tree
->selected_ptr
->name
, tree_cols
));
232 static void show_tree (WTree
*tree
)
234 Dlg_head
*h
= tree
->widget
.parent
;
236 int i
, j
, topsublevel
;
238 int tree_lines
, tree_cols
;
242 tree_lines
= tlines (tree
);
243 tree_cols
= tree
->widget
.cols
;
245 attrset (TREE_NORMALC
);
246 widget_move ((Widget
*)tree
, y
, x
);
252 if (tree
->tree_shown
)
253 g_free (tree
->tree_shown
);
254 tree
->tree_shown
= g_new (tree_entry
*, tree_lines
);
256 for (i
= 0; i
< tree_lines
; i
++)
257 tree
->tree_shown
[i
] = NULL
;
258 if (tree
->store
->tree_first
)
259 topsublevel
= tree
->store
->tree_first
->sublevel
;
262 if (!tree
->selected_ptr
){
263 tree
->selected_ptr
= tree
->store
->tree_first
;
266 current
= tree
->selected_ptr
;
268 /* Calculate the directory which is to be shown on the topmost line */
269 if (tree_navigation_flag
){
271 while (current
->prev
&& i
< tree
->topdiff
){
272 current
= current
->prev
;
273 if (current
->sublevel
< tree
->selected_ptr
->sublevel
){
274 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
275 strlen (current
->name
)) == 0)
277 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
278 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
279 if (strncmp (current
->name
, tree
->selected_ptr
->name
, j
) == 0)
281 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+ 1
282 && strlen (tree
->selected_ptr
->name
) > 1){
283 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
284 strlen (tree
->selected_ptr
->name
)) == 0)
290 current
= back_ptr (current
, &tree
->topdiff
);
292 /* Loop for every line */
293 for (i
= 0; i
< tree_lines
; i
++){
294 /* Move to the beginning of the line */
295 widget_move (&tree
->widget
, y
+i
, x
);
297 hline (' ', tree_cols
);
298 widget_move (&tree
->widget
, y
+i
, x
);
303 tree
->tree_shown
[i
] = current
;
304 if (current
->sublevel
== topsublevel
){
306 /* Top level directory */
307 if (tree
->active
&& current
== tree
->selected_ptr
) {
308 if (!use_colors
&& !tree
->is_panel
)
309 attrset (MARKED_COLOR
);
311 attrset (SELECTED_COLOR
);
315 addstr (name_trunc (current
->name
, tree_cols
- 6));
317 /* Sub level directory */
320 /* Output branch parts */
321 for (j
= 0; j
< current
->sublevel
- topsublevel
- 1; j
++){
322 if (tree_cols
- 8 - 3 * j
< 9)
325 if (current
->submask
& (1 << (j
+ topsublevel
+ 1)))
332 if (!current
->next
|| !(current
->next
->submask
& (1 << current
->sublevel
)))
333 addch (ACS_LLCORNER
);
339 if (tree
->active
&& current
== tree
->selected_ptr
) {
340 /* Selected directory -> change color */
341 if (!use_colors
&& !tree
->is_panel
)
342 attrset (MARKED_COLOR
);
344 attrset (SELECTED_COLOR
);
349 addstr (name_trunc (current
->subname
,
350 tree_cols
- 2 - 4 - 3 * j
));
354 /* Return to normal color */
355 attrset (TREE_NORMALC
);
357 /* Calculate the next value for current */
358 current
= current
->next
;
359 if (tree_navigation_flag
){
361 if (current
->sublevel
< tree
->selected_ptr
->sublevel
){
362 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
363 strlen (current
->name
)) == 0)
365 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
366 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
367 if (strncmp (current
->name
,tree
->selected_ptr
->name
,j
)== 0)
369 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+1
370 && strlen (tree
->selected_ptr
->name
) > 1){
371 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
372 strlen (tree
->selected_ptr
->name
)) == 0)
375 current
= current
->next
;
379 tree_show_mini_info (tree
, tree_lines
, tree_cols
);
382 static void check_focus (WTree
*tree
)
384 if (tree
->topdiff
< 3)
386 else if (tree
->topdiff
>= tlines (tree
) - 3)
387 tree
->topdiff
= tlines (tree
) - 3 - 1;
390 static void tree_move_backward (WTree
*tree
, int i
)
395 if (tree_navigation_flag
){
396 current
= tree
->selected_ptr
;
397 while (j
< i
&& current
->prev
398 && current
->prev
->sublevel
>= tree
->selected_ptr
->sublevel
){
399 current
= current
->prev
;
400 if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
401 tree
->selected_ptr
= current
;
407 tree
->selected_ptr
= back_ptr (tree
->selected_ptr
, &i
);
412 static void tree_move_forward (WTree
*tree
, int i
)
417 if (tree_navigation_flag
){
418 current
= tree
->selected_ptr
;
419 while (j
< i
&& current
->next
420 && current
->next
->sublevel
>= tree
->selected_ptr
->sublevel
){
421 current
= current
->next
;
422 if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
423 tree
->selected_ptr
= current
;
429 tree
->selected_ptr
= forw_ptr (tree
->selected_ptr
, &i
);
434 static void tree_move_to_child (WTree
*tree
)
438 /* Do we have a starting point? */
439 if (!tree
->selected_ptr
)
441 /* Take the next entry */
442 current
= tree
->selected_ptr
->next
;
443 /* Is it the child of the selected entry */
444 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
){
445 /* Yes -> select this entry */
446 tree
->selected_ptr
= current
;
450 /* No -> rescan and try again */
451 tree_rescan_cmd (tree
);
452 current
= tree
->selected_ptr
->next
;
453 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
){
454 tree
->selected_ptr
= current
;
461 static int tree_move_to_parent (WTree
*tree
)
466 if (!tree
->selected_ptr
)
468 old
= tree
->selected_ptr
;
469 current
= tree
->selected_ptr
->prev
;
470 while (current
&& current
->sublevel
>= tree
->selected_ptr
->sublevel
){
471 current
= current
->prev
;
475 current
= tree
->store
->tree_first
;
476 tree
->selected_ptr
= current
;
478 return tree
->selected_ptr
!= old
;
481 static void tree_move_to_top (WTree
*tree
)
483 tree
->selected_ptr
= tree
->store
->tree_first
;
487 static void tree_move_to_bottom (WTree
*tree
)
489 tree
->selected_ptr
= tree
->store
->tree_last
;
490 tree
->topdiff
= tlines (tree
) - 3 - 1;
493 void tree_chdir (WTree
*tree
, char *dir
)
497 current
= tree_store_whereis (dir
);
499 tree
->selected_ptr
= current
;
505 sync_tree (char *path
)
507 tree_chdir (the_tree
, path
);
510 /* Handle mouse click */
511 static void tree_event (WTree
*tree
, int y
)
513 if (tree
->tree_shown
[y
]){
514 tree
->selected_ptr
= tree
->tree_shown
[y
];
520 static void chdir_sel (WTree
*tree
);
522 static void maybe_chdir (WTree
*tree
)
524 if (!(xtree_mode
&& tree
->is_panel
))
531 static int event_callback (Gpm_Event
*event
, WTree
*tree
)
533 if (!(event
->type
& GPM_UP
))
545 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
)){
560 /* Search tree for text */
561 static int search_tree (WTree
*tree
, char *text
)
569 current
= tree
->selected_ptr
;
571 while (!wrapped
|| current
!= tree
->selected_ptr
){
572 if (strncmp (current
->subname
, text
, len
) == 0){
573 tree
->selected_ptr
= current
;
577 current
= current
->next
;
579 current
= tree
->store
->tree_first
;
588 static void tree_do_search (WTree
*tree
, int key
)
592 l
= strlen (tree
->search_buffer
);
593 if (l
&& (key
== 8 || key
== 0177 || key
== KEY_BACKSPACE
))
594 tree
->search_buffer
[--l
] = 0;
596 if (key
&& l
< sizeof (tree
->search_buffer
)){
597 tree
->search_buffer
[l
] = key
;
598 tree
->search_buffer
[l
+1] = 0;
603 if (!search_tree (tree
, tree
->search_buffer
))
604 tree
->search_buffer
[--l
] = 0;
610 static void tree_rescan_cmd (WTree
*tree
)
612 char old_dir
[MC_MAXPATHLEN
];
614 if (!tree
->selected_ptr
|| !mc_get_current_wd (old_dir
, MC_MAXPATHLEN
) ||
615 mc_chdir (tree
->selected_ptr
->name
))
618 tree_store_rescan (tree
->selected_ptr
->name
);
622 static int tree_forget_cmd (WTree
*tree
)
624 if (tree
->selected_ptr
)
625 tree_remove_entry (tree
, tree
->selected_ptr
->name
);
629 static void tree_copy (WTree
*tree
, char *default_dest
)
636 if (!tree
->selected_ptr
)
638 g_snprintf (cmd_buf
, sizeof(cmd_buf
), _("Copy \"%s\" directory to:"),
639 name_trunc (tree
->selected_ptr
->name
, 50));
640 dest
= input_expand_dialog (_(" Copy "), cmd_buf
, default_dest
);
650 ctx
= file_op_context_new ();
651 file_op_context_create_ui (ctx
, OP_COPY
, FALSE
);
652 copy_dir_dir (ctx
, tree
->selected_ptr
->name
, dest
, 1, 0, 0, 0, &count
, &bytes
);
653 file_op_context_destroy (ctx
);
658 static void tree_help_cmd (void)
660 interactive_display (NULL
, "[Directory Tree]");
663 static int tree_copy_cmd (WTree
*tree
)
665 tree_copy (tree
, "");
669 static void tree_move (WTree
*tree
, char *default_dest
)
677 if (!tree
->selected_ptr
)
679 g_snprintf (cmd_buf
, sizeof (cmd_buf
), _("Move \"%s\" directory to:"),
680 name_trunc (tree
->selected_ptr
->name
, 50));
681 dest
= input_expand_dialog (_(" Move "), cmd_buf
, default_dest
);
688 if (stat (dest
, &buf
)){
689 message (1, MSG_ERROR
, _(" Cannot stat the destination \n %s "),
690 unix_error_string (errno
));
694 if (!S_ISDIR (buf
.st_mode
)){
695 message (1, MSG_ERROR
, _(" The destination isn't a directory "));
700 ctx
= file_op_context_new ();
701 file_op_context_create_ui (ctx
, OP_MOVE
, FALSE
);
702 move_dir_dir (ctx
, tree
->selected_ptr
->name
, dest
, &count
, &bytes
);
703 file_op_context_destroy (ctx
);
709 tree_move_cmd (WTree
*tree
)
711 tree_move (tree
, "");
717 tree_mkdir_cmd (WTree
*tree
)
719 char old_dir
[MC_MAXPATHLEN
];
721 if (!tree
->selected_ptr
)
723 if (!mc_get_current_wd (old_dir
, MC_MAXPATHLEN
))
725 if (chdir (tree
->selected_ptr
->name
))
730 tree_rescan_cmd (tree
);
737 tree_rmdir_cmd (WTree
*tree
)
739 char old_dir
[MC_MAXPATHLEN
];
744 if (tree
->selected_ptr
){
745 if (!mc_get_current_wd (old_dir
, MC_MAXPATHLEN
))
747 if (mc_chdir (PATH_SEP_STR
))
753 buf
= g_strdup_printf (_(" Delete %s? "), tree
->selected_ptr
->name
);
754 result
= query_dialog (_(" Delete "), buf
, 3, 2, _("&Yes"), _("&No"));
761 ctx
= file_op_context_new ();
762 file_op_context_create_ui (ctx
, OP_DELETE
, FALSE
);
763 if (erase_dir (ctx
, tree
->selected_ptr
->name
, &count
, &bytes
) == FILE_CONT
)
764 tree_forget_cmd (tree
);
765 file_op_context_destroy (ctx
);
772 static void set_navig_label (WTree
*tree
);
775 tree_toggle_navig (WTree
*tree
)
777 tree_navigation_flag
= 1 - tree_navigation_flag
;
778 set_navig_label (tree
);
782 set_navig_label (WTree
*tree
)
784 define_label_data (tree
->widget
.parent
, (Widget
*) tree
,
785 4, tree_navigation_flag
? _("Static") : _("Dynamc"),
786 (buttonbarfn
) tree_toggle_navig
, tree
);
790 move_down (WTree
*tree
)
792 tree_move_forward (tree
, 1);
798 move_up (WTree
*tree
)
800 tree_move_backward (tree
, 1);
806 move_home (WTree
*tree
)
808 tree_move_to_top (tree
);
814 move_end (WTree
*tree
)
816 tree_move_to_bottom (tree
);
822 move_left (WTree
*tree
)
826 if (tree_navigation_flag
){
827 v
= tree_move_to_parent (tree
);
836 move_right (WTree
*tree
)
838 if (tree_navigation_flag
){
839 tree_move_to_child (tree
);
848 move_prevp (WTree
*tree
)
850 tree_move_backward (tree
, tlines (tree
) - 1);
856 move_nextp (WTree
*tree
)
858 tree_move_forward (tree
, tlines (tree
) - 1);
864 chdir_sel (WTree
*tree
)
866 if (!tree
->is_panel
){
871 if (do_cd (tree
->selected_ptr
->name
, cd_exact
)){
872 paint_panel (cpanel
);
873 select_item (cpanel
);
875 message (1, MSG_ERROR
, _(" Cannot chdir to \"%s\" \n %s "),
876 tree
->selected_ptr
->name
, unix_error_string (errno
));
884 tree_start_search (WTree
*tree
)
888 if (tree
->searching
){
890 if (tree
->selected_ptr
== tree
->store
->tree_last
)
891 tree_move_to_top(tree
);
893 /* set navigation mode temporarily to 'Static' because in
894 * dynamic navigation mode tree_move_forward will not move
895 * to a lower sublevel if necessary (sequent searches must
896 * start with the directory followed the last found directory)
898 i
= tree_navigation_flag
;
899 tree_navigation_flag
= 0;
900 tree_move_forward (tree
, 1);
901 tree_navigation_flag
= i
;
903 tree_do_search (tree
, 0);
907 tree
->search_buffer
[0] = 0;
911 static const key_map tree_keymap
[] = {
912 { XCTRL('n'), move_down
},
913 { XCTRL('p'), move_up
},
914 { KEY_DOWN
, move_down
},
917 { KEY_ENTER
, chdir_sel
},
918 { KEY_HOME
, move_home
},
919 { KEY_C1
, move_end
},
920 { KEY_END
, move_end
},
921 { KEY_A1
, move_home
},
922 { KEY_NPAGE
, move_nextp
},
923 { KEY_PPAGE
, move_prevp
},
924 { XCTRL('v'), move_nextp
},
925 { ALT('v'), move_prevp
},
926 { XCTRL('p'), move_up
},
927 { XCTRL('p'), move_down
},
928 { XCTRL('s'), tree_start_search
},
929 { ALT('s'), tree_start_search
},
930 { XCTRL('r'), tree_rescan_cmd
},
931 { KEY_DC
, tree_rmdir_cmd
},
936 tree_key (WTree
*tree
, int key
)
940 for (i
= 0; tree_keymap
[i
].key_code
; i
++){
941 if (key
== tree_keymap
[i
].key_code
){
942 if (tree_keymap
[i
].fn
!= tree_start_search
)
944 (*tree_keymap
[i
].fn
)(tree
);
950 /* We do not want to use them if we do not need to */
951 /* Input line may want to take the motion key event */
953 return move_left (tree
);
955 if (key
== KEY_RIGHT
)
956 return move_right (tree
);
958 if (is_abort_char (key
)) {
959 if (tree
->is_panel
) {
962 return 1; /* eat abort char */
964 return 0; /* modal tree dialog: let upper layer see the
965 abort character and close the dialog */
968 /* Do not eat characters not meant for the tree below ' ' (e.g. C-l). */
969 if ((key
>= ' '&& key
<= 255) || key
== 8 || key
== KEY_BACKSPACE
) {
970 if (tree
->searching
){
971 tree_do_search (tree
, key
);
976 if (!command_prompt
) {
977 tree_start_search (tree
);
978 tree_do_search (tree
, key
);
981 return tree
->is_panel
;
988 tree_frame (Dlg_head
*h
, WTree
*tree
)
990 attrset (NORMAL_COLOR
);
991 widget_erase ((Widget
*) tree
);
993 draw_double_box (h
, tree
->widget
.y
, tree
->widget
.x
, tree
->widget
.lines
,
996 if (show_mini_info
&& tree
->is_panel
){
997 widget_move (tree
, tlines (tree
) + 1, 1);
998 hline (ACS_HLINE
, tree
->widget
.cols
- 2);
1004 tree_callback (Dlg_head
*h
, WTree
*tree
, int msg
, int par
)
1008 tree_frame (h
, tree
);
1013 return tree_key (tree
, par
);
1017 define_label (h
, (Widget
*)tree
, 1, _("Help"), (voidfn
) tree_help_cmd
);
1018 define_label_data (h
, (Widget
*)tree
,
1019 2, _("Rescan"), (buttonbarfn
)tree_rescan_cmd
, tree
);
1020 define_label_data (h
, (Widget
*)tree
,
1021 3, _("Forget"), (buttonbarfn
)tree_forget_cmd
, tree
);
1022 define_label_data (h
, (Widget
*)tree
,
1023 5, _("Copy"), (buttonbarfn
) tree_copy_cmd
, tree
);
1024 define_label_data (h
, (Widget
*)tree
,
1025 6, _("RenMov"), (buttonbarfn
) tree_move_cmd
, tree
);
1027 /* FIXME: mkdir is currently defunct */
1028 define_label_data (h
, (Widget
*)tree
,
1029 7, _("Mkdir"), (buttonbarfn
) tree_mkdir_cmd
, tree
);
1031 define_label (h
, (Widget
*)tree
, 7, "", 0);
1033 define_label_data (h
, (Widget
*)tree
,
1034 8, _("Rmdir"), (buttonbarfn
) tree_rmdir_cmd
, tree
);
1035 set_navig_label (tree
);
1036 redraw_labels (h
, (Widget
*)tree
);
1039 /* FIXME: Should find a better way of only displaying the
1040 currently selected item */
1044 /* FIXME: Should find a better way of changing the color of the
1046 case WIDGET_UNFOCUS
:
1051 return default_proc (h
, msg
, par
);
1055 tree_new (int is_panel
, int y
, int x
, int lines
, int cols
)
1057 WTree
*tree
= g_new (WTree
, 1);
1059 init_widget (&tree
->widget
, y
, x
, lines
, cols
, tcallback
,
1060 (destroy_fn
) tree_destroy
, (mouse_h
) event_callback
, NULL
);
1061 tree
->is_panel
= is_panel
;
1062 tree
->selected_ptr
= 0;
1064 tree
->store
= tree_store_get ();
1065 tree_store_add_entry_remove_hook (remove_callback
, tree
);
1066 tree
->tree_shown
= 0;
1067 tree
->search_buffer
[0] = 0;
1068 tree
->topdiff
= tree
->widget
.lines
/ 2;
1069 tree
->searching
= 0;
1073 /* We do not want to keep the cursor */
1074 widget_want_cursor (tree
->widget
, 0);