Statistics
| Revision:

root / src / inputdialog.c @ 2196

History | View | Annotate | Download (8.6 kB)

1
/*
2
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3
 * Copyright (C) 1999-2006 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 <glib.h>
25
#include <glib/gi18n.h>
26
#include <gdk/gdkkeysyms.h>
27
#include <gtk/gtkmain.h>
28
#include <gtk/gtkwidget.h>
29
#include <gtk/gtkdialog.h>
30
#include <gtk/gtkwindow.h>
31
#include <gtk/gtksignal.h>
32
#include <gtk/gtkvbox.h>
33
#include <gtk/gtkhbox.h>
34
#include <gtk/gtklabel.h>
35
#include <gtk/gtkentry.h>
36
#include <gtk/gtkcombo.h>
37
#include <gtk/gtkbutton.h>
38
#include <gtk/gtkhbbox.h>
39
#include <gtk/gtkstock.h>
40
41
#include "inputdialog.h"
42
#include "manage_window.h"
43
#include "inc.h"
44
#include "prefs_common.h"
45
#include "gtkutils.h"
46
#include "utils.h"
47
48
#define INPUT_ENTRY_WIDTH        400
49
50
typedef enum
51
{
52
        INPUT_DIALOG_NORMAL,
53
        INPUT_DIALOG_INVISIBLE,
54
        INPUT_DIALOG_COMBO
55
} InputDialogType;
56
57
static gboolean ack;
58
static gboolean fin;
59
60
static InputDialogType type;
61
62
static GtkWidget *dialog;
63
static GtkWidget *msg_label;
64
static GtkWidget *entry;
65
static GtkWidget *combo;
66
static GtkWidget *confirm_area;
67
static GtkWidget *ok_button;
68
69
static void input_dialog_create        (InputDialogType        dialog_type);
70
71
static gchar *input_dialog_open        (const gchar        *title,
72
                                 const gchar        *message,
73
                                 const gchar        *default_string);
74
static void input_dialog_set        (const gchar        *title,
75
                                 const gchar        *message,
76
                                 const gchar        *default_string);
77
78
static void ok_clicked                (GtkWidget        *widget,
79
                                 gpointer         data);
80
static void cancel_clicked        (GtkWidget        *widget,
81
                                 gpointer         data);
82
static gint delete_event        (GtkWidget        *widget,
83
                                 GdkEventAny        *event,
84
                                 gpointer         data);
85
static gboolean key_pressed        (GtkWidget        *widget,
86
                                 GdkEventKey        *event,
87
                                 gpointer         data);
88
static void entry_activated        (GtkEditable        *editable);
89
static void combo_activated        (GtkEditable        *editable);
90
static gint focus_out                (GtkWidget        *widget,
91
                                 GdkEventFocus        *event,
92
                                 gpointer         data);
93
94
95
gchar *input_dialog(const gchar *title, const gchar *message,
96
                    const gchar *default_string)
97
{
98
        if (dialog)
99
                return NULL;
100
101
        input_dialog_create(INPUT_DIALOG_NORMAL);
102
103
        return input_dialog_open(title, message, default_string);
104
}
105
106
gchar *input_dialog_with_invisible(const gchar *title, const gchar *message,
107
                                   const gchar *default_string)
108
{
109
        if (dialog)
110
                return NULL;
111
112
        input_dialog_create(INPUT_DIALOG_INVISIBLE);
113
114
        return input_dialog_open(title, message, default_string);
115
}
116
117
gchar *input_dialog_combo(const gchar *title, const gchar *message,
118
                          const gchar *default_string, GList *list,
119
                          gboolean case_sensitive)
120
{
121
        if (dialog)
122
                return NULL;
123
124
        input_dialog_create(INPUT_DIALOG_COMBO);
125
126
        if (!list) {
127
                GList empty_list;
128
129
                empty_list.data = (gpointer)"";
130
                empty_list.next = NULL;
131
                empty_list.prev = NULL;
132
                gtk_combo_set_popdown_strings(GTK_COMBO(combo), &empty_list);
133
        } else
134
                gtk_combo_set_popdown_strings(GTK_COMBO(combo), list);
135
136
        gtk_combo_set_case_sensitive(GTK_COMBO(combo), case_sensitive);
137
138
        return input_dialog_open(title, message, default_string);
139
}
140
141
gchar *input_dialog_query_password(const gchar *server, const gchar *user)
142
{
143
        gchar *message;
144
        gchar *pass;
145
146
        message = g_strdup_printf(_("Input password for %s on %s:"),
147
                                  user, server);
148
        pass = input_dialog_with_invisible(_("Input password"), message, NULL);
149
        g_free(message);
150
151
        return pass;
152
}
153
154
static void input_dialog_create(InputDialogType dialog_type)
155
{
156
        GtkWidget *vbox;
157
        GtkWidget *hbox;
158
        GtkWidget *cancel_button;
159
160
        dialog = gtk_dialog_new();
161
        gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
162
        gtk_container_set_border_width
163
                (GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), 5);
164
        gtk_window_set_position(GTK_WINDOW(dialog),
165
                                GTK_WIN_POS_CENTER_ON_PARENT);
166
        gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
167
        manage_window_set_transient(GTK_WINDOW(dialog));
168
        g_signal_connect(G_OBJECT(dialog), "delete_event",
169
                         G_CALLBACK(delete_event), NULL);
170
        g_signal_connect(G_OBJECT(dialog), "key_press_event",
171
                         G_CALLBACK(key_pressed), NULL);
172
        g_signal_connect(G_OBJECT(dialog), "focus_out_event",
173
                         G_CALLBACK(focus_out), NULL);
174
        MANAGE_WINDOW_SIGNALS_CONNECT(dialog);
175
176
        vbox = gtk_vbox_new(FALSE, 8);
177
        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), vbox);
178
        gtk_container_set_border_width(GTK_CONTAINER(vbox), 8);
179
180
        hbox = gtk_hbox_new(FALSE, 0);
181
        gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
182
183
        msg_label = gtk_label_new("");
184
        gtk_box_pack_start(GTK_BOX(hbox), msg_label, FALSE, FALSE, 0);
185
        gtk_label_set_justify(GTK_LABEL(msg_label), GTK_JUSTIFY_LEFT);
186
187
        type = dialog_type;
188
189
        if (dialog_type == INPUT_DIALOG_COMBO) {
190
                combo = gtk_combo_new();
191
                gtk_box_pack_start(GTK_BOX(vbox), combo, FALSE, FALSE, 0);
192
                gtk_widget_set_size_request(combo, INPUT_ENTRY_WIDTH, -1);
193
                g_signal_connect(G_OBJECT(GTK_COMBO(combo)->entry), "activate",
194
                                 G_CALLBACK(combo_activated), NULL);
195
        } else {
196
                entry = gtk_entry_new();
197
                gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0);
198
                gtk_widget_set_size_request(entry, INPUT_ENTRY_WIDTH, -1);
199
                g_signal_connect(G_OBJECT(entry), "activate",
200
                                 G_CALLBACK(entry_activated), NULL);
201
                if (dialog_type == INPUT_DIALOG_INVISIBLE)
202
                        gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
203
        }
204
205
        gtkut_stock_button_set_create(&confirm_area,
206
                                      &ok_button, GTK_STOCK_OK,
207
                                      &cancel_button, GTK_STOCK_CANCEL,
208
                                      NULL, NULL);
209
        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
210
                          confirm_area);
211
        gtk_widget_grab_default(ok_button);
212
213
        g_signal_connect(G_OBJECT(ok_button), "clicked",
214
                         G_CALLBACK(ok_clicked), NULL);
215
        g_signal_connect(G_OBJECT(cancel_button), "clicked",
216
                         G_CALLBACK(cancel_clicked), NULL);
217
218
        gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
219
}
220
221
static gchar *input_dialog_open(const gchar *title, const gchar *message,
222
                                const gchar *default_string)
223
{
224
        gchar *str;
225
226
        gtkut_box_set_reverse_order(GTK_BOX(confirm_area),
227
                                    !prefs_common.comply_gnome_hig);
228
        input_dialog_set(title, message, default_string);
229
        gtk_widget_show(dialog);
230
231
        ack = fin = FALSE;
232
233
        inc_lock();
234
235
        while (fin == FALSE)
236
                gtk_main_iteration();
237
238
        manage_window_focus_out(dialog, NULL, NULL);
239
240
        if (ack) {
241
                GtkEditable *editable;
242
243
                if (type == INPUT_DIALOG_COMBO)
244
                        editable = GTK_EDITABLE(GTK_COMBO(combo)->entry);
245
                else
246
                        editable = GTK_EDITABLE(entry);
247
248
                str = gtk_editable_get_chars(editable, 0, -1);
249
                if (str && *str == '\0') {
250
                        g_free(str);
251
                        str = NULL;
252
                }
253
        } else
254
                str = NULL;
255
256
        gtk_widget_destroy(dialog);
257
        dialog = msg_label = entry = combo = confirm_area = ok_button = NULL;
258
259
        GTK_EVENTS_FLUSH();
260
261
        inc_unlock();
262
263
        if (type != INPUT_DIALOG_INVISIBLE)
264
                debug_print("return string = %s\n", str ? str : "(none)");
265
266
        return str;
267
}
268
269
static void input_dialog_set(const gchar *title, const gchar *message,
270
                             const gchar *default_string)
271
{
272
        GtkWidget *entry_;
273
274
        if (type == INPUT_DIALOG_COMBO)
275
                entry_ = GTK_COMBO(combo)->entry;
276
        else
277
                entry_ = entry;
278
279
        gtk_window_set_title(GTK_WINDOW(dialog), title);
280
        gtk_label_set_text(GTK_LABEL(msg_label), message);
281
        if (default_string && *default_string) {
282
                gtk_entry_set_text(GTK_ENTRY(entry_), default_string);
283
                gtk_entry_set_position(GTK_ENTRY(entry_), 0);
284
                gtk_entry_select_region(GTK_ENTRY(entry_), 0, -1);
285
        } else
286
                gtk_entry_set_text(GTK_ENTRY(entry_), "");
287
288
        gtk_widget_grab_focus(ok_button);
289
        gtk_widget_grab_focus(entry_);
290
}
291
292
static void ok_clicked(GtkWidget *widget, gpointer data)
293
{
294
        ack = TRUE;
295
        fin = TRUE;
296
}
297
298
static void cancel_clicked(GtkWidget *widget, gpointer data)
299
{
300
        ack = FALSE;
301
        fin = TRUE;
302
}
303
304
static gint delete_event(GtkWidget *widget, GdkEventAny *event, gpointer data)
305
{
306
        ack = FALSE;
307
        fin = TRUE;
308
309
        return TRUE;
310
}
311
312
static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
313
{
314
        if (event && event->keyval == GDK_Escape) {
315
                ack = FALSE;
316
                fin = TRUE;
317
        }
318
319
        return FALSE;
320
}
321
322
static void entry_activated(GtkEditable *editable)
323
{
324
        ack = TRUE;
325
        fin = TRUE;
326
}
327
328
static void combo_activated(GtkEditable *editable)
329
{
330
        ack = TRUE;
331
        fin = TRUE;
332
}
333
334
static gint focus_out(GtkWidget *widget, GdkEventFocus *event, gpointer data)
335
{
336
#ifdef G_OS_WIN32
337
        gtk_window_present(GTK_WINDOW(widget));
338
#endif
339
        return FALSE;
340
}