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