]> git.sur5r.net Git - glabels/blob - glabels2/src/view.c
Fixed typo.
[glabels] / glabels2 / src / view.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  view.c:  GLabels View module
5  *
6  *  Copyright (C) 2001-2002  Jim Evins <evins@snaught.com>.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  */
22
23 #include <config.h>
24
25 #include <gtk/gtk.h>
26 #include <gtk/gtkinvisible.h>
27
28 #include <string.h>
29 #include <math.h>
30
31 #include "view.h"
32 #include "view-object.h"
33 #include "view-box.h"
34 #include "view-ellipse.h"
35 #include "view-line.h"
36 #include "view-image.h"
37 #include "view-text.h"
38 #include "view-barcode.h"
39 #include "xml-label.h"
40 #include "color.h"
41 #include "stock.h"
42 #include "merge-properties-dialog.h"
43 #include "prefs.h"
44 #include "marshal.h"
45
46 #include "debug.h"
47
48 /*==========================================================================*/
49 /* Private macros and constants.                                            */
50 /*==========================================================================*/
51
52 #define BG_COLOR        GL_COLOR (192, 192, 192)
53 #define OUTLINE_COLOR   GL_COLOR (173, 216, 230)
54 #define PAPER_COLOR     GL_COLOR (255, 255, 255)
55 #define GRID_COLOR      BG_COLOR
56 #define MARKUP_COLOR    GL_COLOR (240, 100, 100)
57
58 #define SEL_LINE_COLOR  GL_COLOR_A (0, 0, 255, 128)
59 #define SEL_FILL_COLOR  GL_COLOR_A (192, 192, 255, 128)
60
61 #define ARC_FINE         2 /* Resolution in degrees of large arcs */
62 #define ARC_COURSE       5 /* Resolution in degrees of small arcs */
63
64 /*==========================================================================*/
65 /* Private types.                                                           */
66 /*==========================================================================*/
67
68 enum {
69         SELECTION_CHANGED,
70         ZOOM_CHANGED,
71         POINTER_MOVED,
72         POINTER_EXIT,
73         MODE_CHANGED,
74         LAST_SIGNAL
75 };
76
77
78 /*==========================================================================*/
79 /* Private globals                                                          */
80 /*==========================================================================*/
81
82 static GtkContainerClass *parent_class;
83
84 static guint signals[LAST_SIGNAL] = {0};
85
86 /* "CLIPBOARD" selection */
87 static GdkAtom clipboard_atom = GDK_NONE;
88
89 static gdouble scales[] = {
90         8.0, 6.0, 4.0, 3.0,
91         2.0,
92         1.5, 1.0, 0.5, 0.25,
93 };
94 #define N_SCALES G_N_ELEMENTS(scales)
95 #define HOME_SCALE 2.0
96
97 /*==========================================================================*/
98 /* Local function prototypes                                                */
99 /*==========================================================================*/
100
101 static void       gl_view_class_init              (glViewClass *class);
102 static void       gl_view_init                    (glView *view);
103 static void       gl_view_finalize                (GObject *object);
104
105 static void       gl_view_construct               (glView *view);
106 static GtkWidget *gl_view_construct_canvas        (glView *view);
107 static void       gl_view_construct_selection     (glView *view);
108
109 static gdouble    get_apropriate_scale            (gdouble w, gdouble h);
110
111 static void       draw_layers                     (glView *view);
112
113 static void       label_resized_cb                (glLabel *label,
114                                                    glView *view);
115
116 static void       draw_label_layer                (glView *view);
117
118 static void       draw_highlight_layer            (glView *view);
119
120 static void       draw_bg_fg_layers               (glView *view);
121 static void       draw_bg_fg_rect                 (glView *view);
122 static void       draw_bg_fg_rounded_rect         (glView *view);
123 static void       draw_bg_fg_round                (glView *view);
124 static void       draw_bg_fg_cd                   (glView *view);
125 static void       draw_bg_fg_cd_bc                (glView *view);
126
127 static void       draw_grid_layer                 (glView *view);
128
129 static void       draw_markup_layer               (glView *view);
130
131 static void       draw_markup_margin              (glView *view,
132                                                    glTemplateMarkupMargin *margin);
133 static void       draw_markup_margin_rect         (glView *view,
134                                                    glTemplateMarkupMargin *margin);
135 static void       draw_markup_margin_rounded_rect (glView *view,
136                                                    glTemplateMarkupMargin *margin);
137 static void       draw_markup_margin_round        (glView *view,
138                                                    glTemplateMarkupMargin *margin);
139 static void       draw_markup_margin_cd           (glView *view,
140                                                    glTemplateMarkupMargin *margin);
141 static void       draw_markup_margin_cd_bc        (glView *view,
142                                                    glTemplateMarkupMargin *margin);
143
144 static void       draw_markup_line                (glView *view,
145                                                    glTemplateMarkupLine   *line);
146
147 static void       draw_markup_circle              (glView *view,
148                                                    glTemplateMarkupCircle *circle);
149
150
151 static void       select_object_real              (glView *view,
152                                                    glViewObject *view_object);
153 static void       unselect_object_real            (glView *view,
154                                                    glViewObject *view_object);
155
156 static gboolean   object_at                       (glView *view,
157                                                    gdouble x, gdouble y);
158
159 static gboolean   is_item_member_of_group         (glView          *view,
160                                                    GnomeCanvasItem *item,
161                                                    GnomeCanvasItem *group);
162
163 static int        canvas_event                    (GnomeCanvas *canvas,
164                                                    GdkEvent    *event,
165                                                    glView      *view);
166 static int        canvas_event_arrow_mode         (GnomeCanvas *canvas,
167                                                    GdkEvent    *event,
168                                                    glView      *view);
169
170 static void       construct_selection_menu       (glView *view);
171
172 static void       construct_empty_selection_menu (glView *view);
173
174 static void       selection_clear_cb             (GtkWidget         *widget,
175                                                   GdkEventSelection *event,
176                                                   gpointer          data);
177
178 static void       selection_get_cb               (GtkWidget         *widget,
179                                                   GtkSelectionData  *selection_data,
180                                                   guint             info,
181                                                   guint             time,
182                                                   gpointer          data);
183
184 static void       selection_received_cb          (GtkWidget         *widget,
185                                                   GtkSelectionData  *selection_data,
186                                                   guint             time,
187                                                   gpointer          data);
188 \f
189 /****************************************************************************/
190 /* Boilerplate Object stuff.                                                */
191 /****************************************************************************/
192 guint
193 gl_view_get_type (void)
194 {
195         static guint view_type = 0;
196
197         if (!view_type) {
198                 GTypeInfo view_info = {
199                         sizeof (glViewClass),
200                         NULL,
201                         NULL,
202                         (GClassInitFunc) gl_view_class_init,
203                         NULL,
204                         NULL,
205                         sizeof (glView),
206                         0,
207                         (GInstanceInitFunc) gl_view_init,
208                 };
209
210                 view_type =
211                     g_type_register_static (gtk_vbox_get_type (),
212                                             "glView", &view_info, 0);
213         }
214
215         return view_type;
216 }
217
218 static void
219 gl_view_class_init (glViewClass *class)
220 {
221         GObjectClass *object_class = (GObjectClass *) class;
222
223         gl_debug (DEBUG_VIEW, "START");
224
225         parent_class = g_type_class_peek_parent (class);
226
227         object_class->finalize = gl_view_finalize;
228
229         signals[SELECTION_CHANGED] =
230                 g_signal_new ("selection_changed",
231                               G_OBJECT_CLASS_TYPE (object_class),
232                               G_SIGNAL_RUN_LAST,
233                               G_STRUCT_OFFSET (glViewClass, selection_changed),
234                               NULL, NULL,
235                               gl_marshal_VOID__VOID,
236                               G_TYPE_NONE,
237                               0);
238
239         signals[ZOOM_CHANGED] =
240                 g_signal_new ("zoom_changed",
241                               G_OBJECT_CLASS_TYPE (object_class),
242                               G_SIGNAL_RUN_LAST,
243                               G_STRUCT_OFFSET (glViewClass, zoom_changed),
244                               NULL, NULL,
245                               gl_marshal_VOID__DOUBLE,
246                               G_TYPE_NONE,
247                               1, G_TYPE_DOUBLE);
248
249         signals[POINTER_MOVED] =
250                 g_signal_new ("pointer_moved",
251                               G_OBJECT_CLASS_TYPE (object_class),
252                               G_SIGNAL_RUN_LAST,
253                               G_STRUCT_OFFSET (glViewClass, pointer_moved),
254                               NULL, NULL,
255                               gl_marshal_VOID__DOUBLE_DOUBLE,
256                               G_TYPE_NONE,
257                               2, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
258
259         signals[POINTER_EXIT] =
260                 g_signal_new ("pointer_exit",
261                               G_OBJECT_CLASS_TYPE (object_class),
262                               G_SIGNAL_RUN_LAST,
263                               G_STRUCT_OFFSET (glViewClass, pointer_exit),
264                               NULL, NULL,
265                               gl_marshal_VOID__VOID,
266                               G_TYPE_NONE,
267                               0);
268
269         signals[MODE_CHANGED] =
270                 g_signal_new ("mode_changed",
271                               G_OBJECT_CLASS_TYPE (object_class),
272                               G_SIGNAL_RUN_LAST,
273                               G_STRUCT_OFFSET (glViewClass, mode_changed),
274                               NULL, NULL,
275                               gl_marshal_VOID__VOID,
276                               G_TYPE_NONE,
277                               0);
278
279         gl_debug (DEBUG_VIEW, "END");
280 }
281
282 static void
283 gl_view_init (glView *view)
284 {
285         gl_debug (DEBUG_VIEW, "START");
286
287         view->label = NULL;
288
289         view->grid_spacing = 9;
290
291         view->default_font_family = NULL;
292
293         gl_debug (DEBUG_VIEW, "END");
294 }
295
296 static void
297 gl_view_finalize (GObject *object)
298 {
299         glView *view;
300
301         gl_debug (DEBUG_VIEW, "START");
302
303         g_return_if_fail (object != NULL);
304         g_return_if_fail (GL_IS_VIEW (object));
305
306         view = GL_VIEW (object);
307
308         G_OBJECT_CLASS (parent_class)->finalize (object);
309
310         gl_debug (DEBUG_VIEW, "END");
311 }
312
313 /****************************************************************************/
314 /* NEW view object.                                                         */
315 /****************************************************************************/
316 GtkWidget *
317 gl_view_new (glLabel *label)
318 {
319         glView *view;
320
321         gl_debug (DEBUG_VIEW, "START");
322
323         g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
324
325         view = g_object_new (gl_view_get_type (), NULL);
326         view->label = label;
327
328         gl_view_construct (view);
329
330         gl_debug (DEBUG_VIEW, "END");
331
332         return GTK_WIDGET (view);
333 }
334
335 /*---------------------------------------------------------------------------*/
336 /* PRIVATE.  Construct composite widget.                                     */
337 /*---------------------------------------------------------------------------*/
338 static void
339 gl_view_construct (glView *view)
340 {
341         GtkWidget *wvbox, *wscroll;
342
343         gl_debug (DEBUG_VIEW, "START");
344
345         g_return_if_fail (GL_IS_VIEW (view));
346
347         wvbox = GTK_WIDGET (view);
348
349         view->state = GL_VIEW_STATE_ARROW;
350         view->object_list = NULL;
351
352         gl_view_construct_canvas (view);
353         wscroll = gtk_scrolled_window_new (NULL, NULL);
354         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (wscroll),
355                                         GTK_POLICY_AUTOMATIC,
356                                         GTK_POLICY_AUTOMATIC);
357         gtk_box_pack_start (GTK_BOX (wvbox), wscroll, TRUE, TRUE, 0);
358         gtk_container_add (GTK_CONTAINER (wscroll), view->canvas);
359
360         gl_view_construct_selection (view);
361
362         construct_selection_menu (view);
363         construct_empty_selection_menu (view);
364
365         gl_view_set_default_font_family      (view, gl_prefs->default_font_family);
366         gl_view_set_default_font_size        (view, gl_prefs->default_font_size);
367         gl_view_set_default_font_weight      (view, gl_prefs->default_font_weight);
368         gl_view_set_default_font_italic_flag (view, gl_prefs->default_font_italic_flag);
369         gl_view_set_default_text_color       (view, gl_prefs->default_text_color);
370         gl_view_set_default_text_alignment   (view, gl_prefs->default_text_alignment);
371         gl_view_set_default_line_width       (view, gl_prefs->default_line_width);
372         gl_view_set_default_line_color       (view, gl_prefs->default_line_color);
373         gl_view_set_default_fill_color       (view, gl_prefs->default_fill_color);
374
375         gl_debug (DEBUG_VIEW, "END");
376 }
377
378 /*---------------------------------------------------------------------------*/
379 /* PRIVATE.  Create canvas w/ a background in the shape of the label/card.   */
380 /*---------------------------------------------------------------------------*/
381 static GtkWidget *
382 gl_view_construct_canvas (glView *view)
383 {
384         gdouble   scale;
385         glLabel  *label;
386         gdouble   label_width, label_height;
387         GdkColor *bg_color;
388
389         gl_debug (DEBUG_VIEW, "START");
390
391         g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
392         g_return_val_if_fail (view->label && GL_IS_LABEL (view->label), NULL);
393
394         label = view->label;
395
396         gtk_widget_push_colormap (gdk_rgb_get_colormap ());
397         view->canvas = gnome_canvas_new_aa ();
398         gtk_widget_pop_colormap ();
399
400         bg_color = gl_color_to_gdk_color (BG_COLOR);
401         gtk_widget_modify_bg (GTK_WIDGET(view->canvas), GTK_STATE_NORMAL, bg_color);
402         g_free (bg_color);
403
404         gl_label_get_size (label, &label_width, &label_height);
405         gl_debug (DEBUG_VIEW, "Label size: w=%lf, h=%lf",
406                   label_width, label_height);
407
408         scale = get_apropriate_scale (label_width, label_height);
409         gl_debug (DEBUG_VIEW, "scale =%lf", scale);
410
411         gl_debug (DEBUG_VIEW, "Canvas size: w=%lf, h=%lf",
412                               scale * label_width + 40,
413                               scale * label_height + 40);
414         gtk_widget_set_size_request (GTK_WIDGET(view->canvas),
415                                      scale * label_width + 40,
416                                      scale * label_height + 40);
417         gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
418                                           scale);
419         view->scale = scale;
420
421         gnome_canvas_set_scroll_region (GNOME_CANVAS (view->canvas),
422                                         0.0, 0.0, label_width, label_height);
423
424         draw_layers (view);
425
426         g_signal_connect (G_OBJECT (view->canvas), "event",
427                           G_CALLBACK (canvas_event), view);
428
429         gl_debug (DEBUG_VIEW, "END");
430
431         return view->canvas;
432 }
433
434 /*---------------------------------------------------------------------------*/
435 /* PRIVATE.  Create clipboard selection targets.                             */
436 /*---------------------------------------------------------------------------*/
437 static void
438 gl_view_construct_selection (glView *view)
439 {
440         gl_debug (DEBUG_VIEW, "START");
441
442         g_return_if_fail (GL_IS_VIEW (view));
443
444         view->have_selection = FALSE;
445         view->selection_data = NULL;
446         view->invisible = gtk_invisible_new ();
447
448         view->selected_object_list = NULL;
449
450         if (!clipboard_atom) {
451                 clipboard_atom = gdk_atom_intern ("GLABELS_CLIPBOARD", FALSE);
452         }
453
454         gtk_selection_add_target (view->invisible,
455                                   clipboard_atom, GDK_SELECTION_TYPE_STRING, 1);
456
457         g_signal_connect (G_OBJECT (view->invisible),
458                           "selection_clear_event",
459                           G_CALLBACK (selection_clear_cb), view);
460
461         g_signal_connect (G_OBJECT (view->invisible), "selection_get",
462                           G_CALLBACK (selection_get_cb), view);
463
464         g_signal_connect (G_OBJECT (view->invisible),
465                           "selection_received",
466                           G_CALLBACK (selection_received_cb), view);
467
468         gl_debug (DEBUG_VIEW, "END");
469 }
470
471 /*---------------------------------------------------------------------------*/
472 /* PRIVATE.  Determine an apropriate scale for given label & screen size     */
473 /*---------------------------------------------------------------------------*/
474 static gdouble
475 get_apropriate_scale (gdouble w, gdouble h)
476 {
477         gdouble w_screen, h_screen;
478         gint i;
479         gdouble k;
480
481         gl_debug (DEBUG_VIEW, "");
482
483         w_screen = (gdouble) gdk_screen_width ();
484         h_screen = (gdouble) gdk_screen_height ();
485
486         for (i = 0; i < N_SCALES; i++) {
487                 k = scales[i];
488                 if (k <= HOME_SCALE) {
489                         if ((k * w < (w_screen - 256))
490                             && (k * h < (h_screen - 256)))
491                                 return k;
492                 }
493         }
494
495         return 0.25;
496 }
497
498 /*---------------------------------------------------------------------------*/
499 /* PRIVATE.  Create, draw and order layers.                                  */
500 /*---------------------------------------------------------------------------*/
501 static void
502 draw_layers (glView *view)
503 {
504         g_return_if_fail (view && GL_IS_VIEW (view));
505         g_return_if_fail (view->label && GL_IS_LABEL (view->label));
506
507         draw_bg_fg_layers (view);
508         draw_grid_layer (view);
509         draw_markup_layer (view);
510         draw_highlight_layer (view); /* Must be done before label layer */
511         draw_label_layer (view);
512
513         gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->fg_group));
514         gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->highlight_group));
515
516         g_signal_connect (G_OBJECT (view->label), "size_changed",
517                           G_CALLBACK (label_resized_cb), view);
518 }
519
520 /*---------------------------------------------------------------------------*/
521 /* PRIVATE.  Handle label resize event.   .                                  */
522 /*---------------------------------------------------------------------------*/
523 static void
524 label_resized_cb (glLabel *label,
525                   glView *view)
526 {
527         g_return_if_fail (label && GL_IS_LABEL (label));
528         g_return_if_fail (view && GL_IS_VIEW (view));
529
530         gtk_object_destroy (GTK_OBJECT (view->bg_group));
531         gtk_object_destroy (GTK_OBJECT (view->grid_group));
532         gtk_object_destroy (GTK_OBJECT (view->markup_group));
533         gtk_object_destroy (GTK_OBJECT (view->fg_group));
534
535         draw_bg_fg_layers (view);
536         draw_grid_layer (view);
537         draw_markup_layer (view);
538
539         gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->label_group));
540         gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->fg_group));
541         gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->highlight_group));
542 }
543
544 /*---------------------------------------------------------------------------*/
545 /* PRIVATE.  Draw label layer.                                               */
546 /*---------------------------------------------------------------------------*/
547 static void
548 draw_label_layer (glView *view)
549 {
550         GnomeCanvasGroup *group;
551         glLabel          *label;
552         GList            *p_obj;
553         glLabelObject    *object;
554         glViewObject     *view_object;
555
556         g_return_if_fail (view && GL_IS_VIEW (view));
557         g_return_if_fail (view->label && GL_IS_LABEL (view->label));
558
559         group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
560         view->label_group = GNOME_CANVAS_GROUP(
561                 gnome_canvas_item_new (group,
562                                        gnome_canvas_group_get_type (),
563                                        "x", 0.0,
564                                        "y", 0.0,
565                                        NULL));
566
567         label = view->label;
568
569         for (p_obj = label->objects; p_obj != NULL; p_obj = p_obj->next) {
570                 object = (glLabelObject *) p_obj->data;
571
572                 if (GL_IS_LABEL_BOX (object)) {
573                         view_object = gl_view_box_new (GL_LABEL_BOX(object),
574                                                        view);
575                 } else if (GL_IS_LABEL_ELLIPSE (object)) {
576                         view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object),
577                                                            view);
578                 } else if (GL_IS_LABEL_LINE (object)) {
579                         view_object = gl_view_line_new (GL_LABEL_LINE(object),
580                                                         view);
581                 } else if (GL_IS_LABEL_IMAGE (object)) {
582                         view_object = gl_view_image_new (GL_LABEL_IMAGE(object),
583                                                          view);
584                 } else if (GL_IS_LABEL_TEXT (object)) {
585                         view_object = gl_view_text_new (GL_LABEL_TEXT(object),
586                                                         view);
587                 } else if (GL_IS_LABEL_BARCODE (object)) {
588                         view_object = gl_view_barcode_new (GL_LABEL_BARCODE(object),
589                                                            view);
590                 } else {
591                         /* Should not happen! */
592                         view_object = NULL;
593                         g_warning ("Invalid label object type.");
594                 }
595         }
596 }
597
598 /*---------------------------------------------------------------------------*/
599 /* PRIVATE.  Create highlight layer.                                         */
600 /*---------------------------------------------------------------------------*/
601 static void
602 draw_highlight_layer (glView *view)
603 {
604         GnomeCanvasGroup *group;
605
606         g_return_if_fail (view && GL_IS_VIEW (view));
607
608         group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
609         view->highlight_group = GNOME_CANVAS_GROUP(
610                 gnome_canvas_item_new (group,
611                                        gnome_canvas_group_get_type (),
612                                        "x", 0.0,
613                                        "y", 0.0,
614                                        NULL));
615 }
616
617 /*---------------------------------------------------------------------------*/
618 /* PRIVATE.  Draw background and foreground outlines.                        */
619 /*---------------------------------------------------------------------------*/
620 static void
621 draw_bg_fg_layers (glView *view)
622 {
623         glLabel          *label;
624         glTemplate       *template;
625         GnomeCanvasGroup *group;
626
627         g_return_if_fail (view && GL_IS_VIEW (view));
628         g_return_if_fail (view->label && GL_IS_LABEL (view->label));
629
630         group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
631         view->bg_group = GNOME_CANVAS_GROUP(
632                 gnome_canvas_item_new (group,
633                                        gnome_canvas_group_get_type (),
634                                        "x", 0.0,
635                                        "y", 0.0,
636                                        NULL));
637         view->fg_group = GNOME_CANVAS_GROUP(
638                 gnome_canvas_item_new (group,
639                                        gnome_canvas_group_get_type (),
640                                        "x", 0.0,
641                                        "y", 0.0,
642                                        NULL));
643
644         label    = view->label;
645         template = gl_label_get_template (label);
646
647         switch (template->label.style) {
648
649         case GL_TEMPLATE_STYLE_RECT:
650                 if (template->label.rect.r == 0.0) {
651                         /* Square corners. */
652                         draw_bg_fg_rect (view);
653                 } else {
654                         /* Rounded corners. */
655                         draw_bg_fg_rounded_rect (view);
656                 }
657                 break;
658
659         case GL_TEMPLATE_STYLE_ROUND:
660                 draw_bg_fg_round (view);
661                 break;
662
663         case GL_TEMPLATE_STYLE_CD:
664                 if ((template->label.cd.w == 0.0) && (template->label.cd.h == 0.0) ) {
665                         draw_bg_fg_cd (view);
666                 } else {
667                         draw_bg_fg_cd_bc (view);
668                 }
669                 break;
670
671         default:
672                 g_warning ("Unknown template label style");
673                 break;
674         }
675 }
676
677 /*---------------------------------------------------------------------------*/
678 /* PRIVATE.  Draw simple recangular background.                              */
679 /*---------------------------------------------------------------------------*/
680 static void
681 draw_bg_fg_rect (glView *view)
682 {
683         glLabel          *label;
684         glTemplate       *template;
685         gdouble           w, h;
686         GnomeCanvasItem  *item;
687
688         gl_debug (DEBUG_VIEW, "START");
689
690         g_return_if_fail (view && GL_IS_VIEW (view));
691         g_return_if_fail (view->label && GL_IS_LABEL (view->label));
692
693         label = view->label;
694
695         gl_label_get_size (label, &w, &h);
696         template = gl_label_get_template (label);
697
698         /* Background */
699         item = gnome_canvas_item_new (view->bg_group,
700                                       gnome_canvas_rect_get_type (),
701                                       "x1", 0.0,
702                                       "y1", 0.0,
703                                       "x2", w,
704                                       "y2", h,
705                                       "fill_color_rgba", PAPER_COLOR,
706                                       NULL);
707
708         /* Foreground */
709         item = gnome_canvas_item_new (view->fg_group,
710                                       gnome_canvas_rect_get_type (),
711                                       "x1", 0.0,
712                                       "y1", 0.0,
713                                       "x2", w,
714                                       "y2", h,
715                                       "width_pixels", 2,
716                                       "outline_color_rgba", OUTLINE_COLOR,
717                                       NULL);
718
719         gl_debug (DEBUG_VIEW, "END");
720 }
721
722 /*---------------------------------------------------------------------------*/
723 /* PRIVATE.  Draw rounded recangular background.                             */
724 /*---------------------------------------------------------------------------*/
725 static void
726 draw_bg_fg_rounded_rect (glView *view)
727 {
728         glLabel           *label;
729         GnomeCanvasPoints *points;
730         gint               i_coords, i_theta;
731         glTemplate        *template;
732         gdouble            r, w, h;
733         GnomeCanvasItem   *item;
734
735         gl_debug (DEBUG_VIEW, "START");
736
737         g_return_if_fail (view && GL_IS_VIEW (view));
738         g_return_if_fail (view->label && GL_IS_LABEL (view->label));
739
740         label = view->label;
741
742         gl_label_get_size (label, &w, &h);
743         template = gl_label_get_template (label);
744         r = template->label.rect.r;
745
746         points = gnome_canvas_points_new (4 * (1 + 90 / ARC_COURSE));
747         i_coords = 0;
748         for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
749                 points->coords[i_coords++] =
750                     r - r * sin (i_theta * G_PI / 180.0);
751                 points->coords[i_coords++] =
752                     r - r * cos (i_theta * G_PI / 180.0);
753         }
754         for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
755                 points->coords[i_coords++] =
756                     r - r * cos (i_theta * G_PI / 180.0);
757                 points->coords[i_coords++] =
758                     (h - r) + r * sin (i_theta * G_PI / 180.0);
759         }
760         for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
761                 points->coords[i_coords++] =
762                     (w - r) + r * sin (i_theta * G_PI / 180.0);
763                 points->coords[i_coords++] =
764                     (h - r) + r * cos (i_theta * G_PI / 180.0);
765         }
766         for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
767                 points->coords[i_coords++] =
768                     (w - r) + r * cos (i_theta * G_PI / 180.0);
769                 points->coords[i_coords++] =
770                     r - r * sin (i_theta * G_PI / 180.0);
771         }
772
773         /* Background */
774         item = gnome_canvas_item_new (view->bg_group,
775                                       gnome_canvas_polygon_get_type (),
776                                       "points", points,
777                                       "fill_color_rgba", PAPER_COLOR,
778                                       NULL);
779
780         /* Foreground */
781         item = gnome_canvas_item_new (view->fg_group,
782                                       gnome_canvas_polygon_get_type (),
783                                       "points", points,
784                                       "width_pixels", 2,
785                                       "outline_color_rgba", OUTLINE_COLOR,
786                                       NULL);
787
788         gnome_canvas_points_free (points);
789
790         gl_debug (DEBUG_VIEW, "END");
791 }
792
793 /*---------------------------------------------------------------------------*/
794 /* PRIVATE.  Draw round background.                                          */
795 /*---------------------------------------------------------------------------*/
796 static void
797 draw_bg_fg_round (glView *view)
798 {
799         glLabel          *label;
800         glTemplate       *template;
801         gdouble           r;
802         GnomeCanvasItem  *item;
803
804         gl_debug (DEBUG_VIEW, "START");
805
806         g_return_if_fail (view && GL_IS_VIEW (view));
807         g_return_if_fail (view->label && GL_IS_LABEL(view->label));
808
809         label    = view->label;
810         template = gl_label_get_template (label);
811
812         r = template->label.round.r;
813
814         /* Background */
815         item = gnome_canvas_item_new (view->bg_group,
816                                       gnome_canvas_ellipse_get_type (),
817                                       "x1", 0.0,
818                                       "y1", 0.0,
819                                       "x2", 2.0*r,
820                                       "y2", 2.0*r,
821                                       "fill_color_rgba", PAPER_COLOR,
822                                       NULL);
823
824         /* Foreground */
825         item = gnome_canvas_item_new (view->fg_group,
826                                       gnome_canvas_ellipse_get_type (),
827                                       "x1", 0.0,
828                                       "y1", 0.0,
829                                       "x2", 2.0*r,
830                                       "y2", 2.0*r,
831                                       "width_pixels", 2,
832                                       "outline_color_rgba", OUTLINE_COLOR,
833                                       NULL);
834
835         gl_debug (DEBUG_VIEW, "END");
836 }
837
838 /*---------------------------------------------------------------------------*/
839 /* PRIVATE.  Draw CD style background, circular w/ concentric hole.          */
840 /*---------------------------------------------------------------------------*/
841 static void
842 draw_bg_fg_cd (glView *view)
843 {
844         glLabel          *label;
845         glTemplate       *template;
846         gdouble           r1, r2;
847         GnomeCanvasItem  *item;
848
849         gl_debug (DEBUG_VIEW, "START");
850
851         g_return_if_fail (view && GL_IS_VIEW (view));
852         g_return_if_fail (view->label && GL_IS_LABEL (view->label));
853
854         label    = view->label;
855         template = gl_label_get_template (label);
856
857         r1 = template->label.cd.r1;
858         r2 = template->label.cd.r2;
859
860         /* Background */
861         /* outer circle */
862         item = gnome_canvas_item_new (view->bg_group,
863                                       gnome_canvas_ellipse_get_type (),
864                                       "x1", 0.0,
865                                       "y1", 0.0,
866                                       "x2", 2.0*r1,
867                                       "y2", 2.0*r1,
868                                       "fill_color_rgba", PAPER_COLOR,
869                                       NULL);
870         /* hole */
871         item = gnome_canvas_item_new (view->bg_group,
872                                       gnome_canvas_ellipse_get_type (),
873                                       "x1", r1 - r2,
874                                       "y1", r1 - r2,
875                                       "x2", r1 + r2,
876                                       "y2", r1 + r2,
877                                       "fill_color_rgba", GRID_COLOR,
878                                       NULL);
879
880         /* Foreground */
881         /* outer circle */
882         item = gnome_canvas_item_new (view->fg_group,
883                                       gnome_canvas_ellipse_get_type (),
884                                       "x1", 0.0,
885                                       "y1", 0.0,
886                                       "x2", 2.0*r1,
887                                       "y2", 2.0*r1,
888                                       "width_pixels", 2,
889                                       "outline_color_rgba", OUTLINE_COLOR,
890                                       NULL);
891         /* hole */
892         item = gnome_canvas_item_new (view->fg_group,
893                                       gnome_canvas_ellipse_get_type (),
894                                       "x1", r1 - r2,
895                                       "y1", r1 - r2,
896                                       "x2", r1 + r2,
897                                       "y2", r1 + r2,
898                                       "width_pixels", 2,
899                                       "outline_color_rgba", OUTLINE_COLOR,
900                                       NULL);
901
902         gl_debug (DEBUG_VIEW, "END");
903 }
904
905 /*---------------------------------------------------------------------------*/
906 /* PRIVATE.  Draw Business Card CD style background, CD w/ chopped ends.     */
907 /*---------------------------------------------------------------------------*/
908 static void
909 draw_bg_fg_cd_bc (glView *view)
910 {
911         glLabel           *label;
912         glTemplate        *template;
913         GnomeCanvasPoints *points;
914         gint               i_coords, i_theta;
915         gdouble            theta1, theta2;
916         gdouble            x0, y0, w, h, r1, r2;
917         GnomeCanvasItem   *item;
918
919         gl_debug (DEBUG_VIEW, "START");
920
921         g_return_if_fail (view && GL_IS_VIEW (view));
922         g_return_if_fail (view->label && GL_IS_LABEL (view->label));
923
924         label    = view->label;
925
926         template = gl_label_get_template (label);
927         gl_label_get_size (label, &w, &h);
928         x0 = w/2.0;
929         y0 = h/2.0;
930
931         r1 = template->label.cd.r1;
932         r2 = template->label.cd.r2;
933
934         theta1 = (180.0/G_PI) * acos (w / (2.0*r1));
935         theta2 = (180.0/G_PI) * asin (h / (2.0*r1));
936
937         points = gnome_canvas_points_new (360/ARC_FINE + 1);
938         i_coords = 0;
939
940         points->coords[i_coords++] = x0 + r1 * cos (theta1 * G_PI / 180.0);
941         points->coords[i_coords++] = y0 + r1 * sin (theta1 * G_PI / 180.0);
942
943         for ( i_theta = theta1 + ARC_FINE; i_theta < theta2; i_theta +=ARC_FINE ) {
944                 points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
945                 points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
946         }
947
948         points->coords[i_coords++] = x0 + r1 * cos (theta2 * G_PI / 180.0);
949         points->coords[i_coords++] = y0 + r1 * sin (theta2 * G_PI / 180.0);
950
951
952         if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
953                 points->coords[i_coords++] = x0 + r1 * cos ((180-theta2) * G_PI / 180.0);
954                 points->coords[i_coords++] = y0 + r1 * sin ((180-theta2) * G_PI / 180.0);
955         }
956
957         for ( i_theta = 180-theta2+ARC_FINE; i_theta < (180-theta1); i_theta +=ARC_FINE ) {
958                 points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
959                 points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
960         }
961
962         points->coords[i_coords++] = x0 + r1 * cos ((180-theta1) * G_PI / 180.0);
963         points->coords[i_coords++] = y0 + r1 * sin ((180-theta1) * G_PI / 180.0);
964
965         if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
966                 points->coords[i_coords++] = x0 + r1 * cos ((180+theta1) * G_PI / 180.0);
967                 points->coords[i_coords++] = y0 + r1 * sin ((180+theta1) * G_PI / 180.0);
968         }
969
970         for ( i_theta = 180+theta1+ARC_FINE; i_theta < (180+theta2); i_theta +=ARC_FINE ) {
971                 points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
972                 points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
973         }
974
975         points->coords[i_coords++] = x0 + r1 * cos ((180+theta2) * G_PI / 180.0);
976         points->coords[i_coords++] = y0 + r1 * sin ((180+theta2) * G_PI / 180.0);
977
978         if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
979                 points->coords[i_coords++] = x0 + r1 * cos ((360-theta2) * G_PI / 180.0);
980                 points->coords[i_coords++] = y0 + r1 * sin ((360-theta2) * G_PI / 180.0);
981         }
982
983         for ( i_theta = 360-theta2+ARC_FINE; i_theta < (360-theta1); i_theta +=ARC_FINE ) {
984                 points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
985                 points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
986         }
987
988         if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
989                 points->coords[i_coords++] = x0 + r1 * cos ((360-theta1) * G_PI / 180.0);
990                 points->coords[i_coords++] = y0 + r1 * sin ((360-theta1) * G_PI / 180.0);
991         }
992
993         points->num_points = i_coords / 2;
994
995         /* Background */
996         /* outer circle */
997         item = gnome_canvas_item_new (view->bg_group,
998                                       gnome_canvas_polygon_get_type (),
999                                       "points", points,
1000                                       "fill_color_rgba", PAPER_COLOR,
1001                                       NULL);
1002         /* hole */
1003         item = gnome_canvas_item_new (view->bg_group,
1004                                       gnome_canvas_ellipse_get_type (),
1005                                       "x1", x0 - r2,
1006                                       "y1", y0 - r2,
1007                                       "x2", x0 + r2,
1008                                       "y2", y0 + r2,
1009                                       "fill_color_rgba", GRID_COLOR,
1010                                       NULL);
1011
1012         /* Foreground */
1013         /* outer circle */
1014         item = gnome_canvas_item_new (view->fg_group,
1015                                       gnome_canvas_polygon_get_type (),
1016                                       "points", points,
1017                                       "width_pixels", 2,
1018                                       "outline_color_rgba", OUTLINE_COLOR,
1019                                       NULL);
1020         /* hole */
1021         item = gnome_canvas_item_new (view->fg_group,
1022                                       gnome_canvas_ellipse_get_type (),
1023                                       "x1", x0 - r2,
1024                                       "y1", y0 - r2,
1025                                       "x2", x0 + r2,
1026                                       "y2", y0 + r2,
1027                                       "width_pixels", 2,
1028                                       "outline_color_rgba", OUTLINE_COLOR,
1029                                       NULL);
1030
1031         gnome_canvas_points_free (points);
1032
1033         gl_debug (DEBUG_VIEW, "END");
1034 }
1035
1036 /*---------------------------------------------------------------------------*/
1037 /* PRIVATE.  Draw grid lines.                                                */
1038 /*---------------------------------------------------------------------------*/
1039 static void
1040 draw_grid_layer (glView *view)
1041 {
1042         gdouble            w, h, x, y;
1043         GnomeCanvasPoints *points;
1044         GnomeCanvasItem  *item;
1045         GnomeCanvasGroup *group;
1046
1047         gl_debug (DEBUG_VIEW, "START");
1048
1049         g_return_if_fail (view && GL_IS_VIEW (view));
1050         g_return_if_fail (view->label && GL_IS_LABEL(view->label));
1051
1052         gl_label_get_size (view->label, &w, &h);
1053
1054         group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
1055         view->grid_group = GNOME_CANVAS_GROUP(
1056                 gnome_canvas_item_new (group,
1057                                        gnome_canvas_group_get_type (),
1058                                        "x", 0.0,
1059                                        "y", 0.0,
1060                                        NULL));
1061         points = gnome_canvas_points_new (2);
1062
1063         points->coords[1] = 0.0;
1064         points->coords[3] = h;
1065         for ( x=0.0; x < w; x += view->grid_spacing ) {
1066                 points->coords[0] = points->coords[2] = x;
1067                 item = gnome_canvas_item_new (view->grid_group,
1068                                               gnome_canvas_line_get_type (),
1069                                               "points", points,
1070                                               "width_pixels", 1,
1071                                               "fill_color_rgba", GRID_COLOR,
1072                                               NULL);
1073         }
1074         points->coords[0] = points->coords[2] = w;
1075         item = gnome_canvas_item_new (view->grid_group,
1076                                       gnome_canvas_line_get_type (),
1077                                       "points", points,
1078                                       "width_pixels", 1,
1079                                       "fill_color_rgba", GRID_COLOR,
1080                                       NULL);
1081
1082         points->coords[0] = 0.0;
1083         points->coords[2] = w;
1084         for ( y=0.0; y < h; y += view->grid_spacing ) {
1085                 points->coords[1] = points->coords[3] = y;
1086                 item = gnome_canvas_item_new (view->grid_group,
1087                                               gnome_canvas_line_get_type (),
1088                                               "points", points,
1089                                               "width_pixels", 1,
1090                                               "fill_color_rgba", GRID_COLOR,
1091                                               NULL);
1092         }
1093         points->coords[1] = points->coords[3] = h;
1094         item = gnome_canvas_item_new (view->grid_group,
1095                                       gnome_canvas_line_get_type (),
1096                                       "points", points,
1097                                       "width_pixels", 1,
1098                                       "fill_color_rgba", GRID_COLOR,
1099                                       NULL);
1100
1101         gnome_canvas_points_free (points);
1102
1103         gl_debug (DEBUG_VIEW, "END");
1104 }
1105
1106 /*---------------------------------------------------------------------------*/
1107 /* PRIVATE.  Draw markup lines.                                              */
1108 /*---------------------------------------------------------------------------*/
1109 static void
1110 draw_markup_layer (glView *view)
1111 {
1112         GnomeCanvasGroup *group;
1113         glLabel          *label;
1114         glTemplate       *template;
1115         GList            *p;
1116         glTemplateMarkup *markup;
1117
1118         g_return_if_fail (view && GL_IS_VIEW (view));
1119         g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1120
1121         group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
1122         view->markup_group = GNOME_CANVAS_GROUP(
1123                 gnome_canvas_item_new (group,
1124                                        gnome_canvas_group_get_type (),
1125                                        "x", 0.0,
1126                                        "y", 0.0,
1127                                        NULL));
1128
1129         label    = view->label;
1130         template = gl_label_get_template (label);
1131
1132         for ( p=template->label.any.markups; p != NULL; p=p->next ) {
1133                 markup = (glTemplateMarkup *)p->data;
1134
1135                 switch (markup->type) {
1136                 case GL_TEMPLATE_MARKUP_MARGIN:
1137                         draw_markup_margin (view,
1138                                             (glTemplateMarkupMargin *)markup);
1139                         break;
1140                 case GL_TEMPLATE_MARKUP_LINE:
1141                         draw_markup_line (view,
1142                                           (glTemplateMarkupLine *)markup);
1143                 case GL_TEMPLATE_MARKUP_CIRCLE:
1144                         draw_markup_circle (view,
1145                                             (glTemplateMarkupCircle *)markup);
1146                         break;
1147                 default:
1148                         g_warning ("Unknown template markup type");
1149                         break;
1150                 }
1151         }
1152 }
1153
1154 /*---------------------------------------------------------------------------*/
1155 /* PRIVATE.  Draw margin markup.                                             */
1156 /*---------------------------------------------------------------------------*/
1157 static void
1158 draw_markup_margin (glView                 *view,
1159                     glTemplateMarkupMargin *margin)
1160 {
1161         glLabel    *label;
1162         glTemplate *template;
1163
1164         g_return_if_fail (view && GL_IS_VIEW (view));
1165         g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1166
1167         label    = view->label;
1168         template = gl_label_get_template (label);
1169
1170         switch (template->label.style) {
1171
1172         case GL_TEMPLATE_STYLE_RECT:
1173                 if (template->label.rect.r == 0.0) {
1174                         /* Square corners. */
1175                         draw_markup_margin_rect (view, margin);
1176                 } else {
1177                         if ( margin->size < template->label.rect.r) {
1178                                 /* Rounded corners. */
1179                                 draw_markup_margin_rounded_rect (view, margin);
1180                         } else {
1181                                 /* Square corners. */
1182                                 draw_markup_margin_rect (view, margin);
1183                         }
1184                 }
1185                 break;
1186
1187         case GL_TEMPLATE_STYLE_ROUND:
1188                 draw_markup_margin_round (view, margin);
1189                 break;
1190
1191         case GL_TEMPLATE_STYLE_CD:
1192                 if ((template->label.cd.w == 0.0) && (template->label.cd.h == 0.0) ) {
1193                         draw_markup_margin_cd (view, margin);
1194                 } else {
1195                         draw_markup_margin_cd_bc (view, margin);
1196                 }
1197                 break;
1198
1199         default:
1200                 g_warning ("Unknown template label style");
1201                 break;
1202         }
1203 }
1204
1205 /*---------------------------------------------------------------------------*/
1206 /* PRIVATE.  Draw simple recangular margin.                                  */
1207 /*---------------------------------------------------------------------------*/
1208 static void
1209 draw_markup_margin_rect (glView                 *view,
1210                          glTemplateMarkupMargin *margin)
1211 {
1212         glLabel          *label;
1213         glTemplate       *template;
1214         gdouble           w, h, m;
1215         GnomeCanvasItem  *item;
1216
1217         gl_debug (DEBUG_VIEW, "START");
1218
1219         g_return_if_fail (view && GL_IS_VIEW (view));
1220         g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1221
1222         label = view->label;
1223
1224         gl_label_get_size (label, &w, &h);
1225         template = gl_label_get_template (label);
1226         m = margin->size;
1227
1228         /* Bounding box @ margin */
1229         gnome_canvas_item_new (view->markup_group,
1230                                gnome_canvas_rect_get_type (),
1231                                "x1", m,
1232                                "y1", m,
1233                                "x2", w - m,
1234                                "y2", h - m,
1235                                "width_pixels", 1,
1236                                "outline_color_rgba", MARKUP_COLOR,
1237                                NULL);
1238
1239         gl_debug (DEBUG_VIEW, "END");
1240 }
1241
1242 /*---------------------------------------------------------------------------*/
1243 /* PRIVATE.  Draw rounded recangular markup.                                 */
1244 /*---------------------------------------------------------------------------*/
1245 static void
1246 draw_markup_margin_rounded_rect (glView                 *view,
1247                                  glTemplateMarkupMargin *margin)
1248 {
1249         glLabel           *label;
1250         GnomeCanvasPoints *points;
1251         gint               i_coords, i_theta;
1252         glTemplate        *template;
1253         gdouble            r, w, h, m;
1254         GnomeCanvasItem   *item;
1255
1256         gl_debug (DEBUG_VIEW, "START");
1257
1258         g_return_if_fail (view && GL_IS_VIEW (view));
1259         g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1260
1261         label = view->label;
1262
1263         gl_label_get_size (label, &w, &h);
1264         template = gl_label_get_template (label);
1265         r = template->label.rect.r;
1266         m = margin->size;
1267
1268         r = r - m;
1269         w = w - 2 * m;
1270         h = h - 2 * m;
1271
1272         /* rectangle with rounded corners */
1273         points = gnome_canvas_points_new (4 * (1 + 90 / ARC_COURSE));
1274         i_coords = 0;
1275         for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1276                 points->coords[i_coords++] =
1277                         m + r - r * sin (i_theta * G_PI / 180.0);
1278                 points->coords[i_coords++] =
1279                         m + r - r * cos (i_theta * G_PI / 180.0);
1280         }
1281         for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1282                 points->coords[i_coords++] =
1283                         m + r - r * cos (i_theta * G_PI / 180.0);
1284                 points->coords[i_coords++] =
1285                         m + (h - r) + r * sin (i_theta * G_PI / 180.0);
1286         }
1287         for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1288                 points->coords[i_coords++] =
1289                         m + (w - r) + r * sin (i_theta * G_PI / 180.0);
1290                 points->coords[i_coords++] =
1291                         m + (h - r) + r * cos (i_theta * G_PI / 180.0);
1292         }
1293         for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1294                 points->coords[i_coords++] =
1295                         m + (w - r) + r * cos (i_theta * G_PI / 180.0);
1296                 points->coords[i_coords++] =
1297                         m + r - r * sin (i_theta * G_PI / 180.0);
1298         }
1299         item = gnome_canvas_item_new (view->markup_group,
1300                                       gnome_canvas_polygon_get_type (),
1301                                       "points", points,
1302                                       "width_pixels", 1,
1303                                       "outline_color_rgba", MARKUP_COLOR,
1304                                       NULL);
1305         gnome_canvas_points_free (points);
1306
1307         gl_debug (DEBUG_VIEW, "END");
1308 }
1309
1310 /*---------------------------------------------------------------------------*/
1311 /* PRIVATE.  Draw round margin.                                              */
1312 /*---------------------------------------------------------------------------*/
1313 static void
1314 draw_markup_margin_round (glView                 *view,
1315                           glTemplateMarkupMargin *margin)
1316 {
1317         glLabel          *label;
1318         glTemplate       *template;
1319         gdouble           r, m;
1320         GnomeCanvasItem  *item;
1321
1322         gl_debug (DEBUG_VIEW, "START");
1323
1324         g_return_if_fail (view && GL_IS_VIEW (view));
1325         g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1326
1327         label    = view->label;
1328         template = gl_label_get_template (label);
1329
1330         r = template->label.round.r;
1331         m = margin->size;
1332
1333         /* Margin outline */
1334         item = gnome_canvas_item_new (view->markup_group,
1335                                       gnome_canvas_ellipse_get_type (),
1336                                       "x1", m,
1337                                       "y1", m,
1338                                       "x2", 2.0*r - m,
1339                                       "y2", 2.0*r - m,
1340                                       "width_pixels", 1,
1341                                       "outline_color_rgba", MARKUP_COLOR,
1342                                       NULL);
1343
1344         gl_debug (DEBUG_VIEW, "END");
1345 }
1346
1347 /*---------------------------------------------------------------------------*/
1348 /* PRIVATE.  Draw CD margins.                                                */
1349 /*---------------------------------------------------------------------------*/
1350 static void
1351 draw_markup_margin_cd (glView                 *view,
1352                        glTemplateMarkupMargin *margin)
1353 {
1354         glLabel          *label;
1355         glTemplate       *template;
1356         gdouble           m, r1, r2;
1357         GnomeCanvasItem  *item;
1358
1359         gl_debug (DEBUG_VIEW, "START");
1360
1361         g_return_if_fail (view && GL_IS_VIEW (view));
1362         g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1363
1364         label    = view->label;
1365         template = gl_label_get_template (label);
1366
1367         r1 = template->label.cd.r1;
1368         r2 = template->label.cd.r2;
1369         m  = margin->size;
1370
1371         /* outer margin */
1372         item = gnome_canvas_item_new (view->markup_group,
1373                                       gnome_canvas_ellipse_get_type (),
1374                                       "x1", m,
1375                                       "y1", m,
1376                                       "x2", 2.0*r1 - m,
1377                                       "y2", 2.0*r1 - m,
1378                                       "width_pixels", 1,
1379                                       "outline_color_rgba", MARKUP_COLOR,
1380                                       NULL);
1381         /* inner margin */
1382         item = gnome_canvas_item_new (view->markup_group,
1383                                       gnome_canvas_ellipse_get_type (),
1384                                       "x1", r1 - r2 - m,
1385                                       "y1", r1 - r2 - m,
1386                                       "x2", r1 + r2 + m,
1387                                       "y2", r1 + r2 + m,
1388                                       "width_pixels", 1,
1389                                       "outline_color_rgba", MARKUP_COLOR,
1390                                       NULL);
1391
1392         gl_debug (DEBUG_VIEW, "END");
1393 }
1394
1395 /*---------------------------------------------------------------------------*/
1396 /* PRIVATE.  Draw Business Card CD margins.                                  */
1397 /*---------------------------------------------------------------------------*/
1398 static void
1399 draw_markup_margin_cd_bc (glView                 *view,
1400                           glTemplateMarkupMargin *margin)
1401 {
1402         glLabel           *label;
1403         glTemplate        *template;
1404         gdouble            m, r1, r2;
1405         GnomeCanvasPoints *points;
1406         gint               i_coords, i_theta;
1407         gdouble            theta1, theta2;
1408         gdouble            x0, y0, w, h, r;
1409         GnomeCanvasItem   *item;
1410
1411         gl_debug (DEBUG_VIEW, "START");
1412
1413         g_return_if_fail (view && GL_IS_VIEW (view));
1414         g_return_if_fail (view->label && GL_IS_LABEL (view->label));
1415
1416         label    = view->label;
1417         template = gl_label_get_template (label);
1418         gl_label_get_size (label, &w, &h);
1419         x0 = w/2.0;
1420         y0 = h/2.0;
1421
1422         r1 = template->label.cd.r1;
1423         r2 = template->label.cd.r2;
1424         m  = margin->size;
1425
1426         /* outer margin */
1427         r = r1 - m;
1428         theta1 = (180.0/G_PI) * acos (w / (2.0*r1));
1429         theta2 = (180.0/G_PI) * asin (h / (2.0*r1));
1430
1431         points = gnome_canvas_points_new (360/ARC_FINE + 1);
1432         i_coords = 0;
1433
1434         points->coords[i_coords++] = x0 + r * cos (theta1 * G_PI / 180.0);
1435         points->coords[i_coords++] = y0 + r * sin (theta1 * G_PI / 180.0);
1436
1437         for ( i_theta = theta1 + ARC_FINE; i_theta < theta2; i_theta +=ARC_FINE ) {
1438                 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
1439                 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
1440         }
1441
1442         points->coords[i_coords++] = x0 + r * cos (theta2 * G_PI / 180.0);
1443         points->coords[i_coords++] = y0 + r * sin (theta2 * G_PI / 180.0);
1444
1445
1446         if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
1447                 points->coords[i_coords++] = x0 + r * cos ((180-theta2) * G_PI / 180.0);
1448                 points->coords[i_coords++] = y0 + r * sin ((180-theta2) * G_PI / 180.0);
1449         }
1450
1451         for ( i_theta = 180-theta2+ARC_FINE; i_theta < (180-theta1); i_theta +=ARC_FINE ) {
1452                 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
1453                 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
1454         }
1455
1456         points->coords[i_coords++] = x0 + r * cos ((180-theta1) * G_PI / 180.0);
1457         points->coords[i_coords++] = y0 + r * sin ((180-theta1) * G_PI / 180.0);
1458
1459         if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
1460                 points->coords[i_coords++] = x0 + r * cos ((180+theta1) * G_PI / 180.0);
1461                 points->coords[i_coords++] = y0 + r * sin ((180+theta1) * G_PI / 180.0);
1462         }
1463
1464         for ( i_theta = 180+theta1+ARC_FINE; i_theta < (180+theta2); i_theta +=ARC_FINE ) {
1465                 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
1466                 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
1467         }
1468
1469         points->coords[i_coords++] = x0 + r * cos ((180+theta2) * G_PI / 180.0);
1470         points->coords[i_coords++] = y0 + r * sin ((180+theta2) * G_PI / 180.0);
1471
1472         if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
1473                 points->coords[i_coords++] = x0 + r * cos ((360-theta2) * G_PI / 180.0);
1474                 points->coords[i_coords++] = y0 + r * sin ((360-theta2) * G_PI / 180.0);
1475         }
1476
1477         for ( i_theta = 360-theta2+ARC_FINE; i_theta < (360-theta1); i_theta +=ARC_FINE ) {
1478                 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
1479                 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
1480         }
1481
1482         if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
1483                 points->coords[i_coords++] = x0 + r * cos ((360-theta1) * G_PI / 180.0);
1484                 points->coords[i_coords++] = y0 + r * sin ((360-theta1) * G_PI / 180.0);
1485         }
1486
1487         points->num_points = i_coords / 2;
1488
1489         item = gnome_canvas_item_new (view->markup_group,
1490                                       gnome_canvas_polygon_get_type (),
1491                                       "points", points,
1492                                       "width_pixels", 1,
1493                                       "outline_color_rgba", MARKUP_COLOR,
1494                                       NULL);
1495
1496         gnome_canvas_points_free (points);
1497
1498         /* inner margin */
1499         item = gnome_canvas_item_new (view->markup_group,
1500                                       gnome_canvas_ellipse_get_type (),
1501                                       "x1", x0 - r2 - m,
1502                                       "y1", y0 - r2 - m,
1503                                       "x2", x0 + r2 + m,
1504                                       "y2", y0 + r2 + m,
1505                                       "width_pixels", 1,
1506                                       "outline_color_rgba", MARKUP_COLOR,
1507                                       NULL);
1508
1509         gl_debug (DEBUG_VIEW, "END");
1510 }
1511
1512 /*---------------------------------------------------------------------------*/
1513 /* PRIVATE.  Draw line markup.                                               */
1514 /*---------------------------------------------------------------------------*/
1515 static void
1516 draw_markup_line (glView               *view,
1517                   glTemplateMarkupLine *line)
1518 {
1519         GnomeCanvasPoints *points;
1520
1521         gl_debug (DEBUG_VIEW, "START");
1522
1523         g_return_if_fail (view && GL_IS_VIEW (view));
1524
1525         points = gnome_canvas_points_new (2);
1526         points->coords[0] = line->x1;
1527         points->coords[1] = line->y1;
1528         points->coords[2] = line->x2;
1529         points->coords[3] = line->y2;
1530
1531         /* Bounding box @ margin */
1532         gnome_canvas_item_new (view->markup_group,
1533                                gnome_canvas_line_get_type (),
1534                                "points", points,
1535                                "width_pixels", 1,
1536                                "fill_color_rgba", MARKUP_COLOR,
1537                                NULL);
1538
1539         gnome_canvas_points_free (points);
1540
1541         gl_debug (DEBUG_VIEW, "END");
1542 }
1543
1544 /*---------------------------------------------------------------------------*/
1545 /* PRIVATE.  Draw circle markup.                                             */
1546 /*---------------------------------------------------------------------------*/
1547 static void
1548 draw_markup_circle (glView                 *view,
1549                     glTemplateMarkupCircle *circle)
1550 {
1551         gl_debug (DEBUG_VIEW, "START");
1552
1553         g_return_if_fail (view && GL_IS_VIEW (view));
1554
1555         /* Circle outline */
1556         gnome_canvas_item_new (view->markup_group,
1557                                gnome_canvas_ellipse_get_type (),
1558                                "x1", circle->x0 - circle->r,
1559                                "y1", circle->y0 - circle->r,
1560                                "x2", circle->x0 + circle->r,
1561                                "y2", circle->y0 + circle->r,
1562                                "width_pixels", 1,
1563                                "outline_color_rgba", MARKUP_COLOR,
1564                                NULL);
1565
1566         gl_debug (DEBUG_VIEW, "END");
1567 }
1568
1569 /*****************************************************************************/
1570 /* Show grid.                                                                */
1571 /*****************************************************************************/
1572 void       gl_view_show_grid               (glView            *view)
1573 {
1574         g_return_if_fail (view && GL_IS_VIEW (view));
1575
1576         gnome_canvas_item_show (GNOME_CANVAS_ITEM(view->grid_group));
1577 }
1578
1579 /*****************************************************************************/
1580 /* Hide grid.                                                                */
1581 /*****************************************************************************/
1582 void       gl_view_hide_grid               (glView            *view)
1583 {
1584         g_return_if_fail (view && GL_IS_VIEW (view));
1585
1586         gnome_canvas_item_hide (GNOME_CANVAS_ITEM(view->grid_group));
1587 }
1588
1589 /*****************************************************************************/
1590 /* Set grid spacing.                                                         */
1591 /*****************************************************************************/
1592 void       gl_view_set_grid_spacing        (glView            *view,
1593                                             gdouble            spacing)
1594 {
1595         g_return_if_fail (view && GL_IS_VIEW (view));
1596
1597         view->grid_spacing = spacing;
1598
1599         gtk_object_destroy (GTK_OBJECT(view->grid_group));
1600         draw_grid_layer (view);
1601 }
1602
1603 /*****************************************************************************/
1604 /* Show markup.                                                              */
1605 /*****************************************************************************/
1606 void       gl_view_show_markup             (glView            *view)
1607 {
1608         g_return_if_fail (view && GL_IS_VIEW (view));
1609
1610         gnome_canvas_item_show (GNOME_CANVAS_ITEM(view->markup_group));
1611 }
1612
1613 /*****************************************************************************/
1614 /* Hide markup.                                                              */
1615 /*****************************************************************************/
1616 void       gl_view_hide_markup             (glView            *view)
1617 {
1618         g_return_if_fail (view && GL_IS_VIEW (view));
1619
1620         gnome_canvas_item_hide (GNOME_CANVAS_ITEM(view->markup_group));
1621 }
1622
1623 /*****************************************************************************/
1624 /* Set arrow mode.                                                           */
1625 /*****************************************************************************/
1626 void
1627 gl_view_arrow_mode (glView *view)
1628 {
1629         static GdkCursor *cursor = NULL;
1630
1631         gl_debug (DEBUG_VIEW, "START");
1632
1633         g_return_if_fail (view && GL_IS_VIEW (view));
1634
1635         if (!cursor) {
1636                 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1637         }
1638
1639         gdk_window_set_cursor (view->canvas->window, cursor);
1640
1641         view->state = GL_VIEW_STATE_ARROW;
1642
1643         gl_debug (DEBUG_VIEW, "END");
1644 }
1645
1646 /*****************************************************************************/
1647 /* Set create text object mode.                                              */
1648 /*****************************************************************************/
1649 void
1650 gl_view_object_create_mode (glView            *view,
1651                             glLabelObjectType type)
1652 {
1653         GdkCursor *cursor;
1654
1655         gl_debug (DEBUG_VIEW, "START");
1656
1657         g_return_if_fail (view && GL_IS_VIEW (view));
1658
1659         switch (type) {
1660         case GL_LABEL_OBJECT_BOX:
1661                 cursor = gl_view_box_get_create_cursor ();
1662                 break;
1663         case GL_LABEL_OBJECT_ELLIPSE:
1664                 cursor = gl_view_ellipse_get_create_cursor ();
1665                 break;
1666         case GL_LABEL_OBJECT_LINE:
1667                 cursor = gl_view_line_get_create_cursor ();
1668                 break;
1669         case GL_LABEL_OBJECT_IMAGE:
1670                 cursor = gl_view_image_get_create_cursor ();
1671                 break;
1672         case GL_LABEL_OBJECT_TEXT:
1673                 cursor = gl_view_text_get_create_cursor ();
1674                 break;
1675         case GL_LABEL_OBJECT_BARCODE:
1676                 cursor = gl_view_barcode_get_create_cursor ();
1677                 break;
1678         default:
1679                 g_warning ("Invalid label object type.");/*Should not happen!*/
1680                 break;
1681         }
1682
1683         gdk_window_set_cursor (view->canvas->window, cursor);
1684
1685         view->state = GL_VIEW_STATE_OBJECT_CREATE;
1686         view->create_type = type;
1687
1688         gl_debug (DEBUG_VIEW, "END");
1689 }
1690
1691 /*****************************************************************************/
1692 /* Select given object (adding to current selection).                        */
1693 /*****************************************************************************/
1694 void
1695 gl_view_select_object (glView       *view,
1696                        glViewObject *view_object)
1697 {
1698         gl_debug (DEBUG_VIEW, "START");
1699
1700         g_return_if_fail (view && GL_IS_VIEW (view));
1701
1702         select_object_real (view, view_object);
1703
1704         g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1705
1706         gl_debug (DEBUG_VIEW, "END");
1707 }
1708
1709 /*****************************************************************************/
1710 /* Unselect given object (removing from current selection).                  */
1711 /*****************************************************************************/
1712 void
1713 gl_view_unselect_object (glView       *view,
1714                          glViewObject *view_object)
1715 {
1716         gl_debug (DEBUG_VIEW, "START");
1717
1718         g_return_if_fail (view && GL_IS_VIEW (view));
1719
1720         unselect_object_real (view, view_object);
1721
1722         g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1723
1724         gl_debug (DEBUG_VIEW, "END");
1725 }
1726
1727 /*****************************************************************************/
1728 /* Select all items.                                                         */
1729 /*****************************************************************************/
1730 void
1731 gl_view_select_all (glView *view)
1732 {
1733         GList *p, *p_next;
1734
1735         gl_debug (DEBUG_VIEW, "START");
1736
1737         g_return_if_fail (view && GL_IS_VIEW (view));
1738
1739         /* 1st unselect anything already selected. */
1740         for (p = view->selected_object_list; p != NULL; p = p_next) {
1741                 p_next = p->next;
1742                 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1743         }
1744
1745         /* Finally select all objects. */
1746         for (p = view->object_list; p != NULL; p = p->next) {
1747                 select_object_real (view, GL_VIEW_OBJECT (p->data));
1748         }
1749
1750         g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1751
1752         gl_debug (DEBUG_VIEW, "END");
1753 }
1754
1755 /*****************************************************************************/
1756 /* Remove all selections                                                     */
1757 /*****************************************************************************/
1758 void
1759 gl_view_unselect_all (glView *view)
1760 {
1761         GList *p, *p_next;
1762
1763         gl_debug (DEBUG_VIEW, "START");
1764
1765         g_return_if_fail (view && GL_IS_VIEW (view));
1766
1767         for (p = view->selected_object_list; p != NULL; p = p_next) {
1768                 p_next = p->next;
1769                 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1770         }
1771
1772         g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1773
1774         gl_debug (DEBUG_VIEW, "END");
1775 }
1776
1777 /*****************************************************************************/
1778 /* Select all objects within given rectangular region (adding to selection). */
1779 /*****************************************************************************/
1780 void
1781 gl_view_select_region (glView  *view,
1782                        gdouble  x1,
1783                        gdouble  y1,
1784                        gdouble  x2,
1785                        gdouble  y2)
1786 {
1787         GList *p;
1788         glViewObject *view_object;
1789         glLabelObject *object;
1790         gdouble i_x1, i_y1, i_x2, i_y2;
1791
1792         gl_debug (DEBUG_VIEW, "START");
1793
1794         g_return_if_fail (view && GL_IS_VIEW (view));
1795         g_return_if_fail ((x1 <= x2) && (y1 <= y2));
1796
1797         for (p = view->object_list; p != NULL; p = p->next) {
1798                 view_object = GL_VIEW_OBJECT(p->data);
1799                 if (!gl_view_is_object_selected (view, view_object)) {
1800
1801                         object = gl_view_object_get_object (view_object);
1802
1803                         gl_label_object_get_extent (object, &i_x1, &i_y1, &i_x2, &i_y2);
1804                         if ((i_x1 >= x1) && (i_x2 <= x2) && (i_y1 >= y1)
1805                             && (i_y2 <= y2)) {
1806                                 select_object_real (view, view_object);
1807                         }
1808
1809                 }
1810         }
1811
1812         g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1813
1814         gl_debug (DEBUG_VIEW, "END");
1815 }
1816
1817 /*---------------------------------------------------------------------------*/
1818 /* PRIVATE. Select an object.                                                */
1819 /*---------------------------------------------------------------------------*/
1820 static void
1821 select_object_real (glView       *view,
1822                     glViewObject *view_object)
1823 {
1824         gl_debug (DEBUG_VIEW, "START");
1825
1826         g_return_if_fail (view && GL_IS_VIEW (view));
1827         g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1828
1829         if (!gl_view_is_object_selected (view, view_object)) {
1830                 view->selected_object_list =
1831                     g_list_prepend (view->selected_object_list, view_object);
1832         }
1833         gl_view_object_show_highlight (view_object);
1834         gtk_widget_grab_focus (GTK_WIDGET (view->canvas));
1835
1836         gl_debug (DEBUG_VIEW, "END");
1837 }
1838
1839 /*---------------------------------------------------------------------------*/
1840 /* PRIVATE.  Un-select object.                                               */
1841 /*---------------------------------------------------------------------------*/
1842 static void
1843 unselect_object_real (glView       *view,
1844                       glViewObject *view_object)
1845 {
1846         gl_debug (DEBUG_VIEW, "START");
1847
1848         g_return_if_fail (view && GL_IS_VIEW (view));
1849         g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1850
1851         gl_view_object_hide_highlight (view_object);
1852
1853         view->selected_object_list =
1854             g_list_remove (view->selected_object_list, view_object);
1855
1856         gl_debug (DEBUG_VIEW, "END");
1857 }
1858
1859 /*---------------------------------------------------------------------------*/
1860 /* PRIVATE. Return object at (x,y).                                          */
1861 /*---------------------------------------------------------------------------*/
1862 static gboolean
1863 object_at (glView  *view,
1864            gdouble  x,
1865            gdouble  y)
1866 {
1867         GnomeCanvasItem *item, *p_item;
1868         GList *p;
1869
1870         gl_debug (DEBUG_VIEW, "");
1871
1872         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1873
1874         item = gnome_canvas_get_item_at (GNOME_CANVAS (view->canvas), x, y);
1875
1876         /* No item is at x, y */
1877         if (item == NULL)
1878                 return FALSE;
1879
1880         /* ignore items not in label or highlight layers, e.g. background items */
1881         if (!is_item_member_of_group(view, item, GNOME_CANVAS_ITEM(view->label_group)) &&
1882             !is_item_member_of_group(view, item, GNOME_CANVAS_ITEM(view->highlight_group)))
1883                 return FALSE;
1884
1885         return TRUE;
1886 }
1887
1888 /*---------------------------------------------------------------------------*/
1889 /* PRIVATE.  Is the item a child (or grandchild, etc.) of group.             */
1890 /*---------------------------------------------------------------------------*/
1891 static gboolean
1892 is_item_member_of_group (glView          *view,
1893                          GnomeCanvasItem *item,
1894                          GnomeCanvasItem *group)
1895 {
1896         GnomeCanvasItem *parent;
1897         GnomeCanvasItem *root_group;
1898
1899         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1900
1901         root_group = GNOME_CANVAS_ITEM(gnome_canvas_root (GNOME_CANVAS (view->canvas)));
1902
1903         for ( parent=item->parent; parent && (parent!=root_group); parent=parent->parent) {
1904                 if (parent == group) return TRUE;
1905         }
1906         return FALSE;
1907 }
1908
1909 /*****************************************************************************/
1910 /* Is the object in our current selection?                                   */
1911 /*****************************************************************************/
1912 gboolean
1913 gl_view_is_object_selected (glView       *view,
1914                     glViewObject *view_object)
1915 {
1916         gl_debug (DEBUG_VIEW, "");
1917
1918         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1919         g_return_val_if_fail (GL_IS_VIEW_OBJECT (view_object), FALSE);
1920
1921         if (g_list_find (view->selected_object_list, view_object) == NULL) {
1922                 return FALSE;
1923         }
1924         return TRUE;
1925 }
1926
1927 /*****************************************************************************/
1928 /* Is our current selection empty?                                           */
1929 /*****************************************************************************/
1930 gboolean
1931 gl_view_is_selection_empty (glView *view)
1932 {
1933         gl_debug (DEBUG_VIEW, "");
1934
1935         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1936
1937         if (view->selected_object_list == NULL) {
1938                 return TRUE;
1939         } else {
1940                 return FALSE;
1941         }
1942 }
1943
1944 /*****************************************************************************/
1945 /* Is our current selection atomic?  I.e. only one item selected.            */
1946 /*****************************************************************************/
1947 gboolean
1948 gl_view_is_selection_atomic (glView *view)
1949 {
1950         gl_debug (DEBUG_VIEW, "");
1951
1952         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
1953
1954         if (view->selected_object_list == NULL)
1955                 return FALSE;
1956         if (view->selected_object_list->next == NULL)
1957                 return TRUE;
1958         return FALSE;
1959 }
1960
1961 /*****************************************************************************/
1962 /* Delete selected objects. (Bypass clipboard)                               */
1963 /*****************************************************************************/
1964 void
1965 gl_view_delete_selection (glView *view)
1966 {
1967         GList *p, *p_next;
1968
1969         gl_debug (DEBUG_VIEW, "START");
1970
1971         g_return_if_fail (view && GL_IS_VIEW (view));
1972
1973         for (p = view->selected_object_list; p != NULL; p = p_next) {
1974                 p_next = p->next;
1975                 g_object_unref (G_OBJECT (p->data));
1976         }
1977
1978         g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1979
1980         gl_debug (DEBUG_VIEW, "END");
1981 }
1982
1983 /*****************************************************************************/
1984 /* Edit properties of selected object.                                       */
1985 /*****************************************************************************/
1986 void
1987 gl_view_edit_object_props (glView *view)
1988 {
1989         glViewObject *view_object;
1990
1991         gl_debug (DEBUG_VIEW, "START");
1992
1993         g_return_if_fail (view && GL_IS_VIEW (view));
1994
1995         if (gl_view_is_selection_atomic (view)) {
1996
1997                 view_object = GL_VIEW_OBJECT(view->selected_object_list->data);
1998                 gl_view_object_show_dialog (view_object);
1999
2000         }
2001
2002         gl_debug (DEBUG_VIEW, "END");
2003 }
2004
2005 /*****************************************************************************/
2006 /* Raise selected items to top.                                              */
2007 /*****************************************************************************/
2008 void
2009 gl_view_raise_selection (glView *view)
2010 {
2011         GList         *p;
2012         glViewObject  *view_object;
2013         glLabelObject *object;
2014
2015         gl_debug (DEBUG_VIEW, "START");
2016
2017         g_return_if_fail (view && GL_IS_VIEW (view));
2018
2019         for (p = view->selected_object_list; p != NULL; p = p->next) {
2020                 view_object = GL_VIEW_OBJECT (p->data);
2021                 object = gl_view_object_get_object (view_object);
2022                 gl_label_object_raise_to_top (object);
2023         }
2024
2025         gl_debug (DEBUG_VIEW, "END");
2026 }
2027
2028 /*****************************************************************************/
2029 /* Lower selected items to bottom.                                           */
2030 /*****************************************************************************/
2031 void
2032 gl_view_lower_selection (glView *view)
2033 {
2034         GList         *p;
2035         glViewObject  *view_object;
2036         glLabelObject *object;
2037
2038         gl_debug (DEBUG_VIEW, "START");
2039
2040         g_return_if_fail (view && GL_IS_VIEW (view));
2041
2042         for (p = view->selected_object_list; p != NULL; p = p->next) {
2043                 view_object = GL_VIEW_OBJECT (p->data);
2044                 object = gl_view_object_get_object (view_object);
2045                 gl_label_object_lower_to_bottom (object);
2046         }
2047
2048         gl_debug (DEBUG_VIEW, "END");
2049 }
2050
2051 /*****************************************************************************/
2052 /* Rotate selected objects by given angle.                                   */
2053 /*****************************************************************************/
2054 void
2055 gl_view_rotate_selection (glView *view,
2056                           gdouble theta_degs)
2057 {
2058         GList         *p;
2059         glViewObject  *view_object;
2060         glLabelObject *object;
2061
2062         gl_debug (DEBUG_VIEW, "START");
2063
2064         g_return_if_fail (view && GL_IS_VIEW (view));
2065
2066         for (p = view->selected_object_list; p != NULL; p = p->next) {
2067                 view_object = GL_VIEW_OBJECT (p->data);
2068                 object = gl_view_object_get_object (view_object);
2069                 gl_label_object_rotate (object, theta_degs);
2070         }
2071
2072         gl_debug (DEBUG_VIEW, "END");
2073 }
2074
2075 /*****************************************************************************/
2076 /* Rotate selected objects 90 degrees left.                                  */
2077 /*****************************************************************************/
2078 void
2079 gl_view_rotate_selection_left (glView *view)
2080 {
2081         GList         *p;
2082         glViewObject  *view_object;
2083         glLabelObject *object;
2084
2085         gl_debug (DEBUG_VIEW, "START");
2086
2087         g_return_if_fail (view && GL_IS_VIEW (view));
2088
2089         for (p = view->selected_object_list; p != NULL; p = p->next) {
2090                 view_object = GL_VIEW_OBJECT (p->data);
2091                 object = gl_view_object_get_object (view_object);
2092                 gl_label_object_rotate (object, -90.0);
2093         }
2094
2095         gl_debug (DEBUG_VIEW, "END");
2096 }
2097
2098 /*****************************************************************************/
2099 /* Rotate selected objects 90 degrees right.                                 */
2100 /*****************************************************************************/
2101 void
2102 gl_view_rotate_selection_right (glView *view)
2103 {
2104         GList         *p;
2105         glViewObject  *view_object;
2106         glLabelObject *object;
2107
2108         gl_debug (DEBUG_VIEW, "START");
2109
2110         g_return_if_fail (view && GL_IS_VIEW (view));
2111
2112         for (p = view->selected_object_list; p != NULL; p = p->next) {
2113                 view_object = GL_VIEW_OBJECT (p->data);
2114                 object = gl_view_object_get_object (view_object);
2115                 gl_label_object_rotate (object, 90.0);
2116         }
2117
2118         gl_debug (DEBUG_VIEW, "END");
2119 }
2120
2121 /*****************************************************************************/
2122 /* Flip selected objects horizontally.                                       */
2123 /*****************************************************************************/
2124 void
2125 gl_view_flip_selection_horiz (glView *view)
2126 {
2127         GList         *p;
2128         glViewObject  *view_object;
2129         glLabelObject *object;
2130
2131         gl_debug (DEBUG_VIEW, "START");
2132
2133         g_return_if_fail (view && GL_IS_VIEW (view));
2134
2135         for (p = view->selected_object_list; p != NULL; p = p->next) {
2136                 view_object = GL_VIEW_OBJECT (p->data);
2137                 object = gl_view_object_get_object (view_object);
2138                 gl_label_object_flip_horiz (object);
2139         }
2140
2141         gl_debug (DEBUG_VIEW, "END");
2142 }
2143
2144 /*****************************************************************************/
2145 /* Flip selected objects vertically.                                         */
2146 /*****************************************************************************/
2147 void
2148 gl_view_flip_selection_vert (glView *view)
2149 {
2150         GList         *p;
2151         glViewObject  *view_object;
2152         glLabelObject *object;
2153
2154         gl_debug (DEBUG_VIEW, "START");
2155
2156         g_return_if_fail (view && GL_IS_VIEW (view));
2157
2158         for (p = view->selected_object_list; p != NULL; p = p->next) {
2159                 view_object = GL_VIEW_OBJECT (p->data);
2160                 object = gl_view_object_get_object (view_object);
2161                 gl_label_object_flip_vert (object);
2162         }
2163
2164         gl_debug (DEBUG_VIEW, "END");
2165 }
2166
2167 /*****************************************************************************/
2168 /* Align selected objects to left most edge.                                 */
2169 /*****************************************************************************/
2170 void
2171 gl_view_align_selection_left (glView *view)
2172 {
2173         GList         *p;
2174         glViewObject  *view_object;
2175         glLabelObject *object;
2176         gdouble        dx, x1min, x1, y1, x2, y2;
2177
2178         gl_debug (DEBUG_VIEW, "START");
2179
2180         g_return_if_fail (view && GL_IS_VIEW (view));
2181
2182         g_return_if_fail (!gl_view_is_selection_empty (view) &&
2183                           !gl_view_is_selection_atomic (view));
2184
2185         /* find left most edge */
2186         p = view->selected_object_list;
2187         view_object = GL_VIEW_OBJECT (p->data);
2188         object = gl_view_object_get_object (view_object);
2189         gl_label_object_get_extent (object, &x1min, &y1, &x2, &y2);
2190         for (p = p->next; p != NULL; p = p->next) {
2191                 view_object = GL_VIEW_OBJECT (p->data);
2192                 object = gl_view_object_get_object (view_object);
2193                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2194                 if ( x1 < x1min ) x1min = x1;
2195         }
2196
2197         /* now adjust the object positions to line up the left edges */
2198         for (p = view->selected_object_list; p != NULL; p = p->next) {
2199                 view_object = GL_VIEW_OBJECT (p->data);
2200                 object = gl_view_object_get_object (view_object);
2201                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2202                 dx = x1min - x1;
2203                 gl_label_object_set_position_relative (object, dx, 0.0);
2204         }
2205
2206         gl_debug (DEBUG_VIEW, "END");
2207 }
2208
2209
2210 /*****************************************************************************/
2211 /* Align selected objects to right most edge.                                */
2212 /*****************************************************************************/
2213 void
2214 gl_view_align_selection_right (glView *view)
2215 {
2216         GList         *p;
2217         glViewObject  *view_object;
2218         glLabelObject *object;
2219         gdouble        dx, x2max, x1, y1, x2, y2;
2220
2221         gl_debug (DEBUG_VIEW, "START");
2222
2223         g_return_if_fail (view && GL_IS_VIEW (view));
2224
2225         g_return_if_fail (!gl_view_is_selection_empty (view) &&
2226                           !gl_view_is_selection_atomic (view));
2227
2228         /* find right most edge */
2229         p = view->selected_object_list;
2230         view_object = GL_VIEW_OBJECT (p->data);
2231         object = gl_view_object_get_object (view_object);
2232         gl_label_object_get_extent (object, &x1, &y1, &x2max, &y2);
2233         for (p = p->next; p != NULL; p = p->next) {
2234                 view_object = GL_VIEW_OBJECT (p->data);
2235                 object = gl_view_object_get_object (view_object);
2236                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2237                 if ( x2 > x2max ) x2max = x2;
2238         }
2239
2240         /* now adjust the object positions to line up the right edges */
2241         for (p = view->selected_object_list; p != NULL; p = p->next) {
2242                 view_object = GL_VIEW_OBJECT (p->data);
2243                 object = gl_view_object_get_object (view_object);
2244                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2245                 dx = x2max - x2;
2246                 gl_label_object_set_position_relative (object, dx, 0.0);
2247         }
2248
2249         gl_debug (DEBUG_VIEW, "END");
2250 }
2251
2252 /*****************************************************************************/
2253 /* Align selected objects to horizontal center of objects.                   */
2254 /*****************************************************************************/
2255 void
2256 gl_view_align_selection_hcenter (glView *view)
2257 {
2258         GList         *p;
2259         glViewObject  *view_object;
2260         glLabelObject *object;
2261         gdouble        dx, dxmin, xsum, xavg, xcenter, x1, y1, x2, y2;
2262         gint           n;
2263
2264         gl_debug (DEBUG_VIEW, "START");
2265
2266         g_return_if_fail (view && GL_IS_VIEW (view));
2267
2268         g_return_if_fail (!gl_view_is_selection_empty (view) &&
2269                           !gl_view_is_selection_atomic (view));
2270
2271         /* find average center of objects */
2272         xsum = 0.0;
2273         n = 0;
2274         for (p = view->selected_object_list; p != NULL; p = p->next) {
2275                 view_object = GL_VIEW_OBJECT (p->data);
2276                 object = gl_view_object_get_object (view_object);
2277                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2278                 xsum += (x1 + x2) / 2.0;
2279                 n++;
2280         }
2281         xavg = xsum / n;
2282
2283         /* find center of object closest to average center */
2284         p = view->selected_object_list;
2285         view_object = GL_VIEW_OBJECT (p->data);
2286         object = gl_view_object_get_object (view_object);
2287         gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2288         dxmin = fabs (xavg - (x1 + x2)/2.0);
2289         xcenter = (x1 + x2)/2.0;
2290         for (p = p->next; p != NULL; p = p->next) {
2291                 view_object = GL_VIEW_OBJECT (p->data);
2292                 object = gl_view_object_get_object (view_object);
2293                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2294                 dx = fabs (xavg - (x1 + x2)/2.0);
2295                 if ( dx < dxmin ) {
2296                         dxmin = dx;
2297                         xcenter = (x1 + x2)/2.0;
2298                 }
2299         }
2300
2301         /* now adjust the object positions to line up this center */
2302         for (p = view->selected_object_list; p != NULL; p = p->next) {
2303                 view_object = GL_VIEW_OBJECT (p->data);
2304                 object = gl_view_object_get_object (view_object);
2305                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2306                 dx = xcenter - (x1 + x2)/2.0;
2307                 gl_label_object_set_position_relative (object, dx, 0.0);
2308         }
2309
2310         gl_debug (DEBUG_VIEW, "END");
2311 }
2312
2313 /*****************************************************************************/
2314 /* Align selected objects to top most edge.                                  */
2315 /*****************************************************************************/
2316 void
2317 gl_view_align_selection_top (glView *view)
2318 {
2319         GList         *p;
2320         glViewObject  *view_object;
2321         glLabelObject *object;
2322         gdouble        dy, y1min, x1, y1, x2, y2;
2323
2324         gl_debug (DEBUG_VIEW, "START");
2325
2326         g_return_if_fail (view && GL_IS_VIEW (view));
2327
2328         g_return_if_fail (!gl_view_is_selection_empty (view) &&
2329                           !gl_view_is_selection_atomic (view));
2330
2331         /* find top most edge */
2332         p = view->selected_object_list;
2333         view_object = GL_VIEW_OBJECT (p->data);
2334         object = gl_view_object_get_object (view_object);
2335         gl_label_object_get_extent (object, &x1, &y1min, &x2, &y2);
2336         for (p = p->next; p != NULL; p = p->next) {
2337                 view_object = GL_VIEW_OBJECT (p->data);
2338                 object = gl_view_object_get_object (view_object);
2339                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2340                 if ( y1 < y1min ) y1min = y1;
2341         }
2342
2343         /* now adjust the object positions to line up the top edges */
2344         for (p = view->selected_object_list; p != NULL; p = p->next) {
2345                 view_object = GL_VIEW_OBJECT (p->data);
2346                 object = gl_view_object_get_object (view_object);
2347                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2348                 dy = y1min - y1;
2349                 gl_label_object_set_position_relative (object, 0.0, dy);
2350         }
2351
2352         gl_debug (DEBUG_VIEW, "END");
2353 }
2354
2355 /*****************************************************************************/
2356 /* Align selected objects to bottom most edge.                               */
2357 /*****************************************************************************/
2358 void
2359 gl_view_align_selection_bottom (glView *view)
2360 {
2361         GList         *p;
2362         glViewObject  *view_object;
2363         glLabelObject *object;
2364         gdouble        dy, y2max, x1, y1, x2, y2;
2365
2366         gl_debug (DEBUG_VIEW, "START");
2367
2368         g_return_if_fail (view && GL_IS_VIEW (view));
2369
2370         g_return_if_fail (!gl_view_is_selection_empty (view) &&
2371                           !gl_view_is_selection_atomic (view));
2372
2373         /* find bottom most edge */
2374         p = view->selected_object_list;
2375         view_object = GL_VIEW_OBJECT (p->data);
2376         object = gl_view_object_get_object (view_object);
2377         gl_label_object_get_extent (object, &x1, &y1, &x2, &y2max);
2378         for (p = p->next; p != NULL; p = p->next) {
2379                 view_object = GL_VIEW_OBJECT (p->data);
2380                 object = gl_view_object_get_object (view_object);
2381                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2382                 if ( y2 > y2max ) y2max = y2;
2383         }
2384
2385         /* now adjust the object positions to line up the bottom edges */
2386         for (p = view->selected_object_list; p != NULL; p = p->next) {
2387                 view_object = GL_VIEW_OBJECT (p->data);
2388                 object = gl_view_object_get_object (view_object);
2389                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2390                 dy = y2max - y2;
2391                 gl_label_object_set_position_relative (object, 0.0, dy);
2392         }
2393
2394         gl_debug (DEBUG_VIEW, "END");
2395 }
2396
2397 /*****************************************************************************/
2398 /* Align selected objects to viertical center of objects.                    */
2399 /*****************************************************************************/
2400 void
2401 gl_view_align_selection_vcenter (glView *view)
2402 {
2403         GList         *p;
2404         glViewObject  *view_object;
2405         glLabelObject *object;
2406         gdouble        dy, dymin, ysum, yavg, ycenter, x1, y1, x2, y2;
2407         gint           n;
2408
2409         gl_debug (DEBUG_VIEW, "START");
2410
2411         g_return_if_fail (view && GL_IS_VIEW (view));
2412
2413         g_return_if_fail (!gl_view_is_selection_empty (view) &&
2414                           !gl_view_is_selection_atomic (view));
2415
2416         /* find average center of objects */
2417         ysum = 0.0;
2418         n = 0;
2419         for (p = view->selected_object_list; p != NULL; p = p->next) {
2420                 view_object = GL_VIEW_OBJECT (p->data);
2421                 object = gl_view_object_get_object (view_object);
2422                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2423                 ysum += (y1 + y2) / 2.0;
2424                 n++;
2425         }
2426         yavg = ysum / n;
2427
2428         /* find center of object closest to average center */
2429         p = view->selected_object_list;
2430         view_object = GL_VIEW_OBJECT (p->data);
2431         object = gl_view_object_get_object (view_object);
2432         gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2433         dymin = fabs (yavg - (y1 + y2)/2.0);
2434         ycenter = (y1 + y2)/2.0;
2435         for (p = p->next; p != NULL; p = p->next) {
2436                 view_object = GL_VIEW_OBJECT (p->data);
2437                 object = gl_view_object_get_object (view_object);
2438                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2439                 dy = fabs (yavg - (y1 + y2)/2.0);
2440                 if ( dy < dymin ) {
2441                         dymin = dy;
2442                         ycenter = (y1 + y2)/2.0;
2443                 }
2444         }
2445
2446         /* now adjust the object positions to line up this center */
2447         for (p = view->selected_object_list; p != NULL; p = p->next) {
2448                 view_object = GL_VIEW_OBJECT (p->data);
2449                 object = gl_view_object_get_object (view_object);
2450                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2451                 dy = ycenter - (y1 + y2)/2.0;
2452                 gl_label_object_set_position_relative (object, 0.0, dy);
2453         }
2454
2455         gl_debug (DEBUG_VIEW, "END");
2456 }
2457
2458 /*****************************************************************************/
2459 /* Center selected objects to in center of label.                            */
2460 /*****************************************************************************/
2461 void
2462 gl_view_center_selection_horiz (glView *view)
2463 {
2464         GList         *p;
2465         glViewObject  *view_object;
2466         glLabelObject *object;
2467         gdouble        dx, x_label_center, x_obj_center, x1, y1, x2, y2, w, h;
2468
2469         gl_debug (DEBUG_VIEW, "START");
2470
2471         g_return_if_fail (view && GL_IS_VIEW (view));
2472
2473         g_return_if_fail (!gl_view_is_selection_empty (view));
2474
2475         gl_label_get_size (view->label, &w, &h);
2476         x_label_center = w / 2.0;
2477
2478         /* adjust the object positions */
2479         for (p = view->selected_object_list; p != NULL; p = p->next) {
2480                 view_object = GL_VIEW_OBJECT (p->data);
2481                 object = gl_view_object_get_object (view_object);
2482                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2483                 x_obj_center = (x1 + x2) / 2.0;
2484                 dx = x_label_center - x_obj_center;
2485                 gl_label_object_set_position_relative (object, dx, 0.0);
2486         }
2487
2488         gl_debug (DEBUG_VIEW, "END");
2489 }
2490
2491
2492 /*****************************************************************************/
2493 /* Center selected objects to in center of label.                            */
2494 /*****************************************************************************/
2495 void
2496 gl_view_center_selection_vert (glView *view)
2497 {
2498         GList         *p;
2499         glViewObject  *view_object;
2500         glLabelObject *object;
2501         gdouble        dy, y_label_center, y_obj_center, x1, y1, x2, y2, w, h;
2502
2503         gl_debug (DEBUG_VIEW, "START");
2504
2505         g_return_if_fail (view && GL_IS_VIEW (view));
2506
2507         g_return_if_fail (!gl_view_is_selection_empty (view));
2508
2509         gl_label_get_size (view->label, &w, &h);
2510         y_label_center = h / 2.0;
2511
2512         /* adjust the object positions */
2513         for (p = view->selected_object_list; p != NULL; p = p->next) {
2514                 view_object = GL_VIEW_OBJECT (p->data);
2515                 object = gl_view_object_get_object (view_object);
2516                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2517                 y_obj_center = (y1 + y2) / 2.0;
2518                 dy = y_label_center - y_obj_center;
2519                 gl_label_object_set_position_relative (object, 0.0, dy);
2520         }
2521
2522         gl_debug (DEBUG_VIEW, "END");
2523 }
2524
2525
2526 /*****************************************************************************/
2527 /* Move selected objects                                                     */
2528 /*****************************************************************************/
2529 void
2530 gl_view_move_selection (glView  *view,
2531                 gdouble  dx,
2532                 gdouble  dy)
2533 {
2534         GList *p;
2535         glLabelObject *object;
2536
2537         gl_debug (DEBUG_VIEW, "START");
2538
2539         g_return_if_fail (view && GL_IS_VIEW (view));
2540
2541         for (p = view->selected_object_list; p != NULL; p = p->next) {
2542
2543                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2544                 gl_label_object_set_position_relative (object, dx, dy);
2545
2546         }
2547
2548         gl_debug (DEBUG_VIEW, "END");
2549 }
2550
2551 /*****************************************************************************/
2552 /* Can text properties be set for selection?                                 */
2553 /*****************************************************************************/
2554 gboolean
2555 gl_view_can_selection_text (glView            *view)
2556 {
2557         GList *p;
2558         glLabelObject *object;
2559
2560         gl_debug (DEBUG_VIEW, "");
2561
2562         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2563
2564         for (p = view->selected_object_list; p != NULL; p = p->next) {
2565
2566                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2567                 if (gl_label_object_can_text (object)) {
2568                         return TRUE;
2569                 }
2570
2571         }
2572
2573         return FALSE;
2574 }
2575
2576 /*****************************************************************************/
2577 /* Set font family for all text contained in selected objects.               */
2578 /*****************************************************************************/
2579 void
2580 gl_view_set_selection_font_family (glView            *view,
2581                                    const gchar       *font_family)
2582 {
2583         GList *p;
2584         glLabelObject *object;
2585
2586         gl_debug (DEBUG_VIEW, "START");
2587
2588         g_return_if_fail (view && GL_IS_VIEW (view));
2589
2590         for (p = view->selected_object_list; p != NULL; p = p->next) {
2591
2592                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2593                 gl_label_object_set_font_family (object, font_family);
2594
2595         }
2596
2597         gl_debug (DEBUG_VIEW, "END");
2598 }
2599
2600 /*****************************************************************************/
2601 /* Set font size for all text contained in selected objects.                 */
2602 /*****************************************************************************/
2603 void
2604 gl_view_set_selection_font_size (glView            *view,
2605                                  gdouble            font_size)
2606 {
2607         GList *p;
2608         glLabelObject *object;
2609
2610         gl_debug (DEBUG_VIEW, "START");
2611
2612         g_return_if_fail (view && GL_IS_VIEW (view));
2613
2614         for (p = view->selected_object_list; p != NULL; p = p->next) {
2615
2616                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2617                 gl_label_object_set_font_size (object, font_size);
2618
2619         }
2620
2621         gl_debug (DEBUG_VIEW, "END");
2622 }
2623
2624 /*****************************************************************************/
2625 /* Set font weight for all text contained in selected objects.               */
2626 /*****************************************************************************/
2627 void
2628 gl_view_set_selection_font_weight (glView            *view,
2629                                    GnomeFontWeight    font_weight)
2630 {
2631         GList *p;
2632         glLabelObject *object;
2633
2634         gl_debug (DEBUG_VIEW, "START");
2635
2636         g_return_if_fail (view && GL_IS_VIEW (view));
2637
2638         for (p = view->selected_object_list; p != NULL; p = p->next) {
2639
2640                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2641                 gl_label_object_set_font_weight (object, font_weight);
2642
2643         }
2644
2645         gl_debug (DEBUG_VIEW, "END");
2646 }
2647
2648 /*****************************************************************************/
2649 /* Set font italic flag for all text contained in selected objects.          */
2650 /*****************************************************************************/
2651 void
2652 gl_view_set_selection_font_italic_flag (glView            *view,
2653                                         gboolean           font_italic_flag)
2654 {
2655         GList *p;
2656         glLabelObject *object;
2657
2658         gl_debug (DEBUG_VIEW, "START");
2659
2660         g_return_if_fail (view && GL_IS_VIEW (view));
2661
2662         for (p = view->selected_object_list; p != NULL; p = p->next) {
2663
2664                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2665                 gl_label_object_set_font_italic_flag (object, font_italic_flag);
2666
2667         }
2668
2669         gl_debug (DEBUG_VIEW, "END");
2670 }
2671
2672 /*****************************************************************************/
2673 /* Set text alignment for all text contained in selected objects.            */
2674 /*****************************************************************************/
2675 void
2676 gl_view_set_selection_text_alignment (glView            *view,
2677                                       GtkJustification   text_alignment)
2678 {
2679         GList *p;
2680         glLabelObject *object;
2681
2682         gl_debug (DEBUG_VIEW, "START");
2683
2684         g_return_if_fail (view && GL_IS_VIEW (view));
2685
2686         for (p = view->selected_object_list; p != NULL; p = p->next) {
2687
2688                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2689                 gl_label_object_set_text_alignment (object, text_alignment);
2690
2691         }
2692
2693         gl_debug (DEBUG_VIEW, "END");
2694 }
2695
2696 /*****************************************************************************/
2697 /* Set text color for all text contained in selected objects.                */
2698 /*****************************************************************************/
2699 void
2700 gl_view_set_selection_text_color (glView            *view,
2701                                   guint              text_color)
2702 {
2703         GList *p;
2704         glLabelObject *object;
2705
2706         gl_debug (DEBUG_VIEW, "START");
2707
2708         g_return_if_fail (view && GL_IS_VIEW (view));
2709
2710         for (p = view->selected_object_list; p != NULL; p = p->next) {
2711
2712                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2713                 gl_label_object_set_text_color (object, text_color);
2714
2715         }
2716
2717         gl_debug (DEBUG_VIEW, "END");
2718 }
2719
2720 /*****************************************************************************/
2721 /* Can fill properties be set for selection?                                 */
2722 /*****************************************************************************/
2723 gboolean
2724 gl_view_can_selection_fill (glView            *view)
2725 {
2726         GList *p;
2727         glLabelObject *object;
2728
2729         gl_debug (DEBUG_VIEW, "");
2730
2731         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2732
2733         for (p = view->selected_object_list; p != NULL; p = p->next) {
2734
2735                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2736                 if (gl_label_object_can_fill (object)) {
2737                         return TRUE;
2738                 }
2739
2740         }
2741
2742         return FALSE;
2743 }
2744
2745 /*****************************************************************************/
2746 /* Set fill color for all selected objects.                                  */
2747 /*****************************************************************************/
2748 void
2749 gl_view_set_selection_fill_color (glView            *view,
2750                                   guint              fill_color)
2751 {
2752         GList *p;
2753         glLabelObject *object;
2754
2755         gl_debug (DEBUG_VIEW, "START");
2756
2757         g_return_if_fail (view && GL_IS_VIEW (view));
2758
2759         for (p = view->selected_object_list; p != NULL; p = p->next) {
2760
2761                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2762                 gl_label_object_set_fill_color (object, fill_color);
2763
2764         }
2765
2766         gl_debug (DEBUG_VIEW, "END");
2767 }
2768
2769 /*****************************************************************************/
2770 /* Can line color properties be set for selection?                           */
2771 /*****************************************************************************/
2772 gboolean
2773 gl_view_can_selection_line_color (glView            *view)
2774 {
2775         GList *p;
2776         glLabelObject *object;
2777
2778         gl_debug (DEBUG_VIEW, "");
2779
2780         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2781
2782         for (p = view->selected_object_list; p != NULL; p = p->next) {
2783
2784                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2785                 if (gl_label_object_can_line_color (object)) {
2786                         return TRUE;
2787                 }
2788
2789         }
2790
2791         return FALSE;
2792 }
2793
2794 /*****************************************************************************/
2795 /* Set line color for all selected objects.                                  */
2796 /*****************************************************************************/
2797 void
2798 gl_view_set_selection_line_color (glView            *view,
2799                                   guint              line_color)
2800 {
2801         GList *p;
2802         glLabelObject *object;
2803
2804         gl_debug (DEBUG_VIEW, "START");
2805
2806         g_return_if_fail (view && GL_IS_VIEW (view));
2807
2808         for (p = view->selected_object_list; p != NULL; p = p->next) {
2809
2810                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2811                 gl_label_object_set_line_color (object, line_color);
2812
2813         }
2814
2815         gl_debug (DEBUG_VIEW, "END");
2816 }
2817
2818 /*****************************************************************************/
2819 /* Can line width properties be set for selection?                           */
2820 /*****************************************************************************/
2821 gboolean
2822 gl_view_can_selection_line_width (glView            *view)
2823 {
2824         GList *p;
2825         glLabelObject *object;
2826
2827         gl_debug (DEBUG_VIEW, "");
2828
2829         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2830
2831         for (p = view->selected_object_list; p != NULL; p = p->next) {
2832
2833                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2834                 if (gl_label_object_can_line_width (object)) {
2835                         return TRUE;
2836                 }
2837
2838         }
2839
2840         return FALSE;
2841 }
2842
2843 /*****************************************************************************/
2844 /* Set line width for all selected objects.                                  */
2845 /*****************************************************************************/
2846 void
2847 gl_view_set_selection_line_width (glView            *view,
2848                                   gdouble            line_width)
2849 {
2850         GList *p;
2851         glLabelObject *object;
2852
2853         gl_debug (DEBUG_VIEW, "START");
2854
2855         g_return_if_fail (view && GL_IS_VIEW (view));
2856
2857         for (p = view->selected_object_list; p != NULL; p = p->next) {
2858
2859                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2860                 gl_label_object_set_line_width (object, line_width);
2861
2862         }
2863
2864         gl_debug (DEBUG_VIEW, "END");
2865 }
2866
2867 /*****************************************************************************/
2868 /* "Cut" selected items and place in clipboard selections.                   */
2869 /*****************************************************************************/
2870 void
2871 gl_view_cut (glView *view)
2872 {
2873         gl_debug (DEBUG_VIEW, "START");
2874
2875         g_return_if_fail (view && GL_IS_VIEW (view));
2876
2877         gl_view_copy (view);
2878         gl_view_delete_selection (view);
2879
2880         gl_debug (DEBUG_VIEW, "END");
2881 }
2882
2883 /*****************************************************************************/
2884 /* "Copy" selected items to clipboard selections.                            */
2885 /*****************************************************************************/
2886 void
2887 gl_view_copy (glView *view)
2888 {
2889         GList *p;
2890         glViewObject *view_object;
2891         glLabelObject *object;
2892         glTemplate *template;
2893         gboolean rotate_flag;
2894
2895         gl_debug (DEBUG_VIEW, "START");
2896
2897         g_return_if_fail (view && GL_IS_VIEW (view));
2898
2899         if (view->selected_object_list) {
2900
2901                 if ( view->selection_data ) {
2902                         g_object_unref (view->selection_data);
2903                 }
2904                 template = gl_label_get_template (view->label);
2905                 rotate_flag = gl_label_get_rotate_flag (view->label);
2906                 view->selection_data = GL_LABEL(gl_label_new ());
2907                 gl_label_set_template (view->selection_data, template);
2908                 gl_label_set_rotate_flag (view->selection_data, rotate_flag);
2909                 gl_template_free (&template);
2910
2911                 for (p = view->selected_object_list; p != NULL; p = p->next) {
2912
2913                         view_object = GL_VIEW_OBJECT (p->data);
2914                         object = gl_view_object_get_object (view_object);
2915
2916                         gl_label_object_dup (object, view->selection_data);
2917
2918                 }
2919
2920                 gtk_selection_owner_set (view->invisible,
2921                                          clipboard_atom, GDK_CURRENT_TIME);
2922                 view->have_selection = TRUE;
2923
2924         }
2925
2926         gl_debug (DEBUG_VIEW, "END");
2927 }
2928
2929 /*****************************************************************************/
2930 /* "Paste" from private clipboard selection.                                 */
2931 /*****************************************************************************/
2932 void
2933 gl_view_paste (glView *view)
2934 {
2935         gl_debug (DEBUG_VIEW, "START");
2936
2937         g_return_if_fail (view && GL_IS_VIEW (view));
2938
2939         gtk_selection_convert (GTK_WIDGET (view->invisible),
2940                                clipboard_atom, GDK_SELECTION_TYPE_STRING,
2941                                GDK_CURRENT_TIME);
2942
2943         gl_debug (DEBUG_VIEW, "END");
2944 }
2945
2946 /*****************************************************************************/
2947 /* Zoom in one "notch"                                                       */
2948 /*****************************************************************************/
2949 void
2950 gl_view_zoom_in (glView *view)
2951 {
2952         gint i, i_min;
2953         gdouble dist, dist_min;
2954
2955         gl_debug (DEBUG_VIEW, "START");
2956
2957         g_return_if_fail (view && GL_IS_VIEW (view));
2958
2959         /* Find index of current scale (or best match) */
2960         i_min = 1;              /* start with 2nd largest scale */
2961         dist_min = fabs (scales[1] - view->scale);
2962         for (i = 2; i < N_SCALES; i++) {
2963                 dist = fabs (scales[i] - view->scale);
2964                 if (dist < dist_min) {
2965                         i_min = i;
2966                         dist_min = dist;
2967                 }
2968         }
2969
2970         /* zoom in one "notch" */
2971         i = MAX (0, i_min - 1);
2972         gl_view_set_zoom (view, scales[i] / HOME_SCALE);
2973
2974         gl_debug (DEBUG_VIEW, "END");
2975 }
2976
2977 /*****************************************************************************/
2978 /* Zoom out one "notch"                                                      */
2979 /*****************************************************************************/
2980 void
2981 gl_view_zoom_out (glView *view)
2982 {
2983         gint i, i_min;
2984         gdouble dist, dist_min;
2985
2986         gl_debug (DEBUG_VIEW, "START");
2987
2988         g_return_if_fail (view && GL_IS_VIEW (view));
2989
2990         /* Find index of current scale (or best match) */
2991         i_min = 0;              /* start with largest scale */
2992         dist_min = fabs (scales[0] - view->scale);
2993         for (i = 1; i < N_SCALES; i++) {
2994                 dist = fabs (scales[i] - view->scale);
2995                 if (dist < dist_min) {
2996                         i_min = i;
2997                         dist_min = dist;
2998                 }
2999         }
3000
3001         /* zoom out one "notch" */
3002         if (i_min >= N_SCALES)
3003                 return;
3004         i = i_min + 1;
3005         if (i >= N_SCALES)
3006                 return;
3007         gl_view_set_zoom (view, scales[i] / HOME_SCALE);
3008
3009         gl_debug (DEBUG_VIEW, "END");
3010 }
3011
3012 /*****************************************************************************/
3013 /* Set current zoom factor to explicit value.                                */
3014 /*****************************************************************************/
3015 void
3016 gl_view_set_zoom (glView  *view,
3017                   gdouble scale)
3018 {
3019         gl_debug (DEBUG_VIEW, "START");
3020
3021         g_return_if_fail (view && GL_IS_VIEW (view));
3022         g_return_if_fail (scale > 0.0);
3023
3024         view->scale = scale * HOME_SCALE;
3025         gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
3026                                           scale * HOME_SCALE);
3027
3028         g_signal_emit (G_OBJECT(view), signals[ZOOM_CHANGED], 0, scale);
3029
3030         gl_debug (DEBUG_VIEW, "END");
3031 }
3032
3033 /*****************************************************************************/
3034 /* Get current zoom factor.                                                  */
3035 /*****************************************************************************/
3036 gdouble
3037 gl_view_get_zoom (glView *view)
3038 {
3039         gl_debug (DEBUG_VIEW, "");
3040
3041         g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
3042
3043         return view->scale / HOME_SCALE;
3044 }
3045
3046 /*****************************************************************************/
3047 /* Is this the maximum zoom level.                                           */
3048 /*****************************************************************************/
3049 gboolean
3050 gl_view_is_zoom_max (glView *view)
3051 {
3052         gl_debug (DEBUG_VIEW, "");
3053
3054         g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
3055
3056         return view->scale >= scales[0];
3057 }
3058
3059 /*****************************************************************************/
3060 /* Is this the minimum zoom level.                                           */
3061 /*****************************************************************************/
3062 gboolean
3063 gl_view_is_zoom_min (glView *view)
3064 {
3065         gl_debug (DEBUG_VIEW, "");
3066
3067         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3068
3069         return view->scale <= scales[N_SCALES-1];
3070 }
3071
3072 /*****************************************************************************/
3073 /* Launch merge properties dialog.                                           */
3074 /*****************************************************************************/
3075 void
3076 gl_view_edit_merge_props (glView *view)
3077 {
3078         gl_debug (DEBUG_VIEW, "");
3079
3080         g_return_if_fail (view && GL_IS_VIEW (view));
3081
3082         if (view->merge_props_dialog != NULL) {
3083                 gtk_widget_show_all (view->merge_props_dialog);
3084                 gtk_window_present (GTK_WINDOW(view->merge_props_dialog));
3085                 return;
3086         }
3087
3088         view->merge_props_dialog = gl_merge_properties_dialog_new (view);
3089         gtk_widget_show_all (view->merge_props_dialog);
3090
3091         g_signal_connect (G_OBJECT(view->merge_props_dialog), "destroy",
3092                           G_CALLBACK (gtk_widget_destroyed),
3093                           &view->merge_props_dialog);
3094 }
3095
3096 /*---------------------------------------------------------------------------*/
3097 /* PRIVATE.  Canvas event handler.                                           */
3098 /*---------------------------------------------------------------------------*/
3099 static int
3100 canvas_event (GnomeCanvas *canvas,
3101               GdkEvent    *event,
3102               glView      *view)
3103 {
3104         gdouble x, y;
3105
3106         gl_debug (DEBUG_VIEW, "");
3107
3108         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3109
3110         /* emit pointer signals regardless of state */
3111         switch (event->type) {
3112         case GDK_MOTION_NOTIFY:
3113                 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
3114                 gnome_canvas_window_to_world (canvas,
3115                                               event->motion.x,
3116                                               event->motion.y, &x, &y);
3117                 g_signal_emit (G_OBJECT(view), signals[POINTER_MOVED], 0, x, y);
3118                 break; /* fall through */
3119
3120         case GDK_LEAVE_NOTIFY:
3121                 gl_debug (DEBUG_VIEW, "LEAVEW_NOTIFY");
3122                 g_signal_emit (G_OBJECT(view), signals[POINTER_EXIT], 0);
3123                 break; /* fall through */
3124
3125         default:
3126                 break; /* fall through */
3127         }
3128
3129
3130         switch (view->state) {
3131
3132         case GL_VIEW_STATE_ARROW:
3133                 return canvas_event_arrow_mode (canvas, event, view);
3134
3135         case GL_VIEW_STATE_OBJECT_CREATE:
3136                 switch (view->create_type) {
3137                 case GL_LABEL_OBJECT_BOX:
3138                         return gl_view_box_create_event_handler (canvas,
3139                                                                  event,
3140                                                                  view);
3141                         break;
3142                 case GL_LABEL_OBJECT_ELLIPSE:
3143                         return gl_view_ellipse_create_event_handler (canvas,
3144                                                                      event,
3145                                                                      view);
3146                         break;
3147                 case GL_LABEL_OBJECT_LINE:
3148                         return gl_view_line_create_event_handler (canvas,
3149                                                                   event,
3150                                                                   view);
3151                         break;
3152                 case GL_LABEL_OBJECT_IMAGE:
3153                         return gl_view_image_create_event_handler (canvas,
3154                                                                    event,
3155                                                                    view);
3156                         break;
3157                 case GL_LABEL_OBJECT_TEXT:
3158                         return gl_view_text_create_event_handler (canvas,
3159                                                                   event,
3160                                                                   view);
3161                         break;
3162                 case GL_LABEL_OBJECT_BARCODE:
3163                         return gl_view_barcode_create_event_handler (canvas,
3164                                                                      event,
3165                                                                      view);
3166                         break;
3167                 default:
3168                         /*Should not happen!*/
3169                         g_warning ("Invalid label object type.");
3170                         return FALSE;
3171         }
3172
3173         default:
3174                 g_warning ("Invalid view state.");      /*Should not happen!*/
3175                 return FALSE;
3176
3177         }
3178 }
3179
3180 /*---------------------------------------------------------------------------*/
3181 /* PRIVATE.  Canvas event handler (arrow mode)                               */
3182 /*---------------------------------------------------------------------------*/
3183 static int
3184 canvas_event_arrow_mode (GnomeCanvas *canvas,
3185                          GdkEvent    *event,
3186                          glView      *view)
3187 {
3188         static gdouble x0, y0;
3189         static gboolean dragging = FALSE;
3190         static GnomeCanvasItem *item;
3191         gdouble x, y, x1, y1, x2, y2;
3192         GnomeCanvasGroup *group;
3193         GdkCursor *cursor;
3194
3195         gl_debug (DEBUG_VIEW, "");
3196
3197         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3198
3199         switch (event->type) {
3200
3201         case GDK_BUTTON_PRESS:
3202                 gl_debug (DEBUG_VIEW, "BUTTON_PRESS");
3203                 switch (event->button.button) {
3204                 case 1:
3205                         gnome_canvas_window_to_world (canvas,
3206                                                       event->button.x,
3207                                                       event->button.y, &x, &y);
3208
3209                         if (!object_at (view, x, y)) {
3210                                 if (!(event->button.state & GDK_CONTROL_MASK)) {
3211                                         gl_view_unselect_all (view);
3212                                 }
3213
3214                                 dragging = TRUE;
3215                                 gnome_canvas_item_grab (canvas->root,
3216                                                         GDK_POINTER_MOTION_MASK |
3217                                                         GDK_BUTTON_RELEASE_MASK |
3218                                                         GDK_BUTTON_PRESS_MASK,
3219                                                         NULL, event->button.time);
3220                                 group =
3221                                     gnome_canvas_root (GNOME_CANVAS
3222                                                        (view->canvas));
3223                                 item =
3224                                     gnome_canvas_item_new (group,
3225                                                            gnome_canvas_rect_get_type (),
3226                                                            "x1", x, "y1", y,
3227                                                            "x2", x, "y2", y,
3228                                                            "width_pixels", 2,
3229                                                            "outline_color_rgba",
3230                                                            SEL_LINE_COLOR,
3231                                                            "fill_color_rgba",
3232                                                            SEL_FILL_COLOR,
3233                                                            NULL);
3234                                 x0 = x;
3235                                 y0 = y;
3236
3237                         }
3238                         return FALSE;
3239                 case 3:
3240                         gnome_canvas_window_to_world (canvas,
3241                                                       event->button.x,
3242                                                       event->button.y, &x, &y);
3243
3244                         if (!object_at (view, x, y)) {
3245                                 /* bring up apropriate menu for selection. */
3246                                 gl_view_popup_menu (view, event);
3247                         }
3248                         return FALSE;
3249                 default:
3250                         return FALSE;
3251                 }
3252
3253         case GDK_BUTTON_RELEASE:
3254                 gl_debug (DEBUG_VIEW, "BUTTON_RELEASE");
3255                 switch (event->button.button) {
3256                 case 1:
3257                         if (dragging) {
3258                                 dragging = FALSE;
3259                                 gnome_canvas_item_ungrab (canvas->root,
3260                                                           event->button.time);
3261                                 gnome_canvas_window_to_world (canvas,
3262                                                               event->button.x,
3263                                                               event->button.y,
3264                                                               &x, &y);
3265                                 x1 = MIN (x, x0);
3266                                 y1 = MIN (y, y0);
3267                                 x2 = MAX (x, x0);
3268                                 y2 = MAX (y, y0);
3269                                 gl_view_select_region (view, x1, y1, x2, y2);
3270                                 gtk_object_destroy (GTK_OBJECT (item));
3271                                 return TRUE;
3272                         }
3273                         return FALSE;
3274
3275                 default:
3276                         return FALSE;
3277                 }
3278
3279         case GDK_MOTION_NOTIFY:
3280                 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
3281                 gnome_canvas_window_to_world (canvas,
3282                                               event->motion.x,
3283                                               event->motion.y, &x, &y);
3284                 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
3285                         gnome_canvas_item_set (item,
3286                                                "x1", MIN (x, x0),
3287                                                "y1", MIN (y, y0),
3288                                                "x2", MAX (x, x0),
3289                                                "y2", MAX (y, y0), NULL);
3290                         return TRUE;
3291                 } else {
3292                         return FALSE;
3293                 }
3294
3295         case GDK_KEY_PRESS:
3296                 gl_debug (DEBUG_VIEW, "KEY_PRESS");
3297                 if (!dragging) {
3298                         switch (event->key.keyval) {
3299                         case GDK_Left:
3300                         case GDK_KP_Left:
3301                                 gl_view_move_selection (view,
3302                                                         -1.0 / (view->scale), 0.0);
3303                                 break;
3304                         case GDK_Up:
3305                         case GDK_KP_Up:
3306                                 gl_view_move_selection (view,
3307                                                         0.0, -1.0 / (view->scale));
3308                                 break;
3309                         case GDK_Right:
3310                         case GDK_KP_Right:
3311                                 gl_view_move_selection (view,
3312                                                         1.0 / (view->scale), 0.0);
3313                                 break;
3314                         case GDK_Down:
3315                         case GDK_KP_Down:
3316                                 gl_view_move_selection (view,
3317                                                         0.0, 1.0 / (view->scale));
3318                                 break;
3319                         case GDK_Delete:
3320                         case GDK_KP_Delete:
3321                                 gl_view_delete_selection (view);
3322                                 cursor = gdk_cursor_new (GDK_LEFT_PTR);
3323                                 gdk_window_set_cursor (view->canvas->window,
3324                                                        cursor);
3325                                 gdk_cursor_unref (cursor);
3326                                 break;
3327                         default:
3328                                 return FALSE;
3329                         }
3330                 }
3331                 return TRUE;    /* We handled this or we were dragging. */
3332
3333         default:
3334                 gl_debug (DEBUG_VIEW, "default");
3335                 return FALSE;
3336         }
3337
3338 }
3339
3340 /*---------------------------------------------------------------------------*/
3341 /* PRIVATE.  create menu for selections.                                     */
3342 /*---------------------------------------------------------------------------*/
3343 void
3344 construct_selection_menu (glView *view)
3345 {
3346         GtkWidget *menu, *menuitem, *submenu;
3347
3348         gl_debug (DEBUG_VIEW, "START");
3349
3350         g_return_if_fail (view && GL_IS_VIEW (view));
3351
3352         menu = gtk_menu_new ();
3353
3354         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_PROPERTIES, NULL);
3355         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3356         gtk_widget_show (menuitem);
3357         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3358                                   G_CALLBACK (gl_view_edit_object_props), view);
3359         view->atomic_selection_items =
3360                 g_list_prepend (view->atomic_selection_items, menuitem);
3361
3362         /*
3363          * Separator -------------------------
3364          */
3365         menuitem = gtk_menu_item_new ();
3366         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3367         gtk_widget_show (menuitem);
3368
3369         /*
3370          * Submenu: Order
3371          */
3372         menuitem = gtk_menu_item_new_with_mnemonic (_("_Order"));
3373         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3374         gtk_widget_show (menuitem);
3375         submenu = gtk_menu_new ();
3376         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3377
3378         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ORDER_TOP, NULL);
3379         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3380         gtk_widget_show (menuitem);
3381         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3382                                   G_CALLBACK (gl_view_raise_selection), view);
3383
3384         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ORDER_BOTTOM, NULL);
3385         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3386         gtk_widget_show (menuitem);
3387         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3388                                   G_CALLBACK (gl_view_lower_selection), view);
3389
3390         /*
3391          * Submenu: Rotate/Flip
3392          */
3393         menuitem = gtk_menu_item_new_with_mnemonic (_("_Rotate/Flip"));
3394         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3395         gtk_widget_show (menuitem);
3396         submenu = gtk_menu_new ();
3397         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3398
3399         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ROTATE_LEFT, NULL);
3400         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3401         gtk_widget_show (menuitem);
3402         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3403                                   G_CALLBACK (gl_view_rotate_selection_left), view);
3404
3405         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ROTATE_RIGHT, NULL);
3406         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3407         gtk_widget_show (menuitem);
3408         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3409                                   G_CALLBACK (gl_view_rotate_selection_right), view);
3410
3411         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_FLIP_HORIZ, NULL);
3412         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3413         gtk_widget_show (menuitem);
3414         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3415                                   G_CALLBACK (gl_view_flip_selection_horiz), view);
3416
3417         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_FLIP_VERT, NULL);
3418         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3419         gtk_widget_show (menuitem);
3420         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3421                                   G_CALLBACK (gl_view_flip_selection_vert), view);
3422
3423         /*
3424          * Submenu: Align Horizontally
3425          */
3426         menuitem = gtk_menu_item_new_with_mnemonic (_("Align _Horizontally"));
3427         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3428         gtk_widget_show (menuitem);
3429         submenu = gtk_menu_new ();
3430         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3431
3432         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_LEFT, NULL);
3433         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3434         gtk_widget_show (menuitem);
3435         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3436                                   G_CALLBACK (gl_view_align_selection_left), view);
3437         view->multi_selection_items =
3438                 g_list_prepend (view->multi_selection_items, menuitem);
3439
3440         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_HCENTER, NULL);
3441         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3442         gtk_widget_show (menuitem);
3443         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3444                                   G_CALLBACK (gl_view_align_selection_hcenter), view);
3445         view->multi_selection_items =
3446                 g_list_prepend (view->multi_selection_items, menuitem);
3447
3448         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_RIGHT, NULL);
3449         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3450         gtk_widget_show (menuitem);
3451         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3452                                   G_CALLBACK (gl_view_align_selection_right), view);
3453         view->multi_selection_items =
3454                 g_list_prepend (view->multi_selection_items, menuitem);
3455
3456         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_CENTER_HORIZ, NULL);
3457         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3458         gtk_widget_show (menuitem);
3459         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3460                                   G_CALLBACK (gl_view_center_selection_horiz), view);
3461
3462         /*
3463          * Submenu: Align Vertically
3464          */
3465         menuitem = gtk_menu_item_new_with_mnemonic (_("Align _Vertically"));
3466         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3467         gtk_widget_show (menuitem);
3468         submenu = gtk_menu_new ();
3469         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3470
3471         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_TOP, NULL);
3472         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3473         gtk_widget_show (menuitem);
3474         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3475                                   G_CALLBACK (gl_view_align_selection_top), view);
3476         view->multi_selection_items =
3477                 g_list_prepend (view->multi_selection_items, menuitem);
3478
3479         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_VCENTER, NULL);
3480         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3481         gtk_widget_show (menuitem);
3482         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3483                                   G_CALLBACK (gl_view_align_selection_vcenter), view);
3484         view->multi_selection_items =
3485                 g_list_prepend (view->multi_selection_items, menuitem);
3486
3487         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_BOTTOM, NULL);
3488         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3489         gtk_widget_show (menuitem);
3490         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3491                                   G_CALLBACK (gl_view_align_selection_bottom), view);
3492         view->multi_selection_items =
3493                 g_list_prepend (view->multi_selection_items, menuitem);
3494
3495         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_CENTER_VERT, NULL);
3496         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3497         gtk_widget_show (menuitem);
3498         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3499                                   G_CALLBACK (gl_view_center_selection_vert), view);
3500
3501         /*
3502          * Separator -------------------------
3503          */
3504         menuitem = gtk_menu_item_new ();
3505         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3506         gtk_widget_show (menuitem);
3507
3508         menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_CUT, NULL);
3509         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3510         gtk_widget_show (menuitem);
3511         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3512                                   G_CALLBACK (gl_view_cut), view);
3513
3514         menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_COPY, NULL);
3515         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3516         gtk_widget_show (menuitem);
3517         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3518                                   G_CALLBACK (gl_view_copy), view);
3519
3520         menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_PASTE, NULL);
3521         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3522         gtk_widget_show (menuitem);
3523         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3524                                   G_CALLBACK (gl_view_paste), view);
3525
3526         menuitem = gtk_menu_item_new_with_mnemonic (_("_Delete"));
3527         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3528         gtk_widget_show (menuitem);
3529         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3530                                   G_CALLBACK (gl_view_delete_selection), view);
3531
3532
3533         view->selection_menu = menu;
3534
3535         gl_debug (DEBUG_VIEW, "END");
3536 }
3537
3538 /*---------------------------------------------------------------------------*/
3539 /* PRIVATE.  create menu for empty selections.                               */
3540 /*---------------------------------------------------------------------------*/
3541 void
3542 construct_empty_selection_menu (glView *view)
3543 {
3544         GtkWidget *menu, *menuitem, *submenu;
3545
3546         gl_debug (DEBUG_VIEW, "START");
3547
3548         g_return_if_fail (view && GL_IS_VIEW (view));
3549
3550         menu = gtk_menu_new ();
3551
3552         menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_PASTE, NULL);
3553         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3554         gtk_widget_show (menuitem);
3555         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3556                                   G_CALLBACK (gl_view_paste), view);
3557
3558
3559         view->empty_selection_menu = menu;
3560
3561         gl_debug (DEBUG_VIEW, "END");
3562 }
3563
3564 /****************************************************************************/
3565 /* popup menu.                                                              */
3566 /****************************************************************************/
3567 void
3568 gl_view_popup_menu (glView       *view,
3569                     GdkEvent     *event)
3570 {
3571         GtkMenu *menu;
3572         GList   *p;
3573
3574         gl_debug (DEBUG_VIEW, "START");
3575
3576         g_return_if_fail (view && GL_IS_VIEW (view));
3577
3578         if (gl_view_is_selection_empty (view)) {
3579
3580                 if (view->empty_selection_menu != NULL) {
3581                         gtk_menu_popup (GTK_MENU (view->empty_selection_menu),
3582                                         NULL, NULL, NULL, NULL,
3583                                         event->button.button,
3584                                         event->button.time);
3585                 }
3586
3587         } else {
3588
3589                 for (p=view->atomic_selection_items; p!=NULL; p=p->next) {
3590                         gtk_widget_set_sensitive (GTK_WIDGET(p->data),
3591                                                   gl_view_is_selection_atomic(view));
3592                 }
3593
3594                 for (p=view->multi_selection_items; p!=NULL; p=p->next) {
3595                         gtk_widget_set_sensitive (GTK_WIDGET(p->data),
3596                                                   !gl_view_is_selection_atomic(view));
3597                 }
3598
3599                 if (view->selection_menu != NULL) {
3600                         gtk_menu_popup (GTK_MENU (view->selection_menu),
3601                                         NULL, NULL, NULL, NULL,
3602                                         event->button.button,
3603                                         event->button.time);
3604                 }
3605
3606         }
3607
3608         gl_debug (DEBUG_VIEW, "END");
3609 }
3610
3611 /*---------------------------------------------------------------------------*/
3612 /* PRIVATE.  Handle "selection-clear" signal.                                */
3613 /*---------------------------------------------------------------------------*/
3614 static void
3615 selection_clear_cb (GtkWidget         *widget,
3616                     GdkEventSelection *event,
3617                     gpointer          data)
3618 {
3619         glView *view = GL_VIEW (data);
3620
3621         gl_debug (DEBUG_VIEW, "START");
3622
3623         g_return_if_fail (view && GL_IS_VIEW (view));
3624
3625         view->have_selection = FALSE;
3626         g_object_unref (view->selection_data);
3627         view->selection_data = NULL;
3628
3629         gl_debug (DEBUG_VIEW, "END");
3630 }
3631
3632 /*---------------------------------------------------------------------------*/
3633 /* PRIVATE.  Handle "selection-get" signal.                                  */
3634 /*---------------------------------------------------------------------------*/
3635 static void
3636 selection_get_cb (GtkWidget        *widget,
3637                   GtkSelectionData *selection_data,
3638                   guint            info,
3639                   guint            time,
3640                   gpointer         data)
3641 {
3642         glView *view = GL_VIEW (data);
3643         gchar *buffer;
3644         glXMLLabelStatus status;
3645
3646         gl_debug (DEBUG_VIEW, "START");
3647
3648         g_return_if_fail (view && GL_IS_VIEW (view));
3649
3650         if (view->have_selection) {
3651
3652                 buffer = gl_xml_label_save_buffer (view->selection_data,
3653                                                    &status);
3654                 gtk_selection_data_set (selection_data,
3655                                         GDK_SELECTION_TYPE_STRING, 8, buffer,
3656                                         strlen (buffer));
3657                 g_free (buffer);
3658         }
3659
3660         gl_debug (DEBUG_VIEW, "END");
3661 }
3662
3663 /*---------------------------------------------------------------------------*/
3664 /* PRIVATE.  Handle "selection-received" signal.  (Result of Paste)          */
3665 /*---------------------------------------------------------------------------*/
3666 static void
3667 selection_received_cb (GtkWidget        *widget,
3668                        GtkSelectionData *selection_data,
3669                        guint            time,
3670                        gpointer         data)
3671 {
3672         glView *view = GL_VIEW (data);
3673         glLabel *label = NULL;
3674         glXMLLabelStatus status;
3675         GList *p, *p_next;
3676         glLabelObject *object, *newobject;
3677         glViewObject *view_object;
3678
3679         gl_debug (DEBUG_VIEW, "START");
3680
3681         g_return_if_fail (view && GL_IS_VIEW (view));
3682
3683         if (selection_data->length < 0) {
3684                 return;
3685         }
3686         if (selection_data->type != GDK_SELECTION_TYPE_STRING) {
3687                 return;
3688         }
3689
3690         gl_view_unselect_all (view);
3691
3692         label = gl_xml_label_open_buffer (selection_data->data, &status);
3693         for (p = label->objects; p != NULL; p = p_next) {
3694                 p_next = p->next;
3695
3696                 object = (glLabelObject *) p->data;
3697                 newobject = gl_label_object_dup (object, view->label);
3698
3699                 gl_debug (DEBUG_VIEW, "object pasted");
3700
3701                 if (GL_IS_LABEL_BOX (newobject)) {
3702                         view_object = gl_view_box_new (GL_LABEL_BOX(newobject),
3703                                                        view);
3704                 } else if (GL_IS_LABEL_ELLIPSE (newobject)) {
3705                         view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(newobject),
3706                                                            view);
3707                 } else if (GL_IS_LABEL_LINE (newobject)) {
3708                         view_object = gl_view_line_new (GL_LABEL_LINE(newobject),
3709                                                         view);
3710                 } else if (GL_IS_LABEL_IMAGE (newobject)) {
3711                         view_object = gl_view_image_new (GL_LABEL_IMAGE(newobject),
3712                                                          view);
3713                 } else if (GL_IS_LABEL_TEXT (newobject)) {
3714                         view_object = gl_view_text_new (GL_LABEL_TEXT(newobject),
3715                                                         view);
3716                 } else if (GL_IS_LABEL_BARCODE (newobject)) {
3717                         view_object = gl_view_barcode_new (GL_LABEL_BARCODE(newobject),
3718                                                            view);
3719                 } else {
3720                         /* Should not happen! */
3721                         view_object = NULL;
3722                         g_warning ("Invalid label object type.");
3723                 }
3724                 gl_view_select_object (view, view_object);
3725         }
3726         g_object_unref (label);
3727
3728         gl_debug (DEBUG_VIEW, "END");
3729 }
3730
3731 /****************************************************************************/
3732 /* Set default font family.                                                 */
3733 /****************************************************************************/
3734 void
3735 gl_view_set_default_font_family (glView            *view,
3736                                  const gchar       *font_family)
3737 {
3738         gl_debug (DEBUG_VIEW, "START");
3739
3740         g_return_if_fail (view && GL_IS_VIEW (view));
3741
3742         if (view->default_font_family) {
3743                 g_free (view->default_font_family);
3744         }
3745         view->default_font_family = g_strdup (font_family);
3746
3747         gl_debug (DEBUG_VIEW, "END");
3748 }
3749
3750
3751 /****************************************************************************/
3752 /* Set default font size.                                                   */
3753 /****************************************************************************/
3754 void
3755 gl_view_set_default_font_size (glView            *view,
3756                                gdouble            font_size)
3757 {
3758         gl_debug (DEBUG_VIEW, "START");
3759
3760         g_return_if_fail (view && GL_IS_VIEW (view));
3761
3762         view->default_font_size = font_size;
3763
3764         gl_debug (DEBUG_VIEW, "END");
3765 }
3766
3767
3768 /****************************************************************************/
3769 /* Set default font weight.                                                 */
3770 /****************************************************************************/
3771 void
3772 gl_view_set_default_font_weight (glView            *view,
3773                                  GnomeFontWeight    font_weight)
3774 {
3775         gl_debug (DEBUG_VIEW, "START");
3776
3777         g_return_if_fail (view && GL_IS_VIEW (view));
3778
3779         view->default_font_weight = font_weight;
3780
3781         gl_debug (DEBUG_VIEW, "END");
3782 }
3783
3784
3785 /****************************************************************************/
3786 /* Set default font italic flag.                                            */
3787 /****************************************************************************/
3788 void
3789 gl_view_set_default_font_italic_flag (glView            *view,
3790                                       gboolean           font_italic_flag)
3791 {
3792         gl_debug (DEBUG_VIEW, "START");
3793
3794         g_return_if_fail (view && GL_IS_VIEW (view));
3795
3796         view->default_font_italic_flag = font_italic_flag;
3797
3798         gl_debug (DEBUG_VIEW, "END");
3799 }
3800
3801
3802 /****************************************************************************/
3803 /* Set default text color.                                                  */
3804 /****************************************************************************/
3805 void
3806 gl_view_set_default_text_color (glView            *view,
3807                                 guint              text_color)
3808 {
3809         gl_debug (DEBUG_VIEW, "START");
3810
3811         g_return_if_fail (view && GL_IS_VIEW (view));
3812
3813         view->default_text_color = text_color;
3814
3815         gl_debug (DEBUG_VIEW, "END");
3816 }
3817
3818
3819 /****************************************************************************/
3820 /* Set default text alignment.                                              */
3821 /****************************************************************************/
3822 void
3823 gl_view_set_default_text_alignment (glView            *view,
3824                                     GtkJustification   text_alignment)
3825 {
3826         gl_debug (DEBUG_VIEW, "START");
3827
3828         g_return_if_fail (view && GL_IS_VIEW (view));
3829
3830         view->default_text_alignment = text_alignment;
3831         gl_debug (DEBUG_VIEW, "END");
3832 }
3833
3834
3835 /****************************************************************************/
3836 /* Set default line width.                                                  */
3837 /****************************************************************************/
3838 void
3839 gl_view_set_default_line_width (glView            *view,
3840                                 gdouble            line_width)
3841 {
3842         gl_debug (DEBUG_VIEW, "START");
3843
3844         g_return_if_fail (view && GL_IS_VIEW (view));
3845
3846         view->default_line_width = line_width;
3847
3848         gl_debug (DEBUG_VIEW, "END");
3849 }
3850
3851
3852 /****************************************************************************/
3853 /* Set default line color.                                                  */
3854 /****************************************************************************/
3855 void
3856 gl_view_set_default_line_color (glView            *view,
3857                                 guint              line_color)
3858 {
3859         gl_debug (DEBUG_VIEW, "START");
3860
3861         g_return_if_fail (view && GL_IS_VIEW (view));
3862
3863         view->default_line_color = line_color;
3864
3865         gl_debug (DEBUG_VIEW, "END");
3866 }
3867
3868
3869 /****************************************************************************/
3870 /* Set default fill color.                                                  */
3871 /****************************************************************************/
3872 void
3873 gl_view_set_default_fill_color (glView            *view,
3874                                 guint              fill_color)
3875 {
3876         gl_debug (DEBUG_VIEW, "START");
3877
3878         g_return_if_fail (view && GL_IS_VIEW (view));
3879
3880         view->default_fill_color = fill_color;
3881
3882         gl_debug (DEBUG_VIEW, "END");
3883 }
3884
3885
3886
3887 /****************************************************************************/
3888 /* Get default font family.                                                 */
3889 /****************************************************************************/
3890 gchar *
3891 gl_view_get_default_font_family (glView            *view)
3892 {
3893         gl_debug (DEBUG_VIEW, "START");
3894
3895         g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
3896
3897         gl_debug (DEBUG_VIEW, "END");
3898
3899         return g_strdup (view->default_font_family);
3900 }
3901
3902
3903 /****************************************************************************/
3904 /* Get default font size.                                                   */
3905 /****************************************************************************/
3906 gdouble
3907 gl_view_get_default_font_size (glView            *view)
3908 {
3909         gl_debug (DEBUG_VIEW, "START");
3910
3911         g_return_val_if_fail (view && GL_IS_VIEW (view), 12.0);
3912
3913         gl_debug (DEBUG_VIEW, "END");
3914
3915         return view->default_font_size;
3916 }
3917
3918
3919 /****************************************************************************/
3920 /* Get default font weight.                                                 */
3921 /****************************************************************************/
3922 GnomeFontWeight
3923 gl_view_get_default_font_weight (glView            *view)
3924 {
3925         gl_debug (DEBUG_VIEW, "START");
3926
3927         g_return_val_if_fail (view && GL_IS_VIEW (view), GNOME_FONT_BOOK);
3928
3929         gl_debug (DEBUG_VIEW, "END");
3930
3931         return view->default_font_weight;
3932 }
3933
3934
3935 /****************************************************************************/
3936 /* Get default font italic flag.                                            */
3937 /****************************************************************************/
3938 gboolean
3939 gl_view_get_default_font_italic_flag (glView            *view)
3940 {
3941         gl_debug (DEBUG_VIEW, "START");
3942
3943         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3944
3945         gl_debug (DEBUG_VIEW, "END");
3946
3947         return view->default_font_italic_flag;
3948 }
3949
3950
3951 /****************************************************************************/
3952 /* Get default text color.                                                  */
3953 /****************************************************************************/
3954 guint
3955 gl_view_get_default_text_color (glView            *view)
3956 {
3957         gl_debug (DEBUG_VIEW, "START");
3958
3959         g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
3960
3961         gl_debug (DEBUG_VIEW, "END");
3962
3963         return view->default_text_color;
3964 }
3965
3966
3967 /****************************************************************************/
3968 /* Get default text alignment.                                              */
3969 /****************************************************************************/
3970 GtkJustification
3971 gl_view_get_default_text_alignment (glView            *view)
3972 {
3973         gl_debug (DEBUG_VIEW, "START");
3974
3975         g_return_val_if_fail (view && GL_IS_VIEW (view), GTK_JUSTIFY_LEFT);
3976
3977         gl_debug (DEBUG_VIEW, "END");
3978
3979         return view->default_text_alignment;
3980 }
3981
3982
3983 /****************************************************************************/
3984 /* Get default line width.                                                  */
3985 /****************************************************************************/
3986 gdouble
3987 gl_view_get_default_line_width (glView            *view)
3988 {
3989         gl_debug (DEBUG_VIEW, "START");
3990
3991         g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
3992
3993         gl_debug (DEBUG_VIEW, "END");
3994
3995         return view->default_line_width;
3996 }
3997
3998
3999 /****************************************************************************/
4000 /* Get default line color.                                                  */
4001 /****************************************************************************/
4002 guint gl_view_get_default_line_color (glView            *view)
4003 {
4004         gl_debug (DEBUG_VIEW, "START");
4005
4006         g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
4007
4008         gl_debug (DEBUG_VIEW, "END");
4009
4010         return view->default_line_color;
4011 }
4012
4013
4014 /****************************************************************************/
4015 /* Get default fill color.                                                  */
4016 /****************************************************************************/
4017 guint gl_view_get_default_fill_color (glView            *view)
4018 {
4019         gl_debug (DEBUG_VIEW, "START");
4020
4021         g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
4022
4023         gl_debug (DEBUG_VIEW, "END");
4024
4025         return view->default_fill_color;
4026 }
4027