Statistics
| Revision:

root / src / prefs.c @ 478

History | View | Annotate | Download (18.7 kB)

1 1 hiro
/*
2 1 hiro
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 14 hiro
 * Copyright (C) 1999-2005 Hiroyuki Yamamoto
4 1 hiro
 *
5 1 hiro
 * This program is free software; you can redistribute it and/or modify
6 1 hiro
 * it under the terms of the GNU General Public License as published by
7 1 hiro
 * the Free Software Foundation; either version 2 of the License, or
8 1 hiro
 * (at your option) any later version.
9 1 hiro
 *
10 1 hiro
 * This program is distributed in the hope that it will be useful,
11 1 hiro
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 1 hiro
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 1 hiro
 * GNU General Public License for more details.
14 1 hiro
 *
15 1 hiro
 * You should have received a copy of the GNU General Public License
16 1 hiro
 * along with this program; if not, write to the Free Software
17 1 hiro
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 1 hiro
 */
19 1 hiro
20 1 hiro
#ifdef HAVE_CONFIG_H
21 1 hiro
#  include "config.h"
22 1 hiro
#endif
23 1 hiro
24 92 hiro
#include <glib.h>
25 92 hiro
#include <glib/gi18n.h>
26 1 hiro
#include <gtk/gtk.h>
27 1 hiro
#include <stdio.h>
28 1 hiro
#include <stdlib.h>
29 1 hiro
#include <string.h>
30 1 hiro
#include <unistd.h>
31 1 hiro
#include <errno.h>
32 1 hiro
33 1 hiro
#include "main.h"
34 1 hiro
#include "prefs.h"
35 1 hiro
#include "codeconv.h"
36 1 hiro
#include "utils.h"
37 1 hiro
#include "gtkutils.h"
38 1 hiro
39 1 hiro
typedef enum
40 1 hiro
{
41 1 hiro
        DUMMY_PARAM
42 1 hiro
} DummyEnum;
43 1 hiro
44 1 hiro
void prefs_read_config(PrefParam *param, const gchar *label,
45 13 hiro
                       const gchar *rcfile, const gchar *encoding)
46 1 hiro
{
47 1 hiro
        FILE *fp;
48 1 hiro
        gchar buf[PREFSBUFSIZE];
49 1 hiro
        gchar *block_label;
50 1 hiro
51 1 hiro
        g_return_if_fail(param != NULL);
52 1 hiro
        g_return_if_fail(label != NULL);
53 1 hiro
        g_return_if_fail(rcfile != NULL);
54 1 hiro
55 13 hiro
        debug_print("Reading configuration...\n");
56 1 hiro
57 1 hiro
        prefs_set_default(param);
58 1 hiro
59 478 hiro
        if ((fp = g_fopen(rcfile, "rb")) == NULL) {
60 13 hiro
                if (ENOENT != errno) FILE_OP_ERROR(rcfile, "fopen");
61 1 hiro
                return;
62 1 hiro
        }
63 1 hiro
64 1 hiro
        block_label = g_strdup_printf("[%s]", label);
65 1 hiro
66 1 hiro
        /* search aiming block */
67 1 hiro
        while (fgets(buf, sizeof(buf), fp) != NULL) {
68 1 hiro
                gint val;
69 1 hiro
70 13 hiro
                if (encoding) {
71 13 hiro
                        gchar *conv_str;
72 13 hiro
73 13 hiro
                        conv_str = conv_codeset_strdup
74 41 hiro
                                (buf, encoding, CS_INTERNAL);
75 13 hiro
                        if (!conv_str)
76 13 hiro
                                conv_str = g_strdup(buf);
77 13 hiro
                        val = strncmp
78 13 hiro
                                (conv_str, block_label, strlen(block_label));
79 13 hiro
                        g_free(conv_str);
80 13 hiro
                } else
81 13 hiro
                        val = strncmp(buf, block_label, strlen(block_label));
82 1 hiro
                if (val == 0) {
83 13 hiro
                        debug_print("Found %s\n", block_label);
84 1 hiro
                        break;
85 1 hiro
                }
86 1 hiro
        }
87 1 hiro
        g_free(block_label);
88 1 hiro
89 1 hiro
        while (fgets(buf, sizeof(buf), fp) != NULL) {
90 1 hiro
                strretchomp(buf);
91 1 hiro
                /* reached next block */
92 1 hiro
                if (buf[0] == '[') break;
93 1 hiro
94 13 hiro
                if (encoding) {
95 13 hiro
                        gchar *conv_str;
96 13 hiro
97 13 hiro
                        conv_str = conv_codeset_strdup
98 41 hiro
                                (buf, encoding, CS_INTERNAL);
99 13 hiro
                        if (!conv_str)
100 13 hiro
                                conv_str = g_strdup(buf);
101 13 hiro
                        prefs_config_parse_one_line(param, conv_str);
102 13 hiro
                        g_free(conv_str);
103 13 hiro
                } else
104 13 hiro
                        prefs_config_parse_one_line(param, buf);
105 1 hiro
        }
106 1 hiro
107 13 hiro
        debug_print("Finished reading configuration.\n");
108 1 hiro
        fclose(fp);
109 1 hiro
}
110 1 hiro
111 1 hiro
void prefs_config_parse_one_line(PrefParam *param, const gchar *buf)
112 1 hiro
{
113 1 hiro
        gint i;
114 1 hiro
        gint name_len;
115 1 hiro
        const gchar *value;
116 1 hiro
117 1 hiro
        for (i = 0; param[i].name != NULL; i++) {
118 1 hiro
                name_len = strlen(param[i].name);
119 333 hiro
                if (g_ascii_strncasecmp(buf, param[i].name, name_len))
120 1 hiro
                        continue;
121 1 hiro
                if (buf[name_len] != '=')
122 1 hiro
                        continue;
123 1 hiro
                value = buf + name_len + 1;
124 1 hiro
                /* debug_print("%s = %s\n", param[i].name, value); */
125 1 hiro
126 1 hiro
                switch (param[i].type) {
127 1 hiro
                case P_STRING:
128 1 hiro
                        g_free(*((gchar **)param[i].data));
129 1 hiro
                        *((gchar **)param[i].data) =
130 1 hiro
                                *value ? g_strdup(value) : NULL;
131 1 hiro
                        break;
132 1 hiro
                case P_INT:
133 1 hiro
                        *((gint *)param[i].data) =
134 1 hiro
                                (gint)atoi(value);
135 1 hiro
                        break;
136 1 hiro
                case P_BOOL:
137 1 hiro
                        *((gboolean *)param[i].data) =
138 1 hiro
                                (*value == '0' || *value == '\0')
139 1 hiro
                                        ? FALSE : TRUE;
140 1 hiro
                        break;
141 1 hiro
                case P_ENUM:
142 1 hiro
                        *((DummyEnum *)param[i].data) =
143 1 hiro
                                (DummyEnum)atoi(value);
144 1 hiro
                        break;
145 1 hiro
                case P_USHORT:
146 1 hiro
                        *((gushort *)param[i].data) =
147 1 hiro
                                (gushort)atoi(value);
148 1 hiro
                        break;
149 1 hiro
                default:
150 1 hiro
                        break;
151 1 hiro
                }
152 1 hiro
        }
153 1 hiro
}
154 1 hiro
155 1 hiro
#define TRY(func) \
156 1 hiro
if (!(func)) \
157 1 hiro
{ \
158 1 hiro
        g_warning(_("failed to write configuration to file\n")); \
159 1 hiro
        if (orig_fp) fclose(orig_fp); \
160 1 hiro
        prefs_file_close_revert(pfile); \
161 1 hiro
        g_free(rcpath); \
162 1 hiro
        g_free(block_label); \
163 1 hiro
        return; \
164 1 hiro
} \
165 1 hiro
166 1 hiro
void prefs_write_config(PrefParam *param, const gchar *label,
167 1 hiro
                        const gchar *rcfile)
