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