]> git.sur5r.net Git - glabels/blob - glabels2/src/view.c
Make sure canvas will regain focus if clicked on.
[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 *p, *p_next;
2008
2009         gl_debug (DEBUG_VIEW, "START");
2010
2011         g_return_if_fail (view && GL_IS_VIEW (view));
2012
2013         for (p = view->selected_object_list; p != NULL; p = p_next) {
2014                 p_next = p->next;
2015                 g_object_unref (G_OBJECT (p->data));
2016         }
2017
2018         g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
2019
2020         gl_debug (DEBUG_VIEW, "END");
2021 }
2022
2023 /*****************************************************************************/
2024 /* Get object property editor of first selected object.                      */
2025 /*****************************************************************************/
2026 GtkWidget *
2027 gl_view_get_editor (glView *view)
2028 {
2029         glViewObject *view_object;
2030         GtkWidget    *editor = NULL;
2031
2032         gl_debug (DEBUG_VIEW, "START");
2033
2034         g_return_if_fail (view && GL_IS_VIEW (view));
2035
2036         if (!gl_view_is_selection_empty (view)) {
2037
2038                 view_object = GL_VIEW_OBJECT(view->selected_object_list->data);
2039                 editor = gl_view_object_get_editor (view_object);
2040
2041         }
2042
2043         gl_debug (DEBUG_VIEW, "END");
2044
2045         return editor;
2046 }
2047
2048 /*****************************************************************************/
2049 /* Raise selected items to top.                                              */
2050 /*****************************************************************************/
2051 void
2052 gl_view_raise_selection (glView *view)
2053 {
2054         GList         *p;
2055         glViewObject  *view_object;
2056         glLabelObject *object;
2057
2058         gl_debug (DEBUG_VIEW, "START");
2059
2060         g_return_if_fail (view && GL_IS_VIEW (view));
2061
2062         for (p = view->selected_object_list; p != NULL; p = p->next) {
2063                 view_object = GL_VIEW_OBJECT (p->data);
2064                 object = gl_view_object_get_object (view_object);
2065                 gl_label_object_raise_to_top (object);
2066         }
2067
2068         gl_debug (DEBUG_VIEW, "END");
2069 }
2070
2071 /*****************************************************************************/
2072 /* Lower selected items to bottom.                                           */
2073 /*****************************************************************************/
2074 void
2075 gl_view_lower_selection (glView *view)
2076 {
2077         GList         *p;
2078         glViewObject  *view_object;
2079         glLabelObject *object;
2080
2081         gl_debug (DEBUG_VIEW, "START");
2082
2083         g_return_if_fail (view && GL_IS_VIEW (view));
2084
2085         for (p = view->selected_object_list; p != NULL; p = p->next) {
2086                 view_object = GL_VIEW_OBJECT (p->data);
2087                 object = gl_view_object_get_object (view_object);
2088                 gl_label_object_lower_to_bottom (object);
2089         }
2090
2091         gl_debug (DEBUG_VIEW, "END");
2092 }
2093
2094 /*****************************************************************************/
2095 /* Rotate selected objects by given angle.                                   */
2096 /*****************************************************************************/
2097 void
2098 gl_view_rotate_selection (glView *view,
2099                           gdouble theta_degs)
2100 {
2101         GList         *p;
2102         glViewObject  *view_object;
2103         glLabelObject *object;
2104
2105         gl_debug (DEBUG_VIEW, "START");
2106
2107         g_return_if_fail (view && GL_IS_VIEW (view));
2108
2109         for (p = view->selected_object_list; p != NULL; p = p->next) {
2110                 view_object = GL_VIEW_OBJECT (p->data);
2111                 object = gl_view_object_get_object (view_object);
2112                 gl_label_object_rotate (object, theta_degs);
2113         }
2114
2115         gl_debug (DEBUG_VIEW, "END");
2116 }
2117
2118 /*****************************************************************************/
2119 /* Rotate selected objects 90 degrees left.                                  */
2120 /*****************************************************************************/
2121 void
2122 gl_view_rotate_selection_left (glView *view)
2123 {
2124         GList         *p;
2125         glViewObject  *view_object;
2126         glLabelObject *object;
2127
2128         gl_debug (DEBUG_VIEW, "START");
2129
2130         g_return_if_fail (view && GL_IS_VIEW (view));
2131
2132         for (p = view->selected_object_list; p != NULL; p = p->next) {
2133                 view_object = GL_VIEW_OBJECT (p->data);
2134                 object = gl_view_object_get_object (view_object);
2135                 gl_label_object_rotate (object, -90.0);
2136         }
2137
2138         gl_debug (DEBUG_VIEW, "END");
2139 }
2140
2141 /*****************************************************************************/
2142 /* Rotate selected objects 90 degrees right.                                 */
2143 /*****************************************************************************/
2144 void
2145 gl_view_rotate_selection_right (glView *view)
2146 {
2147         GList         *p;
2148         glViewObject  *view_object;
2149         glLabelObject *object;
2150
2151         gl_debug (DEBUG_VIEW, "START");
2152
2153         g_return_if_fail (view && GL_IS_VIEW (view));
2154
2155         for (p = view->selected_object_list; p != NULL; p = p->next) {
2156                 view_object = GL_VIEW_OBJECT (p->data);
2157                 object = gl_view_object_get_object (view_object);
2158                 gl_label_object_rotate (object, 90.0);
2159         }
2160
2161         gl_debug (DEBUG_VIEW, "END");
2162 }
2163
2164 /*****************************************************************************/
2165 /* Flip selected objects horizontally.                                       */
2166 /*****************************************************************************/
2167 void
2168 gl_view_flip_selection_horiz (glView *view)
2169 {
2170         GList         *p;
2171         glViewObject  *view_object;
2172         glLabelObject *object;
2173
2174         gl_debug (DEBUG_VIEW, "START");
2175
2176         g_return_if_fail (view && GL_IS_VIEW (view));
2177
2178         for (p = view->selected_object_list; p != NULL; p = p->next) {
2179                 view_object = GL_VIEW_OBJECT (p->data);
2180                 object = gl_view_object_get_object (view_object);
2181                 gl_label_object_flip_horiz (object);
2182         }
2183
2184         gl_debug (DEBUG_VIEW, "END");
2185 }
2186
2187 /*****************************************************************************/
2188 /* Flip selected objects vertically.                                         */
2189 /*****************************************************************************/
2190 void
2191 gl_view_flip_selection_vert (glView *view)
2192 {
2193         GList         *p;
2194         glViewObject  *view_object;
2195         glLabelObject *object;
2196
2197         gl_debug (DEBUG_VIEW, "START");
2198
2199         g_return_if_fail (view && GL_IS_VIEW (view));
2200
2201         for (p = view->selected_object_list; p != NULL; p = p->next) {
2202                 view_object = GL_VIEW_OBJECT (p->data);
2203                 object = gl_view_object_get_object (view_object);
2204                 gl_label_object_flip_vert (object);
2205         }
2206
2207         gl_debug (DEBUG_VIEW, "END");
2208 }
2209
2210 /*****************************************************************************/
2211 /* Align selected objects to left most edge.                                 */
2212 /*****************************************************************************/
2213 void
2214 gl_view_align_selection_left (glView *view)
2215 {
2216         GList         *p;
2217         glViewObject  *view_object;
2218         glLabelObject *object;
2219         gdouble        dx, x1min, x1, y1, x2, y2;
2220
2221         gl_debug (DEBUG_VIEW, "START");
2222
2223         g_return_if_fail (view && GL_IS_VIEW (view));
2224
2225         g_return_if_fail (!gl_view_is_selection_empty (view) &&
2226                           !gl_view_is_selection_atomic (view));
2227
2228         /* find left most edge */
2229         p = view->selected_object_list;
2230         view_object = GL_VIEW_OBJECT (p->data);
2231         object = gl_view_object_get_object (view_object);
2232         gl_label_object_get_extent (object, &x1min, &y1, &x2, &y2);
2233         for (p = p->next; p != NULL; p = p->next) {
2234                 view_object = GL_VIEW_OBJECT (p->data);
2235                 object = gl_view_object_get_object (view_object);
2236                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2237                 if ( x1 < x1min ) x1min = x1;
2238         }
2239
2240         /* now adjust the object positions to line up the left edges */
2241         for (p = view->selected_object_list; p != NULL; p = p->next) {
2242                 view_object = GL_VIEW_OBJECT (p->data);
2243                 object = gl_view_object_get_object (view_object);
2244                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2245                 dx = x1min - x1;
2246                 gl_label_object_set_position_relative (object, dx, 0.0);
2247         }
2248
2249         gl_debug (DEBUG_VIEW, "END");
2250 }
2251
2252
2253 /*****************************************************************************/
2254 /* Align selected objects to right most edge.                                */
2255 /*****************************************************************************/
2256 void
2257 gl_view_align_selection_right (glView *view)
2258 {
2259         GList         *p;
2260         glViewObject  *view_object;
2261         glLabelObject *object;
2262         gdouble        dx, x2max, x1, y1, x2, y2;
2263
2264         gl_debug (DEBUG_VIEW, "START");
2265
2266         g_return_if_fail (view && GL_IS_VIEW (view));
2267
2268         g_return_if_fail (!gl_view_is_selection_empty (view) &&
2269                           !gl_view_is_selection_atomic (view));
2270
2271         /* find right most edge */
2272         p = view->selected_object_list;
2273         view_object = GL_VIEW_OBJECT (p->data);
2274         object = gl_view_object_get_object (view_object);
2275         gl_label_object_get_extent (object, &x1, &y1, &x2max, &y2);
2276         for (p = p->next; p != NULL; p = p->next) {
2277                 view_object = GL_VIEW_OBJECT (p->data);
2278                 object = gl_view_object_get_object (view_object);
2279                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2280                 if ( x2 > x2max ) x2max = x2;
2281         }
2282
2283         /* now adjust the object positions to line up the right edges */
2284         for (p = view->selected_object_list; p != NULL; p = p->next) {
2285                 view_object = GL_VIEW_OBJECT (p->data);
2286                 object = gl_view_object_get_object (view_object);
2287                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2288                 dx = x2max - x2;
2289                 gl_label_object_set_position_relative (object, dx, 0.0);
2290         }
2291
2292         gl_debug (DEBUG_VIEW, "END");
2293 }
2294
2295 /*****************************************************************************/
2296 /* Align selected objects to horizontal center of objects.                   */
2297 /*****************************************************************************/
2298 void
2299 gl_view_align_selection_hcenter (glView *view)
2300 {
2301         GList         *p;
2302         glViewObject  *view_object;
2303         glLabelObject *object;
2304         gdouble        dx, dxmin, xsum, xavg, xcenter, x1, y1, x2, y2;
2305         gint           n;
2306
2307         gl_debug (DEBUG_VIEW, "START");
2308
2309         g_return_if_fail (view && GL_IS_VIEW (view));
2310
2311         g_return_if_fail (!gl_view_is_selection_empty (view) &&
2312                           !gl_view_is_selection_atomic (view));
2313
2314         /* find average center of objects */
2315         xsum = 0.0;
2316         n = 0;
2317         for (p = view->selected_object_list; p != NULL; p = p->next) {
2318                 view_object = GL_VIEW_OBJECT (p->data);
2319                 object = gl_view_object_get_object (view_object);
2320                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2321                 xsum += (x1 + x2) / 2.0;
2322                 n++;
2323         }
2324         xavg = xsum / n;
2325
2326         /* find center of object closest to average center */
2327         p = view->selected_object_list;
2328         view_object = GL_VIEW_OBJECT (p->data);
2329         object = gl_view_object_get_object (view_object);
2330         gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2331         dxmin = fabs (xavg - (x1 + x2)/2.0);
2332         xcenter = (x1 + x2)/2.0;
2333         for (p = p->next; p != NULL; p = p->next) {
2334                 view_object = GL_VIEW_OBJECT (p->data);
2335                 object = gl_view_object_get_object (view_object);
2336                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2337                 dx = fabs (xavg - (x1 + x2)/2.0);
2338                 if ( dx < dxmin ) {
2339                         dxmin = dx;
2340                         xcenter = (x1 + x2)/2.0;
2341                 }
2342         }
2343
2344         /* now adjust the object positions to line up this center */
2345         for (p = view->selected_object_list; p != NULL; p = p->next) {
2346                 view_object = GL_VIEW_OBJECT (p->data);
2347                 object = gl_view_object_get_object (view_object);
2348                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2349                 dx = xcenter - (x1 + x2)/2.0;
2350                 gl_label_object_set_position_relative (object, dx, 0.0);
2351         }
2352
2353         gl_debug (DEBUG_VIEW, "END");
2354 }
2355
2356 /*****************************************************************************/
2357 /* Align selected objects to top most edge.                                  */
2358 /*****************************************************************************/
2359 void
2360 gl_view_align_selection_top (glView *view)
2361 {
2362         GList         *p;
2363         glViewObject  *view_object;
2364         glLabelObject *object;
2365         gdouble        dy, y1min, x1, y1, x2, y2;
2366
2367         gl_debug (DEBUG_VIEW, "START");
2368
2369         g_return_if_fail (view && GL_IS_VIEW (view));
2370
2371         g_return_if_fail (!gl_view_is_selection_empty (view) &&
2372                           !gl_view_is_selection_atomic (view));
2373
2374         /* find top most edge */
2375         p = view->selected_object_list;
2376         view_object = GL_VIEW_OBJECT (p->data);
2377         object = gl_view_object_get_object (view_object);
2378         gl_label_object_get_extent (object, &x1, &y1min, &x2, &y2);
2379         for (p = p->next; p != NULL; p = p->next) {
2380                 view_object = GL_VIEW_OBJECT (p->data);
2381                 object = gl_view_object_get_object (view_object);
2382                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2383                 if ( y1 < y1min ) y1min = y1;
2384         }
2385
2386         /* now adjust the object positions to line up the top edges */
2387         for (p = view->selected_object_list; p != NULL; p = p->next) {
2388                 view_object = GL_VIEW_OBJECT (p->data);
2389                 object = gl_view_object_get_object (view_object);
2390                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2391                 dy = y1min - y1;
2392                 gl_label_object_set_position_relative (object, 0.0, dy);
2393         }
2394
2395         gl_debug (DEBUG_VIEW, "END");
2396 }
2397
2398 /*****************************************************************************/
2399 /* Align selected objects to bottom most edge.                               */
2400 /*****************************************************************************/
2401 void
2402 gl_view_align_selection_bottom (glView *view)
2403 {
2404         GList         *p;
2405         glViewObject  *view_object;
2406         glLabelObject *object;
2407         gdouble        dy, y2max, x1, y1, x2, y2;
2408
2409         gl_debug (DEBUG_VIEW, "START");
2410
2411         g_return_if_fail (view && GL_IS_VIEW (view));
2412
2413         g_return_if_fail (!gl_view_is_selection_empty (view) &&
2414                           !gl_view_is_selection_atomic (view));
2415
2416         /* find bottom most edge */
2417         p = view->selected_object_list;
2418         view_object = GL_VIEW_OBJECT (p->data);
2419         object = gl_view_object_get_object (view_object);
2420         gl_label_object_get_extent (object, &x1, &y1, &x2, &y2max);
2421         for (p = p->next; p != NULL; p = p->next) {
2422                 view_object = GL_VIEW_OBJECT (p->data);
2423                 object = gl_view_object_get_object (view_object);
2424                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2425                 if ( y2 > y2max ) y2max = y2;
2426         }
2427
2428         /* now adjust the object positions to line up the bottom edges */
2429         for (p = view->selected_object_list; p != NULL; p = p->next) {
2430                 view_object = GL_VIEW_OBJECT (p->data);
2431                 object = gl_view_object_get_object (view_object);
2432                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2433                 dy = y2max - y2;
2434                 gl_label_object_set_position_relative (object, 0.0, dy);
2435         }
2436
2437         gl_debug (DEBUG_VIEW, "END");
2438 }
2439
2440 /*****************************************************************************/
2441 /* Align selected objects to viertical center of objects.                    */
2442 /*****************************************************************************/
2443 void
2444 gl_view_align_selection_vcenter (glView *view)
2445 {
2446         GList         *p;
2447         glViewObject  *view_object;
2448         glLabelObject *object;
2449         gdouble        dy, dymin, ysum, yavg, ycenter, x1, y1, x2, y2;
2450         gint           n;
2451
2452         gl_debug (DEBUG_VIEW, "START");
2453
2454         g_return_if_fail (view && GL_IS_VIEW (view));
2455
2456         g_return_if_fail (!gl_view_is_selection_empty (view) &&
2457                           !gl_view_is_selection_atomic (view));
2458
2459         /* find average center of objects */
2460         ysum = 0.0;
2461         n = 0;
2462         for (p = view->selected_object_list; p != NULL; p = p->next) {
2463                 view_object = GL_VIEW_OBJECT (p->data);
2464                 object = gl_view_object_get_object (view_object);
2465                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2466                 ysum += (y1 + y2) / 2.0;
2467                 n++;
2468         }
2469         yavg = ysum / n;
2470
2471         /* find center of object closest to average center */
2472         p = view->selected_object_list;
2473         view_object = GL_VIEW_OBJECT (p->data);
2474         object = gl_view_object_get_object (view_object);
2475         gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2476         dymin = fabs (yavg - (y1 + y2)/2.0);
2477         ycenter = (y1 + y2)/2.0;
2478         for (p = p->next; p != NULL; p = p->next) {
2479                 view_object = GL_VIEW_OBJECT (p->data);
2480                 object = gl_view_object_get_object (view_object);
2481                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2482                 dy = fabs (yavg - (y1 + y2)/2.0);
2483                 if ( dy < dymin ) {
2484                         dymin = dy;
2485                         ycenter = (y1 + y2)/2.0;
2486                 }
2487         }
2488
2489         /* now adjust the object positions to line up this center */
2490         for (p = view->selected_object_list; p != NULL; p = p->next) {
2491                 view_object = GL_VIEW_OBJECT (p->data);
2492                 object = gl_view_object_get_object (view_object);
2493                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2494                 dy = ycenter - (y1 + y2)/2.0;
2495                 gl_label_object_set_position_relative (object, 0.0, dy);
2496         }
2497
2498         gl_debug (DEBUG_VIEW, "END");
2499 }
2500
2501 /*****************************************************************************/
2502 /* Center selected objects to in center of label.                            */
2503 /*****************************************************************************/
2504 void
2505 gl_view_center_selection_horiz (glView *view)
2506 {
2507         GList         *p;
2508         glViewObject  *view_object;
2509         glLabelObject *object;
2510         gdouble        dx, x_label_center, x_obj_center, x1, y1, x2, y2, w, h;
2511
2512         gl_debug (DEBUG_VIEW, "START");
2513
2514         g_return_if_fail (view && GL_IS_VIEW (view));
2515
2516         g_return_if_fail (!gl_view_is_selection_empty (view));
2517
2518         gl_label_get_size (view->label, &w, &h);
2519         x_label_center = w / 2.0;
2520
2521         /* adjust the object positions */
2522         for (p = view->selected_object_list; p != NULL; p = p->next) {
2523                 view_object = GL_VIEW_OBJECT (p->data);
2524                 object = gl_view_object_get_object (view_object);
2525                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2526                 x_obj_center = (x1 + x2) / 2.0;
2527                 dx = x_label_center - x_obj_center;
2528                 gl_label_object_set_position_relative (object, dx, 0.0);
2529         }
2530
2531         gl_debug (DEBUG_VIEW, "END");
2532 }
2533
2534
2535 /*****************************************************************************/
2536 /* Center selected objects to in center of label.                            */
2537 /*****************************************************************************/
2538 void
2539 gl_view_center_selection_vert (glView *view)
2540 {
2541         GList         *p;
2542         glViewObject  *view_object;
2543         glLabelObject *object;
2544         gdouble        dy, y_label_center, y_obj_center, x1, y1, x2, y2, w, h;
2545
2546         gl_debug (DEBUG_VIEW, "START");
2547
2548         g_return_if_fail (view && GL_IS_VIEW (view));
2549
2550         g_return_if_fail (!gl_view_is_selection_empty (view));
2551
2552         gl_label_get_size (view->label, &w, &h);
2553         y_label_center = h / 2.0;
2554
2555         /* adjust the object positions */
2556         for (p = view->selected_object_list; p != NULL; p = p->next) {
2557                 view_object = GL_VIEW_OBJECT (p->data);
2558                 object = gl_view_object_get_object (view_object);
2559                 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2560                 y_obj_center = (y1 + y2) / 2.0;
2561                 dy = y_label_center - y_obj_center;
2562                 gl_label_object_set_position_relative (object, 0.0, dy);
2563         }
2564
2565         gl_debug (DEBUG_VIEW, "END");
2566 }
2567
2568
2569 /*****************************************************************************/
2570 /* Move selected objects                                                     */
2571 /*****************************************************************************/
2572 void
2573 gl_view_move_selection (glView  *view,
2574                 gdouble  dx,
2575                 gdouble  dy)
2576 {
2577         GList *p;
2578         glLabelObject *object;
2579
2580         gl_debug (DEBUG_VIEW, "START");
2581
2582         g_return_if_fail (view && GL_IS_VIEW (view));
2583
2584         for (p = view->selected_object_list; p != NULL; p = p->next) {
2585
2586                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2587                 gl_label_object_set_position_relative (object, dx, dy);
2588
2589         }
2590
2591         gl_debug (DEBUG_VIEW, "END");
2592 }
2593
2594 /*****************************************************************************/
2595 /* Can text properties be set for selection?                                 */
2596 /*****************************************************************************/
2597 gboolean
2598 gl_view_can_selection_text (glView            *view)
2599 {
2600         GList *p;
2601         glLabelObject *object;
2602
2603         gl_debug (DEBUG_VIEW, "");
2604
2605         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2606
2607         for (p = view->selected_object_list; p != NULL; p = p->next) {
2608
2609                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2610                 if (gl_label_object_can_text (object)) {
2611                         return TRUE;
2612                 }
2613
2614         }
2615
2616         return FALSE;
2617 }
2618
2619 /*****************************************************************************/
2620 /* Set font family for all text contained in selected objects.               */
2621 /*****************************************************************************/
2622 void
2623 gl_view_set_selection_font_family (glView            *view,
2624                                    const gchar       *font_family)
2625 {
2626         GList *p;
2627         glLabelObject *object;
2628
2629         gl_debug (DEBUG_VIEW, "START");
2630
2631         g_return_if_fail (view && GL_IS_VIEW (view));
2632
2633         for (p = view->selected_object_list; p != NULL; p = p->next) {
2634
2635                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2636                 gl_label_object_set_font_family (object, font_family);
2637
2638         }
2639
2640         gl_debug (DEBUG_VIEW, "END");
2641 }
2642
2643 /*****************************************************************************/
2644 /* Set font size for all text contained in selected objects.                 */
2645 /*****************************************************************************/
2646 void
2647 gl_view_set_selection_font_size (glView            *view,
2648                                  gdouble            font_size)
2649 {
2650         GList *p;
2651         glLabelObject *object;
2652
2653         gl_debug (DEBUG_VIEW, "START");
2654
2655         g_return_if_fail (view && GL_IS_VIEW (view));
2656
2657         for (p = view->selected_object_list; p != NULL; p = p->next) {
2658
2659                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2660                 gl_label_object_set_font_size (object, font_size);
2661
2662         }
2663
2664         gl_debug (DEBUG_VIEW, "END");
2665 }
2666
2667 /*****************************************************************************/
2668 /* Set font weight for all text contained in selected objects.               */
2669 /*****************************************************************************/
2670 void
2671 gl_view_set_selection_font_weight (glView            *view,
2672                                    GnomeFontWeight    font_weight)
2673 {
2674         GList *p;
2675         glLabelObject *object;
2676
2677         gl_debug (DEBUG_VIEW, "START");
2678
2679         g_return_if_fail (view && GL_IS_VIEW (view));
2680
2681         for (p = view->selected_object_list; p != NULL; p = p->next) {
2682
2683                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2684                 gl_label_object_set_font_weight (object, font_weight);
2685
2686         }
2687
2688         gl_debug (DEBUG_VIEW, "END");
2689 }
2690
2691 /*****************************************************************************/
2692 /* Set font italic flag for all text contained in selected objects.          */
2693 /*****************************************************************************/
2694 void
2695 gl_view_set_selection_font_italic_flag (glView            *view,
2696                                         gboolean           font_italic_flag)
2697 {
2698         GList *p;
2699         glLabelObject *object;
2700
2701         gl_debug (DEBUG_VIEW, "START");
2702
2703         g_return_if_fail (view && GL_IS_VIEW (view));
2704
2705         for (p = view->selected_object_list; p != NULL; p = p->next) {
2706
2707                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2708                 gl_label_object_set_font_italic_flag (object, font_italic_flag);
2709
2710         }
2711
2712         gl_debug (DEBUG_VIEW, "END");
2713 }
2714
2715 /*****************************************************************************/
2716 /* Set text alignment for all text contained in selected objects.            */
2717 /*****************************************************************************/
2718 void
2719 gl_view_set_selection_text_alignment (glView            *view,
2720                                       GtkJustification   text_alignment)
2721 {
2722         GList *p;
2723         glLabelObject *object;
2724
2725         gl_debug (DEBUG_VIEW, "START");
2726
2727         g_return_if_fail (view && GL_IS_VIEW (view));
2728
2729         for (p = view->selected_object_list; p != NULL; p = p->next) {
2730
2731                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2732                 gl_label_object_set_text_alignment (object, text_alignment);
2733
2734         }
2735
2736         gl_debug (DEBUG_VIEW, "END");
2737 }
2738
2739 /*****************************************************************************/
2740 /* Set text color for all text contained in selected objects.                */
2741 /*****************************************************************************/
2742 void
2743 gl_view_set_selection_text_color (glView            *view,
2744                                   guint              text_color)
2745 {
2746         GList *p;
2747         glLabelObject *object;
2748
2749         gl_debug (DEBUG_VIEW, "START");
2750
2751         g_return_if_fail (view && GL_IS_VIEW (view));
2752
2753         for (p = view->selected_object_list; p != NULL; p = p->next) {
2754
2755                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2756                 gl_label_object_set_text_color (object, text_color);
2757
2758         }
2759
2760         gl_debug (DEBUG_VIEW, "END");
2761 }
2762
2763 /*****************************************************************************/
2764 /* Can fill properties be set for selection?                                 */
2765 /*****************************************************************************/
2766 gboolean
2767 gl_view_can_selection_fill (glView            *view)
2768 {
2769         GList *p;
2770         glLabelObject *object;
2771
2772         gl_debug (DEBUG_VIEW, "");
2773
2774         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2775
2776         for (p = view->selected_object_list; p != NULL; p = p->next) {
2777
2778                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2779                 if (gl_label_object_can_fill (object)) {
2780                         return TRUE;
2781                 }
2782
2783         }
2784
2785         return FALSE;
2786 }
2787
2788 /*****************************************************************************/
2789 /* Set fill color for all selected objects.                                  */
2790 /*****************************************************************************/
2791 void
2792 gl_view_set_selection_fill_color (glView            *view,
2793                                   guint              fill_color)
2794 {
2795         GList *p;
2796         glLabelObject *object;
2797
2798         gl_debug (DEBUG_VIEW, "START");
2799
2800         g_return_if_fail (view && GL_IS_VIEW (view));
2801
2802         for (p = view->selected_object_list; p != NULL; p = p->next) {
2803
2804                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2805                 gl_label_object_set_fill_color (object, fill_color);
2806
2807         }
2808
2809         gl_debug (DEBUG_VIEW, "END");
2810 }
2811
2812 /*****************************************************************************/
2813 /* Can line color properties be set for selection?                           */
2814 /*****************************************************************************/
2815 gboolean
2816 gl_view_can_selection_line_color (glView            *view)
2817 {
2818         GList *p;
2819         glLabelObject *object;
2820
2821         gl_debug (DEBUG_VIEW, "");
2822
2823         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2824
2825         for (p = view->selected_object_list; p != NULL; p = p->next) {
2826
2827                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2828                 if (gl_label_object_can_line_color (object)) {
2829                         return TRUE;
2830                 }
2831
2832         }
2833
2834         return FALSE;
2835 }
2836
2837 /*****************************************************************************/
2838 /* Set line color for all selected objects.                                  */
2839 /*****************************************************************************/
2840 void
2841 gl_view_set_selection_line_color (glView            *view,
2842                                   guint              line_color)
2843 {
2844         GList *p;
2845         glLabelObject *object;
2846
2847         gl_debug (DEBUG_VIEW, "START");
2848
2849         g_return_if_fail (view && GL_IS_VIEW (view));
2850
2851         for (p = view->selected_object_list; p != NULL; p = p->next) {
2852
2853                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2854                 gl_label_object_set_line_color (object, line_color);
2855
2856         }
2857
2858         gl_debug (DEBUG_VIEW, "END");
2859 }
2860
2861 /*****************************************************************************/
2862 /* Can line width properties be set for selection?                           */
2863 /*****************************************************************************/
2864 gboolean
2865 gl_view_can_selection_line_width (glView            *view)
2866 {
2867         GList *p;
2868         glLabelObject *object;
2869
2870         gl_debug (DEBUG_VIEW, "");
2871
2872         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
2873
2874         for (p = view->selected_object_list; p != NULL; p = p->next) {
2875
2876                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2877                 if (gl_label_object_can_line_width (object)) {
2878                         return TRUE;
2879                 }
2880
2881         }
2882
2883         return FALSE;
2884 }
2885
2886 /*****************************************************************************/
2887 /* Set line width for all selected objects.                                  */
2888 /*****************************************************************************/
2889 void
2890 gl_view_set_selection_line_width (glView            *view,
2891                                   gdouble            line_width)
2892 {
2893         GList *p;
2894         glLabelObject *object;
2895
2896         gl_debug (DEBUG_VIEW, "START");
2897
2898         g_return_if_fail (view && GL_IS_VIEW (view));
2899
2900         for (p = view->selected_object_list; p != NULL; p = p->next) {
2901
2902                 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2903                 gl_label_object_set_line_width (object, line_width);
2904
2905         }
2906
2907         gl_debug (DEBUG_VIEW, "END");
2908 }
2909
2910 /*****************************************************************************/
2911 /* "Cut" selected items and place in clipboard selections.                   */
2912 /*****************************************************************************/
2913 void
2914 gl_view_cut (glView *view)
2915 {
2916         gl_debug (DEBUG_VIEW, "START");
2917
2918         g_return_if_fail (view && GL_IS_VIEW (view));
2919
2920         gl_view_copy (view);
2921         gl_view_delete_selection (view);
2922
2923         gl_debug (DEBUG_VIEW, "END");
2924 }
2925
2926 /*****************************************************************************/
2927 /* "Copy" selected items to clipboard selections.                            */
2928 /*****************************************************************************/
2929 void
2930 gl_view_copy (glView *view)
2931 {
2932         GList *p;
2933         glViewObject *view_object;
2934         glLabelObject *object;
2935         glTemplate *template;
2936         gboolean rotate_flag;
2937
2938         gl_debug (DEBUG_VIEW, "START");
2939
2940         g_return_if_fail (view && GL_IS_VIEW (view));
2941
2942         if (view->selected_object_list) {
2943
2944                 if ( view->selection_data ) {
2945                         g_object_unref (view->selection_data);
2946                 }
2947                 template = gl_label_get_template (view->label);
2948                 rotate_flag = gl_label_get_rotate_flag (view->label);
2949                 view->selection_data = GL_LABEL(gl_label_new ());
2950                 gl_label_set_template (view->selection_data, template);
2951                 gl_label_set_rotate_flag (view->selection_data, rotate_flag);
2952                 gl_template_free (&template);
2953
2954                 for (p = view->selected_object_list; p != NULL; p = p->next) {
2955
2956                         view_object = GL_VIEW_OBJECT (p->data);
2957                         object = gl_view_object_get_object (view_object);
2958
2959                         gl_label_object_dup (object, view->selection_data);
2960
2961                 }
2962
2963                 gtk_selection_owner_set (view->invisible,
2964                                          clipboard_atom, GDK_CURRENT_TIME);
2965                 view->have_selection = TRUE;
2966
2967         }
2968
2969         gl_debug (DEBUG_VIEW, "END");
2970 }
2971
2972 /*****************************************************************************/
2973 /* "Paste" from private clipboard selection.                                 */
2974 /*****************************************************************************/
2975 void
2976 gl_view_paste (glView *view)
2977 {
2978         gl_debug (DEBUG_VIEW, "START");
2979
2980         g_return_if_fail (view && GL_IS_VIEW (view));
2981
2982         gtk_selection_convert (GTK_WIDGET (view->invisible),
2983                                clipboard_atom, GDK_SELECTION_TYPE_STRING,
2984                                GDK_CURRENT_TIME);
2985
2986         gl_debug (DEBUG_VIEW, "END");
2987 }
2988
2989 /*****************************************************************************/
2990 /* Zoom in one "notch"                                                       */
2991 /*****************************************************************************/
2992 void
2993 gl_view_zoom_in (glView *view)
2994 {
2995         gint i, i_min;
2996         gdouble dist, dist_min;
2997
2998         gl_debug (DEBUG_VIEW, "START");
2999
3000         g_return_if_fail (view && GL_IS_VIEW (view));
3001
3002         /* Find index of current scale (or best match) */
3003         i_min = 1;              /* start with 2nd largest scale */
3004         dist_min = fabs (zooms[1] - view->zoom);
3005         for (i = 2; i < N_ZOOMS; i++) {
3006                 dist = fabs (zooms[i] - view->zoom);
3007                 if (dist < dist_min) {
3008                         i_min = i;
3009                         dist_min = dist;
3010                 }
3011         }
3012
3013         /* zoom in one "notch" */
3014         i = MAX (0, i_min - 1);
3015         gl_debug (DEBUG_VIEW, "zoom[%d] = %g", i, zooms[i]);
3016         set_zoom_real (view, zooms[i], FALSE);
3017
3018         gl_debug (DEBUG_VIEW, "END");
3019 }
3020
3021 /*****************************************************************************/
3022 /* Zoom out one "notch"                                                      */
3023 /*****************************************************************************/
3024 void
3025 gl_view_zoom_out (glView *view)
3026 {
3027         gint i, i_min;
3028         gdouble dist, dist_min;
3029
3030         gl_debug (DEBUG_VIEW, "START");
3031
3032         g_return_if_fail (view && GL_IS_VIEW (view));
3033
3034         /* Find index of current scale (or best match) */
3035         i_min = 0;              /* start with largest scale */
3036         dist_min = fabs (zooms[0] - view->zoom);
3037         for (i = 1; i < N_ZOOMS; i++) {
3038                 dist = fabs (zooms[i] - view->zoom);
3039                 if (dist < dist_min) {
3040                         i_min = i;
3041                         dist_min = dist;
3042                 }
3043         }
3044
3045         /* zoom out one "notch" */
3046         if (i_min >= N_ZOOMS)
3047                 return;
3048         i = i_min + 1;
3049         if (i >= N_ZOOMS)
3050                 return;
3051         set_zoom_real (view, zooms[i], FALSE);
3052
3053         gl_debug (DEBUG_VIEW, "END");
3054 }
3055
3056 /*****************************************************************************/
3057 /* Set zoom to best fit.                                                     */
3058 /*****************************************************************************/
3059 void
3060 gl_view_zoom_to_fit (glView *view)
3061 {
3062         gint w_view, h_view;
3063         gdouble w_label, h_label;
3064         gdouble x_scale, y_scale, scale;
3065
3066         gl_debug (DEBUG_VIEW, "");
3067
3068         if ( ! GTK_WIDGET_VISIBLE(view)) {
3069                 set_zoom_real (view, 1.0, TRUE);
3070                 return;
3071         }
3072
3073         w_view = GTK_WIDGET(view)->allocation.width;
3074         h_view = GTK_WIDGET(view)->allocation.height;
3075
3076         gl_label_get_size (GL_LABEL(view->label), &w_label, &h_label);
3077
3078         gl_debug (DEBUG_VIEW, "View size: %d, %d", w_view, h_view);
3079         gl_debug (DEBUG_VIEW, "Label size: %g, %g", w_label, h_label);
3080
3081         /* Calculate best scale */
3082         x_scale = (double)(w_view - ZOOMTOFIT_PAD) / w_label;
3083         y_scale = (double)(h_view - ZOOMTOFIT_PAD) / h_label;
3084         scale = MIN (x_scale, y_scale);
3085         gl_debug (DEBUG_VIEW, "Candidate zooms: %g, %g => %g", x_scale, y_scale, scale);
3086
3087         /* Limit */
3088         gl_debug (DEBUG_VIEW, "Scale: %g", scale);
3089         scale = MIN (scale, zooms[0]*view->home_scale);
3090         scale = MAX (scale, zooms[N_ZOOMS-1]*view->home_scale);
3091         gl_debug (DEBUG_VIEW, "Limitted scale: %g", scale);
3092
3093         set_zoom_real (view, scale/view->home_scale, TRUE);
3094 }
3095
3096 /*****************************************************************************/
3097 /* Set current zoom factor to explicit value.                                */
3098 /*****************************************************************************/
3099 void
3100 gl_view_set_zoom (glView  *view,
3101                   gdouble zoom)
3102 {
3103         gl_debug (DEBUG_VIEW, "START");
3104
3105         set_zoom_real (view, zoom, FALSE);
3106
3107         gl_debug (DEBUG_VIEW, "END");
3108 }
3109
3110 /*---------------------------------------------------------------------------*/
3111 /* PRIVATE.  Set canvas scale.                                               *
3112 /*---------------------------------------------------------------------------*/
3113 static void
3114 set_zoom_real (glView          *view,
3115                gdouble          zoom,
3116                gboolean         zoom_to_fit_flag)
3117 {
3118         gl_debug (DEBUG_VIEW, "START");
3119
3120         g_return_if_fail (view && GL_IS_VIEW (view));
3121         g_return_if_fail (zoom > 0.0);
3122
3123         /* Limit, if needed */
3124         gl_debug (DEBUG_VIEW, "Zoom requested: %g", zoom);
3125         zoom = MIN (zoom, zooms[0]);
3126         zoom = MAX (zoom, zooms[N_ZOOMS-1]);
3127         gl_debug (DEBUG_VIEW, "Limitted zoom: %g", zoom);
3128
3129         if ( zoom != view->zoom ) {
3130
3131                 view->zoom = zoom;
3132                 view->zoom_to_fit_flag = zoom_to_fit_flag;
3133                 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
3134                                                   zoom*view->home_scale);
3135
3136                 g_signal_emit (G_OBJECT(view), signals[ZOOM_CHANGED], 0, zoom);
3137
3138         }
3139
3140         gl_debug (DEBUG_VIEW, "END");
3141
3142 }
3143
3144
3145 /*---------------------------------------------------------------------------*/
3146 /* PRIVATE. Size allocation changed callback.                                */
3147 /*---------------------------------------------------------------------------*/
3148 static void
3149 size_allocate_cb (glView          *view)
3150 {
3151         gl_debug (DEBUG_VIEW, "START");
3152
3153         if (view->zoom_to_fit_flag) {
3154                 /* Maintain best fit zoom */
3155                 gl_view_zoom_to_fit (view);
3156         }
3157
3158         gl_debug (DEBUG_VIEW, "END");
3159 }
3160
3161
3162
3163 /*---------------------------------------------------------------------------*/
3164 /* PRIVATE. Screen changed callback.                                         */
3165 /*---------------------------------------------------------------------------*/
3166 static void
3167 screen_changed_cb (glView          *view)
3168 {
3169         gl_debug (DEBUG_VIEW, "START");
3170
3171         view->home_scale = get_home_scale (view);
3172
3173         gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
3174                                           view->zoom * view->home_scale);
3175
3176         if (view->zoom_to_fit_flag) {
3177                 /* Maintain best fit zoom */
3178                 gl_view_zoom_to_fit (view);
3179         }
3180
3181         gl_debug (DEBUG_VIEW, "END");
3182 }
3183
3184
3185
3186 /*****************************************************************************/
3187 /* Get current zoom factor.                                                  */
3188 /*****************************************************************************/
3189 gdouble
3190 gl_view_get_zoom (glView *view)
3191 {
3192         gl_debug (DEBUG_VIEW, "");
3193
3194         g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
3195
3196         return view->zoom;
3197 }
3198
3199 /*****************************************************************************/
3200 /* Is this the maximum zoom level.                                           */
3201 /*****************************************************************************/
3202 gboolean
3203 gl_view_is_zoom_max (glView *view)
3204 {
3205         gl_debug (DEBUG_VIEW, "");
3206
3207         g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
3208
3209         return view->zoom >= zooms[0];
3210 }
3211
3212 /*****************************************************************************/
3213 /* Is this the minimum zoom level.                                           */
3214 /*****************************************************************************/
3215 gboolean
3216 gl_view_is_zoom_min (glView *view)
3217 {
3218         gl_debug (DEBUG_VIEW, "");
3219
3220         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3221
3222         return view->zoom <= zooms[N_ZOOMS-1];
3223 }
3224
3225 /*****************************************************************************/
3226 /* Launch merge properties dialog.                                           */
3227 /*****************************************************************************/
3228 void
3229 gl_view_edit_merge_props (glView *view)
3230 {
3231         gl_debug (DEBUG_VIEW, "");
3232
3233         g_return_if_fail (view && GL_IS_VIEW (view));
3234
3235         if (view->merge_props_dialog != NULL) {
3236                 gtk_widget_show_all (view->merge_props_dialog);
3237                 gtk_window_present (GTK_WINDOW(view->merge_props_dialog));
3238                 return;
3239         }
3240
3241         view->merge_props_dialog = gl_merge_properties_dialog_new (view);
3242         gtk_widget_show_all (view->merge_props_dialog);
3243
3244         g_signal_connect (G_OBJECT(view->merge_props_dialog), "destroy",
3245                           G_CALLBACK (gtk_widget_destroyed),
3246                           &view->merge_props_dialog);
3247 }
3248
3249 /*---------------------------------------------------------------------------*/
3250 /* PRIVATE.  Canvas event handler.                                           */
3251 /*---------------------------------------------------------------------------*/
3252 static int
3253 canvas_event (GnomeCanvas *canvas,
3254               GdkEvent    *event,
3255               glView      *view)
3256 {
3257         gdouble x, y;
3258
3259         gl_debug (DEBUG_VIEW, "");
3260
3261         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3262
3263         /* emit pointer signals regardless of state */
3264         switch (event->type) {
3265         case GDK_MOTION_NOTIFY:
3266                 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
3267                 gnome_canvas_window_to_world (canvas,
3268                                               event->motion.x,
3269                                               event->motion.y, &x, &y);
3270                 g_signal_emit (G_OBJECT(view), signals[POINTER_MOVED], 0, x, y);
3271                 break; /* fall through */
3272
3273         case GDK_LEAVE_NOTIFY:
3274                 gl_debug (DEBUG_VIEW, "LEAVEW_NOTIFY");
3275                 g_signal_emit (G_OBJECT(view), signals[POINTER_EXIT], 0);
3276                 break; /* fall through */
3277
3278         default:
3279                 break; /* fall through */
3280         }
3281
3282
3283         switch (view->state) {
3284
3285         case GL_VIEW_STATE_ARROW:
3286                 return canvas_event_arrow_mode (canvas, event, view);
3287
3288         case GL_VIEW_STATE_OBJECT_CREATE:
3289                 switch (view->create_type) {
3290                 case GL_LABEL_OBJECT_BOX:
3291                         return gl_view_box_create_event_handler (canvas,
3292                                                                  event,
3293                                                                  view);
3294                         break;
3295                 case GL_LABEL_OBJECT_ELLIPSE:
3296                         return gl_view_ellipse_create_event_handler (canvas,
3297                                                                      event,
3298                                                                      view);
3299                         break;
3300                 case GL_LABEL_OBJECT_LINE:
3301                         return gl_view_line_create_event_handler (canvas,
3302                                                                   event,
3303                                                                   view);
3304                         break;
3305                 case GL_LABEL_OBJECT_IMAGE:
3306                         return gl_view_image_create_event_handler (canvas,
3307                                                                    event,
3308                                                                    view);
3309                         break;
3310                 case GL_LABEL_OBJECT_TEXT:
3311                         return gl_view_text_create_event_handler (canvas,
3312                                                                   event,
3313                                                                   view);
3314                         break;
3315                 case GL_LABEL_OBJECT_BARCODE:
3316                         return gl_view_barcode_create_event_handler (canvas,
3317                                                                      event,
3318                                                                      view);
3319                         break;
3320                 default:
3321                         /*Should not happen!*/
3322                         g_warning ("Invalid label object type.");
3323                         return FALSE;
3324         }
3325
3326         default:
3327                 g_warning ("Invalid view state.");      /*Should not happen!*/
3328                 return FALSE;
3329
3330         }
3331 }
3332
3333 /*---------------------------------------------------------------------------*/
3334 /* PRIVATE.  Canvas event handler (arrow mode)                               */
3335 /*---------------------------------------------------------------------------*/
3336 static int
3337 canvas_event_arrow_mode (GnomeCanvas *canvas,
3338                          GdkEvent    *event,
3339                          glView      *view)
3340 {
3341         static gdouble x0, y0;
3342         static gboolean dragging = FALSE;
3343         static GnomeCanvasItem *item;
3344         gdouble x, y, x1, y1, x2, y2;
3345         GnomeCanvasGroup *group;
3346         GdkCursor *cursor;
3347
3348         gl_debug (DEBUG_VIEW, "");
3349
3350         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
3351
3352         switch (event->type) {
3353
3354         case GDK_BUTTON_PRESS:
3355                 gl_debug (DEBUG_VIEW, "BUTTON_PRESS");
3356                 gtk_widget_grab_focus (GTK_WIDGET(canvas));
3357                 switch (event->button.button) {
3358                 case 1:
3359                         gnome_canvas_window_to_world (canvas,
3360                                                       event->button.x,
3361                                                       event->button.y, &x, &y);
3362
3363                         if (!object_at (view, x, y)) {
3364                                 if (!(event->button.state & GDK_CONTROL_MASK)) {
3365                                         gl_view_unselect_all (view);
3366                                 }
3367
3368                                 dragging = TRUE;
3369                                 gnome_canvas_item_grab (canvas->root,
3370                                                         GDK_POINTER_MOTION_MASK |
3371                                                         GDK_BUTTON_RELEASE_MASK |
3372                                                         GDK_BUTTON_PRESS_MASK,
3373                                                         NULL, event->button.time);
3374                                 group =
3375                                     gnome_canvas_root (GNOME_CANVAS
3376                                                        (view->canvas));
3377                                 item =
3378                                     gnome_canvas_item_new (group,
3379                                                            gnome_canvas_rect_get_type (),
3380                                                            "x1", x, "y1", y,
3381                                                            "x2", x, "y2", y,
3382                                                            "width_pixels", 2,
3383                                                            "outline_color_rgba",
3384                                                            SEL_LINE_COLOR,
3385                                                            "fill_color_rgba",
3386                                                            SEL_FILL_COLOR,
3387                                                            NULL);
3388                                 x0 = x;
3389                                 y0 = y;
3390
3391                         }
3392                         return FALSE;
3393                 case 3:
3394                         gnome_canvas_window_to_world (canvas,
3395                                                       event->button.x,
3396                                                       event->button.y, &x, &y);
3397
3398                         if (!object_at (view, x, y)) {
3399                                 /* bring up apropriate menu for selection. */
3400                                 gl_view_popup_menu (view, event);
3401                         }
3402                         return FALSE;
3403                 default:
3404                         return FALSE;
3405                 }
3406
3407         case GDK_BUTTON_RELEASE:
3408                 gl_debug (DEBUG_VIEW, "BUTTON_RELEASE");
3409                 switch (event->button.button) {
3410                 case 1:
3411                         if (dragging) {
3412                                 dragging = FALSE;
3413                                 gnome_canvas_item_ungrab (canvas->root,
3414                                                           event->button.time);
3415                                 gnome_canvas_window_to_world (canvas,
3416                                                               event->button.x,
3417                                                               event->button.y,
3418                                                               &x, &y);
3419                                 x1 = MIN (x, x0);
3420                                 y1 = MIN (y, y0);
3421                                 x2 = MAX (x, x0);
3422                                 y2 = MAX (y, y0);
3423                                 gl_view_select_region (view, x1, y1, x2, y2);
3424                                 gtk_object_destroy (GTK_OBJECT (item));
3425                                 return TRUE;
3426                         }
3427                         return FALSE;
3428
3429                 default:
3430                         return FALSE;
3431                 }
3432
3433         case GDK_MOTION_NOTIFY:
3434                 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
3435                 gnome_canvas_window_to_world (canvas,
3436                                               event->motion.x,
3437                                               event->motion.y, &x, &y);
3438                 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
3439                         gnome_canvas_item_set (item,
3440                                                "x1", MIN (x, x0),
3441                                                "y1", MIN (y, y0),
3442                                                "x2", MAX (x, x0),
3443                                                "y2", MAX (y, y0), NULL);
3444                         return TRUE;
3445                 } else {
3446                         return FALSE;
3447                 }
3448
3449         case GDK_KEY_PRESS:
3450                 gl_debug (DEBUG_VIEW, "KEY_PRESS");
3451                 if (!dragging) {
3452                         switch (event->key.keyval) {
3453                         case GDK_Left:
3454                         case GDK_KP_Left:
3455                                 gl_view_move_selection (view,
3456                                                         -1.0 / (view->zoom), 0.0);
3457                                 break;
3458                         case GDK_Up:
3459                         case GDK_KP_Up:
3460                                 gl_view_move_selection (view,
3461                                                         0.0, -1.0 / (view->zoom));
3462                                 break;
3463                         case GDK_Right:
3464                         case GDK_KP_Right:
3465                                 gl_view_move_selection (view,
3466                                                         1.0 / (view->zoom), 0.0);
3467                                 break;
3468                         case GDK_Down:
3469                         case GDK_KP_Down:
3470                                 gl_view_move_selection (view,
3471                                                         0.0, 1.0 / (view->zoom));
3472                                 break;
3473                         case GDK_Delete:
3474                         case GDK_KP_Delete:
3475                                 gl_view_delete_selection (view);
3476                                 cursor = gdk_cursor_new (GDK_LEFT_PTR);
3477                                 gdk_window_set_cursor (view->canvas->window,
3478                                                        cursor);
3479                                 gdk_cursor_unref (cursor);
3480                                 break;
3481                         default:
3482                                 return FALSE;
3483                         }
3484                 }
3485                 return TRUE;    /* We handled this or we were dragging. */
3486
3487         default:
3488                 gl_debug (DEBUG_VIEW, "default");
3489                 return FALSE;
3490         }
3491
3492 }
3493
3494 /*---------------------------------------------------------------------------*/
3495 /* PRIVATE.  create menu for selections.                                     */
3496 /*---------------------------------------------------------------------------*/
3497 void
3498 construct_selection_menu (glView *view)
3499 {
3500         GtkWidget *menu, *menuitem, *submenu;
3501
3502         gl_debug (DEBUG_VIEW, "START");
3503
3504         g_return_if_fail (view && GL_IS_VIEW (view));
3505
3506         menu = gtk_menu_new ();
3507
3508         /*
3509          * Submenu: Order
3510          */
3511         menuitem = gtk_menu_item_new_with_mnemonic (_("_Order"));
3512         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3513         gtk_widget_show (menuitem);
3514         submenu = gtk_menu_new ();
3515         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3516
3517         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ORDER_TOP, NULL);
3518         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3519         gtk_widget_show (menuitem);
3520         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3521                                   G_CALLBACK (gl_view_raise_selection), view);
3522
3523         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ORDER_BOTTOM, NULL);
3524         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3525         gtk_widget_show (menuitem);
3526         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3527                                   G_CALLBACK (gl_view_lower_selection), view);
3528
3529         /*
3530          * Submenu: Rotate/Flip
3531          */
3532         menuitem = gtk_menu_item_new_with_mnemonic (_("_Rotate/Flip"));
3533         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3534         gtk_widget_show (menuitem);
3535         submenu = gtk_menu_new ();
3536         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3537
3538         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ROTATE_LEFT, NULL);
3539         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3540         gtk_widget_show (menuitem);
3541         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3542                                   G_CALLBACK (gl_view_rotate_selection_left), view);
3543
3544         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ROTATE_RIGHT, NULL);
3545         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3546         gtk_widget_show (menuitem);
3547         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3548                                   G_CALLBACK (gl_view_rotate_selection_right), view);
3549
3550         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_FLIP_HORIZ, NULL);
3551         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3552         gtk_widget_show (menuitem);
3553         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3554                                   G_CALLBACK (gl_view_flip_selection_horiz), view);
3555
3556         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_FLIP_VERT, NULL);
3557         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3558         gtk_widget_show (menuitem);
3559         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3560                                   G_CALLBACK (gl_view_flip_selection_vert), view);
3561
3562         /*
3563          * Submenu: Align Horizontally
3564          */
3565         menuitem = gtk_menu_item_new_with_mnemonic (_("Align _Horizontally"));
3566         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3567         gtk_widget_show (menuitem);
3568         submenu = gtk_menu_new ();
3569         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3570
3571         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_LEFT, NULL);
3572         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3573         gtk_widget_show (menuitem);
3574         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3575                                   G_CALLBACK (gl_view_align_selection_left), view);
3576         view->multi_selection_items =
3577                 g_list_prepend (view->multi_selection_items, menuitem);
3578
3579         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_HCENTER, NULL);
3580         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3581         gtk_widget_show (menuitem);
3582         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3583                                   G_CALLBACK (gl_view_align_selection_hcenter), view);
3584         view->multi_selection_items =
3585                 g_list_prepend (view->multi_selection_items, menuitem);
3586
3587         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_RIGHT, NULL);
3588         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3589         gtk_widget_show (menuitem);
3590         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3591                                   G_CALLBACK (gl_view_align_selection_right), view);
3592         view->multi_selection_items =
3593                 g_list_prepend (view->multi_selection_items, menuitem);
3594
3595         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_CENTER_HORIZ, NULL);
3596         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3597         gtk_widget_show (menuitem);
3598         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3599                                   G_CALLBACK (gl_view_center_selection_horiz), view);
3600
3601         /*
3602          * Submenu: Align Vertically
3603          */
3604         menuitem = gtk_menu_item_new_with_mnemonic (_("Align _Vertically"));
3605         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3606         gtk_widget_show (menuitem);
3607         submenu = gtk_menu_new ();
3608         gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3609
3610         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_TOP, NULL);
3611         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3612         gtk_widget_show (menuitem);
3613         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3614                                   G_CALLBACK (gl_view_align_selection_top), view);
3615         view->multi_selection_items =
3616                 g_list_prepend (view->multi_selection_items, menuitem);
3617
3618         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_VCENTER, NULL);
3619         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3620         gtk_widget_show (menuitem);
3621         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3622                                   G_CALLBACK (gl_view_align_selection_vcenter), view);
3623         view->multi_selection_items =
3624                 g_list_prepend (view->multi_selection_items, menuitem);
3625
3626         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_BOTTOM, NULL);
3627         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3628         gtk_widget_show (menuitem);
3629         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3630                                   G_CALLBACK (gl_view_align_selection_bottom), view);
3631         view->multi_selection_items =
3632                 g_list_prepend (view->multi_selection_items, menuitem);
3633
3634         menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_CENTER_VERT, NULL);
3635         gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3636         gtk_widget_show (menuitem);
3637         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3638                                   G_CALLBACK (gl_view_center_selection_vert), view);
3639
3640         /*
3641          * Separator -------------------------
3642          */
3643         menuitem = gtk_menu_item_new ();
3644         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3645         gtk_widget_show (menuitem);
3646
3647         menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_CUT, NULL);
3648         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3649         gtk_widget_show (menuitem);
3650         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3651                                   G_CALLBACK (gl_view_cut), view);
3652
3653         menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_COPY, NULL);
3654         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3655         gtk_widget_show (menuitem);
3656         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3657                                   G_CALLBACK (gl_view_copy), view);
3658
3659         menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_PASTE, NULL);
3660         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3661         gtk_widget_show (menuitem);
3662         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3663                                   G_CALLBACK (gl_view_paste), view);
3664
3665         menuitem = gtk_menu_item_new_with_mnemonic (_("_Delete"));
3666         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3667         gtk_widget_show (menuitem);
3668         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3669                                   G_CALLBACK (gl_view_delete_selection), view);
3670
3671
3672         view->selection_menu = menu;
3673
3674         gl_debug (DEBUG_VIEW, "END");
3675 }
3676
3677 /*---------------------------------------------------------------------------*/
3678 /* PRIVATE.  create menu for empty selections.                               */
3679 /*---------------------------------------------------------------------------*/
3680 void
3681 construct_empty_selection_menu (glView *view)
3682 {
3683         GtkWidget *menu, *menuitem, *submenu;
3684
3685         gl_debug (DEBUG_VIEW, "START");
3686
3687         g_return_if_fail (view && GL_IS_VIEW (view));
3688
3689         menu = gtk_menu_new ();
3690
3691         menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_PASTE, NULL);
3692         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3693         gtk_widget_show (menuitem);
3694         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3695                                   G_CALLBACK (gl_view_paste), view);
3696
3697
3698         view->empty_selection_menu = menu;
3699
3700         gl_debug (DEBUG_VIEW, "END");
3701 }
3702
3703 /****************************************************************************/
3704 /* popup menu.                                                              */
3705 /****************************************************************************/
3706 void
3707 gl_view_popup_menu (glView       *view,
3708                     GdkEvent     *event)
3709 {
3710         GtkMenu *menu;
3711         GList   *p;
3712
3713         gl_debug (DEBUG_VIEW, "START");
3714
3715         g_return_if_fail (view && GL_IS_VIEW (view));
3716
3717         if (gl_view_is_selection_empty (view)) {
3718
3719                 if (view->empty_selection_menu != NULL) {
3720                         gtk_menu_popup (GTK_MENU (view->empty_selection_menu),
3721                                         NULL, NULL, NULL, NULL,
3722                                         event->button.button,
3723                                         event->button.time);
3724                 }
3725
3726         } else {
3727
3728                 for (p=view->atomic_selection_items; p!=NULL; p=p->next) {
3729                         gtk_widget_set_sensitive (GTK_WIDGET(p->data),
3730                                                   gl_view_is_selection_atomic(view));
3731                 }
3732
3733                 for (p=view->multi_selection_items; p!=NULL; p=p->next) {
3734                         gtk_widget_set_sensitive (GTK_WIDGET(p->data),
3735                                                   !gl_view_is_selection_atomic(view));
3736                 }
3737
3738                 if (view->selection_menu != NULL) {
3739                         gtk_menu_popup (GTK_MENU (view->selection_menu),
3740                                         NULL, NULL, NULL, NULL,
3741                                         event->button.button,
3742                                         event->button.time);
3743                 }
3744
3745         }
3746
3747         gl_debug (DEBUG_VIEW, "END");
3748 }
3749
3750 /*---------------------------------------------------------------------------*/
3751 /* PRIVATE.  Handle "selection-clear" signal.                                */
3752 /*---------------------------------------------------------------------------*/
3753 static void
3754 selection_clear_cb (GtkWidget         *widget,
3755                     GdkEventSelection *event,
3756                     gpointer          data)
3757 {
3758         glView *view = GL_VIEW (data);
3759
3760         gl_debug (DEBUG_VIEW, "START");
3761
3762         g_return_if_fail (view && GL_IS_VIEW (view));
3763
3764         view->have_selection = FALSE;
3765         g_object_unref (view->selection_data);
3766         view->selection_data = NULL;
3767
3768         gl_debug (DEBUG_VIEW, "END");
3769 }
3770
3771 /*---------------------------------------------------------------------------*/
3772 /* PRIVATE.  Handle "selection-get" signal.                                  */
3773 /*---------------------------------------------------------------------------*/
3774 static void
3775 selection_get_cb (GtkWidget        *widget,
3776                   GtkSelectionData *selection_data,
3777                   guint            info,
3778                   guint            time,
3779                   gpointer         data)
3780 {
3781         glView *view = GL_VIEW (data);
3782         gchar *buffer;
3783         glXMLLabelStatus status;
3784
3785         gl_debug (DEBUG_VIEW, "START");
3786
3787         g_return_if_fail (view && GL_IS_VIEW (view));
3788
3789         if (view->have_selection) {
3790
3791                 buffer = gl_xml_label_save_buffer (view->selection_data,
3792                                                    &status);
3793                 gtk_selection_data_set (selection_data,
3794                                         GDK_SELECTION_TYPE_STRING, 8, buffer,
3795                                         strlen (buffer));
3796                 g_free (buffer);
3797         }
3798
3799         gl_debug (DEBUG_VIEW, "END");
3800 }
3801
3802 /*---------------------------------------------------------------------------*/
3803 /* PRIVATE.  Handle "selection-received" signal.  (Result of Paste)          */
3804 /*---------------------------------------------------------------------------*/
3805 static void
3806 selection_received_cb (GtkWidget        *widget,
3807                        GtkSelectionData *selection_data,
3808                        guint            time,
3809                        gpointer         data)
3810 {
3811         glView *view = GL_VIEW (data);
3812         glLabel *label = NULL;
3813         glXMLLabelStatus status;
3814         GList *p, *p_next;
3815         glLabelObject *object, *newobject;
3816         glViewObject *view_object;
3817
3818         gl_debug (DEBUG_VIEW, "START");
3819
3820         g_return_if_fail (view && GL_IS_VIEW (view));
3821
3822         if (selection_data->length < 0) {
3823                 return;
3824         }
3825         if (selection_data->type != GDK_SELECTION_TYPE_STRING) {
3826                 return;
3827         }
3828
3829         gl_view_unselect_all (view);
3830
3831         label = gl_xml_label_open_buffer (selection_data->data, &status);
3832         for (p = label->objects; p != NULL; p = p_next) {
3833                 p_next = p->next;
3834
3835                 object = (glLabelObject *) p->data;
3836                 newobject = gl_label_object_dup (object, view->label);
3837
3838                 gl_debug (DEBUG_VIEW, "object pasted");
3839
3840                 if (GL_IS_LABEL_BOX (newobject)) {
3841                         view_object = gl_view_box_new (GL_LABEL_BOX(newobject),
3842                                                        view);
3843                 } else if (GL_IS_LABEL_ELLIPSE (newobject)) {
3844                         view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(newobject),
3845                                                            view);
3846                 } else if (GL_IS_LABEL_LINE (newobject)) {
3847                         view_object = gl_view_line_new (GL_LABEL_LINE(newobject),
3848                                                         view);
3849                 } else if (GL_IS_LABEL_IMAGE (newobject)) {
3850                         view_object = gl_view_image_new (GL_LABEL_IMAGE(newobject),
3851                                                          view);
3852                 } else if (GL_IS_LABEL_TEXT (newobject)) {
3853                         view_object = gl_view_text_new (GL_LABEL_TEXT(newobject),
3854                                                         view);
3855                 } else if (GL_IS_LABEL_BARCODE (newobject)) {
3856                         view_object = gl_view_barcode_new (GL_LABEL_BARCODE(newobject),
3857                                                            view);
3858                 } else {
3859                         /* Should not happen! */
3860                         view_object = NULL;
3861                         g_warning ("Invalid label object type.");
3862                 }
3863                 gl_view_select_object (view, view_object);
3864         }
3865         g_object_unref (label);
3866
3867         gl_debug (DEBUG_VIEW, "END");
3868 }
3869
3870 /****************************************************************************/
3871 /* Set default font family.                                                 */
3872 /****************************************************************************/
3873 void
3874 gl_view_set_default_font_family (glView            *view,
3875                                  const gchar       *font_family)
3876 {
3877         gl_debug (DEBUG_VIEW, "START");
3878
3879         g_return_if_fail (view && GL_IS_VIEW (view));
3880
3881         if (view->default_font_family) {
3882                 g_free (view->default_font_family);
3883         }
3884         view->default_font_family = g_strdup (font_family);
3885
3886         gl_debug (DEBUG_VIEW, "END");
3887 }
3888
3889
3890 /****************************************************************************/
3891 /* Set default font size.                                                   */
3892 /****************************************************************************/
3893 void
3894 gl_view_set_default_font_size (glView            *view,
3895                                gdouble            font_size)
3896 {
3897         gl_debug (DEBUG_VIEW, "START");
3898
3899         g_return_if_fail (view && GL_IS_VIEW (view));
3900
3901         view->default_font_size = font_size;
3902
3903         gl_debug (DEBUG_VIEW, "END");
3904 }
3905
3906
3907 /****************************************************************************/
3908 /* Set default font weight.                                                 */
3909 /****************************************************************************/
3910 void
3911 gl_view_set_default_font_weight (glView            *view,
3912                                  GnomeFontWeight    font_weight)
3913 {
3914         gl_debug (DEBUG_VIEW, "START");
3915
3916         g_return_if_fail (view && GL_IS_VIEW (view));
3917
3918         view->default_font_weight = font_weight;
3919
3920         gl_debug (DEBUG_VIEW, "END");
3921 }
3922
3923
3924 /****************************************************************************/
3925 /* Set default font italic flag.                                            */
3926 /****************************************************************************/
3927 void
3928 gl_view_set_default_font_italic_flag (glView            *view,
3929                                       gboolean           font_italic_flag)
3930 {
3931         gl_debug (DEBUG_VIEW, "START");
3932
3933         g_return_if_fail (view && GL_IS_VIEW (view));
3934
3935         view->default_font_italic_flag = font_italic_flag;
3936
3937         gl_debug (DEBUG_VIEW, "END");
3938 }
3939
3940
3941 /****************************************************************************/
3942 /* Set default text color.                                                  */
3943 /****************************************************************************/
3944 void
3945 gl_view_set_default_text_color (glView            *view,
3946                                 guint              text_color)
3947 {
3948         gl_debug (DEBUG_VIEW, "START");
3949
3950         g_return_if_fail (view && GL_IS_VIEW (view));
3951
3952         view->default_text_color = text_color;
3953
3954         gl_debug (DEBUG_VIEW, "END");
3955 }
3956
3957
3958 /****************************************************************************/
3959 /* Set default text alignment.                                              */
3960 /****************************************************************************/
3961 void
3962 gl_view_set_default_text_alignment (glView            *view,
3963                                     GtkJustification   text_alignment)
3964 {
3965         gl_debug (DEBUG_VIEW, "START");
3966
3967         g_return_if_fail (view && GL_IS_VIEW (view));
3968
3969         view->default_text_alignment = text_alignment;
3970         gl_debug (DEBUG_VIEW, "END");
3971 }
3972
3973
3974 /****************************************************************************/
3975 /* Set default line width.                                                  */
3976 /****************************************************************************/
3977 void
3978 gl_view_set_default_line_width (glView            *view,
3979                                 gdouble            line_width)
3980 {
3981         gl_debug (DEBUG_VIEW, "START");
3982
3983         g_return_if_fail (view && GL_IS_VIEW (view));
3984
3985         view->default_line_width = line_width;
3986
3987         gl_debug (DEBUG_VIEW, "END");
3988 }
3989
3990
3991 /****************************************************************************/
3992 /* Set default line color.                                                  */
3993 /****************************************************************************/
3994 void
3995 gl_view_set_default_line_color (glView            *view,
3996                                 guint              line_color)
3997 {
3998         gl_debug (DEBUG_VIEW, "START");
3999
4000         g_return_if_fail (view && GL_IS_VIEW (view));
4001
4002         view->default_line_color = line_color;
4003
4004         gl_debug (DEBUG_VIEW, "END");
4005 }
4006
4007
4008 /****************************************************************************/
4009 /* Set default fill color.                                                  */
4010 /****************************************************************************/
4011 void
4012 gl_view_set_default_fill_color (glView            *view,
4013                                 guint              fill_color)
4014 {
4015         gl_debug (DEBUG_VIEW, "START");
4016
4017         g_return_if_fail (view && GL_IS_VIEW (view));
4018
4019         view->default_fill_color = fill_color;
4020
4021         gl_debug (DEBUG_VIEW, "END");
4022 }
4023
4024
4025
4026 /****************************************************************************/
4027 /* Get default font family.                                                 */
4028 /****************************************************************************/
4029 gchar *
4030 gl_view_get_default_font_family (glView            *view)
4031 {
4032         gl_debug (DEBUG_VIEW, "START");
4033
4034         g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
4035
4036         gl_debug (DEBUG_VIEW, "END");
4037
4038         return g_strdup (view->default_font_family);
4039 }
4040
4041
4042 /****************************************************************************/
4043 /* Get default font size.                                                   */
4044 /****************************************************************************/
4045 gdouble
4046 gl_view_get_default_font_size (glView            *view)
4047 {
4048         gl_debug (DEBUG_VIEW, "START");
4049
4050         g_return_val_if_fail (view && GL_IS_VIEW (view), 12.0);
4051
4052         gl_debug (DEBUG_VIEW, "END");
4053
4054         return view->default_font_size;
4055 }
4056
4057
4058 /****************************************************************************/
4059 /* Get default font weight.                                                 */
4060 /****************************************************************************/
4061 GnomeFontWeight
4062 gl_view_get_default_font_weight (glView            *view)
4063 {
4064         gl_debug (DEBUG_VIEW, "START");
4065
4066         g_return_val_if_fail (view && GL_IS_VIEW (view), GNOME_FONT_BOOK);
4067
4068         gl_debug (DEBUG_VIEW, "END");
4069
4070         return view->default_font_weight;
4071 }
4072
4073
4074 /****************************************************************************/
4075 /* Get default font italic flag.                                            */
4076 /****************************************************************************/
4077 gboolean
4078 gl_view_get_default_font_italic_flag (glView            *view)
4079 {
4080         gl_debug (DEBUG_VIEW, "START");
4081
4082         g_return_val_if_fail (view && GL_IS_VIEW (view), FALSE);
4083
4084         gl_debug (DEBUG_VIEW, "END");
4085
4086         return view->default_font_italic_flag;
4087 }
4088
4089
4090 /****************************************************************************/
4091 /* Get default text color.                                                  */
4092 /****************************************************************************/
4093 guint
4094 gl_view_get_default_text_color (glView            *view)
4095 {
4096         gl_debug (DEBUG_VIEW, "START");
4097
4098         g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
4099
4100         gl_debug (DEBUG_VIEW, "END");
4101
4102         return view->default_text_color;
4103 }
4104
4105
4106 /****************************************************************************/
4107 /* Get default text alignment.                                              */
4108 /****************************************************************************/
4109 GtkJustification
4110 gl_view_get_default_text_alignment (glView            *view)
4111 {
4112         gl_debug (DEBUG_VIEW, "START");
4113
4114         g_return_val_if_fail (view && GL_IS_VIEW (view), GTK_JUSTIFY_LEFT);
4115
4116         gl_debug (DEBUG_VIEW, "END");
4117
4118         return view->default_text_alignment;
4119 }
4120
4121
4122 /****************************************************************************/
4123 /* Get default line width.                                                  */
4124 /****************************************************************************/
4125 gdouble
4126 gl_view_get_default_line_width (glView            *view)
4127 {
4128         gl_debug (DEBUG_VIEW, "START");
4129
4130         g_return_val_if_fail (view && GL_IS_VIEW (view), 1.0);
4131
4132         gl_debug (DEBUG_VIEW, "END");
4133
4134         return view->default_line_width;
4135 }
4136
4137
4138 /****************************************************************************/
4139 /* Get default line color.                                                  */
4140 /****************************************************************************/
4141 guint gl_view_get_default_line_color (glView            *view)
4142 {
4143         gl_debug (DEBUG_VIEW, "START");
4144
4145         g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
4146
4147         gl_debug (DEBUG_VIEW, "END");
4148
4149         return view->default_line_color;
4150 }
4151
4152
4153 /****************************************************************************/
4154 /* Get default fill color.                                                  */
4155 /****************************************************************************/
4156 guint gl_view_get_default_fill_color (glView            *view)
4157 {
4158         gl_debug (DEBUG_VIEW, "START");
4159
4160         g_return_val_if_fail (view && GL_IS_VIEW (view), 0);
4161
4162         gl_debug (DEBUG_VIEW, "END");
4163
4164         return view->default_fill_color;
4165 }
4166