Statistics
| Revision:

root / src / prefs_ui.c @ 3070

History | View | Annotate | Download (13.4 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 <gtk/gtk.h>
27
#include <stdio.h>
28
#include <stdlib.h>
29
#include <string.h>
30
#include <unistd.h>
31
#include <errno.h>
32
33
#include "prefs.h"
34
#include "prefs_ui.h"
35
#include "menu.h"
36
#include "codeconv.h"
37
#include "utils.h"
38
#include "gtkutils.h"
39
40
typedef enum
41
{
42
        DUMMY_PARAM
43
} DummyEnum;
44
45
void prefs_dialog_create(PrefsDialog *dialog)
46
{
47
        GtkWidget *window;
48
        GtkWidget *vbox;
49
        GtkWidget *notebook;
50
51
        GtkWidget *confirm_area;
52
        GtkWidget *ok_btn;
53
        GtkWidget *cancel_btn;
54
        GtkWidget *apply_btn;
55
56
        g_return_if_fail(dialog != NULL);
57
58
        window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
59
        gtk_container_set_border_width (GTK_CONTAINER (window), 6);
60
        gtk_window_set_position (GTK_WINDOW(window), GTK_WIN_POS_CENTER);
61
        gtk_window_set_modal (GTK_WINDOW (window), TRUE);
62
        gtk_window_set_policy (GTK_WINDOW(window), FALSE, TRUE, FALSE);
63
64
        vbox = gtk_vbox_new (FALSE, 6);
65
        gtk_widget_show(vbox);
66
        gtk_container_add (GTK_CONTAINER (window), vbox);
67
68
        notebook = gtk_notebook_new ();
69
        gtk_widget_show(notebook);
70
        gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0);
71
        gtk_container_set_border_width (GTK_CONTAINER (notebook), 2);
72
        /* GTK_WIDGET_UNSET_FLAGS (notebook, GTK_CAN_FOCUS); */
73
        gtk_notebook_set_scrollable (GTK_NOTEBOOK (notebook), TRUE);
74
75
        gtkut_stock_button_set_create(&confirm_area,
76
                                      &ok_btn, GTK_STOCK_OK,
77
                                      &cancel_btn, GTK_STOCK_CANCEL,
78
                                      &apply_btn, GTK_STOCK_APPLY);
79
        gtk_widget_show(confirm_area);
80
        gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
81
        gtk_widget_grab_default(ok_btn);
82
83
        dialog->window       = window;
84
        dialog->notebook     = notebook;
85
        dialog->confirm_area = confirm_area;
86
        dialog->ok_btn       = ok_btn;
87
        dialog->cancel_btn   = cancel_btn;
88
        dialog->apply_btn    = apply_btn;
89
}
90
91
void prefs_dialog_destroy(PrefsDialog *dialog)
92
{
93
        gtk_widget_destroy(dialog->window);
94
        dialog->window     = NULL;
95
        dialog->notebook   = NULL;
96
        dialog->ok_btn     = NULL;
97
        dialog->cancel_btn = NULL;
98
        dialog->apply_btn  = NULL;
99
}
100
101
void prefs_button_toggled(GtkToggleButton *toggle_btn, GtkWidget *widget)
102
{
103
        gboolean is_active;
104
105
        is_active = gtk_toggle_button_get_active(toggle_btn);
106
        gtk_widget_set_sensitive(widget, is_active);
107
}
108
109
void prefs_button_toggled_rev(GtkToggleButton *toggle_btn, GtkWidget *widget)
110
{
111
        gboolean is_active;
112
113
        is_active = gtk_toggle_button_get_active(toggle_btn);
114
        gtk_widget_set_sensitive(widget, !is_active);
115
}
116
117
void prefs_register_ui(PrefParam *param, PrefsUIData *ui_data)
118
{
119
        GHashTable *param_table;
120
        PrefParam *param_;
121
        gint i;
122
123
        param_table = prefs_param_table_get(param);
124
125
        for (i = 0; ui_data[i].name != NULL; i++) {
126
                param_ = g_hash_table_lookup(param_table, ui_data[i].name);
127
                if (param_) {
128
                        param_->ui_data = &ui_data[i];
129
                }
130
        }
131
132
        prefs_param_table_destroy(param_table);
133
}
134
135
void prefs_set_dialog(PrefParam *param)
136
{
137
        PrefsUIData *ui_data;
138
        gint i;
139
140
        for (i = 0; param[i].name != NULL; i++) {
141
                ui_data = (PrefsUIData *)param[i].ui_data;
142
                if (ui_data && ui_data->widget_set_func)
143
                        ui_data->widget_set_func(&param[i]);
144
        }
145
}
146
147
void prefs_set_data_from_dialog(PrefParam *param)
148
{
149
        PrefsUIData *ui_data;
150
        gint i;
151
152
        for (i = 0; param[i].name != NULL; i++) {
153
                ui_data = (PrefsUIData *)param[i].ui_data;
154
                if (ui_data && ui_data->data_set_func)
155
                        ui_data->data_set_func(&param[i]);
156
        }
157
}
158
159
void prefs_set_dialog_to_default(PrefParam *param)
160
{
161
        gint           i;
162
        PrefsUIData *ui_data;
163
        PrefParam  tmpparam;
164
        gchar          *str_data = NULL;
165
        gint           int_data;
166
        gushort    ushort_data;
167
        gboolean   bool_data;
168
        DummyEnum  enum_data;
169
170
        for (i = 0; param[i].name != NULL; i++) {
171
                ui_data = (PrefsUIData *)param[i].ui_data;
172
                if (!ui_data || !ui_data->widget_set_func) continue;
173
174
                tmpparam = param[i];
175
176
                switch (tmpparam.type) {
177
                case P_STRING:
178
                        if (tmpparam.defval) {
179
                                if (!g_ascii_strncasecmp
180
                                        (tmpparam.defval, "ENV_", 4)) {
181
                                        str_data = g_strdup
182
                                                (g_getenv(param[i].defval + 4));
183
                                        tmpparam.data = &str_data;
184
                                        break;
185
                                } else if (tmpparam.defval[0] == '~') {
186
                                        str_data =
187
#ifdef G_OS_WIN32
188
                                                g_strconcat(get_rc_dir(),
189
#else
190
                                                g_strconcat(get_home_dir(),
191
#endif
192
                                                            param[i].defval + 1,
193
                                                            NULL);
194
                                        tmpparam.data = &str_data;
195
                                        break;
196
                                }
197
                        }
198
                        tmpparam.data = &tmpparam.defval;
199
                        break;
200
                case P_INT:
201
                        if (tmpparam.defval)
202
                                int_data = atoi(tmpparam.defval);
203
                        else
204
                                int_data = 0;
205
                        tmpparam.data = &int_data;
206
                        break;
207
                case P_USHORT:
208
                        if (tmpparam.defval)
209
                                ushort_data = atoi(tmpparam.defval);
210
                        else
211
                                ushort_data = 0;
212
                        tmpparam.data = &ushort_data;
213
                        break;
214
                case P_BOOL:
215
                        if (tmpparam.defval) {
216
                                if (!g_ascii_strcasecmp(tmpparam.defval, "TRUE"))
217
                                        bool_data = TRUE;
218
                                else
219
                                        bool_data = atoi(tmpparam.defval)
220
                                                ? TRUE : FALSE;
221
                        } else
222
                                bool_data = FALSE;
223
                        tmpparam.data = &bool_data;
224
                        break;
225
                case P_ENUM:
226
                        if (tmpparam.defval)
227
                                enum_data = (DummyEnum)atoi(tmpparam.defval);
228
                        else
229
                                enum_data = 0;
230
                        tmpparam.data = &enum_data;
231
                        break;
232
                case P_OTHER:
233
                        break;
234
                }
235
                ui_data->widget_set_func(&tmpparam);
236
                g_free(str_data);
237
                str_data = NULL;
238
        }
239
}
240
241
void prefs_set_data_from_entry(PrefParam *pparam)
242
{
243
        PrefsUIData *ui_data;
244
        gchar **str;
245
        const gchar *entry_str;
246
247
        ui_data = (PrefsUIData *)pparam->ui_data;
248
        g_return_if_fail(ui_data != NULL);
249
        g_return_if_fail(*ui_data->widget != NULL);
250
251
        entry_str = gtk_entry_get_text(GTK_ENTRY(*ui_data->widget));
252
253
        switch (pparam->type) {
254
        case P_STRING:
255
                str = (gchar **)pparam->data;
256
                g_free(*str);
257
                *str = entry_str[0] ? g_strdup(entry_str) : NULL;
258
                break;
259
        case P_USHORT:
260
                *((gushort *)pparam->data) = atoi(entry_str);
261
                break;
262
        case P_INT:
263
                *((gint *)pparam->data) = atoi(entry_str);
264
                break;
265
        default:
266
                g_warning("Invalid PrefType for GtkEntry widget: %d\n",
267
                          pparam->type);
268
        }
269
}
270
271
void prefs_set_entry(PrefParam *pparam)
272
{
273
        PrefsUIData *ui_data;
274
        gchar **str;
275
276
        ui_data = (PrefsUIData *)pparam->ui_data;
277
        g_return_if_fail(ui_data != NULL);
278
        g_return_if_fail(*ui_data->widget != NULL);
279
280
        switch (pparam->type) {
281
        case P_STRING:
282
                str = (gchar **)pparam->data;
283
                gtk_entry_set_text(GTK_ENTRY(*ui_data->widget),
284
                                   *str ? *str : "");
285
                break;
286
        case P_INT:
287
                gtk_entry_set_text(GTK_ENTRY(*ui_data->widget),
288
                                   itos(*((gint *)pparam->data)));
289
                break;
290
        case P_USHORT:
291
                gtk_entry_set_text(GTK_ENTRY(*ui_data->widget),
292
                                   itos(*((gushort *)pparam->data)));
293
                break;
294
        default:
295
                g_warning("Invalid PrefType for GtkEntry widget: %d\n",
296
                          pparam->type);
297
        }
298
}
299
300
void prefs_set_data_from_text(PrefParam *pparam)
301
{
302
        PrefsUIData *ui_data;
303
        gchar **str;
304
        gchar *text = NULL, *tp = NULL;
305
        gchar *tmp, *tmpp;
306
307
        ui_data = (PrefsUIData *)pparam->ui_data;
308
        g_return_if_fail(ui_data != NULL);
309
        g_return_if_fail(*ui_data->widget != NULL);
310
        g_return_if_fail(GTK_IS_EDITABLE(*ui_data->widget) ||
311
                         GTK_IS_TEXT_VIEW(*ui_data->widget));
312
313
        switch (pparam->type) {
314
        case P_STRING:
315
                str = (gchar **)pparam->data;
316
                g_free(*str);
317
                if (GTK_IS_EDITABLE(*ui_data->widget)) {
318
                        tp = text = gtk_editable_get_chars
319
                                (GTK_EDITABLE(*ui_data->widget), 0, -1);
320
                } else if (GTK_IS_TEXT_VIEW(*ui_data->widget)) {
321
                        GtkTextView *textview = GTK_TEXT_VIEW(*ui_data->widget);
322
                        GtkTextBuffer *buffer;
323
                        GtkTextIter start, end;
324
325
                        buffer = gtk_text_view_get_buffer(textview);
326
                        gtk_text_buffer_get_start_iter(buffer, &start);
327
                        gtk_text_buffer_get_iter_at_offset(buffer, &end, -1);
328
                        tp = text = gtk_text_buffer_get_text
329
                                (buffer, &start, &end, FALSE);
330
                }
331
332
                g_return_if_fail(tp != NULL && text != NULL);
333
334
                if (text[0] == '\0') {
335
                        *str = NULL;
336
                        g_free(text);
337
                        break;
338
                }
339
340
                tmpp = tmp = g_malloc(strlen(text) * 2 + 1);
341
                while (*tp) {
342
                        if (*tp == '\n') {
343
                                *tmpp++ = '\\';
344
                                *tmpp++ = 'n';
345
                                tp++;
346
                        } else
347
                                *tmpp++ = *tp++;
348
                }
349
                *tmpp = '\0';
350
                *str = tmp;
351
                g_free(text);
352
                break;
353
        default:
354
                g_warning("Invalid PrefType for GtkTextView widget: %d\n",
355
                          pparam->type);
356
        }
357
}
358
359
void prefs_set_text(PrefParam *pparam)
360
{
361
        PrefsUIData *ui_data;
362
        gchar *buf, *sp, *bufp;
363
        gchar **str;
364
        GtkTextView *text;
365
        GtkTextBuffer *buffer;
366
        GtkTextIter iter;
367
368
        ui_data = (PrefsUIData *)pparam->ui_data;
369
        g_return_if_fail(ui_data != NULL);
370
        g_return_if_fail(*ui_data->widget != NULL);
371
372
        switch (pparam->type) {
373
        case P_STRING:
374
                str = (gchar **)pparam->data;
375
                if (*str) {
376
                        bufp = buf = g_malloc(strlen(*str) + 1);
377
                        sp = *str;
378
                        while (*sp) {
379
                                if (*sp == '\\' && *(sp + 1) == 'n') {
380
                                        *bufp++ = '\n';
381
                                        sp += 2;
382
                                } else
383
                                        *bufp++ = *sp++;
384
                        }
385
                        *bufp = '\0';
386
                } else
387
                        buf = g_strdup("");
388
389
                text = GTK_TEXT_VIEW(*ui_data->widget);
390
                buffer = gtk_text_view_get_buffer(text);
391
                gtk_text_buffer_set_text(buffer, "", 0);
392
                gtk_text_buffer_get_start_iter(buffer, &iter);
393
                gtk_text_buffer_insert(buffer, &iter, buf, -1);
394
                g_free(buf);
395
                break;
396
        default:
397
                g_warning("Invalid PrefType for GtkTextView widget: %d\n",
398
                          pparam->type);
399
        }
400
}
401
402
void prefs_set_data_from_toggle(PrefParam *pparam)
403
{
404
        PrefsUIData *ui_data;
405
406
        ui_data = (PrefsUIData *)pparam->ui_data;
407
        g_return_if_fail(pparam->type == P_BOOL);
408
        g_return_if_fail(ui_data != NULL);
409
        g_return_if_fail(*ui_data->widget != NULL);
410
        
411
        *((gboolean *)pparam->data) =
412
                gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(*ui_data->widget));
413
}
414
415
void prefs_set_toggle(PrefParam *pparam)
416
{
417
        PrefsUIData *ui_data;
418
419
        ui_data = (PrefsUIData *)pparam->ui_data;
420
        g_return_if_fail(pparam->type == P_BOOL);
421
        g_return_if_fail(ui_data != NULL);
422
        g_return_if_fail(*ui_data->widget != NULL);
423
424
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(*ui_data->widget),
425
                                     *((gboolean *)pparam->data));
