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