168 1 hiro
{
169 1 hiro
        FILE *orig_fp;
170 1 hiro
        PrefFile *pfile;
171 1 hiro
        gchar *rcpath;
172 1 hiro
        gchar buf[PREFSBUFSIZE];
173 1 hiro
        gchar *block_label = NULL;
174 1 hiro
        gboolean block_matched = FALSE;
175 1 hiro
176 1 hiro
        g_return_if_fail(param != NULL);
177 1 hiro
        g_return_if_fail(label != NULL);
178 1 hiro
        g_return_if_fail(rcfile != NULL);
179 1 hiro
180 1 hiro
        rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, rcfile, NULL);
181 478 hiro
        if ((orig_fp = g_fopen(rcpath, "rb")) == NULL) {
182 1 hiro
                if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
183 1 hiro
        }
184 1 hiro
185 1 hiro
        if ((pfile = prefs_file_open(rcpath)) == NULL) {
186 1 hiro
                g_warning(_("failed to write configuration to file\n"));
187 1 hiro
                if (orig_fp) fclose(orig_fp);
188 1 hiro
                g_free(rcpath);
189 1 hiro
                return;
190 1 hiro
        }
191 1 hiro
192 1 hiro
        block_label = g_strdup_printf("[%s]", label);
193 1 hiro
194 1 hiro
        /* search aiming block */
195 1 hiro
        if (orig_fp) {
196 1 hiro
                while (fgets(buf, sizeof(buf), orig_fp) != NULL) {
197 1 hiro
                        gint val;
198 1 hiro
199 1 hiro
                        val = strncmp(buf, block_label, strlen(block_label));
200 1 hiro
                        if (val == 0) {
201 1 hiro
                                debug_print(_("Found %s\n"), block_label);
202 1 hiro
                                block_matched = TRUE;
203 1 hiro
                                break;
204 1 hiro
                        } else
205 1 hiro
                                TRY(fputs(buf, pfile->fp) != EOF);
206 1 hiro
                }
207 1 hiro
        }
208 1 hiro
209 1 hiro
        TRY(fprintf(pfile->fp, "%s\n", block_label) > 0);
210 1 hiro
        g_free(block_label);
211 1 hiro
        block_label = NULL;
212 1 hiro
213 1 hiro
        /* write all param data to file */
214 1 hiro
        TRY(prefs_file_write_param(pfile, param) == 0);
