Statistics
| Revision:

root / src / prefs.c @ 1

History | View | Annotate | Download (18.1 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 <gtk/gtk.h>
25
#include <stdio.h>
26
#include <stdlib.h>
27
#include <string.h>
28
#include <unistd.h>
29
#include <errno.h>
30

    
31
#include "intl.h"
32
#include "main.h"
33
#include "prefs.h"
34
#include "codeconv.h"
35
#include "utils.h"
36
#include "gtkutils.h"
37

    
38
typedef enum
39
{
40
        DUMMY_PARAM
41
} DummyEnum;
42

    
43
void prefs_read_config(PrefParam *param, const gchar *label,
44
                       const gchar *rcfile)
45
{
46
        FILE *fp;
47
        gchar buf[PREFSBUFSIZE];
48
        gchar *rcpath;
49
        gchar *block_label;
50

    
51
        g_return_if_fail(param != NULL);
52
        g_return_if_fail(label != NULL);
53
        g_return_if_fail(rcfile != NULL);
54

    
55
        debug_print(_("Reading configuration...\n"));
56

    
57
        prefs_set_default(param);
58

    
59
        rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, rcfile, NULL);
60
        if ((fp = fopen(rcpath, "rb")) == NULL) {
61
                if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
62
                g_free(rcpath);
63
                return;
64
        }
65
        g_free(rcpath);
66

    
67
        block_label = g_strdup_printf("[%s]", label);
68

    
69
        /* search aiming block */
70
        while (fgets(buf, sizeof(buf), fp) != NULL) {
71
                gint val;
72

    
73
                val = strncmp(buf, block_label, strlen(block_label));
74
                if (val == 0) {
75
                        debug_print(_("Found %s\n"), block_label);
76
                        break;
77
                }
78
        }
79
        g_free(block_label);
80

    
81
        while (fgets(buf, sizeof(buf), fp) != NULL) {
82
                strretchomp(buf);
83
                /* reached next block */
84
                if (buf[0] == '[') break;
85

    
86
                prefs_config_parse_one_line(param, buf);
87
        }
88

    
89
        debug_print(_("Finished reading configuration.\n"));
90
        fclose(fp);
91
}
92

    
93
void prefs_config_parse_one_line(PrefParam *param, const gchar *buf)
94
{
95
        gint i;
96
        gint name_len;
97
        const gchar *value;
98

    
99
        for (i = 0; param[i].name != NULL; i++) {
100
                name_len = strlen(param[i].name);
101
                if (strncasecmp(buf, param[i].name, name_len))
102
                        continue;
103
                if (buf[name_len] != '=')
104
                        continue;
105
                value = buf + name_len + 1;
106
                /* debug_print("%s = %s\n", param[i].name, value); */
107

    
108
                switch (param[i].type) {
109
                case P_STRING:
110
                        g_free(*((gchar **)param[i].data));
111
                        *((gchar **)param[i].data) =
112
                                *value ? g_strdup(value) : NULL;
113
                        break;
114
                case P_INT:
115
                        *((gint *)param[i].data) =
116
                                (gint)atoi(value);
117
                        break;
118
                case P_BOOL:
119
                        *((gboolean *)param[i].data) =
120
                                (*value == '0' || *value == '\0')
121
                                        ? FALSE : TRUE;
122
                        break;
123
                case P_ENUM:
124
                        *((DummyEnum *)param[i].data) =
125
                                (DummyEnum)atoi(value);
126
                        break;
127
                case P_USHORT:
128
                        *((gushort *)param[i].data) =
129
                                (gushort)atoi(value);
130
                        break;
131
                default:
132
                        break;
133
                }
134
        }
135
}
136

    
137
#define TRY(func) \
138
if (!(func)) \
139
{ \
140
        g_warning(_("failed to write configuration to file\n")); \
141
        if (orig_fp) fclose(orig_fp); \
142
        prefs_file_close_revert(pfile); \
143
        g_free(rcpath); \
144
        g_free(block_label); \
145
        return; \
146
} \
147

    
148
void prefs_write_config(PrefParam *param, const gchar *label,
149
                        const gchar *rcfile)
