2 * (GLABELS) Label and Business Card Creation program for GNOME
4 * view.c: GLabels View module
6 * Copyright (C) 2001-2002 Jim Evins <evins@snaught.com>.
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.
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.
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
26 #include <gtk/gtkinvisible.h>
32 #include "view-object.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"
45 /*==========================================================================*/
46 /* Private macros and constants. */
47 /*==========================================================================*/
49 #define BG_COLOR GL_COLOR (192, 192, 192)
50 #define OUTLINE_COLOR GL_COLOR (173, 216, 230)
51 #define PAPER_COLOR GL_COLOR (255, 255, 255)
52 #define GRID_COLOR BG_COLOR
53 #define MARKUP_COLOR GL_COLOR (240, 100, 100)
55 #define SEL_LINE_COLOR GL_COLOR_A (0, 0, 255, 128)
56 #define SEL_FILL_COLOR GL_COLOR_A (192, 192, 255, 128)
58 /*==========================================================================*/
60 /*==========================================================================*/
72 /*==========================================================================*/
74 /*==========================================================================*/
76 static GtkContainerClass *parent_class;
78 static guint signals[LAST_SIGNAL] = {0};
80 /* "CLIPBOARD" selection */
81 static GdkAtom clipboard_atom = GDK_NONE;
83 static gdouble scales[] = {
88 #define N_SCALES G_N_ELEMENTS(scales)
89 #define HOME_SCALE 2.0
91 /*==========================================================================*/
92 /* Local function prototypes */
93 /*==========================================================================*/
95 static void gl_view_class_init (glViewClass *class);
96 static void gl_view_init (glView *view);
97 static void gl_view_finalize (GObject *object);
99 static void gl_view_construct (glView *view);
100 static GtkWidget *gl_view_construct_canvas (glView *view);
101 static void gl_view_construct_selection (glView *view);
103 static gdouble get_apropriate_scale (gdouble w, gdouble h);
105 static void draw_layers (glView *view);
107 static void draw_label_layer (glView *view);
109 static void draw_highlight_layer (glView *view);
111 static void draw_bg_fg_layers (glView *view);
112 static void draw_bg_fg_rect (glView *view);
113 static void draw_bg_fg_rounded_rect (glView *view);
114 static void draw_bg_fg_round (glView *view);
115 static void draw_bg_fg_cd (glView *view);
117 static void draw_grid_layer (glView *view);
119 static void draw_markup_layer (glView *view);
121 static void draw_markup_margin (glView *view,
122 glTemplateMarkupMargin *margin);
123 static void draw_markup_margin_rect (glView *view,
124 glTemplateMarkupMargin *margin);
125 static void draw_markup_margin_rounded_rect (glView *view,
126 glTemplateMarkupMargin *margin);
127 static void draw_markup_margin_round (glView *view,
128 glTemplateMarkupMargin *margin);
129 static void draw_markup_margin_cd (glView *view,
130 glTemplateMarkupMargin *margin);
132 static void draw_markup_line (glView *view,
133 glTemplateMarkupLine *line);
136 static void select_object_real (glView *view,
137 glViewObject *view_object);
138 static void unselect_object_real (glView *view,
139 glViewObject *view_object);
141 static gboolean object_at (glView *view,
142 gdouble x, gdouble y);
144 static gboolean is_item_member_of_group (glView *view,
145 GnomeCanvasItem *item,
146 GnomeCanvasItem *group);
148 static gboolean is_object_selected (glView *view,
149 glViewObject *view_object);
151 static void move_selection (glView *view,
152 gdouble dx, gdouble dy);
154 static int canvas_event (GnomeCanvas *canvas,
157 static int canvas_event_arrow_mode (GnomeCanvas *canvas,
161 static int item_event_arrow_mode (GnomeCanvasItem *item,
163 glViewObject *view_object);
165 static GtkWidget *new_selection_menu (glView *view);
167 static void popup_selection_menu (glView *view,
168 glViewObject *view_object,
171 static void selection_clear_cb (GtkWidget *widget,
172 GdkEventSelection *event,
175 static void selection_get_cb (GtkWidget *widget,
176 GtkSelectionData *selection_data,
181 static void selection_received_cb (GtkWidget *widget,
182 GtkSelectionData *selection_data,
186 /****************************************************************************/
187 /* Boilerplate Object stuff. */
188 /****************************************************************************/
190 gl_view_get_type (void)
192 static guint view_type = 0;
195 GTypeInfo view_info = {
196 sizeof (glViewClass),
199 (GClassInitFunc) gl_view_class_init,
204 (GInstanceInitFunc) gl_view_init,
208 g_type_register_static (gtk_vbox_get_type (),
209 "glView", &view_info, 0);
216 gl_view_class_init (glViewClass *class)
218 GObjectClass *object_class = (GObjectClass *) class;
220 gl_debug (DEBUG_VIEW, "START");
222 parent_class = g_type_class_peek_parent (class);
224 object_class->finalize = gl_view_finalize;
226 signals[SELECTION_CHANGED] =
227 g_signal_new ("selection_changed",
228 G_OBJECT_CLASS_TYPE (object_class),
230 G_STRUCT_OFFSET (glViewClass, selection_changed),
232 gl_marshal_VOID__VOID,
236 signals[ZOOM_CHANGED] =
237 g_signal_new ("zoom_changed",
238 G_OBJECT_CLASS_TYPE (object_class),
240 G_STRUCT_OFFSET (glViewClass, zoom_changed),
242 gl_marshal_VOID__DOUBLE,
246 signals[POINTER_MOVED] =
247 g_signal_new ("pointer_moved",
248 G_OBJECT_CLASS_TYPE (object_class),
250 G_STRUCT_OFFSET (glViewClass, pointer_moved),
252 gl_marshal_VOID__DOUBLE_DOUBLE,
254 2, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
256 signals[POINTER_EXIT] =
257 g_signal_new ("pointer_exit",
258 G_OBJECT_CLASS_TYPE (object_class),
260 G_STRUCT_OFFSET (glViewClass, pointer_exit),
262 gl_marshal_VOID__VOID,
266 signals[MODE_CHANGED] =
267 g_signal_new ("mode_changed",
268 G_OBJECT_CLASS_TYPE (object_class),
270 G_STRUCT_OFFSET (glViewClass, mode_changed),
272 gl_marshal_VOID__VOID,
276 gl_debug (DEBUG_VIEW, "END");
280 gl_view_init (glView *view)
282 gl_debug (DEBUG_VIEW, "START");
286 view->grid_spacing = 9;
288 gl_debug (DEBUG_VIEW, "END");
292 gl_view_finalize (GObject *object)
296 gl_debug (DEBUG_VIEW, "START");
298 g_return_if_fail (object != NULL);
299 g_return_if_fail (GL_IS_VIEW (object));
301 view = GL_VIEW (object);
303 G_OBJECT_CLASS (parent_class)->finalize (object);
305 gl_debug (DEBUG_VIEW, "END");
308 /****************************************************************************/
309 /* NEW view object. */
310 /****************************************************************************/
312 gl_view_new (glLabel *label)
314 glView *view = g_object_new (gl_view_get_type (), NULL);
316 gl_debug (DEBUG_VIEW, "START");
320 gl_view_construct (view);
322 gl_debug (DEBUG_VIEW, "END");
324 return GTK_WIDGET (view);
327 /*---------------------------------------------------------------------------*/
328 /* PRIVATE. Construct composite widget. */
329 /*---------------------------------------------------------------------------*/
331 gl_view_construct (glView *view)
333 GtkWidget *wvbox, *wscroll;
335 gl_debug (DEBUG_VIEW, "START");
337 g_return_if_fail (GL_IS_VIEW (view));
339 wvbox = GTK_WIDGET (view);
341 view->state = GL_VIEW_STATE_ARROW;
342 view->object_list = NULL;
344 gl_view_construct_canvas (view);
345 wscroll = gtk_scrolled_window_new (NULL, NULL);
346 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (wscroll),
347 GTK_POLICY_AUTOMATIC,
348 GTK_POLICY_AUTOMATIC);
349 gtk_box_pack_start (GTK_BOX (wvbox), wscroll, TRUE, TRUE, 0);
350 gtk_container_add (GTK_CONTAINER (wscroll), view->canvas);
352 gl_view_construct_selection (view);
354 view->menu = new_selection_menu (view);
356 gl_debug (DEBUG_VIEW, "END");
359 /*---------------------------------------------------------------------------*/
360 /* PRIVATE. Create canvas w/ a background in the shape of the label/card. */
361 /*---------------------------------------------------------------------------*/
363 gl_view_construct_canvas (glView *view)
366 glLabel *label = view->label;
367 gdouble label_width, label_height;
370 gl_debug (DEBUG_VIEW, "START");
372 g_return_val_if_fail (GL_IS_VIEW (view), NULL);
373 g_return_val_if_fail (label != NULL, NULL);
375 gtk_widget_push_colormap (gdk_rgb_get_colormap ());
376 view->canvas = gnome_canvas_new_aa ();
377 gtk_widget_pop_colormap ();
379 bg_color = gl_color_to_gdk_color (BG_COLOR);
380 gtk_widget_modify_bg (GTK_WIDGET(view->canvas), GTK_STATE_NORMAL, bg_color);
383 gl_label_get_size (label, &label_width, &label_height);
384 gl_debug (DEBUG_VIEW, "Label size: w=%lf, h=%lf",
385 label_width, label_height);
387 scale = get_apropriate_scale (label_width, label_height);
388 gl_debug (DEBUG_VIEW, "scale =%lf", scale);
390 gl_debug (DEBUG_VIEW, "Canvas size: w=%lf, h=%lf",
391 scale * label_width + 40,
392 scale * label_height + 40);
393 gtk_widget_set_size_request (GTK_WIDGET(view->canvas),
394 scale * label_width + 40,
395 scale * label_height + 40);
396 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
400 gnome_canvas_set_scroll_region (GNOME_CANVAS (view->canvas),
401 0.0, 0.0, label_width, label_height);
405 g_signal_connect (G_OBJECT (view->canvas), "event",
406 G_CALLBACK (canvas_event), view);
408 gl_debug (DEBUG_VIEW, "END");
413 /*---------------------------------------------------------------------------*/
414 /* PRIVATE. Create clipboard selection targets. */
415 /*---------------------------------------------------------------------------*/
417 gl_view_construct_selection (glView *view)
419 gl_debug (DEBUG_VIEW, "START");
421 g_return_if_fail (GL_IS_VIEW (view));
423 view->have_selection = FALSE;
424 view->selection_data = NULL;
425 view->invisible = gtk_invisible_new ();
427 view->selected_object_list = NULL;
429 if (!clipboard_atom) {
430 clipboard_atom = gdk_atom_intern ("GLABELS_CLIPBOARD", FALSE);
433 gtk_selection_add_target (view->invisible,
434 clipboard_atom, GDK_SELECTION_TYPE_STRING, 1);
436 g_signal_connect (G_OBJECT (view->invisible),
437 "selection_clear_event",
438 G_CALLBACK (selection_clear_cb), view);
440 g_signal_connect (G_OBJECT (view->invisible), "selection_get",
441 G_CALLBACK (selection_get_cb), view);
443 g_signal_connect (G_OBJECT (view->invisible),
444 "selection_received",
445 G_CALLBACK (selection_received_cb), view);
447 gl_debug (DEBUG_VIEW, "END");
450 /*---------------------------------------------------------------------------*/
451 /* PRIVATE. Determine an apropriate scale for given label & screen size */
452 /*---------------------------------------------------------------------------*/
454 get_apropriate_scale (gdouble w, gdouble h)
456 gdouble w_screen, h_screen;
460 gl_debug (DEBUG_VIEW, "");
462 w_screen = (gdouble) gdk_screen_width ();
463 h_screen = (gdouble) gdk_screen_height ();
465 for (i = 0; i < N_SCALES; i++) {
467 if (k <= HOME_SCALE) {
468 if ((k * w < (w_screen - 256))
469 && (k * h < (h_screen - 256)))
477 /*---------------------------------------------------------------------------*/
478 /* PRIVATE. Create, draw and order layers. */
479 /*---------------------------------------------------------------------------*/
481 draw_layers (glView *view)
483 draw_bg_fg_layers (view);
484 draw_grid_layer (view);
485 draw_markup_layer (view);
486 draw_highlight_layer (view); /* Must be done before label layer */
487 draw_label_layer (view);
489 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->fg_group));
490 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->highlight_group));
493 /*---------------------------------------------------------------------------*/
494 /* PRIVATE. Draw label layer. */
495 /*---------------------------------------------------------------------------*/
497 draw_label_layer (glView *view)
499 GnomeCanvasGroup *group;
502 glLabelObject *object;
503 glViewObject *view_object;
505 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
506 view->label_group = GNOME_CANVAS_GROUP(
507 gnome_canvas_item_new (group,
508 gnome_canvas_group_get_type (),
515 for (p_obj = label->objects; p_obj != NULL; p_obj = p_obj->next) {
516 object = (glLabelObject *) p_obj->data;
518 if (GL_IS_LABEL_BOX (object)) {
519 view_object = gl_view_box_new (GL_LABEL_BOX(object),
521 } else if (GL_IS_LABEL_ELLIPSE (object)) {
522 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object),
524 } else if (GL_IS_LABEL_LINE (object)) {
525 view_object = gl_view_line_new (GL_LABEL_LINE(object),
527 } else if (GL_IS_LABEL_IMAGE (object)) {
528 view_object = gl_view_image_new (GL_LABEL_IMAGE(object),
530 } else if (GL_IS_LABEL_TEXT (object)) {
531 view_object = gl_view_text_new (GL_LABEL_TEXT(object),
533 } else if (GL_IS_LABEL_BARCODE (object)) {
534 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(object),
537 /* Should not happen! */
539 g_warning ("Invalid label object type.");
544 /*---------------------------------------------------------------------------*/
545 /* PRIVATE. Create highlight layer. */
546 /*---------------------------------------------------------------------------*/
548 draw_highlight_layer (glView *view)
550 GnomeCanvasGroup *group;
552 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
553 view->highlight_group = GNOME_CANVAS_GROUP(
554 gnome_canvas_item_new (group,
555 gnome_canvas_group_get_type (),
561 /*---------------------------------------------------------------------------*/
562 /* PRIVATE. Draw background and foreground outlines. */
563 /*---------------------------------------------------------------------------*/
565 draw_bg_fg_layers (glView *view)
568 glTemplate *template;
569 GnomeCanvasGroup *group;
571 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
572 view->bg_group = GNOME_CANVAS_GROUP(
573 gnome_canvas_item_new (group,
574 gnome_canvas_group_get_type (),
578 view->fg_group = GNOME_CANVAS_GROUP(
579 gnome_canvas_item_new (group,
580 gnome_canvas_group_get_type (),
586 template = gl_label_get_template (label);
588 switch (template->label.style) {
590 case GL_TEMPLATE_STYLE_RECT:
591 if (template->label.rect.r == 0.0) {
592 /* Square corners. */
593 draw_bg_fg_rect (view);
595 /* Rounded corners. */
596 draw_bg_fg_rounded_rect (view);
600 case GL_TEMPLATE_STYLE_ROUND:
601 draw_bg_fg_round (view);
604 case GL_TEMPLATE_STYLE_CD:
605 draw_bg_fg_cd (view);
609 g_warning ("Unknown template label style");
614 /*---------------------------------------------------------------------------*/
615 /* PRIVATE. Draw simple recangular background. */
616 /*---------------------------------------------------------------------------*/
618 draw_bg_fg_rect (glView *view)
620 glLabel *label = view->label;
621 glTemplate *template;
623 GnomeCanvasItem *item;
625 gl_debug (DEBUG_VIEW, "START");
627 g_return_if_fail (GL_IS_VIEW (view));
628 g_return_if_fail (label != NULL);
630 gl_label_get_size (label, &w, &h);
631 template = gl_label_get_template (label);
634 item = gnome_canvas_item_new (view->bg_group,
635 gnome_canvas_rect_get_type (),
640 "fill_color_rgba", PAPER_COLOR,
644 item = gnome_canvas_item_new (view->fg_group,
645 gnome_canvas_rect_get_type (),
651 "outline_color_rgba", OUTLINE_COLOR,
654 gl_debug (DEBUG_VIEW, "END");
657 /*---------------------------------------------------------------------------*/
658 /* PRIVATE. Draw rounded recangular background. */
659 /*---------------------------------------------------------------------------*/
661 draw_bg_fg_rounded_rect (glView *view)
663 glLabel *label = view->label;
664 GnomeCanvasPoints *points;
665 gint i_coords, i_theta;
666 glTemplate *template;
668 GnomeCanvasItem *item;
670 gl_debug (DEBUG_VIEW, "START");
672 g_return_if_fail (GL_IS_VIEW (view));
673 g_return_if_fail (label != NULL);
675 gl_label_get_size (label, &w, &h);
676 template = gl_label_get_template (label);
677 r = template->label.rect.r;
679 points = gnome_canvas_points_new (4 * (1 + 90 / 5));
681 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
682 points->coords[i_coords++] =
683 r - r * sin (i_theta * M_PI / 180.0);
684 points->coords[i_coords++] =
685 r - r * cos (i_theta * M_PI / 180.0);
687 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
688 points->coords[i_coords++] =
689 r - r * cos (i_theta * M_PI / 180.0);
690 points->coords[i_coords++] =
691 (h - r) + r * sin (i_theta * M_PI / 180.0);
693 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
694 points->coords[i_coords++] =
695 (w - r) + r * sin (i_theta * M_PI / 180.0);
696 points->coords[i_coords++] =
697 (h - r) + r * cos (i_theta * M_PI / 180.0);
699 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
700 points->coords[i_coords++] =
701 (w - r) + r * cos (i_theta * M_PI / 180.0);
702 points->coords[i_coords++] =
703 r - r * sin (i_theta * M_PI / 180.0);
707 item = gnome_canvas_item_new (view->bg_group,
708 gnome_canvas_polygon_get_type (),
710 "fill_color_rgba", PAPER_COLOR,
714 item = gnome_canvas_item_new (view->fg_group,
715 gnome_canvas_polygon_get_type (),
718 "outline_color_rgba", OUTLINE_COLOR,
721 gnome_canvas_points_free (points);
723 gl_debug (DEBUG_VIEW, "END");
726 /*---------------------------------------------------------------------------*/
727 /* PRIVATE. Draw round background. */
728 /*---------------------------------------------------------------------------*/
730 draw_bg_fg_round (glView *view)
732 glLabel *label = view->label;
733 glTemplate *template;
735 GnomeCanvasItem *item;
737 gl_debug (DEBUG_VIEW, "START");
739 g_return_if_fail (GL_IS_VIEW (view));
740 g_return_if_fail (label != NULL);
742 template = gl_label_get_template (label);
744 r = template->label.round.r;
747 item = gnome_canvas_item_new (view->bg_group,
748 gnome_canvas_ellipse_get_type (),
753 "fill_color_rgba", PAPER_COLOR,
757 item = gnome_canvas_item_new (view->fg_group,
758 gnome_canvas_ellipse_get_type (),
764 "outline_color_rgba", OUTLINE_COLOR,
767 gl_debug (DEBUG_VIEW, "END");
770 /*---------------------------------------------------------------------------*/
771 /* PRIVATE. Draw CD style background, circular w/ concentric hole. */
772 /*---------------------------------------------------------------------------*/
774 draw_bg_fg_cd (glView *view)
776 glLabel *label = view->label;
777 glTemplate *template;
779 GnomeCanvasItem *item;
781 gl_debug (DEBUG_VIEW, "START");
783 g_return_if_fail (GL_IS_VIEW (view));
784 g_return_if_fail (label != NULL);
786 template = gl_label_get_template (label);
788 r1 = template->label.cd.r1;
789 r2 = template->label.cd.r2;
793 item = gnome_canvas_item_new (view->bg_group,
794 gnome_canvas_ellipse_get_type (),
799 "fill_color_rgba", PAPER_COLOR,
802 item = gnome_canvas_item_new (view->bg_group,
803 gnome_canvas_ellipse_get_type (),
808 "fill_color_rgba", GRID_COLOR,
813 item = gnome_canvas_item_new (view->fg_group,
814 gnome_canvas_ellipse_get_type (),
820 "outline_color_rgba", OUTLINE_COLOR,
823 item = gnome_canvas_item_new (view->fg_group,
824 gnome_canvas_ellipse_get_type (),
830 "outline_color_rgba", OUTLINE_COLOR,
833 gl_debug (DEBUG_VIEW, "END");
836 /*---------------------------------------------------------------------------*/
837 /* PRIVATE. Draw grid lines. */
838 /*---------------------------------------------------------------------------*/
840 draw_grid_layer (glView *view)
843 GnomeCanvasPoints *points;
844 GnomeCanvasItem *item;
845 GnomeCanvasGroup *group;
847 gl_debug (DEBUG_VIEW, "START");
849 g_return_if_fail (view && GL_IS_VIEW (view));
850 g_return_if_fail (view->label && GL_IS_LABEL(view->label));
852 gl_label_get_size (view->label, &w, &h);
854 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
855 view->grid_group = GNOME_CANVAS_GROUP(
856 gnome_canvas_item_new (group,
857 gnome_canvas_group_get_type (),
861 points = gnome_canvas_points_new (2);
863 points->coords[1] = 0.0;
864 points->coords[3] = h;
865 for ( x=0.0; x < w; x += view->grid_spacing ) {
866 points->coords[0] = points->coords[2] = x;
867 item = gnome_canvas_item_new (view->grid_group,
868 gnome_canvas_line_get_type (),
871 "fill_color_rgba", GRID_COLOR,
874 points->coords[0] = points->coords[2] = w;
875 item = gnome_canvas_item_new (view->grid_group,
876 gnome_canvas_line_get_type (),
879 "fill_color_rgba", GRID_COLOR,
882 points->coords[0] = 0.0;
883 points->coords[2] = w;
884 for ( y=0.0; y < h; y += view->grid_spacing ) {
885 points->coords[1] = points->coords[3] = y;
886 item = gnome_canvas_item_new (view->grid_group,
887 gnome_canvas_line_get_type (),
890 "fill_color_rgba", GRID_COLOR,
893 points->coords[1] = points->coords[3] = h;
894 item = gnome_canvas_item_new (view->grid_group,
895 gnome_canvas_line_get_type (),
898 "fill_color_rgba", GRID_COLOR,
901 gnome_canvas_points_free (points);
903 gl_debug (DEBUG_VIEW, "END");
906 /*---------------------------------------------------------------------------*/
907 /* PRIVATE. Draw markup lines. */
908 /*---------------------------------------------------------------------------*/
910 draw_markup_layer (glView *view)
912 GnomeCanvasGroup *group;
914 glTemplate *template;
916 glTemplateMarkup *markup;
918 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
919 view->markup_group = GNOME_CANVAS_GROUP(
920 gnome_canvas_item_new (group,
921 gnome_canvas_group_get_type (),
926 template = gl_label_get_template (label);
928 for ( p=template->label.any.markups; p != NULL; p=p->next ) {
929 markup = (glTemplateMarkup *)p->data;
931 switch (markup->type) {
932 case GL_TEMPLATE_MARKUP_MARGIN:
933 draw_markup_margin (view,
934 (glTemplateMarkupMargin *)markup);
936 case GL_TEMPLATE_MARKUP_LINE:
937 draw_markup_line (view,
938 (glTemplateMarkupLine *)markup);
941 g_warning ("Unknown template markup type");
947 /*---------------------------------------------------------------------------*/
948 /* PRIVATE. Draw margin markup. */
949 /*---------------------------------------------------------------------------*/
951 draw_markup_margin (glView *view,
952 glTemplateMarkupMargin *margin)
955 glTemplate *template;
958 template = gl_label_get_template (label);
960 switch (template->label.style) {
962 case GL_TEMPLATE_STYLE_RECT:
963 if (template->label.rect.r == 0.0) {
964 /* Square corners. */
965 draw_markup_margin_rect (view, margin);
967 if ( margin->size < template->label.rect.r) {
968 /* Rounded corners. */
969 draw_markup_margin_rounded_rect (view, margin);
971 /* Square corners. */
972 draw_markup_margin_rect (view, margin);
977 case GL_TEMPLATE_STYLE_ROUND:
978 draw_markup_margin_round (view, margin);
981 case GL_TEMPLATE_STYLE_CD:
982 draw_markup_margin_cd (view, margin);
986 g_warning ("Unknown template label style");
991 /*---------------------------------------------------------------------------*/
992 /* PRIVATE. Draw simple recangular margin. */
993 /*---------------------------------------------------------------------------*/
995 draw_markup_margin_rect (glView *view,
996 glTemplateMarkupMargin *margin)
998 glLabel *label = view->label;
999 glTemplate *template;
1001 GnomeCanvasItem *item;
1003 gl_debug (DEBUG_VIEW, "START");
1005 g_return_if_fail (GL_IS_VIEW (view));
1006 g_return_if_fail (label != NULL);
1008 gl_label_get_size (label, &w, &h);
1009 template = gl_label_get_template (label);
1012 /* Bounding box @ margin */
1013 gnome_canvas_item_new (view->markup_group,
1014 gnome_canvas_rect_get_type (),
1020 "outline_color_rgba", MARKUP_COLOR,
1023 gl_debug (DEBUG_VIEW, "END");
1026 /*---------------------------------------------------------------------------*/
1027 /* PRIVATE. Draw rounded recangular markup. */
1028 /*---------------------------------------------------------------------------*/
1030 draw_markup_margin_rounded_rect (glView *view,
1031 glTemplateMarkupMargin *margin)
1033 glLabel *label = view->label;
1034 GnomeCanvasPoints *points;
1035 gint i_coords, i_theta;
1036 glTemplate *template;
1038 GnomeCanvasItem *item;
1040 gl_debug (DEBUG_VIEW, "START");
1042 g_return_if_fail (GL_IS_VIEW (view));
1043 g_return_if_fail (label != NULL);
1045 gl_label_get_size (label, &w, &h);
1046 template = gl_label_get_template (label);
1047 r = template->label.rect.r;
1054 /* rectangle with rounded corners */
1055 points = gnome_canvas_points_new (4 * (1 + 90 / 5));
1057 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
1058 points->coords[i_coords++] =
1059 m + r - r * sin (i_theta * M_PI / 180.0);
1060 points->coords[i_coords++] =
1061 m + r - r * cos (i_theta * M_PI / 180.0);
1063 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
1064 points->coords[i_coords++] =
1065 m + r - r * cos (i_theta * M_PI / 180.0);
1066 points->coords[i_coords++] =
1067 m + (h - r) + r * sin (i_theta * M_PI / 180.0);
1069 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
1070 points->coords[i_coords++] =
1071 m + (w - r) + r * sin (i_theta * M_PI / 180.0);
1072 points->coords[i_coords++] =
1073 m + (h - r) + r * cos (i_theta * M_PI / 180.0);
1075 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
1076 points->coords[i_coords++] =
1077 m + (w - r) + r * cos (i_theta * M_PI / 180.0);
1078 points->coords[i_coords++] =
1079 m + r - r * sin (i_theta * M_PI / 180.0);
1081 item = gnome_canvas_item_new (view->markup_group,
1082 gnome_canvas_polygon_get_type (),
1085 "outline_color_rgba", MARKUP_COLOR,
1087 gnome_canvas_points_free (points);
1089 gl_debug (DEBUG_VIEW, "END");
1092 /*---------------------------------------------------------------------------*/
1093 /* PRIVATE. Draw round margin. */
1094 /*---------------------------------------------------------------------------*/
1096 draw_markup_margin_round (glView *view,
1097 glTemplateMarkupMargin *margin)
1099 glLabel *label = view->label;
1100 glTemplate *template;
1102 GnomeCanvasItem *item;
1104 gl_debug (DEBUG_VIEW, "START");
1106 g_return_if_fail (GL_IS_VIEW (view));
1107 g_return_if_fail (label != NULL);
1109 template = gl_label_get_template (label);
1111 r = template->label.round.r;
1114 /* Margin outline */
1115 item = gnome_canvas_item_new (view->markup_group,
1116 gnome_canvas_ellipse_get_type (),
1122 "outline_color_rgba", MARKUP_COLOR,
1125 gl_debug (DEBUG_VIEW, "END");
1128 /*---------------------------------------------------------------------------*/
1129 /* PRIVATE. Draw CD margins. */
1130 /*---------------------------------------------------------------------------*/
1132 draw_markup_margin_cd (glView *view,
1133 glTemplateMarkupMargin *margin)
1135 glLabel *label = view->label;
1136 glTemplate *template;
1138 GnomeCanvasItem *item;
1140 gl_debug (DEBUG_VIEW, "START");
1142 g_return_if_fail (GL_IS_VIEW (view));
1143 g_return_if_fail (label != NULL);
1145 template = gl_label_get_template (label);
1147 r1 = template->label.cd.r1;
1148 r2 = template->label.cd.r2;
1152 item = gnome_canvas_item_new (view->markup_group,
1153 gnome_canvas_ellipse_get_type (),
1159 "outline_color_rgba", MARKUP_COLOR,
1162 item = gnome_canvas_item_new (view->markup_group,
1163 gnome_canvas_ellipse_get_type (),
1169 "outline_color_rgba", MARKUP_COLOR,
1172 gl_debug (DEBUG_VIEW, "END");
1175 /*---------------------------------------------------------------------------*/
1176 /* PRIVATE. Draw line markup. */
1177 /*---------------------------------------------------------------------------*/
1179 draw_markup_line (glView *view,
1180 glTemplateMarkupLine *line)
1182 GnomeCanvasPoints *points;
1184 gl_debug (DEBUG_VIEW, "START");
1186 g_return_if_fail (GL_IS_VIEW (view));
1188 points = gnome_canvas_points_new (2);
1189 points->coords[0] = line->x1;
1190 points->coords[1] = line->y1;
1191 points->coords[2] = line->x2;
1192 points->coords[3] = line->y2;
1194 /* Bounding box @ margin */
1195 gnome_canvas_item_new (view->markup_group,
1196 gnome_canvas_line_get_type (),
1199 "fill_color_rgba", MARKUP_COLOR,
1202 gnome_canvas_points_free (points);
1204 gl_debug (DEBUG_VIEW, "END");
1207 /*****************************************************************************/
1209 /*****************************************************************************/
1210 void gl_view_show_grid (glView *view)
1212 gnome_canvas_item_show (GNOME_CANVAS_ITEM(view->grid_group));
1215 /*****************************************************************************/
1217 /*****************************************************************************/
1218 void gl_view_hide_grid (glView *view)
1220 gnome_canvas_item_hide (GNOME_CANVAS_ITEM(view->grid_group));
1223 /*****************************************************************************/
1224 /* Set grid spacing. */
1225 /*****************************************************************************/
1226 void gl_view_set_grid_spacing (glView *view,
1229 view->grid_spacing = spacing;
1231 gtk_object_destroy (GTK_OBJECT(view->grid_group));
1232 draw_grid_layer (view);
1235 /*****************************************************************************/
1237 /*****************************************************************************/
1238 void gl_view_show_markup (glView *view)
1240 gnome_canvas_item_show (GNOME_CANVAS_ITEM(view->markup_group));
1243 /*****************************************************************************/
1245 /*****************************************************************************/
1246 void gl_view_hide_markup (glView *view)
1248 gnome_canvas_item_hide (GNOME_CANVAS_ITEM(view->markup_group));
1251 /*****************************************************************************/
1252 /* Set arrow mode. */
1253 /*****************************************************************************/
1255 gl_view_arrow_mode (glView *view)
1257 static GdkCursor *cursor = NULL;
1259 gl_debug (DEBUG_VIEW, "START");
1261 g_return_if_fail (GL_IS_VIEW (view));
1264 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1267 gdk_window_set_cursor (view->canvas->window, cursor);
1269 view->state = GL_VIEW_STATE_ARROW;
1271 gl_debug (DEBUG_VIEW, "END");
1274 /*****************************************************************************/
1275 /* Set create text object mode. */
1276 /*****************************************************************************/
1278 gl_view_object_create_mode (glView *view,
1279 glLabelObjectType type)
1283 gl_debug (DEBUG_VIEW, "START");
1285 g_return_if_fail (GL_IS_VIEW (view));
1288 case GL_LABEL_OBJECT_BOX:
1289 cursor = gl_view_box_get_create_cursor ();
1291 case GL_LABEL_OBJECT_ELLIPSE:
1292 cursor = gl_view_ellipse_get_create_cursor ();
1294 case GL_LABEL_OBJECT_LINE:
1295 cursor = gl_view_line_get_create_cursor ();
1297 case GL_LABEL_OBJECT_IMAGE:
1298 cursor = gl_view_image_get_create_cursor ();
1300 case GL_LABEL_OBJECT_TEXT:
1301 cursor = gl_view_text_get_create_cursor ();
1303 case GL_LABEL_OBJECT_BARCODE:
1304 cursor = gl_view_barcode_get_create_cursor ();
1307 g_warning ("Invalid label object type.");/*Should not happen!*/
1311 gdk_window_set_cursor (view->canvas->window, cursor);
1313 view->state = GL_VIEW_STATE_OBJECT_CREATE;
1314 view->create_type = type;
1316 gl_debug (DEBUG_VIEW, "END");
1319 /*****************************************************************************/
1320 /* Select given object (adding to current selection). */
1321 /*****************************************************************************/
1323 gl_view_select_object (glView *view,
1324 glViewObject *view_object)
1326 gl_debug (DEBUG_VIEW, "START");
1328 select_object_real (view, view_object);
1330 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1332 gl_debug (DEBUG_VIEW, "END");
1335 /*****************************************************************************/
1336 /* Unselect given object (removing from current selection). */
1337 /*****************************************************************************/
1339 gl_view_unselect_object (glView *view,
1340 glViewObject *view_object)
1342 gl_debug (DEBUG_VIEW, "START");
1344 unselect_object_real (view, view_object);
1346 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1348 gl_debug (DEBUG_VIEW, "END");
1351 /*****************************************************************************/
1352 /* Select all items. */
1353 /*****************************************************************************/
1355 gl_view_select_all (glView *view)
1359 gl_debug (DEBUG_VIEW, "START");
1361 g_return_if_fail (GL_IS_VIEW (view));
1363 /* 1st unselect anything already selected. */
1364 for (p = view->selected_object_list; p != NULL; p = p_next) {
1366 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1369 /* Finally select all objects. */
1370 for (p = view->object_list; p != NULL; p = p->next) {
1371 select_object_real (view, GL_VIEW_OBJECT (p->data));
1374 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1376 gl_debug (DEBUG_VIEW, "END");
1379 /*****************************************************************************/
1380 /* Remove all selections */
1381 /*****************************************************************************/
1383 gl_view_unselect_all (glView *view)
1387 gl_debug (DEBUG_VIEW, "START");
1389 g_return_if_fail (GL_IS_VIEW (view));
1391 for (p = view->selected_object_list; p != NULL; p = p_next) {
1393 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1396 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1398 gl_debug (DEBUG_VIEW, "END");
1401 /*****************************************************************************/
1402 /* Select all objects within given rectangular region (adding to selection). */
1403 /*****************************************************************************/
1405 gl_view_select_region (glView *view,
1412 glViewObject *view_object;
1413 glLabelObject *object;
1414 gdouble i_x1, i_y1, i_x2, i_y2;
1416 gl_debug (DEBUG_VIEW, "START");
1418 g_return_if_fail (GL_IS_VIEW (view));
1419 g_return_if_fail ((x1 <= x2) && (y1 <= y2));
1421 for (p = view->object_list; p != NULL; p = p->next) {
1422 view_object = GL_VIEW_OBJECT(p->data);
1423 if (!is_object_selected (view, view_object)) {
1425 object = gl_view_object_get_object (view_object);
1427 gl_label_object_get_extent (object, &i_x1, &i_y1, &i_x2, &i_y2);
1428 if ((i_x1 >= x1) && (i_x2 <= x2) && (i_y1 >= y1)
1430 select_object_real (view, view_object);
1436 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1438 gl_debug (DEBUG_VIEW, "END");
1441 /*---------------------------------------------------------------------------*/
1442 /* PRIVATE. Select an object. */
1443 /*---------------------------------------------------------------------------*/
1445 select_object_real (glView *view,
1446 glViewObject *view_object)
1448 gl_debug (DEBUG_VIEW, "START");
1450 g_return_if_fail (GL_IS_VIEW (view));
1451 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1453 if (!is_object_selected (view, view_object)) {
1454 view->selected_object_list =
1455 g_list_prepend (view->selected_object_list, view_object);
1457 gl_view_object_show_highlight (view_object);
1458 gtk_widget_grab_focus (GTK_WIDGET (view->canvas));
1460 gl_debug (DEBUG_VIEW, "END");
1463 /*---------------------------------------------------------------------------*/
1464 /* PRIVATE. Un-select object. */
1465 /*---------------------------------------------------------------------------*/
1467 unselect_object_real (glView *view,
1468 glViewObject *view_object)
1470 gl_debug (DEBUG_VIEW, "START");
1472 g_return_if_fail (GL_IS_VIEW (view));
1473 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1475 gl_view_object_hide_highlight (view_object);
1477 view->selected_object_list =
1478 g_list_remove (view->selected_object_list, view_object);
1480 gl_debug (DEBUG_VIEW, "END");
1483 /*---------------------------------------------------------------------------*/
1484 /* PRIVATE. Return object at (x,y). */
1485 /*---------------------------------------------------------------------------*/
1487 object_at (glView *view,
1491 GnomeCanvasItem *item, *p_item;
1494 gl_debug (DEBUG_VIEW, "");
1496 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1498 item = gnome_canvas_get_item_at (GNOME_CANVAS (view->canvas), x, y);
1500 /* No item is at x, y */
1504 /* ignore items not in label or highlight layers, e.g. background items */
1505 if (!is_item_member_of_group(view, item, GNOME_CANVAS_ITEM(view->label_group)) &&
1506 !is_item_member_of_group(view, item, GNOME_CANVAS_ITEM(view->highlight_group)))
1512 /*---------------------------------------------------------------------------*/
1513 /* PRIVATE. Is the item a child (or grandchild, etc.) of group. */
1514 /*---------------------------------------------------------------------------*/
1516 is_item_member_of_group (glView *view,
1517 GnomeCanvasItem *item,
1518 GnomeCanvasItem *group)
1520 GnomeCanvasItem *parent;
1521 GnomeCanvasItem *root_group;
1523 root_group = GNOME_CANVAS_ITEM(gnome_canvas_root (GNOME_CANVAS (view->canvas)));
1525 for ( parent=item->parent; parent && (parent!=root_group); parent=parent->parent) {
1526 if (parent == group) return TRUE;
1531 /*---------------------------------------------------------------------------*/
1532 /* PRIVATE. Is the object in our current selection? */
1533 /*---------------------------------------------------------------------------*/
1535 is_object_selected (glView *view,
1536 glViewObject *view_object)
1538 gl_debug (DEBUG_VIEW, "");
1540 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1541 g_return_val_if_fail (GL_IS_VIEW_OBJECT (view_object), FALSE);
1543 if (g_list_find (view->selected_object_list, view_object) == NULL) {
1549 /*****************************************************************************/
1550 /* Is our current selection empty? */
1551 /*****************************************************************************/
1553 gl_view_is_selection_empty (glView *view)
1555 gl_debug (DEBUG_VIEW, "");
1557 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1559 if (view->selected_object_list == NULL) {
1566 /*****************************************************************************/
1567 /* Is our current selection atomic? I.e. only one item selected. */
1568 /*****************************************************************************/
1570 gl_view_is_selection_atomic (glView *view)
1572 gl_debug (DEBUG_VIEW, "");
1574 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1576 if (view->selected_object_list == NULL)
1578 if (view->selected_object_list->next == NULL)
1583 /*****************************************************************************/
1584 /* Delete selected objects. (Bypass clipboard) */
1585 /*****************************************************************************/
1587 gl_view_delete_selection (glView *view)
1591 gl_debug (DEBUG_VIEW, "START");
1593 g_return_if_fail (GL_IS_VIEW (view));
1595 for (p = view->selected_object_list; p != NULL; p = p_next) {
1597 g_object_unref (G_OBJECT (p->data));
1600 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1602 gl_debug (DEBUG_VIEW, "END");
1605 /*****************************************************************************/
1606 /* Edit properties of selected object. */
1607 /*****************************************************************************/
1609 gl_view_edit_object_props (glView *view)
1611 glViewObject *view_object;
1613 gl_debug (DEBUG_VIEW, "START");
1615 g_return_if_fail (GL_IS_VIEW (view));
1617 if (gl_view_is_selection_atomic (view)) {
1619 view_object = GL_VIEW_OBJECT(view->selected_object_list->data);
1620 gl_view_object_show_dialog (view_object);
1624 gl_debug (DEBUG_VIEW, "END");
1627 /*****************************************************************************/
1628 /* Raise selected items to top. */
1629 /*****************************************************************************/
1631 gl_view_raise_selection (glView *view)
1634 glViewObject *view_object;
1635 glLabelObject *object;
1637 gl_debug (DEBUG_VIEW, "START");
1639 g_return_if_fail (GL_IS_VIEW (view));
1641 for (p = view->selected_object_list; p != NULL; p = p->next) {
1642 view_object = GL_VIEW_OBJECT (p->data);
1643 object = gl_view_object_get_object (view_object);
1644 gl_label_object_raise_to_top (object);
1647 gl_debug (DEBUG_VIEW, "END");
1650 /*****************************************************************************/
1651 /* Lower selected items to bottom. */
1652 /*****************************************************************************/
1654 gl_view_lower_selection (glView *view)
1657 glViewObject *view_object;
1658 glLabelObject *object;
1660 gl_debug (DEBUG_VIEW, "START");
1662 g_return_if_fail (GL_IS_VIEW (view));
1664 for (p = view->selected_object_list; p != NULL; p = p->next) {
1665 view_object = GL_VIEW_OBJECT (p->data);
1666 object = gl_view_object_get_object (view_object);
1667 gl_label_object_lower_to_bottom (object);
1670 gl_debug (DEBUG_VIEW, "END");
1673 /*****************************************************************************/
1674 /* Rotate selected objects by given angle. */
1675 /*****************************************************************************/
1677 gl_view_rotate_selection (glView *view,
1681 glViewObject *view_object;
1682 glLabelObject *object;
1684 gl_debug (DEBUG_VIEW, "START");
1686 g_return_if_fail (GL_IS_VIEW (view));
1688 for (p = view->selected_object_list; p != NULL; p = p->next) {
1689 view_object = GL_VIEW_OBJECT (p->data);
1690 object = gl_view_object_get_object (view_object);
1691 gl_label_object_rotate (object, theta_degs);
1694 gl_debug (DEBUG_VIEW, "END");
1697 /*****************************************************************************/
1698 /* Flip selected objects horizontally. */
1699 /*****************************************************************************/
1701 gl_view_flip_selection_horiz (glView *view)
1704 glViewObject *view_object;
1705 glLabelObject *object;
1707 gl_debug (DEBUG_VIEW, "START");
1709 g_return_if_fail (GL_IS_VIEW (view));
1711 for (p = view->selected_object_list; p != NULL; p = p->next) {
1712 view_object = GL_VIEW_OBJECT (p->data);
1713 object = gl_view_object_get_object (view_object);
1714 gl_label_object_flip_horiz (object);
1717 gl_debug (DEBUG_VIEW, "END");
1720 /*****************************************************************************/
1721 /* Flip selected objects vertically. */
1722 /*****************************************************************************/
1724 gl_view_flip_selection_vert (glView *view)
1727 glViewObject *view_object;
1728 glLabelObject *object;
1730 gl_debug (DEBUG_VIEW, "START");
1732 g_return_if_fail (GL_IS_VIEW (view));
1734 for (p = view->selected_object_list; p != NULL; p = p->next) {
1735 view_object = GL_VIEW_OBJECT (p->data);
1736 object = gl_view_object_get_object (view_object);
1737 gl_label_object_flip_vert (object);
1740 gl_debug (DEBUG_VIEW, "END");
1743 /*****************************************************************************/
1744 /* Align selected objects to left most edge. */
1745 /*****************************************************************************/
1747 gl_view_align_selection_left (glView *view)
1750 glViewObject *view_object;
1751 glLabelObject *object;
1752 gdouble dx, x1min, x1, y1, x2, y2;
1754 gl_debug (DEBUG_VIEW, "START");
1756 g_return_if_fail (GL_IS_VIEW (view));
1758 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1759 !gl_view_is_selection_atomic (view));
1761 /* find left most edge */
1762 p = view->selected_object_list;
1763 view_object = GL_VIEW_OBJECT (p->data);
1764 object = gl_view_object_get_object (view_object);
1765 gl_label_object_get_extent (object, &x1min, &y1, &x2, &y2);
1766 for (p = p->next; p != NULL; p = p->next) {
1767 view_object = GL_VIEW_OBJECT (p->data);
1768 object = gl_view_object_get_object (view_object);
1769 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1770 if ( x1 < x1min ) x1min = x1;
1773 /* now adjust the object positions to line up the left edges */
1774 for (p = view->selected_object_list; p != NULL; p = p->next) {
1775 view_object = GL_VIEW_OBJECT (p->data);
1776 object = gl_view_object_get_object (view_object);
1777 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1779 gl_label_object_set_position_relative (object, dx, 0.0);
1782 gl_debug (DEBUG_VIEW, "END");
1786 /*****************************************************************************/
1787 /* Align selected objects to right most edge. */
1788 /*****************************************************************************/
1790 gl_view_align_selection_right (glView *view)
1793 glViewObject *view_object;
1794 glLabelObject *object;
1795 gdouble dx, x2max, x1, y1, x2, y2;
1797 gl_debug (DEBUG_VIEW, "START");
1799 g_return_if_fail (GL_IS_VIEW (view));
1801 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1802 !gl_view_is_selection_atomic (view));
1804 /* find right most edge */
1805 p = view->selected_object_list;
1806 view_object = GL_VIEW_OBJECT (p->data);
1807 object = gl_view_object_get_object (view_object);
1808 gl_label_object_get_extent (object, &x1, &y1, &x2max, &y2);
1809 for (p = p->next; p != NULL; p = p->next) {
1810 view_object = GL_VIEW_OBJECT (p->data);
1811 object = gl_view_object_get_object (view_object);
1812 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1813 if ( x2 > x2max ) x2max = x2;
1816 /* now adjust the object positions to line up the right edges */
1817 for (p = view->selected_object_list; p != NULL; p = p->next) {
1818 view_object = GL_VIEW_OBJECT (p->data);
1819 object = gl_view_object_get_object (view_object);
1820 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1822 gl_label_object_set_position_relative (object, dx, 0.0);
1825 gl_debug (DEBUG_VIEW, "END");
1828 /*****************************************************************************/
1829 /* Align selected objects to horizontal center of objects. */
1830 /*****************************************************************************/
1832 gl_view_align_selection_hcenter (glView *view)
1835 glViewObject *view_object;
1836 glLabelObject *object;
1837 gdouble dx, dxmin, xsum, xavg, xcenter, x1, y1, x2, y2;
1840 gl_debug (DEBUG_VIEW, "START");
1842 g_return_if_fail (GL_IS_VIEW (view));
1844 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1845 !gl_view_is_selection_atomic (view));
1847 /* find average center of objects */
1850 for (p = view->selected_object_list; p != NULL; p = p->next) {
1851 view_object = GL_VIEW_OBJECT (p->data);
1852 object = gl_view_object_get_object (view_object);
1853 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1854 xsum += (x1 + x2) / 2.0;
1859 /* find center of object closest to average center */
1860 p = view->selected_object_list;
1861 view_object = GL_VIEW_OBJECT (p->data);
1862 object = gl_view_object_get_object (view_object);
1863 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1864 dxmin = fabs (xavg - (x1 + x2)/2.0);
1865 xcenter = (x1 + x2)/2.0;
1866 for (p = p->next; p != NULL; p = p->next) {
1867 view_object = GL_VIEW_OBJECT (p->data);
1868 object = gl_view_object_get_object (view_object);
1869 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1870 dx = fabs (xavg - (x1 + x2)/2.0);
1873 xcenter = (x1 + x2)/2.0;
1877 /* now adjust the object positions to line up this center */
1878 for (p = view->selected_object_list; p != NULL; p = p->next) {
1879 view_object = GL_VIEW_OBJECT (p->data);
1880 object = gl_view_object_get_object (view_object);
1881 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1882 dx = xcenter - (x1 + x2)/2.0;
1883 gl_label_object_set_position_relative (object, dx, 0.0);
1886 gl_debug (DEBUG_VIEW, "END");
1889 /*****************************************************************************/
1890 /* Align selected objects to top most edge. */
1891 /*****************************************************************************/
1893 gl_view_align_selection_top (glView *view)
1896 glViewObject *view_object;
1897 glLabelObject *object;
1898 gdouble dy, y1min, x1, y1, x2, y2;
1900 gl_debug (DEBUG_VIEW, "START");
1902 g_return_if_fail (GL_IS_VIEW (view));
1904 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1905 !gl_view_is_selection_atomic (view));
1907 /* find top most edge */
1908 p = view->selected_object_list;
1909 view_object = GL_VIEW_OBJECT (p->data);
1910 object = gl_view_object_get_object (view_object);
1911 gl_label_object_get_extent (object, &x1, &y1min, &x2, &y2);
1912 for (p = p->next; p != NULL; p = p->next) {
1913 view_object = GL_VIEW_OBJECT (p->data);
1914 object = gl_view_object_get_object (view_object);
1915 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1916 if ( y1 < y1min ) y1min = y1;
1919 /* now adjust the object positions to line up the top edges */
1920 for (p = view->selected_object_list; p != NULL; p = p->next) {
1921 view_object = GL_VIEW_OBJECT (p->data);
1922 object = gl_view_object_get_object (view_object);
1923 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1925 gl_label_object_set_position_relative (object, 0.0, dy);
1928 gl_debug (DEBUG_VIEW, "END");
1931 /*****************************************************************************/
1932 /* Align selected objects to bottom most edge. */
1933 /*****************************************************************************/
1935 gl_view_align_selection_bottom (glView *view)
1938 glViewObject *view_object;
1939 glLabelObject *object;
1940 gdouble dy, y2max, x1, y1, x2, y2;
1942 gl_debug (DEBUG_VIEW, "START");
1944 g_return_if_fail (GL_IS_VIEW (view));
1946 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1947 !gl_view_is_selection_atomic (view));
1949 /* find bottom most edge */
1950 p = view->selected_object_list;
1951 view_object = GL_VIEW_OBJECT (p->data);
1952 object = gl_view_object_get_object (view_object);
1953 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2max);
1954 for (p = p->next; p != NULL; p = p->next) {
1955 view_object = GL_VIEW_OBJECT (p->data);
1956 object = gl_view_object_get_object (view_object);
1957 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1958 if ( y2 > y2max ) y2max = y2;
1961 /* now adjust the object positions to line up the bottom edges */
1962 for (p = view->selected_object_list; p != NULL; p = p->next) {
1963 view_object = GL_VIEW_OBJECT (p->data);
1964 object = gl_view_object_get_object (view_object);
1965 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1967 gl_label_object_set_position_relative (object, 0.0, dy);
1970 gl_debug (DEBUG_VIEW, "END");
1973 /*****************************************************************************/
1974 /* Align selected objects to viertical center of objects. */
1975 /*****************************************************************************/
1977 gl_view_align_selection_vcenter (glView *view)
1980 glViewObject *view_object;
1981 glLabelObject *object;
1982 gdouble dy, dymin, ysum, yavg, ycenter, x1, y1, x2, y2;
1985 gl_debug (DEBUG_VIEW, "START");
1987 g_return_if_fail (GL_IS_VIEW (view));
1989 g_return_if_fail (!gl_view_is_selection_empty (view) &&
1990 !gl_view_is_selection_atomic (view));
1992 /* find average center of objects */
1995 for (p = view->selected_object_list; p != NULL; p = p->next) {
1996 view_object = GL_VIEW_OBJECT (p->data);
1997 object = gl_view_object_get_object (view_object);
1998 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
1999 ysum += (y1 + y2) / 2.0;
2004 /* find center of object closest to average center */
2005 p = view->selected_object_list;
2006 view_object = GL_VIEW_OBJECT (p->data);
2007 object = gl_view_object_get_object (view_object);
2008 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2009 dymin = fabs (yavg - (y1 + y2)/2.0);
2010 ycenter = (y1 + y2)/2.0;
2011 for (p = p->next; 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_get_extent (object, &x1, &y1, &x2, &y2);
2015 dy = fabs (yavg - (y1 + y2)/2.0);
2018 ycenter = (y1 + y2)/2.0;
2022 /* now adjust the object positions to line up this center */
2023 for (p = view->selected_object_list; p != NULL; p = p->next) {
2024 view_object = GL_VIEW_OBJECT (p->data);
2025 object = gl_view_object_get_object (view_object);
2026 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2027 dy = ycenter - (y1 + y2)/2.0;
2028 gl_label_object_set_position_relative (object, 0.0, dy);
2031 gl_debug (DEBUG_VIEW, "END");
2034 /*****************************************************************************/
2035 /* "Cut" selected items and place in clipboard selections. */
2036 /*****************************************************************************/
2038 gl_view_cut (glView *view)
2040 gl_debug (DEBUG_VIEW, "START");
2042 g_return_if_fail (GL_IS_VIEW (view));
2044 gl_view_copy (view);
2045 gl_view_delete_selection (view);
2047 gl_debug (DEBUG_VIEW, "END");
2050 /*****************************************************************************/
2051 /* "Copy" selected items to clipboard selections. */
2052 /*****************************************************************************/
2054 gl_view_copy (glView *view)
2057 glViewObject *view_object;
2058 glLabelObject *object;
2059 glTemplate *template;
2060 gboolean rotate_flag;
2062 gl_debug (DEBUG_VIEW, "START");
2064 g_return_if_fail (GL_IS_VIEW (view));
2066 if (view->selected_object_list) {
2068 if ( view->selection_data ) {
2069 g_object_unref (view->selection_data);
2071 template = gl_label_get_template (view->label);
2072 rotate_flag = gl_label_get_rotate_flag (view->label);
2073 view->selection_data = GL_LABEL(gl_label_new ());
2074 gl_label_set_template (view->selection_data, template);
2075 gl_label_set_rotate_flag (view->selection_data, rotate_flag);
2076 gl_template_free (&template);
2078 for (p = view->selected_object_list; p != NULL; p = p->next) {
2080 view_object = GL_VIEW_OBJECT (p->data);
2081 object = gl_view_object_get_object (view_object);
2083 gl_label_object_dup (object, view->selection_data);
2087 gtk_selection_owner_set (view->invisible,
2088 clipboard_atom, GDK_CURRENT_TIME);
2089 view->have_selection = TRUE;
2093 gl_debug (DEBUG_VIEW, "END");
2096 /*****************************************************************************/
2097 /* "Paste" from private clipboard selection. */
2098 /*****************************************************************************/
2100 gl_view_paste (glView *view)
2102 gl_debug (DEBUG_VIEW, "START");
2104 g_return_if_fail (GL_IS_VIEW (view));
2106 gtk_selection_convert (GTK_WIDGET (view->invisible),
2107 clipboard_atom, GDK_SELECTION_TYPE_STRING,
2110 gl_debug (DEBUG_VIEW, "END");
2113 /*---------------------------------------------------------------------------*/
2114 /* PRIVATE. move selected objects */
2115 /*---------------------------------------------------------------------------*/
2117 move_selection (glView *view,
2122 glLabelObject *object;
2124 gl_debug (DEBUG_VIEW, "START");
2126 g_return_if_fail (GL_IS_VIEW (view));
2128 for (p = view->selected_object_list; p != NULL; p = p->next) {
2130 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2131 gl_label_object_set_position_relative (object, dx, dy);
2135 gl_debug (DEBUG_VIEW, "END");
2138 /*****************************************************************************/
2139 /* Zoom in one "notch" */
2140 /*****************************************************************************/
2142 gl_view_zoom_in (glView *view)
2145 gdouble dist, dist_min;
2147 gl_debug (DEBUG_VIEW, "START");
2149 g_return_if_fail (GL_IS_VIEW (view));
2151 /* Find index of current scale (or best match) */
2152 i_min = 1; /* start with 2nd largest scale */
2153 dist_min = fabs (scales[1] - view->scale);
2154 for (i = 2; i < N_SCALES; i++) {
2155 dist = fabs (scales[i] - view->scale);
2156 if (dist < dist_min) {
2162 /* zoom in one "notch" */
2163 i = MAX (0, i_min - 1);
2164 gl_view_set_zoom (view, scales[i] / HOME_SCALE);
2166 gl_debug (DEBUG_VIEW, "END");
2169 /*****************************************************************************/
2170 /* Zoom out one "notch" */
2171 /*****************************************************************************/
2173 gl_view_zoom_out (glView *view)
2176 gdouble dist, dist_min;
2178 gl_debug (DEBUG_VIEW, "START");
2180 g_return_if_fail (GL_IS_VIEW (view));
2182 /* Find index of current scale (or best match) */
2183 i_min = 0; /* start with largest scale */
2184 dist_min = fabs (scales[0] - view->scale);
2185 for (i = 1; i < N_SCALES; i++) {
2186 dist = fabs (scales[i] - view->scale);
2187 if (dist < dist_min) {
2193 /* zoom out one "notch" */
2194 if (i_min >= N_SCALES)
2199 gl_view_set_zoom (view, scales[i] / HOME_SCALE);
2201 gl_debug (DEBUG_VIEW, "END");
2204 /*****************************************************************************/
2205 /* Set current zoom factor to explicit value. */
2206 /*****************************************************************************/
2208 gl_view_set_zoom (glView *view,
2211 gl_debug (DEBUG_VIEW, "START");
2213 g_return_if_fail (GL_IS_VIEW (view));
2214 g_return_if_fail (scale > 0.0);
2216 view->scale = scale * HOME_SCALE;
2217 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
2218 scale * HOME_SCALE);
2220 g_signal_emit (G_OBJECT(view), signals[ZOOM_CHANGED], 0, scale);
2222 gl_debug (DEBUG_VIEW, "END");
2225 /*****************************************************************************/
2226 /* Get current zoom factor. */
2227 /*****************************************************************************/
2229 gl_view_get_zoom (glView *view)
2231 gl_debug (DEBUG_VIEW, "");
2233 g_return_val_if_fail (GL_IS_VIEW (view), 1.0);
2235 return view->scale / HOME_SCALE;
2238 /*****************************************************************************/
2239 /* Is this the maximum zoom level. */
2240 /*****************************************************************************/
2242 gl_view_is_zoom_max (glView *view)
2244 gl_debug (DEBUG_VIEW, "");
2246 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
2248 return view->scale >= scales[0];
2251 /*****************************************************************************/
2252 /* Is this the minimum zoom level. */
2253 /*****************************************************************************/
2255 gl_view_is_zoom_min (glView *view)
2257 gl_debug (DEBUG_VIEW, "");
2259 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
2261 return view->scale <= scales[N_SCALES-1];
2264 /*---------------------------------------------------------------------------*/
2265 /* PRIVATE. Canvas event handler. */
2266 /*---------------------------------------------------------------------------*/
2268 canvas_event (GnomeCanvas *canvas,
2274 gl_debug (DEBUG_VIEW, "");
2276 /* emit pointer signals regardless of state */
2277 switch (event->type) {
2278 case GDK_MOTION_NOTIFY:
2279 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
2280 gnome_canvas_window_to_world (canvas,
2282 event->motion.y, &x, &y);
2283 g_signal_emit (G_OBJECT(view), signals[POINTER_MOVED], 0, x, y);
2284 break; /* fall through */
2286 case GDK_LEAVE_NOTIFY:
2287 gl_debug (DEBUG_VIEW, "LEAVEW_NOTIFY");
2288 g_signal_emit (G_OBJECT(view), signals[POINTER_EXIT], 0);
2289 break; /* fall through */
2292 break; /* fall through */
2296 switch (view->state) {
2298 case GL_VIEW_STATE_ARROW:
2299 return canvas_event_arrow_mode (canvas, event, view);
2301 case GL_VIEW_STATE_OBJECT_CREATE:
2302 switch (view->create_type) {
2303 case GL_LABEL_OBJECT_BOX:
2304 return gl_view_box_create_event_handler (canvas,
2308 case GL_LABEL_OBJECT_ELLIPSE:
2309 return gl_view_ellipse_create_event_handler (canvas,
2313 case GL_LABEL_OBJECT_LINE:
2314 return gl_view_line_create_event_handler (canvas,
2318 case GL_LABEL_OBJECT_IMAGE:
2319 return gl_view_image_create_event_handler (canvas,
2323 case GL_LABEL_OBJECT_TEXT:
2324 return gl_view_text_create_event_handler (canvas,
2328 case GL_LABEL_OBJECT_BARCODE:
2329 return gl_view_barcode_create_event_handler (canvas,
2334 /*Should not happen!*/
2335 g_warning ("Invalid label object type.");
2340 g_warning ("Invalid view state."); /*Should not happen!*/
2346 /*---------------------------------------------------------------------------*/
2347 /* PRIVATE. Canvas event handler (arrow mode) */
2348 /*---------------------------------------------------------------------------*/
2350 canvas_event_arrow_mode (GnomeCanvas *canvas,
2354 static gdouble x0, y0;
2355 static gboolean dragging = FALSE;
2356 static GnomeCanvasItem *item;
2357 gdouble x, y, x1, y1, x2, y2;
2358 GnomeCanvasGroup *group;
2361 gl_debug (DEBUG_VIEW, "");
2363 switch (event->type) {
2365 case GDK_BUTTON_PRESS:
2366 gl_debug (DEBUG_VIEW, "BUTTON_PRESS");
2367 switch (event->button.button) {
2369 gnome_canvas_window_to_world (canvas,
2371 event->button.y, &x, &y);
2373 if (!object_at (view, x, y)) {
2374 if (!(event->button.state & GDK_CONTROL_MASK)) {
2375 gl_view_unselect_all (view);
2379 gnome_canvas_item_grab (canvas->root,
2380 GDK_POINTER_MOTION_MASK |
2381 GDK_BUTTON_RELEASE_MASK |
2382 GDK_BUTTON_PRESS_MASK,
2383 NULL, event->button.time);
2385 gnome_canvas_root (GNOME_CANVAS
2388 gnome_canvas_item_new (group,
2389 gnome_canvas_rect_get_type (),
2393 "outline_color_rgba",
2408 case GDK_BUTTON_RELEASE:
2409 gl_debug (DEBUG_VIEW, "BUTTON_RELEASE");
2410 switch (event->button.button) {
2414 gnome_canvas_item_ungrab (canvas->root,
2415 event->button.time);
2416 gnome_canvas_window_to_world (canvas,
2424 gl_view_select_region (view, x1, y1, x2, y2);
2425 gtk_object_destroy (GTK_OBJECT (item));
2434 case GDK_MOTION_NOTIFY:
2435 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
2436 gnome_canvas_window_to_world (canvas,
2438 event->motion.y, &x, &y);
2439 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
2440 gnome_canvas_item_set (item,
2444 "y2", MAX (y, y0), NULL);
2451 gl_debug (DEBUG_VIEW, "KEY_PRESS");
2453 switch (event->key.keyval) {
2456 move_selection (view,
2457 -1.0 / (view->scale), 0.0);
2461 move_selection (view,
2462 0.0, -1.0 / (view->scale));
2466 move_selection (view,
2467 1.0 / (view->scale), 0.0);
2471 move_selection (view,
2472 0.0, 1.0 / (view->scale));
2476 gl_view_delete_selection (view);
2477 cursor = gdk_cursor_new (GDK_LEFT_PTR);
2478 gdk_window_set_cursor (view->canvas->window,
2480 gdk_cursor_unref (cursor);
2486 return TRUE; /* We handled this or we were dragging. */
2489 gl_debug (DEBUG_VIEW, "default");
2495 /*****************************************************************************/
2496 /* Item event handler. */
2497 /*****************************************************************************/
2499 gl_view_item_event_handler (GnomeCanvasItem *item,
2501 glViewObject *view_object)
2505 gl_debug (DEBUG_VIEW, "");
2507 view = gl_view_object_get_view(view_object);
2508 switch (view->state) {
2510 case GL_VIEW_STATE_ARROW:
2511 return item_event_arrow_mode (item, event, view_object);
2520 /*---------------------------------------------------------------------------*/
2521 /* PRIVATE. Item event handler (arrow mode) */
2522 /*---------------------------------------------------------------------------*/
2524 item_event_arrow_mode (GnomeCanvasItem *item,
2526 glViewObject *view_object)
2528 static gdouble x, y;
2529 static gboolean dragging = FALSE;
2532 gdouble item_x, item_y;
2533 gdouble new_x, new_y;
2534 gboolean control_key_pressed;
2536 gl_debug (DEBUG_VIEW, "");
2538 item_x = event->button.x;
2539 item_y = event->button.y;
2540 gnome_canvas_item_w2i (item->parent, &item_x, &item_y);
2542 view = gl_view_object_get_view(view_object);
2544 switch (event->type) {
2546 case GDK_BUTTON_PRESS:
2547 gl_debug (DEBUG_VIEW, "BUTTON_PRESS");
2548 control_key_pressed = event->button.state & GDK_CONTROL_MASK;
2549 switch (event->button.button) {
2551 if (control_key_pressed) {
2552 if (is_object_selected (view, view_object)) {
2553 /* Un-selecting a selected item */
2554 gl_view_unselect_object (view,
2558 /* Add to current selection */
2559 gl_view_select_object (view,
2563 if (!is_object_selected (view, view_object)) {
2564 /* No control, key so remove any selections before adding */
2565 gl_view_unselect_all (view);
2566 /* Add to current selection */
2567 gl_view_select_object (view,
2571 /* Go into dragging mode while button remains pressed. */
2574 cursor = gdk_cursor_new (GDK_FLEUR);
2575 gnome_canvas_item_grab (item,
2576 GDK_POINTER_MOTION_MASK |
2577 GDK_BUTTON_RELEASE_MASK |
2578 GDK_BUTTON_PRESS_MASK,
2579 cursor, event->button.time);
2580 gdk_cursor_unref (cursor);
2585 if (!is_object_selected (view, view_object)) {
2586 if (!control_key_pressed) {
2587 /* No control, key so remove any selections before adding */
2588 gl_view_unselect_all (view);
2591 /* Add to current selection */
2592 gl_view_select_object (view, view_object);
2593 /* bring up apropriate menu for selection. */
2594 popup_selection_menu (view, view_object, event);
2601 case GDK_BUTTON_RELEASE:
2602 gl_debug (DEBUG_VIEW, "BUTTON_RELEASE");
2603 switch (event->button.button) {
2605 /* Exit dragging mode */
2606 gnome_canvas_item_ungrab (item, event->button.time);
2614 case GDK_MOTION_NOTIFY:
2615 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
2616 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
2617 /* Dragging mode, move selection */
2620 move_selection (view, (new_x - x), (new_y - y));
2628 case GDK_2BUTTON_PRESS:
2629 gl_debug (DEBUG_VIEW, "2BUTTON_PRESS");
2630 switch (event->button.button) {
2632 /* Also exit dragging mode w/ double-click, run dlg */
2633 gnome_canvas_item_ungrab (item, event->button.time);
2635 gl_view_select_object (view, view_object);
2636 gl_view_object_show_dialog (view_object);
2643 case GDK_ENTER_NOTIFY:
2644 gl_debug (DEBUG_VIEW, "ENTER_NOTIFY");
2645 cursor = gdk_cursor_new (GDK_FLEUR);
2646 gdk_window_set_cursor (view->canvas->window, cursor);
2647 gdk_cursor_unref (cursor);
2650 case GDK_LEAVE_NOTIFY:
2651 gl_debug (DEBUG_VIEW, "LEAVE_NOTIFY");
2652 cursor = gdk_cursor_new (GDK_LEFT_PTR);
2653 gdk_window_set_cursor (view->canvas->window, cursor);
2654 gdk_cursor_unref (cursor);
2658 gl_debug (DEBUG_VIEW, "default");
2664 /*---------------------------------------------------------------------------*/
2665 /* PRIVATE. create menu for multiple selections. */
2666 /*---------------------------------------------------------------------------*/
2668 new_selection_menu (glView *view)
2670 GtkWidget *menu, *menuitem;
2672 gl_debug (DEBUG_VIEW, "START");
2674 g_return_val_if_fail (GL_IS_VIEW (view), NULL);
2676 menu = gtk_menu_new ();
2678 menuitem = gtk_menu_item_new_with_label (_("Delete"));
2679 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2680 gtk_widget_show (menuitem);
2681 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2682 G_CALLBACK (gl_view_delete_selection), view);
2684 menuitem = gtk_menu_item_new ();
2685 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2686 gtk_widget_show (menuitem);
2688 menuitem = gtk_menu_item_new_with_label (_("Bring to front"));
2689 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2690 gtk_widget_show (menuitem);
2691 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2692 G_CALLBACK (gl_view_raise_selection), view);
2694 menuitem = gtk_menu_item_new_with_label (_("Send to back"));
2695 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2696 gtk_widget_show (menuitem);
2697 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2698 G_CALLBACK (gl_view_lower_selection), view);
2700 gl_debug (DEBUG_VIEW, "END");
2705 /*---------------------------------------------------------------------------*/
2706 /* PRIVATE. popup menu for given item. */
2707 /*---------------------------------------------------------------------------*/
2709 popup_selection_menu (glView *view,
2710 glViewObject *view_object,
2715 gl_debug (DEBUG_VIEW, "START");
2717 g_return_if_fail (GL_IS_VIEW (view));
2718 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
2720 if (gl_view_is_selection_atomic (view)) {
2722 menu = gl_view_object_get_menu (view_object);
2724 gtk_menu_popup (GTK_MENU (menu),
2725 NULL, NULL, NULL, NULL,
2726 event->button.button,
2727 event->button.time);
2732 if (view->menu != NULL) {
2733 gtk_menu_popup (GTK_MENU (view->menu),
2734 NULL, NULL, NULL, NULL,
2735 event->button.button,
2736 event->button.time);
2741 gl_debug (DEBUG_VIEW, "END");
2744 /*---------------------------------------------------------------------------*/
2745 /* PRIVATE. Handle "selection-clear" signal. */
2746 /*---------------------------------------------------------------------------*/
2748 selection_clear_cb (GtkWidget *widget,
2749 GdkEventSelection *event,
2752 glView *view = GL_VIEW (data);
2754 gl_debug (DEBUG_VIEW, "START");
2756 g_return_if_fail (GL_IS_VIEW (view));
2758 view->have_selection = FALSE;
2759 g_object_unref (view->selection_data);
2760 view->selection_data = NULL;
2762 gl_debug (DEBUG_VIEW, "END");
2765 /*---------------------------------------------------------------------------*/
2766 /* PRIVATE. Handle "selection-get" signal. */
2767 /*---------------------------------------------------------------------------*/
2769 selection_get_cb (GtkWidget *widget,
2770 GtkSelectionData *selection_data,
2775 glView *view = GL_VIEW (data);
2777 glXMLLabelStatus status;
2779 gl_debug (DEBUG_VIEW, "START");
2781 g_return_if_fail (GL_IS_VIEW (view));
2783 if (view->have_selection) {
2785 buffer = gl_xml_label_save_buffer (view->selection_data,
2787 gtk_selection_data_set (selection_data,
2788 GDK_SELECTION_TYPE_STRING, 8, buffer,
2793 gl_debug (DEBUG_VIEW, "END");
2796 /*---------------------------------------------------------------------------*/
2797 /* PRIVATE. Handle "selection-received" signal. (Result of Paste) */
2798 /*---------------------------------------------------------------------------*/
2800 selection_received_cb (GtkWidget *widget,
2801 GtkSelectionData *selection_data,
2805 glView *view = GL_VIEW (data);
2806 glLabel *label = NULL;
2807 glXMLLabelStatus status;
2809 glLabelObject *object, *newobject;
2810 glViewObject *view_object;
2812 gl_debug (DEBUG_VIEW, "START");
2814 g_return_if_fail (GL_IS_VIEW (view));
2816 if (selection_data->length < 0) {
2819 if (selection_data->type != GDK_SELECTION_TYPE_STRING) {
2823 gl_view_unselect_all (view);
2825 label = gl_xml_label_open_buffer (selection_data->data, &status);
2826 for (p = label->objects; p != NULL; p = p_next) {
2829 object = (glLabelObject *) p->data;
2830 gl_label_object_set_parent (object, view->label);
2832 gl_debug (DEBUG_VIEW, "object pasted");
2834 if (GL_IS_LABEL_BOX (object)) {
2835 view_object = gl_view_box_new (GL_LABEL_BOX(object),
2837 } else if (GL_IS_LABEL_ELLIPSE (object)) {
2838 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object),
2840 } else if (GL_IS_LABEL_LINE (object)) {
2841 view_object = gl_view_line_new (GL_LABEL_LINE(object),
2843 } else if (GL_IS_LABEL_IMAGE (object)) {
2844 view_object = gl_view_image_new (GL_LABEL_IMAGE(object),
2846 } else if (GL_IS_LABEL_TEXT (object)) {
2847 view_object = gl_view_text_new (GL_LABEL_TEXT(object),
2849 } else if (GL_IS_LABEL_BARCODE (object)) {
2850 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(object),
2853 /* Should not happen! */
2855 g_warning ("Invalid label object type.");
2857 gl_view_select_object (view, view_object);
2859 g_object_unref (label);
2861 gl_debug (DEBUG_VIEW, "END");