215 1 hiro
216 1 hiro
        if (block_matched) {
217 1 hiro
                while (fgets(buf, sizeof(buf), orig_fp) != NULL) {
218 1 hiro
                        /* next block */
219 1 hiro
                        if (buf[0] == '[') {
220 1 hiro
                                TRY(fputc('\n', pfile->fp) != EOF &&
221 1 hiro
                                    fputs(buf, pfile->fp)  != EOF);
222 1 hiro
                                break;
223 1 hiro
                        }
224 1 hiro
                }
225 1 hiro
                while (fgets(buf, sizeof(buf), orig_fp) != NULL)
226 1 hiro
                        TRY(fputs(buf, pfile->fp) != EOF);
227 1 hiro
        }
228 1 hiro
229 1 hiro
        if (orig_fp) fclose(orig_fp);
230 1 hiro
        if (prefs_file_close(pfile) < 0)
231 1 hiro
                g_warning(_("failed to write configuration to file\n"));
232 1 hiro
        g_free(rcpath);
233 1 hiro
234 1 hiro
        debug_print(_("Configuration is saved.\n"));
235 1 hiro
}
236 1 hiro
237 1 hiro
gint prefs_file_write_param(PrefFile *pfile, PrefParam *param)
238 1 hiro
{
239 1 hiro
        gint i;
240 1 hiro
        gchar buf[PREFSBUFSIZE];
241 1 hiro
242 1 hiro
        for (i = 0; param[i].name != NULL; i++) {
243 1 hiro
                switch (param[i].type) {
244 1 hiro
                case P_STRING:
245 1 hiro
                        g_snprintf(buf, sizeof(buf), "%s=%s\n", param[i].name,
246 1 hiro
                                   *((gchar **)param[i].data) ?
247 1 hiro
                                   *((gchar **)param[i].data) : "");
248 1 hiro
                        break;
249 1 hiro
                case P_INT:
250 1 hiro
                        g_snprintf(buf, sizeof(buf), "%s=%d\n", param[i].name,
251 1 hiro
                                   *((gint *)param[i].data));
252 1 hiro
                        break;
253 1 hiro
                case P_BOOL:
254 1 hiro
                        g_snprintf(buf, sizeof(buf), "%s=%d\n", param[i].name,
255 1 hiro
                                   *((gboolean *)param[i].data));
256 1 hiro
                        break;
257 1 hiro
                case P_ENUM:
258 1 hiro
                        g_snprintf(buf, sizeof(buf), "%s=%d\n", param[i].name,
259 1 hiro
                                   *((DummyEnum *)param[i].data));
260 1 hiro
                        break;
261 1 hiro
                case P_USHORT:
262 1 hiro
                        g_snprintf(buf, sizeof(buf), "%s=%d\n", param[i].name,
263 1 hiro
                                   *((gushort *)param[i].data));
264 1 hiro
                        break;
265 1 hiro
                default:
266 1 hiro
                        buf[0] = '\0';
267 1 hiro
                }
268 1 hiro
269 1 hiro
                if (buf[0] != '\0') {
270 1 hiro
                        if (fputs(buf, pfile->fp) == EOF) {
271 1 hiro
                                perror("fputs");
272 1 hiro
                                return -1;
273 1 hiro
                        }
274 1 hiro
                }
275 1 hiro
        }
276 1 hiro
277 1 hiro
        return 0;
278 1 hiro
}
279 1 hiro
280 1 hiro
PrefFile *prefs_file_open(const gchar *path)
281 1 hiro
{
282 1 hiro
        PrefFile *pfile;
283 1 hiro
        gchar *tmppath;
284 1 hiro
        FILE *fp;
285 1 hiro
286 1 hiro
        g_return_val_if_fail(path != NULL, NULL);
287 1 hiro
288 1 hiro
        tmppath = g_strconcat(path, ".tmp", NULL);
289 478 hiro
        if ((fp = g_fopen(tmppath, "wb")) == NULL) {
290 1 hiro
                FILE_OP_ERROR(tmppath, "fopen");
291 1 hiro
                g_free(tmppath);
292 1 hiro
                return NULL;
293 1 hiro
        }
294 1 hiro
295 1 hiro
        if (change_file_mode_rw(fp, tmppath) < 0)
296 1 hiro
                FILE_OP_ERROR(tmppath, "chmod");
297 1 hiro
298 1 hiro
        g_free(tmppath);
299 1 hiro
300 1 hiro
        pfile = g_new(PrefFile, 1);
301 1 hiro
        pfile->fp = fp;
302 1 hiro
        pfile->path = g_strdup(path);
303 1 hiro
304 1 hiro
        return pfile;
305 1 hiro
}
306 1 hiro
307 1 hiro
gint prefs_file_close(PrefFile *pfile)
308 1 hiro
{
309 1 hiro
        FILE *fp;
310 1 hiro
        gchar *path;
311 1 hiro
        gchar *tmppath;
312 1 hiro
        gchar *bakpath = NULL;
313 1 hiro
314 1 hiro
        g_return_val_if_fail(pfile != NULL, -1);
315 1 hiro
316 1 hiro
        fp = pfile->fp;
317 1 hiro
        path = pfile->path;
318 1 hiro
        g_free(pfile);
319 1 hiro
320 1 hiro
        tmppath = g_strconcat(path, ".tmp", NULL);
321 1 hiro
        if (fclose(fp) == EOF) {
322 1 hiro
                FILE_OP_ERROR(tmppath, "fclose");
323 478 hiro
                g_unlink(tmppath);
324 1 hiro
                g_free(path);
325 1 hiro
                g_free(tmppath);
326 1 hiro
                return -1;
327 1 hiro
        }
328 1 hiro
329 1 hiro
        if (is_file_exist(path)) {
330 1 hiro
                bakpath = g_strconcat(path, ".bak", NULL);
331 470 hiro
                if (rename_force(path, bakpath) < 0) {
332 1 hiro
                        FILE_OP_ERROR(path, "rename");
333 478 hiro
                        g_unlink(tmppath);
334 1 hiro
                        g_free(path);
335 1 hiro
                        g_free(tmppath);
336 1 hiro
                        g_free(bakpath);
337 1 hiro
                        return -1;
338 1 hiro
                }
339 1 hiro
        }
340 1 hiro
341 470 hiro
        if (rename_force(tmppath, path) < 0) {
342 1 hiro
                FILE_OP_ERROR(tmppath, "rename");
343 478 hiro
                g_unlink(tmppath);
344 1 hiro
                g_free(path);
345 1 hiro
                g_free(tmppath);
346 1 hiro
                g_free(bakpath);
347 1 hiro
                return -1;
348 1 hiro
        }
349 1 hiro
350 1 hiro
        g_free(path);
351 1 hiro
        g_free(tmppath);
352 1 hiro
        g_free(bakpath);
353 1 hiro
        return 0;
354 1 hiro
}
355 1 hiro
356 1 hiro
gint prefs_file_close_revert(PrefFile *pfile)
357 1 hiro
{
358 1 hiro
        gchar *tmppath;
359 1 hiro
360 1 hiro
        g_return_val_if_fail(pfile != NULL, -1);
361 1 hiro
362 1 hiro
        tmppath = g_strconcat(pfile->path, ".tmp", NULL);
363 1 hiro
        fclose(pfile->fp);
364 478 hiro
        if (g_unlink(tmppath) < 0)
365 478 hiro
                FILE_OP_ERROR(tmppath, "unlink");
366 1 hiro
        g_free(tmppath);
367 1 hiro
        g_free(pfile->path);
368 1 hiro
        g_free(pfile);
369 1 hiro
370 1 hiro
        return 0;
371 1 hiro
}
372 1 hiro
373 1 hiro
void prefs_set_default(PrefParam *param)
374 1 hiro
{
375 1 hiro
        gint i;
376 1 hiro
377 1 hiro
        g_return_if_fail(param != NULL);
378 1 hiro
379 1 hiro
        for (i = 0; param[i].name != NULL; i++) {
380 1 hiro
                if (!param[i].data) continue;
381 1 hiro
382 1 hiro
                switch (param[i].type) {
383 1 hiro
                case P_STRING:
384 1 hiro
                        if (param[i].defval != NULL) {
385 333 hiro
                                if (!g_ascii_strncasecmp(param[i].defval, "ENV_", 4)) {
386 1 hiro
                                        const gchar *envstr;
387 1 hiro
                                        gchar *tmp = NULL;
388 1 hiro
389 1 hiro
                                        envstr = g_getenv(param[i].defval + 4);
390 1 hiro
                                        if (envstr) {
391 1 hiro
                                                tmp = conv_codeset_strdup
392 1 hiro
                                                        (envstr,
393 1 hiro
                                                         conv_get_locale_charset_str(),
394 1 hiro
                                                         CS_UTF_8);
395 1 hiro
                                                if (!tmp) {
396 1 hiro
                                                        g_warning("failed to convert character set.");
397 1 hiro
                                                        tmp = g_strdup(envstr);
398 1 hiro
                                                }
399 1 hiro
                                        }
400 1 hiro
                                        *((gchar **)param[i].data) = tmp;
401 1 hiro
                                } else if (param[i].defval[0] == '~')
402 1 hiro
                                        *((gchar **)param[i].data) =
403 1 hiro
                                                g_strconcat(get_home_dir(),
404 1 hiro
                                                            param[i].defval + 1,
405 1 hiro
                                                            NULL);
406 1 hiro
                                else if (param[i].defval[0] != '\0')
407 1 hiro
                                        *((gchar **)param[i].data) =
408 1 hiro
                                                g_strdup(param[i].defval);
409 1 hiro
                                else
410 1 hiro
                                        *((gchar **)param[i].data) = NULL;
411 1 hiro
                        } else
412 1 hiro
                                *((gchar **)param[i].data) = NULL;
413 1 hiro
                        break;
414 1 hiro
                case P_INT:
415 1 hiro
                        if (param[i].defval != NULL)
416 1 hiro
                                *((gint *)param[i].data) =
417 1 hiro
                                        (gint)atoi(param[i].defval);
418 1 hiro
                        else
419 1 hiro
                                *((gint *)param[i].data) = 0;
420 1 hiro
                        break;
421 1 hiro
                case P_BOOL:
422 1 hiro
                        if (param[i].defval != NULL) {
423 333 hiro
                                if (!g_ascii_strcasecmp(param[i].defval, "TRUE"))
424 1 hiro
                                        *((gboolean *)param[i].data) = TRUE;
425 1 hiro
                                else
426 1 hiro
                                        *((gboolean *)param[i].data) =
427 1 hiro
                                                atoi(param[i].defval) ? TRUE : FALSE;
428 1 hiro
                        } else
429 1 hiro
                                *((gboolean *)param[i].data) = FALSE;
430 1 hiro
                        break;
431 1 hiro
                case P_ENUM:
432 1 hiro
                        if (param[i].defval != NULL)
433 1 hiro
                                *((DummyEnum*)param[i].data) =
434 1 hiro
                                        (DummyEnum)atoi(param[i].defval);
435 1 hiro
                        else
436 1 hiro
                                *((DummyEnum *)param[i].data) = 0;
437 1 hiro
                        break;
438 1 hiro
                case P_USHORT:
439 1 hiro
                        if (param[i].defval != NULL)
440 1 hiro
                                *((gushort *)param[i].data) =
441 1 hiro
                                        (gushort)atoi(param[i].defval);
442 1 hiro
                        else
443 1 hiro
                                *((gushort *)param[i].data) = 0;
444 1 hiro
                        break;
445 1 hiro
                default:
446 1 hiro
                        break;
447 1 hiro
                }
448 1 hiro
        }
449 1 hiro
}
450 1 hiro
451 1 hiro
void prefs_free(PrefParam *param)
452 1 hiro
{
453 1 hiro
        gint i;
454 1 hiro
455 1 hiro
        g_return_if_fail(param != NULL);
456 1 hiro
457 1 hiro
        for (i = 0; param[i].name != NULL; i++) {
458 1 hiro
                if (!param[i].data) continue;
459 1 hiro
460 1 hiro
                switch (param[i].type) {
461 1 hiro
                case P_STRING:
462 1 hiro
                        g_free(*((gchar **)param[i].data));
463 1 hiro
                        break;
464 1 hiro
                default:
465 1 hiro
                        break;
466 1 hiro
                }
467 1 hiro
        }
468 1 hiro
}
469 1 hiro
470 1 hiro
void prefs_dialog_create(PrefsDialog *dialog)
471 1 hiro
{
472 1 hiro
        GtkWidget *window;
473 1 hiro
        GtkWidget *vbox;
474 1 hiro
        GtkWidget *notebook;
475 1 hiro
476 1 hiro
        GtkWidget *confirm_area;
477 1 hiro
        GtkWidget *ok_btn;
478 1 hiro
        GtkWidget *cancel_btn;
479 1 hiro
        GtkWidget *apply_btn;
480 1 hiro
481 1 hiro
        g_return_if_fail(dialog != NULL);
482 1 hiro
483 1 hiro
        window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
484 1 hiro
        gtk_container_set_border_width (GTK_CONTAINER (window), 8);
485 1 hiro
        gtk_window_set_position (GTK_WINDOW(window), GTK_WIN_POS_CENTER);
486 1 hiro
        gtk_window_set_modal (GTK_WINDOW (window), TRUE);
487 1 hiro
        gtk_window_set_policy (GTK_WINDOW(window), FALSE, TRUE, FALSE);
488 1 hiro
489 1 hiro
        vbox = gtk_vbox_new (FALSE, 6);
490 1 hiro
        gtk_widget_show(vbox);
491 1 hiro
        gtk_container_add (GTK_CONTAINER (window), vbox);
492 1 hiro
493 1 hiro
        notebook = gtk_notebook_new ();
494 1 hiro
        gtk_widget_show(notebook);
495 1 hiro
        gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0);
