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