1
/* Prefabricated message box implementation. */
2
/* $Id: msgbox.c,v 1.88 2003/11/29 01:46:26 jonas Exp $ */
12
#include "bfu/dialog.h"
13
#include "bfu/button.h"
14
#include "bfu/msgbox.h"
15
#include "bfu/style.h"
17
#include "intl/gettext/libintl.h"
18
#include "terminal/terminal.h"
19
#include "util/color.h"
20
#include "util/memlist.h"
21
#include "util/memory.h"
22
#include "util/snprintf.h"
23
#include "util/string.h"
27
msg_box(struct terminal *term, struct memory_list *ml, enum msgbox_flags flags,
28
unsigned char *title, enum format_align align,
29
unsigned char *text, void *udata, int buttons, ...)
34
/* Check if the info string is valid. */
35
if (!text || buttons < 0) return NULL;
37
/* Use the @flags to determine whether @text should be free()d. */
38
if (flags & MSGBOX_FREE_TEXT)
39
add_one_to_ml(&ml, text);
41
/* Use the @flags to determine whether strings should be l18n'd. */
42
if (!(flags & MSGBOX_NO_INTL)) {
43
title = _(title, term);
44
if (!(flags & MSGBOX_FREE_TEXT)) text = _(text, term);
45
/* Button labels will be gettextized as will they be extracted
49
dlg = calloc_dialog(buttons + 1, 0);
55
add_one_to_ml(&ml, dlg);
58
dlg->layouter = generic_dialog_layouter;
59
dlg->layout.padding_top = 1;
62
if (flags & MSGBOX_SCROLLABLE)
63
dlg->widgets->info.text.is_scrollable = 1;
64
add_dlg_text(dlg, text, align, 0);
66
va_start(ap, buttons);
68
while (dlg->widgets_size < buttons + 1) {
73
label = va_arg(ap, unsigned char *);
74
fn = va_arg(ap, void *);
75
bflags = va_arg(ap, int);
78
/* Skip this button. */
83
if (!(flags & MSGBOX_NO_INTL))
84
label = _(label, term);
86
add_dlg_ok_button(dlg, bflags, label, fn, udata);
91
add_dlg_end(dlg, buttons + 1);
93
return do_dialog(term, dlg, ml);
96
/* Do not inline this function, because with inline
97
* elinks segfaults on Cygwin */
98
static unsigned char *
99
msg_text_do(unsigned char *format, va_list ap)
107
infolen = vsnprintf(NULL, 0, format, ap2);
108
info = mem_alloc(infolen + 1);
110
if (vsnprintf((char *) info, infolen + 1, format, ap) != infolen) {
114
/* Wear safety boots */
115
info[infolen] = '\0';
123
msg_text_ni(unsigned char *format, ...)
128
va_start(ap, format);
129
info = msg_text_do(format, ap);
136
msg_text(struct terminal *term, unsigned char *format, ...)
141
va_start(ap, format);
142
info = msg_text_do(_(format, term), ap);
149
abort_refreshed_msg_box_handler(struct dialog_data *dlg_data)
151
if (dlg_data->dlg->udata != dlg_data->dlg->widgets->text)
152
mem_free(dlg_data->dlg->widgets->text);
155
static enum dlg_refresh_code
156
refresh_msg_box(struct dialog_data *dlg_data, void *data)
158
unsigned char *(*get_info)(struct terminal *, void *) = data;
159
void *msg_data = dlg_data->dlg->udata2;
160
unsigned char *info = get_info(dlg_data->win->term, msg_data);
162
if (!info) return REFRESH_CANCEL;
164
abort_refreshed_msg_box_handler(dlg_data);
166
dlg_data->dlg->widgets->text = info;
167
return REFRESH_DIALOG;
171
refreshed_msg_box(struct terminal *term, enum msgbox_flags flags,
172
unsigned char *title, enum format_align align,
173
unsigned char *(get_info)(struct terminal *, void *),
176
struct dialog_data *dlg_data;
177
unsigned char *info = get_info(term, data);
181
dlg_data = msg_box(term, NULL, flags | MSGBOX_FREE_TEXT,
185
N_("OK"), NULL, B_ENTER | B_ESC);
188
/* Save the original text to check up on it when the dialog
190
dlg_data->dlg->udata = info;
191
dlg_data->dlg->abort = abort_refreshed_msg_box_handler;
192
refresh_dialog(dlg_data, refresh_msg_box, get_info);