Statistics
| Revision:

root / src / alertpanel.c @ 30

History | View | Annotate | Download (9.6 kB)

1
/*
2
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3
 * Copyright (C) 1999-2005 Hiroyuki Yamamoto
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
 */
19
20
#ifdef HAVE_CONFIG_H
21
#  include "config.h"
22
#endif
23
24
#include "defs.h"
25
26
#include <gtk/gtk.h>
27
#include <gdk/gdkkeysyms.h>
28
29
#include "intl.h"
30
#include "alertpanel.h"
31
#include "manage_window.h"
32
#include "utils.h"
33
#include "gtkutils.h"
34
#include "inc.h"
35
#include "stock_pixmap.h"
36
#include "prefs_common.h"
37
38
#define ALERT_PANEL_WIDTH        380
39
#define TITLE_HEIGHT                72
40
#define MESSAGE_HEIGHT                62
41
42
static gboolean alertpanel_is_open = FALSE;
43
static AlertValue value;
44
45
static GtkWidget *dialog;
46
47
static void alertpanel_show                (void);
48
static void alertpanel_create                (const gchar        *title,
49
                                         const gchar        *message,
50
                                         const gchar        *button1_label,
51
                                         const gchar        *button2_label,
52
                                         const gchar        *button3_label,
53
                                         gboolean         can_disable,
54
                                         AlertType         type);
55
56
static void alertpanel_button_toggled        (GtkToggleButton        *button,
57
                                         gpointer                 data);
58
static void alertpanel_button_clicked        (GtkWidget                *widget,
59
                                         gpointer                 data);
60
static gint alertpanel_deleted                (GtkWidget                *widget,
61
                                         GdkEventAny                *event,
62
                                         gpointer                 data);
63
static gboolean alertpanel_close        (GtkWidget                *widget,
64
                                         GdkEventAny                *event,
65
                                         gpointer                 data);
66
67
AlertValue alertpanel(const gchar *title,
68
                      const gchar *message,
69
                      const gchar *button1_label,
70
                      const gchar *button2_label,
71
                      const gchar *button3_label)
72
{
73
        if (alertpanel_is_open)
74
                return -1;
75
        else
76
                alertpanel_is_open = TRUE;
77
78
        alertpanel_create(title, message, button1_label, button2_label,
79
                          button3_label, FALSE, ALERT_QUESTION);
80
        alertpanel_show();
81
82
        debug_print("return value = %d\n", value);
83
        return value;
84
}
85
86
void alertpanel_message(const gchar *title, const gchar *message,
87
                        AlertType type)
88
{
89
        if (alertpanel_is_open)
90
                return;
91
        else
92
                alertpanel_is_open = TRUE;
93
94
        alertpanel_create(title, message, NULL, NULL, NULL, FALSE, type);
95
        alertpanel_show();
96
}
97
98
AlertValue alertpanel_message_with_disable(const gchar *title,
99
                                           const gchar *message,
100
                                           AlertType type)
101
{
102
        if (alertpanel_is_open)
103
                return 0;
104
        else
105
                alertpanel_is_open = TRUE;
106
107
        alertpanel_create(title, message, NULL, NULL, NULL, TRUE, type);
108
        alertpanel_show();
109
110
        return value;
111
}
112
113
void alertpanel_notice(const gchar *format, ...)
114
{
115
        va_list args;
116
        gchar buf[256];
117
118
        va_start(args, format);
119
        g_vsnprintf(buf, sizeof(buf), format, args);
120
        va_end(args);
121
        strretchomp(buf);
122
123
        alertpanel_message(_("Notice"), buf, ALERT_NOTICE);
124
}
125
126
void alertpanel_warning(const gchar *format, ...)
127
{
128
        va_list args;
129
        gchar buf[256];
130
131
        va_start(args, format);
132
        g_vsnprintf(buf, sizeof(buf), format, args);
133
        va_end(args);
134
        strretchomp(buf);
135
136
        alertpanel_message(_("Warning"), buf, ALERT_WARNING);
137
}
138
139
void alertpanel_error(const gchar *format, ...)
140
{
141
        va_list args;
142
        gchar buf[256];
143
144
        va_start(args, format);
145
        g_vsnprintf(buf, sizeof(buf), format, args);
146
        va_end(args);
147
        strretchomp(buf);
148
149
        alertpanel_message(_("Error"), buf, ALERT_ERROR);
150
}
151
152
static void alertpanel_show(void)
153
{
154
        gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
155
        manage_window_set_transient(GTK_WINDOW(dialog));
156
        value = G_ALERTWAIT;
157
158
        inc_lock();
159
        while ((value & G_ALERT_VALUE_MASK) == G_ALERTWAIT)
160
                gtk_main_iteration();
161
162
        gtk_widget_destroy(dialog);
163
        GTK_EVENTS_FLUSH();
164
165
        alertpanel_is_open = FALSE;
166
        inc_unlock();
167
}
168
169
static void alertpanel_create(const gchar *title,
170
                              const gchar *message,
171
                              const gchar *button1_label,
172
                              const gchar *button2_label,
173
                              const gchar *button3_label,
174
                              gboolean           can_disable,
175
                              AlertType    type)