150
{
151
        FILE *orig_fp;
152
        PrefFile *pfile;
153
        gchar *rcpath;
154
        gchar buf[PREFSBUFSIZE];
155
        gchar *block_label = NULL;
156
        gboolean block_matched = FALSE;
157

    
158
        g_return_if_fail(param != NULL);
159
        g_return_if_fail(label != NULL);
160
        g_return_if_fail(rcfile != NULL);
161

    
162
        rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, rcfile, NULL);
163
        if ((orig_fp = fopen(rcpath, "rb")) == NULL) {
164
                if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
165
        }
166

    
167
        if ((pfile = prefs_file_open(rcpath)) == NULL) {
168
                g_warning(_("failed to write configuration to file\n"));
169
                if (orig_fp) fclose(orig_fp);
170
                g_free(rcpath);
171
                return;
172
        }
173

    
174
        block_label = g_strdup_printf("[%s]", label);
175

    
176
        /* search aiming block */
177
        if (orig_fp) {
178
                while (fgets(buf, sizeof(buf), orig_fp) != NULL) {
179
                        gint val;
180

    
181
                        val = strncmp(buf, block_label, strlen(block_label));
182
                        if (val == 0) {
183
                                debug_print(_("Found %s\n"), block_label);
184
                                block_matched = TRUE;
185
                                break;
186
                        } else
187
                                TRY(fputs(buf, pfile->fp) != EOF);
188
                }
189
        }
190

    
191
        TRY(fprintf(pfile->fp, "%s\n", block_label) > 0);
192
        g_free(block_label);
193
        block_label = NULL;
194

    
195
        /* write all param data to file */
196
        TRY(prefs_file_write_param(pfile, param) == 0);
197

    
198
        if (block_matched) {
199
                while (fgets(buf, sizeof(buf), orig_fp) != NULL) {
200
                        /* next block */
201
                        if (buf[0] == '[') {
202
                                TRY(fputc('\n', pfile->fp) != EOF &&
203
                                    fputs(buf, pfile->fp)  != EOF);
204
                                break;
205
                        }
206
                }
207
                while (fgets(buf, sizeof(buf), orig_fp) != NULL)
208
                        TRY(fputs(buf, pfile->fp) != EOF);
209
        }
210

    
211
        if (orig_fp) fclose(orig_fp);
212
        if (prefs_file_close(pfile) < 0)
213
                g_warning(_("failed to write configuration to file\n"));
214
        g_free(rcpath);
215

    
216
        debug_print(_("Configuration is saved.\n"));
