* make the shape export work again
[dia.git] / app / preferences.c
blobf6f543c32f8c166dce6d05547df3fe40f7a72272
1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1999 Alexander Larsson
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 #include "config.h"
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #ifdef HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
29 #ifdef HAVE_STDDEF_H
30 #include <stddef.h>
31 #endif
32 #include <locale.h>
34 #ifdef GNOME
35 # include <gnome.h>
36 #else
37 # include <gtk/gtk.h>
38 #endif
40 #include "intl.h"
41 #include "widgets.h"
42 #include "diagram.h"
43 #include "message.h"
44 #include "preferences.h"
45 #include "dia_dirs.h"
47 struct DiaPreferences prefs;
49 enum DiaPrefType {
50 PREF_NONE,
51 PREF_BOOLEAN,
52 PREF_INT,
53 PREF_UINT,
54 PREF_REAL,
55 PREF_UREAL,
56 PREF_COLOUR
59 struct DiaPrefsData {
60 char *name;
61 enum DiaPrefType type;
62 int offset;
63 void *default_value;
64 int tab;
65 char *label_text;
66 GtkWidget *widget;
69 static int default_true = 1;
70 static int default_false = 0;
71 static real default_real_one = 1.0;
72 static real default_real_zoom = 100.0;
73 static int default_int_w = 500;
74 static int default_int_h = 400;
75 static int default_undo_depth = 15;
76 static Color default_colour = { 0.5, 0.5, 0.5 };
77 static Color pbreak_colour = { 0.0, 0.0, 0.6 };
79 struct DiaPrefsTab {
80 char *title;
81 GtkTable *table;
82 int row;
85 struct DiaPrefsTab prefs_tabs[] =
87 {N_("User Interface"), NULL, 0},
88 {N_("View Defaults"), NULL, 0},
89 {N_("Grid Lines"), NULL, 0},
92 #define NUM_PREFS_TABS (sizeof(prefs_tabs)/sizeof(struct DiaPrefsTab))
94 /* retrive a structure offset */
95 #ifdef offsetof
96 #define PREF_OFFSET(field) ((int) offsetof (struct DiaPreferences, field))
97 #else /* !offsetof */
98 #define PREF_OFFSET(field) ((int) ((char*) &((struct DiaPreferences *) 0)->field))
99 #endif /* !offsetof */
101 struct DiaPrefsData prefs_data[] =
103 { "reset_tools_after_create", PREF_BOOLEAN, PREF_OFFSET(reset_tools_after_create), &default_true, 0, N_("Reset tools after create:") },
104 { "compress_save", PREF_BOOLEAN, PREF_OFFSET(compress_save), &default_true, 0, N_("Compress saved files:") },
105 { "undo_depth", PREF_UINT, PREF_OFFSET(undo_depth), &default_undo_depth, 0, N_("Number of undo levels:") },
106 { "reverse_rubberbanding_intersects", PREF_BOOLEAN, PREF_OFFSET(reverse_rubberbanding_intersects), &default_true, 0, N_("Reverse dragging selects\nintersecting objects:") },
107 { NULL, PREF_NONE, 0, NULL, 1, N_("New window:") },
108 { "new_view_width", PREF_UINT, PREF_OFFSET(new_view.width), &default_int_w, 1, N_("Width:") },
109 { "new_view_height", PREF_UINT, PREF_OFFSET(new_view.height), &default_int_h, 1, N_("Height:") },
110 { "new_view_zoom", PREF_UREAL, PREF_OFFSET(new_view.zoom), &default_real_zoom, 1, N_("Magnify:") },
112 { NULL, PREF_NONE, 0, NULL, 1, N_("Connection Points:") },
113 { "show_cx_pts", PREF_BOOLEAN, PREF_OFFSET(show_cx_pts), &default_true, 1, N_("Visible:") },
115 { NULL, PREF_NONE, 0, NULL, 2, N_("Grid:") },
116 { "grid_visible", PREF_BOOLEAN, PREF_OFFSET(grid.visible), &default_true, 2, N_("Visible:") },
117 { "grid_snap", PREF_BOOLEAN, PREF_OFFSET(grid.snap), &default_false, 2, N_("Snap to:") },
118 { "grid_x", PREF_UREAL, PREF_OFFSET(grid.x), &default_real_one, 2, N_("X Size:") },
119 { "grid_y", PREF_UREAL, PREF_OFFSET(grid.y), &default_real_one, 2, N_("Y Size:") },
120 { "grid_colour", PREF_COLOUR, PREF_OFFSET(grid.colour), &default_colour, 2, N_("Colour:") },
121 { "grid_solid", PREF_BOOLEAN, PREF_OFFSET(grid.solid), &default_true, 2, N_("Solid lines:") },
123 { NULL, PREF_NONE, 0, NULL, 2, N_("Page breaks:") },
124 { "pagebreak_visible", PREF_BOOLEAN, PREF_OFFSET(pagebreak.visible), &default_true, 2, N_("Visible:") },
125 { "pagebreak_colour", PREF_COLOUR, PREF_OFFSET(pagebreak.colour), &pbreak_colour, 2, N_("Colour:") },
126 { "pagebreak_solid", PREF_BOOLEAN, PREF_OFFSET(pagebreak.solid), &default_true, 2, N_("Solid lines:") },
129 #define NUM_PREFS_DATA (sizeof(prefs_data)/sizeof(struct DiaPrefsData))
131 static const GScannerConfig dia_prefs_scanner_config =
134 " \t\n"
135 ) /* cset_skip_characters */,
137 G_CSET_a_2_z
139 G_CSET_A_2_Z
140 ) /* cset_identifier_first */,
142 G_CSET_a_2_z
143 "_-0123456789"
144 G_CSET_A_2_Z
145 ) /* cset_identifier_nth */,
146 ( "#\n" ) /* cpair_comment_single */,
148 TRUE /* case_sensitive */,
150 FALSE /* skip_comment_multi */,
151 TRUE /* skip_comment_single */,
152 FALSE /* scan_comment_multi */,
153 TRUE /* scan_identifier */,
154 TRUE /* scan_identifier_1char */,
155 FALSE /* scan_identifier_NULL */,
156 TRUE /* scan_symbols */,
157 FALSE /* scan_binary */,
158 FALSE /* scan_octal */,
159 TRUE /* scan_float */,
160 TRUE /* scan_hex */,
161 FALSE /* scan_hex_dollar */,
162 FALSE /* scan_string_sq */,
163 TRUE /* scan_string_dq */,
164 TRUE /* numbers_2_int */,
165 FALSE /* int_2_float */,
166 FALSE /* identifier_2_string */,
167 TRUE /* char_2_token */,
168 FALSE /* symbol_2_token */,
169 FALSE /* scope_0_fallback */,
172 typedef enum {
173 DIA_PREFS_TOKEN_BOOLEAN = G_TOKEN_LAST
174 } DiaPrefsTokenType;
176 static void prefs_create_dialog(void);
177 static void prefs_set_value_in_widget(GtkWidget * widget, enum DiaPrefType type, char *ptr);
178 static void prefs_get_value_from_widget(GtkWidget * widget, enum DiaPrefType type, char *ptr);
179 static void prefs_update_dialog_from_prefs(void);
180 static void prefs_update_prefs_from_dialog(void);
181 static gint prefs_apply(GtkWidget *widget, gpointer data);
184 static GtkWidget *prefs_dialog = NULL;
186 void
187 prefs_show(void)
189 prefs_create_dialog();
190 gtk_widget_show(prefs_dialog);
192 prefs_update_dialog_from_prefs();
195 void
196 prefs_set_defaults(void)
198 int i;
199 char *ptr;
201 for (i=0;i<NUM_PREFS_DATA;i++) {
202 ptr = (char *)&prefs + prefs_data[i].offset;
204 switch (prefs_data[i].type) {
205 case PREF_BOOLEAN:
206 case PREF_INT:
207 case PREF_UINT:
208 *(int *)ptr = *(int *)prefs_data[i].default_value;
209 break;
210 case PREF_REAL:
211 case PREF_UREAL:
212 *(real *)ptr = *(real *)prefs_data[i].default_value;
213 break;
214 case PREF_COLOUR:
215 *(Color *)ptr = *(Color *)prefs_data[i].default_value;
216 break;
217 case PREF_NONE:
218 break;
223 void
224 prefs_save(void)
226 int i;
227 char *ptr;
228 gchar *filename;
229 char *old_locale;
230 FILE *file;
232 filename = dia_config_filename("diarc");
234 file = fopen(filename, "w");
236 if (!file) {
237 message_error(_("Could not open `%s' for writing"), filename);
238 g_free(filename);
239 return;
242 g_free(filename);
244 old_locale = setlocale(LC_NUMERIC, "C");
245 fprintf(file, "# Note: This file is automatically generated by Dia\n");
246 for (i=0;i<NUM_PREFS_DATA;i++) {
247 if (prefs_data[i].type == PREF_NONE)
248 continue;
250 fprintf(file, "%s=", prefs_data[i].name);
252 ptr = (char *)&prefs + prefs_data[i].offset;
254 switch (prefs_data[i].type) {
255 case PREF_BOOLEAN:
256 fprintf(file, (*(int *)ptr)?"true\n":"false\n");
257 break;
258 case PREF_INT:
259 case PREF_UINT:
260 fprintf(file, "%d\n", *(int *)ptr);
261 break;
262 case PREF_REAL:
263 case PREF_UREAL:
265 fprintf(file, "%f\n", (double) *(real *)ptr);
266 break;
267 case PREF_COLOUR:
268 fprintf(file, "%f %f %f\n", (double) ((Color *)ptr)->red,
269 (double) ((Color *)ptr)->green, (double) ((Color *)ptr)->blue);
270 case PREF_NONE:
271 break;
274 setlocale(LC_NUMERIC, old_locale);
275 fclose(file);
279 static guint
280 prefs_parse_line(GScanner *scanner)
282 guint token;
283 int symbol_nr;
284 char *ptr;
286 token = g_scanner_get_next_token(scanner);
287 if (token != G_TOKEN_SYMBOL)
288 return G_TOKEN_SYMBOL;
290 symbol_nr = GPOINTER_TO_INT(scanner->value.v_symbol);
292 token = g_scanner_get_next_token(scanner);
293 if (token != G_TOKEN_EQUAL_SIGN)
294 return G_TOKEN_EQUAL_SIGN;
296 token = g_scanner_get_next_token(scanner);
298 ptr = (unsigned char *)&prefs + prefs_data[symbol_nr].offset;
300 switch (prefs_data[symbol_nr].type) {
301 case PREF_BOOLEAN:
302 if (token != G_TOKEN_IDENTIFIER)
303 return G_TOKEN_IDENTIFIER;
305 if (strcmp(scanner->value.v_string, "true")==0)
306 *(int *)ptr = 1;
307 else
308 *(int *)ptr = 0;
309 break;
311 case PREF_INT:
312 case PREF_UINT:
313 if (token != G_TOKEN_INT)
314 return G_TOKEN_INT;
316 *(int *)ptr = scanner->value.v_int;
317 break;
319 case PREF_REAL:
320 case PREF_UREAL:
321 if (token != G_TOKEN_FLOAT)
322 return G_TOKEN_FLOAT;
324 *(real *)ptr = scanner->value.v_float;
325 break;
326 case PREF_COLOUR:
327 if (token != G_TOKEN_FLOAT)
328 return G_TOKEN_FLOAT;
329 ((Color *)ptr)->red = scanner->value.v_float;
331 token = g_scanner_get_next_token(scanner);
332 if (token != G_TOKEN_FLOAT)
333 return G_TOKEN_FLOAT;
334 ((Color *)ptr)->green = scanner->value.v_float;
336 token = g_scanner_get_next_token(scanner);
337 if (token != G_TOKEN_FLOAT)
338 return G_TOKEN_FLOAT;
339 ((Color *)ptr)->blue = scanner->value.v_float;
341 break;
342 case PREF_NONE:
343 break;
346 return G_TOKEN_NONE;
350 void
351 prefs_load(void)
353 int i;
354 gchar *filename;
355 int fd;
356 GScanner *scanner;
357 guint expected_token;
359 filename = dia_config_filename("diarc");
361 fd = open(filename, O_RDONLY);
363 if (fd < 0) {
364 char *homedir = g_get_home_dir();
366 g_free(filename);
367 filename = g_strconcat(homedir, G_DIR_SEPARATOR_S ".diarc", NULL);
368 fd = open(filename, O_RDONLY);
370 g_free(filename);
372 prefs_set_defaults();
374 if (fd < 0) {
375 return;
378 scanner = g_scanner_new ((GScannerConfig *) &dia_prefs_scanner_config);
380 g_scanner_input_file (scanner, fd);
382 scanner->input_name = filename;
384 g_scanner_freeze_symbol_table(scanner);
385 for (i = 0; i < NUM_PREFS_DATA; i++)
386 if (prefs_data[i].type != PREF_NONE) {
387 g_scanner_add_symbol(scanner, prefs_data[i].name,
388 GINT_TO_POINTER(i));
390 g_scanner_thaw_symbol_table(scanner);
392 while (1) {
393 if (g_scanner_peek_next_token(scanner) == G_TOKEN_EOF) {
394 break;
397 expected_token = prefs_parse_line(scanner);
399 if (expected_token != G_TOKEN_NONE) {
400 gchar *symbol_name;
401 gchar *msg;
403 msg = NULL;
404 symbol_name = NULL;
405 g_scanner_unexp_token (scanner,
406 expected_token,
407 NULL,
408 "keyword",
409 symbol_name,
410 msg,
411 TRUE);
415 g_scanner_destroy (scanner);
417 close(fd);
420 static gint
421 prefs_okay(GtkWidget *widget, gpointer data)
423 gint ret = prefs_apply(widget,data);
424 gtk_widget_hide(widget);
425 return ret;
428 static gint
429 prefs_apply(GtkWidget *widget, gpointer data)
431 prefs_update_prefs_from_dialog();
432 prefs_save();
433 diagram_redraw_all();
434 return 1;
437 static void
438 prefs_set_value_in_widget(GtkWidget * widget, enum DiaPrefType type,
439 char *ptr)
441 switch(type) {
442 case PREF_BOOLEAN:
443 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), *((int *)ptr));
444 break;
445 case PREF_INT:
446 case PREF_UINT:
447 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget),
448 (gfloat) (*((int *)ptr)));
449 break;
450 case PREF_REAL:
451 case PREF_UREAL:
452 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget),
453 (gfloat) (*((real *)ptr)));
454 break;
455 case PREF_COLOUR:
456 dia_color_selector_set_color(DIACOLORSELECTOR(widget), (Color *)ptr);
457 break;
458 case PREF_NONE:
459 break;
463 static void
464 prefs_get_value_from_widget(GtkWidget * widget, enum DiaPrefType type,
465 char *ptr)
467 switch(type) {
468 case PREF_BOOLEAN:
469 *((int *)ptr) = GTK_TOGGLE_BUTTON(widget)->active;
470 break;
471 case PREF_INT:
472 case PREF_UINT:
473 *((int *)ptr) =
474 gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
475 break;
476 case PREF_REAL:
477 case PREF_UREAL:
478 *((real *)ptr) = (real)
479 gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(widget));
480 break;
481 case PREF_COLOUR:
482 dia_color_selector_get_color(DIACOLORSELECTOR(widget), (Color *)ptr);
483 break;
484 case PREF_NONE:
485 break;
489 static void
490 prefs_boolean_toggle(GtkWidget *widget, gpointer data)
492 guint active = GTK_TOGGLE_BUTTON(widget)->active;
493 GtkWidget *label = GTK_BUTTON(widget)->child;
494 gtk_label_set(GTK_LABEL(label), active ? _("Yes") : _("No"));
497 static GtkWidget *
498 prefs_get_property_widget(enum DiaPrefType type)
500 GtkWidget *widget = NULL;
501 GtkAdjustment *adj;
503 switch(type) {
504 case PREF_BOOLEAN:
505 widget = gtk_toggle_button_new_with_label (_("No"));
506 gtk_signal_connect (GTK_OBJECT (widget), "toggled",
507 GTK_SIGNAL_FUNC (prefs_boolean_toggle), NULL);
508 break;
509 case PREF_INT:
510 adj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0,
511 G_MININT, G_MAXINT,
512 1.0, 10.0, 10.0 ));
513 widget = gtk_spin_button_new (adj, 1.0, 0);
514 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(widget), TRUE);
515 gtk_widget_set_usize(widget, 80, -1);
516 break;
517 case PREF_UINT:
518 adj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0,
519 0.0, G_MAXINT,
520 1.0, 10.0, 10.0 ));
521 widget = gtk_spin_button_new (adj, 1.0, 0);
522 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(widget), TRUE);
523 gtk_widget_set_usize(widget, 80, -1);
524 break;
525 case PREF_REAL:
526 adj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0,
527 G_MINFLOAT, G_MAXFLOAT,
528 1.0, 10.0, 10.0 ));
529 widget = gtk_spin_button_new (adj, 1.0, 3);
530 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(widget), TRUE);
531 gtk_widget_set_usize(widget, 80, -1);
532 break;
533 case PREF_UREAL:
534 adj = GTK_ADJUSTMENT(gtk_adjustment_new(0.0,
535 0.0, G_MAXFLOAT,
536 1.0, 10.0, 10.0 ));
537 widget = gtk_spin_button_new (adj, 1.0, 3);
538 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(widget), TRUE);
539 gtk_widget_set_usize(widget, 80, -1);
540 break;
541 case PREF_COLOUR:
542 widget = dia_color_selector_new();
543 break;
544 case PREF_NONE:
545 widget = NULL;
546 break;
548 if (widget != NULL)
549 gtk_widget_show(widget);
550 return widget;
553 static void
554 prefs_create_dialog(void)
556 GtkWidget *notebook_page;
557 GtkWidget *label;
558 #ifndef GNOME
559 GtkWidget *button;
560 #endif
561 GtkWidget *dialog_vbox;
562 GtkWidget *notebook;
563 GtkWidget *table;
564 int i;
566 if (prefs_dialog != NULL)
567 return;
569 #ifdef GNOME
570 prefs_dialog = gnome_dialog_new(_("Preferences"),
571 GNOME_STOCK_BUTTON_OK,
572 GNOME_STOCK_BUTTON_APPLY,
573 GNOME_STOCK_BUTTON_CLOSE, NULL);
574 gnome_dialog_set_default(GNOME_DIALOG(prefs_dialog), 1);
576 dialog_vbox = GNOME_DIALOG(prefs_dialog)->vbox;
577 #else
578 prefs_dialog = gtk_dialog_new();
579 gtk_window_set_title (GTK_WINDOW (prefs_dialog), _("Preferences"));
580 gtk_container_set_border_width (GTK_CONTAINER (prefs_dialog), 2);
581 gtk_window_set_policy (GTK_WINDOW (prefs_dialog),
582 FALSE, TRUE, FALSE);
584 dialog_vbox = GTK_DIALOG (prefs_dialog)->vbox;
585 #endif
587 gtk_window_set_wmclass (GTK_WINDOW (prefs_dialog),
588 "preferences_window", "Dia");
591 #ifdef GNOME
592 gnome_dialog_button_connect_object(GNOME_DIALOG(prefs_dialog), 0,
593 GTK_SIGNAL_FUNC(prefs_okay),
594 GTK_OBJECT(prefs_dialog));
595 gnome_dialog_button_connect_object(GNOME_DIALOG(prefs_dialog), 1,
596 GTK_SIGNAL_FUNC(prefs_apply),
597 GTK_OBJECT(prefs_dialog));
598 gnome_dialog_button_connect_object(GNOME_DIALOG(prefs_dialog), 2,
599 GTK_SIGNAL_FUNC(gtk_widget_hide),
600 GTK_OBJECT(prefs_dialog));
601 #else
602 button = gtk_button_new_with_label( _("OK") );
603 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
604 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (prefs_dialog)->action_area),
605 button, TRUE, TRUE, 0);
606 gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
607 GTK_SIGNAL_FUNC(prefs_okay),
608 GTK_OBJECT(prefs_dialog));
609 gtk_widget_show (button);
611 button = gtk_button_new_with_label( _("Apply") );
612 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
613 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (prefs_dialog)->action_area),
614 button, TRUE, TRUE, 0);
615 gtk_signal_connect (GTK_OBJECT (button), "clicked",
616 GTK_SIGNAL_FUNC(prefs_apply),
617 NULL);
618 gtk_widget_show (button);
620 button = gtk_button_new_with_label( _("Close") );
621 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
622 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (prefs_dialog)->action_area),
623 button, TRUE, TRUE, 0);
624 gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
625 GTK_SIGNAL_FUNC(gtk_widget_hide),
626 GTK_OBJECT(prefs_dialog));
627 gtk_widget_grab_default (button);
628 gtk_widget_show (button);
629 #endif
631 gtk_signal_connect (GTK_OBJECT (prefs_dialog), "delete_event",
632 GTK_SIGNAL_FUNC(gtk_widget_hide), NULL);
634 notebook = gtk_notebook_new ();
635 gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
636 gtk_box_pack_start (GTK_BOX (dialog_vbox), notebook, TRUE, TRUE, 0);
637 gtk_container_set_border_width (GTK_CONTAINER (notebook), 2);
638 gtk_widget_show (notebook);
640 for (i=0;i<NUM_PREFS_TABS;i++) {
641 label = gtk_label_new(gettext(prefs_tabs[i].title));
642 gtk_widget_show(label);
644 table = gtk_table_new (9, 2, FALSE);
645 prefs_tabs[i].table = GTK_TABLE(table);
646 gtk_widget_show(table);
648 #ifdef SCROLLED_PAGES
649 notebook_page = gtk_scrolled_window_new (NULL, NULL);
650 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (notebook_page),
651 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
652 gtk_widget_show(notebook_page);
653 #else
654 notebook_page = table;
655 #endif/* SCROLLED_PAGES */
657 gtk_notebook_append_page(GTK_NOTEBOOK(notebook), notebook_page, label);
659 #ifdef SCROLLED_PAGES
660 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(notebook_page),
661 table);
662 gtk_viewport_set_shadow_type(GTK_VIEWPORT(GTK_BIN(notebook_page)->child),
663 GTK_SHADOW_NONE);
664 #endif /* SCROLLED_PAGES */
668 for (i=0;i<NUM_PREFS_DATA;i++) {
669 GtkTable *table;
670 GtkWidget *widget;
671 int row;
673 label = gtk_label_new (gettext(prefs_data[i].label_text));
674 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.3);
675 gtk_widget_show (label);
677 table = prefs_tabs[prefs_data[i].tab].table;
678 row = prefs_tabs[prefs_data[i].tab].row++;
679 gtk_table_attach (table, label, 0, 1,
680 row, row + 1,
681 GTK_FILL, GTK_FILL, 1, 1);
683 widget = prefs_get_property_widget(prefs_data[i].type);
684 prefs_data[i].widget = widget;
685 if (widget != NULL) {
686 gtk_table_attach (table, widget, 1, 2,
687 row, row + 1,
688 GTK_EXPAND | GTK_FILL, GTK_FILL, 1, 1);
693 gtk_widget_show (prefs_dialog);
696 static void
697 prefs_update_prefs_from_dialog(void)
699 GtkWidget *widget;
700 int i;
701 char *ptr;
703 for (i=0;i<NUM_PREFS_DATA;i++) {
704 widget = prefs_data[i].widget;
705 ptr = (char *)&prefs + prefs_data[i].offset;
707 prefs_get_value_from_widget(widget, prefs_data[i].type, ptr);
711 static void
712 prefs_update_dialog_from_prefs(void)
714 GtkWidget *widget;
715 int i;
716 char *ptr;
718 for (i=0;i<NUM_PREFS_DATA;i++) {
719 widget = prefs_data[i].widget;
720 ptr = (char *)&prefs + prefs_data[i].offset;
722 prefs_set_value_in_widget(widget, prefs_data[i].type, ptr);