176
{
177
        static PangoFontDescription *font_desc;
178
        StockPixmap stock_pixmap;
179
        GtkWidget *pixmapwid;
180
        GtkWidget *label;
181
        GtkWidget *hbox;
182
        GtkWidget *vbox;
183
        GtkWidget *spc_vbox;
184
        GtkWidget *msg_vbox;
185
        GtkWidget *disable_chkbtn;
186
        GtkWidget *confirm_area;
187
        GtkWidget *button1;
188
        GtkWidget *button2;
189
        GtkWidget *button3;
190
        const gchar *label2;
191
        const gchar *label3;
192
193
        debug_print(_("Creating alert panel dialog...\n"));
194
195
        dialog = gtk_dialog_new();
196
        gtk_window_set_title(GTK_WINDOW(dialog), title);
197
        gtk_window_set_policy(GTK_WINDOW(dialog), FALSE, FALSE, FALSE);
198
        gtk_container_set_border_width
199
                (GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), 5);
200
        gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
201
        g_signal_connect(G_OBJECT(dialog), "delete_event",
202
                         G_CALLBACK(alertpanel_deleted),
203
                         (gpointer)G_ALERTOTHER);
204
        g_signal_connect(G_OBJECT(dialog), "key_press_event",
205
                         G_CALLBACK(alertpanel_close),
206
                         (gpointer)G_ALERTOTHER);
207
        gtk_widget_realize(dialog);
208
209
        /* for title label */
210
        hbox = gtk_hbox_new(FALSE, 0);
211
        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
212
                           hbox, TRUE, TRUE, 8);
213
214
        /* title icon and label */
215
        switch (type) {
216
        case ALERT_NOTICE:
217
                stock_pixmap = STOCK_PIXMAP_DIALOG_INFO; break;
218
        case ALERT_QUESTION:
219
                stock_pixmap = STOCK_PIXMAP_DIALOG_QUESTION; break;
220
        case ALERT_WARNING:
221
                stock_pixmap = STOCK_PIXMAP_DIALOG_WARNING; break;
222
        case ALERT_ERROR:
223
                stock_pixmap = STOCK_PIXMAP_DIALOG_ERROR; break;
224
        default:
225
                stock_pixmap = STOCK_PIXMAP_DIALOG_QUESTION; break;
226
        }
227
        pixmapwid = stock_pixmap_widget(dialog, stock_pixmap);
228
        gtk_box_pack_start(GTK_BOX(hbox), pixmapwid, FALSE, FALSE, 16);
229
230
        label = gtk_label_new(title);
231
        gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
232
        gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
233
        if (!font_desc) {
234
                gchar *fontstr = prefs_common.titlefont
235
                        ? prefs_common.titlefont
236
                        : DEFAULT_TITLE_FONT;
237
                font_desc = pango_font_description_from_string(fontstr);
238
        }
239
        if (font_desc)
240
                gtk_widget_modify_font(label, font_desc);
241
242
        /* for message and button(s) */
243
        vbox = gtk_vbox_new(FALSE, 0);
244
        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
245
                          vbox);
246
247
        spc_vbox = gtk_vbox_new(FALSE, 0);
248
        gtk_box_pack_start(GTK_BOX(vbox), spc_vbox, FALSE, FALSE, 0);
249
        gtk_widget_set_size_request(spc_vbox, -1, 16);
250
251
        msg_vbox = gtk_vbox_new(FALSE, 0);
252
        gtk_box_pack_start(GTK_BOX(vbox), msg_vbox, FALSE, FALSE, 0);
253
254
        /* for message label */