217
}
218

    
219
gint prefs_file_write_param(PrefFile *pfile, PrefParam *param)
220
{
221
        gint i;
222
        gchar buf[PREFSBUFSIZE];
223

    
224
        for (i = 0; param[i].name != NULL; i++) {
225
                switch (param[i].type) {
226
                case P_STRING:
227
                        g_snprintf(buf, sizeof(buf), "%s=%s\n", param[i].name,
228
                                   *((gchar **)param[i].data) ?
229
                                   *((gchar **)param[i].data) : "");
230
                        break;
231
                case P_INT:
232
                        g_snprintf(buf, sizeof(buf), "%s=%d\n", param[i].name,
233
                                   *((gint *)param[i].data));
234
                        break;
235
                case P_BOOL:
236
                        g_snprintf(buf, sizeof(buf), "%s=%d\n", param[i].name,
237
                                   *((gboolean *)param[i].data));
238
                        break;
239
                case P_ENUM:
240
                        g_snprintf(buf, sizeof(buf), "%s=%d\n", param[i].name,
241
                                   *((DummyEnum *)param[i].data));
242
                        break;
243
                case P_USHORT:
244
                        g_snprintf(buf, sizeof(buf), "%s=%d\n", param[i].name,
245
                                   *((gushort *)param[i].data));
246
                        break;
247
                default:
248
                        buf[0] = '\0';
249
                }
250

    
251
                if (buf[0] != '\0') {
252
                        if (fputs(buf, pfile->fp) == EOF) {
253
                                perror("fputs");
254
                                return -1;
255
                        }
256
                }
257
        }
258

    
259
        return 0;
260
}
261

    
262
PrefFile *prefs_file_open(const gchar *path)
263
{
264
        PrefFile *pfile;
265
        gchar *tmppath;
266
        FILE *fp;
267

    
268
        g_return_val_if_fail(path != NULL, NULL);
269

    
270
        tmppath = g_strconcat(path, ".tmp", NULL);
271
        if ((fp = fopen(tmppath, "wb")) == NULL) {
272
                FILE_OP_ERROR(tmppath, "fopen");
273
                g_free(tmppath);
274
                return NULL;
275
        }
276

    
277
        if (change_file_mode_rw(fp, tmppath) < 0)
278
                FILE_OP_ERROR(tmppath, "chmod");
279

    
280
        g_free(tmppath);
281

    
282
        pfile = g_new(PrefFile, 1);
283
        pfile->fp = fp;
284
        pfile->path = g_strdup(path);
285

    
286
        return pfile;
287
}
288

    
289
gint prefs_file_close(PrefFile *pfile)
290
{
291
        FILE *fp;
292
        gchar *path;
293
        gchar *tmppath;
294
        gchar *bakpath = NULL;
295

    
296
        g_return_val_if_fail(pfile != NULL, -1);
297

    
298
        fp = pfile->fp;
299
        path = pfile->path;
300
        g_free(pfile);
301

    
302
        tmppath = g_strconcat(path, ".tmp", NULL);
303
        if (fclose(fp) == EOF) {
304
                FILE_OP_ERROR(tmppath, "fclose");
305
                unlink(tmppath);
306
                g_free(path);
307
                g_free(tmppath);
308
                return -1;
309
        }
310

    
311
        if (is_file_exist(path)) {
312
                bakpath = g_strconcat(path, ".bak", NULL);
313
                if (rename(path, bakpath) < 0) {
314
                        FILE_OP_ERROR(path, "rename");
315
                        unlink(tmppath);
316
                        g_free(path);
317
                        g_free(tmppath);
318
                        g_free(bakpath);
319
                        return -1;
320
                }
321
        }
322

    
323
        if (rename(tmppath, path) < 0) {
324
                FILE_OP_ERROR(tmppath, "rename");
325
                unlink(tmppath);
326
                g_free(path);
327
                g_free(tmppath);
328
                g_free(bakpath);
329
                return -1;
330
        }
331

    
332
        g_free(path);
333
        g_free(tmppath);
334
        g_free(bakpath);
335
        return 0;
336
}
337

    
338
gint prefs_file_close_revert(PrefFile *pfile)
339
{
340
        gchar *tmppath;
341

    
342
        g_return_val_if_fail(pfile != NULL, -1);
343

    
344
        tmppath = g_strconcat(pfile->path, ".tmp", NULL);
345
        fclose(pfile->fp);
346
        if (unlink(tmppath) < 0) FILE_OP_ERROR(tmppath, "unlink");
347
        g_free(tmppath);
348
        g_free(pfile->path);
349
        g_free(pfile);
350

    
351
        return 0;
352
}
353

    
354
void prefs_set_default(PrefParam *param)
355
{
356
        gint i;
357

    
358
        g_return_if_fail(param != NULL);
359

    
360
        for (i = 0; param[i].name != NULL; i++) {
361
                if (!param[i].data) continue;
362

    
363
                switch (param[i].type) {
364
                case P_STRING:
365
                        if (param[i].defval != NULL) {
366
                                if (!strncasecmp(param[i].defval, "ENV_", 4)) {
367
                                        const gchar *envstr;
368
                                        gchar *tmp = NULL;
369

    
370
                                        envstr = g_getenv(param[i].defval + 4);
371
                                        if (envstr) {
372
                                                tmp = conv_codeset_strdup
373
                                                        (envstr,
374
                                                         conv_get_locale_charset_str(),
375
                                                         CS_UTF_8);
376
                                                if (!tmp) {
377
                                                        g_warning("failed to convert character set.");
378
                                                        tmp = g_strdup(envstr);
379
                                                }
380
                                        }
381
                                        *((gchar **)param[i].data) = tmp;
382
                                } else if (param[i].defval[0] == '~')
383
                                        *((gchar **)param[i].data) =
384
                                                g_strconcat(get_home_dir(),
385
                                                            param[i].defval + 1,
386
                                                            NULL);
387
                                else if (param[i].defval[0] != '\0')
388
                                        *((gchar **)param[i].data) =
389
                                                g_strdup(param[i].defval);
390
                                else
391
                                        *((gchar **)param[i].data) = NULL;
392
                        } else
393
                                *((gchar **)param[i].data) = NULL;
394
                        break;
395
                case P_INT:
396
                        if (param[i].defval != NULL)
397
                                *((gint *)param[i].data) =
398
                                        (gint)atoi(param[i].defval);
399
                        else
400
                                *((gint *)param[i].data) = 0;
401
                        break;
402
                case P_BOOL:
403
                        if (param[i].defval != NULL) {
404
                                if (!strcasecmp(param[i].defval, "TRUE"))
405
                                        *((gboolean *)param[i].data) = TRUE;
406
                                else
407
                                        *((gboolean *)param[i].data) =
408
                                                atoi(param[i].defval) ? TRUE : FALSE;
409
                        } else
410
                                *((gboolean *)param[i].data) = FALSE;
411
                        break;
412
                case P_ENUM:
413
                        if (param[i].defval != NULL)
414
                                *((DummyEnum*)param[i].data) =
415
                                        (DummyEnum)atoi(param[i].defval);
416
                        else
417
                                *((DummyEnum *)param[i].data) = 0;
418
                        break;
419
                case P_USHORT:
420
                        if (param[i].defval != NULL)
421
                                *((gushort *)param[i].data) =
422
                                        (gushort)atoi(param[i].defval);
423
                        else
424
                                *((gushort *)param[i].data) = 0;
425
                        break;
426
                default:
427
                        break;
428
                }
429
        }
430
}
431

    
432
void prefs_free(PrefParam *param)
433
{
434
        gint i;
435

    
436
        g_return_if_fail(param != NULL);
437

    
438
        for (i = 0; param[i].name != NULL; i++) {
439
                if (!param[i].data) continue;
440

    
441
                switch (param[i].type) {
442
                case P_STRING:
443
                        g_free(*((gchar **)param[i].data));
444
                        break;
445
                default:
446
                        break;
447
                }
448
        }
449
}
450

    
451
void prefs_dialog_create(PrefsDialog *dialog)
452
{
453
        GtkWidget *window;
454
        GtkWidget *vbox;
455
        GtkWidget *notebook;
456

    
457
        GtkWidget *confirm_area;
458
        GtkWidget *ok_btn;
459
        GtkWidget *cancel_btn;
460
        GtkWidget *apply_btn;
461

    
462
        g_return_if_fail(dialog != NULL);
463

    
464
        window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
465
        gtk_container_set_border_width (GTK_CONTAINER (window), 8);
466
        gtk_window_set_position (GTK_WINDOW(window), GTK_WIN_POS_CENTER);
467
        gtk_window_set_modal (GTK_WINDOW (window), TRUE);
468
        gtk_window_set_policy (GTK_WINDOW(window), FALSE, TRUE, FALSE);
469

    
470
        vbox = gtk_vbox_new (FALSE, 6);
471
        gtk_widget_show(vbox);
472
        gtk_container_add (GTK_CONTAINER (window), vbox);
473

    
474
        notebook = gtk_notebook_new ();
475
        gtk_widget_show(notebook);
476
        gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0);
