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