496 1 hiro
        gtk_container_set_border_width (GTK_CONTAINER (notebook), 2);
497 1 hiro
        /* GTK_WIDGET_UNSET_FLAGS (notebook, GTK_CAN_FOCUS); */
498 1 hiro
        gtk_notebook_set_scrollable (GTK_NOTEBOOK (notebook), TRUE);
499 1 hiro
500 30 hiro
        gtkut_stock_button_set_create(&confirm_area,
501 30 hiro
                                      &ok_btn, GTK_STOCK_OK,
502 30 hiro
                                      &cancel_btn, GTK_STOCK_CANCEL,
503 30 hiro
                                      &apply_btn, GTK_STOCK_APPLY);
504 1 hiro
        gtk_widget_show(confirm_area);
505 1 hiro
        gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
506 1 hiro
        gtk_widget_grab_default(ok_btn);
507 1 hiro
508 405 hiro
        dialog->window       = window;
509 405 hiro
        dialog->notebook     = notebook;
510 405 hiro
        dialog->confirm_area = confirm_area;
511 405 hiro
        dialog->ok_btn       = ok_btn;
512 405 hiro
        dialog->cancel_btn   = cancel_btn;
513 405 hiro
        dialog->apply_btn    = apply_btn;
514 1 hiro
}
515 1 hiro
516 1 hiro
void prefs_dialog_destroy(PrefsDialog *dialog)
517 1 hiro
{
518 1 hiro
        gtk_widget_destroy(dialog->window);
519 1 hiro
        dialog->window     = NULL;
520 1 hiro
        dialog->notebook   = NULL;
521 1 hiro
        dialog->ok_btn     = NULL;
522 1 hiro
        dialog->cancel_btn = NULL;
523 1 hiro
        dialog->apply_btn  = NULL;
524 1 hiro
}
525 1 hiro
526 1 hiro
void prefs_button_toggled(GtkToggleButton *toggle_btn, GtkWidget *widget)
527 1 hiro
{
528 1 hiro
        gboolean is_active;
529 1 hiro
530 1 hiro
        is_active = gtk_toggle_button_get_active(toggle_btn);
531 1 hiro
        gtk_widget_set_sensitive(widget, is_active);
532 1 hiro
}
533 1 hiro
534 1 hiro
void prefs_set_dialog(PrefParam *param)
535 1 hiro
{
536 1 hiro
        gint i;
537 1 hiro
538 1 hiro
        for (i = 0; param[i].name != NULL; i++) {
539 1 hiro
                if (param[i].widget_set_func)
540 1 hiro
                        param[i].widget_set_func(&param[i]);
541 1 hiro
        }
542 1 hiro
}
543 1 hiro
544 1 hiro
void prefs_set_data_from_dialog(PrefParam *param)
545 1 hiro
{
546 1 hiro
        gint i;
547 1 hiro
548 1 hiro
        for (i = 0; param[i].name != NULL; i++) {
549 1 hiro
                if (param[i].data_set_func)
550 1 hiro
                        param[i].data_set_func(&param[i]);
551 1 hiro
        }
552 1 hiro
}
553 1 hiro
554 1 hiro
void prefs_set_dialog_to_default(PrefParam *param)
555 1 hiro
{
556 1 hiro
        gint           i;
557 1 hiro
        PrefParam  tmpparam;
558 1 hiro
        gchar          *str_data = NULL;
559 1 hiro
        gint           int_data;
560 1 hiro
        gushort    ushort_data;
561 1 hiro
        gboolean   bool_data;
562 1 hiro
        DummyEnum  enum_data;
563 1 hiro
564 1 hiro
        for (i = 0; param[i].name != NULL; i++) {
565 1 hiro
                if (!param[i].widget_set_func) continue;
566 1 hiro
567 1 hiro
                tmpparam = param[i];
568 1 hiro
569 1 hiro
                switch (tmpparam.type) {
570 1 hiro
                case P_STRING:
571 1 hiro
                        if (tmpparam.defval) {
572 433 hiro
                                if (!g_ascii_strncasecmp
573 433 hiro
                                        (tmpparam.defval, "ENV_", 4)) {
574 433 hiro
                                        str_data = g_strdup
575 433 hiro
                                                (g_getenv(param[i].defval + 4));
576 1 hiro
                                        tmpparam.data = &str_data;
577 1 hiro
                                        break;
578 1 hiro
                                } else if (tmpparam.defval[0] == '~') {
579 1 hiro
                                        str_data =
580 1 hiro
                                                g_strconcat(get_home_dir(),
581 1 hiro
                                                            param[i].defval + 1,
582 1 hiro
                                                            NULL);
583 1 hiro
                                        tmpparam.data = &str_data;
584 1 hiro
                                        break;
585 1 hiro
                                }
586 1 hiro
                        }
587 1 hiro
                        tmpparam.data = &tmpparam.defval;
588 1 hiro
                        break;
589 1 hiro
                case P_INT:
590 1 hiro
                        if (tmpparam.defval)
591 1 hiro
                                int_data = atoi(tmpparam.defval);
592 1 hiro
                        else
593 1 hiro
                                int_data = 0;
594 1 hiro
                        tmpparam.data = &int_data;
595 1 hiro
                        break;
596 1 hiro
                case P_USHORT:
597 1 hiro
                        if (tmpparam.defval)
598 1 hiro
                                ushort_data = atoi(tmpparam.defval);
599 1 hiro
                        else
600 1 hiro
                                ushort_data = 0;
601 1 hiro
                        tmpparam.data = &ushort_data;
602 1 hiro
                        break;
603 1 hiro
                case P_BOOL:
604 1 hiro
                        if (tmpparam.defval) {
605 333 hiro
                                if (!g_ascii_strcasecmp(tmpparam.defval, "TRUE"))
606 1 hiro
                                        bool_data = TRUE;
607 1 hiro
                                else
608 1 hiro
                                        bool_data = atoi(tmpparam.defval)
609 1 hiro
                                                ? TRUE : FALSE;
610 1 hiro
                        } else
611 1 hiro
                                bool_data = FALSE;
612 1 hiro
                        tmpparam.data = &bool_data;
613 1 hiro
                        break;
614 1 hiro
                case P_ENUM:
615 1 hiro
                        if (tmpparam.defval)
616 1 hiro
                                enum_data = (DummyEnum)atoi(tmpparam.defval);
617 1 hiro
                        else
618 1 hiro
                                enum_data = 0;
619 1 hiro
                        tmpparam.data = &enum_data;
620 1 hiro
                        break;
621 1 hiro
                case P_OTHER:
622 1 hiro
                        break;
623 1 hiro
                }
624 1 hiro
                tmpparam.widget_set_func(&tmpparam);
625 1 hiro
                g_free(str_data);
626 1 hiro
                str_data = NULL;
627 1 hiro
        }
628 1 hiro
}
629 1 hiro
630 1 hiro
void prefs_set_data_from_entry(PrefParam *pparam)
631 1 hiro
{
632 1 hiro
        gchar **str;
633 1 hiro
        const gchar *entry_str;
634 1 hiro
635 1 hiro
        g_return_if_fail(*pparam->widget != NULL);
636 1 hiro
637 1 hiro
        entry_str = gtk_entry_get_text(GTK_ENTRY(*pparam->widget));
638 1 hiro
639 1 hiro
        switch (pparam->type) {
640 1 hiro
        case P_STRING:
641 1 hiro
                str = (gchar **)pparam->data;
642 1 hiro
                g_free(*str);
643 1 hiro
                *str = entry_str[0] ? g_strdup(entry_str) : NULL;
644 1 hiro
                break;
645 1 hiro
        case P_USHORT:
646 1 hiro
                *((gushort *)pparam->data) = atoi(entry_str);
647 1 hiro
                break;
648 1 hiro
        case P_INT:
649 1 hiro
                *((gint *)pparam->data) = atoi(entry_str);
650 1 hiro
                break;
651 1 hiro
        default:
652 1 hiro
                g_warning("Invalid PrefType for GtkEntry widget: %d\n",
653 1 hiro
                          pparam->type);
654 1 hiro
        }
655 1 hiro
}
656 1 hiro
657 1 hiro
void prefs_set_entry(PrefParam *pparam)
658 1 hiro
{
659 1 hiro
        gchar **str;
660 1 hiro
661 1 hiro
        g_return_if_fail(*pparam->widget != NULL);
662 1 hiro
663 1 hiro
        switch (pparam->type) {
664 1 hiro
        case P_STRING:
665 1 hiro
                str = (gchar **)pparam->data;
666 1 hiro
                gtk_entry_set_text(GTK_ENTRY(*pparam->widget),
667 1 hiro
                                   *str ? *str : "");
668 1 hiro
                break;
669 1 hiro
        case P_INT:
670 1 hiro
                gtk_entry_set_text(GTK_ENTRY(*pparam->widget),
671 1 hiro
                                   itos(*((gint *)pparam->data)));
672 1 hiro
                break;
673 1 hiro
        case P_USHORT:
674 1 hiro
                gtk_entry_set_text(GTK_ENTRY(*pparam->widget),
675 1 hiro
                                   itos(*((gushort *)pparam->data)));
676 1 hiro
                break;
677 1 hiro
        default:
678 1 hiro
                g_warning("Invalid PrefType for GtkEntry widget: %d\n",
679 1 hiro
                          pparam->type);
680 1 hiro
        }
681 1 hiro
}
682 1 hiro
683 1 hiro
void prefs_set_data_from_text(PrefParam *pparam)
684 1 hiro
{
685 1 hiro
        gchar **str;
686 1 hiro
        gchar *text = NULL, *tp = NULL;
687 1 hiro
        gchar *tmp, *tmpp;
688 1 hiro
689 1 hiro
        g_return_if_fail(*pparam->widget != NULL);
690 1 hiro
        g_return_if_fail(GTK_IS_EDITABLE(*pparam->widget) ||
691 1 hiro
                         GTK_IS_TEXT_VIEW(*pparam->widget));
692 1 hiro
693 1 hiro
        switch (pparam->type) {
694 1 hiro
        case P_STRING:
695 1 hiro
                str = (gchar **)pparam->data;
696 1 hiro
                g_free(*str);
697 1 hiro
                if (GTK_IS_EDITABLE(*pparam->widget)) {
698 1 hiro
                        tp = text = gtk_editable_get_chars
699 1 hiro
                                (GTK_EDITABLE(*pparam->widget), 0, -1);
700 1 hiro
                } else if (GTK_IS_TEXT_VIEW(*pparam->widget)) {
701 1 hiro
                        GtkTextView *textview = GTK_TEXT_VIEW(*pparam->widget);
702 1 hiro
                        GtkTextBuffer *buffer;
703 1 hiro
                        GtkTextIter start, end;
704 1 hiro
705 1 hiro
                        buffer = gtk_text_view_get_buffer(textview);
706 1 hiro
                        gtk_text_buffer_get_start_iter(buffer, &start);
707 1 hiro
                        gtk_text_buffer_get_iter_at_offset(buffer, &end, -1);
708 1 hiro
                        tp = text = gtk_text_buffer_get_text
709 1 hiro
                                (buffer, &start, &end, FALSE);
710 1 hiro
                }
711 1 hiro
712 1 hiro
                g_return_if_fail(tp != NULL && text != NULL);
713 1 hiro
714 1 hiro
                if (text[0] == '\0') {
715 1 hiro
                        *str = NULL;
716 1 hiro
                        g_free(text);
717 1 hiro
                        break;
718 1 hiro
                }
719 1 hiro
720 1 hiro
                Xalloca(tmpp = tmp, strlen(text) * 2 + 1,
721 1 hiro
                        { *str = NULL; break; });
722 1 hiro
                while (*tp) {
723 1 hiro
                        if (*tp == '\n') {
724 1 hiro
                                *tmpp++ = '\\';
725 1 hiro
                                *tmpp++ = 'n';
726 1 hiro
                                tp++;
727 1 hiro
                        } else
728 1 hiro
                                *tmpp++ = *tp++;
729 1 hiro
                }
730 1 hiro
                *tmpp = '\0';
731 1 hiro
                *str = g_strdup(tmp);
732 1 hiro
                g_free(text);
733 1 hiro
                break;
734 1 hiro
        default:
735 1 hiro
                g_warning("Invalid PrefType for GtkTextView widget: %d\n",
736 1 hiro
                          pparam->type);
737 1 hiro
        }
738 1 hiro
}
739 1 hiro
740 1 hiro
void prefs_set_text(PrefParam *pparam)
741 1 hiro
{
742 1 hiro
        gchar *buf, *sp, *bufp;
743 1 hiro
        gchar **str;
744 1 hiro
        GtkTextView *text;
745 1 hiro
        GtkTextBuffer *buffer;
746 1 hiro
        GtkTextIter iter;
747 1 hiro
748 1 hiro
        g_return_if_fail(*pparam->widget != NULL);
749 1 hiro
750 1 hiro
        switch (pparam->type) {
751 1 hiro
        case P_STRING:
752 1 hiro
                str = (gchar **)pparam->data;
753 1 hiro
                if (*str) {
754 1 hiro
                        bufp = buf = alloca(strlen(*str) + 1);
755 1 hiro
                        if (!buf) buf = "";
756 1 hiro
                        else {
757 1 hiro
                                sp = *str;
758 1 hiro
                                while (*sp) {
759 1 hiro
                                        if (*sp == '\\' && *(sp + 1) == 'n') {
760 1 hiro
                                                *bufp++ = '\n';
761 1 hiro
                                                sp += 2;
762 1 hiro
                                        } else
763 1 hiro
                                                *bufp++ = *sp++;
764 1 hiro
                                }
765 1 hiro
                                *bufp = '\0';
766 1 hiro
                        }
767 1 hiro
                } else
768 1 hiro
                        buf = "";
769 1 hiro
770 1 hiro
                text = GTK_TEXT_VIEW(*pparam->widget);
771 1 hiro
                buffer = gtk_text_view_get_buffer(text);
772 1 hiro
                gtk_text_buffer_set_text(buffer, "", 0);
773 1 hiro
                gtk_text_buffer_get_start_iter(buffer, &iter);
774 1 hiro
                gtk_text_buffer_insert(buffer, &iter, buf, -1);
775 1 hiro
                break;
776 1 hiro
        default:
777 1 hiro
                g_warning("Invalid PrefType for GtkTextView widget: %d\n",
778 1 hiro
                          pparam->type);
779 1 hiro
        }
780 1 hiro
}
781 1 hiro
782 1 hiro
void prefs_set_data_from_toggle(PrefParam *pparam)
783 1 hiro
{
784 1 hiro
        g_return_if_fail(pparam->type == P_BOOL);
785 1 hiro
        g_return_if_fail(*pparam->widget != NULL);
786 1 hiro
787 1 hiro
        *((gboolean *)pparam->data) =
788 1 hiro
                gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(*pparam->widget));