477
        gtk_container_set_border_width (GTK_CONTAINER (notebook), 2);
478
        /* GTK_WIDGET_UNSET_FLAGS (notebook, GTK_CAN_FOCUS); */
479
        gtk_notebook_set_scrollable (GTK_NOTEBOOK (notebook), TRUE);
480

    
481
        gtkut_button_set_create(&confirm_area,
482
                                &ok_btn,        _("OK"),
483
                                &cancel_btn,        _("Cancel"),
484
                                &apply_btn,        _("Apply"));
485
        gtk_widget_show(confirm_area);
486
        gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
487
        gtk_widget_grab_default(ok_btn);
488

    
489
        dialog->window     = window;
490
        dialog->notebook   = notebook;
491
        dialog->ok_btn     = ok_btn;
492
        dialog->cancel_btn = cancel_btn;
493
        dialog->apply_btn  = apply_btn;
494
}
495

    
496
void prefs_dialog_destroy(PrefsDialog *dialog)
497
{
498
        gtk_widget_destroy(dialog->window);
499
        dialog->window     = NULL;
500
        dialog->notebook   = NULL;
501
        dialog->ok_btn     = NULL;
502
        dialog->cancel_btn = NULL;
503
        dialog->apply_btn  = NULL;
504
}
505

    
506
void prefs_button_toggled(GtkToggleButton *toggle_btn, GtkWidget *widget)
507
{
508
        gboolean is_active;
509

    
510
        is_active = gtk_toggle_button_get_active(toggle_btn);
511
        gtk_widget_set_sensitive(widget, is_active);
512
}
513

    
514
void prefs_set_dialog(PrefParam *param)
515
{
516
        gint i;
517

    
518
        for (i = 0; param[i].name != NULL; i++) {
519
                if (param[i].widget_set_func)
520
                        param[i].widget_set_func(&param[i]);
521
        }
522
}
523

    
524
void prefs_set_data_from_dialog(PrefParam *param)
525
{
526
        gint i;
527

    
528
        for (i = 0; param[i].name != NULL; i++) {
529
                if (param[i].data_set_func)
530
                        param[i].data_set_func(&param[i]);
531
        }
532
}
533

    
534
void prefs_set_dialog_to_default(PrefParam *param)
535
{
536
        gint           i;
537
        PrefParam  tmpparam;
538
        gchar          *str_data = NULL;
539
        gint           int_data;
540
        gushort    ushort_data;
541
        gboolean   bool_data;
542
        DummyEnum  enum_data;
543

    
544
        for (i = 0; param[i].name != NULL; i++) {
545
                if (!param[i].widget_set_func) continue;
546

    
547
                tmpparam = param[i];
548

    
549
                switch (tmpparam.type) {
550
                case P_STRING:
551
#warning FIXME_GTK2
552
                        if (tmpparam.defval) {
553
                                if (!strncasecmp(tmpparam.defval, "ENV_", 4)) {
554
                                        str_data = g_strdup(g_getenv(param[i].defval + 4));
555
                                        tmpparam.data = &str_data;
556
                                        break;
557
                                } else if (tmpparam.defval[0] == '~') {
558
                                        str_data =
559
                                                g_strconcat(get_home_dir(),
560
                                                            param[i].defval + 1,
561
                                                            NULL);
562
                                        tmpparam.data = &str_data;
563
                                        break;
564
                                }
565
                        }
566
                        tmpparam.data = &tmpparam.defval;
567
                        break;
568
                case P_INT:
569
                        if (tmpparam.defval)
570
                                int_data = atoi(tmpparam.defval);
571
                        else
572
                                int_data = 0;
573
                        tmpparam.data = &int_data;
574
                        break;
575
                case P_USHORT:
576
                        if (tmpparam.defval)
577
                                ushort_data = atoi(tmpparam.defval);
578
                        else
579
                                ushort_data = 0;
580
                        tmpparam.data = &ushort_data;
581
                        break;
582
                case P_BOOL:
583
                        if (tmpparam.defval) {
584
                                if (!strcasecmp(tmpparam.defval, "TRUE"))
585
                                        bool_data = TRUE;
586
                                else
587
                                        bool_data = atoi(tmpparam.defval)
588
                                                ? TRUE : FALSE;
589
                        } else
590
                                bool_data = FALSE;
591
                        tmpparam.data = &bool_data;
592
                        break;
593
                case P_ENUM:
594
                        if (tmpparam.defval)
595
                                enum_data = (DummyEnum)atoi(tmpparam.defval);
596
                        else
597
                                enum_data = 0;
598
                        tmpparam.data = &enum_data;
599
                        break;
600
                case P_OTHER:
601
                        break;
602
                }
603
                tmpparam.widget_set_func(&tmpparam);
604
                g_free(str_data);
605
                str_data = NULL;
606
        }
607
}
608

    
609
void prefs_set_data_from_entry(PrefParam *pparam)
610
{
611
        gchar **str;
612
        const gchar *entry_str;
613

    
614
        g_return_if_fail(*pparam->widget != NULL);
615

    
616
        entry_str = gtk_entry_get_text(GTK_ENTRY(*pparam->widget));
617

    
618
        switch (pparam->type) {
619
        case P_STRING:
620
                str = (gchar **)pparam->data;
621
                g_free(*str);
622
                *str = entry_str[0] ? g_strdup(entry_str) : NULL;
623
                break;
624
        case P_USHORT:
625
                *((gushort *)pparam->data) = atoi(entry_str);
626
                break;
627
        case P_INT:
628
                *((gint *)pparam->data) = atoi(entry_str);
629
                break;
630
        default:
631
                g_warning("Invalid PrefType for GtkEntry widget: %d\n",
632
                          pparam->type);
633
        }
634
}
635

    
636
void prefs_set_entry(PrefParam *pparam)
637
{
638
        gchar **str;
639

    
640
        g_return_if_fail(*pparam->widget != NULL);
641

    
642
        switch (pparam->type) {
643
        case P_STRING:
644
                str = (gchar **)pparam->data;
645
                gtk_entry_set_text(GTK_ENTRY(*pparam->widget),
646
                                   *str ? *str : "");
647
                break;
648
        case P_INT:
649
                gtk_entry_set_text(GTK_ENTRY(*pparam->widget),
650
                                   itos(*((gint *)pparam->data)));
651
                break;
652
        case P_USHORT:
653
                gtk_entry_set_text(GTK_ENTRY(*pparam->widget),
654
                                   itos(*((gushort *)pparam->data)));
655
                break;
656
        default:
657
                g_warning("Invalid PrefType for GtkEntry widget: %d\n",
658
                          pparam->type);
659
        }
660
}
661

    
662
void prefs_set_data_from_text(PrefParam *pparam)
663
{
664
        gchar **str;
665
        gchar *text = NULL, *tp = NULL;
666
        gchar *tmp, *tmpp;
667

    
668
        g_return_if_fail(*pparam->widget != NULL);
669
        g_return_if_fail(GTK_IS_EDITABLE(*pparam->widget) ||
670
                         GTK_IS_TEXT_VIEW(*pparam->widget));
671

    
672
        switch (pparam->type) {
673
        case P_STRING:
674
                str = (gchar **)pparam->data;
675
                g_free(*str);
676
                if (GTK_IS_EDITABLE(*pparam->widget)) {
677
                        tp = text = gtk_editable_get_chars
678
                                (GTK_EDITABLE(*pparam->widget), 0, -1);
679
                } else if (GTK_IS_TEXT_VIEW(*pparam->widget)) {
680
                        GtkTextView *textview = GTK_TEXT_VIEW(*pparam->widget);
681
                        GtkTextBuffer *buffer;
682
                        GtkTextIter start, end;
683

    
684
                        buffer = gtk_text_view_get_buffer(textview);
685
                        gtk_text_buffer_get_start_iter(buffer, &start);
686
                        gtk_text_buffer_get_iter_at_offset(buffer, &end, -1);
687
                        tp = text = gtk_text_buffer_get_text
688
                                (buffer, &start, &end, FALSE);
689
                }
690

    
691
                g_return_if_fail(tp != NULL && text != NULL);
692

    
693
                if (text[0] == '\0') {
694
                        *str = NULL;
695
                        g_free(text);
696
                        break;
697
                }
698

    
699
                Xalloca(tmpp = tmp, strlen(text) * 2 + 1,
700
                        { *str = NULL; break; });
701
                while (*tp) {
702
                        if (*tp == '\n') {
703
                                *tmpp++ = '\\';
704
                                *tmpp++ = 'n';
705
                                tp++;
706
                        } else
707
                                *tmpp++ = *tp++;
708
                }
709
                *tmpp = '\0';
710
                *str = g_strdup(tmp);
711
                g_free(text);
712
                break;
713
        default:
714
                g_warning("Invalid PrefType for GtkTextView widget: %d\n",
715
                          pparam->type);
716
        }
717
}
718

    
719
void prefs_set_text(PrefParam *pparam)
720
{
721
        gchar *buf, *sp, *bufp;
722
        gchar **str;
723
        GtkTextView *text;
724
        GtkTextBuffer *buffer;
725
        GtkTextIter iter;
726

    
727
        g_return_if_fail(*pparam->widget != NULL);
728

    
729
        switch (pparam->type) {
730
        case P_STRING:
731
                str = (gchar **)pparam->data;
732
                if (*str) {
733
                        bufp = buf = alloca(strlen(*str) + 1);
734
                        if (!buf) buf = "";
735
                        else {
736
                                sp = *str;
737
                                while (*sp) {
738
                                        if (*sp == '\\' && *(sp + 1) == 'n') {
739
                                                *bufp++ = '\n';
740
                                                sp += 2;
741
                                        } else
742
                                                *bufp++ = *sp++;
743
                                }
744
                                *bufp = '\0';
745
                        }
746
                } else
747
                        buf = "";
748

    
749
                text = GTK_TEXT_VIEW(*pparam->widget);
750
                buffer = gtk_text_view_get_buffer(text);
751
                gtk_text_buffer_set_text(buffer, "", 0);
752
                gtk_text_buffer_get_start_iter(buffer, &iter);
753
                gtk_text_buffer_insert(buffer, &iter, buf, -1);
754
                break;
755
        default:
756
                g_warning("Invalid PrefType for GtkTextView widget: %d\n",
757
                          pparam->type);
758
        }
759
}
760

    
761
void prefs_set_data_from_toggle(PrefParam *pparam)
762
{
763
        g_return_if_fail(pparam->type == P_BOOL);
764
        g_return_if_fail(*pparam->widget != NULL);
765
        
766
        *((gboolean *)pparam->data) =
767
                gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(*pparam->widget));
