scoring / expression matcher
[claws.git] / src / prefs.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999,2000 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 "utils.h"
35 #include "gtkutils.h"
36
37 typedef enum
38 {
39         DUMMY_PARAM
40 } DummyEnum;
41
42 #define PREFSBUFSIZE    1024
43
44 void prefs_read_config(PrefParam *param, const gchar *label,
45                        const gchar *rcfile)
46 {
47         FILE *fp;
48         gchar buf[PREFSBUFSIZE];
49         gchar *rcpath;
50         gchar *block_label;
51
52         g_return_if_fail(param != NULL);
53         g_return_if_fail(label != NULL);
54         g_return_if_fail(rcfile != NULL);
55
56         debug_print(_("Reading configuration...\n"));
57
58         prefs_set_default(param);
59
60         rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, rcfile, NULL);
61         if ((fp = fopen(rcpath, "r")) == NULL) {
62                 if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
63                 g_free(rcpath);
64                 return;
65         }
66         g_free(rcpath);
67
68         block_label = g_strdup_printf("[%s]", label);
69
70         /* search aiming block */
71         while (fgets(buf, sizeof(buf), fp) != NULL) {
72                 gint val;
73
74                 val = strncmp(buf, block_label, strlen(block_label));
75                 if (val == 0) {
76                         debug_print(_("Found %s\n"), block_label);
77                         break;
78                 }
79         }
80         g_free(block_label);
81
82         while (fgets(buf, sizeof(buf), fp) != NULL) {
83                 strretchomp(buf);
84                 /* reached next block */
85                 if (buf[0] == '[') break;
86
87                 prefs_config_parse_one_line(param, buf);
88         }
89
90         debug_print(_("Finished reading configuration.\n"));
91         fclose(fp);
92 }
93
94 void prefs_config_parse_one_line(PrefParam *param, const gchar *buf)
95 {
96         gint i;
97         gint name_len;
98         const gchar *value;
99
100         for (i = 0; param[i].name != NULL; i++) {
101                 name_len = strlen(param[i].name);
102                 if (strncasecmp(buf, param[i].name, name_len))
103                         continue;
104                 if (buf[name_len] != '=')
105                         continue;
106                 value = buf + name_len + 1;
107                 debug_print("%s = %s\n", param[i].name, value);
108
109                 switch (param[i].type) {
110                 case P_STRING:
111                         g_free(*((gchar **)param[i].data));
112                         *((gchar **)param[i].data) =
113                                 *value ? g_strdup(value) : NULL;
114                         break;
115                 case P_INT:
116                         *((gint *)param[i].data) =
117                                 (gint)atoi(value);
118                         break;
119                 case P_BOOL:
120                         *((gboolean *)param[i].data) =
121                                 (*value == '0' || *value == '\0')
122                                         ? FALSE : TRUE;
123                         break;
124                 case P_ENUM:
125                         *((DummyEnum *)param[i].data) =
126                                 (DummyEnum)atoi(value);
127                         break;
128                 case P_USHORT:
129                         *((gushort *)param[i].data) =
130                                 (gushort)atoi(value);
131                         break;
132                 default:
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_write_close_revert(pfile); \
143         g_free(rcpath); \
144         g_free(block_label); \
145         return; \
146 } \
147
148 void prefs_save_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, "r")) == NULL) {
164                 if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
165         }
166
167         if ((pfile = prefs_write_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_write_param(param, pfile->fp) == 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_write_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_write_param(PrefParam *param, FILE *fp)
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, fp) == EOF) {
253                                 perror("fputs");
254                                 return -1;
255                         }
256                 }
257         }
258
259         return 0;
260 }
261
262 PrefFile *prefs_write_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, "w")) == 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_write_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_write_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                                         *((gchar **)param[i].data) =
368                                                 g_strdup(g_getenv(param[i].defval + 4));
369                                 else if (param[i].defval[0] == '~')
370                                         *((gchar **)param[i].data) =
371                                                 g_strconcat(get_home_dir(),
372                                                             param[i].defval + 1,
373                                                             NULL);
374                                 else if (param[i].defval[0] != '\0')
375                                         *((gchar **)param[i].data) =
376                                                 g_strdup(param[i].defval);
377                                 else
378                                         *((gchar **)param[i].data) = NULL;
379                         } else
380                                 *((gchar **)param[i].data) = NULL;
381                         break;
382                 case P_INT:
383                         if (param[i].defval != NULL)
384                                 *((gint *)param[i].data) =
385                                         (gint)atoi(param[i].defval);
386                         else
387                                 *((gint *)param[i].data) = 0;
388                         break;
389                 case P_BOOL:
390                         if (param[i].defval != NULL) {
391                                 if (!strcasecmp(param[i].defval, "TRUE"))
392                                         *((gboolean *)param[i].data) = TRUE;
393                                 else
394                                         *((gboolean *)param[i].data) =
395                                                 atoi(param[i].defval) ? TRUE : FALSE;
396                         } else
397                                 *((gboolean *)param[i].data) = FALSE;
398                         break;
399                 case P_ENUM:
400                         if (param[i].defval != NULL)
401                                 *((DummyEnum*)param[i].data) =
402                                         (DummyEnum)atoi(param[i].defval);
403                         else
404                                 *((DummyEnum *)param[i].data) = 0;
405                         break;
406                 case P_USHORT:
407                         if (param[i].defval != NULL)
408                                 *((gushort *)param[i].data) =
409                                         (gushort)atoi(param[i].defval);
410                         else
411                                 *((gushort *)param[i].data) = 0;
412                         break;
413                 default:
414                 }
415         }
416 }
417
418 void prefs_free(PrefParam *param)
419 {
420         gint i;
421
422         g_return_if_fail(param != NULL);
423
424         for (i = 0; param[i].name != NULL; i++) {
425                 if (!param[i].data) continue;
426
427                 switch (param[i].type) {
428                 case P_STRING:
429                         g_free(*((gchar **)param[i].data));
430                         break;
431                 default:
432                 }
433         }
434 }
435
436 void prefs_dialog_create(PrefsDialog *dialog)
437 {
438         GtkWidget *window;
439         GtkWidget *vbox;
440         GtkWidget *notebook;
441
442         GtkWidget *confirm_area;
443         GtkWidget *ok_btn;
444         GtkWidget *cancel_btn;
445         GtkWidget *apply_btn;
446
447         g_return_if_fail(dialog != NULL);
448
449         window = gtk_window_new (GTK_WINDOW_DIALOG);
450         gtk_container_set_border_width (GTK_CONTAINER (window), 8);
451         gtk_window_position (GTK_WINDOW(window), GTK_WIN_POS_CENTER);
452         gtk_window_set_modal (GTK_WINDOW (window), TRUE);
453         gtk_window_set_policy (GTK_WINDOW(window), FALSE, TRUE, FALSE);
454
455         vbox = gtk_vbox_new (FALSE, 6);
456         gtk_widget_show(vbox);
457         gtk_container_add (GTK_CONTAINER (window), vbox);
458
459         notebook = gtk_notebook_new ();
460         gtk_widget_show(notebook);
461         gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0);
462         gtk_container_set_border_width (GTK_CONTAINER (notebook), 2);
463         /* GTK_WIDGET_UNSET_FLAGS (notebook, GTK_CAN_FOCUS); */
464         gtk_notebook_set_scrollable (GTK_NOTEBOOK (notebook), TRUE);
465
466         gtkut_button_set_create(&confirm_area,
467                                 &ok_btn,        _("OK"),
468                                 &cancel_btn,    _("Cancel"),
469                                 &apply_btn,     _("Apply"));
470         gtk_widget_show(confirm_area);
471         gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
472         gtk_widget_grab_default(ok_btn);
473
474         dialog->window     = window;
475         dialog->notebook   = notebook;
476         dialog->ok_btn     = ok_btn;
477         dialog->cancel_btn = cancel_btn;
478         dialog->apply_btn  = apply_btn;
479 }
480
481 void prefs_button_toggled(GtkToggleButton *toggle_btn, GtkWidget *widget)
482 {
483         gboolean is_active;
484
485         is_active = gtk_toggle_button_get_active(toggle_btn);
486         gtk_widget_set_sensitive(widget, is_active);
487 }
488
489 void prefs_set_dialog(PrefParam *param)
490 {
491         gint i;
492
493         for (i = 0; param[i].name != NULL; i++) {
494                 if (param[i].widget_set_func)
495                         param[i].widget_set_func(&param[i]);
496         }
497 }
498
499 void prefs_set_data_from_dialog(PrefParam *param)
500 {
501         gint i;
502
503         for (i = 0; param[i].name != NULL; i++) {
504                 if (param[i].data_set_func)
505                         param[i].data_set_func(&param[i]);
506         }
507 }
508
509 void prefs_set_dialog_to_default(PrefParam *param)
510 {
511         gint       i;
512         PrefParam  tmpparam;
513         gchar     *str_data = NULL;
514         gint       int_data;
515         gushort    ushort_data;
516         gboolean   bool_data;
517         DummyEnum  enum_data;
518
519         for (i = 0; param[i].name != NULL; i++) {
520                 if (!param[i].widget_set_func) continue;
521
522                 tmpparam = param[i];
523
524                 switch (tmpparam.type) {
525                 case P_STRING:
526                         if (tmpparam.defval) {
527                                 if (!strncasecmp(tmpparam.defval, "ENV_", 4)) {
528                                         str_data = g_strdup(g_getenv(param[i].defval + 4));
529                                         tmpparam.data = &str_data;
530                                         break;
531                                 } else if (tmpparam.defval[0] == '~') {
532                                         str_data =
533                                                 g_strconcat(get_home_dir(),
534                                                             param[i].defval + 1,
535                                                             NULL);
536                                         tmpparam.data = &str_data;
537                                         break;
538                                 }
539                         }
540                         tmpparam.data = &tmpparam.defval;
541                         break;
542                 case P_INT:
543                         if (tmpparam.defval)
544                                 int_data = atoi(tmpparam.defval);
545                         else
546                                 int_data = 0;
547                         tmpparam.data = &int_data;
548                         break;
549                 case P_USHORT:
550                         if (tmpparam.defval)
551                                 ushort_data = atoi(tmpparam.defval);
552                         else
553                                 ushort_data = 0;
554                         tmpparam.data = &ushort_data;
555                         break;
556                 case P_BOOL:
557                         if (tmpparam.defval) {
558                                 if (!strcasecmp(tmpparam.defval, "TRUE"))
559                                         bool_data = TRUE;
560                                 else
561                                         bool_data = atoi(tmpparam.defval)
562                                                 ? TRUE : FALSE;
563                         } else
564                                 bool_data = FALSE;
565                         tmpparam.data = &bool_data;
566                         break;
567                 case P_ENUM:
568                         if (tmpparam.defval)
569                                 enum_data = (DummyEnum)atoi(tmpparam.defval);
570                         else
571                                 enum_data = 0;
572                         tmpparam.data = &enum_data;
573                         break;
574                 case P_OTHER:
575                 }
576                 tmpparam.widget_set_func(&tmpparam);
577                 g_free(str_data);
578                 str_data = NULL;
579         }
580 }
581
582 void prefs_set_data_from_entry(PrefParam *pparam)
583 {
584         gchar **str, *entry_str;
585
586         g_return_if_fail(*pparam->widget != NULL);
587
588         entry_str = gtk_entry_get_text(GTK_ENTRY(*pparam->widget));
589
590         switch (pparam->type) {
591         case P_STRING:
592                 str = (gchar **)pparam->data;
593                 g_free(*str);
594                 *str = entry_str[0] ? g_strdup(entry_str) : NULL;
595                 break;
596         case P_USHORT:
597                 *((gushort *)pparam->data) = atoi(entry_str);
598                 break;
599         case P_INT:
600                 *((gint *)pparam->data) = atoi(entry_str);
601                 break;
602         default:
603                 g_warning("Invalid PrefType for GtkEntry widget: %d\n",
604                           pparam->type);
605         }
606 }
607
608 void prefs_set_entry(PrefParam *pparam)
609 {
610         gchar **str;
611
612         g_return_if_fail(*pparam->widget != NULL);
613
614         switch (pparam->type) {
615         case P_STRING:
616                 str = (gchar **)pparam->data;
617                 gtk_entry_set_text(GTK_ENTRY(*pparam->widget),
618                                    *str ? *str : "");
619                 break;
620         case P_INT:
621                 gtk_entry_set_text(GTK_ENTRY(*pparam->widget),
622                                    itos(*((gint *)pparam->data)));
623                 break;
624         case P_USHORT:
625                 gtk_entry_set_text(GTK_ENTRY(*pparam->widget),
626                                    itos(*((gushort *)pparam->data)));
627                 break;
628         default:
629                 g_warning("Invalid PrefType for GtkEntry widget: %d\n",
630                           pparam->type);
631         }
632 }
633
634 void prefs_set_data_from_text(PrefParam *pparam)
635 {
636         gchar **str;
637         gchar *text, *tp;
638         gchar *tmp, *tmpp;
639
640         g_return_if_fail(*pparam->widget != NULL);
641
642         switch (pparam->type) {
643         case P_STRING:
644                 str = (gchar **)pparam->data;
645                 g_free(*str);
646                 tp = text = gtk_editable_get_chars
647                         (GTK_EDITABLE(*pparam->widget), 0, -1);
648                 if (text[0] == '\0') {
649                         *str = NULL;
650                         g_free(text);
651                         break;
652                 }
653
654                 Xalloca(tmpp = tmp, strlen(text) * 2 + 1,
655                         { *str = NULL; break; });
656                 while (*tp) {
657                         if (*tp == '\n') {
658                                 *tmpp++ = '\\';
659                                 *tmpp++ = 'n';
660                                 tp++;
661                         } else
662                                 *tmpp++ = *tp++;
663                 }
664                 *tmpp = '\0';
665                 *str = g_strdup(tmp);
666                 g_free(text);
667                 break;
668         default:
669                 g_warning("Invalid PrefType for GtkText widget: %d\n",
670                           pparam->type);
671         }
672 }
673
674 void prefs_set_text(PrefParam *pparam)
675 {
676         gchar *buf, *sp, *bufp;
677         gchar **str;
678         GtkText *text;
679
680         g_return_if_fail(*pparam->widget != NULL);
681
682         switch (pparam->type) {
683         case P_STRING:
684                 str = (gchar **)pparam->data;
685                 if (*str) {
686                         bufp = buf = alloca(strlen(*str) + 1);
687                         if (!buf) buf = "";
688                         else {
689                                 sp = *str;
690                                 while (*sp) {
691                                         if (*sp == '\\' && *(sp + 1) == 'n') {
692                                                 *bufp++ = '\n';
693                                                 sp += 2;
694                                         } else
695                                                 *bufp++ = *sp++;
696                                 }
697                                 *bufp = '\0';
698                         }
699                 } else
700                         buf = "";
701
702                 text = GTK_TEXT(*pparam->widget);
703                 gtk_text_set_point(text, 0);
704                 gtk_text_forward_delete(text, gtk_text_get_length(text));
705                 gtk_text_set_point(text, 0);
706                 gtk_text_insert(text, NULL, NULL, NULL, buf, -1);
707                 break;
708         default:
709                 g_warning("Invalid PrefType for GtkText widget: %d\n",
710                           pparam->type);
711         }
712 }
713
714 void prefs_set_data_from_toggle(PrefParam *pparam)
715 {
716         g_return_if_fail(pparam->type == P_BOOL);
717         g_return_if_fail(*pparam->widget != NULL);
718         
719         *((gboolean *)pparam->data) =
720                 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(*pparam->widget));
721 }
722
723 void prefs_set_toggle(PrefParam *pparam)
724 {
725         g_return_if_fail(pparam->type == P_BOOL);
726         g_return_if_fail(*pparam->widget != NULL);
727
728         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(*pparam->widget),
729                                      *((gboolean *)pparam->data));
730 }
731
732 void prefs_set_data_from_spinbtn(PrefParam *pparam)
733 {
734         g_return_if_fail(*pparam->widget != NULL);
735
736         switch (pparam->type) {
737         case P_INT:
738                 *((gint *)pparam->data) =
739                         gtk_spin_button_get_value_as_int
740                         (GTK_SPIN_BUTTON(*pparam->widget));
741                 break;
742         case P_USHORT:
743                 *((gushort *)pparam->data) =
744                         (gushort)gtk_spin_button_get_value_as_int
745                         (GTK_SPIN_BUTTON(*pparam->widget));
746                 break;
747         default:
748                 g_warning("Invalid PrefType for GtkSpinButton widget: %d\n",
749                           pparam->type);
750         }
751 }
752
753 void prefs_set_spinbtn(PrefParam *pparam)
754 {
755         g_return_if_fail(*pparam->widget != NULL);
756
757         switch (pparam->type) {
758         case P_INT:
759                 gtk_spin_button_set_value(GTK_SPIN_BUTTON(*pparam->widget),
760                                           (gfloat)*((gint *)pparam->data));
761                 break;
762         case P_USHORT:
763                 gtk_spin_button_set_value(GTK_SPIN_BUTTON(*pparam->widget),
764                                           (gfloat)*((gushort *)pparam->data));
765                 break;
766         default:
767                 g_warning("Invalid PrefType for GtkSpinButton widget: %d\n",
768                           pparam->type);
769         }
770 }