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