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))
75 #define TREE_CURRENTC(h) (DLG_FOCUSC (h))
77 /* Specifies the display mode: 1d or 2d */
78 static gboolean tree_navigation_flag
= FALSE
;
83 struct TreeStore
*store
;
84 tree_entry
*selected_ptr
; /* The selected directory */
85 char search_buffer
[256]; /* Current search string */
86 tree_entry
**tree_shown
; /* Entries currently on screen */
87 int is_panel
; /* panel or plain widget flag */
88 int active
; /* if it's currently selected */
89 int searching
; /* Are we on searching mode? */
90 int topdiff
; /* The difference between the topmost
91 shown and the selected */
95 static void tree_rescan (void *data
);
98 back_ptr (tree_entry
* ptr
, int *count
)
102 while (ptr
&& ptr
->prev
&& i
< *count
)
112 forw_ptr (tree_entry
* ptr
, int *count
)
116 while (ptr
&& ptr
->next
&& i
< *count
)
126 remove_callback (tree_entry
* entry
, void *data
)
130 if (tree
->selected_ptr
== entry
)
132 if (tree
->selected_ptr
->next
)
133 tree
->selected_ptr
= tree
->selected_ptr
->next
;
135 tree
->selected_ptr
= tree
->selected_ptr
->prev
;
139 /* Save the ~/.mc/Tree file */
141 save_tree (WTree
* tree
)
147 error
= tree_store_save ();
152 tree_name
= g_build_filename (home_dir
, MC_USERCONF_DIR
, MC_TREESTORE_FILE
, (char *) NULL
);
153 fprintf (stderr
, _("Cannot open the %s file for writing:\n%s\n"), tree_name
,
154 unix_error_string (error
));
160 tree_remove_entry (WTree
* tree
, char *name
)
163 tree_store_remove_entry (name
);
167 tree_destroy (WTree
* tree
)
169 tree_store_remove_entry_remove_hook (remove_callback
);
172 g_free (tree
->tree_shown
);
173 tree
->tree_shown
= 0;
174 tree
->selected_ptr
= NULL
;
177 /* Loads the .mc.tree file */
179 load_tree (WTree
* tree
)
183 tree
->selected_ptr
= tree
->store
->tree_first
;
184 tree_chdir (tree
, home_dir
);
188 tree_show_mini_info (WTree
* tree
, int tree_lines
, int tree_cols
)
190 Dlg_head
*h
= tree
->widget
.parent
;
198 line
= tree_lines
+ 2;
201 line
= tree_lines
+ 1;
205 /* Show search string */
206 tty_setcolor (INPUT_COLOR
);
207 tty_draw_hline (tree
->widget
.y
+ line
, tree
->widget
.x
+ 1, ' ', tree_cols
);
208 widget_move (&tree
->widget
, line
, 1);
209 tty_print_char (PATH_SEP
);
210 tty_print_string (str_fit_to_term (tree
->search_buffer
, tree_cols
- 2, J_LEFT_FIT
));
211 tty_print_char (' ');
215 /* Show full name of selected directory */
216 tty_setcolor (tree
->is_panel
? NORMAL_COLOR
: TREE_NORMALC (h
));
217 tty_draw_hline (tree
->widget
.y
+ line
, tree
->widget
.x
+ 1, ' ', tree_cols
);
218 widget_move (&tree
->widget
, line
, 1);
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
;
233 tree_lines
= tlines (tree
);
234 tree_cols
= tree
->widget
.cols
;
236 widget_move ((Widget
*) tree
, y
, x
);
243 g_free (tree
->tree_shown
);
244 tree
->tree_shown
= g_new0 (tree_entry
*, tree_lines
);
246 if (tree
->store
->tree_first
)
247 topsublevel
= tree
->store
->tree_first
->sublevel
;
250 if (!tree
->selected_ptr
)
252 tree
->selected_ptr
= tree
->store
->tree_first
;
255 current
= tree
->selected_ptr
;
257 /* Calculate the directory which is to be shown on the topmost line */
258 if (!tree_navigation_flag
)
259 current
= back_ptr (current
, &tree
->topdiff
);
263 while (current
->prev
&& i
< tree
->topdiff
)
265 current
= current
->prev
;
266 if (current
->sublevel
< tree
->selected_ptr
->sublevel
)
268 if (strncmp (current
->name
, tree
->selected_ptr
->name
, strlen (current
->name
)) == 0)
271 else if (current
->sublevel
== tree
->selected_ptr
->sublevel
)
273 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--);
274 if (strncmp (current
->name
, tree
->selected_ptr
->name
, j
) == 0)
277 else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+ 1
278 && strlen (tree
->selected_ptr
->name
) > 1)
280 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
281 strlen (tree
->selected_ptr
->name
)) == 0)
288 /* Loop for every line */
289 for (i
= 0; i
< tree_lines
; i
++)
291 tty_setcolor (tree
->is_panel
? NORMAL_COLOR
: TREE_NORMALC (h
));
293 /* Move to the beginning of the line */
294 tty_draw_hline (tree
->widget
.y
+ y
+ i
, tree
->widget
.x
+ x
, ' ', tree_cols
);
300 tty_setcolor (tree
->active
&& current
== tree
->selected_ptr
301 ? SELECTED_COLOR
: NORMAL_COLOR
);
303 tty_setcolor (current
== tree
->selected_ptr
? TREE_CURRENTC (h
) : TREE_NORMALC (h
));
305 tree
->tree_shown
[i
] = current
;
306 if (current
->sublevel
== topsublevel
)
309 tty_print_string (str_fit_to_term (current
->name
, tree_cols
+ (tree
->is_panel
? 0 : 1), J_LEFT_FIT
));
313 /* Sub level directory */
314 tty_set_alt_charset (TRUE
);
316 /* Output branch parts */
317 for (j
= 0; j
< current
->sublevel
- topsublevel
- 1; j
++)
319 if (tree_cols
- 8 - 3 * j
< 9)
321 tty_print_char (' ');
322 if (current
->submask
& (1 << (j
+ topsublevel
+ 1)))
323 tty_print_char (ACS_VLINE
);
325 tty_print_char (' ');
326 tty_print_char (' ');
328 tty_print_char (' ');
330 if (!current
->next
|| !(current
->next
->submask
& (1 << current
->sublevel
)))
331 tty_print_char (ACS_LLCORNER
);
333 tty_print_char (ACS_LTEE
);
334 tty_print_char (ACS_HLINE
);
335 tty_set_alt_charset (FALSE
);
338 tty_print_char (' ');
339 tty_print_string (str_fit_to_term (current
->subname
, tree_cols
- x
- 3 * j
, J_LEFT_FIT
));
342 /* Calculate the next value for current */
343 current
= current
->next
;
344 if (tree_navigation_flag
)
346 while (current
!= NULL
)
348 if (current
->sublevel
< tree
->selected_ptr
->sublevel
)
350 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
351 strlen (current
->name
)) == 0)
354 else if (current
->sublevel
== tree
->selected_ptr
->sublevel
)
356 for (j
= strlen (current
->name
) - 1; current
->name
[j
] != PATH_SEP
; j
--)
358 if (strncmp (current
->name
, tree
->selected_ptr
->name
, j
) == 0)
361 else if (current
->sublevel
== tree
->selected_ptr
->sublevel
+ 1
362 && strlen (tree
->selected_ptr
->name
) > 1)
364 if (strncmp (current
->name
, tree
->selected_ptr
->name
,
365 strlen (tree
->selected_ptr
->name
)) == 0)
368 current
= current
->next
;
373 tree_show_mini_info (tree
, tree_lines
, tree_cols
);
377 tree_check_focus (WTree
* tree
)
379 if (tree
->topdiff
< 3)
381 else if (tree
->topdiff
>= tlines (tree
) - 3)
382 tree
->topdiff
= tlines (tree
) - 3 - 1;
386 tree_move_backward (WTree
* tree
, int i
)
388 if (!tree_navigation_flag
)
389 tree
->selected_ptr
= back_ptr (tree
->selected_ptr
, &i
);
395 current
= tree
->selected_ptr
;
396 while (j
< i
&& current
->prev
&& current
->prev
->sublevel
>= tree
->selected_ptr
->sublevel
)
398 current
= current
->prev
;
399 if (current
->sublevel
== tree
->selected_ptr
->sublevel
)
401 tree
->selected_ptr
= current
;
409 tree_check_focus (tree
);
413 tree_move_forward (WTree
* tree
, int i
)
415 if (!tree_navigation_flag
)
416 tree
->selected_ptr
= forw_ptr (tree
->selected_ptr
, &i
);
422 current
= tree
->selected_ptr
;
423 while (j
< i
&& current
->next
&& current
->next
->sublevel
>= tree
->selected_ptr
->sublevel
)
425 current
= current
->next
;
426 if (current
->sublevel
== tree
->selected_ptr
->sublevel
)
428 tree
->selected_ptr
= current
;
436 tree_check_focus (tree
);
440 tree_move_to_child (WTree
* tree
)
444 /* Do we have a starting point? */
445 if (!tree
->selected_ptr
)
447 /* Take the next entry */
448 current
= tree
->selected_ptr
->next
;
449 /* Is it the child of the selected entry */
450 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
)
452 /* Yes -> select this entry */
453 tree
->selected_ptr
= current
;
455 tree_check_focus (tree
);
459 /* No -> rescan and try again */
461 current
= tree
->selected_ptr
->next
;
462 if (current
&& current
->sublevel
> tree
->selected_ptr
->sublevel
)
464 tree
->selected_ptr
= current
;
466 tree_check_focus (tree
);
472 tree_move_to_parent (WTree
* tree
)
477 if (!tree
->selected_ptr
)
480 old
= tree
->selected_ptr
;
481 current
= tree
->selected_ptr
->prev
;
482 while (current
&& current
->sublevel
>= tree
->selected_ptr
->sublevel
)
484 current
= current
->prev
;
488 current
= tree
->store
->tree_first
;
489 tree
->selected_ptr
= current
;
490 tree_check_focus (tree
);
491 return tree
->selected_ptr
!= old
;
495 tree_move_to_top (WTree
* tree
)
497 tree
->selected_ptr
= tree
->store
->tree_first
;
502 tree_move_to_bottom (WTree
* tree
)
504 tree
->selected_ptr
= tree
->store
->tree_last
;
505 tree
->topdiff
= tlines (tree
) - 3 - 1;
508 /* Handle mouse click */
510 tree_event (WTree
* tree
, int y
)
512 if (tree
->tree_shown
[y
])
514 tree
->selected_ptr
= tree
->tree_shown
[y
];
521 tree_chdir_sel (WTree
* tree
)
528 if (do_cd (tree
->selected_ptr
->name
, cd_exact
))
529 select_item (current_panel
);
531 message (D_ERROR
, MSG_ERROR
, _("Cannot chdir to \"%s\"\n%s"),
532 tree
->selected_ptr
->name
, unix_error_string (errno
));
539 maybe_chdir (WTree
* tree
)
541 if (xtree_mode
&& tree
->is_panel
&& is_idle ())
542 tree_chdir_sel (tree
);
547 event_callback (Gpm_Event
* event
, void *data
)
551 /* rest of the upper frame, the menu is invisible - call menu */
552 if (tree
->is_panel
&& (event
->type
& GPM_DOWN
) && event
->y
== 1 && !menubar_visible
)
554 event
->x
+= tree
->widget
.x
;
555 return the_menubar
->widget
.mouse (event
, the_menubar
);
558 if (!(event
->type
& GPM_UP
))
571 tree_move_backward (tree
, tlines (tree
) - 1);
574 else if (event
->y
>= tlines (tree
))
576 tree_move_forward (tree
, tlines (tree
) - 1);
581 tree_event (tree
, event
->y
);
582 if ((event
->type
& (GPM_UP
| GPM_DOUBLE
)) == (GPM_UP
| GPM_DOUBLE
))
584 tree_chdir_sel (tree
);
590 /* Search tree for text */
592 search_tree (WTree
* tree
, char *text
)
600 current
= tree
->selected_ptr
;
602 while (!wrapped
|| current
!= tree
->selected_ptr
)
604 if (strncmp (current
->subname
, text
, len
) == 0)
606 tree
->selected_ptr
= current
;
610 current
= current
->next
;
613 current
= tree
->store
->tree_first
;
618 tree_check_focus (tree
);
623 tree_do_search (WTree
* tree
, int key
)
627 l
= strlen (tree
->search_buffer
);
628 if ((l
!= 0) && (key
== KEY_BACKSPACE
))
629 tree
->search_buffer
[--l
] = '\0';
630 else if (key
&& l
< sizeof (tree
->search_buffer
))
632 tree
->search_buffer
[l
] = key
;
633 tree
->search_buffer
[++l
] = '\0';
636 if (!search_tree (tree
, tree
->search_buffer
))
637 tree
->search_buffer
[--l
] = 0;
644 tree_rescan (void *data
)
646 char old_dir
[MC_MAXPATHLEN
];
650 if (!tree
->selected_ptr
|| !mc_get_current_wd (old_dir
, MC_MAXPATHLEN
) ||
651 mc_chdir (tree
->selected_ptr
->name
))
654 tree_store_rescan (tree
->selected_ptr
->name
);
655 ret
= mc_chdir (old_dir
);
659 tree_forget (void *data
)
662 if (tree
->selected_ptr
)
663 tree_remove_entry (tree
, tree
->selected_ptr
->name
);
667 tree_copy (WTree
* tree
, const char *default_dest
)
669 char msg
[BUF_MEDIUM
];
672 if (tree
->selected_ptr
== NULL
)
675 g_snprintf (msg
, sizeof (msg
), _("Copy \"%s\" directory to:"),
676 str_trunc (tree
->selected_ptr
->name
, 50));
677 dest
= input_expand_dialog (Q_ ("DialogTitle|Copy"),
678 msg
, MC_HISTORY_FM_TREE_COPY
, default_dest
);
680 if (dest
!= NULL
&& *dest
!= '\0')
683 FileOpTotalContext
*tctx
;
685 ctx
= file_op_context_new (OP_COPY
);
686 tctx
= file_op_total_context_new ();
687 file_op_context_create_ui (ctx
, FALSE
, FILEGUI_DIALOG_MULTI_ITEM
);
688 tctx
->ask_overwrite
= FALSE
;
689 tctx
->is_toplevel_file
= FALSE
;
690 copy_dir_dir (tctx
, ctx
, tree
->selected_ptr
->name
, dest
, TRUE
, FALSE
, FALSE
, NULL
);
691 file_op_total_context_destroy (tctx
);
692 file_op_context_destroy (ctx
);
699 tree_move (WTree
* tree
, const char *default_dest
)
701 char msg
[BUF_MEDIUM
];
705 FileOpTotalContext
*tctx
;
707 if (tree
->selected_ptr
== NULL
)
710 g_snprintf (msg
, sizeof (msg
), _("Move \"%s\" directory to:"),
711 str_trunc (tree
->selected_ptr
->name
, 50));
713 input_expand_dialog (Q_ ("DialogTitle|Move"), msg
, MC_HISTORY_FM_TREE_MOVE
, default_dest
);
715 if (dest
== NULL
|| *dest
== '\0')
721 if (stat (dest
, &buf
))
723 message (D_ERROR
, MSG_ERROR
, _("Cannot stat the destination\n%s"),
724 unix_error_string (errno
));
729 if (!S_ISDIR (buf
.st_mode
))
731 file_error (_("Destination \"%s\" must be a directory\n%s"), dest
);
736 ctx
= file_op_context_new (OP_MOVE
);
737 tctx
= file_op_total_context_new ();
738 file_op_context_create_ui (ctx
, FALSE
, FILEGUI_DIALOG_ONE_ITEM
);
739 move_dir_dir (tctx
, ctx
, tree
->selected_ptr
->name
, dest
);
740 file_op_total_context_destroy (tctx
);
741 file_op_context_destroy (ctx
);
748 tree_mkdir (WTree
* tree
)
750 char old_dir
[MC_MAXPATHLEN
];
752 if (!tree
->selected_ptr
)
754 if (!mc_get_current_wd (old_dir
, MC_MAXPATHLEN
))
756 if (chdir (tree
->selected_ptr
->name
))
767 tree_rmdir (void *data
)
771 FileOpTotalContext
*tctx
;
773 if (!tree
->selected_ptr
)
781 buf
= g_strdup_printf (_("Delete %s?"), tree
->selected_ptr
->name
);
782 result
= query_dialog (Q_ ("DialogTitle|Delete"), buf
, D_ERROR
, 2, _("&Yes"), _("&No"));
788 ctx
= file_op_context_new (OP_DELETE
);
789 tctx
= file_op_total_context_new ();
791 file_op_context_create_ui (ctx
, FALSE
, FILEGUI_DIALOG_ONE_ITEM
);
792 if (erase_dir (tctx
, ctx
, tree
->selected_ptr
->name
) == FILE_CONT
)
794 file_op_total_context_destroy (tctx
);
795 file_op_context_destroy (ctx
);
799 tree_move_up (WTree
* tree
)
801 tree_move_backward (tree
, 1);
807 tree_move_down (WTree
* tree
)
809 tree_move_forward (tree
, 1);
815 tree_move_home (WTree
* tree
)
817 tree_move_to_top (tree
);
823 tree_move_end (WTree
* tree
)
825 tree_move_to_bottom (tree
);
831 tree_move_pgup (WTree
* tree
)
833 tree_move_backward (tree
, tlines (tree
) - 1);
839 tree_move_pgdn (WTree
* tree
)
841 tree_move_forward (tree
, tlines (tree
) - 1);
847 tree_move_left (WTree
* tree
)
851 if (tree_navigation_flag
)
853 v
= tree_move_to_parent (tree
);
862 tree_move_right (WTree
* tree
)
866 if (tree_navigation_flag
)
868 tree_move_to_child (tree
);
878 tree_start_search (WTree
* tree
)
884 if (tree
->selected_ptr
== tree
->store
->tree_last
)
885 tree_move_to_top (tree
);
888 /* set navigation mode temporarily to 'Static' because in
889 * dynamic navigation mode tree_move_forward will not move
890 * to a lower sublevel if necessary (sequent searches must
891 * start with the directory followed the last found directory)
893 i
= tree_navigation_flag
;
894 tree_navigation_flag
= 0;
895 tree_move_forward (tree
, 1);
896 tree_navigation_flag
= i
;
898 tree_do_search (tree
, 0);
903 tree
->search_buffer
[0] = 0;
908 tree_toggle_navig (WTree
* tree
)
910 tree_navigation_flag
= !tree_navigation_flag
;
911 buttonbar_set_label (find_buttonbar (tree
->widget
.parent
), 4,
912 tree_navigation_flag
? Q_ ("ButtonBar|Static")
913 : Q_ ("ButtonBar|Dynamc"), tree_map
, (Widget
*) tree
);
917 tree_execute_cmd (WTree
* tree
, unsigned long command
)
919 cb_ret_t res
= MSG_HANDLED
;
921 if (command
!= CK_TreeStartSearch
)
927 interactive_display (NULL
, "[Directory Tree]");
932 case CK_TreeToggleNav
:
933 tree_toggle_navig (tree
);
936 tree_copy (tree
, "");
939 tree_move (tree
, "");
944 case CK_TreeMoveDown
:
945 tree_move_down (tree
);
947 case CK_TreeMoveHome
:
948 tree_move_home (tree
);
951 tree_move_end (tree
);
953 case CK_TreeMovePgUp
:
954 tree_move_pgup (tree
);
956 case CK_TreeMovePgDn
:
957 tree_move_pgdn (tree
);
960 tree_chdir_sel (tree
);
965 case CK_TreeStartSearch
:
966 tree_start_search (tree
);
972 res
= MSG_NOT_HANDLED
;
981 tree_key (WTree
* tree
, int key
)
985 for (i
= 0; tree_map
[i
].key
!= 0; i
++)
986 if (key
== tree_map
[i
].key
)
987 switch (tree_map
[i
].command
)
989 case CK_TreeMoveLeft
:
990 return tree_move_left (tree
) ? MSG_HANDLED
: MSG_NOT_HANDLED
;
991 case CK_TreeMoveRight
:
992 return tree_move_right (tree
) ? MSG_HANDLED
: MSG_NOT_HANDLED
;
994 tree_execute_cmd (tree
, tree_map
[i
].command
);
998 if (is_abort_char (key
))
1002 tree
->searching
= 0;
1004 return MSG_HANDLED
; /* eat abort char */
1006 /* modal tree dialog: let upper layer see the
1007 abort character and close the dialog */
1008 return MSG_NOT_HANDLED
;
1011 /* Do not eat characters not meant for the tree below ' ' (e.g. C-l). */
1012 if ((key
>= ' ' && key
<= 255) || key
== KEY_BACKSPACE
)
1014 if (tree
->searching
)
1016 tree_do_search (tree
, key
);
1021 if (!command_prompt
)
1023 tree_start_search (tree
);
1024 tree_do_search (tree
, key
);
1027 return tree
->is_panel
? MSG_HANDLED
: MSG_NOT_HANDLED
;
1030 return MSG_NOT_HANDLED
;
1034 tree_frame (Dlg_head
* h
, WTree
* tree
)
1036 tty_setcolor (NORMAL_COLOR
);
1037 widget_erase ((Widget
*) tree
);
1040 const char *title
= _("Directory tree");
1041 const int len
= str_term_width1 (title
);
1043 draw_box (h
, tree
->widget
.y
, tree
->widget
.x
, tree
->widget
.lines
, tree
->widget
.cols
, FALSE
);
1045 widget_move (&tree
->widget
, 0, (tree
->widget
.cols
- len
- 2)/2);
1046 tty_printf (" %s ", title
);
1049 widget_move (&tree
->widget
, tlines (tree
) + 1, 0);
1050 tty_print_alt_char (ACS_LTEE
, FALSE
);
1051 widget_move (&tree
->widget
, tlines (tree
) + 1, tree
->widget
.cols
- 1);
1052 tty_print_alt_char (ACS_RTEE
, FALSE
);
1053 tty_draw_hline (tree
->widget
.y
+ tlines (tree
) + 1,
1054 tree
->widget
.x
+ 1, ACS_HLINE
, tree
->widget
.cols
- 2);
1059 tree_callback (Widget
* w
, widget_msg_t msg
, int parm
)
1061 WTree
*tree
= (WTree
*) w
;
1062 Dlg_head
*h
= tree
->widget
.parent
;
1063 WButtonBar
*b
= find_buttonbar (h
);
1068 tree_frame (h
, tree
);
1074 buttonbar_set_label (b
, 1, Q_ ("ButtonBar|Help"), tree_map
, (Widget
*) tree
);
1075 buttonbar_set_label (b
, 2, Q_ ("ButtonBar|Rescan"), tree_map
, (Widget
*) tree
);
1076 buttonbar_set_label (b
, 3, Q_ ("ButtonBar|Forget"), tree_map
, (Widget
*) tree
);
1077 buttonbar_set_label (b
, 4, tree_navigation_flag
? Q_ ("ButtonBar|Static")
1078 : Q_ ("ButtonBar|Dynamc"), tree_map
, (Widget
*) tree
);
1079 buttonbar_set_label (b
, 5, Q_ ("ButtonBar|Copy"), tree_map
, (Widget
*) tree
);
1080 buttonbar_set_label (b
, 6, Q_ ("ButtonBar|RenMov"), tree_map
, (Widget
*) tree
);
1082 /* FIXME: mkdir is currently defunct */
1083 buttonbar_set_label (b
, 7, Q_ ("ButtonBar|Mkdir"), tree_map
, (Widget
*) tree
);
1085 buttonbar_clear_label (b
, 7, (Widget
*) tree
);
1087 buttonbar_set_label (b
, 8, Q_ ("ButtonBar|Rmdir"), tree_map
, (Widget
*) tree
);
1088 buttonbar_redraw (b
);
1090 /* FIXME: Should find a better way of only displaying the
1091 currently selected item */
1095 /* FIXME: Should find a better way of changing the color of the
1098 case WIDGET_UNFOCUS
:
1100 tree
->searching
= 0;
1105 return tree_key (tree
, parm
);
1107 case WIDGET_COMMAND
:
1108 /* command from buttonbar */
1109 return tree_execute_cmd (tree
, parm
);
1111 case WIDGET_DESTROY
:
1112 tree_destroy (tree
);
1116 return default_proc (msg
, parm
);
1121 tree_new (int y
, int x
, int lines
, int cols
, gboolean is_panel
)
1123 WTree
*tree
= g_new (WTree
, 1);
1125 init_widget (&tree
->widget
, y
, x
, lines
, cols
, tree_callback
, event_callback
);
1126 tree
->is_panel
= is_panel
;
1127 tree
->selected_ptr
= 0;
1129 tree
->store
= tree_store_get ();
1130 tree_store_add_entry_remove_hook (remove_callback
, tree
);
1131 tree
->tree_shown
= 0;
1132 tree
->search_buffer
[0] = 0;
1133 tree
->topdiff
= tree
->widget
.lines
/ 2;
1134 tree
->searching
= 0;
1137 /* We do not want to keep the cursor */
1138 widget_want_cursor (tree
->widget
, 0);
1144 tree_chdir (WTree
* tree
, const char *dir
)
1146 tree_entry
*current
;
1148 current
= tree_store_whereis (dir
);
1150 if (current
!= NULL
)
1152 tree
->selected_ptr
= current
;
1153 tree_check_focus (tree
);
1157 /* Return name of the currently selected entry */
1159 tree_selected_name (const WTree
* tree
)
1161 return tree
->selected_ptr
->name
;
1165 sync_tree (const char *path
)
1167 tree_chdir (the_tree
, path
);
1171 find_tree (struct Dlg_head
*h
)
1173 return (WTree
*) find_widget_type (h
, tree_callback
);