426
}
427
428
void prefs_set_data_from_spinbtn(PrefParam *pparam)
429
{
430
        PrefsUIData *ui_data;
431
432
        ui_data = (PrefsUIData *)pparam->ui_data;
433
        g_return_if_fail(ui_data != NULL);
434
        g_return_if_fail(*ui_data->widget != NULL);
435
436
        switch (pparam->type) {
437
        case P_INT:
438
                *((gint *)pparam->data) =
439
                        gtk_spin_button_get_value_as_int
440
                        (GTK_SPIN_BUTTON(*ui_data->widget));
441
                break;
442
        case P_USHORT:
443
                *((gushort *)pparam->data) =
444
                        (gushort)gtk_spin_button_get_value_as_int
445
                        (GTK_SPIN_BUTTON(*ui_data->widget));
446
                break;
447
        default:
448
                g_warning("Invalid PrefType for GtkSpinButton widget: %d\n",
449
                          pparam->type);
450
        }
451
}
452
453
void prefs_set_spinbtn(PrefParam *pparam)
454
{
455
        PrefsUIData *ui_data;
456
457
        ui_data = (PrefsUIData *)pparam->ui_data;
458
        g_return_if_fail(ui_data != NULL);
459
        g_return_if_fail(*ui_data->widget != NULL);
460
461
        switch (pparam->type) {
462
        case P_INT:
463
                gtk_spin_button_set_value(GTK_SPIN_BUTTON(*ui_data->widget),
464
                                          (gfloat)*((gint *)pparam->data));
465
                break;
466
        case P_USHORT:
467
                gtk_spin_button_set_value(GTK_SPIN_BUTTON(*ui_data->widget),
468
                                          (gfloat)*((gushort *)pparam->data));
469
                break;
470
        default:
471
                g_warning("Invalid PrefType for GtkSpinButton widget: %d\n",
472
                          pparam->type);
473
        }
474
}
475
476
void prefs_set_data_from_fontbtn(PrefParam *pparam)
477
{
478
        PrefsUIData *ui_data;
479
        gchar **str;
480
        const gchar *font_str;
481
482
        ui_data = (PrefsUIData *)pparam->ui_data;
483
        g_return_if_fail(ui_data != NULL);
484
        g_return_if_fail(*ui_data->widget != NULL);
485
486
        font_str = gtk_font_button_get_font_name
487
                (GTK_FONT_BUTTON(*ui_data->widget));
488
489
        switch (pparam->type) {
490
        case P_STRING:
491
                str = (gchar **)pparam->data;
492
                g_free(*str);
493
                *str = font_str[0] ? g_strdup(font_str) : NULL;
494
                break;
495
        default:
496
                g_warning("Invalid PrefType for GtkFontButton widget: %d\n",
497
                          pparam->type);
498
        }
499
}
500
501
void prefs_set_fontbtn(PrefParam *pparam)
502
{
503
        PrefsUIData *ui_data;
504
        gchar **str;
505
506
        ui_data = (PrefsUIData *)pparam->ui_data;
507
        g_return_if_fail(ui_data != NULL);
508
        g_return_if_fail(*ui_data->widget != NULL);
509
510
        switch (pparam->type) {
511
        case P_STRING:
512
                str = (gchar **)pparam->data;
513
                gtk_font_button_set_font_name(GTK_FONT_BUTTON(*ui_data->widget),
514
                                              *str ? *str : "");
515
                break;
516
        default:
517
                g_warning("Invalid PrefType for GtkFontButton widget: %d\n",
518
                          pparam->type);
519
        }
520
}
521
522
void prefs_set_data_from_optmenu(PrefParam *pparam)
523
{
524
        PrefsUIData *ui_data;
525
        GtkWidget *menu;
526
        GtkWidget *menuitem;
527
528
        ui_data = (PrefsUIData *)pparam->ui_data;
529
        g_return_if_fail(ui_data != NULL);
530
        g_return_if_fail(*ui_data->widget != NULL);
531
532
        menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(*ui_data->widget));
533
        menuitem = gtk_menu_get_active(GTK_MENU(menu));
534
        *((DummyEnum *)pparam->data) = GPOINTER_TO_INT
535
                (g_object_get_data(G_OBJECT(menuitem), MENU_VAL_ID));
536
}
537
538
void prefs_set_optmenu(PrefParam *pparam)
539
{
540
        PrefsUIData *ui_data;
541
        DummyEnum val = *((DummyEnum *)pparam->data);
542
        GtkOptionMenu *optmenu;
543
        gint index;
544
545
        ui_data = (PrefsUIData *)pparam->ui_data;
546
        g_return_if_fail(ui_data != NULL);
547
        g_return_if_fail(*ui_data->widget != NULL);
548
549
        optmenu = GTK_OPTION_MENU(*ui_data->widget);
550
        g_return_if_fail(optmenu != NULL);
551
552
        index = menu_find_option_menu_index(optmenu, GINT_TO_POINTER(val),
553
                                            NULL);
554
        if (index >= 0)
555
                gtk_option_menu_set_history(optmenu, index);
556
        else {
557
                gtk_option_menu_set_history(optmenu, 0);
558
                prefs_set_data_from_optmenu(pparam);
559
        }
560
}