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 #define tlines(t) (t->is_panel ? t->widget.lines - 2 - (show_mini_info ? 2 : 0) : t->widget.lines)
73 /* Use the color of the parent widget for the unselected entries */
74 #define TREE_NORMALC(h) (DLG_NORMALC (h))
76 /* Specifies the display mode: 1d or 2d */
77 static gboolean tree_navigation_flag
= FALSE
;
82 struct TreeStore
*store
;
83 tree_entry
*selected_ptr
; /* The selected directory */
84 char search_buffer
[256]; /* Current search string */
85 tree_entry
**tree_shown
; /* Entries currently on screen */
86 int is_panel
; /* panel or plain widget flag */
87 int active
; /* if it's currently selected */
88 int searching
; /* Are we on searching mode? */
89 int topdiff
; /* The difference between the topmost
90 shown and the selected */
94 static void tree_rescan (void *data
);
97 back_ptr (tree_entry
* ptr
, int *count
)
101 while (ptr
&& ptr
->prev
&& i
< *count
)
111 forw_ptr (tree_entry
* ptr
, int *count
)
115 while (ptr
&& ptr
->next
&& i
< *count
)
125 remove_callback (tree_entry
* entry
, void *data
)
129 if (tree
->selected_ptr
== entry
)
131 if (tree
->selected_ptr
->next
)
132 tree
->selected_ptr
= tree
->selected_ptr
->next
;
134 tree
->selected_ptr
= tree
->selected_ptr
->prev
;
138 /* Save the ~/.mc/Tree file */
140 save_tree (WTree
* tree
)
146 error
= tree_store_save ();
151 tree_name
= g_build_filename (home_dir
, MC_USERCONF_DIR
, MC_TREESTORE_FILE
, (char *) NULL
);
152 fprintf (stderr
, _("Cannot open the %s file for writing:\n%s\n"), tree_name
,
153 unix_error_string (error
));
159 tree_remove_entry (WTree
* tree
, char *name
)
162 tree_store_remove_entry (name
);
166 tree_destroy (WTree
* tree
)
168 tree_store_remove_entry_remove_hook (remove_callback
);
171 g_free (tree
->tree_shown
);
172 tree
->tree_shown
= 0;
173 tree
->selected_ptr
= NULL
;
176 /* Loads the .mc.tree file */
178 load_tree (WTree
* tree
)
182 tree
->selected_ptr
= tree
->store
->tree_first
;
183 tree_chdir (tree
, home_dir
);
187 tree_show_mini_info (WTree
* tree
, int tree_lines
, int tree_cols
)
189 Dlg_head
*h
= tree
->widget
.parent
;
197 line
= tree_lines
+ 2;
200 line
= tree_lines
+ 1;
202 tty_draw_hline (tree
->widget
.y
+ line
, tree
->widget
.x
+ 1, ' ', tree_cols
);
203 widget_move (&tree
->widget
, line
, 1);
207 /* Show search string */
208 tty_setcolor (TREE_NORMALC (h
));
209 tty_setcolor (DLG_FOCUSC (h
));
210 tty_print_char (PATH_SEP
);
212 tty_print_string (str_fit_to_term (tree
->search_buffer
, tree_cols
- 2, J_LEFT_FIT
));
213 tty_print_char (' ');
214 tty_setcolor (DLG_FOCUSC (h
));
218 /* Show full name of selected directory */
219 tty_print_string (str_fit_to_term (tree
->selected_ptr
->name
, tree_cols
, J_LEFT_FIT
));
224 show_tree (WTree
* tree
)
226 Dlg_head
*h
= tree
->widget
.parent
;
228 int i
, j
, topsublevel
;
230 int tree_lines
, tree_cols
;
234 tree_lines
= tlines (tree
);
235 tree_cols
= tree
->widget
.cols
;
237 tty_setcolor (TREE_NORMALC (h
));
238 widget_move ((Widget
*) tree
, y
, x
);
245 g_free (tree
->tree_shown
);
246 tree
->tree_shown
= g_new0 (tree_entry
*, tree_lines
);
248 if (tree
->store
->tree_first
)
249 topsublevel
= tree
->store
->tree_first
->sublevel
;
252 if (!tree
->selected_ptr
)
254 tree
->selected_ptr
= tree
->store
->tree_first
;
257 current
= tree
->selected_ptr
;
259 /* Calculate the directory which is to be shown on the topmost line */
260 if (!tree_navigation_flag
)
261 current
= back_ptr (current
, &tree
->topdiff
);
265 while (current
->prev
&& i
< tree
->topdiff
)
267 current
= current
->prev
;
268 if (current
->sublevel
< tree
->selected_ptr
->sublevel
)
270 if (strncmp (current
->name
, tree
->selected_ptr
->name
, strlen (current
->name
)) == 0)
273 else if (current
->sublevel
== tree
->selected_ptr
->sublevel
)
275 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
276 if (strncmp (current
->name
, tree
->selected_ptr
->name
, j
) == 0)
279 else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+ 1
280 && strlen (tree
->selected_ptr
->name
) > 1)
282 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
283 strlen (tree
->selected_ptr
->name
)) == 0)
290 /* Loop for every line */
291 for (i
= 0; i
< tree_lines
; i
++)
293 /* Move to the beginning of the line */
294 tty_draw_hline (tree
->widget
.y
+ y
+ i
, tree
->widget
.x
+ x
, ' ', tree_cols
);
299 tree
->tree_shown
[i
] = current
;
300 if (current
->sublevel
== topsublevel
)
303 /* Top level directory */
304 if (tree
->active
&& current
== tree
->selected_ptr
)
306 if (!tty_use_colors () && !tree
->is_panel
)
307 tty_setcolor (MARKED_COLOR
);
309 tty_setcolor (SELECTED_COLOR
);
313 tty_print_string (str_fit_to_term (current
->name
, tree_cols
- 6, J_LEFT_FIT
));
317 /* Sub level directory */
319 tty_set_alt_charset (TRUE
);
320 /* Output branch parts */
321 for (j
= 0; j
< current
->sublevel
- topsublevel
- 1; j
++)
323 if (tree_cols
- 8 - 3 * j
< 9)
325 tty_print_char (' ');
326 if (current
->submask
& (1 << (j
+ topsublevel
+ 1)))
327 tty_print_char (ACS_VLINE
);
329 tty_print_char (' ');
330 tty_print_char (' ');
332 tty_print_char (' ');
334 if (!current
->next
|| !(current
->next
->submask
& (1 << current
->sublevel
)))
335 tty_print_char (ACS_LLCORNER
);
337 tty_print_char (ACS_LTEE
);
338 tty_print_char (ACS_HLINE
);
339 tty_set_alt_charset (FALSE
);
341 if (tree
->active
&& current
== tree
->selected_ptr
)
343 /* Selected directory -> change color */
344 if (!tty_use_colors () && !tree
->is_panel
)
345 tty_setcolor (MARKED_COLOR
);
347 tty_setcolor (SELECTED_COLOR
);
351 tty_print_char (' ');
352 tty_print_string (str_fit_to_term (current
->subname
,
353 tree_cols
- 2 - 4 - 3 * j
, J_LEFT_FIT
));
355 tty_print_char (' ');
357 /* Return to normal color */
358 tty_setcolor (TREE_NORMALC (h
));
360 /* Calculate the next value for current */
361 current
= current
->next
;
362 if (tree_navigation_flag
)
366 if (current
->sublevel
< tree
->selected_ptr
->sublevel
)
368 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
369 strlen (current
->name
)) == 0)
372 else if (current
->sublevel
== tree
->selected_ptr
->sublevel
)
374 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
375 if (strncmp (current
->name
, tree
->selected_ptr
->name
, j
) == 0)
378 else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+ 1
379 && 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
);
393 tree_check_focus (WTree
* tree
)
395 if (tree
->topdiff
< 3)
397 else if (tree
->topdiff
>= tlines (tree
) - 3)
398 tree
->topdiff
= tlines (tree
) - 3 - 1;
402 tree_move_backward (WTree
* tree
, int i
)
404 if (!tree_navigation_flag
)
405 tree
->selected_ptr
= back_ptr (tree
->selected_ptr
, &i
);
411 current
= tree
->selected_ptr
;
412 while (j
< i
&& current
->prev
&& current
->prev
->sublevel
>= tree
->selected_ptr
->sublevel
)
414 current
= current
->prev
;
415 if (current
->sublevel
== tree
->selected_ptr
->sublevel
)
417 tree
->selected_ptr
= current
;
425 tree_check_focus (tree
);
429 tree_move_forward (WTree
* tree
, int i
)
431 if (!tree_navigation_flag
)
432 tree
->selected_ptr
= forw_ptr (tree
->selected_ptr
, &i
);
438 current
= tree
->selected_ptr
;
439 while (j
< i
&& current
->next
&& current
->next
->sublevel
>= tree
->selected_ptr
->sublevel
)
441 current
= current
->next
;
442 if (current
->sublevel
== tree
->selected_ptr
->sublevel
)
444 tree
->selected_ptr
= current
;
452 tree_check_focus (tree
);
456 tree_move_to_child (WTree
* tree
)
460 /* Do we have a starting point? */
461 if (!tree
->selected_ptr
)
463 /* Take the next entry */
464 current
= tree
->selected_ptr
->next
;
465 /* Is it the child of the selected entry */
466 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
)
468 /* Yes -> select this entry */
469 tree
->selected_ptr
= current
;
471 tree_check_focus (tree
);
475 /* No -> rescan and try again */
477 current
= tree
->selected_ptr
->next
;
478 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
)
480 tree
->selected_ptr
= current
;
482 tree_check_focus (tree
);
488 tree_move_to_parent (WTree
* tree
)
493 if (!tree
->selected_ptr
)
496 old
= tree
->selected_ptr
;
497 current
= tree
->selected_ptr
->prev
;
498 while (current
&& current
->sublevel
>= tree
->selected_ptr
->sublevel
)
500 current
= current
->prev
;
504 current
= tree
->store
->tree_first
;
505 tree
->selected_ptr
= current
;
506 tree_check_focus (tree
);
507 return tree
->selected_ptr
!= old
;
511 tree_move_to_top (WTree
* tree
)
513 tree
->selected_ptr
= tree
->store
->tree_first
;
518 tree_move_to_bottom (WTree
* tree
)
520 tree
->selected_ptr
= tree
->store
->tree_last
;
521 tree
->topdiff
= tlines (tree
) - 3 - 1;
524 /* Handle mouse click */
526 tree_event (WTree
* tree
, int y
)
528 if (tree
->tree_shown
[y
])
530 tree
->selected_ptr
= tree
->tree_shown
[y
];
537 tree_chdir_sel (WTree
* tree
)
544 if (do_cd (tree
->selected_ptr
->name
, cd_exact
))
545 select_item (current_panel
);
547 message (D_ERROR
, MSG_ERROR
, _(" Cannot chdir to \"%s\" \n %s "),
548 tree
->selected_ptr
->name
, unix_error_string (errno
));
555 maybe_chdir (WTree
* tree
)
557 if (xtree_mode
&& tree
->is_panel
&& is_idle ())
558 tree_chdir_sel (tree
);
563 event_callback (Gpm_Event
* event
, void *data
)
567 /* rest of the upper frame, the menu is invisible - call menu */
568 if (tree
->is_panel
&& (event
->type
& GPM_DOWN
) && event
->y
== 1 && !menubar_visible
)
570 event
->x
+= tree
->widget
.x
;
571 return the_menubar
->widget
.mouse (event
, the_menubar
);
574 if (!(event
->type
& GPM_UP
))
587 tree_move_backward (tree
, tlines (tree
) - 1);
590 else if (event
->y
>= tlines (tree
))
592 tree_move_forward (tree
, tlines (tree
) - 1);
597 tree_event (tree
, event
->y
);
598 if ((event
->type
& (GPM_UP
| GPM_DOUBLE
)) == (GPM_UP
| GPM_DOUBLE
))
600 tree_chdir_sel (tree
);
606 /* Search tree for text */
608 search_tree (WTree
* tree
, char *text
)
616 current
= tree
->selected_ptr
;
618 while (!wrapped
|| current
!= tree
->selected_ptr
)
620 if (strncmp (current
->subname
, text
, len
) == 0)
622 tree
->selected_ptr
= current
;
626 current
= current
->next
;
629 current
= tree
->store
->tree_first
;
634 tree_check_focus (tree
);
639 tree_do_search (WTree
* tree
, int key
)
643 l
= strlen (tree
->search_buffer
);
644 if ((l
!= 0) && (key
== KEY_BACKSPACE
))
645 tree
->search_buffer
[--l
] = '\0';
646 else if (key
&& l
< sizeof (tree
->search_buffer
))
648 tree
->search_buffer
[l
] = key
;
649 tree
->search_buffer
[++l
] = '\0';
652 if (!search_tree (tree
, tree
->search_buffer
))
653 tree
->search_buffer
[--l
] = 0;
660 tree_rescan (void *data
)
662 char old_dir
[MC_MAXPATHLEN
];
666 if (!tree
->selected_ptr
|| !mc_get_current_wd (old_dir
, MC_MAXPATHLEN
) ||
667 mc_chdir (tree
->selected_ptr
->name
))
670 tree_store_rescan (tree
->selected_ptr
->name
);
671 ret
= mc_chdir (old_dir
);
675 tree_forget (void *data
)
678 if (tree
->selected_ptr
)
679 tree_remove_entry (tree
, tree
->selected_ptr
->name
);
683 tree_copy (WTree
* tree
, const char *default_dest
)
685 char msg
[BUF_MEDIUM
];
688 if (tree
->selected_ptr
== NULL
)
691 g_snprintf (msg
, sizeof (msg
), _("Copy \"%s\" directory to:"),
692 str_trunc (tree
->selected_ptr
->name
, 50));
693 dest
= input_expand_dialog (Q_ ("DialogTitle|Copy"),
694 msg
, MC_HISTORY_FM_TREE_COPY
, default_dest
);
696 if (dest
!= NULL
&& *dest
!= '\0')
699 FileOpTotalContext
*tctx
;
701 ctx
= file_op_context_new (OP_COPY
);
702 tctx
= file_op_total_context_new ();
703 file_op_context_create_ui (ctx
, FALSE
, FILEGUI_DIALOG_MULTI_ITEM
);
704 tctx
->ask_overwrite
= FALSE
;
705 tctx
->is_toplevel_file
= FALSE
;
706 copy_dir_dir (tctx
, ctx
, tree
->selected_ptr
->name
, dest
, TRUE
, FALSE
, FALSE
, NULL
);
707 file_op_total_context_destroy (tctx
);
708 file_op_context_destroy (ctx
);
715 tree_move (WTree
* tree
, const char *default_dest
)
717 char msg
[BUF_MEDIUM
];
721 FileOpTotalContext
*tctx
;
723 if (tree
->selected_ptr
== NULL
)
726 g_snprintf (msg
, sizeof (msg
), _("Move \"%s\" directory to:"),
727 str_trunc (tree
->selected_ptr
->name
, 50));
729 input_expand_dialog (Q_ ("DialogTitle|Move"), msg
, MC_HISTORY_FM_TREE_MOVE
, default_dest
);
731 if (dest
== NULL
|| *dest
== '\0')
737 if (stat (dest
, &buf
))
739 message (D_ERROR
, MSG_ERROR
, _(" Cannot stat the destination \n %s "),
740 unix_error_string (errno
));
745 if (!S_ISDIR (buf
.st_mode
))
747 file_error (_(" Destination \"%s\" must be a directory \n %s "), dest
);
752 ctx
= file_op_context_new (OP_MOVE
);
753 tctx
= file_op_total_context_new ();
754 file_op_context_create_ui (ctx
, FALSE
, FILEGUI_DIALOG_ONE_ITEM
);
755 move_dir_dir (tctx
, ctx
, tree
->selected_ptr
->name
, dest
);
756 file_op_total_context_destroy (tctx
);
757 file_op_context_destroy (ctx
);
764 tree_mkdir (WTree
* tree
)
766 char old_dir
[MC_MAXPATHLEN
];
768 if (!tree
->selected_ptr
)
770 if (!mc_get_current_wd (old_dir
, MC_MAXPATHLEN
))
772 if (chdir (tree
->selected_ptr
->name
))
783 tree_rmdir (void *data
)
787 FileOpTotalContext
*tctx
;
789 if (!tree
->selected_ptr
)
797 buf
= g_strdup_printf (_(" Delete %s? "), tree
->selected_ptr
->name
);
798 result
= query_dialog (Q_ ("DialogTitle|Delete"), buf
, D_ERROR
, 2, _("&Yes"), _("&No"));
804 ctx
= file_op_context_new (OP_DELETE
);
805 tctx
= file_op_total_context_new ();
807 file_op_context_create_ui (ctx
, FALSE
, FILEGUI_DIALOG_ONE_ITEM
);
808 if (erase_dir (tctx
, ctx
, tree
->selected_ptr
->name
) == FILE_CONT
)
810 file_op_total_context_destroy (tctx
);
811 file_op_context_destroy (ctx
);
815 tree_move_up (WTree
* tree
)
817 tree_move_backward (tree
, 1);
823 tree_move_down (WTree
* tree
)
825 tree_move_forward (tree
, 1);
831 tree_move_home (WTree
* tree
)
833 tree_move_to_top (tree
);
839 tree_move_end (WTree
* tree
)
841 tree_move_to_bottom (tree
);
847 tree_move_pgup (WTree
* tree
)
849 tree_move_backward (tree
, tlines (tree
) - 1);
855 tree_move_pgdn (WTree
* tree
)
857 tree_move_forward (tree
, tlines (tree
) - 1);
863 tree_move_left (WTree
* tree
)
867 if (tree_navigation_flag
)
869 v
= tree_move_to_parent (tree
);
878 tree_move_right (WTree
* tree
)
882 if (tree_navigation_flag
)
884 tree_move_to_child (tree
);
894 tree_start_search (WTree
* tree
)
900 if (tree
->selected_ptr
== tree
->store
->tree_last
)
901 tree_move_to_top (tree
);
904 /* set navigation mode temporarily to 'Static' because in
905 * dynamic navigation mode tree_move_forward will not move
906 * to a lower sublevel if necessary (sequent searches must
907 * start with the directory followed the last found directory)
909 i
= tree_navigation_flag
;
910 tree_navigation_flag
= 0;
911 tree_move_forward (tree
, 1);
912 tree_navigation_flag
= i
;
914 tree_do_search (tree
, 0);
919 tree
->search_buffer
[0] = 0;
924 tree_toggle_navig (WTree
* tree
)
926 tree_navigation_flag
= !tree_navigation_flag
;
927 buttonbar_set_label (find_buttonbar (tree
->widget
.parent
), 4,
928 tree_navigation_flag
? Q_ ("ButtonBar|Static")
929 : Q_ ("ButtonBar|Dynamc"), tree_map
, (Widget
*) tree
);
933 tree_execute_cmd (WTree
* tree
, unsigned long command
)
935 cb_ret_t res
= MSG_HANDLED
;
937 if (command
!= CK_TreeStartSearch
)
943 interactive_display (NULL
, "[Directory Tree]");
948 case CK_TreeToggleNav
:
949 tree_toggle_navig (tree
);
952 tree_copy (tree
, "");
955 tree_move (tree
, "");
960 case CK_TreeMoveDown
:
961 tree_move_down (tree
);
963 case CK_TreeMoveHome
:
964 tree_move_home (tree
);
967 tree_move_end (tree
);
969 case CK_TreeMovePgUp
:
970 tree_move_pgup (tree
);
972 case CK_TreeMovePgDn
:
973 tree_move_pgdn (tree
);
976 tree_chdir_sel (tree
);
981 case CK_TreeStartSearch
:
982 tree_start_search (tree
);
988 res
= MSG_NOT_HANDLED
;
997 tree_key (WTree
* tree
, int key
)
1001 for (i
= 0; tree_map
[i
].key
!= 0; i
++)
1002 if (key
== tree_map
[i
].key
)
1003 switch (tree_map
[i
].command
)
1005 case CK_TreeMoveLeft
:
1006 return tree_move_left (tree
) ? MSG_HANDLED
: MSG_NOT_HANDLED
;
1007 case CK_TreeMoveRight
:
1008 return tree_move_right (tree
) ? MSG_HANDLED
: MSG_NOT_HANDLED
;
1010 tree_execute_cmd (tree
, tree_map
[i
].command
);
1014 if (is_abort_char (key
))
1018 tree
->searching
= 0;
1020 return MSG_HANDLED
; /* eat abort char */
1022 /* modal tree dialog: let upper layer see the
1023 abort character and close the dialog */
1024 return MSG_NOT_HANDLED
;
1027 /* Do not eat characters not meant for the tree below ' ' (e.g. C-l). */
1028 if ((key
>= ' ' && key
<= 255) || key
== KEY_BACKSPACE
)
1030 if (tree
->searching
)
1032 tree_do_search (tree
, key
);
1037 if (!command_prompt
)
1039 tree_start_search (tree
);
1040 tree_do_search (tree
, key
);
1043 return tree
->is_panel
? MSG_HANDLED
: MSG_NOT_HANDLED
;
1046 return MSG_NOT_HANDLED
;
1050 tree_frame (Dlg_head
* h
, WTree
* tree
)
1052 tty_setcolor (NORMAL_COLOR
);
1053 widget_erase ((Widget
*) tree
);
1056 draw_box (h
, tree
->widget
.y
, tree
->widget
.x
, tree
->widget
.lines
, tree
->widget
.cols
, FALSE
);
1059 tty_draw_hline (tree
->widget
.y
+ tlines (tree
) + 1,
1060 tree
->widget
.x
+ 1, ACS_HLINE
, tree
->widget
.cols
- 2);
1065 tree_callback (Widget
* w
, widget_msg_t msg
, int parm
)
1067 WTree
*tree
= (WTree
*) w
;
1068 Dlg_head
*h
= tree
->widget
.parent
;
1069 WButtonBar
*b
= find_buttonbar (h
);
1074 tree_frame (h
, tree
);
1080 buttonbar_set_label (b
, 1, Q_ ("ButtonBar|Help"), tree_map
, (Widget
*) tree
);
1081 buttonbar_set_label (b
, 2, Q_ ("ButtonBar|Rescan"), tree_map
, (Widget
*) tree
);
1082 buttonbar_set_label (b
, 3, Q_ ("ButtonBar|Forget"), tree_map
, (Widget
*) tree
);
1083 buttonbar_set_label (b
, 4, tree_navigation_flag
? Q_ ("ButtonBar|Static")
1084 : Q_ ("ButtonBar|Dynamc"), tree_map
, (Widget
*) tree
);
1085 buttonbar_set_label (b
, 5, Q_ ("ButtonBar|Copy"), tree_map
, (Widget
*) tree
);
1086 buttonbar_set_label (b
, 6, Q_ ("ButtonBar|RenMov"), tree_map
, (Widget
*) tree
);
1088 /* FIXME: mkdir is currently defunct */
1089 buttonbar_set_label (b
, 7, Q_ ("ButtonBar|Mkdir"), tree_map
, (Widget
*) tree
);
1091 buttonbar_clear_label (b
, 7, (Widget
*) tree
);
1093 buttonbar_set_label (b
, 8, Q_ ("ButtonBar|Rmdir"), tree_map
, (Widget
*) tree
);
1094 buttonbar_redraw (b
);
1096 /* FIXME: Should find a better way of only displaying the
1097 currently selected item */
1101 /* FIXME: Should find a better way of changing the color of the
1104 case WIDGET_UNFOCUS
:
1110 return tree_key (tree
, parm
);
1112 case WIDGET_COMMAND
:
1113 /* command from buttonbar */
1114 return tree_execute_cmd (tree
, parm
);
1116 case WIDGET_DESTROY
:
1117 tree_destroy (tree
);
1121 return default_proc (msg
, parm
);
1126 tree_new (int is_panel
, int y
, int x
, int lines
, int cols
)
1128 WTree
*tree
= g_new (WTree
, 1);
1130 init_widget (&tree
->widget
, y
, x
, lines
, cols
, tree_callback
, event_callback
);
1131 tree
->is_panel
= is_panel
;
1132 tree
->selected_ptr
= 0;
1134 tree
->store
= tree_store_get ();
1135 tree_store_add_entry_remove_hook (remove_callback
, tree
);
1136 tree
->tree_shown
= 0;
1137 tree
->search_buffer
[0] = 0;
1138 tree
->topdiff
= tree
->widget
.lines
/ 2;
1139 tree
->searching
= 0;
1142 /* We do not want to keep the cursor */
1143 widget_want_cursor (tree
->widget
, 0);
1149 tree_chdir (WTree
* tree
, const char *dir
)
1151 tree_entry
*current
;
1153 current
= tree_store_whereis (dir
);
1155 if (current
!= NULL
)
1157 tree
->selected_ptr
= current
;
1158 tree_check_focus (tree
);
1162 /* Return name of the currently selected entry */
1164 tree_selected_name (const WTree
* tree
)
1166 return tree
->selected_ptr
->name
;
1170 sync_tree (const char *path
)
1172 tree_chdir (the_tree
, path
);
1176 find_tree (struct Dlg_head
*h
)
1178 return (WTree
*) find_widget_type (h
, tree_callback
);