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