1 /* Hiearchic listboxes browser dialog commons */
11 #include "bfu/button.h"
12 #include "bfu/dialog.h"
13 #include "bfu/hierbox.h"
14 #include "bfu/inpfield.h"
15 #include "bfu/listbox.h"
16 #include "bfu/msgbox.h"
18 #include "config/kbdbind.h"
19 #include "intl/gettext/libintl.h"
20 #include "protocol/uri.h"
21 #include "session/task.h"
22 #include "terminal/screen.h"
23 #include "terminal/tab.h"
24 #include "terminal/terminal.h"
28 update_hierbox_browser(struct hierbox_browser
*browser
)
30 struct hierbox_dialog_list_item
*item
;
32 foreach (item
, browser
->dialogs
) {
33 redraw_from_window(item
->dlg_data
->win
->next
);
38 /* Common backend for listbox adding */
40 add_listbox_item(struct hierbox_browser
*browser
, struct listbox_item
*root
,
41 enum listbox_item_type type
, void *data
, int add_position
)
43 struct listbox_item
*item
;
46 assertm(browser
, "Nowhere to add new list box item");
47 root
= &browser
->root
;
50 item
= mem_calloc(1, sizeof(*item
));
51 if (!item
) return NULL
;
53 init_list(item
->child
);
58 item
->depth
= root
->depth
+ 1;
60 /* TODO: Possibility to sort by making add_position into a flag */
62 add_to_list_end(root
->child
, item
);
64 add_to_list(root
->child
, item
);
66 if (browser
) update_hierbox_browser(browser
);
72 /* Find a listbox item to replace @item. This is done by trying first to
73 * traverse down then up, and if both traversals end up returning the @item
74 * (that is, it is the last item in the box), return NULL. */
75 static inline struct listbox_item
*
76 replace_listbox_item(struct listbox_item
*item
, struct listbox_data
*data
)
78 struct listbox_item
*new_item
;
80 new_item
= traverse_listbox_items_list(item
, data
, 1, 1, NULL
, NULL
);
81 if (item
!= new_item
) return new_item
;
83 new_item
= traverse_listbox_items_list(item
, data
, -1, 1, NULL
, NULL
);
84 return (item
== new_item
) ? NULL
: new_item
;
88 done_listbox_item(struct hierbox_browser
*browser
, struct listbox_item
*box_item
)
90 struct listbox_data
*box_data
;
92 assert(box_item
&& list_empty(box_item
->child
));
94 /* The option dialog needs this test */
96 /* If we are removing the top or the selected box
97 * we have to figure out a replacement. */
99 foreach (box_data
, browser
->boxes
) {
100 if (box_data
->sel
== box_item
)
101 box_data
->sel
= replace_listbox_item(box_item
,
104 if (box_data
->top
== box_item
)
105 box_data
->top
= replace_listbox_item(box_item
,
109 del_from_list(box_item
);
111 update_hierbox_browser(browser
);
119 recursively_set_expanded(struct listbox_item
*item
, int expanded
)
121 struct listbox_item
*child
;
123 if (item
->type
!= BI_FOLDER
)
126 item
->expanded
= expanded
;
128 foreach (child
, item
->child
)
129 recursively_set_expanded(child
, expanded
);
132 static widget_handler_status_T
133 hierbox_ev_kbd(struct dialog_data
*dlg_data
)
135 struct hierbox_browser
*browser
= dlg_data
->dlg
->udata2
;
136 struct widget_data
*widget_data
= dlg_data
->widgets_data
;
137 struct widget
*widget
= widget_data
->widget
;
138 struct listbox_data
*box
;
139 struct listbox_item
*selected
;
140 enum menu_action action_id
;
141 struct term_event
*ev
= dlg_data
->term_event
;
143 /* Check if listbox has something to say to this */
145 && widget
->ops
->kbd(dlg_data
, widget_data
)
147 return EVENT_PROCESSED
;
149 box
= get_dlg_listbox_data(dlg_data
);
151 action_id
= kbd_action(KEYMAP_MENU
, ev
, NULL
);
153 if (action_id
== ACT_MENU_SELECT
) {
154 if (!selected
) return EVENT_PROCESSED
;
155 if (selected
->type
!= BI_FOLDER
)
156 return EVENT_NOT_PROCESSED
;
157 selected
->expanded
= !selected
->expanded
;
159 } else if (action_id
== ACT_MENU_UNEXPAND
) {
160 /* Recursively unexpand all folders */
161 if (!selected
) return EVENT_PROCESSED
;
163 /* Special trick: if the folder is already
164 * folded, jump to the parent folder, so the
165 * next time when user presses the key, the
166 * whole parent folder will be closed. */
167 if (list_empty(selected
->child
)
168 || !selected
->expanded
) {
169 struct listbox_item
*root
= box
->ops
->get_root(selected
);
172 listbox_sel(widget_data
, root
);
175 } else if (selected
->type
== BI_FOLDER
) {
176 recursively_set_expanded(selected
, 0);
179 } else if (action_id
== ACT_MENU_EXPAND
) {
180 /* Recursively expand all folders */
182 if (!selected
|| box
->sel
->type
!= BI_FOLDER
)
183 return EVENT_PROCESSED
;
185 recursively_set_expanded(box
->sel
, 1);
187 } else if (action_id
== ACT_MENU_SEARCH
) {
188 if (!box
->ops
->match
)
189 return EVENT_NOT_PROCESSED
;
191 push_hierbox_search_button(dlg_data
, NULL
);
192 return EVENT_PROCESSED
;
195 return EVENT_NOT_PROCESSED
;
199 if (browser
->expansion_callback
)
200 browser
->expansion_callback();
202 display_widget(dlg_data
, widget_data
);
204 return EVENT_PROCESSED
;
207 static widget_handler_status_T
208 hierbox_ev_init(struct dialog_data
*dlg_data
)
210 struct hierbox_browser
*browser
= dlg_data
->dlg
->udata2
;
211 struct hierbox_dialog_list_item
*item
;
212 struct listbox_item
*litem
;
214 /* If we fail here it only means automatic updating
215 * will not be possible so no need to panic. */
216 item
= mem_alloc(sizeof(*item
));
218 item
->dlg_data
= dlg_data
;
219 add_to_list(browser
->dialogs
, item
);
222 foreach (litem
, browser
->root
.child
) {
226 return EVENT_NOT_PROCESSED
; /* FIXME: is this correct ? --Zas */
229 static widget_handler_status_T
230 hierbox_ev_abort(struct dialog_data
*dlg_data
)
232 struct listbox_data
*box
= get_dlg_listbox_data(dlg_data
);
233 struct hierbox_browser
*browser
= dlg_data
->dlg
->udata2
;
234 struct hierbox_dialog_list_item
*item
;
236 /* Save state and delete the box structure */
237 if (!browser
->do_not_save_state
)
238 copy_struct(&browser
->box_data
, box
);
241 /* Delete the dialog list entry */
242 foreach (item
, browser
->dialogs
) {
243 if (item
->dlg_data
== dlg_data
) {
250 return EVENT_NOT_PROCESSED
; /* FIXME: is this correct ? --Zas */
254 /* We install own dialog event handler, so that we can give the listbox widget
255 * an early chance to catch the event. Basically, the listbox widget is itself
256 * unselectable, instead one of the buttons below is always active. So, we
257 * always first let the listbox catch the keypress and handle it, and if it
258 * doesn't care, we pass it on to the button. */
259 static widget_handler_status_T
260 hierbox_dialog_event_handler(struct dialog_data
*dlg_data
)
262 struct term_event
*ev
= dlg_data
->term_event
;
266 return hierbox_ev_kbd(dlg_data
);
269 return hierbox_ev_init(dlg_data
);
274 return EVENT_NOT_PROCESSED
;
277 return hierbox_ev_abort(dlg_data
);
280 return EVENT_NOT_PROCESSED
;
285 hierbox_browser(struct hierbox_browser
*browser
, struct session
*ses
)
287 struct terminal
*term
= ses
->tab
->term
;
288 struct listbox_data
*listbox_data
;
290 int button
= browser
->buttons_size
+ 2;
291 int anonymous
= get_cmd_opt_bool("anonymous");
295 dlg
= calloc_dialog(button
, sizeof(*listbox_data
));
296 if (!dlg
) return NULL
;
298 listbox_data
= (struct listbox_data
*) get_dialog_offset(dlg
, button
);
300 dlg
->title
= _(browser
->title
, term
);
301 dlg
->layouter
= generic_dialog_layouter
;
302 dlg
->layout
.maximize_width
= 1;
303 dlg
->layout
.padding_top
= 1;
304 dlg
->handle_event
= hierbox_dialog_event_handler
;
306 dlg
->udata2
= browser
;
308 add_dlg_listbox(dlg
, 12, listbox_data
);
310 for (button
= 0; button
< browser
->buttons_size
; button
++) {
311 struct hierbox_browser_button
*but
= &browser
->buttons
[button
];
313 /* Skip buttons that should not be displayed in anonymous mode */
314 if (anonymous
&& !but
->anonymous
) {
319 add_dlg_button(dlg
, _(but
->label
, term
), B_ENTER
, but
->handler
, NULL
);
322 add_dlg_button(dlg
, _("Close", term
), B_ESC
, cancel_dialog
, NULL
);
324 /* @anonymous was initially 1 if we are running in anonymous mode so we
325 * have to subtract one. */
326 add_dlg_end(dlg
, button
+ 2 - (anonymous
? anonymous
- 1 : 0));
328 return do_dialog(term
, dlg
, getml(dlg
, NULL
));
332 /* Action info management */
335 scan_for_marks(struct listbox_item
*item
, void *info_
, int *offset
)
338 struct listbox_context
*context
= info_
;
340 context
->item
= NULL
;
348 scan_for_used(struct listbox_item
*item
, void *info_
, int *offset
)
350 struct listbox_context
*context
= info_
;
352 if (context
->box
->ops
->is_used(item
)) {
353 context
->item
= item
;
361 static struct listbox_context
*
362 init_listbox_context(struct listbox_data
*box
, struct terminal
*term
,
363 struct listbox_item
*item
,
364 int (*scanner
)(struct listbox_item
*, void *, int *))
366 struct listbox_context
*context
;
368 context
= mem_calloc(1, sizeof(*context
));
369 if (!context
) return NULL
;
371 context
->item
= item
;
372 context
->term
= term
;
375 if (!scanner
) return context
;
377 /* Look if it wouldn't be more interesting to blast off the marked
379 assert(!list_empty(*box
->items
));
380 traverse_listbox_items_list(box
->items
->next
, box
, 0, 0,
387 done_listbox_context(void *context_
)
389 struct listbox_context
*context
= context_
;
392 context
->box
->ops
->unlock(context
->item
);
398 widget_handler_status_T
399 push_hierbox_info_button(struct dialog_data
*dlg_data
, struct widget_data
*button
)
401 struct listbox_data
*box
= get_dlg_listbox_data(dlg_data
);
402 struct terminal
*term
= dlg_data
->win
->term
;
403 struct listbox_context
*context
;
406 if (!box
->sel
) return EVENT_PROCESSED
;
410 context
= init_listbox_context(box
, term
, box
->sel
, NULL
);
411 if (!context
) return EVENT_PROCESSED
;
413 msg
= box
->ops
->get_info(context
->item
, term
);
416 if (box
->sel
->type
== BI_FOLDER
) {
417 info_box(term
, 0, N_("Info"), ALIGN_CENTER
,
418 N_("Press space to expand this folder."));
420 return EVENT_PROCESSED
;
423 box
->ops
->lock(context
->item
);
425 msg_box(term
, getml(context
, NULL
), MSGBOX_FREE_TEXT
/* | MSGBOX_SCROLLABLE */,
426 N_("Info"), ALIGN_LEFT
,
429 N_("~OK"), done_listbox_context
, B_ESC
| B_ENTER
);
431 return EVENT_PROCESSED
;
438 recursively_goto_listbox(struct session
*ses
, struct listbox_item
*root
,
439 struct listbox_data
*box
)
441 struct listbox_item
*item
;
443 foreach (item
, root
->child
) {
444 if (item
->type
== BI_FOLDER
) {
445 recursively_goto_listbox(ses
, item
, box
);
448 } else if (item
->type
== BI_LEAF
) {
449 struct uri
*uri
= box
->ops
->get_uri(item
);
453 open_uri_in_new_tab(ses
, uri
, 1, 0);
460 goto_marked(struct listbox_item
*item
, void *data_
, int *offset
)
462 struct listbox_context
*context
= data_
;
465 struct session
*ses
= context
->dlg_data
->dlg
->udata
;
466 struct listbox_data
*box
= context
->box
;
468 if (item
->type
== BI_FOLDER
) {
469 recursively_goto_listbox(ses
, item
, box
);
472 } else if (item
->type
== BI_LEAF
) {
473 struct uri
*uri
= box
->ops
->get_uri(item
);
477 open_uri_in_new_tab(ses
, uri
, 1, 0);
485 widget_handler_status_T
486 push_hierbox_goto_button(struct dialog_data
*dlg_data
,
487 struct widget_data
*button
)
489 struct listbox_data
*box
= get_dlg_listbox_data(dlg_data
);
490 struct session
*ses
= dlg_data
->dlg
->udata
;
491 struct terminal
*term
= dlg_data
->win
->term
;
492 struct listbox_context
*context
;
494 /* Do nothing with a folder */
495 if (!box
->sel
) return EVENT_PROCESSED
;
497 context
= init_listbox_context(box
, term
, box
->sel
, scan_for_marks
);
498 if (!context
) return EVENT_PROCESSED
;
500 if (!context
->item
) {
501 context
->dlg_data
= dlg_data
;
502 traverse_listbox_items_list(context
->box
->items
->next
,
504 goto_marked
, context
);
506 } else if (box
->sel
->type
== BI_FOLDER
) {
507 recursively_goto_listbox(ses
, box
->sel
, box
);
509 } else if (box
->sel
->type
== BI_LEAF
) {
510 struct uri
*uri
= box
->ops
->get_uri(box
->sel
);
519 return EVENT_PROCESSED
;
524 /* Close the dialog */
525 delete_window(dlg_data
->win
);
526 return EVENT_PROCESSED
;
533 DELETE_IMPOSSIBLE
= 0,
538 unsigned char *delete_messages
[2][DELETE_ERRORS
] = {
540 N_("Sorry, but the item \"%s\" cannot be deleted."),
541 N_("Sorry, but the item \"%s\" is being used by something else."),
544 N_("Sorry, but the folder \"%s\" cannot be deleted."),
545 N_("Sorry, but the folder \"%s\" is being used by something else."),
550 print_delete_error(struct listbox_item
*item
, struct terminal
*term
,
551 struct listbox_ops
*ops
, enum delete_error err
)
554 unsigned char *errmsg
;
558 case DELETE_IMPOSSIBLE
:
559 if (item
->type
== BI_FOLDER
) {
560 if (ops
->messages
&& ops
->messages
->cant_delete_folder
)
561 errmsg
= ops
->messages
->cant_delete_folder
;
563 errmsg
= delete_messages
[1][DELETE_IMPOSSIBLE
];
565 if (ops
->messages
&& ops
->messages
->cant_delete_item
)
566 errmsg
= ops
->messages
->cant_delete_item
;
568 errmsg
= delete_messages
[0][DELETE_IMPOSSIBLE
];
573 if (item
->type
== BI_FOLDER
) {
574 if (ops
->messages
&& ops
->messages
->cant_delete_used_folder
)
575 errmsg
= ops
->messages
->cant_delete_used_folder
;
577 errmsg
= delete_messages
[1][DELETE_LOCKED
];
579 if (ops
->messages
&& ops
->messages
->cant_delete_used_item
)
580 errmsg
= ops
->messages
->cant_delete_used_item
;
582 errmsg
= delete_messages
[0][DELETE_LOCKED
];
587 INTERNAL("Bad delete error code (%d)!", err
);
591 text
= ops
->get_text(item
, term
);
593 if (!text
|| !init_string(&msg
)) {
598 add_format_to_string(&msg
, _(errmsg
, term
), text
);
601 if (item
->type
== BI_LEAF
) {
602 unsigned char *info
= ops
->get_info(item
, term
);
605 add_format_to_string(&msg
, "\n\n%s", info
);
610 info_box(term
, MSGBOX_FREE_TEXT
, N_("Delete error"), ALIGN_LEFT
,
615 do_delete_item(struct listbox_item
*item
, struct listbox_context
*info
,
618 struct listbox_ops
*ops
= info
->box
->ops
;
622 if (!ops
->can_delete(item
)) {
623 print_delete_error(item
, info
->term
, ops
, DELETE_IMPOSSIBLE
);
627 if (ops
->is_used(item
)) {
628 print_delete_error(item
, info
->term
, ops
, DELETE_LOCKED
);
632 ops
->delete(item
, last
);
636 delete_marked(struct listbox_item
*item
, void *data_
, int *offset
)
638 struct listbox_context
*context
= data_
;
640 if (item
->marked
&& !context
->box
->ops
->is_used(item
)) {
641 /* Save the first marked so it can be deleted last */
642 if (!context
->item
) {
643 context
->item
= item
;
645 do_delete_item(item
, context
, 0);
655 push_ok_delete_button(void *context_
)
657 struct listbox_context
*context
= context_
;
658 struct listbox_item
*root
;
662 context
->box
->ops
->unlock(context
->item
);
664 traverse_listbox_items_list(context
->box
->items
->next
,
666 delete_marked
, context
);
667 if (!context
->item
) return;
670 root
= context
->box
->ops
->get_root(context
->item
);
672 last
= context
->item
== root
->child
.prev
;
675 /* Delete the last one (traversal should save one to delete) */
676 do_delete_item(context
->item
, context
, 1);
678 /* If removing the last item in a folder move focus to previous item in
679 * the folder or the root. */
681 listbox_sel_move(context
->widget_data
, -1);
684 widget_handler_status_T
685 push_hierbox_delete_button(struct dialog_data
*dlg_data
,
686 struct widget_data
*button
)
688 struct terminal
*term
= dlg_data
->win
->term
;
689 struct listbox_data
*box
= get_dlg_listbox_data(dlg_data
);
690 struct listbox_context
*context
;
692 enum delete_error
delete;
694 if (!box
->sel
) return EVENT_PROCESSED
;
696 assert(box
->ops
&& box
->ops
->can_delete
&& box
->ops
->delete);
698 context
= init_listbox_context(box
, term
, box
->sel
, scan_for_marks
);
699 if (!context
) return EVENT_PROCESSED
;
701 context
->widget_data
= dlg_data
->widgets_data
;
703 if (!context
->item
) {
704 unsigned char *title
= N_("Delete marked items");
705 unsigned char *message
= N_("Delete marked items?");
707 if (box
->ops
->messages
) {
708 if (box
->ops
->messages
->delete_marked_items
)
709 message
= box
->ops
->messages
->delete_marked_items
;
710 if (box
->ops
->messages
->delete_marked_items_title
)
711 title
= box
->ops
->messages
->delete_marked_items_title
;
714 msg_box(term
, getml(context
, NULL
), 0,
718 N_("~Yes"), push_ok_delete_button
, B_ENTER
,
719 N_("~No"), done_listbox_context
, B_ESC
);
720 return EVENT_PROCESSED
;
723 delete = box
->ops
->can_delete(context
->item
)
724 ? DELETE_LOCKED
: DELETE_IMPOSSIBLE
;
726 if (delete == DELETE_IMPOSSIBLE
|| box
->ops
->is_used(context
->item
)) {
727 print_delete_error(context
->item
, term
, box
->ops
, delete);
729 return EVENT_PROCESSED
;
732 text
= box
->ops
->get_text(context
->item
, term
);
735 return EVENT_PROCESSED
;
738 if (context
->item
->type
== BI_FOLDER
) {
739 unsigned char *title
= N_("Delete folder");
740 unsigned char *message
= N_("Delete the folder \"%s\" and its content?");
742 if (box
->ops
->messages
) {
743 if (box
->ops
->messages
->delete_folder
)
744 message
= box
->ops
->messages
->delete_folder
;
745 if (box
->ops
->messages
->delete_folder_title
)
746 title
= box
->ops
->messages
->delete_folder_title
;
749 box
->ops
->lock(context
->item
);
750 msg_box(term
, getml(context
, NULL
), MSGBOX_FREE_TEXT
,
752 msg_text(term
, message
, text
),
754 N_("~Yes"), push_ok_delete_button
, B_ENTER
,
755 N_("~No"), done_listbox_context
, B_ESC
);
757 unsigned char *title
= N_("Delete item");
758 unsigned char *message
= N_("Delete \"%s\"?\n\n%s");
761 if (box
->ops
->messages
) {
762 if (box
->ops
->messages
->delete_item
)
763 message
= box
->ops
->messages
->delete_item
;
764 if (box
->ops
->messages
->delete_item_title
)
765 title
= box
->ops
->messages
->delete_item_title
;
768 msg
= box
->ops
->get_info(context
->item
, term
);
769 box
->ops
->lock(context
->item
);
771 msg_box(term
, getml(context
, NULL
), MSGBOX_FREE_TEXT
,
773 msg_text(term
, message
, text
, empty_string_or_(msg
)),
775 N_("~Yes"), push_ok_delete_button
, B_ENTER
,
776 N_("~No"), done_listbox_context
, B_ESC
);
781 return EVENT_PROCESSED
;
788 delete_unused(struct listbox_item
*item
, void *data_
, int *offset
)
790 struct listbox_context
*context
= data_
;
792 if (context
->box
->ops
->is_used(item
)) return 0;
794 do_delete_item(item
, context
, 0);
799 do_clear_browser(void *context_
)
801 struct listbox_context
*context
= context_
;
803 traverse_listbox_items_list(context
->box
->items
->next
,
805 delete_unused
, context
);
808 widget_handler_status_T
809 push_hierbox_clear_button(struct dialog_data
*dlg_data
,
810 struct widget_data
*button
)
812 struct listbox_data
*box
= get_dlg_listbox_data(dlg_data
);
813 struct terminal
*term
= dlg_data
->win
->term
;
814 struct listbox_context
*context
;
815 unsigned char *title
= N_("Clear all items");
816 unsigned char *message
= N_("Do you really want to remove all items?");
818 if (!box
->sel
) return EVENT_PROCESSED
;
822 context
= init_listbox_context(box
, term
, NULL
, scan_for_used
);
823 if (!context
) return EVENT_PROCESSED
;
826 /* FIXME: If the clear button should be used for browsers where
827 * not all items can be deleted scan_for_used() should also can
828 * for undeletable and we should be able to pass either delete
830 print_delete_error(context
->item
, term
, box
->ops
, DELETE_LOCKED
);
832 return EVENT_PROCESSED
;
835 if (box
->ops
->messages
) {
836 if (box
->ops
->messages
->clear_all_items
)
837 message
= box
->ops
->messages
->clear_all_items
;
838 if (box
->ops
->messages
->clear_all_items_title
)
839 title
= box
->ops
->messages
->clear_all_items_title
;
842 msg_box(term
, getml(context
, NULL
), 0,
846 N_("~Yes"), do_clear_browser
, B_ENTER
,
847 N_("~No"), NULL
, B_ESC
);
849 return EVENT_PROCESSED
;
856 scan_for_matches(struct listbox_item
*item
, void *info_
, int *offset
)
858 struct listbox_context
*context
= info_
;
859 unsigned char *text
= (unsigned char *) context
->widget_data
;
866 switch (context
->box
->ops
->match(item
, context
->term
, text
)) {
867 case LISTBOX_MATCH_OK
:
868 /* Mark that we have a match by setting the item to non-NULL */
869 context
->item
= item
;
873 case LISTBOX_MATCH_NO
:
877 case LISTBOX_MATCH_IMPOSSIBLE
:
885 mark_visible(struct listbox_item
*item
, void *xxx
, int *offset
)
893 search_hierbox_browser(void *data
, unsigned char *text
)
895 struct dialog_data
*dlg_data
= data
;
896 struct listbox_data
*box
= get_dlg_listbox_data(dlg_data
);
897 struct terminal
*term
= dlg_data
->win
->term
;
898 struct listbox_context
*context
;
900 context
= init_listbox_context(box
, term
, NULL
, NULL
);
901 if (!context
) return;
904 context
->widget_data
= (void *) text
;
906 traverse_listbox_items_list(box
->items
->next
, box
, 0, 0,
907 scan_for_matches
, context
);
909 if (!context
->item
&& *text
) {
910 switch (get_opt_int("document.browse.search.show_not_found")) {
912 info_box(term
, MSGBOX_FREE_TEXT
,
913 N_("Search"), ALIGN_CENTER
,
915 N_("Search string '%s' not found"),
926 traverse_listbox_items_list(box
->items
->next
, box
, 0, 0,
933 widget_handler_status_T
934 push_hierbox_search_button(struct dialog_data
*dlg_data
,
935 struct widget_data
*button
)
937 struct terminal
*term
= dlg_data
->win
->term
;
938 struct listbox_data
*box
= get_dlg_listbox_data(dlg_data
);
940 if (!box
->sel
) return EVENT_PROCESSED
;
942 assert(box
->ops
->match
);
944 input_dialog(term
, NULL
, N_("Search"), N_("Name"),
946 MAX_STR_LEN
, "", 0, 0, NULL
,
947 search_hierbox_browser
, NULL
);
949 return EVENT_PROCESSED
;