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 #define TREE_NORMALC HOT_FOCUSC
56 /* Specifies the display mode: 1d or 2d */
57 int tree_navigation_flag
;
60 static void save_tree (WTree
*tree
);
61 static void tree_rescan_cmd (WTree
*tree
);
62 static int tree_callback (Dlg_head
*h
, WTree
*tree
, int msg
, int par
);
63 #define tcallback (callback_fn) tree_callback
67 static tree_entry
*back_ptr (tree_entry
*ptr
, int *count
)
71 while (ptr
&& ptr
->prev
&& i
< *count
){
79 static tree_entry
*forw_ptr (tree_entry
*ptr
, int *count
)
83 while (ptr
&& ptr
->next
&& i
< *count
){
92 /* Add a directory to the list of directories */
93 static tree_entry
*tree_add_entry (WTree
*tree
, char *name
)
98 return tree_store_add_entry (name
);
101 /* Append a directory to the list of directories */
102 static tree_entry
*tree_append_entry (WTree
*tree
, char *name
)
104 tree_entry
*current
, *new;
108 /* We assume the directory is not yet in the list */
110 new = g_new (tree_entry
, 1);
111 if (!tree
->store
->tree_first
){
113 tree
->store
->tree_first
= new;
116 tree
->tree_last
->next
= new;
117 new->prev
= tree
->tree_last
;
120 tree
->store
->tree_last
= new;
122 /* Calculate attributes */
123 new->name
= g_strdup (name
);
124 len
= strlen (new->name
);
126 for (i
= 0; i
< len
; i
++)
127 if (new->name
[i
] == PATH_SEP
){
129 new->subname
= new->name
+ i
+ 1;
131 submask
= 1 << new->sublevel
;
132 submask
&= (2 << new->sublevel
) - 1;
133 new->submask
= submask
;
136 /* Correct the submasks of the previous entries */
138 while (current
&& current
->sublevel
> new->sublevel
){
139 current
->submask
|= 1 << new->sublevel
;
140 current
= current
->prev
;
143 /* The entry has now been appended */
149 remove_callback (tree_entry
*entry
, void *data
)
153 if (tree
->selected_ptr
== entry
){
154 if (tree
->selected_ptr
->next
)
155 tree
->selected_ptr
= tree
->selected_ptr
->next
;
157 tree
->selected_ptr
= tree
->selected_ptr
->prev
;
161 static void tree_remove_entry (WTree
*tree
, char *name
)
163 tree_store_remove_entry (name
);
166 static void tree_destroy (WTree
*tree
)
168 tree_store_remove_entry_remove_hook (remove_callback
);
171 if (tree
->tree_shown
){
172 g_free (tree
->tree_shown
);
173 tree
->tree_shown
= 0;
175 tree
->selected_ptr
= NULL
;
178 /* Loads the .mc.tree file */
179 static void load_tree (WTree
*tree
)
183 tree
->selected_ptr
= tree
->store
->tree_first
;
184 tree_chdir (tree
, home_dir
);
187 /* Save the .mc.tree file */
188 static void save_tree (WTree
*tree
)
192 error
= tree_store_save ();
195 fprintf (stderr
, _("Cannot open the %s file for writing:\n%s\n"), MC_TREE
,
196 unix_error_string (error
));
201 static void tree_show_mini_info (WTree
*tree
, int tree_lines
, int tree_cols
)
203 Dlg_head
*h
= tree
->widget
.parent
;
214 widget_move (&tree
->widget
, line
, 1);
215 hline (' ', tree_cols
);
216 widget_move (&tree
->widget
, line
, 1);
218 if (tree
->searching
){
219 /* Show search string */
220 attrset (TREE_NORMALC
);
224 addstr (name_trunc (tree
->search_buffer
, tree_cols
-2));
228 /* Show full name of selected directory */
229 addstr (name_trunc (tree
->selected_ptr
->name
, tree_cols
));
233 static void show_tree (WTree
*tree
)
235 Dlg_head
*h
= tree
->widget
.parent
;
237 int i
, j
, topsublevel
;
239 int tree_lines
, tree_cols
;
243 tree_lines
= tlines (tree
);
244 tree_cols
= tree
->widget
.cols
;
246 attrset (TREE_NORMALC
);
247 widget_move ((Widget
*)tree
, y
, x
);
253 if (tree
->tree_shown
)
254 g_free (tree
->tree_shown
);
255 tree
->tree_shown
= g_new (tree_entry
*, tree_lines
);
257 for (i
= 0; i
< tree_lines
; i
++)
258 tree
->tree_shown
[i
] = NULL
;
259 if (tree
->store
->tree_first
)
260 topsublevel
= tree
->store
->tree_first
->sublevel
;
263 if (!tree
->selected_ptr
){
264 tree
->selected_ptr
= tree
->store
->tree_first
;
267 current
= tree
->selected_ptr
;
269 /* Calculate the directory which is to be shown on the topmost line */
270 if (tree_navigation_flag
){
272 while (current
->prev
&& i
< tree
->topdiff
){
273 current
= current
->prev
;
274 if (current
->sublevel
< tree
->selected_ptr
->sublevel
){
275 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
276 strlen (current
->name
)) == 0)
278 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
279 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
280 if (strncmp (current
->name
, tree
->selected_ptr
->name
, j
) == 0)
282 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+ 1
283 && strlen (tree
->selected_ptr
->name
) > 1){
284 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
285 strlen (tree
->selected_ptr
->name
)) == 0)
291 current
= back_ptr (current
, &tree
->topdiff
);
293 /* Loop for every line */
294 for (i
= 0; i
< tree_lines
; i
++){
295 /* Move to the beginning of the line */
296 widget_move (&tree
->widget
, y
+i
, x
);
298 hline (' ', tree_cols
);
299 widget_move (&tree
->widget
, y
+i
, x
);
304 tree
->tree_shown
[i
] = current
;
305 if (current
->sublevel
== topsublevel
){
307 /* Top level directory */
308 if (tree
->active
&& current
== tree
->selected_ptr
) {
309 if (!use_colors
&& !tree
->is_panel
)
310 attrset (MARKED_COLOR
);
312 attrset (SELECTED_COLOR
);
316 addstr (name_trunc (current
->name
, tree_cols
- 6));
318 /* Sub level directory */
321 /* Output branch parts */
322 for (j
= 0; j
< current
->sublevel
- topsublevel
- 1; j
++){
323 if (tree_cols
- 8 - 3 * j
< 9)
326 if (current
->submask
& (1 << (j
+ topsublevel
+ 1)))
333 if (!current
->next
|| !(current
->next
->submask
& (1 << current
->sublevel
)))
334 addch (ACS_LLCORNER
);
340 if (tree
->active
&& current
== tree
->selected_ptr
) {
341 /* Selected directory -> change color */
342 if (!use_colors
&& !tree
->is_panel
)
343 attrset (MARKED_COLOR
);
345 attrset (SELECTED_COLOR
);
350 addstr (name_trunc (current
->subname
,
351 tree_cols
- 2 - 4 - 3 * j
));
355 /* Return to normal color */
356 attrset (TREE_NORMALC
);
358 /* Calculate the next value for current */
359 current
= current
->next
;
360 if (tree_navigation_flag
){
362 if (current
->sublevel
< tree
->selected_ptr
->sublevel
){
363 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
364 strlen (current
->name
)) == 0)
366 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
367 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
368 if (strncmp (current
->name
,tree
->selected_ptr
->name
,j
)== 0)
370 } else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+1
371 && strlen (tree
->selected_ptr
->name
) > 1){
372 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
373 strlen (tree
->selected_ptr
->name
)) == 0)
376 current
= current
->next
;
380 tree_show_mini_info (tree
, tree_lines
, tree_cols
);
383 static void check_focus (WTree
*tree
)
385 if (tree
->topdiff
< 3)
387 else if (tree
->topdiff
>= tlines (tree
) - 3)
388 tree
->topdiff
= tlines (tree
) - 3 - 1;
391 static void tree_move_backward (WTree
*tree
, int i
)
396 if (tree_navigation_flag
){
397 current
= tree
->selected_ptr
;
398 while (j
< i
&& current
->prev
399 && current
->prev
->sublevel
>= tree
->selected_ptr
->sublevel
){
400 current
= current
->prev
;
401 if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
402 tree
->selected_ptr
= current
;
408 tree
->selected_ptr
= back_ptr (tree
->selected_ptr
, &i
);
413 static void tree_move_forward (WTree
*tree
, int i
)
418 if (tree_navigation_flag
){
419 current
= tree
->selected_ptr
;
420 while (j
< i
&& current
->next
421 && current
->next
->sublevel
>= tree
->selected_ptr
->sublevel
){
422 current
= current
->next
;
423 if (current
->sublevel
== tree
->selected_ptr
->sublevel
){
424 tree
->selected_ptr
= current
;
430 tree
->selected_ptr
= forw_ptr (tree
->selected_ptr
, &i
);
435 static void tree_move_to_child (WTree
*tree
)
439 /* Do we have a starting point? */
440 if (!tree
->selected_ptr
)
442 /* Take the next entry */
443 current
= tree
->selected_ptr
->next
;
444 /* Is it the child of the selected entry */
445 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
){
446 /* Yes -> select this entry */
447 tree
->selected_ptr
= current
;
451 /* No -> rescan and try again */
452 tree_rescan_cmd (tree
);
453 current
= tree
->selected_ptr
->next
;
454 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
){
455 tree
->selected_ptr
= current
;
462 static int tree_move_to_parent (WTree
*tree
)
467 if (!tree
->selected_ptr
)
469 old
= tree
->selected_ptr
;
470 current
= tree
->selected_ptr
->prev
;
471 while (current
&& current
->sublevel
>= tree
->selected_ptr
->sublevel
){
472 current
= current
->prev
;
476 current
= tree
->store
->tree_first
;
477 tree
->selected_ptr
= current
;
479 return tree
->selected_ptr
!= old
;
482 static void tree_move_to_top (WTree
*tree
)
484 tree
->selected_ptr
= tree
->store
->tree_first
;
488 static void tree_move_to_bottom (WTree
*tree
)
490 tree
->selected_ptr
= tree
->store
->tree_last
;
491 tree
->topdiff
= tlines (tree
) - 3 - 1;
494 void tree_chdir (WTree
*tree
, char *dir
)
498 current
= tree_store_whereis (dir
);
500 tree
->selected_ptr
= current
;
506 sync_tree (char *path
)
508 tree_chdir (the_tree
, path
);
511 /* Handle mouse click */
512 static void tree_event (WTree
*tree
, int y
)
514 if (tree
->tree_shown
[y
]){
515 tree
->selected_ptr
= tree
->tree_shown
[y
];
521 static void chdir_sel (WTree
*tree
);
523 static void maybe_chdir (WTree
*tree
)
525 if (!(xtree_mode
&& tree
->is_panel
))
532 static int event_callback (Gpm_Event
*event
, WTree
*tree
)
534 if (!(event
->type
& GPM_UP
))
546 tree_move_backward (tree
, tlines (tree
) - 1);
549 else if (event
->y
>= tlines (tree
)){
550 tree_move_forward (tree
, tlines (tree
) - 1);
553 tree_event (tree
, event
->y
);
554 if ((event
->type
& (GPM_UP
|GPM_DOUBLE
)) == (GPM_UP
|GPM_DOUBLE
)){
561 /* Search tree for text */
562 static int search_tree (WTree
*tree
, char *text
)
570 current
= tree
->selected_ptr
;
572 while (!wrapped
|| current
!= tree
->selected_ptr
){
573 if (strncmp (current
->subname
, text
, len
) == 0){
574 tree
->selected_ptr
= current
;
578 current
= current
->next
;
580 current
= tree
->store
->tree_first
;
589 static void tree_do_search (WTree
*tree
, int key
)
593 l
= strlen (tree
->search_buffer
);
594 if (l
&& (key
== 8 || key
== 0177 || key
== KEY_BACKSPACE
))
595 tree
->search_buffer
[--l
] = 0;
597 if (key
&& l
< sizeof (tree
->search_buffer
)){
598 tree
->search_buffer
[l
] = key
;
599 tree
->search_buffer
[l
+1] = 0;
604 if (!search_tree (tree
, tree
->search_buffer
))
605 tree
->search_buffer
[--l
] = 0;
611 static void tree_rescan_cmd (WTree
*tree
)
613 char old_dir
[MC_MAXPATHLEN
];
615 if (!tree
->selected_ptr
|| !mc_get_current_wd (old_dir
, MC_MAXPATHLEN
) ||
616 mc_chdir (tree
->selected_ptr
->name
))
619 tree_store_rescan (tree
->selected_ptr
->name
);
623 static int tree_forget_cmd (WTree
*tree
)
625 if (tree
->selected_ptr
)
626 tree_remove_entry (tree
, tree
->selected_ptr
->name
);
630 static void tree_copy (WTree
*tree
, char *default_dest
)
637 if (!tree
->selected_ptr
)
639 g_snprintf (cmd_buf
, sizeof(cmd_buf
), _("Copy \"%s\" directory to:"),
640 name_trunc (tree
->selected_ptr
->name
, 50));
641 dest
= input_expand_dialog (_(" Copy "), cmd_buf
, default_dest
);
651 ctx
= file_op_context_new ();
652 file_op_context_create_ui (ctx
, OP_COPY
, FALSE
);
653 copy_dir_dir (ctx
, tree
->selected_ptr
->name
, dest
, 1, 0, 0, 0, &count
, &bytes
);
654 file_op_context_destroy (ctx
);
659 static void tree_help_cmd (void)
661 interactive_display (NULL
, "[Directory Tree]");
664 static int tree_copy_cmd (WTree
*tree
)
666 tree_copy (tree
, "");
670 static void tree_move (WTree
*tree
, char *default_dest
)
678 if (!tree
->selected_ptr
)
680 g_snprintf (cmd_buf
, sizeof (cmd_buf
), _("Move \"%s\" directory to:"),
681 name_trunc (tree
->selected_ptr
->name
, 50));
682 dest
= input_expand_dialog (_(" Move "), cmd_buf
, default_dest
);
689 if (stat (dest
, &buf
)){
690 message (1, MSG_ERROR
, _(" Cannot stat the destination \n %s "),
691 unix_error_string (errno
));
695 if (!S_ISDIR (buf
.st_mode
)){
696 message (1, MSG_ERROR
, _(" The destination isn't a directory "));
701 ctx
= file_op_context_new ();
702 file_op_context_create_ui (ctx
, OP_MOVE
, FALSE
);
703 move_dir_dir (ctx
, tree
->selected_ptr
->name
, dest
, &count
, &bytes
);
704 file_op_context_destroy (ctx
);
710 tree_move_cmd (WTree
*tree
)
712 tree_move (tree
, "");
718 tree_mkdir_cmd (WTree
*tree
)
720 char old_dir
[MC_MAXPATHLEN
];
722 if (!tree
->selected_ptr
)
724 if (!mc_get_current_wd (old_dir
, MC_MAXPATHLEN
))
726 if (chdir (tree
->selected_ptr
->name
))
731 tree_rescan_cmd (tree
);
738 tree_rmdir_cmd (WTree
*tree
)
740 char old_dir
[MC_MAXPATHLEN
];
745 if (tree
->selected_ptr
){
746 if (!mc_get_current_wd (old_dir
, MC_MAXPATHLEN
))
748 if (mc_chdir (PATH_SEP_STR
))
754 buf
= g_strdup_printf (_(" Delete %s? "), tree
->selected_ptr
->name
);
755 result
= query_dialog (_(" Delete "), buf
, 3, 2, _("&Yes"), _("&No"));
762 ctx
= file_op_context_new ();
763 file_op_context_create_ui (ctx
, OP_DELETE
, FALSE
);
764 if (erase_dir (ctx
, tree
->selected_ptr
->name
, &count
, &bytes
) == FILE_CONT
)
765 tree_forget_cmd (tree
);
766 file_op_context_destroy (ctx
);
773 static void set_navig_label (WTree
*tree
);
776 tree_toggle_navig (WTree
*tree
)
778 tree_navigation_flag
= 1 - tree_navigation_flag
;
779 set_navig_label (tree
);
783 set_navig_label (WTree
*tree
)
785 define_label_data (tree
->widget
.parent
, (Widget
*) tree
,
786 4, tree_navigation_flag
? _("Static") : _("Dynamc"),
787 (buttonbarfn
) tree_toggle_navig
, tree
);
791 move_down (WTree
*tree
)
793 tree_move_forward (tree
, 1);
799 move_up (WTree
*tree
)
801 tree_move_backward (tree
, 1);
807 move_home (WTree
*tree
)
809 tree_move_to_top (tree
);
815 move_end (WTree
*tree
)
817 tree_move_to_bottom (tree
);
823 move_left (WTree
*tree
)
827 if (tree_navigation_flag
){
828 v
= tree_move_to_parent (tree
);
837 move_right (WTree
*tree
)
839 if (tree_navigation_flag
){
840 tree_move_to_child (tree
);
849 move_prevp (WTree
*tree
)
851 tree_move_backward (tree
, tlines (tree
) - 1);
857 move_nextp (WTree
*tree
)
859 tree_move_forward (tree
, tlines (tree
) - 1);
865 chdir_sel (WTree
*tree
)
867 if (!tree
->is_panel
){
872 if (do_cd (tree
->selected_ptr
->name
, cd_exact
)){
873 paint_panel (cpanel
);
874 select_item (cpanel
);
876 message (1, MSG_ERROR
, _(" Cannot chdir to \"%s\" \n %s "),
877 tree
->selected_ptr
->name
, unix_error_string (errno
));
885 tree_start_search (WTree
*tree
)
889 if (tree
->searching
){
891 if (tree
->selected_ptr
== tree
->store
->tree_last
)
892 tree_move_to_top(tree
);
894 /* set navigation mode temporarily to 'Static' because in
895 * dynamic navigation mode tree_move_forward will not move
896 * to a lower sublevel if necessary (sequent searches must
897 * start with the directory followed the last found directory)
899 i
= tree_navigation_flag
;
900 tree_navigation_flag
= 0;
901 tree_move_forward (tree
, 1);
902 tree_navigation_flag
= i
;
904 tree_do_search (tree
, 0);
908 tree
->search_buffer
[0] = 0;
912 static const key_map tree_keymap
[] = {
913 { XCTRL('n'), move_down
},
914 { XCTRL('p'), move_up
},
915 { KEY_DOWN
, move_down
},
918 { KEY_ENTER
, chdir_sel
},
919 { KEY_HOME
, move_home
},
920 { KEY_C1
, move_end
},
921 { KEY_END
, move_end
},
922 { KEY_A1
, move_home
},
923 { KEY_NPAGE
, move_nextp
},
924 { KEY_PPAGE
, move_prevp
},
925 { XCTRL('v'), move_nextp
},
926 { ALT('v'), move_prevp
},
927 { XCTRL('p'), move_up
},
928 { XCTRL('p'), move_down
},
929 { XCTRL('s'), tree_start_search
},
930 { ALT('s'), tree_start_search
},
931 { XCTRL('r'), tree_rescan_cmd
},
932 { KEY_DC
, tree_rmdir_cmd
},
937 tree_key (WTree
*tree
, int key
)
941 for (i
= 0; tree_keymap
[i
].key_code
; i
++){
942 if (key
== tree_keymap
[i
].key_code
){
943 if (tree_keymap
[i
].fn
!= tree_start_search
)
945 (*tree_keymap
[i
].fn
)(tree
);
951 /* We do not want to use them if we do not need to */
952 /* Input line may want to take the motion key event */
954 return move_left (tree
);
956 if (key
== KEY_RIGHT
)
957 return move_right (tree
);
959 if (is_abort_char (key
)) {
960 if (tree
->is_panel
) {
963 return 1; /* eat abort char */
965 return 0; /* modal tree dialog: let upper layer see the
966 abort character and close the dialog */
969 /* Do not eat characters not meant for the tree below ' ' (e.g. C-l). */
970 if ((key
>= ' '&& key
<= 255) || key
== 8 || key
== KEY_BACKSPACE
) {
971 if (tree
->searching
){
972 tree_do_search (tree
, key
);
977 if (!command_prompt
) {
978 tree_start_search (tree
);
979 tree_do_search (tree
, key
);
982 return tree
->is_panel
;
989 tree_frame (Dlg_head
*h
, WTree
*tree
)
991 attrset (NORMAL_COLOR
);
992 widget_erase ((Widget
*) tree
);
994 draw_double_box (h
, tree
->widget
.y
, tree
->widget
.x
, tree
->widget
.lines
,
997 if (show_mini_info
&& tree
->is_panel
){
998 widget_move (tree
, tlines (tree
) + 1, 1);
999 hline (ACS_HLINE
, tree
->widget
.cols
- 2);
1005 tree_callback (Dlg_head
*h
, WTree
*tree
, int msg
, int par
)
1009 tree_frame (h
, tree
);
1014 return tree_key (tree
, par
);
1018 define_label (h
, (Widget
*)tree
, 1, _("Help"), (voidfn
) tree_help_cmd
);
1019 define_label_data (h
, (Widget
*)tree
,
1020 2, _("Rescan"), (buttonbarfn
)tree_rescan_cmd
, tree
);
1021 define_label_data (h
, (Widget
*)tree
,
1022 3, _("Forget"), (buttonbarfn
)tree_forget_cmd
, tree
);
1023 define_label_data (h
, (Widget
*)tree
,
1024 5, _("Copy"), (buttonbarfn
) tree_copy_cmd
, tree
);
1025 define_label_data (h
, (Widget
*)tree
,
1026 6, _("RenMov"), (buttonbarfn
) tree_move_cmd
, tree
);
1028 /* FIXME: mkdir is currently defunct */
1029 define_label_data (h
, (Widget
*)tree
,
1030 7, _("Mkdir"), (buttonbarfn
) tree_mkdir_cmd
, tree
);
1032 define_label (h
, (Widget
*)tree
, 7, "", 0);
1034 define_label_data (h
, (Widget
*)tree
,
1035 8, _("Rmdir"), (buttonbarfn
) tree_rmdir_cmd
, tree
);
1036 set_navig_label (tree
);
1037 redraw_labels (h
, (Widget
*)tree
);
1040 /* FIXME: Should find a better way of only displaying the
1041 currently selected item */
1045 /* FIXME: Should find a better way of changing the color of the
1047 case WIDGET_UNFOCUS
:
1052 return default_proc (h
, msg
, par
);
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
, tcallback
,
1061 (destroy_fn
) tree_destroy
, (mouse_h
) event_callback
, NULL
);
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;
1074 /* We do not want to keep the cursor */
1075 widget_want_cursor (tree
->widget
, 0);