768
}
769

    
770
void prefs_set_toggle(PrefParam *pparam)
771
{
772
        g_return_if_fail(pparam->type == P_BOOL);
773
        g_return_if_fail(*pparam->widget != NULL);
774

    
775
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(*pparam->widget),
776
                                     *((gboolean *)pparam->data));
777
}
778

    
779
void prefs_set_data_from_spinbtn(PrefParam *pparam)
780
{
781
        g_return_if_fail(*pparam->widget != NULL);
782

    
783
        switch (pparam->type) {
784
        case P_INT:
785
                *((gint *)pparam->data) =
786
                        gtk_spin_button_get_value_as_int
787
                        (GTK_SPIN_BUTTON(*pparam->widget));
788
                break;
789
        case P_USHORT:
790
                *((gushort *)pparam->data) =
791
                        (gushort)gtk_spin_button_get_value_as_int
792
                        (GTK_SPIN_BUTTON(*pparam->widget));
793
                break;
794
        default:
795
                g_warning("Invalid PrefType for GtkSpinButton widget: %d\n",
796
                          pparam->type);
797
        }
798
}
799

    
800
void prefs_set_spinbtn(PrefParam *pparam)
801
{
802
        g_return_if_fail(*pparam->widget != NULL);
803

    
804
        switch (pparam->type) {
805
        case P_INT:
806
                gtk_spin_button_set_value(GTK_SPIN_BUTTON(*pparam->widget),
807
                                          (gfloat)*((gint *)pparam->data));
808
                break;
809
        case P_USHORT:
810
                gtk_spin_button_set_value(GTK_SPIN_BUTTON(*pparam->widget),
811
                                          (gfloat)*((gushort *)pparam->data));
812
                break;
813
        default:
814
                g_warning("Invalid PrefType for GtkSpinButton widget: %d\n",
815
                          pparam->type);
816
        }
817
}