6 * PCB, interactive printed circuit board design
7 * Copyright (C) 1994,1995,1996 Thomas Nau
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 /* This file written by Bill Wilson for the PCB Gtk port.
39 #include "../hidint.h"
53 #ifdef HAVE_LIBDMALLOC
57 extern int MoveLayerAction(int argc
, char **argv
, int x
, int y
);
90 HID_Attribute
*attributes
;
93 gboolean color_is_mapped
;
97 static GList
*config_color_list
, *lib_newlib_list
;
99 static gchar
*lib_newlib_config
, *board_size_override
;
102 static gchar
*color_file
;
104 extern void ghid_set_special_colors (HID_Attribute
* ha
);
107 #define PCB_CONFIG_DIR ".pcb"
108 #define PCB_CONFIG_FILE "preferences"
109 #define PCB_COLORS_DIR "colors"
111 static gchar
*config_dir
, *color_dir
;
113 /* CONFIG_Unused types are expected to be found in main_attribute_list and
114 | will be assigned the type found there. NULL value pointers here are
115 | also expected to be assigned values from the main_attribute_list.
117 /* PinoutFont also not used anymore */
119 static ConfigAttribute config_attributes
[] = {
120 {"gui-compact-horizontal", CONFIG_Boolean
, &_ghidgui
.compact_horizontal
},
121 {"gui-compact-vertical", CONFIG_Boolean
, &_ghidgui
.compact_vertical
},
122 {"gui-title-window", CONFIG_Boolean
, &_ghidgui
.ghid_title_window
},
123 {"use-command-window", CONFIG_Boolean
, &_ghidgui
.use_command_window
},
124 {"save-in-tmp", CONFIG_Unused
, NULL
},
125 {"grid-units-mm", CONFIG_Unused
, NULL
},
127 {"history-size", CONFIG_Integer
, &_ghidgui
.history_size
},
128 {"auto-pan-speed", CONFIG_Integer
, &_ghidgui
.auto_pan_speed
},
129 {"top-window-width", CONFIG_Integer
, &_ghidgui
.top_window_width
},
130 {"top-window-height", CONFIG_Integer
, &_ghidgui
.top_window_height
},
131 {"log-window-width", CONFIG_Integer
, &_ghidgui
.log_window_width
},
132 {"log-window-height", CONFIG_Integer
, &_ghidgui
.log_window_height
},
133 {"library-window-width", CONFIG_Integer
, &_ghidgui
.library_window_width
},
134 {"library-window-height", CONFIG_Integer
, &_ghidgui
.library_window_height
},
135 {"netlist-window-height", CONFIG_Integer
, &_ghidgui
.netlist_window_height
},
136 {"keyref-window-width", CONFIG_Integer
, &_ghidgui
.keyref_window_width
},
137 {"keyref-window-height", CONFIG_Integer
, &_ghidgui
.keyref_window_height
},
138 {"text-scale", CONFIG_Unused
, NULL
},
139 {"via-thickness", CONFIG_Unused
, NULL
},
140 {"via-drilling-hole", CONFIG_Unused
, NULL
},
141 {"backup-interval", CONFIG_Unused
, NULL
},
142 {"line-thickness", CONFIG_Unused
, NULL
},
143 {"rat-thickness", CONFIG_Unused
, NULL
},
144 {"bloat", CONFIG_Unused
, NULL
},
145 {"shrink", CONFIG_Unused
, NULL
},
146 {"min-width", CONFIG_Unused
, NULL
},
147 {"min-silk", CONFIG_Unused
, NULL
},
148 {"min-drill", CONFIG_Unused
, NULL
},
149 {"min-ring", CONFIG_Unused
, NULL
},
150 {"default-PCB-width", CONFIG_Unused
, NULL
},
151 {"default-PCB-height", CONFIG_Unused
, NULL
},
153 {"grid-increment-mil", CONFIG_Unused
, NULL
},
154 {"grid-increment-mm", CONFIG_Unused
, NULL
},
155 {"size-increment-mil", CONFIG_Unused
, NULL
},
156 {"size-increment-mm", CONFIG_Unused
, NULL
},
157 {"line-increment-mil", CONFIG_Unused
, NULL
},
158 {"line-increment-mm", CONFIG_Unused
, NULL
},
159 {"clear-increment-mil", CONFIG_Unused
, NULL
},
160 {"clear-increment-mm", CONFIG_Unused
, NULL
},
162 {"groups", CONFIG_Unused
, NULL
},
163 {"route-styles", CONFIG_Unused
, NULL
},
164 {"library-newlib", CONFIG_String
, &lib_newlib_config
},
165 {"color-file", CONFIG_String
, &color_file
},
166 /* FIXME: construct layer-names- in a list */
167 {"layer-name-1", CONFIG_Unused
, NULL
},
168 {"layer-name-2", CONFIG_Unused
, NULL
},
169 {"layer-name-3", CONFIG_Unused
, NULL
},
170 {"layer-name-4", CONFIG_Unused
, NULL
},
171 {"layer-name-5", CONFIG_Unused
, NULL
},
172 {"layer-name-6", CONFIG_Unused
, NULL
},
173 {"layer-name-7", CONFIG_Unused
, NULL
},
174 {"layer-name-8", CONFIG_Unused
, NULL
},
179 config_file_open (gchar
* mode
)
182 gchar
*homedir
, *fname
;
185 homedir
= (gchar
*) g_get_home_dir ();
188 g_message ("config_file_open: Can't get home directory!");
195 g_build_path (G_DIR_SEPARATOR_S
, homedir
, PCB_CONFIG_DIR
, NULL
);
196 if (!g_file_test (config_dir
, G_FILE_TEST_IS_DIR
)
197 && mkdir (config_dir
, 0755) < 0)
199 g_message ("config_file_open: Can't make \"%s\" directory!",
207 if (!color_dir
) /* Convenient to make the color dir here */
210 g_build_path (G_DIR_SEPARATOR_S
, config_dir
, PCB_COLORS_DIR
, NULL
);
211 if (!g_file_test (color_dir
, G_FILE_TEST_IS_DIR
))
213 if (mkdir (color_dir
, 0755) < 0)
215 g_message ("config_file_open: Can't make \"%s\" directory!",
220 fname
= g_build_path (G_DIR_SEPARATOR_S
,
221 color_dir
, "Default", NULL
);
222 dup_string (&color_file
, fname
);
227 fname
= g_build_path (G_DIR_SEPARATOR_S
, config_dir
, PCB_CONFIG_FILE
, NULL
);
228 f
= fopen (fname
, mode
);
234 static ConfigAttribute
*
235 lookup_config_attribute (gchar
* name
, gboolean if_null_value
)
239 for (ca
= &config_attributes
[0];
240 ca
< &config_attributes
[0] + G_N_ELEMENTS (config_attributes
); ++ca
)
242 if (name
&& (!strcmp (name
, ca
->name
)))
244 if (ca
->value
&& if_null_value
)
253 ghid_config_init (void)
257 ConfigAttribute
*ca
, dummy_attribute
;
261 ghidgui
->n_mode_button_columns
= 3;
262 ghidgui
->small_label_markup
= TRUE
;
263 ghidgui
->auto_pan_on
= TRUE
;
264 ghidgui
->auto_pan_speed
= 3;
265 ghidgui
->history_size
= 5;
266 dup_string (&color_file
, "");
268 for (ha
= hid_attr_nodes
; ha
; ha
= ha
->next
)
270 for (a
= ha
->attributes
; a
< ha
->attributes
+ ha
->n
; ++a
)
274 if ((ca
= lookup_config_attribute (a
->name
, TRUE
)) == NULL
)
275 ca
= &dummy_attribute
;
276 ca
->value
= a
->value
; /* Typically &Setting.xxx */
277 ca
->type
= CONFIG_Unused
;
281 *(char *) a
->value
= a
->default_val
.int_value
;
282 ca
->type
= CONFIG_Boolean
;
285 *(int *) a
->value
= a
->default_val
.int_value
;
286 ca
->type
= CONFIG_Integer
;
289 *(double *) a
->value
= a
->default_val
.real_value
;
290 ca
->type
= CONFIG_Real
;
296 *(char **) a
->value
= g_strdup (a
->default_val
.str_value
);
297 ca
->type
= CONFIG_String
;
299 len
= strlen (a
->name
);
300 if (len
< 7 || strstr (a
->name
, "color") == NULL
)
303 cc
= g_new0 (ConfigColor
, 1);
306 if (!strncmp (a
->name
, "layer-color", 11))
307 cc
->type
= LAYER_COLOR
;
308 else if (!strncmp (a
->name
, "layer-selected-color", 20))
309 cc
->type
= LAYER_SELECTED_COLOR
;
310 else if (!strncmp (a
->name
+ len
- 14, "selected-color", 14))
311 cc
->type
= MISC_SELECTED_COLOR
;
313 cc
->type
= MISC_COLOR
;
315 config_color_list
= g_list_append (config_color_list
, cc
);
319 *(int *) a
->value
= a
->default_val
.int_value
;
334 parse_option_line (gchar
* line
, gchar
** option_result
, gchar
** arg_result
)
336 gchar
*s
, *ss
, option
[64], arg
[512];
340 *option_result
= NULL
;
345 while (*s
== ' ' || *s
== '\t')
347 if (!*s
|| *s
== '\n' || *s
== '#' || *s
== '[')
349 if ((ss
= strchr (s
, '\n')) != NULL
)
352 sscanf (s
, "%63s %511[^\n]", option
, arg
);
354 s
= option
; /* Strip trailing ':' or '=' */
355 while (*s
&& *s
!= ':' && *s
!= '=')
359 s
= arg
; /* Strip leading ':', '=', and whitespace */
360 while (*s
== ' ' || *s
== '\t' || *s
== ':' || *s
== '=' || *s
== '"')
362 if ((ss
= strchr (s
, '"')) != NULL
)
366 *option_result
= g_strdup (option
);
367 if (arg_result
&& *s
)
369 *arg_result
= g_strdup (s
);
376 set_config_attribute (gchar
* option
, gchar
* arg
)
381 gchar locale_point
, *comma_point
, *period_point
;
383 /* Until LC_NUMERIC is totally resolved, check if we need to decimal
384 | point convert. Ultimately, data files will be POSIX and gui
385 | presentation (hence the config file reals) will be in the users locale.
388 locale_point
= *lc
->decimal_point
;
391 if ((ca
= lookup_config_attribute (option
, FALSE
)) == NULL
)
396 *(gchar
*) ca
->value
= (gchar
) atoi (arg
);
400 *(gint
*) ca
->value
= atoi (arg
);
404 /* Hopefully temporary locale decimal point check:
407 comma_point
= strrchr (arg
, ',');
408 period_point
= strrchr (arg
, '.');
409 if (comma_point
&& *comma_point
!= locale_point
)
410 *comma_point
= locale_point
;
411 else if (period_point
&& *period_point
!= locale_point
)
412 *period_point
= locale_point
;
414 *(double *) ca
->value
= atof (arg
);
418 dup_string ((char **) ca
->value
, arg
? arg
: "");
427 config_file_read (void)
430 gchar buf
[512], *option
, *arg
;
432 if ((f
= config_file_open ("r")) == NULL
)
436 while (fgets (buf
, sizeof (buf
), f
))
438 if (parse_option_line (buf
, &option
, &arg
) > 0)
439 set_config_attribute (option
, arg
);
448 config_colors_write (gchar
* path
)
455 if ((f
= fopen (path
, "w")) == NULL
)
457 for (list
= config_color_list
; list
; list
= list
->next
)
459 cc
= (ConfigColor
*) list
->data
;
461 fprintf (f
, "%s =\t%s\n", ha
->name
, *(char **) ha
->value
);
467 config_colors_read (gchar
* path
)
473 gchar
*s
, buf
[512], option
[64], arg
[512];
475 if (!path
|| !*path
|| (f
= fopen (path
, "r")) == NULL
)
478 while (fgets (buf
, sizeof (buf
), f
))
480 sscanf (buf
, "%63s %511[^\n]", option
, arg
);
481 s
= option
; /* Strip trailing ':' or '=' */
482 while (*s
&& *s
!= ':' && *s
!= '=')
485 s
= arg
; /* Strip leading ':', '=', and whitespace */
486 while (*s
== ' ' || *s
== '\t' || *s
== ':' || *s
== '=')
489 for (list
= config_color_list
; list
; list
= list
->next
)
491 cc
= (ConfigColor
*) list
->data
;
493 if (!strcmp (option
, ha
->name
))
495 *(char **) ha
->value
= g_strdup (s
);
496 cc
->color_is_mapped
= FALSE
;
497 ghid_set_special_colors (ha
);
504 ghid_layer_buttons_color_update ();
509 expand_dir (gchar
* dir
)
514 s
= g_build_filename ((gchar
*) g_get_home_dir (), dir
+ 1, NULL
);
521 add_to_paths_list (GList
** list
, gchar
* path_string
)
525 paths
= g_strdup (path_string
);
526 for (p
= strtok (paths
, PCB_PATH_DELIMETER
); p
&& *p
; p
= strtok (NULL
, PCB_PATH_DELIMETER
))
527 *list
= g_list_prepend (*list
, expand_dir (p
));
531 /* Parse command line code borrowed from hid/common/hidinit.c
534 parse_optionv (gint
* argc
, gchar
*** argv
, gboolean from_cmd_line
)
540 gboolean matched
= FALSE
;
542 offset
= from_cmd_line
? 2 : 0;
545 && (((*argv
)[0][0] == '-' && (*argv
)[0][1] == '-')
548 for (ha
= hid_attr_nodes
; ha
; ha
= ha
->next
)
550 for (a
= ha
->attributes
; a
< ha
->attributes
+ ha
->n
; ++a
)
552 if (!a
->name
|| strcmp ((*argv
)[0] + offset
, a
->name
))
560 *(int *) a
->value
= strtol ((*argv
)[1], 0, 0);
562 a
->default_val
.int_value
= strtol ((*argv
)[1], 0, 0);
568 *(double *) a
->value
= strtod ((*argv
)[1], 0);
570 a
->default_val
.real_value
= strtod ((*argv
)[1], 0);
576 *(char **) a
->value
= g_strdup((*argv
)[1]);
578 a
->default_val
.str_value
= g_strdup((*argv
)[1]);
584 *(char *) a
->value
= 1;
586 a
->default_val
.int_value
= 1;
590 a
->default_val
.real_value
= strtod ((*argv
)[1], &ep
);
596 for (e
= 0; a
->enumerations
[e
]; e
++)
597 if (strcmp (a
->enumerations
[e
], (*argv
)[1]) == 0)
600 a
->default_val
.int_value
= e
;
601 a
->default_val
.str_value
= ep
;
607 "ERROR: \"%s\" is an unknown value for the --%s option\n",
608 (*argv
)[1], a
->name
);
616 a
->default_val
.str_value
= (*argv
)[1];
626 if (a
< ha
->attributes
+ ha
->n
)
633 fprintf (stderr
, "unrecognized option: %s\n", (*argv
)[0]);
637 // ghid_log("unrecognized option: %s\n", (*argv)[0]);
638 fprintf (stderr
, "unrecognized option: %s\n", (*argv
)[0]);
647 load_rc_file (gchar
* path
)
650 gchar buf
[1024], *av
[2], **argv
;
653 f
= fopen (path
, "r");
657 if (Settings
.verbose
)
658 printf ("Loading pcbrc file: %s\n", path
);
659 while (fgets (buf
, sizeof (buf
), f
))
662 if ((argc
= parse_option_line (buf
, &av
[0], &av
[1])) > 0)
663 parse_optionv (&argc
, &argv
, FALSE
);
675 load_rc_file ("/etc/pcbrc");
676 load_rc_file ("/usr/local/etc/pcbrc");
678 path
= g_build_filename (pcblibdir
, "pcbrc", NULL
);
682 path
= g_build_filename ((gchar
*) g_get_home_dir (), ".pcb/pcbrc", NULL
);
686 load_rc_file ("pcbrc");
691 ghid_config_files_read (gint
* argc
, gchar
*** argv
)
702 config_colors_read (color_file
);
705 parse_optionv (argc
, argv
, TRUE
);
707 if (board_size_override
708 && sscanf (board_size_override
, "%dx%d", &width
, &height
) == 2)
710 Settings
.MaxWidth
= TO_PCB_UNITS (width
);
711 Settings
.MaxHeight
= TO_PCB_UNITS (height
);
714 if (lib_newlib_config
&& *lib_newlib_config
)
715 add_to_paths_list (&lib_newlib_list
, lib_newlib_config
);
717 for (list
= lib_newlib_list
; list
; list
= list
->next
)
719 str
= Settings
.LibraryTree
;
720 dir
= expand_dir ((gchar
*) list
->data
);
721 Settings
.LibraryTree
= g_strconcat (str
, PCB_PATH_DELIMETER
, dir
, NULL
);
728 ghid_config_files_write (void)
733 if (!ghidgui
->config_modified
|| (f
= config_file_open ("w")) == NULL
)
736 fprintf (f
, "### PCB configuration file. ###\n");
738 for (ca
= &config_attributes
[0];
739 ca
< &config_attributes
[0] + G_N_ELEMENTS (config_attributes
); ++ca
)
744 fprintf (f
, "%s = %d\n", ca
->name
, (gint
) * (gchar
*) ca
->value
);
748 fprintf (f
, "%s = %d\n", ca
->name
, *(gint
*) ca
->value
);
752 fprintf (f
, "%s = %f\n", ca
->name
, *(double *) ca
->value
);
756 if (*(char **) ca
->value
== NULL
)
757 fprintf (f
, "# %s = NULL\n", ca
->name
);
759 fprintf (f
, "%s = %s\n", ca
->name
, *(char **) ca
->value
);
767 ghidgui
->config_modified
= FALSE
;
770 /* =================== OK, now the gui stuff ======================
772 static GtkWidget
*config_window
;
774 /* -------------- The General config page ----------------
778 config_command_window_toggle_cb (GtkToggleButton
* button
, gpointer data
)
780 gboolean active
= gtk_toggle_button_get_active (button
);
781 static gboolean holdoff
;
786 /* Can't toggle into command window mode if the status line command
789 if (ghidgui
->command_entry_status_line_active
)
792 gtk_toggle_button_set_active (button
, FALSE
);
796 ghidgui
->use_command_window
= active
;
797 ghid_command_use_command_window_sync ();
802 config_compact_horizontal_toggle_cb (GtkToggleButton
* button
, gpointer data
)
804 gboolean active
= gtk_toggle_button_get_active (button
);
806 ghidgui
->compact_horizontal
= active
;
809 gtk_container_remove (GTK_CONTAINER (ghidgui
->compact_hbox
),
810 ghidgui
->position_hbox
);
811 gtk_box_pack_end (GTK_BOX (ghidgui
->compact_vbox
),
812 ghidgui
->position_hbox
, TRUE
, FALSE
, 0);
816 gtk_container_remove (GTK_CONTAINER (ghidgui
->compact_vbox
),
817 ghidgui
->position_hbox
);
818 gtk_box_pack_end(GTK_BOX(ghidgui
->compact_hbox
), ghidgui
->position_hbox
,
821 ghid_set_status_line_label ();
822 ghidgui
->config_modified
= TRUE
;
826 config_compact_vertical_toggle_cb (GtkToggleButton
* button
, gpointer data
)
828 gboolean active
= gtk_toggle_button_get_active (button
);
830 ghidgui
->compact_vertical
= active
;
831 ghid_pack_mode_buttons();
832 ghidgui
->config_modified
= TRUE
;
836 config_title_window_cb (GtkToggleButton
* button
, gpointer data
)
838 gboolean active
= gtk_toggle_button_get_active (button
);
840 ghidgui
->ghid_title_window
= active
;
841 ghid_window_set_name_label (ghidgui
->name_label_string
);
842 ghidgui
->config_modified
= TRUE
;
846 config_general_toggle_cb (GtkToggleButton
* button
, gint
* setting
)
848 *setting
= gtk_toggle_button_get_active (button
);
849 ghidgui
->config_modified
= TRUE
;
853 config_backup_spin_button_cb (GtkSpinButton
* spin_button
, gpointer data
)
855 Settings
.BackupInterval
= gtk_spin_button_get_value_as_int (spin_button
);
857 ghidgui
->config_modified
= TRUE
;
861 config_history_spin_button_cb (GtkSpinButton
* spin_button
, gpointer data
)
863 ghidgui
->history_size
= gtk_spin_button_get_value_as_int (spin_button
);
864 ghidgui
->config_modified
= TRUE
;
868 config_auto_pan_speed_spin_button_cb (GtkSpinButton
* spin_button
,
871 ghidgui
->auto_pan_speed
= gtk_spin_button_get_value_as_int (spin_button
);
872 ghidgui
->config_modified
= TRUE
;
876 config_general_tab_create (GtkWidget
* tab_vbox
)
880 gtk_container_set_border_width (GTK_CONTAINER (tab_vbox
), 6);
882 vbox
= ghid_category_vbox (tab_vbox
, _("Enables"), 4, 2, TRUE
, TRUE
);
884 ghid_check_button_connected (vbox
, NULL
, ghidgui
->use_command_window
,
885 TRUE
, FALSE
, FALSE
, 2,
886 config_command_window_toggle_cb
, NULL
,
887 _("Use separate window for command entry"));
889 ghid_check_button_connected (vbox
, NULL
, ghidgui
->compact_horizontal
,
890 TRUE
, FALSE
, FALSE
, 2,
891 config_compact_horizontal_toggle_cb
, NULL
,
892 _("Alternate window layout to allow smaller horizontal size"));
894 ghid_check_button_connected (vbox
, NULL
, ghidgui
->compact_vertical
,
895 TRUE
, FALSE
, FALSE
, 2,
896 config_compact_vertical_toggle_cb
, NULL
,
897 _("Alternate window layout to allow smaller vertical size"));
899 ghid_check_button_connected (vbox
, NULL
, ghidgui
->ghid_title_window
,
900 TRUE
, FALSE
, FALSE
, 2,
901 config_title_window_cb
, NULL
,
902 _("Put layout name on the window title bar"));
904 vbox
= ghid_category_vbox (tab_vbox
, _("Backups"), 4, 2, TRUE
, TRUE
);
905 ghid_check_button_connected (vbox
, NULL
, Settings
.SaveInTMP
,
906 TRUE
, FALSE
, FALSE
, 2,
907 config_general_toggle_cb
, &Settings
.SaveInTMP
,
908 _("If layout is modified at exit, save into PCB.%i.save"));
909 ghid_spin_button (vbox
, NULL
, Settings
.BackupInterval
, 0.0, 60 * 60, 60.0,
910 600.0, 0, 0, config_backup_spin_button_cb
, NULL
, FALSE
,
911 _("Seconds between auto backups\n"
912 "(set to zero to disable auto backups)"));
914 vbox
= ghid_category_vbox (tab_vbox
, _("Misc"), 4, 2, TRUE
, TRUE
);
915 ghid_spin_button (vbox
, NULL
, ghidgui
->history_size
,
916 5.0, 25.0, 1.0, 1.0, 0, 0,
917 config_history_spin_button_cb
, NULL
, FALSE
,
918 _("Number of commands to remember in the history list"));
919 ghid_spin_button (vbox
, NULL
, ghidgui
->auto_pan_speed
,
920 1.0, 10.0, 1.0, 1.0, 0, 0,
921 config_auto_pan_speed_spin_button_cb
, NULL
, FALSE
,
922 _("Auto pan speed"));
927 config_general_apply (void)
929 /* save the settings */
930 ghid_config_files_write ();
934 /* -------------- The Sizes config page ----------------
936 #define STEP0_SMALL_SIZE (Settings.grid_units_mm ? 0.005 : 0.1)
937 #define STEP1_SMALL_SIZE (Settings.grid_units_mm ? 0.05 : 1.0)
938 #define STEP0_SIZE (Settings.grid_units_mm ? 5.0 : 100)
939 #define STEP1_SIZE (Settings.grid_units_mm ? 25.0 : 1000)
940 #define SPIN_DIGITS (Settings.grid_units_mm ? 3 : 1)
942 static GtkWidget
*config_sizes_vbox
,
943 *config_sizes_tab_vbox
, *config_text_spin_button
;
945 static GtkWidget
*use_board_size_default_button
,
946 *use_drc_sizes_default_button
;
948 static gint new_board_width
, new_board_height
;
951 config_sizes_apply (void)
956 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
957 (use_board_size_default_button
));
960 Settings
.MaxWidth
= new_board_width
;
961 Settings
.MaxHeight
= new_board_height
;
962 ghidgui
->config_modified
= TRUE
;
966 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
967 (use_drc_sizes_default_button
));
970 Settings
.Bloat
= PCB
->Bloat
;
971 Settings
.Shrink
= PCB
->Shrink
;
972 Settings
.minWid
= PCB
->minWid
;
973 Settings
.minSlk
= PCB
->minSlk
;
974 Settings
.IsleArea
= PCB
->IsleArea
;
975 Settings
.minDrill
= PCB
->minDrill
;
976 Settings
.minRing
= PCB
->minRing
;
977 ghidgui
->config_modified
= TRUE
;
980 if (PCB
->MaxWidth
!= new_board_width
|| PCB
->MaxHeight
!= new_board_height
)
981 ChangePCBSize (new_board_width
, new_board_height
);
985 text_spin_button_cb (GtkSpinButton
* spin
, gint
* dst
)
987 *dst
= gtk_spin_button_get_value_as_int (spin
);
988 ghidgui
->config_modified
= TRUE
;
989 ghid_set_status_line_label ();
994 size_spin_button_cb (GtkSpinButton
* spin
, gint
* dst
)
998 value
= gtk_spin_button_get_value (spin
);
999 *dst
= TO_PCB_UNITS (value
);
1000 ghidgui
->config_modified
= TRUE
;
1004 config_sizes_tab_create (GtkWidget
* tab_vbox
)
1006 GtkWidget
*table
, *vbox
, *hbox
, *label
;
1009 /* Need a vbox we can destroy if user changes grid units.
1011 if (!config_sizes_vbox
)
1013 vbox
= gtk_vbox_new (FALSE
, 0);
1014 gtk_box_pack_start (GTK_BOX (tab_vbox
), vbox
, FALSE
, FALSE
, 0);
1015 gtk_container_set_border_width (GTK_CONTAINER (vbox
), 6);
1016 config_sizes_vbox
= vbox
;
1017 config_sizes_tab_vbox
= tab_vbox
;
1020 str
= g_strdup_printf (_("<b>%s</b> grid units are selected"),
1021 Settings
.grid_units_mm
? "mm" : "mil");
1022 label
= gtk_label_new ("");
1023 gtk_label_set_use_markup (GTK_LABEL (label
), TRUE
);
1024 gtk_label_set_markup (GTK_LABEL (label
), str
);
1027 gtk_box_pack_start (GTK_BOX (config_sizes_vbox
), label
, FALSE
, FALSE
, 4);
1030 /* ---- Board Size ---- */
1031 vbox
= ghid_category_vbox (config_sizes_vbox
, _("Board Size"),
1033 hbox
= gtk_hbox_new (FALSE
, 0);
1034 gtk_box_pack_start (GTK_BOX (vbox
), hbox
, FALSE
, FALSE
, 0);
1035 table
= gtk_table_new (2, 2, FALSE
);
1036 gtk_box_pack_start (GTK_BOX (hbox
), table
, FALSE
, FALSE
, 0);
1037 gtk_table_set_col_spacings (GTK_TABLE (table
), 6);
1038 gtk_table_set_row_spacings (GTK_TABLE (table
), 3);
1040 new_board_width
= PCB
->MaxWidth
;
1041 new_board_height
= PCB
->MaxHeight
;
1042 ghid_table_spin_button (table
, 0, 0, NULL
,
1043 FROM_PCB_UNITS (PCB
->MaxWidth
),
1044 FROM_PCB_UNITS (MIN_SIZE
),
1045 FROM_PCB_UNITS (MAX_COORD
), STEP0_SIZE
, STEP1_SIZE
,
1046 SPIN_DIGITS
, 0, size_spin_button_cb
,
1047 &new_board_width
, FALSE
, _("Width"));
1049 ghid_table_spin_button (table
, 1, 0, NULL
,
1050 FROM_PCB_UNITS (PCB
->MaxHeight
),
1051 FROM_PCB_UNITS (MIN_SIZE
),
1052 FROM_PCB_UNITS (MAX_COORD
), STEP0_SIZE
, STEP1_SIZE
,
1053 SPIN_DIGITS
, 0, size_spin_button_cb
,
1054 &new_board_height
, FALSE
, _("Height"));
1055 ghid_check_button_connected (vbox
, &use_board_size_default_button
, FALSE
,
1056 TRUE
, FALSE
, FALSE
, 0, NULL
, NULL
,
1058 ("Use this board size as the default for new layouts"));
1060 /* ---- Text Scale ---- */
1061 vbox
= ghid_category_vbox (config_sizes_vbox
, _("Text Scale"),
1063 hbox
= gtk_hbox_new (FALSE
, 0);
1064 gtk_box_pack_start (GTK_BOX (vbox
), hbox
, FALSE
, FALSE
, 0);
1065 table
= gtk_table_new (4, 2, FALSE
);
1066 gtk_box_pack_start (GTK_BOX (hbox
), table
, FALSE
, FALSE
, 0);
1067 gtk_table_set_col_spacings (GTK_TABLE (table
), 6);
1068 gtk_table_set_row_spacings (GTK_TABLE (table
), 3);
1070 ghid_table_spin_button (table
, 0, 0, &config_text_spin_button
,
1072 MIN_TEXTSCALE
, MAX_TEXTSCALE
,
1074 0, 0, text_spin_button_cb
,
1075 &Settings
.TextScale
, FALSE
, "%");
1078 /* ---- DRC Sizes ---- */
1079 vbox
= ghid_category_vbox (config_sizes_vbox
, _("Design Rule Checking"),
1081 hbox
= gtk_hbox_new (FALSE
, 0);
1082 gtk_box_pack_start (GTK_BOX (vbox
), hbox
, FALSE
, FALSE
, 0);
1083 table
= gtk_table_new (4, 2, FALSE
);
1084 gtk_box_pack_start (GTK_BOX (hbox
), table
, FALSE
, FALSE
, 0);
1085 gtk_table_set_col_spacings (GTK_TABLE (table
), 6);
1086 gtk_table_set_row_spacings (GTK_TABLE (table
), 3);
1088 ghid_table_spin_button (table
, 0, 0, NULL
,
1089 FROM_PCB_UNITS (PCB
->Bloat
),
1090 FROM_PCB_UNITS (MIN_DRC_VALUE
),
1091 FROM_PCB_UNITS (MAX_DRC_VALUE
), STEP0_SMALL_SIZE
,
1092 STEP1_SMALL_SIZE
, SPIN_DIGITS
, 0,
1093 size_spin_button_cb
, &PCB
->Bloat
, FALSE
,
1094 _("Minimum copper spacing"));
1096 ghid_table_spin_button (table
, 1, 0, NULL
,
1097 FROM_PCB_UNITS (PCB
->minWid
),
1098 FROM_PCB_UNITS (MIN_DRC_VALUE
),
1099 FROM_PCB_UNITS (MAX_DRC_VALUE
), STEP0_SMALL_SIZE
,
1100 STEP1_SMALL_SIZE
, SPIN_DIGITS
, 0,
1101 size_spin_button_cb
, &PCB
->minWid
, FALSE
,
1102 _("Minimum copper width"));
1104 ghid_table_spin_button (table
, 2, 0, NULL
,
1105 FROM_PCB_UNITS (PCB
->Shrink
),
1106 FROM_PCB_UNITS (MIN_DRC_VALUE
),
1107 FROM_PCB_UNITS (MAX_DRC_VALUE
), STEP0_SMALL_SIZE
,
1108 STEP1_SMALL_SIZE
, SPIN_DIGITS
, 0,
1109 size_spin_button_cb
, &PCB
->Shrink
, FALSE
,
1110 _("Minimum touching copper overlap"));
1112 ghid_table_spin_button (table
, 3, 0, NULL
,
1113 FROM_PCB_UNITS (PCB
->minSlk
),
1114 FROM_PCB_UNITS (MIN_DRC_SILK
),
1115 FROM_PCB_UNITS (MAX_DRC_SILK
), STEP0_SMALL_SIZE
,
1116 STEP1_SMALL_SIZE
, SPIN_DIGITS
, 0,
1117 size_spin_button_cb
, &PCB
->minSlk
, FALSE
,
1118 _("Minimum silk width"));
1120 ghid_table_spin_button (table
, 4, 0, NULL
,
1121 FROM_PCB_UNITS (PCB
->minDrill
),
1122 FROM_PCB_UNITS (MIN_DRC_DRILL
),
1123 FROM_PCB_UNITS (MAX_DRC_DRILL
), STEP0_SMALL_SIZE
,
1124 STEP1_SMALL_SIZE
, SPIN_DIGITS
, 0,
1125 size_spin_button_cb
, &PCB
->minDrill
, FALSE
,
1126 _("Minimum drill diameter"));
1128 ghid_table_spin_button (table
, 5, 0, NULL
,
1129 FROM_PCB_UNITS (PCB
->minRing
),
1130 FROM_PCB_UNITS (MIN_DRC_RING
),
1131 FROM_PCB_UNITS (MAX_DRC_RING
), STEP0_SMALL_SIZE
,
1132 STEP1_SMALL_SIZE
, SPIN_DIGITS
, 0,
1133 size_spin_button_cb
, &PCB
->minRing
, FALSE
,
1134 _("Minimum annular ring"));
1136 ghid_check_button_connected (vbox
, &use_drc_sizes_default_button
, FALSE
,
1137 TRUE
, FALSE
, FALSE
, 0, NULL
, NULL
,
1139 ("Use DRC values as the default for new layouts"));
1141 gtk_widget_show_all (config_sizes_vbox
);
1145 /* -------------- The Increments config page ----------------
1147 /* Increment/decrement values are kept in mil and mm units and not in
1150 static GtkWidget
*config_increments_vbox
, *config_increments_tab_vbox
;
1153 increment_spin_button_cb (GtkSpinButton
* spin
, gdouble
* dst
)
1157 value
= gtk_spin_button_get_value (spin
);
1158 *dst
= value
; /* Not using PCB units */
1161 ghidgui
->config_modified
= TRUE
;
1165 config_increments_tab_create (GtkWidget
* tab_vbox
)
1167 GtkWidget
*vbox
, *label
;
1171 /* Need a vbox we can destroy if user changes grid units.
1173 if (!config_increments_vbox
)
1175 vbox
= gtk_vbox_new (FALSE
, 0);
1176 gtk_box_pack_start (GTK_BOX (tab_vbox
), vbox
, FALSE
, FALSE
, 0);
1177 gtk_container_set_border_width (GTK_CONTAINER (vbox
), 6);
1178 config_increments_vbox
= vbox
;
1179 config_increments_tab_vbox
= tab_vbox
;
1184 ("Increment/Decrement values to use in <b>%s</b> units mode.\n"),
1185 Settings
.grid_units_mm
? "mm" : "mil");
1186 label
= gtk_label_new ("");
1187 gtk_label_set_use_markup (GTK_LABEL (label
), TRUE
);
1188 gtk_label_set_markup (GTK_LABEL (label
), str
);
1189 gtk_box_pack_start (GTK_BOX (config_increments_vbox
), label
,
1194 /* ---- Grid Increment/Decrement ---- */
1195 vbox
= ghid_category_vbox (config_increments_vbox
,
1196 _("Grid Increment/Decrement"), 4, 2, TRUE
, TRUE
);
1198 /* Grid increment spin button ('g' and '<shift>g'). For mil
1199 | units, range from 1.0 to 25.0. For mm, range from 0.01 to 1.0
1200 | Step sizes of 5 mil or .05 mm, and .01 mm precision or 1 mil precision.
1202 target
= Settings
.grid_units_mm
?
1203 &Settings
.grid_increment_mm
: &Settings
.grid_increment_mil
;
1204 ghid_spin_button (vbox
, NULL
,
1205 GRID_UNITS_VALUE (Settings
.grid_increment_mm
,
1206 Settings
.grid_increment_mil
),
1207 GRID_UNITS_VALUE (0.01, 1.0), GRID_UNITS_VALUE (1.0,
1209 GRID_UNITS_VALUE (0.05, 5.0), GRID_UNITS_VALUE (0.05,
1211 GRID_UNITS_VALUE (2, 0), 0, increment_spin_button_cb
,
1213 _("For 'g' and '<shift>g' grid change actions"));
1216 /* ---- Size Increment/Decrement ---- */
1217 vbox
= ghid_category_vbox (config_increments_vbox
,
1218 _("Size Increment/Decrement"), 4, 2, TRUE
, TRUE
);
1220 /* Size increment spin button ('s' and '<shift>s'). For mil
1221 | units, range from 1.0 to 10.0. For mm, range from 0.01 to 0.5
1222 | Step sizes of 1 mil or .01 mm, and .01 mm precision or 1 mil precision.
1224 target
= Settings
.grid_units_mm
?
1225 &Settings
.size_increment_mm
: &Settings
.size_increment_mil
;
1226 ghid_spin_button (vbox
, NULL
,
1227 GRID_UNITS_VALUE (Settings
.size_increment_mm
,
1228 Settings
.size_increment_mil
),
1229 GRID_UNITS_VALUE (0.01, 1.0), GRID_UNITS_VALUE (0.5,
1231 GRID_UNITS_VALUE (0.01, 1.0), GRID_UNITS_VALUE (0.05,
1233 GRID_UNITS_VALUE (2, 0), 0, increment_spin_button_cb
,
1235 _("For 's' and '<shift>s' size change actions on lines,\n"
1236 "pads, pins and text.\n"
1237 "Use '<ctrl>s' and '<shift><ctrl>s' for drill holes."));
1239 /* ---- Line Increment/Decrement ---- */
1240 vbox
= ghid_category_vbox (config_increments_vbox
,
1241 _("Line Increment/Decrement"), 4, 2, TRUE
, TRUE
);
1243 /* Line increment spin button ('l' and '<shift>l'). For mil
1244 | units, range from 0.5 to 10.0. For mm, range from 0.005 to 0.5
1245 | Step sizes of 0.5 mil or .005 mm, and .001 mm precision or 0.1 mil
1248 target
= Settings
.grid_units_mm
?
1249 &Settings
.line_increment_mm
: &Settings
.line_increment_mil
;
1250 ghid_spin_button (vbox
, NULL
,
1251 GRID_UNITS_VALUE (Settings
.line_increment_mm
,
1252 Settings
.line_increment_mil
),
1253 GRID_UNITS_VALUE (0.005, 0.5), GRID_UNITS_VALUE (0.5,
1255 GRID_UNITS_VALUE (0.005, 0.5), GRID_UNITS_VALUE (0.05,
1257 GRID_UNITS_VALUE (3, 1), 0, increment_spin_button_cb
,
1260 ("For 'l' and '<shift>l' routing line width change actions"));
1262 /* ---- Clear Increment/Decrement ---- */
1263 vbox
= ghid_category_vbox (config_increments_vbox
,
1264 _("Clear Increment/Decrement"), 4, 2, TRUE
,
1267 /* Clear increment spin button ('l' and '<shift>l'). For mil
1268 | units, range from 0.5 to 10.0. For mm, range from 0.005 to 0.5
1269 | Step sizes of 0.5 mil or .005 mm, and .001 mm precision or 0.1 mil
1272 target
= Settings
.grid_units_mm
?
1273 &Settings
.clear_increment_mm
: &Settings
.clear_increment_mil
;
1274 ghid_spin_button (vbox
, NULL
,
1275 GRID_UNITS_VALUE (Settings
.clear_increment_mm
,
1276 Settings
.clear_increment_mil
),
1277 GRID_UNITS_VALUE (0.005, 0.5), GRID_UNITS_VALUE (0.5,
1279 GRID_UNITS_VALUE (0.005, 0.5), GRID_UNITS_VALUE (0.05,
1281 GRID_UNITS_VALUE (3, 1), 0, increment_spin_button_cb
,
1284 ("For 'k' and '<shift>k' line clearance inside polygon size\n"
1288 gtk_widget_show_all (config_increments_vbox
);
1291 /* -------------- The Library config page ----------------
1293 static GtkWidget
*library_newlib_entry
;
1296 config_library_apply (void)
1299 (&lib_newlib_config
, ghid_entry_get_text (library_newlib_entry
)))
1300 ghidgui
->config_modified
= TRUE
;
1304 config_library_tab_create (GtkWidget
* tab_vbox
)
1306 GtkWidget
*vbox
, *label
, *entry
;
1308 gtk_container_set_border_width (GTK_CONTAINER (tab_vbox
), 6);
1309 vbox
= ghid_category_vbox (tab_vbox
, _("Element Directories"),
1311 label
= gtk_label_new ("");
1312 gtk_label_set_use_markup (GTK_LABEL (label
), TRUE
);
1313 gtk_label_set_markup (GTK_LABEL (label
),
1315 ("<small>Enter a \""
1317 "\" separated list of custom top level\n"
1318 "element directories. For example:\n"
1319 "\t<b>~/gaf/pcb-elements"
1323 "/usr/local/pcb-elements</b>\n"
1324 "Elements should be organized into subdirectories below each\n"
1325 "top level directory. Restart program for changes to take effect."
1328 gtk_box_pack_start (GTK_BOX (vbox
), label
, FALSE
, FALSE
, 0);
1329 entry
= gtk_entry_new ();
1330 library_newlib_entry
= entry
;
1331 gtk_entry_set_text (GTK_ENTRY (entry
), lib_newlib_config
);
1332 gtk_box_pack_start (GTK_BOX (vbox
), entry
, FALSE
, FALSE
, 4);
1336 /* -------------- The Layers Group config page ----------------
1338 static GtkWidget
*config_groups_table
, *config_groups_vbox
, *config_groups_window
;
1340 static GtkWidget
*layer_entry
[MAX_LAYER
];
1341 static GtkWidget
*group_button
[MAX_LAYER
+ 2][MAX_LAYER
];
1344 static GtkWidget
*use_layer_default_button
;
1347 static gint config_layer_group
[MAX_LAYER
+ 2];
1349 static LayerGroupType layer_groups
, /* Working copy */
1350 *lg_monitor
; /* Keep track if our working copy */
1351 /* needs to be changed (new layout) */
1353 static gboolean groups_modified
, groups_holdoff
, layers_applying
;
1355 static gchar
*layer_info_text
[] = {
1356 N_("<h>Layer Names\n"),
1357 N_("You may enter layer names for the layers drawn on the screen.\n"
1358 "The special 'component side' and 'solder side' are layers which\n"
1359 "will be printed out, so they must have in their group at least one\n"
1360 "of the other layers that are drawn on the screen.\n"),
1362 N_("<h>Layer Groups\n"),
1363 N_("Each layer on the screen may be in its own group which allows the\n"
1364 "maximum number of board layers. However, for boards with fewer\n"
1365 "layers, you may group layers together which will then print as a\n"
1366 "single layer on a printout. This allows a visual color distinction\n"
1367 "to be displayed on the screen for signal groups which will print as\n"
1368 "a single layer\n"),
1370 N_("For example, for a 4 layer board a useful layer group arrangement\n"
1371 "can be to have 3 screen displayed layers grouped into the same group\n"
1372 "as the 'component side' and 'solder side' printout layers. Then\n"
1373 "groups such as signals, ground, and supply traces can be color\n"
1374 "coded on the screen while printing as a single layer. For this\n"
1375 "you would select buttons and enter names on the Setup page to\n"
1376 "structure four layer groups similar to this:\n"),
1392 N_("GND-component"),
1394 N_("Vcc-component"),
1396 N_("component side"),
1409 config_layer_groups_radio_button_cb (GtkToggleButton
* button
, gpointer data
)
1411 gint layer
= GPOINTER_TO_INT (data
) >> 8;
1412 gint group
= GPOINTER_TO_INT (data
) & 0xff;
1414 if (!gtk_toggle_button_get_active (button
) || groups_holdoff
)
1416 config_layer_group
[layer
] = group
;
1417 groups_modified
= TRUE
;
1418 ghidgui
->config_modified
= TRUE
;
1421 /* Construct a layer group string. Follow logic in WritePCBDataHeader(),
1422 | but use g_string functions.
1425 make_layer_group_string (LayerGroupType
* lg
)
1428 gint group
, entry
, layer
;
1430 string
= g_string_new ("");
1432 for (group
= 0; group
< max_layer
; group
++)
1434 if (lg
->Number
[group
] == 0)
1436 for (entry
= 0; entry
< lg
->Number
[group
]; entry
++)
1438 layer
= lg
->Entries
[group
][entry
];
1439 if (layer
== max_layer
+ COMPONENT_LAYER
)
1440 string
= g_string_append (string
, "c");
1441 else if (layer
== max_layer
+ SOLDER_LAYER
)
1442 string
= g_string_append (string
, "s");
1444 g_string_append_printf (string
, "%d", layer
+ 1);
1446 if (entry
!= lg
->Number
[group
] - 1)
1447 string
= g_string_append (string
, ",");
1449 if (group
!= max_layer
- 1)
1450 string
= g_string_append (string
, ":");
1452 return g_string_free (string
, FALSE
); /* Don't free string->str */
1456 config_layers_apply (void)
1461 gint componentgroup
= 0, soldergroup
= 0;
1462 gboolean use_as_default
= FALSE
, layers_modified
= FALSE
;
1466 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
1467 (use_layer_default_button
));
1470 /* Get each layer name entry and dup if modified into the PCB layer names
1471 | and, if to use as default, the Settings layer names.
1473 for (i
= 0; i
< max_layer
; ++i
)
1475 layer
= &PCB
->Data
->Layer
[i
];
1476 s
= ghid_entry_get_text (layer_entry
[i
]);
1477 if (dup_string (&layer
->Name
, s
))
1478 layers_modified
= TRUE
;
1480 if (use_as_default
&& dup_string (&Settings
.DefaultLayerName
[i
], s
))
1481 ghidgui
->config_modified
= TRUE
;
1484 /* Layer names can be changed from the menus and that can update the
1485 | config. So holdoff the loop.
1487 layers_applying
= TRUE
;
1488 if (layers_modified
)
1489 ghid_layer_buttons_update ();
1490 layers_applying
= FALSE
;
1492 if (groups_modified
) /* If any group radio buttons were toggled. */
1494 /* clear all entries and read layer by layer
1496 for (group
= 0; group
< max_layer
; group
++)
1497 layer_groups
.Number
[group
] = 0;
1499 for (i
= 0; i
< max_layer
+ 2; i
++)
1501 group
= config_layer_group
[i
] - 1;
1502 layer_groups
.Entries
[group
][layer_groups
.Number
[group
]++] = i
;
1504 if (i
== max_layer
+ COMPONENT_LAYER
)
1505 componentgroup
= group
;
1506 else if (i
== max_layer
+ SOLDER_LAYER
)
1507 soldergroup
= group
;
1510 /* do some cross-checking
1511 | solder-side and component-side must be in different groups
1512 | solder-side and component-side must not be the only one in the group
1514 if (layer_groups
.Number
[soldergroup
] <= 1
1515 || layer_groups
.Number
[componentgroup
] <= 1)
1518 ("Both 'solder side' or 'component side' layers must have at least\n"
1519 "\tone other layer in their group.\n"));
1522 else if (soldergroup
== componentgroup
)
1525 ("The 'solder side' and 'component side' layers are not allowed\n"
1526 "\tto be in the same layer group #\n"));
1529 PCB
->LayerGroups
= layer_groups
;
1530 ghid_invalidate_all();
1531 groups_modified
= FALSE
;
1535 s
= make_layer_group_string (&PCB
->LayerGroups
);
1536 if (dup_string (&Settings
.Groups
, s
))
1538 ParseGroupString (Settings
.Groups
, &Settings
.LayerGroups
, max_layer
);
1539 ghidgui
->config_modified
= TRUE
;
1546 config_layer_group_button_state_update (void)
1550 /* Set button active corresponding to layer group state.
1552 groups_holdoff
= TRUE
;
1553 for (g
= 0; g
< max_layer
; g
++)
1554 for (i
= 0; i
< layer_groups
.Number
[g
]; i
++)
1556 /* printf("layer %d in group %d\n", layer_groups.Entries[g][i], g +1); */
1557 config_layer_group
[layer_groups
.Entries
[g
][i
]] = g
+ 1;
1558 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
1560 [layer_groups
.Entries
[g
][i
]][g
]),
1563 groups_holdoff
= FALSE
;
1567 layer_name_entry_cb(GtkWidget
*entry
, gpointer data
)
1569 gint i
= GPOINTER_TO_INT(data
);
1573 layer
= &PCB
->Data
->Layer
[i
];
1574 name
= ghid_entry_get_text(entry
);
1575 if (dup_string (&layer
->Name
, name
))
1576 ghid_layer_buttons_update();
1580 ghid_config_groups_changed(void)
1582 GtkWidget
*vbox
, *table
, *button
, *label
, *scrolled_window
;
1584 gchar buf
[32], *name
;
1587 if (!config_groups_vbox
)
1589 vbox
= config_groups_vbox
;
1591 if (config_groups_table
)
1592 gtk_widget_destroy(config_groups_table
);
1593 if (config_groups_window
)
1594 gtk_widget_destroy(config_groups_window
);
1596 config_groups_window
= scrolled_window
=
1597 gtk_scrolled_window_new (NULL
, NULL
);
1598 gtk_widget_set_size_request (scrolled_window
, 34, 408);
1599 gtk_container_set_border_width (GTK_CONTAINER (scrolled_window
), 3);
1600 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window
),
1601 GTK_POLICY_AUTOMATIC
, GTK_POLICY_ALWAYS
);
1602 gtk_box_pack_start (GTK_BOX (vbox
), scrolled_window
, TRUE
, TRUE
, 0);
1603 gtk_widget_show (scrolled_window
);
1606 table
= gtk_table_new (max_layer
+ 3, max_layer
+ 1, FALSE
);
1607 config_groups_table
= table
;
1608 gtk_table_set_row_spacings (GTK_TABLE (table
), 3);
1609 gtk_scrolled_window_add_with_viewport (
1610 GTK_SCROLLED_WINDOW (scrolled_window
), table
);
1611 gtk_widget_show (table
);
1613 layer_groups
= PCB
->LayerGroups
; /* working copy */
1614 lg_monitor
= &PCB
->LayerGroups
; /* So can know if PCB changes on us */
1616 label
= gtk_label_new (_("Group #"));
1617 gtk_table_attach_defaults (GTK_TABLE (table
), label
, 0, 1, 0, 1);
1618 gtk_misc_set_alignment (GTK_MISC (label
), 1.0, 0.5);
1620 for (i
= 1; i
< max_layer
+ 1; ++i
)
1623 snprintf (buf
, sizeof (buf
), " %d", i
);
1625 snprintf (buf
, sizeof (buf
), "%d", i
);
1626 label
= gtk_label_new (buf
);
1627 gtk_table_attach_defaults (GTK_TABLE (table
), label
, i
, i
+ 1, 0, 1);
1630 /* Create a row of radio toggle buttons for layer. So each layer
1631 | can have an active radio button set for the group it needs to be in.
1633 for (layer
= 0; layer
< max_layer
+ 2; ++layer
)
1635 if (layer
== max_layer
+ COMPONENT_LAYER
)
1636 name
= _("component side");
1637 else if (layer
== max_layer
+ SOLDER_LAYER
)
1638 name
= _("solder side");
1640 name
= UNKNOWN (PCB
->Data
->Layer
[layer
].Name
);
1642 if (layer
>= max_layer
)
1644 label
= gtk_label_new (name
);
1645 gtk_misc_set_alignment (GTK_MISC (label
), 0.0, 0.5);
1646 gtk_table_attach_defaults (GTK_TABLE (table
), label
,
1647 0, 1, layer
+ 1, layer
+ 2);
1651 layer_entry
[layer
] = gtk_entry_new ();
1652 gtk_entry_set_text (GTK_ENTRY (layer_entry
[layer
]), name
);
1653 gtk_table_attach_defaults (GTK_TABLE (table
), layer_entry
[layer
],
1654 0, 1, layer
+ 1, layer
+ 2);
1655 g_signal_connect(G_OBJECT(layer_entry
[layer
]), "activate",
1656 G_CALLBACK(layer_name_entry_cb
), GINT_TO_POINTER(layer
));
1660 for (i
= 0; i
< max_layer
; ++i
)
1662 snprintf (buf
, sizeof (buf
), "%2.2d", i
+1);
1663 button
= gtk_radio_button_new_with_label (group
, buf
);
1665 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button
), FALSE
);
1666 group
= gtk_radio_button_get_group (GTK_RADIO_BUTTON (button
));
1667 gtk_table_attach_defaults (GTK_TABLE (table
), button
,
1668 i
+ 1, i
+ 2, layer
+ 1, layer
+ 2);
1669 g_signal_connect (G_OBJECT (button
), "toggled",
1670 G_CALLBACK (config_layer_groups_radio_button_cb
),
1671 GINT_TO_POINTER ((layer
<< 8) | (i
+ 1)));
1672 group_button
[layer
][i
] = button
;
1675 gtk_widget_show_all(config_groups_vbox
);
1676 config_layer_group_button_state_update ();
1681 edit_layer_button_cb(GtkWidget
*widget
, gchar
*data
)
1685 if (PCB
->RatDraw
|| PCB
->SilkActive
)
1688 argv
= g_strsplit(data
, ",", -1);
1689 MoveLayerAction(2, argv
, 0, 0);
1694 config_layers_tab_create (GtkWidget
* tab_vbox
)
1696 GtkWidget
*tabs
, *vbox
, *vbox1
, *button
, *text
, *sep
;
1697 GtkWidget
*hbox
, *arrow
;
1700 tabs
= gtk_notebook_new ();
1701 gtk_box_pack_start (GTK_BOX (tab_vbox
), tabs
, TRUE
, TRUE
, 0);
1704 vbox
= ghid_notebook_page(tabs
, _("Change"), 0, 6);
1705 vbox1
= ghid_category_vbox(vbox
,
1706 _("Operations on currently selected layer:"),
1709 button
= gtk_button_new();
1710 arrow
= gtk_arrow_new(GTK_ARROW_UP
, GTK_SHADOW_ETCHED_IN
);
1711 gtk_container_add(GTK_CONTAINER(button
), arrow
);
1712 g_signal_connect(G_OBJECT(button
), "clicked",
1713 G_CALLBACK(edit_layer_button_cb
), "c,up");
1714 hbox
= gtk_hbox_new(FALSE
, 0);
1715 gtk_box_pack_start(GTK_BOX(vbox1
), hbox
, TRUE
, TRUE
, 0);
1716 gtk_box_pack_start(GTK_BOX(hbox
), button
, FALSE
, FALSE
, 0);
1718 button
= gtk_button_new();
1719 arrow
= gtk_arrow_new(GTK_ARROW_DOWN
, GTK_SHADOW_ETCHED_IN
);
1720 gtk_container_add(GTK_CONTAINER(button
), arrow
);
1721 g_signal_connect(G_OBJECT(button
), "clicked",
1722 G_CALLBACK(edit_layer_button_cb
), "c,down");
1723 hbox
= gtk_hbox_new(FALSE
, 0);
1724 gtk_box_pack_start(GTK_BOX(vbox1
), hbox
, TRUE
, TRUE
, 0);
1725 gtk_box_pack_start(GTK_BOX(hbox
), button
, FALSE
, FALSE
, 0);
1727 button
= gtk_button_new_from_stock(GTK_STOCK_DELETE
);
1728 g_signal_connect(G_OBJECT(button
), "clicked",
1729 G_CALLBACK(edit_layer_button_cb
), "c,-1");
1730 hbox
= gtk_hbox_new(FALSE
, 0);
1731 gtk_box_pack_start(GTK_BOX(vbox1
), hbox
, TRUE
, TRUE
, 0);
1732 gtk_box_pack_start(GTK_BOX(hbox
), button
, FALSE
, FALSE
, 0);
1734 vbox1
= ghid_category_vbox(vbox
,
1735 _("Add new layer above currently selected layer:"),
1737 button
= gtk_button_new_from_stock(GTK_STOCK_ADD
);
1738 g_signal_connect(G_OBJECT(button
), "clicked",
1739 G_CALLBACK(edit_layer_button_cb
), "-1,c");
1740 hbox
= gtk_hbox_new(FALSE
, 0);
1741 gtk_box_pack_start(GTK_BOX(vbox1
), hbox
, TRUE
, TRUE
, 0);
1742 gtk_box_pack_start(GTK_BOX(hbox
), button
, FALSE
, FALSE
, 0);
1745 vbox
= ghid_notebook_page (tabs
, _("Groups"), 0, 6);
1746 config_groups_vbox
= gtk_vbox_new(FALSE
, 0);
1747 gtk_box_pack_start(GTK_BOX(vbox
), config_groups_vbox
, FALSE
, FALSE
, 0);
1748 ghid_config_groups_changed();
1750 sep
= gtk_hseparator_new ();
1751 gtk_box_pack_start (GTK_BOX (vbox
), sep
, FALSE
, FALSE
, 4);
1754 ghid_check_button_connected (vbox
, &use_layer_default_button
, FALSE
,
1755 TRUE
, FALSE
, FALSE
, 8, NULL
, NULL
,
1756 ("Use these layer settings as the default for new layouts"));
1761 vbox
= ghid_notebook_page (tabs
, _("Info"), 0, 6);
1763 text
= ghid_scrolled_text_view (vbox
, NULL
,
1764 GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1765 for (i
= 0; i
< sizeof (layer_info_text
) / sizeof (gchar
*); ++i
)
1766 ghid_text_view_append (text
, _(layer_info_text
[i
]));
1771 ghid_config_layer_name_update (gchar
* name
, gint layer
)
1773 if (!config_window
|| layers_applying
|| !name
)
1775 gtk_entry_set_text (GTK_ENTRY (layer_entry
[layer
]), name
);
1777 /* If we get a config layer name change because a new PCB is loaded
1778 | or new layout started, need to change our working layer group copy.
1780 if (lg_monitor
!= &PCB
->LayerGroups
)
1782 layer_groups
= PCB
->LayerGroups
;
1783 lg_monitor
= &PCB
->LayerGroups
;
1784 config_layer_group_button_state_update ();
1785 groups_modified
= FALSE
;
1789 /* -------------- The Colors config page ----------------
1791 static GtkWidget
*config_colors_vbox
,
1792 *config_colors_tab_vbox
,
1793 *config_colors_save_button
,
1794 *config_color_file_label
, *config_color_warn_label
;
1796 static void config_colors_tab_create (GtkWidget
* tab_vbox
);
1798 static gboolean config_colors_modified
;
1801 config_color_file_set_label (void)
1806 name
= g_strdup ("defaults");
1808 name
= g_path_get_basename (color_file
);
1810 str
= g_strdup_printf ("Current colors loaded: <b>%s</b>", name
);
1811 gtk_label_set_markup (GTK_LABEL (config_color_file_label
), str
);
1817 config_color_defaults_cb (gpointer data
)
1823 for (list
= config_color_list
; list
; list
= list
->next
)
1825 cc
= (ConfigColor
*) list
->data
;
1826 ha
= cc
->attributes
;
1827 dup_string ((char **) ha
->value
, ha
->default_val
.str_value
);
1828 cc
->color_is_mapped
= FALSE
;
1829 ghid_set_special_colors (ha
);
1832 dup_string (&color_file
, "");
1833 ghidgui
->config_modified
= TRUE
;
1835 gtk_widget_set_sensitive (config_colors_save_button
, FALSE
);
1836 gtk_widget_set_sensitive (config_color_warn_label
, FALSE
);
1837 config_color_file_set_label ();
1838 config_colors_modified
= FALSE
;
1840 ghid_layer_buttons_color_update ();
1842 /* Receate the colors config page to pick up new colors.
1844 gtk_widget_destroy (config_colors_vbox
);
1845 config_colors_tab_create (config_colors_tab_vbox
);
1847 ghid_invalidate_all();
1851 config_color_load_cb (gpointer data
)
1853 gchar
*path
, *dir
= g_strdup (color_dir
);
1855 path
= ghid_dialog_file_select_open (_("Load Color File"), &dir
, NULL
);
1858 config_colors_read (path
);
1859 dup_string (&color_file
, path
);
1860 ghidgui
->config_modified
= TRUE
;
1862 gtk_widget_set_sensitive (config_colors_save_button
, FALSE
);
1863 gtk_widget_set_sensitive (config_color_warn_label
, FALSE
);
1864 config_color_file_set_label ();
1865 config_colors_modified
= FALSE
;
1870 /* Receate the colors config page to pick up new colors.
1872 gtk_widget_destroy (config_colors_vbox
);
1873 config_colors_tab_create (config_colors_tab_vbox
);
1875 ghid_invalidate_all();
1879 config_color_save_cb (gpointer data
)
1881 gchar
*name
, *path
, *dir
= g_strdup (color_dir
);
1884 ghid_dialog_file_select_save (_("Save Color File"), &dir
, NULL
, NULL
);
1887 name
= g_path_get_basename (path
);
1888 if (!strcmp (name
, "default"))
1889 ghid_dialog_message (_
1890 ("Sorry, not overwriting the default color file!"));
1893 config_colors_write (path
);
1894 dup_string (&color_file
, path
);
1895 ghidgui
->config_modified
= TRUE
;
1897 gtk_widget_set_sensitive (config_colors_save_button
, FALSE
);
1898 gtk_widget_set_sensitive (config_color_warn_label
, FALSE
);
1899 config_color_file_set_label ();
1900 config_colors_modified
= FALSE
;
1909 config_color_set_cb (GtkWidget
* button
, ConfigColor
* cc
)
1912 HID_Attribute
*ha
= cc
->attributes
;
1915 gtk_color_button_get_color (GTK_COLOR_BUTTON (button
), &new_color
);
1916 str
= ghid_get_color_name (&new_color
);
1917 ghid_map_color_string (str
, &cc
->color
);
1918 *(char **) ha
->value
= str
;
1919 /* g_free(str); Memory leak */
1921 config_colors_modified
= TRUE
;
1922 gtk_widget_set_sensitive (config_colors_save_button
, TRUE
);
1923 gtk_widget_set_sensitive (config_color_warn_label
, TRUE
);
1925 ghid_layer_buttons_color_update ();
1926 ghid_invalidate_all();
1930 config_color_button_create (GtkWidget
* box
, ConfigColor
* cc
)
1932 GtkWidget
*button
, *hbox
, *label
;
1933 HID_Attribute
*ha
= cc
->attributes
;
1936 hbox
= gtk_hbox_new (FALSE
, 6);
1937 gtk_box_pack_start (GTK_BOX (box
), hbox
, FALSE
, FALSE
, 0);
1939 if (!cc
->color_is_mapped
)
1940 ghid_map_color_string (*(char **) ha
->value
, &cc
->color
);
1941 cc
->color_is_mapped
= TRUE
;
1943 title
= g_strdup_printf (_("PCB %s Color"), ha
->name
);
1944 button
= gtk_color_button_new_with_color (&cc
->color
);
1945 gtk_color_button_set_title (GTK_COLOR_BUTTON (button
), title
);
1948 gtk_box_pack_start (GTK_BOX (hbox
), button
, FALSE
, FALSE
, 0);
1949 label
= gtk_label_new (ha
->name
);
1950 gtk_box_pack_start (GTK_BOX (hbox
), label
, FALSE
, FALSE
, 0);
1951 g_signal_connect (G_OBJECT (button
), "color-set",
1952 G_CALLBACK (config_color_set_cb
), cc
);
1956 config_colors_tab_create (GtkWidget
* tab_vbox
)
1958 GtkWidget
*scrolled_vbox
, *vbox
, *hbox
, *expander
, *sep
;
1962 vbox
= gtk_vbox_new (FALSE
, 0);
1963 gtk_box_pack_start (GTK_BOX (tab_vbox
), vbox
, TRUE
, TRUE
, 0);
1964 gtk_container_set_border_width (GTK_CONTAINER (vbox
), 6);
1966 config_colors_vbox
= vbox
; /* can be destroyed if color file loaded */
1967 config_colors_tab_vbox
= tab_vbox
;
1969 scrolled_vbox
= ghid_scrolled_vbox (config_colors_vbox
, NULL
,
1970 GTK_POLICY_NEVER
, GTK_POLICY_AUTOMATIC
);
1972 /* ---- Main colors ---- */
1973 expander
= gtk_expander_new (_("Main colors"));
1974 gtk_box_pack_start (GTK_BOX (scrolled_vbox
), expander
, FALSE
, FALSE
, 2);
1975 vbox
= gtk_vbox_new (FALSE
, 0);
1976 gtk_container_add (GTK_CONTAINER (expander
), vbox
);
1977 vbox
= ghid_category_vbox (vbox
, NULL
, 0, 2, TRUE
, FALSE
);
1979 for (list
= config_color_list
; list
; list
= list
->next
)
1981 cc
= (ConfigColor
*) list
->data
;
1982 if (cc
->type
!= MISC_COLOR
)
1984 config_color_button_create (vbox
, cc
);
1987 /* ---- Layer colors ---- */
1988 expander
= gtk_expander_new (_("Layer colors"));
1989 gtk_box_pack_start (GTK_BOX (scrolled_vbox
), expander
, FALSE
, FALSE
, 2);
1990 vbox
= gtk_vbox_new (FALSE
, 0);
1991 gtk_container_add (GTK_CONTAINER (expander
), vbox
);
1992 vbox
= ghid_category_vbox (vbox
, NULL
, 0, 2, TRUE
, FALSE
);
1994 for (list
= config_color_list
; list
; list
= list
->next
)
1996 cc
= (ConfigColor
*) list
->data
;
1997 if (cc
->type
!= LAYER_COLOR
)
1999 config_color_button_create (vbox
, cc
);
2002 /* ---- Selected colors ---- */
2003 expander
= gtk_expander_new (_("Selected colors"));
2004 gtk_box_pack_start (GTK_BOX (scrolled_vbox
), expander
, FALSE
, FALSE
, 2);
2005 vbox
= gtk_vbox_new (FALSE
, 0);
2006 gtk_container_add (GTK_CONTAINER (expander
), vbox
);
2007 vbox
= ghid_category_vbox (vbox
, NULL
, 0, 2, TRUE
, FALSE
);
2009 for (list
= config_color_list
; list
; list
= list
->next
)
2011 cc
= (ConfigColor
*) list
->data
;
2012 if (cc
->type
!= MISC_SELECTED_COLOR
)
2014 config_color_button_create (vbox
, cc
);
2016 sep
= gtk_hseparator_new ();
2017 gtk_box_pack_start (GTK_BOX (vbox
), sep
, FALSE
, FALSE
, 2);
2018 for (list
= config_color_list
; list
; list
= list
->next
)
2020 cc
= (ConfigColor
*) list
->data
;
2021 if (cc
->type
!= LAYER_SELECTED_COLOR
)
2023 config_color_button_create (vbox
, cc
);
2026 config_color_warn_label
= gtk_label_new ("");
2027 gtk_label_set_use_markup (GTK_LABEL (config_color_warn_label
), TRUE
);
2028 gtk_label_set_markup (GTK_LABEL (config_color_warn_label
),
2029 _("<b>Warning:</b> unsaved color changes will be lost"
2030 " at program exit."));
2031 gtk_box_pack_start (GTK_BOX (config_colors_vbox
), config_color_warn_label
,
2034 hbox
= gtk_hbox_new (FALSE
, 0);
2035 gtk_box_pack_start (GTK_BOX (config_colors_vbox
), hbox
, FALSE
, FALSE
, 6);
2037 config_color_file_label
= gtk_label_new ("");
2038 gtk_label_set_use_markup (GTK_LABEL (config_color_file_label
), TRUE
);
2039 config_color_file_set_label ();
2040 gtk_box_pack_start (GTK_BOX (hbox
), config_color_file_label
,
2043 ghid_button_connected (hbox
, NULL
, FALSE
, FALSE
, FALSE
, 4,
2044 config_color_load_cb
, NULL
, _("Load"));
2045 ghid_button_connected (hbox
, &config_colors_save_button
,
2046 FALSE
, FALSE
, FALSE
, 4,
2047 config_color_save_cb
, NULL
, _("Save"));
2048 ghid_button_connected (hbox
, NULL
, FALSE
, FALSE
, FALSE
, 4,
2049 config_color_defaults_cb
, NULL
, _("Defaults"));
2051 gtk_widget_set_sensitive (config_colors_save_button
,
2052 config_colors_modified
);
2053 gtk_widget_set_sensitive (config_color_warn_label
, config_colors_modified
);
2054 gtk_widget_show_all (config_colors_vbox
);
2058 /* --------------- The main config page -----------------
2067 static GtkNotebook
*config_notebook
;
2070 config_page_create (GtkTreeStore
* tree
, GtkTreeIter
* iter
,
2071 GtkNotebook
* notebook
)
2076 vbox
= gtk_vbox_new (FALSE
, 0);
2077 gtk_notebook_append_page (notebook
, vbox
, NULL
);
2078 page
= g_list_length (notebook
->children
) - 1;
2079 gtk_tree_store_set (tree
, iter
, CONFIG_PAGE_COLUMN
, page
, -1);
2084 ghid_config_handle_units_changed (void)
2086 ghid_set_cursor_position_labels ();
2087 gtk_label_set_markup (GTK_LABEL (ghidgui
->grid_units_label
),
2088 Settings
.grid_units_mm
?
2089 "<b>mm</b> " : "<b>mil</b> ");
2090 if (config_sizes_vbox
)
2092 gtk_widget_destroy (config_sizes_vbox
);
2093 config_sizes_vbox
= NULL
;
2094 config_sizes_tab_create (config_sizes_tab_vbox
);
2096 if (config_increments_vbox
)
2098 gtk_widget_destroy (config_increments_vbox
);
2099 config_increments_vbox
= NULL
;
2100 config_increments_tab_create (config_increments_tab_vbox
);
2102 ghidgui
->config_modified
= TRUE
;
2106 ghid_config_text_scale_update (void)
2109 gtk_spin_button_set_value (GTK_SPIN_BUTTON (config_text_spin_button
),
2110 (gdouble
) Settings
.TextScale
);
2114 config_close_cb (gpointer data
)
2116 /* Config pages may need to check for modified entries, use as default
2117 | options, etc when the config window is closed.
2119 config_sizes_apply ();
2120 config_layers_apply ();
2121 config_library_apply ();
2122 config_general_apply ();
2124 config_sizes_vbox
= NULL
;
2125 config_increments_vbox
= NULL
;
2127 config_groups_vbox
= config_groups_table
= NULL
;
2128 config_groups_window
= NULL
;
2130 gtk_widget_destroy (config_window
);
2131 config_window
= NULL
;
2135 config_destroy_cb (gpointer data
)
2137 config_sizes_vbox
= NULL
;
2138 config_increments_vbox
= NULL
;
2139 config_groups_vbox
= config_groups_table
= NULL
;
2140 config_groups_window
= NULL
;
2141 gtk_widget_destroy (config_window
);
2142 config_window
= NULL
;
2146 config_selection_changed_cb (GtkTreeSelection
* selection
, gpointer data
)
2149 GtkTreeModel
*model
;
2152 if (!gtk_tree_selection_get_selected (selection
, &model
, &iter
))
2154 gtk_tree_model_get (model
, &iter
, CONFIG_PAGE_COLUMN
, &page
, -1);
2155 gtk_notebook_set_current_page (config_notebook
, page
);
2159 ghid_config_window_show (void)
2161 GtkWidget
*widget
, *main_vbox
, *vbox
, *config_hbox
, *hbox
;
2162 GtkWidget
*scrolled
;
2164 GtkTreeStore
*model
;
2165 GtkTreeView
*treeview
;
2167 GtkCellRenderer
*renderer
;
2168 GtkTreeViewColumn
*column
;
2169 GtkTreeSelection
*select
;
2173 gtk_window_present (GTK_WINDOW (config_window
));
2177 config_window
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
2178 g_signal_connect (G_OBJECT (config_window
), "delete_event",
2179 G_CALLBACK (config_destroy_cb
), NULL
);
2181 gtk_window_set_title (GTK_WINDOW (config_window
), "PCB Preferences");
2182 gtk_window_set_wmclass (GTK_WINDOW (config_window
), "Pcb_Conf", "PCB");
2183 gtk_container_set_border_width (GTK_CONTAINER (config_window
), 2);
2185 config_hbox
= gtk_hbox_new (FALSE
, 4);
2186 gtk_container_add (GTK_CONTAINER (config_window
), config_hbox
);
2188 scrolled
= gtk_scrolled_window_new (NULL
, NULL
);
2189 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled
),
2190 GTK_POLICY_NEVER
, GTK_POLICY_AUTOMATIC
);
2191 gtk_box_pack_start (GTK_BOX (config_hbox
), scrolled
, FALSE
, FALSE
, 0);
2193 main_vbox
= gtk_vbox_new (FALSE
, 4);
2194 gtk_box_pack_start (GTK_BOX (config_hbox
), main_vbox
, TRUE
, TRUE
, 0);
2196 widget
= gtk_notebook_new ();
2197 gtk_box_pack_start (GTK_BOX (main_vbox
), widget
, TRUE
, TRUE
, 0);
2198 config_notebook
= GTK_NOTEBOOK (widget
);
2199 gtk_notebook_set_show_tabs (config_notebook
, FALSE
);
2201 model
= gtk_tree_store_new (N_CONFIG_COLUMNS
, G_TYPE_STRING
, G_TYPE_INT
);
2205 gtk_tree_store_append (model
, &iter
, NULL
);
2206 gtk_tree_store_set (model
, &iter
, CONFIG_NAME_COLUMN
, _("General"), -1);
2207 vbox
= config_page_create (model
, &iter
, config_notebook
);
2208 config_general_tab_create (vbox
);
2212 gtk_tree_store_append (model
, &iter
, NULL
);
2213 gtk_tree_store_set (model
, &iter
, CONFIG_NAME_COLUMN
, _("Sizes"), -1);
2214 vbox
= config_page_create (model
, &iter
, config_notebook
);
2215 config_sizes_tab_create (vbox
);
2217 /* -- Increments -- */
2218 gtk_tree_store_append (model
, &iter
, NULL
);
2219 gtk_tree_store_set (model
, &iter
, CONFIG_NAME_COLUMN
, _("Increments"), -1);
2220 vbox
= config_page_create (model
, &iter
, config_notebook
);
2221 config_increments_tab_create (vbox
);
2224 gtk_tree_store_append (model
, &iter
, NULL
);
2225 gtk_tree_store_set (model
, &iter
, CONFIG_NAME_COLUMN
, _("Library"), -1);
2226 vbox
= config_page_create (model
, &iter
, config_notebook
);
2227 config_library_tab_create (vbox
);
2229 /* -- Layer names and groups -- */
2230 gtk_tree_store_append (model
, &iter
, NULL
);
2231 gtk_tree_store_set (model
, &iter
, CONFIG_NAME_COLUMN
, _("Layers"), -1);
2232 vbox
= config_page_create (model
, &iter
, config_notebook
);
2233 config_layers_tab_create (vbox
);
2237 gtk_tree_store_append (model
, &iter
, NULL
);
2238 gtk_tree_store_set (model
, &iter
, CONFIG_NAME_COLUMN
, _("Colors"), -1);
2239 vbox
= config_page_create (model
, &iter
, config_notebook
);
2240 config_colors_tab_create (vbox
);
2243 /* Create the tree view
2246 GTK_TREE_VIEW (gtk_tree_view_new_with_model (GTK_TREE_MODEL (model
)));
2247 g_object_unref (G_OBJECT (model
)); /* Don't need the model anymore */
2249 renderer
= gtk_cell_renderer_text_new ();
2250 column
= gtk_tree_view_column_new_with_attributes (NULL
, renderer
,
2254 gtk_tree_view_append_column (treeview
, column
);
2255 gtk_container_add (GTK_CONTAINER (scrolled
), GTK_WIDGET (treeview
));
2258 select
= gtk_tree_view_get_selection (treeview
);
2259 gtk_tree_selection_set_mode (select
, GTK_SELECTION_SINGLE
);
2260 g_signal_connect (G_OBJECT (select
), "changed",
2261 G_CALLBACK (config_selection_changed_cb
), NULL
);
2264 hbox
= gtk_hbutton_box_new ();
2265 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox
), GTK_BUTTONBOX_END
);
2266 gtk_box_set_spacing (GTK_BOX (hbox
), 5);
2267 gtk_box_pack_start (GTK_BOX (main_vbox
), hbox
, FALSE
, FALSE
, 0);
2269 button
= gtk_button_new_from_stock (GTK_STOCK_OK
);
2270 GTK_WIDGET_SET_FLAGS (button
, GTK_CAN_DEFAULT
);
2271 g_signal_connect (G_OBJECT (button
), "clicked",
2272 G_CALLBACK (config_close_cb
), NULL
);
2273 gtk_box_pack_start (GTK_BOX (hbox
), button
, TRUE
, TRUE
, 0);
2274 gtk_widget_grab_default (button
);
2276 gtk_widget_show_all (config_window
);