Statistics
| Revision:

root / src / alertpanel.c @ 1

History | View | Annotate | Download (9.5 KB)

1
/*
2
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3
 * Copyright (C) 1999-2004 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_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
262

    
263
        if (can_disable) {
264
                hbox = gtk_hbox_new(FALSE, 0);
265
                gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
266
                gtk_container_set_border_width(GTK_CONTAINER(hbox), 8);
267

    
268
                disable_chkbtn = gtk_check_button_new_with_label
269
                        (_("Show this message next time"));
270
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(disable_chkbtn),
271
                                             TRUE);
272
                gtk_box_pack_start(GTK_BOX(hbox), disable_chkbtn,
273
                                   FALSE, FALSE, 0);
274
                g_signal_connect(G_OBJECT(disable_chkbtn), "toggled",
275
                                 G_CALLBACK(alertpanel_button_toggled),
276
                                 GUINT_TO_POINTER(G_ALERTDISABLE));
277
        } else {
278
                spc_vbox = gtk_vbox_new(FALSE, 0);
279
                gtk_box_pack_start(GTK_BOX(vbox), spc_vbox, FALSE, FALSE, 0);
280
                gtk_widget_set_size_request(spc_vbox, -1, 20);
281
        }
282

    
283
        /* for button(s) */
284
        if (!button1_label)
285
                button1_label = _("OK");
286
        label2 = button2_label;
287
        label3 = button3_label;
288
        if (label2 && *label2 == '+') label2++;
289
        if (label3 && *label3 == '+') label3++;
290

    
291
        gtkut_button_set_create(&confirm_area,
292
                                &button1, button1_label,
293
                                button2_label ? &button2 : NULL, label2,
294
                                button3_label ? &button3 : NULL, label3);
295

    
296
        gtk_box_pack_end(GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
297
        gtk_widget_grab_default(button1);
298
        gtk_widget_grab_focus(button1);
299
        if (button2_label && *button2_label == '+') {
300
                gtk_widget_grab_default(button2);
301
                gtk_widget_grab_focus(button2);
302
        }
303
        if (button3_label && *button3_label == '+') {
304
                gtk_widget_grab_default(button3);
305
                gtk_widget_grab_focus(button3);
306
        }
307

    
308
        g_signal_connect(G_OBJECT(button1), "clicked",
309
                         G_CALLBACK(alertpanel_button_clicked),
310
                         GUINT_TO_POINTER(G_ALERTDEFAULT));
311
        if (button2_label)
312
                g_signal_connect(G_OBJECT(button2), "clicked",
313
                                 G_CALLBACK(alertpanel_button_clicked),
314
                                 GUINT_TO_POINTER(G_ALERTALTERNATE));
315
        if (button3_label)
316
                g_signal_connect(G_OBJECT(button3), "clicked",
317
                                 G_CALLBACK(alertpanel_button_clicked),
318
                                 GUINT_TO_POINTER(G_ALERTOTHER));
319

    
320
        gtk_widget_show_all(dialog);
321
}
322

    
323
static void alertpanel_button_toggled(GtkToggleButton *button,
324
                                      gpointer data)
325
{
326
        if (gtk_toggle_button_get_active(button))
327
                value &= ~GPOINTER_TO_UINT(data);
328
        else
329
                value |= GPOINTER_TO_UINT(data);
330
}
331

    
332
static void alertpanel_button_clicked(GtkWidget *widget, gpointer data)
333
{
334
        value = (value & ~G_ALERT_VALUE_MASK) | (AlertValue)data;
335
}
336

    
337
static gint alertpanel_deleted(GtkWidget *widget, GdkEventAny *event,
338
                               gpointer data)
339
{
340
        value = (value & ~G_ALERT_VALUE_MASK) | (AlertValue)data;
341
        return TRUE;
342
}
343

    
344
static gboolean alertpanel_close(GtkWidget *widget, GdkEventAny *event,
345
                                 gpointer data)
346
{
347
        if (event->type == GDK_KEY_PRESS)
348
                if (((GdkEventKey *)event)->keyval != GDK_Escape)
349
                        return FALSE;
350

    
351
        value = (value & ~G_ALERT_VALUE_MASK) | (AlertValue)data;
352
        return FALSE;
353
}