]> git.sur5r.net Git - glabels/blob - glabels2/src/template-designer.c
2004-07-11 Jim Evins <evins@snaught.com>
[glabels] / glabels2 / src / template-designer.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  template-designer.c:  Template designer module
5  *
6  *  Copyright (C) 2003  Jim Evins <evins@snaught.com>.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  */
22 #include <config.h>
23
24 #include <math.h>
25 #include <libgnome/libgnome.h>
26 #include <libgnomeui/libgnomeui.h>
27 #include <glade/glade-xml.h>
28
29 #include "template-designer.h"
30 #include "prefs.h"
31 #include <libglabels/paper.h>
32 #include <libglabels/template.h>
33 #include "wdgt-mini-preview.h"
34 #include "print-dialog.h"
35
36 #include "debug.h"
37
38 /*========================================================*/
39 /* Private macros and constants.                          */
40 /*========================================================*/
41 #define ICON_PIXMAP gnome_program_locate_file (NULL,\
42                                                GNOME_FILE_DOMAIN_APP_PIXMAP,\
43                                                "glabels/glabels-icon.png",\
44                                                FALSE, NULL)
45
46 #define EX_RECT_IMAGE gnome_program_locate_file (NULL,\
47                                                GNOME_FILE_DOMAIN_APP_PIXMAP,\
48                                                "glabels/ex-rect-size.png",\
49                                                FALSE, NULL)
50
51 #define EX_ROUND_IMAGE gnome_program_locate_file (NULL,\
52                                                GNOME_FILE_DOMAIN_APP_PIXMAP,\
53                                                "glabels/ex-round-size.png",\
54                                                FALSE, NULL)
55
56 #define EX_CD_IMAGE gnome_program_locate_file (NULL,\
57                                                GNOME_FILE_DOMAIN_APP_PIXMAP,\
58                                                "glabels/ex-cd-size.png",\
59                                                FALSE, NULL)
60
61 #define EX_NLAYOUTS_IMAGE1 gnome_program_locate_file (NULL,\
62                                                GNOME_FILE_DOMAIN_APP_PIXMAP,\
63                                                "glabels/ex-1layout.png",\
64                                                FALSE, NULL)
65
66 #define EX_NLAYOUTS_IMAGE2 gnome_program_locate_file (NULL,\
67                                                GNOME_FILE_DOMAIN_APP_PIXMAP,\
68                                                "glabels/ex-2layouts.png",\
69                                                FALSE, NULL)
70
71 #define DEFAULT_MARGIN 9.0
72
73 #define DEFAULT_RECT_W      252.0
74 #define DEFAULT_RECT_H      144.0
75 #define DEFAULT_RECT_R        0.0
76 #define DEFAULT_RECT_WASTE    0.0 /* Should never exceed 1/2 the distance between items. */
77
78 #define DEFAULT_ROUND_R      72.0
79 #define DEFAULT_ROUND_WASTE   0.0 /* Should never exceed 1/2 the distance between items. */
80
81 #define DEFAULT_CD_RADIUS   166.5
82 #define DEFAULT_CD_HOLE      58.5
83 #define DEFAULT_CD_WASTE      9.0 /* Should never exceed 1/2 the distance between items. */
84
85 #define CONTENTS_BG 0xF5F5F5FF
86 #define DELTA 0.01
87 #define MAX_PAGE_DIM_POINTS 5000.0
88
89 /*========================================================*/
90 /* Private types.                                         */
91 /*========================================================*/
92
93 struct _glTemplateDesignerPrivate
94 {
95         GladeXML        *gui;
96         GtkWidget       *druid;
97
98         /* Druid pages */
99         GtkWidget       *start_page;
100         GtkWidget       *name_page;
101         GtkWidget       *pg_size_page;
102         GtkWidget       *shape_page;
103         GtkWidget       *rect_size_page;
104         GtkWidget       *round_size_page;
105         GtkWidget       *cd_size_page;
106         GtkWidget       *nlayouts_page;
107         GtkWidget       *layout_page;
108         GtkWidget       *finish_page;
109
110         /* Name page controls */
111         GtkWidget       *brand_entry;
112         GtkWidget       *part_num_entry;
113         GtkWidget       *description_entry;
114
115         /* Page size page controls */
116         GtkWidget       *pg_size_combo;
117         GtkWidget       *pg_size_entry;
118         GtkWidget       *pg_w_spin;
119         GtkWidget       *pg_h_spin;
120         GtkWidget       *pg_w_units_label;
121         GtkWidget       *pg_h_units_label;
122
123         /* Shape page controls */
124         GtkWidget       *shape_rect_radio;
125         GtkWidget       *shape_round_radio;
126         GtkWidget       *shape_cd_radio;
127
128         /* Label size (rectangular) page controls */
129         GtkWidget       *rect_image;
130         GtkWidget       *rect_w_spin;
131         GtkWidget       *rect_h_spin;
132         GtkWidget       *rect_r_spin;
133         GtkWidget       *rect_x_waste_spin;
134         GtkWidget       *rect_y_waste_spin;
135         GtkWidget       *rect_margin_spin;
136         GtkWidget       *rect_w_units_label;
137         GtkWidget       *rect_h_units_label;
138         GtkWidget       *rect_r_units_label;
139         GtkWidget       *rect_x_waste_units_label;
140         GtkWidget       *rect_y_waste_units_label;
141         GtkWidget       *rect_margin_units_label;
142
143         /* Label size (round) page controls */
144         GtkWidget       *round_image;
145         GtkWidget       *round_r_spin;
146         GtkWidget       *round_waste_spin;
147         GtkWidget       *round_margin_spin;
148         GtkWidget       *round_r_units_label;
149         GtkWidget       *round_waste_units_label;
150         GtkWidget       *round_margin_units_label;
151
152         /* Label size (cd) page controls */
153         GtkWidget       *cd_image;
154         GtkWidget       *cd_radius_spin;
155         GtkWidget       *cd_hole_spin;
156         GtkWidget       *cd_w_spin;
157         GtkWidget       *cd_h_spin;
158         GtkWidget       *cd_waste_spin;
159         GtkWidget       *cd_margin_spin;
160         GtkWidget       *cd_radius_units_label;
161         GtkWidget       *cd_hole_units_label;
162         GtkWidget       *cd_w_units_label;
163         GtkWidget       *cd_h_units_label;
164         GtkWidget       *cd_waste_units_label;
165         GtkWidget       *cd_margin_units_label;
166
167         /* Number of layouts controls */
168         GtkWidget       *nlayouts_image1;
169         GtkWidget       *nlayouts_image2;
170         GtkWidget       *nlayouts_spin;
171
172         /* Layout page controls */
173         GtkWidget       *layout1_head_label;
174         GtkWidget       *layout1_nx_spin;
175         GtkWidget       *layout1_ny_spin;
176         GtkWidget       *layout1_x0_spin;
177         GtkWidget       *layout1_y0_spin;
178         GtkWidget       *layout1_dx_spin;
179         GtkWidget       *layout1_dy_spin;
180         GtkWidget       *layout2_head_label;
181         GtkWidget       *layout2_nx_spin;
182         GtkWidget       *layout2_ny_spin;
183         GtkWidget       *layout2_x0_spin;
184         GtkWidget       *layout2_y0_spin;
185         GtkWidget       *layout2_dx_spin;
186         GtkWidget       *layout2_dy_spin;
187         GtkWidget       *layout_x0_units_label;
188         GtkWidget       *layout_y0_units_label;
189         GtkWidget       *layout_dx_units_label;
190         GtkWidget       *layout_dy_units_label;
191         GtkWidget       *layout_mini_preview;
192         GtkWidget       *layout_test_button;
193
194         /* Units related stuff */
195         const gchar     *units_string;
196         gdouble          units_per_point;
197         gdouble          climb_rate;
198         gint             digits;
199
200 };
201
202 /*========================================================*/
203 /* Private globals.                                       */
204 /*========================================================*/
205
206 static GtkWindowClass* parent_class = NULL;
207
208 /*========================================================*/
209 /* Private function prototypes.                           */
210 /*========================================================*/
211
212 static void gl_template_designer_class_init       (glTemplateDesignerClass *klass);
213 static void gl_template_designer_init             (glTemplateDesigner      *dlg);
214 static void gl_template_designer_finalize         (GObject                 *object);
215 static void gl_template_designer_construct        (glTemplateDesigner      *dlg);
216
217 static void     construct_start_page              (glTemplateDesigner      *dlg,
218                                                    GdkPixbuf               *logo);
219
220 static void     construct_name_page               (glTemplateDesigner      *dlg,
221                                                    GdkPixbuf               *logo);
222
223 static void     construct_pg_size_page            (glTemplateDesigner      *dlg,
224                                                    GdkPixbuf               *logo);
225
226 static void     construct_shape_page              (glTemplateDesigner      *dlg,
227                                                    GdkPixbuf               *logo);
228
229 static void     construct_rect_size_page          (glTemplateDesigner      *dlg,
230                                                    GdkPixbuf               *logo);
231
232 static void     construct_round_size_page         (glTemplateDesigner      *dlg,
233                                                    GdkPixbuf               *logo);
234
235 static void     construct_cd_size_page            (glTemplateDesigner      *dlg,
236                                                    GdkPixbuf               *logo);
237
238 static void     construct_nlayouts_page           (glTemplateDesigner      *dlg,
239                                                    GdkPixbuf               *logo);
240
241 static void     construct_layout_page             (glTemplateDesigner      *dlg,
242                                                    GdkPixbuf               *logo);
243
244 static void     construct_finish_page             (glTemplateDesigner      *dlg,
245                                                    GdkPixbuf               *logo);
246
247 static void     construct_edge_page_boilerplate   (glTemplateDesigner      *dlg,
248                                                    GnomeDruidPageEdge      *page,
249                                                    GdkPixbuf               *logo);
250
251 static void     construct_page_boilerplate        (glTemplateDesigner      *dlg,
252                                                    GnomeDruidPageStandard  *page,
253                                                    GdkPixbuf               *logo);
254
255 static void     cancel_cb                         (glTemplateDesigner      *dlg);
256
257 static void     name_page_changed_cb              (glTemplateDesigner      *dlg);
258
259 static void     pg_size_page_changed_cb           (glTemplateDesigner      *dlg);
260
261 static void     rect_size_page_prepare_cb         (glTemplateDesigner      *dlg);
262
263 static void     round_size_page_prepare_cb        (glTemplateDesigner      *dlg);
264
265 static void     cd_size_page_prepare_cb           (glTemplateDesigner      *dlg);
266
267 static void     layout_page_prepare_cb            (glTemplateDesigner      *dlg);
268
269 static void     layout_page_changed_cb            (glTemplateDesigner      *dlg);
270
271 static void     print_test_cb                     (glTemplateDesigner      *dlg);
272
273 static glTemplate *build_template                 (glTemplateDesigner      *dlg);
274
275 static gboolean next_cb                           (GnomeDruidPage          *druidpage,
276                                                    GtkWidget               *widget,
277                                                    glTemplateDesigner      *dlg);
278
279 static gboolean back_cb                           (GnomeDruidPage          *druidpage,
280                                                    GtkWidget               *widget,
281                                                    glTemplateDesigner      *dlg);
282
283 static void finish_cb                             (glTemplateDesigner      *dlg);
284
285 \f
286 /*****************************************************************************/
287 /* Boilerplate object stuff.                                                 */
288 /*****************************************************************************/
289 GType
290 gl_template_designer_get_type (void)
291 {
292         static GType type = 0;
293
294         if (!type)
295         {
296                 static const GTypeInfo info =
297                 {
298                         sizeof (glTemplateDesignerClass),
299                         NULL,           /* base_init */
300                         NULL,           /* base_finalize */
301                         (GClassInitFunc) gl_template_designer_class_init,
302                         NULL,           /* class_finalize */
303                         NULL,           /* class_data */
304                         sizeof (glTemplateDesigner),
305                         0,              /* n_preallocs */
306                         (GInstanceInitFunc) gl_template_designer_init,
307                         NULL
308                 };
309
310                 type = g_type_register_static (GTK_TYPE_WINDOW,
311                                                "glTemplateDesigner", &info, 0);
312         }
313
314         return type;
315 }
316
317 static void
318 gl_template_designer_class_init (glTemplateDesignerClass *klass)
319 {
320         GObjectClass *object_class = G_OBJECT_CLASS (klass);
321
322         gl_debug (DEBUG_TEMPLATE, "");
323         
324         parent_class = g_type_class_peek_parent (klass);
325
326         object_class->finalize = gl_template_designer_finalize;         
327 }
328
329 static void
330 gl_template_designer_init (glTemplateDesigner *dlg)
331 {
332         gl_debug (DEBUG_TEMPLATE, "START");
333
334         dlg->priv = g_new0 (glTemplateDesignerPrivate, 1);
335
336         dlg->priv->gui = glade_xml_new (GLABELS_GLADE_DIR "template-designer.glade",
337                                         "druid",
338                                         NULL);
339
340         if (!dlg->priv->gui) {
341                 g_warning ("Could not open template-designer.glade, reinstall glabels!");
342                 return;
343         }
344
345         gl_debug (DEBUG_TEMPLATE, "END");
346 }
347
348 static void 
349 gl_template_designer_finalize (GObject *object)
350 {
351         glTemplateDesigner* dlg;
352         
353         gl_debug (DEBUG_TEMPLATE, "START");
354
355         g_return_if_fail (object != NULL);
356         
357         dlg = GL_TEMPLATE_DESIGNER (object);
358
359         g_return_if_fail (GL_IS_TEMPLATE_DESIGNER (dlg));
360         g_return_if_fail (dlg->priv != NULL);
361
362         G_OBJECT_CLASS (parent_class)->finalize (object);
363
364         g_free (dlg->priv);
365
366         gl_debug (DEBUG_TEMPLATE, "END");
367 }
368
369 /*****************************************************************************/
370 /* NEW preferences dialog.                                                   */
371 /*****************************************************************************/
372 GtkWidget*
373 gl_template_designer_new (GtkWindow *parent)
374 {
375         GtkWidget *dlg;
376
377         gl_debug (DEBUG_TEMPLATE, "START");
378
379         dlg = GTK_WIDGET (g_object_new (GL_TYPE_TEMPLATE_DESIGNER, NULL));
380
381         if (parent)
382                 gtk_window_set_transient_for (GTK_WINDOW (dlg), parent);
383         
384         gl_template_designer_construct (GL_TEMPLATE_DESIGNER(dlg));
385
386
387         gl_debug (DEBUG_TEMPLATE, "END");
388
389         return dlg;
390 }
391
392 /*---------------------------------------------------------------------------*/
393 /* PRIVATE.  Construct composite widget.                                     */
394 /*---------------------------------------------------------------------------*/
395 static void
396 gl_template_designer_construct (glTemplateDesigner *dlg)
397 {
398         GdkPixbuf  *logo;
399
400         g_return_if_fail (dlg && GL_IS_TEMPLATE_DESIGNER (dlg));
401         g_return_if_fail (dlg->priv != NULL);
402
403         /* Initialize units stuff from prefs */
404         dlg->priv->units_string    = gl_prefs_get_units_string ();
405         dlg->priv->units_per_point = gl_prefs_get_units_per_point ();
406         dlg->priv->climb_rate      = gl_prefs_get_units_step_size ();
407         dlg->priv->digits          = gl_prefs_get_units_precision ();
408
409         gtk_window_set_title (GTK_WINDOW(dlg), _("gLabels Template Designer"));
410
411         logo = gdk_pixbuf_new_from_file (ICON_PIXMAP, NULL);
412
413         dlg->priv->druid = glade_xml_get_widget (dlg->priv->gui, "druid");
414         gtk_container_add (GTK_CONTAINER(dlg), dlg->priv->druid);
415
416         construct_start_page (dlg, logo);
417         construct_name_page (dlg, logo);
418         construct_pg_size_page (dlg, logo);
419         construct_shape_page (dlg, logo);
420         construct_rect_size_page (dlg, logo);
421         construct_round_size_page (dlg, logo);
422         construct_cd_size_page (dlg, logo);
423         construct_nlayouts_page (dlg, logo);
424         construct_layout_page (dlg, logo);
425         construct_finish_page (dlg, logo);
426
427         /* Cancel button */
428         g_signal_connect_swapped (G_OBJECT(dlg->priv->druid), "cancel",
429                                   G_CALLBACK(cancel_cb), dlg);
430
431         gtk_widget_show_all (GTK_WIDGET(dlg));   
432 }
433
434 /*--------------------------------------------------------------------------*/
435 /* PRIVATE.  Construct start page.                                          */
436 /*--------------------------------------------------------------------------*/
437 static void
438 construct_start_page (glTemplateDesigner      *dlg,
439                       GdkPixbuf               *logo)
440 {
441         dlg->priv->start_page =
442                 glade_xml_get_widget (dlg->priv->gui, "start_page");
443
444         construct_edge_page_boilerplate (dlg,
445                                          GNOME_DRUID_PAGE_EDGE(dlg->priv->start_page),
446                                          logo);
447 }
448
449 /*--------------------------------------------------------------------------*/
450 /* PRIVATE.  Construct name page.                                           */
451 /*--------------------------------------------------------------------------*/
452 static void
453 construct_name_page (glTemplateDesigner      *dlg,
454                      GdkPixbuf               *logo)
455 {
456         dlg->priv->name_page =
457                 glade_xml_get_widget (dlg->priv->gui, "name_page");
458
459         /* Name Page Widgets */
460         dlg->priv->brand_entry =
461                 glade_xml_get_widget (dlg->priv->gui, "brand_entry");
462         dlg->priv->part_num_entry =
463                 glade_xml_get_widget (dlg->priv->gui, "part_num_entry");
464         dlg->priv->description_entry =
465                 glade_xml_get_widget (dlg->priv->gui, "description_entry");
466
467         /* Connect a handler that listens for changes in these widgets */
468         /* This controls whether we can progress to the next page. */
469         g_signal_connect_swapped (G_OBJECT(dlg->priv->brand_entry), "changed",
470                                   G_CALLBACK(name_page_changed_cb), dlg);
471         g_signal_connect_swapped (G_OBJECT(dlg->priv->part_num_entry), "changed",
472                                   G_CALLBACK(name_page_changed_cb), dlg);
473         g_signal_connect_swapped (G_OBJECT(dlg->priv->description_entry), "changed",
474                                   G_CALLBACK(name_page_changed_cb), dlg);
475
476         /* Use this same handler to prepare the page. */
477         g_signal_connect_data (G_OBJECT(dlg->priv->name_page), "prepare",
478                                G_CALLBACK(name_page_changed_cb), dlg,
479                                NULL, (G_CONNECT_AFTER|G_CONNECT_SWAPPED));
480
481         construct_page_boilerplate (dlg,
482                                     GNOME_DRUID_PAGE_STANDARD(dlg->priv->name_page),
483                                     logo);
484 }
485
486 /*--------------------------------------------------------------------------*/
487 /* PRIVATE. Construct page size page.                                       */
488 /*--------------------------------------------------------------------------*/
489 static void
490 construct_pg_size_page (glTemplateDesigner      *dlg,
491                         GdkPixbuf               *logo)
492 {
493         GList *page_sizes;
494         const gchar *default_page_size_id;
495         gchar       *default_page_size_name;
496
497         dlg->priv->pg_size_page =
498                 glade_xml_get_widget (dlg->priv->gui, "pg_size_page");
499
500         /* Page Size Page Widgets */
501         dlg->priv->pg_size_combo =
502                 glade_xml_get_widget (dlg->priv->gui, "pg_size_combo");
503         dlg->priv->pg_size_entry =
504                 glade_xml_get_widget (dlg->priv->gui, "pg_size_entry");
505         dlg->priv->pg_w_spin =
506                 glade_xml_get_widget (dlg->priv->gui, "pg_w_spin");
507         dlg->priv->pg_h_spin =
508                 glade_xml_get_widget (dlg->priv->gui, "pg_h_spin");
509         dlg->priv->pg_w_units_label =
510                 glade_xml_get_widget (dlg->priv->gui, "pg_w_units_label");
511         dlg->priv->pg_h_units_label =
512                 glade_xml_get_widget (dlg->priv->gui, "pg_h_units_label");
513
514         /* Load page size combo */
515         page_sizes = gl_paper_get_name_list ();
516         gtk_combo_set_popdown_strings (GTK_COMBO(dlg->priv->pg_size_combo), page_sizes);
517         gl_paper_free_name_list (page_sizes);
518         default_page_size_id = gl_prefs_get_page_size ();
519         default_page_size_name = gl_paper_lookup_name_from_id (default_page_size_id);
520         gtk_entry_set_text (GTK_ENTRY(dlg->priv->pg_size_entry), default_page_size_name);
521         g_free (default_page_size_name);
522
523         /* Apply units to spinbuttons and units labels. */
524         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->pg_w_spin),
525                                     dlg->priv->digits);
526         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->pg_w_spin),
527                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
528         gtk_label_set_text (GTK_LABEL(dlg->priv->pg_w_units_label),
529                             dlg->priv->units_string);
530         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->pg_w_spin),
531                                    0.0, MAX_PAGE_DIM_POINTS*dlg->priv->units_per_point);
532         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->pg_h_spin),
533                                     dlg->priv->digits);
534         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->pg_h_spin),
535                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
536         gtk_label_set_text (GTK_LABEL(dlg->priv->pg_h_units_label),
537                             dlg->priv->units_string);
538         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->pg_h_spin),
539                                    0.0, MAX_PAGE_DIM_POINTS*dlg->priv->units_per_point);
540
541         /* Connect a handler that listens for changes in these widgets */
542         /* This controls sensitivity of related widgets. */
543         g_signal_connect_swapped (G_OBJECT(dlg->priv->pg_size_entry), "changed",
544                                   G_CALLBACK(pg_size_page_changed_cb), dlg);
545
546         /* Use this same handler to prepare the page. */
547         g_signal_connect_data (G_OBJECT(dlg->priv->pg_size_page), "prepare",
548                                G_CALLBACK(pg_size_page_changed_cb), dlg,
549                                NULL, (G_CONNECT_AFTER|G_CONNECT_SWAPPED));
550
551         construct_page_boilerplate (dlg,
552                                     GNOME_DRUID_PAGE_STANDARD(dlg->priv->pg_size_page),
553                                     logo);
554 }
555
556 /*--------------------------------------------------------------------------*/
557 /* PRIVATE.  Construct shape page.                                          */
558 /*--------------------------------------------------------------------------*/
559 static void
560 construct_shape_page (glTemplateDesigner      *dlg,
561                       GdkPixbuf               *logo)
562 {
563         dlg->priv->shape_page =
564                 glade_xml_get_widget (dlg->priv->gui, "shape_page");
565
566         /* Shape Page Widgets */
567         dlg->priv->shape_rect_radio =
568                 glade_xml_get_widget (dlg->priv->gui, "shape_rect_radio");
569         dlg->priv->shape_round_radio =
570                 glade_xml_get_widget (dlg->priv->gui, "shape_round_radio");
571         dlg->priv->shape_cd_radio =
572                 glade_xml_get_widget (dlg->priv->gui, "shape_cd_radio");
573
574         construct_page_boilerplate (dlg,
575                                     GNOME_DRUID_PAGE_STANDARD(dlg->priv->shape_page),
576                                     logo);
577 }
578
579 /*--------------------------------------------------------------------------*/
580 /* PRIVATE.  Construct rect size page.                                      */
581 /*--------------------------------------------------------------------------*/
582 static void
583 construct_rect_size_page (glTemplateDesigner      *dlg,
584                           GdkPixbuf               *logo)
585 {
586         GdkPixbuf *pixbuf;
587
588         dlg->priv->rect_size_page =
589                 glade_xml_get_widget (dlg->priv->gui, "rect_size_page");
590
591         /* Rect Size Page Widgets */
592         dlg->priv->rect_image =
593                 glade_xml_get_widget (dlg->priv->gui, "rect_image");
594         dlg->priv->rect_w_spin =
595                 glade_xml_get_widget (dlg->priv->gui, "rect_w_spin");
596         dlg->priv->rect_h_spin =
597                 glade_xml_get_widget (dlg->priv->gui, "rect_h_spin");
598         dlg->priv->rect_r_spin =
599                 glade_xml_get_widget (dlg->priv->gui, "rect_r_spin");
600         dlg->priv->rect_x_waste_spin =
601                 glade_xml_get_widget (dlg->priv->gui, "rect_x_waste_spin");
602         dlg->priv->rect_y_waste_spin =
603                 glade_xml_get_widget (dlg->priv->gui, "rect_y_waste_spin");
604         dlg->priv->rect_margin_spin =
605                 glade_xml_get_widget (dlg->priv->gui, "rect_margin_spin");
606         dlg->priv->rect_w_units_label =
607                 glade_xml_get_widget (dlg->priv->gui, "rect_w_units_label");
608         dlg->priv->rect_h_units_label =
609                 glade_xml_get_widget (dlg->priv->gui, "rect_h_units_label");
610         dlg->priv->rect_r_units_label =
611                 glade_xml_get_widget (dlg->priv->gui, "rect_r_units_label");
612         dlg->priv->rect_x_waste_units_label =
613                 glade_xml_get_widget (dlg->priv->gui, "rect_x_waste_units_label");
614         dlg->priv->rect_y_waste_units_label =
615                 glade_xml_get_widget (dlg->priv->gui, "rect_y_waste_units_label");
616         dlg->priv->rect_margin_units_label =
617                 glade_xml_get_widget (dlg->priv->gui, "rect_margin_units_label");
618
619         /* Initialize illustration. */
620         pixbuf = gdk_pixbuf_new_from_file (EX_RECT_IMAGE, NULL);
621         gtk_image_set_from_pixbuf (GTK_IMAGE(dlg->priv->rect_image), pixbuf);
622
623         /* Apply units to spinbuttons and units labels. */
624         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->rect_w_spin),
625                                     dlg->priv->digits);
626         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->rect_w_spin),
627                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
628         gtk_label_set_text (GTK_LABEL(dlg->priv->rect_w_units_label),
629                             dlg->priv->units_string);
630         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->rect_h_spin),
631                                     dlg->priv->digits);
632         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->rect_h_spin),
633                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
634         gtk_label_set_text (GTK_LABEL(dlg->priv->rect_h_units_label),
635                             dlg->priv->units_string);
636         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->rect_r_spin),
637                                     dlg->priv->digits);
638         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->rect_r_spin),
639                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
640         gtk_label_set_text (GTK_LABEL(dlg->priv->rect_r_units_label),
641                             dlg->priv->units_string);
642         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->rect_x_waste_spin),
643                                     dlg->priv->digits);
644         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->rect_x_waste_spin),
645                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
646         gtk_label_set_text (GTK_LABEL(dlg->priv->rect_x_waste_units_label),
647                             dlg->priv->units_string);
648         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->rect_y_waste_spin),
649                                     dlg->priv->digits);
650         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->rect_y_waste_spin),
651                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
652         gtk_label_set_text (GTK_LABEL(dlg->priv->rect_y_waste_units_label),
653                             dlg->priv->units_string);
654         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->rect_margin_spin),
655                                     dlg->priv->digits);
656         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->rect_margin_spin),
657                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
658         gtk_label_set_text (GTK_LABEL(dlg->priv->rect_margin_units_label),
659                             dlg->priv->units_string);
660
661         /* Load some realistic defaults. */
662         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->rect_w_spin),
663                                    DEFAULT_RECT_W * dlg->priv->units_per_point);
664         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->rect_h_spin),
665                                    DEFAULT_RECT_H * dlg->priv->units_per_point);
666         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->rect_r_spin),
667                                    DEFAULT_RECT_R * dlg->priv->units_per_point);
668         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->rect_x_waste_spin),
669                                    DEFAULT_RECT_WASTE * dlg->priv->units_per_point);
670         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->rect_y_waste_spin),
671                                    DEFAULT_RECT_WASTE * dlg->priv->units_per_point);
672         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->rect_margin_spin),
673                                    DEFAULT_MARGIN * dlg->priv->units_per_point);
674
675         /* Handler to prepare the page. */
676         g_signal_connect_data (G_OBJECT(dlg->priv->rect_size_page), "prepare",
677                                G_CALLBACK(rect_size_page_prepare_cb), dlg,
678                                NULL, (G_CONNECT_AFTER|G_CONNECT_SWAPPED));
679
680         construct_page_boilerplate (dlg,
681                                     GNOME_DRUID_PAGE_STANDARD(dlg->priv->rect_size_page),
682                                     logo);
683 }
684
685 /*--------------------------------------------------------------------------*/
686 /* PRIVATE.  Construct round size page.                                     */
687 /*--------------------------------------------------------------------------*/
688 static void
689 construct_round_size_page (glTemplateDesigner      *dlg,
690                            GdkPixbuf               *logo)
691 {
692         GdkPixbuf *pixbuf;
693
694         dlg->priv->round_size_page =
695                 glade_xml_get_widget (dlg->priv->gui, "round_size_page");
696
697         /* Round Size Page Widgets */
698         dlg->priv->round_image =
699                 glade_xml_get_widget (dlg->priv->gui, "round_image");
700         dlg->priv->round_r_spin =
701                 glade_xml_get_widget (dlg->priv->gui, "round_r_spin");
702         dlg->priv->round_waste_spin =
703                 glade_xml_get_widget (dlg->priv->gui, "round_waste_spin");
704         dlg->priv->round_margin_spin =
705                 glade_xml_get_widget (dlg->priv->gui, "round_margin_spin");
706         dlg->priv->round_r_units_label =
707                 glade_xml_get_widget (dlg->priv->gui, "round_r_units_label");
708         dlg->priv->round_waste_units_label =
709                 glade_xml_get_widget (dlg->priv->gui, "round_waste_units_label");
710         dlg->priv->round_margin_units_label =
711                 glade_xml_get_widget (dlg->priv->gui, "round_margin_units_label");
712
713         /* Initialize illustration. */
714         pixbuf = gdk_pixbuf_new_from_file (EX_ROUND_IMAGE, NULL);
715         gtk_image_set_from_pixbuf (GTK_IMAGE(dlg->priv->round_image), pixbuf);
716
717         /* Apply units to spinbuttons and units labels. */
718         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->round_r_spin),
719                                     dlg->priv->digits);
720         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->round_r_spin),
721                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
722         gtk_label_set_text (GTK_LABEL(dlg->priv->round_r_units_label),
723                             dlg->priv->units_string);
724         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->round_waste_spin),
725                                     dlg->priv->digits);
726         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->round_waste_spin),
727                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
728         gtk_label_set_text (GTK_LABEL(dlg->priv->round_waste_units_label),
729                             dlg->priv->units_string);
730         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->round_margin_spin),
731                                     dlg->priv->digits);
732         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->round_margin_spin),
733                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
734         gtk_label_set_text (GTK_LABEL(dlg->priv->round_margin_units_label),
735                             dlg->priv->units_string);
736
737         /* Load some realistic defaults. */
738         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->round_r_spin),
739                                    DEFAULT_ROUND_R * dlg->priv->units_per_point);
740         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->round_waste_spin),
741                                    DEFAULT_ROUND_WASTE * dlg->priv->units_per_point);
742         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->round_margin_spin),
743                                    DEFAULT_MARGIN * dlg->priv->units_per_point);
744
745         /* Handler to prepare the page. */
746         g_signal_connect_data (G_OBJECT(dlg->priv->round_size_page), "prepare",
747                                G_CALLBACK(round_size_page_prepare_cb), dlg,
748                                NULL, (G_CONNECT_AFTER|G_CONNECT_SWAPPED));
749
750         construct_page_boilerplate (dlg,
751                                     GNOME_DRUID_PAGE_STANDARD(dlg->priv->round_size_page),
752                                     logo);
753 }
754
755 /*--------------------------------------------------------------------------*/
756 /* PRIVATE.  Construct CD/DVD size page.                                    */
757 /*--------------------------------------------------------------------------*/
758 static void
759 construct_cd_size_page (glTemplateDesigner      *dlg,
760                         GdkPixbuf               *logo)
761 {
762         GdkPixbuf *pixbuf;
763
764         dlg->priv->cd_size_page =
765                 glade_xml_get_widget (dlg->priv->gui, "cd_size_page");
766
767         /* Cd Size Page Widgets */
768         dlg->priv->cd_image =
769                 glade_xml_get_widget (dlg->priv->gui, "cd_image");
770         dlg->priv->cd_radius_spin =
771                 glade_xml_get_widget (dlg->priv->gui, "cd_radius_spin");
772         dlg->priv->cd_hole_spin =
773                 glade_xml_get_widget (dlg->priv->gui, "cd_hole_spin");
774         dlg->priv->cd_w_spin =
775                 glade_xml_get_widget (dlg->priv->gui, "cd_w_spin");
776         dlg->priv->cd_h_spin =
777                 glade_xml_get_widget (dlg->priv->gui, "cd_h_spin");
778         dlg->priv->cd_waste_spin =
779                 glade_xml_get_widget (dlg->priv->gui, "cd_waste_spin");
780         dlg->priv->cd_margin_spin =
781                 glade_xml_get_widget (dlg->priv->gui, "cd_margin_spin");
782         dlg->priv->cd_radius_units_label =
783                 glade_xml_get_widget (dlg->priv->gui, "cd_radius_units_label");
784         dlg->priv->cd_hole_units_label =
785                 glade_xml_get_widget (dlg->priv->gui, "cd_hole_units_label");
786         dlg->priv->cd_w_units_label =
787                 glade_xml_get_widget (dlg->priv->gui, "cd_w_units_label");
788         dlg->priv->cd_h_units_label =
789                 glade_xml_get_widget (dlg->priv->gui, "cd_h_units_label");
790         dlg->priv->cd_waste_units_label =
791                 glade_xml_get_widget (dlg->priv->gui, "cd_waste_units_label");
792         dlg->priv->cd_margin_units_label =
793                 glade_xml_get_widget (dlg->priv->gui, "cd_margin_units_label");
794
795         /* Initialize illustration. */
796         pixbuf = gdk_pixbuf_new_from_file (EX_CD_IMAGE, NULL);
797         gtk_image_set_from_pixbuf (GTK_IMAGE(dlg->priv->cd_image), pixbuf);
798
799         /* Apply units to spinbuttons and units labels. */
800         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->cd_radius_spin),
801                                     dlg->priv->digits);
802         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->cd_radius_spin),
803                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
804         gtk_label_set_text (GTK_LABEL(dlg->priv->cd_radius_units_label),
805                             dlg->priv->units_string);
806         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->cd_hole_spin),
807                                     dlg->priv->digits);
808         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->cd_hole_spin),
809                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
810         gtk_label_set_text (GTK_LABEL(dlg->priv->cd_hole_units_label),
811                             dlg->priv->units_string);
812         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->cd_w_spin),
813                                     dlg->priv->digits);
814         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->cd_w_spin),
815                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
816         gtk_label_set_text (GTK_LABEL(dlg->priv->cd_w_units_label),
817                             dlg->priv->units_string);
818         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->cd_h_spin),
819                                     dlg->priv->digits);
820         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->cd_h_spin),
821                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
822         gtk_label_set_text (GTK_LABEL(dlg->priv->cd_h_units_label),
823                             dlg->priv->units_string);
824         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->cd_waste_spin),
825                                     dlg->priv->digits);
826         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->cd_waste_spin),
827                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
828         gtk_label_set_text (GTK_LABEL(dlg->priv->cd_waste_units_label),
829                             dlg->priv->units_string);
830         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->cd_margin_spin),
831                                     dlg->priv->digits);
832         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->cd_margin_spin),
833                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
834         gtk_label_set_text (GTK_LABEL(dlg->priv->cd_margin_units_label),
835                             dlg->priv->units_string);
836
837         /* Load some realistic defaults. */
838         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->cd_radius_spin),
839                                    DEFAULT_CD_RADIUS * dlg->priv->units_per_point);
840         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->cd_hole_spin),
841                                    DEFAULT_CD_HOLE * dlg->priv->units_per_point);
842         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->cd_waste_spin),
843                                    DEFAULT_CD_WASTE * dlg->priv->units_per_point);
844         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->cd_margin_spin),
845                                    DEFAULT_MARGIN * dlg->priv->units_per_point);
846
847         /* Handler to prepare the page. */
848         g_signal_connect_data (G_OBJECT(dlg->priv->cd_size_page), "prepare",
849                                G_CALLBACK(cd_size_page_prepare_cb), dlg,
850                                NULL, (G_CONNECT_AFTER|G_CONNECT_SWAPPED));
851
852         construct_page_boilerplate (dlg,
853                                     GNOME_DRUID_PAGE_STANDARD(dlg->priv->cd_size_page),
854                                     logo);
855 }
856
857 /*--------------------------------------------------------------------------*/
858 /* PRIVATE.  Construct number of layouts page.                              */
859 /*--------------------------------------------------------------------------*/
860 static void
861 construct_nlayouts_page (glTemplateDesigner      *dlg,
862                          GdkPixbuf               *logo)
863 {
864         GdkPixbuf *pixbuf;
865
866         dlg->priv->nlayouts_page =
867                 glade_xml_get_widget (dlg->priv->gui, "nlayouts_page");
868
869         /* Widgets */
870         dlg->priv->nlayouts_image1 =
871                 glade_xml_get_widget (dlg->priv->gui, "nlayouts_image1");
872         dlg->priv->nlayouts_image2 =
873                 glade_xml_get_widget (dlg->priv->gui, "nlayouts_image2");
874         dlg->priv->nlayouts_spin =
875                 glade_xml_get_widget (dlg->priv->gui, "nlayouts_spin");
876
877         /* Initialize illustrations. */
878         pixbuf = gdk_pixbuf_new_from_file (EX_NLAYOUTS_IMAGE1, NULL);
879         gtk_image_set_from_pixbuf (GTK_IMAGE(dlg->priv->nlayouts_image1), pixbuf);
880         pixbuf = gdk_pixbuf_new_from_file (EX_NLAYOUTS_IMAGE2, NULL);
881         gtk_image_set_from_pixbuf (GTK_IMAGE(dlg->priv->nlayouts_image2), pixbuf);
882
883         construct_page_boilerplate (dlg,
884                                     GNOME_DRUID_PAGE_STANDARD(dlg->priv->nlayouts_page),
885                                     logo);
886 }
887
888 /*--------------------------------------------------------------------------*/
889 /* PRIVATE.  Construct layout page.                                         */
890 /*--------------------------------------------------------------------------*/
891 static void
892 construct_layout_page (glTemplateDesigner      *dlg,
893                        GdkPixbuf               *logo)
894 {
895         dlg->priv->layout_page =
896                 glade_xml_get_widget (dlg->priv->gui, "layout_page");
897
898         /* Page Size Page Widgets */
899         dlg->priv->layout1_head_label =
900                 glade_xml_get_widget (dlg->priv->gui, "layout1_head_label");
901         dlg->priv->layout1_nx_spin =
902                 glade_xml_get_widget (dlg->priv->gui, "layout1_nx_spin");
903         dlg->priv->layout1_ny_spin =
904                 glade_xml_get_widget (dlg->priv->gui, "layout1_ny_spin");
905         dlg->priv->layout1_x0_spin =
906                 glade_xml_get_widget (dlg->priv->gui, "layout1_x0_spin");
907         dlg->priv->layout1_y0_spin =
908                 glade_xml_get_widget (dlg->priv->gui, "layout1_y0_spin");
909         dlg->priv->layout1_dx_spin =
910                 glade_xml_get_widget (dlg->priv->gui, "layout1_dx_spin");
911         dlg->priv->layout1_dy_spin =
912                 glade_xml_get_widget (dlg->priv->gui, "layout1_dy_spin");
913         dlg->priv->layout2_head_label =
914                 glade_xml_get_widget (dlg->priv->gui, "layout2_head_label");
915         dlg->priv->layout2_nx_spin =
916                 glade_xml_get_widget (dlg->priv->gui, "layout2_nx_spin");
917         dlg->priv->layout2_ny_spin =
918                 glade_xml_get_widget (dlg->priv->gui, "layout2_ny_spin");
919         dlg->priv->layout2_x0_spin =
920                 glade_xml_get_widget (dlg->priv->gui, "layout2_x0_spin");
921         dlg->priv->layout2_y0_spin =
922                 glade_xml_get_widget (dlg->priv->gui, "layout2_y0_spin");
923         dlg->priv->layout2_dx_spin =
924                 glade_xml_get_widget (dlg->priv->gui, "layout2_dx_spin");
925         dlg->priv->layout2_dy_spin =
926                 glade_xml_get_widget (dlg->priv->gui, "layout2_dy_spin");
927         dlg->priv->layout_x0_units_label =
928                 glade_xml_get_widget (dlg->priv->gui, "layout_x0_units_label");
929         dlg->priv->layout_y0_units_label =
930                 glade_xml_get_widget (dlg->priv->gui, "layout_y0_units_label");
931         dlg->priv->layout_dx_units_label =
932                 glade_xml_get_widget (dlg->priv->gui, "layout_dx_units_label");
933         dlg->priv->layout_dy_units_label =
934                 glade_xml_get_widget (dlg->priv->gui, "layout_dy_units_label");
935         dlg->priv->layout_mini_preview =
936                 glade_xml_get_widget (dlg->priv->gui, "layout_mini_preview");
937         dlg->priv->layout_test_button =
938                 glade_xml_get_widget (dlg->priv->gui, "layout_test_button");
939
940         /* Apply units to spinbuttons and units labels. */
941         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->layout1_x0_spin),
942                                     dlg->priv->digits);
943         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->layout1_x0_spin),
944                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
945         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->layout2_x0_spin),
946                                     dlg->priv->digits);
947         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->layout2_x0_spin),
948                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
949         gtk_label_set_text (GTK_LABEL(dlg->priv->layout_x0_units_label),
950                             dlg->priv->units_string);
951         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->layout1_y0_spin),
952                                     dlg->priv->digits);
953         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->layout1_y0_spin),
954                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
955         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->layout2_y0_spin),
956                                     dlg->priv->digits);
957         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->layout2_y0_spin),
958                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
959         gtk_label_set_text (GTK_LABEL(dlg->priv->layout_y0_units_label),
960                             dlg->priv->units_string);
961         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->layout1_dx_spin),
962                                     dlg->priv->digits);
963         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->layout1_dx_spin),
964                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
965         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->layout2_dx_spin),
966                                     dlg->priv->digits);
967         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->layout2_dx_spin),
968                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
969         gtk_label_set_text (GTK_LABEL(dlg->priv->layout_dx_units_label),
970                             dlg->priv->units_string);
971         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->layout1_dy_spin),
972                                     dlg->priv->digits);
973         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->layout1_dy_spin),
974                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
975         gtk_spin_button_set_digits (GTK_SPIN_BUTTON(dlg->priv->layout2_dy_spin),
976                                     dlg->priv->digits);
977         gtk_spin_button_set_increments (GTK_SPIN_BUTTON(dlg->priv->layout2_dy_spin),
978                                         dlg->priv->climb_rate, 10.0*dlg->priv->climb_rate);
979         gtk_label_set_text (GTK_LABEL(dlg->priv->layout_dy_units_label),
980                             dlg->priv->units_string);
981
982         /* Adjust preview */
983         gl_wdgt_mini_preview_set_bg_color (GL_WDGT_MINI_PREVIEW(dlg->priv->layout_mini_preview),
984                                            CONTENTS_BG);
985
986         /* Connect a handler that listens for changes in these widgets */
987         /* This controls sensitivity of related widgets. */
988         g_signal_connect_swapped (G_OBJECT(dlg->priv->layout1_nx_spin), "changed",
989                                   G_CALLBACK(layout_page_changed_cb), dlg);
990         g_signal_connect_swapped (G_OBJECT(dlg->priv->layout1_ny_spin), "changed",
991                                   G_CALLBACK(layout_page_changed_cb), dlg);
992         g_signal_connect_swapped (G_OBJECT(dlg->priv->layout1_x0_spin), "changed",
993                                   G_CALLBACK(layout_page_changed_cb), dlg);
994         g_signal_connect_swapped (G_OBJECT(dlg->priv->layout1_y0_spin), "changed",
995                                   G_CALLBACK(layout_page_changed_cb), dlg);
996         g_signal_connect_swapped (G_OBJECT(dlg->priv->layout1_dx_spin), "changed",
997                                   G_CALLBACK(layout_page_changed_cb), dlg);
998         g_signal_connect_swapped (G_OBJECT(dlg->priv->layout1_dy_spin), "changed",
999                                   G_CALLBACK(layout_page_changed_cb), dlg);
1000         g_signal_connect_swapped (G_OBJECT(dlg->priv->layout2_nx_spin), "changed",
1001                                   G_CALLBACK(layout_page_changed_cb), dlg);
1002         g_signal_connect_swapped (G_OBJECT(dlg->priv->layout2_ny_spin), "changed",
1003                                   G_CALLBACK(layout_page_changed_cb), dlg);
1004         g_signal_connect_swapped (G_OBJECT(dlg->priv->layout2_x0_spin), "changed",
1005                                   G_CALLBACK(layout_page_changed_cb), dlg);
1006         g_signal_connect_swapped (G_OBJECT(dlg->priv->layout2_y0_spin), "changed",
1007                                   G_CALLBACK(layout_page_changed_cb), dlg);
1008         g_signal_connect_swapped (G_OBJECT(dlg->priv->layout2_dx_spin), "changed",
1009                                   G_CALLBACK(layout_page_changed_cb), dlg);
1010         g_signal_connect_swapped (G_OBJECT(dlg->priv->layout2_dy_spin), "changed",
1011                                   G_CALLBACK(layout_page_changed_cb), dlg);
1012
1013
1014         /* Print button */
1015         g_signal_connect_swapped (G_OBJECT(dlg->priv->layout_test_button), "clicked",
1016                                   G_CALLBACK(print_test_cb), dlg);
1017
1018         /* Handler to prepare the page. */
1019         g_signal_connect_data (G_OBJECT(dlg->priv->layout_page), "prepare",
1020                                G_CALLBACK(layout_page_prepare_cb), dlg,
1021                                NULL, (G_CONNECT_AFTER|G_CONNECT_SWAPPED));
1022
1023         construct_page_boilerplate (dlg,
1024                                     GNOME_DRUID_PAGE_STANDARD(dlg->priv->layout_page),
1025                                     logo);
1026 }
1027
1028 /*--------------------------------------------------------------------------*/
1029 /* PRIVATE.  Construct finish page.                                         */
1030 /*--------------------------------------------------------------------------*/
1031 static void
1032 construct_finish_page (glTemplateDesigner      *dlg,
1033                        GdkPixbuf               *logo)
1034 {
1035
1036         dlg->priv->finish_page =
1037                 glade_xml_get_widget (dlg->priv->gui, "finish_page");
1038
1039         /* Accept button */
1040         g_signal_connect_swapped (G_OBJECT(dlg->priv->finish_page), "finish",
1041                                   G_CALLBACK(finish_cb), dlg);
1042
1043         construct_edge_page_boilerplate (dlg,
1044                                          GNOME_DRUID_PAGE_EDGE(dlg->priv->start_page),
1045                                          logo);
1046 }
1047
1048 /*--------------------------------------------------------------------------*/
1049 /* PRIVATE.  Common construction tasks for start and finish page.           */
1050 /*--------------------------------------------------------------------------*/
1051 static void
1052 construct_edge_page_boilerplate (glTemplateDesigner      *dlg,
1053                                  GnomeDruidPageEdge      *page,
1054                                  GdkPixbuf               *logo)
1055 {
1056         gnome_druid_page_edge_set_logo (page, logo);
1057 }
1058
1059 /*--------------------------------------------------------------------------*/
1060 /* PRIVATE.  Common construction tasks for all other pages.                 */
1061 /*--------------------------------------------------------------------------*/
1062 static void
1063 construct_page_boilerplate (glTemplateDesigner      *dlg,
1064                             GnomeDruidPageStandard  *page,
1065                             GdkPixbuf               *logo)
1066 {
1067         gnome_druid_page_standard_set_logo (page, logo);
1068
1069         g_signal_connect (G_OBJECT(page), "next", G_CALLBACK(next_cb), dlg);
1070         g_signal_connect (G_OBJECT(page), "back", G_CALLBACK(back_cb), dlg);
1071 }
1072
1073 /*--------------------------------------------------------------------------*/
1074 /* PRIVATE.  Cancel druid.                                                  */
1075 /*--------------------------------------------------------------------------*/
1076 static void
1077 cancel_cb (glTemplateDesigner *dlg)
1078 {
1079                                                                                
1080         gtk_widget_destroy (GTK_WIDGET(dlg));
1081
1082 }
1083                          
1084 /*--------------------------------------------------------------------------*/
1085 /* PRIVATE.  Widget on name page "changed" callback.                        */
1086 /*--------------------------------------------------------------------------*/
1087 static void
1088 name_page_changed_cb (glTemplateDesigner *dlg)
1089 {
1090         gchar *brand, *part_num, *desc;
1091
1092         brand    = gtk_editable_get_chars (GTK_EDITABLE(dlg->priv->brand_entry), 0, -1);
1093         part_num = gtk_editable_get_chars (GTK_EDITABLE(dlg->priv->part_num_entry), 0, -1);
1094         desc     = gtk_editable_get_chars (GTK_EDITABLE(dlg->priv->description_entry), 0, -1);
1095
1096         if (brand && brand[0] && part_num && part_num[0] && desc && desc[0]) {
1097
1098                 gnome_druid_set_buttons_sensitive (GNOME_DRUID(dlg->priv->druid),
1099                                                    TRUE, TRUE, TRUE, FALSE);
1100
1101         } else {
1102
1103                 gnome_druid_set_buttons_sensitive (GNOME_DRUID(dlg->priv->druid),
1104                                                    TRUE, FALSE, TRUE, FALSE);
1105
1106         }
1107
1108         g_free (brand);
1109         g_free (part_num);
1110         g_free (desc);
1111
1112 }
1113                                                                                
1114 /*--------------------------------------------------------------------------*/
1115 /* PRIVATE.  Widget on page size page "changed" callback.                   */
1116 /*--------------------------------------------------------------------------*/
1117 static void
1118 pg_size_page_changed_cb (glTemplateDesigner *dlg)
1119 {
1120         gchar   *page_size_name;
1121         glPaper *paper;
1122         
1123
1124         page_size_name =
1125                 gtk_editable_get_chars (GTK_EDITABLE(dlg->priv->pg_size_entry), 0, -1);
1126
1127         if (page_size_name && strlen(page_size_name)) {
1128
1129                 paper = gl_paper_from_name (page_size_name);
1130         
1131
1132                 if ( g_strcasecmp (paper->id, "Other") == 0 ) {
1133                         gtk_widget_set_sensitive (GTK_WIDGET(dlg->priv->pg_w_spin), TRUE);
1134                         gtk_widget_set_sensitive (GTK_WIDGET(dlg->priv->pg_h_spin), TRUE);
1135                         gtk_widget_set_sensitive (GTK_WIDGET(dlg->priv->pg_w_units_label),
1136                                                   TRUE);
1137                         gtk_widget_set_sensitive (GTK_WIDGET(dlg->priv->pg_h_units_label),
1138                                                   TRUE);
1139
1140                 } else {
1141                         gtk_widget_set_sensitive (GTK_WIDGET(dlg->priv->pg_w_spin), FALSE);
1142                         gtk_widget_set_sensitive (GTK_WIDGET(dlg->priv->pg_h_spin), FALSE);
1143                         gtk_widget_set_sensitive (GTK_WIDGET(dlg->priv->pg_w_units_label),
1144                                                   FALSE);
1145                         gtk_widget_set_sensitive (GTK_WIDGET(dlg->priv->pg_h_units_label),
1146                                                   FALSE);
1147
1148                         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->pg_w_spin),
1149                                                    paper->width * dlg->priv->units_per_point);
1150                         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->pg_h_spin),
1151                                                    paper->height * dlg->priv->units_per_point);
1152                 }
1153
1154                 gl_paper_free (paper);
1155         }
1156
1157         g_free (page_size_name);
1158
1159 }
1160                                                                                
1161 /*--------------------------------------------------------------------------*/
1162 /* PRIVATE.  Prepare rectangular size page.                                 */
1163 /*--------------------------------------------------------------------------*/
1164 static void
1165 rect_size_page_prepare_cb (glTemplateDesigner *dlg)
1166 {
1167         gdouble max_w, max_h;
1168         gdouble w, h, r, x_waste, y_waste, margin;
1169
1170         /* Limit label size based on already chosen page size. */
1171         max_w = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->pg_w_spin));
1172         max_h = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->pg_h_spin));
1173
1174         w = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->rect_w_spin));
1175         h = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->rect_h_spin));
1176         r = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->rect_r_spin));
1177         x_waste = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->rect_x_waste_spin));
1178         y_waste = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->rect_y_waste_spin));
1179         margin = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->rect_margin_spin));
1180
1181         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->rect_w_spin),
1182                                    dlg->priv->climb_rate, max_w);
1183         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->rect_h_spin),
1184                                    dlg->priv->climb_rate, max_h);
1185         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->rect_r_spin),
1186                                    0.0, MIN(max_w, max_h)/2.0);
1187         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->rect_x_waste_spin),
1188                                    0.0, MIN(max_w, max_h)/4.0);
1189         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->rect_y_waste_spin),
1190                                    0.0, MIN(max_w, max_h)/4.0);
1191         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->rect_margin_spin),
1192                                    0.0, MIN(max_w, max_h)/4.0);
1193
1194         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->rect_w_spin), w);
1195         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->rect_h_spin), h);
1196         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->rect_r_spin), r);
1197         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->rect_x_waste_spin), x_waste);
1198         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->rect_y_waste_spin), y_waste);
1199         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->rect_margin_spin), margin);
1200
1201 }
1202
1203 /*--------------------------------------------------------------------------*/
1204 /* PRIVATE.  Prepare round size page.                                       */
1205 /*--------------------------------------------------------------------------*/
1206 static void
1207 round_size_page_prepare_cb (glTemplateDesigner *dlg)
1208 {
1209         gdouble max_w, max_h;
1210         gdouble r, waste, margin;
1211
1212         /* Limit label size based on already chosen page size. */
1213         max_w = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->pg_w_spin));
1214         max_h = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->pg_h_spin));
1215
1216         r = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->round_r_spin));
1217         waste  = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->round_waste_spin));
1218         margin = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->round_margin_spin));
1219
1220         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->round_r_spin),
1221                                    dlg->priv->climb_rate, MIN(max_w, max_h)/2.0);
1222         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->round_waste_spin),
1223                                    0.0, MIN(max_w, max_h)/4.0);
1224         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->round_margin_spin),
1225                                    0.0, MIN(max_w, max_h)/4.0);
1226
1227         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->round_r_spin), r);
1228         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->round_waste_spin), waste);
1229         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->round_margin_spin), margin);
1230
1231 }
1232
1233 /*--------------------------------------------------------------------------*/
1234 /* PRIVATE.  Prepare cd/dvd size page.                                      */
1235 /*--------------------------------------------------------------------------*/
1236 static void
1237 cd_size_page_prepare_cb (glTemplateDesigner *dlg)
1238 {
1239         gdouble max_w, max_h;
1240         gdouble radius, hole, w, h, waste, margin;
1241
1242         /* Limit label size based on already chosen page size. */
1243         max_w = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->pg_w_spin));
1244         max_h = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->pg_h_spin));
1245
1246         radius = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->cd_radius_spin));
1247         hole = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->cd_hole_spin));
1248         w = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->cd_w_spin));
1249         h = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->cd_h_spin));
1250         waste  = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->cd_waste_spin));
1251         margin = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->cd_margin_spin));
1252
1253         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->cd_radius_spin),
1254                                    dlg->priv->climb_rate, MIN(max_w, max_h)/2.0);
1255         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->cd_hole_spin),
1256                                    dlg->priv->climb_rate, MIN(max_w, max_h)/2.0);
1257         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->cd_w_spin),
1258                                    0.0, max_w);
1259         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->cd_h_spin),
1260                                    0.0, max_h);
1261         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->cd_waste_spin),
1262                                    0.0, MIN(max_w, max_h)/4.0);
1263         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->cd_margin_spin),
1264                                    0.0, MIN(max_w, max_h)/4.0);
1265
1266         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->cd_radius_spin), radius);
1267         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->cd_hole_spin), hole);
1268         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->cd_w_spin), w);
1269         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->cd_h_spin), h);
1270         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->cd_waste_spin), waste);
1271         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->cd_margin_spin), margin);
1272
1273 }
1274
1275 /*--------------------------------------------------------------------------*/
1276 /* PRIVATE.  Layout page widget changed cb.                                 */
1277 /*--------------------------------------------------------------------------*/
1278 static void
1279 layout_page_prepare_cb (glTemplateDesigner *dlg)
1280 {
1281         gdouble page_w, page_h;
1282         gdouble w, h, x_waste, y_waste;
1283         gint    max_nx, max_ny;
1284         gint    nlayouts;
1285         gdouble nx_1, ny_1, x0_1, y0_1, dx_1, dy_1;
1286         gdouble nx_2, ny_2, x0_2, y0_2, dx_2, dy_2;
1287
1288         g_signal_handlers_block_by_func (G_OBJECT(dlg->priv->layout1_nx_spin),
1289                                          G_CALLBACK(layout_page_changed_cb),
1290                                          G_OBJECT(dlg));
1291         g_signal_handlers_block_by_func (G_OBJECT(dlg->priv->layout1_ny_spin),
1292                                          G_CALLBACK(layout_page_changed_cb),
1293                                          G_OBJECT(dlg));
1294         g_signal_handlers_block_by_func (G_OBJECT(dlg->priv->layout1_x0_spin),
1295                                          G_CALLBACK(layout_page_changed_cb),
1296                                          G_OBJECT(dlg));
1297         g_signal_handlers_block_by_func (G_OBJECT(dlg->priv->layout1_y0_spin),
1298                                          G_CALLBACK(layout_page_changed_cb),
1299                                          G_OBJECT(dlg));
1300         g_signal_handlers_block_by_func (G_OBJECT(dlg->priv->layout1_dx_spin),
1301                                          G_CALLBACK(layout_page_changed_cb),
1302                                          G_OBJECT(dlg));
1303         g_signal_handlers_block_by_func (G_OBJECT(dlg->priv->layout1_dy_spin),
1304                                          G_CALLBACK(layout_page_changed_cb),
1305                                          G_OBJECT(dlg));
1306         g_signal_handlers_block_by_func (G_OBJECT(dlg->priv->layout2_nx_spin),
1307                                          G_CALLBACK(layout_page_changed_cb),
1308                                          G_OBJECT(dlg));
1309         g_signal_handlers_block_by_func (G_OBJECT(dlg->priv->layout2_ny_spin),
1310                                          G_CALLBACK(layout_page_changed_cb),
1311                                          G_OBJECT(dlg));
1312         g_signal_handlers_block_by_func (G_OBJECT(dlg->priv->layout2_x0_spin),
1313                                          G_CALLBACK(layout_page_changed_cb),
1314                                          G_OBJECT(dlg));
1315         g_signal_handlers_block_by_func (G_OBJECT(dlg->priv->layout2_y0_spin),
1316                                          G_CALLBACK(layout_page_changed_cb),
1317                                          G_OBJECT(dlg));
1318         g_signal_handlers_block_by_func (G_OBJECT(dlg->priv->layout2_dx_spin),
1319                                          G_CALLBACK(layout_page_changed_cb),
1320                                          G_OBJECT(dlg));
1321         g_signal_handlers_block_by_func (G_OBJECT(dlg->priv->layout2_dy_spin),
1322                                          G_CALLBACK(layout_page_changed_cb),
1323                                          G_OBJECT(dlg));
1324
1325         /* Limit ranges based on already chosen page and label sizes. */
1326         page_w = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->pg_w_spin));
1327         page_h = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->pg_h_spin));
1328         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(dlg->priv->shape_rect_radio))) {
1329                 w = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->rect_w_spin));
1330                 h = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->rect_h_spin));
1331                 x_waste = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->rect_x_waste_spin));
1332                 y_waste = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->rect_y_waste_spin));
1333         }
1334         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(dlg->priv->shape_round_radio))) {
1335                 w = 2*gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->round_r_spin));
1336                 h = w;
1337                 x_waste = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->round_waste_spin));
1338                 y_waste = x_waste;
1339         }
1340         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(dlg->priv->shape_cd_radio))) {
1341                 w = 2*gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->cd_radius_spin));
1342                 h = w;
1343                 x_waste = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->cd_waste_spin));
1344                 y_waste = x_waste;
1345         }
1346         max_nx = MAX (floor (page_w/(w + 2*x_waste) + DELTA), 1.0);
1347         max_ny = MAX (floor (page_h/(h + 2*y_waste) + DELTA), 1.0);
1348
1349         nx_1 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout1_nx_spin));
1350         ny_1 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout1_ny_spin));
1351         x0_1 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout1_x0_spin));
1352         y0_1 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout1_y0_spin));
1353         dx_1 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout1_dx_spin));
1354         dy_1 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout1_dy_spin));
1355         nx_2 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout2_nx_spin));
1356         ny_2 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout2_ny_spin));
1357         x0_2 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout2_x0_spin));
1358         y0_2 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout2_y0_spin));
1359         dx_2 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout2_dx_spin));
1360         dy_2 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout2_dy_spin));
1361
1362         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->layout1_nx_spin),
1363                                    1, max_nx);
1364         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->layout1_ny_spin),
1365                                    1, max_ny);
1366         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->layout1_x0_spin),
1367                                    x_waste, page_w - w - x_waste);
1368         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->layout1_y0_spin),
1369                                    y_waste, page_h - h - y_waste);
1370         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->layout1_dx_spin),
1371                                    w + 2*x_waste, page_w - w - 2*x_waste);
1372         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->layout1_dy_spin),
1373                                    h + 2*y_waste, page_h - h - 2*y_waste);
1374         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->layout2_nx_spin),
1375                                    1, max_nx);
1376         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->layout2_ny_spin),
1377                                    1, max_ny);
1378         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->layout2_x0_spin),
1379                                    x_waste, page_w - w - x_waste);
1380         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->layout2_y0_spin),
1381                                    y_waste, page_h - h - y_waste);
1382         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->layout2_dx_spin),
1383                                    w + 2*x_waste, page_w - w - 2*x_waste);
1384         gtk_spin_button_set_range (GTK_SPIN_BUTTON (dlg->priv->layout2_dy_spin),
1385                                    h + 2*y_waste, page_h - h - 2*y_waste);
1386
1387         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->layout1_nx_spin), nx_1);
1388         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->layout1_ny_spin), ny_1);
1389         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->layout1_x0_spin), x0_1);
1390         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->layout1_y0_spin), y0_1);
1391         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->layout1_dx_spin), dx_1);
1392         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->layout1_dy_spin), dy_1);
1393         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->layout2_nx_spin), nx_2);
1394         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->layout2_ny_spin), ny_2);
1395         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->layout2_x0_spin), x0_2);
1396         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->layout2_y0_spin), y0_2);
1397         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->layout2_dx_spin), dx_2);
1398         gtk_spin_button_set_value (GTK_SPIN_BUTTON(dlg->priv->layout2_dy_spin), dy_2);
1399
1400         /* Set visibility of layout2 widgets as appropriate. */
1401         nlayouts = gtk_spin_button_get_value (GTK_SPIN_BUTTON (dlg->priv->nlayouts_spin));
1402         if ( nlayouts == 1 ) {
1403
1404                 gtk_widget_hide (dlg->priv->layout1_head_label);
1405                 gtk_widget_hide (dlg->priv->layout2_head_label);
1406                 gtk_widget_hide (dlg->priv->layout2_nx_spin);
1407                 gtk_widget_hide (dlg->priv->layout2_ny_spin);
1408                 gtk_widget_hide (dlg->priv->layout2_x0_spin);
1409                 gtk_widget_hide (dlg->priv->layout2_y0_spin);
1410                 gtk_widget_hide (dlg->priv->layout2_dx_spin);
1411                 gtk_widget_hide (dlg->priv->layout2_dy_spin);
1412
1413         } else {
1414
1415                 gtk_widget_show (dlg->priv->layout1_head_label);
1416                 gtk_widget_show (dlg->priv->layout2_head_label);
1417                 gtk_widget_show (dlg->priv->layout2_nx_spin);
1418                 gtk_widget_show (dlg->priv->layout2_ny_spin);
1419                 gtk_widget_show (dlg->priv->layout2_x0_spin);
1420                 gtk_widget_show (dlg->priv->layout2_y0_spin);
1421                 gtk_widget_show (dlg->priv->layout2_dx_spin);
1422                 gtk_widget_show (dlg->priv->layout2_dy_spin);
1423
1424         }
1425
1426         g_signal_handlers_unblock_by_func (G_OBJECT(dlg->priv->layout1_nx_spin),
1427                                            G_CALLBACK(layout_page_changed_cb),
1428                                            G_OBJECT(dlg));
1429         g_signal_handlers_unblock_by_func (G_OBJECT(dlg->priv->layout1_ny_spin),
1430                                            G_CALLBACK(layout_page_changed_cb),
1431                                            G_OBJECT(dlg));
1432         g_signal_handlers_unblock_by_func (G_OBJECT(dlg->priv->layout1_x0_spin),
1433                                            G_CALLBACK(layout_page_changed_cb),
1434                                            G_OBJECT(dlg));
1435         g_signal_handlers_unblock_by_func (G_OBJECT(dlg->priv->layout1_y0_spin),
1436                                            G_CALLBACK(layout_page_changed_cb),
1437                                            G_OBJECT(dlg));
1438         g_signal_handlers_unblock_by_func (G_OBJECT(dlg->priv->layout1_dx_spin),
1439                                            G_CALLBACK(layout_page_changed_cb),
1440                                            G_OBJECT(dlg));
1441         g_signal_handlers_unblock_by_func (G_OBJECT(dlg->priv->layout1_dy_spin),
1442                                            G_CALLBACK(layout_page_changed_cb),
1443                                            G_OBJECT(dlg));
1444         g_signal_handlers_unblock_by_func (G_OBJECT(dlg->priv->layout2_nx_spin),
1445                                            G_CALLBACK(layout_page_changed_cb),
1446                                            G_OBJECT(dlg));
1447         g_signal_handlers_unblock_by_func (G_OBJECT(dlg->priv->layout2_ny_spin),
1448                                            G_CALLBACK(layout_page_changed_cb),
1449                                            G_OBJECT(dlg));
1450         g_signal_handlers_unblock_by_func (G_OBJECT(dlg->priv->layout2_x0_spin),
1451                                            G_CALLBACK(layout_page_changed_cb),
1452                                            G_OBJECT(dlg));
1453         g_signal_handlers_unblock_by_func (G_OBJECT(dlg->priv->layout2_y0_spin),
1454                                            G_CALLBACK(layout_page_changed_cb),
1455                                            G_OBJECT(dlg));
1456         g_signal_handlers_unblock_by_func (G_OBJECT(dlg->priv->layout2_dx_spin),
1457                                            G_CALLBACK(layout_page_changed_cb),
1458                                            G_OBJECT(dlg));
1459         g_signal_handlers_unblock_by_func (G_OBJECT(dlg->priv->layout2_dy_spin),
1460                                            G_CALLBACK(layout_page_changed_cb),
1461                                            G_OBJECT(dlg));
1462
1463         layout_page_changed_cb (dlg);
1464 }
1465
1466 /*--------------------------------------------------------------------------*/
1467 /* PRIVATE.  Layout page widget changed cb.                                 */
1468 /*--------------------------------------------------------------------------*/
1469 static void
1470 layout_page_changed_cb (glTemplateDesigner *dlg)
1471 {
1472         glTemplate *template;
1473
1474         template = build_template (dlg);
1475
1476         gl_wdgt_mini_preview_set_template (GL_WDGT_MINI_PREVIEW(dlg->priv->layout_mini_preview),
1477                                            template);
1478
1479         gl_template_free (template);
1480 }
1481
1482 /*--------------------------------------------------------------------------*/
1483 /* PRIVATE.  Print test sheet callback.                                     */
1484 /*--------------------------------------------------------------------------*/
1485 static void
1486 print_test_cb (glTemplateDesigner      *dlg)
1487 {
1488         GObject    *label;
1489         glTemplate *template;
1490         GtkWidget  *print_dialog;
1491
1492         label = gl_label_new ();
1493
1494         template = build_template (dlg);
1495         gl_label_set_template (GL_LABEL(label), template);
1496
1497         print_dialog = gl_print_dialog_new (GL_LABEL(label), NULL);
1498         gl_print_dialog_force_outline_flag (GL_PRINT_DIALOG(print_dialog));
1499         gtk_widget_show (print_dialog);
1500
1501         gl_template_free (template);
1502         g_object_unref (G_OBJECT(label));
1503 }
1504
1505 /*--------------------------------------------------------------------------*/
1506 /* PRIVATE.  Finish druid.                                                  */
1507 /*--------------------------------------------------------------------------*/
1508 static void
1509 finish_cb (glTemplateDesigner *dlg)
1510 {
1511         glTemplate *template;
1512         
1513         template = build_template (dlg);
1514         gl_template_register (template);
1515                                                                                
1516         gtk_widget_destroy (GTK_WIDGET(dlg));
1517
1518 }
1519                          
1520 /*--------------------------------------------------------------------------*/
1521 /* Build a template based on current druid settings.                        */
1522 /*--------------------------------------------------------------------------*/
1523 static glTemplate *
1524 build_template (glTemplateDesigner      *dlg)
1525 {
1526         gdouble               upp;
1527         gchar                *brand, *part_num, *name, *desc;
1528         gchar                *page_size_name;
1529         glPaper              *paper;
1530         glTemplateLabelShape  shape;
1531         glTemplateLabelType  *label_type;
1532         gdouble               w, h, r, radius, hole, waste, x_waste, y_waste, margin;
1533         gint                  nlayouts;
1534         gdouble               nx_1, ny_1, x0_1, y0_1, dx_1, dy_1;
1535         gdouble               nx_2, ny_2, x0_2, y0_2, dx_2, dy_2;
1536         glTemplate           *template;
1537
1538         upp = dlg->priv->units_per_point;
1539
1540         brand    = gtk_editable_get_chars (GTK_EDITABLE(dlg->priv->brand_entry), 0, -1);
1541         part_num = gtk_editable_get_chars (GTK_EDITABLE(dlg->priv->part_num_entry), 0, -1);
1542         name     = g_strdup_printf ("%s %s", brand, part_num);
1543         desc     = gtk_editable_get_chars (GTK_EDITABLE(dlg->priv->description_entry), 0, -1);
1544
1545         page_size_name =
1546                 gtk_editable_get_chars (GTK_EDITABLE(dlg->priv->pg_size_entry), 0, -1);
1547         paper = gl_paper_from_name (page_size_name);
1548         if ( g_strcasecmp (paper->id, "Other") == 0 ) {
1549                 paper->width =
1550                         gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->pg_w_spin))
1551                         / upp;
1552                 paper->height =
1553                         gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->pg_h_spin))
1554                          / upp;
1555         }
1556
1557         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(dlg->priv->shape_rect_radio))) {
1558                 shape = GL_TEMPLATE_SHAPE_RECT;
1559                 w = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->rect_w_spin));
1560                 h = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->rect_h_spin));
1561                 r = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->rect_r_spin));
1562                 x_waste = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->rect_x_waste_spin));
1563                 y_waste = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->rect_y_waste_spin));
1564                 margin = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->rect_margin_spin));
1565         }
1566
1567         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(dlg->priv->shape_round_radio))) {
1568                 shape = GL_TEMPLATE_SHAPE_ROUND;
1569                 r = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->round_r_spin));
1570                 waste = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->round_waste_spin));
1571                 margin = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->round_margin_spin));
1572         }
1573
1574         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(dlg->priv->shape_cd_radio))) {
1575                 shape = GL_TEMPLATE_SHAPE_CD;
1576                 radius = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->cd_radius_spin));
1577                 hole = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->cd_hole_spin));
1578                 w = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->cd_w_spin));
1579                 h = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->cd_h_spin));
1580                 waste = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->cd_waste_spin));
1581                 margin = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->cd_margin_spin));
1582         }
1583
1584         nlayouts = gtk_spin_button_get_value (GTK_SPIN_BUTTON (dlg->priv->nlayouts_spin));
1585         nx_1 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout1_nx_spin));
1586         ny_1 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout1_ny_spin));
1587         x0_1 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout1_x0_spin));
1588         y0_1 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout1_y0_spin));
1589         dx_1 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout1_dx_spin));
1590         dy_1 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout1_dy_spin));
1591         nx_2 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout2_nx_spin));
1592         ny_2 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout2_ny_spin));
1593         x0_2 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout2_x0_spin));
1594         y0_2 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout2_y0_spin));
1595         dx_2 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout2_dx_spin));
1596         dy_2 = gtk_spin_button_get_value (GTK_SPIN_BUTTON(dlg->priv->layout2_dy_spin));
1597
1598
1599         template = gl_template_new (name, desc, paper->id, paper->width, paper->height);
1600
1601         switch (shape) {
1602         case GL_TEMPLATE_SHAPE_RECT:
1603                 label_type =
1604                         gl_template_rect_label_type_new ("0",
1605                                                          w/upp, h/upp, r/upp,
1606                                                          x_waste/upp, y_waste/upp);
1607                 break;
1608         case GL_TEMPLATE_SHAPE_ROUND:
1609                 label_type =
1610                         gl_template_round_label_type_new ("0", r/upp, waste/upp);
1611                 break;
1612         case GL_TEMPLATE_SHAPE_CD:
1613                 label_type =
1614                         gl_template_cd_label_type_new ("0",
1615                                                        radius/upp, hole/upp,
1616                                                        w/upp, h/upp,
1617                                                        waste/upp);
1618                 break;
1619         }
1620         gl_template_add_label_type (template, label_type);
1621
1622         gl_template_add_markup (label_type,
1623                                 gl_template_markup_margin_new (margin/upp));
1624
1625         gl_template_add_layout (label_type,
1626                                 gl_template_layout_new (nx_1, ny_1,
1627                                                         x0_1/upp,
1628                                                         y0_1/upp,
1629                                                         dx_1/upp,
1630                                                         dy_1/upp));
1631         if (nlayouts > 1) {
1632                 gl_template_add_layout (label_type,
1633                                         gl_template_layout_new (nx_2, ny_2,
1634                                                                 x0_2/upp,
1635                                                                 y0_2/upp,
1636                                                                 dx_2/upp,
1637                                                                 dy_2/upp));
1638         }
1639
1640         g_free (brand);
1641         g_free (part_num);
1642         g_free (name);
1643         g_free (desc);
1644
1645         g_free (page_size_name);
1646         gl_paper_free (paper);
1647
1648         return template;
1649 }
1650
1651 /*--------------------------------------------------------------------------*/
1652 /* PRIVATE.  Handle non-linear forward traversal.                           */
1653 /*--------------------------------------------------------------------------*/
1654 static gboolean
1655 next_cb (GnomeDruidPage     *druidpage,
1656          GtkWidget          *widget,
1657          glTemplateDesigner *dlg)
1658 {
1659
1660         if ( GTK_WIDGET(druidpage) == dlg->priv->shape_page ) {
1661
1662                 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(dlg->priv->shape_rect_radio))) {
1663                         gnome_druid_set_page (GNOME_DRUID(dlg->priv->druid),
1664                                               GNOME_DRUID_PAGE(dlg->priv->rect_size_page));
1665                         return TRUE;
1666                 }
1667
1668                 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(dlg->priv->shape_round_radio))) {
1669                         gnome_druid_set_page (GNOME_DRUID(dlg->priv->druid),
1670                                               GNOME_DRUID_PAGE(dlg->priv->round_size_page));
1671                         return TRUE;
1672                 }
1673
1674                 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(dlg->priv->shape_cd_radio))) {
1675                         gnome_druid_set_page (GNOME_DRUID(dlg->priv->druid),
1676                                               GNOME_DRUID_PAGE(dlg->priv->cd_size_page));
1677                         return TRUE;
1678                 }
1679
1680         }
1681
1682         if ( GTK_WIDGET(druidpage) == dlg->priv->rect_size_page ) {
1683
1684                 gnome_druid_set_page (GNOME_DRUID(dlg->priv->druid),
1685                                       GNOME_DRUID_PAGE(dlg->priv->nlayouts_page));
1686                 return TRUE;
1687
1688         }
1689
1690         if ( GTK_WIDGET(druidpage) == dlg->priv->round_size_page ) {
1691
1692                 gnome_druid_set_page (GNOME_DRUID(dlg->priv->druid),
1693                                       GNOME_DRUID_PAGE(dlg->priv->nlayouts_page));
1694                 return TRUE;
1695
1696         }
1697
1698         if ( GTK_WIDGET(druidpage) == dlg->priv->cd_size_page ) {
1699
1700                 gnome_druid_set_page (GNOME_DRUID(dlg->priv->druid),
1701                                       GNOME_DRUID_PAGE(dlg->priv->nlayouts_page));
1702                 return TRUE;
1703
1704         }
1705
1706         /* Default case is linear. */
1707         return FALSE;
1708 }
1709
1710 /*--------------------------------------------------------------------------*/
1711 /* PRIVATE.  Handle non-linear reverse traversal.                           */
1712 /*--------------------------------------------------------------------------*/
1713 static gboolean
1714 back_cb (GnomeDruidPage     *druidpage,
1715          GtkWidget          *widget,
1716          glTemplateDesigner *dlg)
1717 {
1718
1719         if ( GTK_WIDGET(druidpage) == dlg->priv->rect_size_page ) {
1720
1721                 gnome_druid_set_page (GNOME_DRUID(dlg->priv->druid),
1722                                       GNOME_DRUID_PAGE(dlg->priv->shape_page));
1723                 return TRUE;
1724
1725         }
1726
1727         if ( GTK_WIDGET(druidpage) == dlg->priv->round_size_page ) {
1728
1729                 gnome_druid_set_page (GNOME_DRUID(dlg->priv->druid),
1730                                       GNOME_DRUID_PAGE(dlg->priv->shape_page));
1731                 return TRUE;
1732
1733         }
1734
1735         if ( GTK_WIDGET(druidpage) == dlg->priv->cd_size_page ) {
1736
1737                 gnome_druid_set_page (GNOME_DRUID(dlg->priv->druid),
1738                                       GNOME_DRUID_PAGE(dlg->priv->shape_page));
1739                 return TRUE;
1740
1741         }
1742
1743         if ( GTK_WIDGET(druidpage) == dlg->priv->nlayouts_page ) {
1744
1745                 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(dlg->priv->shape_rect_radio))) {
1746                         gnome_druid_set_page (GNOME_DRUID(dlg->priv->druid),
1747                                               GNOME_DRUID_PAGE(dlg->priv->rect_size_page));
1748                         return TRUE;
1749                 }
1750
1751                 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(dlg->priv->shape_round_radio))) {
1752                         gnome_druid_set_page (GNOME_DRUID(dlg->priv->druid),
1753                                               GNOME_DRUID_PAGE(dlg->priv->round_size_page));
1754                         return TRUE;
1755                 }
1756
1757                 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(dlg->priv->shape_cd_radio))) {
1758                         gnome_druid_set_page (GNOME_DRUID(dlg->priv->druid),
1759                                               GNOME_DRUID_PAGE(dlg->priv->cd_size_page));
1760                         return TRUE;
1761                 }
1762
1763         }
1764
1765         /* Default case is linear. */
1766         return FALSE;
1767 }
1768
1769 /*****************************************************************************/
1770 /* Construct mini preview widget.                                            */
1771 /*****************************************************************************/
1772 GtkWidget *
1773 gl_template_designer_construct_mini_preview (gchar *name,
1774                                              gchar *string1,
1775                                              gchar *string2,
1776                                              gint   int1,
1777                                              gint   int2)
1778 {
1779         gint width  = int1;
1780         gint height = int2;
1781
1782         return gl_wdgt_mini_preview_new (height, width);
1783 }
1784