Statistics
| Revision:

root / src / inputdialog.c @ 1

History | View | Annotate | Download (8.23 KB)

1
/*
2
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3
 * Copyright (C) 1999-2003 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 <gdk/gdkkeysyms.h>
26
#include <gtk/gtkmain.h>
27
#include <gtk/gtkwidget.h>
28
#include <gtk/gtkdialog.h>
29
#include <gtk/gtkwindow.h>
30
#include <gtk/gtksignal.h>
31
#include <gtk/gtkvbox.h>
32
#include <gtk/gtkhbox.h>
33
#include <gtk/gtklabel.h>
34
#include <gtk/gtkentry.h>
35
#include <gtk/gtkcombo.h>
36
#include <gtk/gtkbutton.h>
37
#include <gtk/gtkhbbox.h>
38

    
39
#include "intl.h"
40
#include "inputdialog.h"
41
#include "manage_window.h"
42
#include "inc.h"
43
#include "gtkutils.h"
44
#include "utils.h"
45

    
46
#define INPUT_DIALOG_WIDTH        420
47

    
48
typedef enum
49
{
50
        INPUT_DIALOG_NORMAL,
51
        INPUT_DIALOG_INVISIBLE,
52
        INPUT_DIALOG_COMBO
53
} InputDialogType;
54

    
55
static gboolean ack;
56
static gboolean fin;
57

    
58
static InputDialogType type;
59

    
60
static GtkWidget *dialog;
61
static GtkWidget *msg_label;
62
static GtkWidget *entry;
63
static GtkWidget *combo;
64
static GtkWidget *ok_button;
65

    
66
static void input_dialog_create        (void);
67
static gchar *input_dialog_open        (const gchar        *title,
68
                                 const gchar        *message,
69
                                 const gchar        *default_string);
70
static void input_dialog_set        (const gchar        *title,
71
                                 const gchar        *message,
72
                                 const gchar        *default_string);
73

    
74
static void ok_clicked                (GtkWidget        *widget,
75
                                 gpointer         data);
76
static void cancel_clicked        (GtkWidget        *widget,
77
                                 gpointer         data);
78
static gint delete_event        (GtkWidget        *widget,
79
                                 GdkEventAny        *event,
80
                                 gpointer         data);
81
static gboolean key_pressed        (GtkWidget        *widget,
82
                                 GdkEventKey        *event,
83
                                 gpointer         data);
84
static void entry_activated        (GtkEditable        *editable);
85
static void combo_activated        (GtkEditable        *editable);
86

    
87

    
88
gchar *input_dialog(const gchar *title, const gchar *message,
89
                    const gchar *default_string)
90
{
91
        if (dialog && GTK_WIDGET_VISIBLE(dialog)) return NULL;
92

    
93
        if (!dialog)
94
                input_dialog_create();
95

    
96
        type = INPUT_DIALOG_NORMAL;
97
        gtk_widget_hide(combo);
98
        gtk_widget_show(entry);
99
        gtk_entry_set_visibility(GTK_ENTRY(entry), TRUE);
100

    
101
        return input_dialog_open(title, message, default_string);
102
}
103

    
104
gchar *input_dialog_with_invisible(const gchar *title, const gchar *message,
105
                                   const gchar *default_string)
106
{
107
        if (dialog && GTK_WIDGET_VISIBLE(dialog)) return NULL;
108

    
109
        if (!dialog)
110
                input_dialog_create();
111

    
112
        type = INPUT_DIALOG_INVISIBLE;
113
        gtk_widget_hide(combo);
114
        gtk_widget_show(entry);
115
        gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
116

    
117
        return input_dialog_open(title, message, default_string);
118
}
119

    
120
gchar *input_dialog_combo(const gchar *title, const gchar *message,
121
                          const gchar *default_string, GList *list,
122
                          gboolean case_sensitive)
123
{
124
        if (dialog && GTK_WIDGET_VISIBLE(dialog)) return NULL;
125

    
126
        if (!dialog)
127
                input_dialog_create();
128

    
129
        type = INPUT_DIALOG_COMBO;
130
        gtk_widget_hide(entry);
131
        gtk_widget_show(combo);
132

    
133
        if (!list) {
134
                GList empty_list;
135

    
136
                empty_list.data = (gpointer)"";
137
                empty_list.next = NULL;
138
                empty_list.prev = NULL;
139
                gtk_combo_set_popdown_strings(GTK_COMBO(combo), &empty_list);
140
        } else
141
                gtk_combo_set_popdown_strings(GTK_COMBO(combo), list);
142

    
143
        gtk_combo_set_case_sensitive(GTK_COMBO(combo), case_sensitive);
144

    
145
        return input_dialog_open(title, message, default_string);
146
}
147

    
148
gchar *input_dialog_query_password(const gchar *server, const gchar *user)
149
{
150
        gchar *message;
151
        gchar *pass;
152

    
153
        message = g_strdup_printf(_("Input password for %s on %s:"),
154
                                  user, server);
155
        pass = input_dialog_with_invisible(_("Input password"), message, NULL);
156
        g_free(message);
157

    
158
        return pass;
159
}
160

    
161
static void input_dialog_create(void)
162
{
163
        GtkWidget *vbox;
164
        GtkWidget *hbox;
165
        GtkWidget *confirm_area;
166
        GtkWidget *cancel_button;
167

    
168
        dialog = gtk_dialog_new();
169
        gtk_window_set_policy(GTK_WINDOW(dialog), FALSE, FALSE, FALSE);
170
        gtk_widget_set_size_request(dialog, INPUT_DIALOG_WIDTH, -1);
171
        gtk_container_set_border_width
172
                (GTK_CONTAINER(GTK_DIALOG(dialog)->action_area), 5);
173
        gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER);
174
        g_signal_connect(G_OBJECT(dialog), "delete_event",
175
                         G_CALLBACK(delete_event), NULL);
176
        g_signal_connect(G_OBJECT(dialog), "key_press_event",
177
                         G_CALLBACK(key_pressed), NULL);
178
        MANAGE_WINDOW_SIGNALS_CONNECT(dialog);
179

    
180
        gtk_widget_realize(dialog);
181

    
182
        vbox = gtk_vbox_new(FALSE, 8);
183
        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), vbox);
184
        gtk_container_set_border_width(GTK_CONTAINER(vbox), 8);
185

    
186
        hbox = gtk_hbox_new(FALSE, 0);
187
        gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
188

    
189
        msg_label = gtk_label_new("");
190
        gtk_box_pack_start(GTK_BOX(hbox), msg_label, FALSE, FALSE, 0);
191
        gtk_label_set_justify(GTK_LABEL(msg_label), GTK_JUSTIFY_LEFT);
192

    
193
        entry = gtk_entry_new();
194
        gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0);
195
        g_signal_connect(G_OBJECT(entry), "activate",
196
                         G_CALLBACK(entry_activated), NULL);
197

    
198
        combo = gtk_combo_new();
199
        gtk_box_pack_start(GTK_BOX(vbox), combo, FALSE, FALSE, 0);
200
        g_signal_connect(G_OBJECT(GTK_COMBO(combo)->entry), "activate",
201
                         G_CALLBACK(combo_activated), NULL);
202

    
203
        gtkut_button_set_create(&confirm_area,
204
                                &ok_button,     _("OK"),
205
                                &cancel_button, _("Cancel"),
206
                                NULL, NULL);
207
        gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
208
                          confirm_area);
209
        gtk_widget_grab_default(ok_button);
210

    
211
        g_signal_connect(G_OBJECT(ok_button), "clicked",
212
                         G_CALLBACK(ok_clicked), NULL);
213
        g_signal_connect(G_OBJECT(cancel_button), "clicked",
214
                         G_CALLBACK(cancel_clicked), NULL);
215

    
216

    
217
        gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
218
}
219

    
220
static gchar *input_dialog_open(const gchar *title, const gchar *message,
221
                                const gchar *default_string)
222
{
223
        gchar *str;
224

    
225
        if (dialog && GTK_WIDGET_VISIBLE(dialog)) return NULL;
226

    
227
        if (!dialog)
228
                input_dialog_create();
229

    
230
        input_dialog_set(title, message, default_string);
231
        gtk_widget_show(dialog);
232
        gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
233
        manage_window_set_transient(GTK_WINDOW(dialog));
234

    
235
        ack = fin = FALSE;
236

    
237
        inc_lock();
238

    
239
        while (fin == FALSE)
240
                gtk_main_iteration();
241

    
242
        manage_window_focus_out(dialog, NULL, NULL);
243
        gtk_widget_hide(dialog);
244

    
245
        if (ack) {
246
                GtkEditable *editable;
247

    
248
                if (type == INPUT_DIALOG_COMBO)
249
                        editable = GTK_EDITABLE(GTK_COMBO(combo)->entry);
250
                else
251
                        editable = GTK_EDITABLE(entry);
252

    
253
                str = gtk_editable_get_chars(editable, 0, -1);
254
                if (str && *str == '\0') {
255
                        g_free(str);
256
                        str = NULL;
257
                }
258
        } else
259
                str = NULL;
260

    
261
        GTK_EVENTS_FLUSH();
262

    
263
        inc_unlock();
264

    
265
        debug_print("return string = %s\n", str ? str : "(none)");
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
}