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