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.
32 * \brief Source: directory tree browser
40 #include <sys/types.h>
42 #include "lib/global.h"
44 #include "lib/tty/tty.h"
46 #include "lib/tty/mouse.h"
47 #include "lib/tty/key.h"
48 #include "lib/vfs/mc-vfs/vfs.h"
49 #include "lib/fileloc.h"
50 #include "lib/strutil.h"
52 #include "wtools.h" /* message() */
58 #include "main-widgets.h" /* the_menubar */
59 #include "menu.h" /* menubar_visible */
60 #include "file.h" /* copy_dir_dir(), move_dir_dir(), erase_dir() */
61 #include "layout.h" /* command_prompt */
63 #include "treestore.h"
71 const global_keymap_t
*tree_map
;
73 #define tlines(t) (t->is_panel ? t->widget.lines - 2 - (show_mini_info ? 2 : 0) : t->widget.lines)
75 /* Use the color of the parent widget for the unselected entries */
76 #define TREE_NORMALC(h) (DLG_NORMALC (h))
78 /* Specifies the display mode: 1d or 2d */
79 static gboolean tree_navigation_flag
= FALSE
;
84 struct TreeStore
*store
;
85 tree_entry
*selected_ptr
; /* The selected directory */
86 char search_buffer
[256]; /* Current search string */
87 tree_entry
**tree_shown
; /* Entries currently on screen */
88 int is_panel
; /* panel or plain widget flag */
89 int active
; /* if it's currently selected */
90 int searching
; /* Are we on searching mode? */
91 int topdiff
; /* The difference between the topmost
92 shown and the selected */
96 static void tree_rescan (void *data
);
99 back_ptr (tree_entry
* ptr
, int *count
)
103 while (ptr
&& ptr
->prev
&& i
< *count
)
113 forw_ptr (tree_entry
* ptr
, int *count
)
117 while (ptr
&& ptr
->next
&& i
< *count
)
127 remove_callback (tree_entry
* entry
, void *data
)
131 if (tree
->selected_ptr
== entry
)
133 if (tree
->selected_ptr
->next
)
134 tree
->selected_ptr
= tree
->selected_ptr
->next
;
136 tree
->selected_ptr
= tree
->selected_ptr
->prev
;
140 /* Save the ~/.mc/Tree file */
142 save_tree (WTree
* tree
)
148 error
= tree_store_save ();
153 tree_name
= g_build_filename (home_dir
, MC_USERCONF_DIR
, MC_TREESTORE_FILE
, (char *) NULL
);
154 fprintf (stderr
, _("Cannot open the %s file for writing:\n%s\n"), tree_name
,
155 unix_error_string (error
));
161 tree_remove_entry (WTree
* tree
, char *name
)
164 tree_store_remove_entry (name
);
168 tree_destroy (WTree
* tree
)
170 tree_store_remove_entry_remove_hook (remove_callback
);
173 g_free (tree
->tree_shown
);
174 tree
->tree_shown
= 0;
175 tree
->selected_ptr
= NULL
;
178 /* Loads the .mc.tree file */
180 load_tree (WTree
* tree
)
184 tree
->selected_ptr
= tree
->store
->tree_first
;
185 tree_chdir (tree
, home_dir
);
189 tree_show_mini_info (WTree
* tree
, int tree_lines
, int tree_cols
)
191 Dlg_head
*h
= tree
->widget
.parent
;
199 line
= tree_lines
+ 2;
202 line
= tree_lines
+ 1;
204 tty_draw_hline (tree
->widget
.y
+ line
, tree
->widget
.x
+ 1, ' ', tree_cols
);
205 widget_move (&tree
->widget
, line
, 1);
209 /* Show search string */
210 tty_setcolor (TREE_NORMALC (h
));
211 tty_setcolor (DLG_FOCUSC (h
));
212 tty_print_char (PATH_SEP
);
214 tty_print_string (str_fit_to_term (tree
->search_buffer
, tree_cols
- 2, J_LEFT_FIT
));
215 tty_print_char (' ');
216 tty_setcolor (DLG_FOCUSC (h
));
220 /* Show full name of selected directory */
221 tty_print_string (str_fit_to_term (tree
->selected_ptr
->name
, tree_cols
, J_LEFT_FIT
));
226 show_tree (WTree
* tree
)
228 Dlg_head
*h
= tree
->widget
.parent
;
230 int i
, j
, topsublevel
;
232 int tree_lines
, tree_cols
;
236 tree_lines
= tlines (tree
);
237 tree_cols
= tree
->widget
.cols
;
239 tty_setcolor (TREE_NORMALC (h
));
240 widget_move ((Widget
*) tree
, y
, x
);
247 g_free (tree
->tree_shown
);
248 tree
->tree_shown
= g_new0 (tree_entry
*, tree_lines
);
250 if (tree
->store
->tree_first
)
251 topsublevel
= tree
->store
->tree_first
->sublevel
;
254 if (!tree
->selected_ptr
)
256 tree
->selected_ptr
= tree
->store
->tree_first
;
259 current
= tree
->selected_ptr
;
261 /* Calculate the directory which is to be shown on the topmost line */
262 if (!tree_navigation_flag
)
263 current
= back_ptr (current
, &tree
->topdiff
);
267 while (current
->prev
&& i
< tree
->topdiff
)
269 current
= current
->prev
;
270 if (current
->sublevel
< tree
->selected_ptr
->sublevel
)
272 if (strncmp (current
->name
, tree
->selected_ptr
->name
, strlen (current
->name
)) == 0)
275 else if (current
->sublevel
== tree
->selected_ptr
->sublevel
)
277 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
278 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)
284 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
285 strlen (tree
->selected_ptr
->name
)) == 0)
292 /* Loop for every line */
293 for (i
= 0; i
< tree_lines
; i
++)
295 /* Move to the beginning of the line */
296 tty_draw_hline (tree
->widget
.y
+ y
+ i
, tree
->widget
.x
+ x
, ' ', tree_cols
);
301 tree
->tree_shown
[i
] = current
;
302 if (current
->sublevel
== topsublevel
)
305 /* Top level directory */
306 if (tree
->active
&& current
== tree
->selected_ptr
)
308 if (!tty_use_colors () && !tree
->is_panel
)
309 tty_setcolor (MARKED_COLOR
);
311 tty_setcolor (SELECTED_COLOR
);
315 tty_print_string (str_fit_to_term (current
->name
, tree_cols
- 6, J_LEFT_FIT
));
319 /* Sub level directory */
321 tty_set_alt_charset (TRUE
);
322 /* Output branch parts */
323 for (j
= 0; j
< current
->sublevel
- topsublevel
- 1; j
++)
325 if (tree_cols
- 8 - 3 * j
< 9)
327 tty_print_char (' ');
328 if (current
->submask
& (1 << (j
+ topsublevel
+ 1)))
329 tty_print_char (ACS_VLINE
);
331 tty_print_char (' ');
332 tty_print_char (' ');
334 tty_print_char (' ');
336 if (!current
->next
|| !(current
->next
->submask
& (1 << current
->sublevel
)))
337 tty_print_char (ACS_LLCORNER
);
339 tty_print_char (ACS_LTEE
);
340 tty_print_char (ACS_HLINE
);
341 tty_set_alt_charset (FALSE
);
343 if (tree
->active
&& current
== tree
->selected_ptr
)
345 /* Selected directory -> change color */
346 if (!tty_use_colors () && !tree
->is_panel
)
347 tty_setcolor (MARKED_COLOR
);
349 tty_setcolor (SELECTED_COLOR
);
353 tty_print_char (' ');
354 tty_print_string (str_fit_to_term (current
->subname
,
355 tree_cols
- 2 - 4 - 3 * j
, J_LEFT_FIT
));
357 tty_print_char (' ');
359 /* Return to normal color */
360 tty_setcolor (TREE_NORMALC (h
));
362 /* Calculate the next value for current */
363 current
= current
->next
;
364 if (tree_navigation_flag
)
368 if (current
->sublevel
< tree
->selected_ptr
->sublevel
)
370 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
371 strlen (current
->name
)) == 0)
374 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)
380 else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+ 1
381 && strlen (tree
->selected_ptr
->name
) > 1)
383 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
384 strlen (tree
->selected_ptr
->name
)) == 0)
387 current
= current
->next
;
391 tree_show_mini_info (tree
, tree_lines
, tree_cols
);
395 tree_check_focus (WTree
* tree
)
397 if (tree
->topdiff
< 3)
399 else if (tree
->topdiff
>= tlines (tree
) - 3)
400 tree
->topdiff
= tlines (tree
) - 3 - 1;
404 tree_move_backward (WTree
* tree
, int i
)
406 if (!tree_navigation_flag
)
407 tree
->selected_ptr
= back_ptr (tree
->selected_ptr
, &i
);
413 current
= tree
->selected_ptr
;
414 while (j
< i
&& current
->prev
&& current
->prev
->sublevel
>= tree
->selected_ptr
->sublevel
)
416 current
= current
->prev
;
417 if (current
->sublevel
== tree
->selected_ptr
->sublevel
)
419 tree
->selected_ptr
= current
;
427 tree_check_focus (tree
);
431 tree_move_forward (WTree
* tree
, int i
)
433 if (!tree_navigation_flag
)
434 tree
->selected_ptr
= forw_ptr (tree
->selected_ptr
, &i
);
440 current
= tree
->selected_ptr
;
441 while (j
< i
&& current
->next
&& current
->next
->sublevel
>= tree
->selected_ptr
->sublevel
)
443 current
= current
->next
;
444 if (current
->sublevel
== tree
->selected_ptr
->sublevel
)
446 tree
->selected_ptr
= current
;
454 tree_check_focus (tree
);
458 tree_move_to_child (WTree
* tree
)
462 /* Do we have a starting point? */
463 if (!tree
->selected_ptr
)
465 /* Take the next entry */
466 current
= tree
->selected_ptr
->next
;
467 /* Is it the child of the selected entry */
468 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
)
470 /* Yes -> select this entry */
471 tree
->selected_ptr
= current
;
473 tree_check_focus (tree
);
477 /* No -> rescan and try again */
479 current
= tree
->selected_ptr
->next
;
480 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
)
482 tree
->selected_ptr
= current
;
484 tree_check_focus (tree
);
490 tree_move_to_parent (WTree
* tree
)
495 if (!tree
->selected_ptr
)
498 old
= tree
->selected_ptr
;
499 current
= tree
->selected_ptr
->prev
;
500 while (current
&& current
->sublevel
>= tree
->selected_ptr
->sublevel
)
502 current
= current
->prev
;
506 current
= tree
->store
->tree_first
;
507 tree
->selected_ptr
= current
;
508 tree_check_focus (tree
);
509 return tree
->selected_ptr
!= old
;
513 tree_move_to_top (WTree
* tree
)
515 tree
->selected_ptr
= tree
->store
->tree_first
;
520 tree_move_to_bottom (WTree
* tree
)
522 tree
->selected_ptr
= tree
->store
->tree_last
;
523 tree
->topdiff
= tlines (tree
) - 3 - 1;
526 /* Handle mouse click */
528 tree_event (WTree
* tree
, int y
)
530 if (tree
->tree_shown
[y
])
532 tree
->selected_ptr
= tree
->tree_shown
[y
];
539 tree_chdir_sel (WTree
* tree
)
546 if (do_cd (tree
->selected_ptr
->name
, cd_exact
))
547 select_item (current_panel
);
549 message (D_ERROR
, MSG_ERROR
, _(" Cannot chdir to \"%s\" \n %s "),
550 tree
->selected_ptr
->name
, unix_error_string (errno
));
557 maybe_chdir (WTree
* tree
)
559 if (xtree_mode
&& tree
->is_panel
&& is_idle ())
560 tree_chdir_sel (tree
);
565 event_callback (Gpm_Event
* event
, void *data
)
569 /* rest of the upper frame, the menu is invisible - call menu */
570 if (tree
->is_panel
&& (event
->type
& GPM_DOWN
) && event
->y
== 1 && !menubar_visible
)
572 event
->x
+= tree
->widget
.x
;
573 return the_menubar
->widget
.mouse (event
, the_menubar
);
576 if (!(event
->type
& GPM_UP
))
589 tree_move_backward (tree
, tlines (tree
) - 1);
592 else if (event
->y
>= tlines (tree
))
594 tree_move_forward (tree
, tlines (tree
) - 1);
599 tree_event (tree
, event
->y
);
600 if ((event
->type
& (GPM_UP
| GPM_DOUBLE
)) == (GPM_UP
| GPM_DOUBLE
))
602 tree_chdir_sel (tree
);
608 /* Search tree for text */
610 search_tree (WTree
* tree
, char *text
)
618 current
= tree
->selected_ptr
;
620 while (!wrapped
|| current
!= tree
->selected_ptr
)
622 if (strncmp (current
->subname
, text
, len
) == 0)
624 tree
->selected_ptr
= current
;
628 current
= current
->next
;
631 current
= tree
->store
->tree_first
;
636 tree_check_focus (tree
);
641 tree_do_search (WTree
* tree
, int key
)
645 l
= strlen (tree
->search_buffer
);
646 if ((l
!= 0) && (key
== KEY_BACKSPACE
))
647 tree
->search_buffer
[--l
] = '\0';
648 else if (key
&& l
< sizeof (tree
->search_buffer
))
650 tree
->search_buffer
[l
] = key
;
651 tree
->search_buffer
[++l
] = '\0';
654 if (!search_tree (tree
, tree
->search_buffer
))
655 tree
->search_buffer
[--l
] = 0;
662 tree_rescan (void *data
)
664 char old_dir
[MC_MAXPATHLEN
];
667 if (!tree
->selected_ptr
|| !mc_get_current_wd (old_dir
, MC_MAXPATHLEN
) ||
668 mc_chdir (tree
->selected_ptr
->name
))
671 tree_store_rescan (tree
->selected_ptr
->name
);
676 tree_forget (void *data
)
679 if (tree
->selected_ptr
)
680 tree_remove_entry (tree
, tree
->selected_ptr
->name
);
684 tree_copy (WTree
* tree
, const char *default_dest
)
686 char msg
[BUF_MEDIUM
];
689 if (tree
->selected_ptr
== NULL
)
692 g_snprintf (msg
, sizeof (msg
), _("Copy \"%s\" directory to:"),
693 str_trunc (tree
->selected_ptr
->name
, 50));
694 dest
= input_expand_dialog (Q_ ("DialogTitle|Copy"),
695 msg
, MC_HISTORY_FM_TREE_COPY
, default_dest
);
697 if (dest
!= NULL
&& *dest
!= '\0')
700 FileOpTotalContext
*tctx
;
702 ctx
= file_op_context_new (OP_COPY
);
703 tctx
= file_op_total_context_new ();
704 file_op_context_create_ui (ctx
, FALSE
, FILEGUI_DIALOG_MULTI_ITEM
);
705 tctx
->ask_overwrite
= FALSE
;
706 tctx
->is_toplevel_file
= FALSE
;
707 copy_dir_dir (tctx
, ctx
, tree
->selected_ptr
->name
, dest
, TRUE
, FALSE
, FALSE
, NULL
);
708 file_op_total_context_destroy (tctx
);
709 file_op_context_destroy (ctx
);
716 tree_move (WTree
* tree
, const char *default_dest
)
718 char msg
[BUF_MEDIUM
];
722 FileOpTotalContext
*tctx
;
724 if (tree
->selected_ptr
== NULL
)
727 g_snprintf (msg
, sizeof (msg
), _("Move \"%s\" directory to:"),
728 str_trunc (tree
->selected_ptr
->name
, 50));
730 input_expand_dialog (Q_ ("DialogTitle|Move"), msg
, MC_HISTORY_FM_TREE_MOVE
, default_dest
);
732 if (dest
== NULL
|| *dest
== '\0')
738 if (stat (dest
, &buf
))
740 message (D_ERROR
, MSG_ERROR
, _(" Cannot stat the destination \n %s "),
741 unix_error_string (errno
));
746 if (!S_ISDIR (buf
.st_mode
))
748 file_error (_(" Destination \"%s\" must be a directory \n %s "), dest
);
753 ctx
= file_op_context_new (OP_MOVE
);
754 tctx
= file_op_total_context_new ();
755 file_op_context_create_ui (ctx
, FALSE
, FILEGUI_DIALOG_ONE_ITEM
);
756 move_dir_dir (tctx
, ctx
, tree
->selected_ptr
->name
, dest
);
757 file_op_total_context_destroy (tctx
);
758 file_op_context_destroy (ctx
);
765 tree_mkdir (WTree
* tree
)
767 char old_dir
[MC_MAXPATHLEN
];
769 if (!tree
->selected_ptr
)
771 if (!mc_get_current_wd (old_dir
, MC_MAXPATHLEN
))
773 if (chdir (tree
->selected_ptr
->name
))
784 tree_rmdir (void *data
)
788 FileOpTotalContext
*tctx
;
790 if (!tree
->selected_ptr
)
798 buf
= g_strdup_printf (_(" Delete %s? "), tree
->selected_ptr
->name
);
799 result
= query_dialog (Q_ ("DialogTitle|Delete"), buf
, D_ERROR
, 2, _("&Yes"), _("&No"));
805 ctx
= file_op_context_new (OP_DELETE
);
806 tctx
= file_op_total_context_new ();
808 file_op_context_create_ui (ctx
, FALSE
, FILEGUI_DIALOG_ONE_ITEM
);
809 if (erase_dir (tctx
, ctx
, tree
->selected_ptr
->name
) == FILE_CONT
)
811 file_op_total_context_destroy (tctx
);
812 file_op_context_destroy (ctx
);
816 tree_move_up (WTree
* tree
)
818 tree_move_backward (tree
, 1);
824 tree_move_down (WTree
* tree
)
826 tree_move_forward (tree
, 1);
832 tree_move_home (WTree
* tree
)
834 tree_move_to_top (tree
);
840 tree_move_end (WTree
* tree
)
842 tree_move_to_bottom (tree
);
848 tree_move_pgup (WTree
* tree
)
850 tree_move_backward (tree
, tlines (tree
) - 1);
856 tree_move_pgdn (WTree
* tree
)
858 tree_move_forward (tree
, tlines (tree
) - 1);
864 tree_move_left (WTree
* tree
)
868 if (tree_navigation_flag
)
870 v
= tree_move_to_parent (tree
);
879 tree_move_right (WTree
* tree
)
883 if (tree_navigation_flag
)
885 tree_move_to_child (tree
);
895 tree_start_search (WTree
* tree
)
901 if (tree
->selected_ptr
== tree
->store
->tree_last
)
902 tree_move_to_top (tree
);
905 /* set navigation mode temporarily to 'Static' because in
906 * dynamic navigation mode tree_move_forward will not move
907 * to a lower sublevel if necessary (sequent searches must
908 * start with the directory followed the last found directory)
910 i
= tree_navigation_flag
;
911 tree_navigation_flag
= 0;
912 tree_move_forward (tree
, 1);
913 tree_navigation_flag
= i
;
915 tree_do_search (tree
, 0);
920 tree
->search_buffer
[0] = 0;
925 tree_toggle_navig (WTree
* tree
)
927 tree_navigation_flag
= !tree_navigation_flag
;
928 buttonbar_set_label (find_buttonbar (tree
->widget
.parent
), 4,
929 tree_navigation_flag
? Q_ ("ButtonBar|Static")
930 : Q_ ("ButtonBar|Dynamc"), tree_map
, (Widget
*) tree
);
934 tree_execute_cmd (WTree
* tree
, unsigned long command
)
936 cb_ret_t res
= MSG_HANDLED
;
938 if (command
!= CK_TreeStartSearch
)
944 interactive_display (NULL
, "[Directory Tree]");
949 case CK_TreeToggleNav
:
950 tree_toggle_navig (tree
);
953 tree_copy (tree
, "");
956 tree_move (tree
, "");
961 case CK_TreeMoveDown
:
962 tree_move_down (tree
);
964 case CK_TreeMoveHome
:
965 tree_move_home (tree
);
968 tree_move_end (tree
);
970 case CK_TreeMovePgUp
:
971 tree_move_pgup (tree
);
973 case CK_TreeMovePgDn
:
974 tree_move_pgdn (tree
);
977 tree_chdir_sel (tree
);
982 case CK_TreeStartSearch
:
983 tree_start_search (tree
);
989 res
= MSG_NOT_HANDLED
;
998 tree_key (WTree
* tree
, int key
)
1002 for (i
= 0; tree_map
[i
].key
!= 0; i
++)
1003 if (key
== tree_map
[i
].key
)
1004 switch (tree_map
[i
].command
)
1006 case CK_TreeMoveLeft
:
1007 return tree_move_left (tree
) ? MSG_HANDLED
: MSG_NOT_HANDLED
;
1008 case CK_TreeMoveRight
:
1009 return tree_move_right (tree
) ? MSG_HANDLED
: MSG_NOT_HANDLED
;
1011 tree_execute_cmd (tree
, tree_map
[i
].command
);
1015 if (is_abort_char (key
))
1019 tree
->searching
= 0;
1021 return MSG_HANDLED
; /* eat abort char */
1023 /* modal tree dialog: let upper layer see the
1024 abort character and close the dialog */
1025 return MSG_NOT_HANDLED
;
1028 /* Do not eat characters not meant for the tree below ' ' (e.g. C-l). */
1029 if ((key
>= ' ' && key
<= 255) || key
== KEY_BACKSPACE
)
1031 if (tree
->searching
)
1033 tree_do_search (tree
, key
);
1038 if (!command_prompt
)
1040 tree_start_search (tree
);
1041 tree_do_search (tree
, key
);
1044 return tree
->is_panel
? MSG_HANDLED
: MSG_NOT_HANDLED
;
1047 return MSG_NOT_HANDLED
;
1051 tree_frame (Dlg_head
* h
, WTree
* tree
)
1053 tty_setcolor (NORMAL_COLOR
);
1054 widget_erase ((Widget
*) tree
);
1057 draw_box (h
, tree
->widget
.y
, tree
->widget
.x
, tree
->widget
.lines
, tree
->widget
.cols
, FALSE
);
1060 tty_draw_hline (tree
->widget
.y
+ tlines (tree
) + 1,
1061 tree
->widget
.x
+ 1, ACS_HLINE
, tree
->widget
.cols
- 2);
1066 tree_callback (Widget
* w
, widget_msg_t msg
, int parm
)
1068 WTree
*tree
= (WTree
*) w
;
1069 Dlg_head
*h
= tree
->widget
.parent
;
1070 WButtonBar
*b
= find_buttonbar (h
);
1075 tree_frame (h
, tree
);
1081 buttonbar_set_label (b
, 1, Q_ ("ButtonBar|Help"), tree_map
, (Widget
*) tree
);
1082 buttonbar_set_label (b
, 2, Q_ ("ButtonBar|Rescan"), tree_map
, (Widget
*) tree
);
1083 buttonbar_set_label (b
, 3, Q_ ("ButtonBar|Forget"), tree_map
, (Widget
*) tree
);
1084 buttonbar_set_label (b
, 4, tree_navigation_flag
? Q_ ("ButtonBar|Static")
1085 : Q_ ("ButtonBar|Dynamc"), tree_map
, (Widget
*) tree
);
1086 buttonbar_set_label (b
, 5, Q_ ("ButtonBar|Copy"), tree_map
, (Widget
*) tree
);
1087 buttonbar_set_label (b
, 6, Q_ ("ButtonBar|RenMov"), tree_map
, (Widget
*) tree
);
1089 /* FIXME: mkdir is currently defunct */
1090 buttonbar_set_label (b
, 7, Q_ ("ButtonBar|Mkdir"), tree_map
, (Widget
*) tree
);
1092 buttonbar_clear_label (b
, 7, (Widget
*) tree
);
1094 buttonbar_set_label (b
, 8, Q_ ("ButtonBar|Rmdir"), tree_map
, (Widget
*) tree
);
1095 buttonbar_redraw (b
);
1097 /* FIXME: Should find a better way of only displaying the
1098 currently selected item */
1102 /* FIXME: Should find a better way of changing the color of the
1105 case WIDGET_UNFOCUS
:
1111 return tree_key (tree
, parm
);
1113 case WIDGET_COMMAND
:
1114 /* command from buttonbar */
1115 return tree_execute_cmd (tree
, parm
);
1117 case WIDGET_DESTROY
:
1118 tree_destroy (tree
);
1122 return default_proc (msg
, parm
);
1127 tree_new (int is_panel
, int y
, int x
, int lines
, int cols
)
1129 WTree
*tree
= g_new (WTree
, 1);
1131 init_widget (&tree
->widget
, y
, x
, lines
, cols
, tree_callback
, event_callback
);
1132 tree
->is_panel
= is_panel
;
1133 tree
->selected_ptr
= 0;
1135 tree
->store
= tree_store_get ();
1136 tree_store_add_entry_remove_hook (remove_callback
, tree
);
1137 tree
->tree_shown
= 0;
1138 tree
->search_buffer
[0] = 0;
1139 tree
->topdiff
= tree
->widget
.lines
/ 2;
1140 tree
->searching
= 0;
1143 /* We do not want to keep the cursor */
1144 widget_want_cursor (tree
->widget
, 0);
1150 tree_chdir (WTree
* tree
, const char *dir
)
1152 tree_entry
*current
;
1154 current
= tree_store_whereis (dir
);
1156 if (current
!= NULL
)
1158 tree
->selected_ptr
= current
;
1159 tree_check_focus (tree
);
1163 /* Return name of the currently selected entry */
1165 tree_selected_name (const WTree
* tree
)
1167 return tree
->selected_ptr
->name
;
1171 sync_tree (const char *path
)
1173 tree_chdir (the_tree
, path
);
1177 find_tree (struct Dlg_head
*h
)
1179 return (WTree
*) find_widget_type (h
, tree_callback
);