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