789 1 hiro
}
790 1 hiro
791 1 hiro
void prefs_set_toggle(PrefParam *pparam)
792 1 hiro
{
793 1 hiro
        g_return_if_fail(pparam->type == P_BOOL);
794 1 hiro
        g_return_if_fail(*pparam->widget != NULL);
795 1 hiro
796 1 hiro
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(*pparam->widget),
797 1 hiro
                                     *((gboolean *)pparam->data));
798 1 hiro
}
799 1 hiro
800 1 hiro
void prefs_set_data_from_spinbtn(PrefParam *pparam)
801 1 hiro
{
802 1 hiro
        g_return_if_fail(*pparam->widget != NULL);
803 1 hiro
804 1 hiro
        switch (pparam->type) {
805 1 hiro
        case P_INT:
806 1 hiro
                *((gint *)pparam->data) =
807 1 hiro
                        gtk_spin_button_get_value_as_int
808 1 hiro
                        (GTK_SPIN_BUTTON(*pparam->widget));
809 1 hiro
                break;
810 1 hiro
        case P_USHORT:
811 1 hiro
                *((gushort *)pparam->data) =
812 1 hiro
                        (gushort)gtk_spin_button_get_value_as_int
813 1 hiro
                        (GTK_SPIN_BUTTON(*pparam->widget));
814 1 hiro
                break;
815 1 hiro
        default:
816 1 hiro
                g_warning("Invalid PrefType for GtkSpinButton widget: %d\n",
817 1 hiro
                          pparam->type);
818 1 hiro
        }
819 1 hiro
}
820 1 hiro
821 1 hiro
void prefs_set_spinbtn(PrefParam *pparam)
822 1 hiro
{
823 1 hiro
        g_return_if_fail(*pparam->widget != NULL);
824 1 hiro
825 1 hiro
        switch (pparam->type) {
826 1 hiro
        case P_INT:
827 1 hiro
                gtk_spin_button_set_value(GTK_SPIN_BUTTON(*pparam->widget),
828 1 hiro
                                          (gfloat)*((gint *)pparam->data));
829 1 hiro
                break;
830 1 hiro
        case P_USHORT:
831 1 hiro
                gtk_spin_button_set_value(GTK_SPIN_BUTTON(*pparam->widget),
832 1 hiro
                                          (gfloat)*((gushort *)pparam->data));
833 1 hiro
                break;
834 1 hiro
        default:
835 1 hiro
                g_warning("Invalid PrefType for GtkSpinButton widget: %d\n",
836 1 hiro
                          pparam->type);
837 1 hiro
        }
838 1 hiro
}