~ubuntu-branches/ubuntu/feisty/elinks/feisty-updates

« back to all changes in this revision

Viewing changes to src/bfu/msgbox.c

  • Committer: Bazaar Package Importer
  • Author(s): Peter Gervai
  • Date: 2004-01-21 22:13:45 UTC
  • Revision ID: james.westby@ubuntu.com-20040121221345-ju33hai1yhhqt6kn
Tags: upstream-0.9.1
ImportĀ upstreamĀ versionĀ 0.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Prefabricated message box implementation. */
 
2
/* $Id: msgbox.c,v 1.88 2003/11/29 01:46:26 jonas Exp $ */
 
3
 
 
4
#ifdef HAVE_CONFIG_H
 
5
#include "config.h"
 
6
#endif
 
7
 
 
8
#include <stdarg.h>
 
9
 
 
10
#include "elinks.h"
 
11
 
 
12
#include "bfu/dialog.h"
 
13
#include "bfu/button.h"
 
14
#include "bfu/msgbox.h"
 
15
#include "bfu/style.h"
 
16
#include "bfu/text.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"
 
24
 
 
25
 
 
26
struct dialog_data *
 
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, ...)
 
30
{
 
31
        struct dialog *dlg;
 
32
        va_list ap;
 
33
 
 
34
        /* Check if the info string is valid. */
 
35
        if (!text || buttons < 0) return NULL;
 
36
 
 
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);
 
40
 
 
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
 
46
                 * from @ap. */
 
47
        }
 
48
 
 
49
        dlg = calloc_dialog(buttons + 1, 0);
 
50
        if (!dlg) {
 
51
                freeml(ml);
 
52
                return NULL;
 
53
        }
 
54
 
 
55
        add_one_to_ml(&ml, dlg);
 
56
 
 
57
        dlg->title = title;
 
58
        dlg->layouter = generic_dialog_layouter;
 
59
        dlg->layout.padding_top = 1;
 
60
        dlg->udata2 = udata;
 
61
 
 
62
        if (flags & MSGBOX_SCROLLABLE)
 
63
                dlg->widgets->info.text.is_scrollable = 1;
 
64
        add_dlg_text(dlg, text, align, 0);
 
65
 
 
66
        va_start(ap, buttons);
 
67
 
 
68
        while (dlg->widgets_size < buttons + 1) {
 
69
                unsigned char *label;
 
70
                void (*fn)(void *);
 
71
                int bflags;
 
72
 
 
73
                label = va_arg(ap, unsigned char *);
 
74
                fn = va_arg(ap, void *);
 
75
                bflags = va_arg(ap, int);
 
76
 
 
77
                if (!label) {
 
78
                        /* Skip this button. */
 
79
                        buttons--;
 
80
                        continue;
 
81
                }
 
82
 
 
83
                if (!(flags & MSGBOX_NO_INTL))
 
84
                        label = _(label, term);
 
85
 
 
86
                add_dlg_ok_button(dlg, bflags, label, fn, udata);
 
87
        }
 
88
 
 
89
        va_end(ap);
 
90
 
 
91
        add_dlg_end(dlg, buttons + 1);
 
92
 
 
93
        return do_dialog(term, dlg, ml);
 
94
}
 
95
 
 
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)
 
100
{
 
101
        unsigned char *info;
 
102
        int infolen;
 
103
        va_list ap2;
 
104
 
 
105
        VA_COPY(ap2, ap);
 
106
 
 
107
        infolen = vsnprintf(NULL, 0, format, ap2);
 
108
        info = mem_alloc(infolen + 1);
 
109
        if (info) {
 
110
                if (vsnprintf((char *) info, infolen + 1, format, ap) != infolen) {
 
111
                        mem_free(info);
 
112
                        info = NULL;
 
113
                } else {
 
114
                        /* Wear safety boots */
 
115
                        info[infolen] = '\0';
 
116
                }
 
117
        }
 
118
 
 
119
        return info;
 
120
}
 
121
 
 
122
unsigned char *
 
123
msg_text_ni(unsigned char *format, ...)
 
124
{
 
125
        unsigned char *info;
 
126
        va_list ap;
 
127
 
 
128
        va_start(ap, format);
 
129
        info = msg_text_do(format, ap);
 
130
        va_end(ap);
 
131
 
 
132
        return info;
 
133
}
 
134
 
 
135
unsigned char *
 
136
msg_text(struct terminal *term, unsigned char *format, ...)
 
137
{
 
138
        unsigned char *info;
 
139
        va_list ap;
 
140
 
 
141
        va_start(ap, format);
 
142
        info = msg_text_do(_(format, term), ap);
 
143
        va_end(ap);
 
144
 
 
145
        return info;
 
146
}
 
147
 
 
148
static void
 
149
abort_refreshed_msg_box_handler(struct dialog_data *dlg_data)
 
150
{
 
151
        if (dlg_data->dlg->udata != dlg_data->dlg->widgets->text)
 
152
                mem_free(dlg_data->dlg->widgets->text);
 
153
}
 
154
 
 
155
static enum dlg_refresh_code
 
156
refresh_msg_box(struct dialog_data *dlg_data, void *data)
 
157
{
 
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);
 
161
 
 
162
        if (!info) return REFRESH_CANCEL;
 
163
 
 
164
        abort_refreshed_msg_box_handler(dlg_data);
 
165
 
 
166
        dlg_data->dlg->widgets->text = info;
 
167
        return REFRESH_DIALOG;
 
168
}
 
169
 
 
170
void
 
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 *),
 
174
                  void *data)
 
175
{
 
176
        struct dialog_data *dlg_data;
 
177
        unsigned char *info = get_info(term, data);
 
178
 
 
179
        if (!info) return;
 
180
 
 
181
        dlg_data = msg_box(term, NULL, flags | MSGBOX_FREE_TEXT,
 
182
                           title, align,
 
183
                           info,
 
184
                           data, 1,
 
185
                           N_("OK"), NULL, B_ENTER | B_ESC);
 
186
 
 
187
        if (dlg_data) {
 
188
                /* Save the original text to check up on it when the dialog
 
189
                 * is freed. */
 
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);
 
193
        }
 
194
}