255
        hbox = gtk_hbox_new(FALSE, 0);
256
        gtk_box_pack_start(GTK_BOX(msg_vbox), hbox, FALSE, FALSE, 0);
257
258
        /* message label */
259
        label = gtk_label_new(message);
260
        gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 24);
261
        gtk_label_set_selectable(GTK_LABEL(label), TRUE);
262
        gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
263
264
        if (can_disable) {
265
                hbox = gtk_hbox_new(FALSE, 0);
266
                gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
267
                gtk_container_set_border_width(GTK_CONTAINER(hbox), 8);
268
269
                disable_chkbtn = gtk_check_button_new_with_label
270
                        (_("Show this message next time"));
271
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(disable_chkbtn),
272
                                             TRUE);
273
                gtk_box_pack_start(GTK_BOX(hbox), disable_chkbtn,
274
                                   FALSE, FALSE, 0);
275
                g_signal_connect(G_OBJECT(disable_chkbtn), "toggled",
276
                                 G_CALLBACK(alertpanel_button_toggled),
277
                                 GUINT_TO_POINTER(G_ALERTDISABLE));
278
        } else {
279
                spc_vbox = gtk_vbox_new(FALSE, 0);
280
                gtk_box_pack_start(GTK_BOX(vbox), spc_vbox, FALSE, FALSE, 0);
281
                gtk_widget_set_size_request(spc_vbox, -1, 20);
282
        }
283
284
        /* for button(s) */
285
        if (!button1_label)
286
                button1_label = GTK_STOCK_OK;
287
        label2 = button2_label;
288
        label3 = button3_label;
289
        if (label2 && *label2 == '+') label2++;
290
        if (label3 && *label3 == '+') label3++;
291
292
        gtkut_stock_button_set_create(&confirm_area,
293
                                      &button1, button1_label,
294
                                      button2_label ? &button2 : NULL, label2,
295
                                      button3_label ? &button3 : NULL, label3);
296
297
        gtk_box_pack_end(GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
298
        gtk_widget_grab_default(button1);
299
        gtk_widget_grab_focus(button1);
300
        if (button2_label && *button2_label == '+') {
301
                gtk_widget_grab_default(button2);
302
                gtk_widget_grab_focus(button2);
303
        }
304
        if (button3_label && *button3_label == '+') {
305
                gtk_widget_grab_default(button3);
306
                gtk_widget_grab_focus(button3);
307
        }
308
309
        g_signal_connect(G_OBJECT(button1), "clicked",
310
                         G_CALLBACK(alertpanel_button_clicked),
311
                         GUINT_TO_POINTER(G_ALERTDEFAULT));
312
        if (button2_label)
313
                g_signal_connect(G_OBJECT(button2), "clicked",
314
                                 G_CALLBACK(alertpanel_button_clicked),
315
                                 GUINT_TO_POINTER(G_ALERTALTERNATE));
316
        if (button3_label)
317
                g_signal_connect(G_OBJECT(button3), "clicked",
318
                                 G_CALLBACK(alertpanel_button_clicked),
319
                                 GUINT_TO_POINTER(G_ALERTOTHER));
320
321
        gtk_widget_show_all(dialog);
322
}
323
324
static void alertpanel_button_toggled(GtkToggleButton *button,
325
                                      gpointer data)
326
{
327
        if (gtk_toggle_button_get_active(button))
328
                value &= ~GPOINTER_TO_UINT(data);
329
        else
330
                value |= GPOINTER_TO_UINT(data);
331
}
332
333
static void alertpanel_button_clicked(GtkWidget *widget, gpointer data)
334
{
335
        value = (value & ~G_ALERT_VALUE_MASK) | (AlertValue)data;
336
}
337
338
static gint alertpanel_deleted(GtkWidget *widget, GdkEventAny *event,
339
                               gpointer data)
340
{
341
        value = (value & ~G_ALERT_VALUE_MASK) | (AlertValue)data;
342
        return TRUE;
343
}
344
345
static gboolean alertpanel_close(GtkWidget *widget, GdkEventAny *event,
346
                                 gpointer data)
347
{
348
        if (event->type == GDK_KEY_PRESS)
349
                if (((GdkEventKey *)event)->keyval != GDK_Escape)
350
                        return FALSE;
351
352
        value = (value & ~G_ALERT_VALUE_MASK) | (AlertValue)data;
353
        return FALSE;
354
}