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