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