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"
42 #include "merge-properties-dialog.h"
47 /*==========================================================================*/
48 /* Private macros and constants. */
49 /*==========================================================================*/
51 #define BG_COLOR GL_COLOR (192, 192, 192)
52 #define OUTLINE_COLOR GL_COLOR (173, 216, 230)
53 #define PAPER_COLOR GL_COLOR (255, 255, 255)
54 #define GRID_COLOR BG_COLOR
55 #define MARKUP_COLOR GL_COLOR (240, 100, 100)
57 #define SEL_LINE_COLOR GL_COLOR_A (0, 0, 255, 128)
58 #define SEL_FILL_COLOR GL_COLOR_A (192, 192, 255, 128)
60 #define ARC_FINE 2 /* Resolution in degrees of large arcs */
61 #define ARC_COURSE 5 /* Resolution in degrees of small arcs */
63 /*==========================================================================*/
65 /*==========================================================================*/
77 /*==========================================================================*/
79 /*==========================================================================*/
81 static GtkContainerClass *parent_class;
83 static guint signals[LAST_SIGNAL] = {0};
85 /* "CLIPBOARD" selection */
86 static GdkAtom clipboard_atom = GDK_NONE;
88 static gdouble scales[] = {
93 #define N_SCALES G_N_ELEMENTS(scales)
94 #define HOME_SCALE 2.0
96 /*==========================================================================*/
97 /* Local function prototypes */
98 /*==========================================================================*/
100 static void gl_view_class_init (glViewClass *class);
101 static void gl_view_init (glView *view);
102 static void gl_view_finalize (GObject *object);
104 static void gl_view_construct (glView *view);
105 static GtkWidget *gl_view_construct_canvas (glView *view);
106 static void gl_view_construct_selection (glView *view);
108 static gdouble get_apropriate_scale (gdouble w, gdouble h);
110 static void draw_layers (glView *view);
112 static void draw_label_layer (glView *view);
114 static void draw_highlight_layer (glView *view);
116 static void draw_bg_fg_layers (glView *view);
117 static void draw_bg_fg_rect (glView *view);
118 static void draw_bg_fg_rounded_rect (glView *view);
119 static void draw_bg_fg_round (glView *view);
120 static void draw_bg_fg_cd (glView *view);
121 static void draw_bg_fg_cd_bc (glView *view);
123 static void draw_grid_layer (glView *view);
125 static void draw_markup_layer (glView *view);
127 static void draw_markup_margin (glView *view,
128 glTemplateMarkupMargin *margin);
129 static void draw_markup_margin_rect (glView *view,
130 glTemplateMarkupMargin *margin);
131 static void draw_markup_margin_rounded_rect (glView *view,
132 glTemplateMarkupMargin *margin);
133 static void draw_markup_margin_round (glView *view,
134 glTemplateMarkupMargin *margin);
135 static void draw_markup_margin_cd (glView *view,
136 glTemplateMarkupMargin *margin);
137 static void draw_markup_margin_cd_bc (glView *view,
138 glTemplateMarkupMargin *margin);
140 static void draw_markup_line (glView *view,
141 glTemplateMarkupLine *line);
144 static void select_object_real (glView *view,
145 glViewObject *view_object);
146 static void unselect_object_real (glView *view,
147 glViewObject *view_object);
149 static gboolean object_at (glView *view,
150 gdouble x, gdouble y);
152 static gboolean is_item_member_of_group (glView *view,
153 GnomeCanvasItem *item,
154 GnomeCanvasItem *group);
156 static int canvas_event (GnomeCanvas *canvas,
159 static int canvas_event_arrow_mode (GnomeCanvas *canvas,
163 static void construct_selection_menu (glView *view);
165 static void construct_empty_selection_menu (glView *view);
167 static void selection_clear_cb (GtkWidget *widget,
168 GdkEventSelection *event,
171 static void selection_get_cb (GtkWidget *widget,
172 GtkSelectionData *selection_data,
177 static void selection_received_cb (GtkWidget *widget,
178 GtkSelectionData *selection_data,
182 /****************************************************************************/
183 /* Boilerplate Object stuff. */
184 /****************************************************************************/
186 gl_view_get_type (void)
188 static guint view_type = 0;
191 GTypeInfo view_info = {
192 sizeof (glViewClass),
195 (GClassInitFunc) gl_view_class_init,
200 (GInstanceInitFunc) gl_view_init,
204 g_type_register_static (gtk_vbox_get_type (),
205 "glView", &view_info, 0);
212 gl_view_class_init (glViewClass *class)
214 GObjectClass *object_class = (GObjectClass *) class;
216 gl_debug (DEBUG_VIEW, "START");
218 parent_class = g_type_class_peek_parent (class);
220 object_class->finalize = gl_view_finalize;
222 signals[SELECTION_CHANGED] =
223 g_signal_new ("selection_changed",
224 G_OBJECT_CLASS_TYPE (object_class),
226 G_STRUCT_OFFSET (glViewClass, selection_changed),
228 gl_marshal_VOID__VOID,
232 signals[ZOOM_CHANGED] =
233 g_signal_new ("zoom_changed",
234 G_OBJECT_CLASS_TYPE (object_class),
236 G_STRUCT_OFFSET (glViewClass, zoom_changed),
238 gl_marshal_VOID__DOUBLE,
242 signals[POINTER_MOVED] =
243 g_signal_new ("pointer_moved",
244 G_OBJECT_CLASS_TYPE (object_class),
246 G_STRUCT_OFFSET (glViewClass, pointer_moved),
248 gl_marshal_VOID__DOUBLE_DOUBLE,
250 2, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
252 signals[POINTER_EXIT] =
253 g_signal_new ("pointer_exit",
254 G_OBJECT_CLASS_TYPE (object_class),
256 G_STRUCT_OFFSET (glViewClass, pointer_exit),
258 gl_marshal_VOID__VOID,
262 signals[MODE_CHANGED] =
263 g_signal_new ("mode_changed",
264 G_OBJECT_CLASS_TYPE (object_class),
266 G_STRUCT_OFFSET (glViewClass, mode_changed),
268 gl_marshal_VOID__VOID,
272 gl_debug (DEBUG_VIEW, "END");
276 gl_view_init (glView *view)
278 gl_debug (DEBUG_VIEW, "START");
282 view->grid_spacing = 9;
284 gl_debug (DEBUG_VIEW, "END");
288 gl_view_finalize (GObject *object)
292 gl_debug (DEBUG_VIEW, "START");
294 g_return_if_fail (object != NULL);
295 g_return_if_fail (GL_IS_VIEW (object));
297 view = GL_VIEW (object);
299 G_OBJECT_CLASS (parent_class)->finalize (object);
301 gl_debug (DEBUG_VIEW, "END");
304 /****************************************************************************/
305 /* NEW view object. */
306 /****************************************************************************/
308 gl_view_new (glLabel *label)
310 glView *view = g_object_new (gl_view_get_type (), NULL);
312 gl_debug (DEBUG_VIEW, "START");
316 gl_view_construct (view);
318 gl_debug (DEBUG_VIEW, "END");
320 return GTK_WIDGET (view);
323 /*---------------------------------------------------------------------------*/
324 /* PRIVATE. Construct composite widget. */
325 /*---------------------------------------------------------------------------*/
327 gl_view_construct (glView *view)
329 GtkWidget *wvbox, *wscroll;
331 gl_debug (DEBUG_VIEW, "START");
333 g_return_if_fail (GL_IS_VIEW (view));
335 wvbox = GTK_WIDGET (view);
337 view->state = GL_VIEW_STATE_ARROW;
338 view->object_list = NULL;
340 gl_view_construct_canvas (view);
341 wscroll = gtk_scrolled_window_new (NULL, NULL);
342 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (wscroll),
343 GTK_POLICY_AUTOMATIC,
344 GTK_POLICY_AUTOMATIC);
345 gtk_box_pack_start (GTK_BOX (wvbox), wscroll, TRUE, TRUE, 0);
346 gtk_container_add (GTK_CONTAINER (wscroll), view->canvas);
348 gl_view_construct_selection (view);
350 construct_selection_menu (view);
351 construct_empty_selection_menu (view);
353 gl_debug (DEBUG_VIEW, "END");
356 /*---------------------------------------------------------------------------*/
357 /* PRIVATE. Create canvas w/ a background in the shape of the label/card. */
358 /*---------------------------------------------------------------------------*/
360 gl_view_construct_canvas (glView *view)
363 glLabel *label = view->label;
364 gdouble label_width, label_height;
367 gl_debug (DEBUG_VIEW, "START");
369 g_return_val_if_fail (GL_IS_VIEW (view), NULL);
370 g_return_val_if_fail (label != NULL, NULL);
372 gtk_widget_push_colormap (gdk_rgb_get_colormap ());
373 view->canvas = gnome_canvas_new_aa ();
374 gtk_widget_pop_colormap ();
376 bg_color = gl_color_to_gdk_color (BG_COLOR);
377 gtk_widget_modify_bg (GTK_WIDGET(view->canvas), GTK_STATE_NORMAL, bg_color);
380 gl_label_get_size (label, &label_width, &label_height);
381 gl_debug (DEBUG_VIEW, "Label size: w=%lf, h=%lf",
382 label_width, label_height);
384 scale = get_apropriate_scale (label_width, label_height);
385 gl_debug (DEBUG_VIEW, "scale =%lf", scale);
387 gl_debug (DEBUG_VIEW, "Canvas size: w=%lf, h=%lf",
388 scale * label_width + 40,
389 scale * label_height + 40);
390 gtk_widget_set_size_request (GTK_WIDGET(view->canvas),
391 scale * label_width + 40,
392 scale * label_height + 40);
393 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
397 gnome_canvas_set_scroll_region (GNOME_CANVAS (view->canvas),
398 0.0, 0.0, label_width, label_height);
402 g_signal_connect (G_OBJECT (view->canvas), "event",
403 G_CALLBACK (canvas_event), view);
405 gl_debug (DEBUG_VIEW, "END");
410 /*---------------------------------------------------------------------------*/
411 /* PRIVATE. Create clipboard selection targets. */
412 /*---------------------------------------------------------------------------*/
414 gl_view_construct_selection (glView *view)
416 gl_debug (DEBUG_VIEW, "START");
418 g_return_if_fail (GL_IS_VIEW (view));
420 view->have_selection = FALSE;
421 view->selection_data = NULL;
422 view->invisible = gtk_invisible_new ();
424 view->selected_object_list = NULL;
426 if (!clipboard_atom) {
427 clipboard_atom = gdk_atom_intern ("GLABELS_CLIPBOARD", FALSE);
430 gtk_selection_add_target (view->invisible,
431 clipboard_atom, GDK_SELECTION_TYPE_STRING, 1);
433 g_signal_connect (G_OBJECT (view->invisible),
434 "selection_clear_event",
435 G_CALLBACK (selection_clear_cb), view);
437 g_signal_connect (G_OBJECT (view->invisible), "selection_get",
438 G_CALLBACK (selection_get_cb), view);
440 g_signal_connect (G_OBJECT (view->invisible),
441 "selection_received",
442 G_CALLBACK (selection_received_cb), view);
444 gl_debug (DEBUG_VIEW, "END");
447 /*---------------------------------------------------------------------------*/
448 /* PRIVATE. Determine an apropriate scale for given label & screen size */
449 /*---------------------------------------------------------------------------*/
451 get_apropriate_scale (gdouble w, gdouble h)
453 gdouble w_screen, h_screen;
457 gl_debug (DEBUG_VIEW, "");
459 w_screen = (gdouble) gdk_screen_width ();
460 h_screen = (gdouble) gdk_screen_height ();
462 for (i = 0; i < N_SCALES; i++) {
464 if (k <= HOME_SCALE) {
465 if ((k * w < (w_screen - 256))
466 && (k * h < (h_screen - 256)))
474 /*---------------------------------------------------------------------------*/
475 /* PRIVATE. Create, draw and order layers. */
476 /*---------------------------------------------------------------------------*/
478 draw_layers (glView *view)
480 draw_bg_fg_layers (view);
481 draw_grid_layer (view);
482 draw_markup_layer (view);
483 draw_highlight_layer (view); /* Must be done before label layer */
484 draw_label_layer (view);
486 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->fg_group));
487 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(view->highlight_group));
490 /*---------------------------------------------------------------------------*/
491 /* PRIVATE. Draw label layer. */
492 /*---------------------------------------------------------------------------*/
494 draw_label_layer (glView *view)
496 GnomeCanvasGroup *group;
499 glLabelObject *object;
500 glViewObject *view_object;
502 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
503 view->label_group = GNOME_CANVAS_GROUP(
504 gnome_canvas_item_new (group,
505 gnome_canvas_group_get_type (),
512 for (p_obj = label->objects; p_obj != NULL; p_obj = p_obj->next) {
513 object = (glLabelObject *) p_obj->data;
515 if (GL_IS_LABEL_BOX (object)) {
516 view_object = gl_view_box_new (GL_LABEL_BOX(object),
518 } else if (GL_IS_LABEL_ELLIPSE (object)) {
519 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object),
521 } else if (GL_IS_LABEL_LINE (object)) {
522 view_object = gl_view_line_new (GL_LABEL_LINE(object),
524 } else if (GL_IS_LABEL_IMAGE (object)) {
525 view_object = gl_view_image_new (GL_LABEL_IMAGE(object),
527 } else if (GL_IS_LABEL_TEXT (object)) {
528 view_object = gl_view_text_new (GL_LABEL_TEXT(object),
530 } else if (GL_IS_LABEL_BARCODE (object)) {
531 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(object),
534 /* Should not happen! */
536 g_warning ("Invalid label object type.");
541 /*---------------------------------------------------------------------------*/
542 /* PRIVATE. Create highlight layer. */
543 /*---------------------------------------------------------------------------*/
545 draw_highlight_layer (glView *view)
547 GnomeCanvasGroup *group;
549 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
550 view->highlight_group = GNOME_CANVAS_GROUP(
551 gnome_canvas_item_new (group,
552 gnome_canvas_group_get_type (),
558 /*---------------------------------------------------------------------------*/
559 /* PRIVATE. Draw background and foreground outlines. */
560 /*---------------------------------------------------------------------------*/
562 draw_bg_fg_layers (glView *view)
565 glTemplate *template;
566 GnomeCanvasGroup *group;
568 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
569 view->bg_group = GNOME_CANVAS_GROUP(
570 gnome_canvas_item_new (group,
571 gnome_canvas_group_get_type (),
575 view->fg_group = GNOME_CANVAS_GROUP(
576 gnome_canvas_item_new (group,
577 gnome_canvas_group_get_type (),
583 template = gl_label_get_template (label);
585 switch (template->label.style) {
587 case GL_TEMPLATE_STYLE_RECT:
588 if (template->label.rect.r == 0.0) {
589 /* Square corners. */
590 draw_bg_fg_rect (view);
592 /* Rounded corners. */
593 draw_bg_fg_rounded_rect (view);
597 case GL_TEMPLATE_STYLE_ROUND:
598 draw_bg_fg_round (view);
601 case GL_TEMPLATE_STYLE_CD:
602 if ((template->label.cd.w == 0.0) && (template->label.cd.h == 0.0) ) {
603 draw_bg_fg_cd (view);
605 draw_bg_fg_cd_bc (view);
610 g_warning ("Unknown template label style");
615 /*---------------------------------------------------------------------------*/
616 /* PRIVATE. Draw simple recangular background. */
617 /*---------------------------------------------------------------------------*/
619 draw_bg_fg_rect (glView *view)
621 glLabel *label = view->label;
622 glTemplate *template;
624 GnomeCanvasItem *item;
626 gl_debug (DEBUG_VIEW, "START");
628 g_return_if_fail (GL_IS_VIEW (view));
629 g_return_if_fail (label != NULL);
631 gl_label_get_size (label, &w, &h);
632 template = gl_label_get_template (label);
635 item = gnome_canvas_item_new (view->bg_group,
636 gnome_canvas_rect_get_type (),
641 "fill_color_rgba", PAPER_COLOR,
645 item = gnome_canvas_item_new (view->fg_group,
646 gnome_canvas_rect_get_type (),
652 "outline_color_rgba", OUTLINE_COLOR,
655 gl_debug (DEBUG_VIEW, "END");
658 /*---------------------------------------------------------------------------*/
659 /* PRIVATE. Draw rounded recangular background. */
660 /*---------------------------------------------------------------------------*/
662 draw_bg_fg_rounded_rect (glView *view)
664 glLabel *label = view->label;
665 GnomeCanvasPoints *points;
666 gint i_coords, i_theta;
667 glTemplate *template;
669 GnomeCanvasItem *item;
671 gl_debug (DEBUG_VIEW, "START");
673 g_return_if_fail (GL_IS_VIEW (view));
674 g_return_if_fail (label != NULL);
676 gl_label_get_size (label, &w, &h);
677 template = gl_label_get_template (label);
678 r = template->label.rect.r;
680 points = gnome_canvas_points_new (4 * (1 + 90 / ARC_COURSE));
682 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
683 points->coords[i_coords++] =
684 r - r * sin (i_theta * G_PI / 180.0);
685 points->coords[i_coords++] =
686 r - r * cos (i_theta * G_PI / 180.0);
688 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
689 points->coords[i_coords++] =
690 r - r * cos (i_theta * G_PI / 180.0);
691 points->coords[i_coords++] =
692 (h - r) + r * sin (i_theta * G_PI / 180.0);
694 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
695 points->coords[i_coords++] =
696 (w - r) + r * sin (i_theta * G_PI / 180.0);
697 points->coords[i_coords++] =
698 (h - r) + r * cos (i_theta * G_PI / 180.0);
700 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
701 points->coords[i_coords++] =
702 (w - r) + r * cos (i_theta * G_PI / 180.0);
703 points->coords[i_coords++] =
704 r - r * sin (i_theta * G_PI / 180.0);
708 item = gnome_canvas_item_new (view->bg_group,
709 gnome_canvas_polygon_get_type (),
711 "fill_color_rgba", PAPER_COLOR,
715 item = gnome_canvas_item_new (view->fg_group,
716 gnome_canvas_polygon_get_type (),
719 "outline_color_rgba", OUTLINE_COLOR,
722 gnome_canvas_points_free (points);
724 gl_debug (DEBUG_VIEW, "END");
727 /*---------------------------------------------------------------------------*/
728 /* PRIVATE. Draw round background. */
729 /*---------------------------------------------------------------------------*/
731 draw_bg_fg_round (glView *view)
733 glLabel *label = view->label;
734 glTemplate *template;
736 GnomeCanvasItem *item;
738 gl_debug (DEBUG_VIEW, "START");
740 g_return_if_fail (GL_IS_VIEW (view));
741 g_return_if_fail (label != NULL);
743 template = gl_label_get_template (label);
745 r = template->label.round.r;
748 item = gnome_canvas_item_new (view->bg_group,
749 gnome_canvas_ellipse_get_type (),
754 "fill_color_rgba", PAPER_COLOR,
758 item = gnome_canvas_item_new (view->fg_group,
759 gnome_canvas_ellipse_get_type (),
765 "outline_color_rgba", OUTLINE_COLOR,
768 gl_debug (DEBUG_VIEW, "END");
771 /*---------------------------------------------------------------------------*/
772 /* PRIVATE. Draw CD style background, circular w/ concentric hole. */
773 /*---------------------------------------------------------------------------*/
775 draw_bg_fg_cd (glView *view)
777 glLabel *label = view->label;
778 glTemplate *template;
780 GnomeCanvasItem *item;
782 gl_debug (DEBUG_VIEW, "START");
784 g_return_if_fail (GL_IS_VIEW (view));
785 g_return_if_fail (label != NULL);
787 template = gl_label_get_template (label);
789 r1 = template->label.cd.r1;
790 r2 = template->label.cd.r2;
794 item = gnome_canvas_item_new (view->bg_group,
795 gnome_canvas_ellipse_get_type (),
800 "fill_color_rgba", PAPER_COLOR,
803 item = gnome_canvas_item_new (view->bg_group,
804 gnome_canvas_ellipse_get_type (),
809 "fill_color_rgba", GRID_COLOR,
814 item = gnome_canvas_item_new (view->fg_group,
815 gnome_canvas_ellipse_get_type (),
821 "outline_color_rgba", OUTLINE_COLOR,
824 item = gnome_canvas_item_new (view->fg_group,
825 gnome_canvas_ellipse_get_type (),
831 "outline_color_rgba", OUTLINE_COLOR,
834 gl_debug (DEBUG_VIEW, "END");
837 /*---------------------------------------------------------------------------*/
838 /* PRIVATE. Draw Business Card CD style background, CD w/ chopped ends. */
839 /*---------------------------------------------------------------------------*/
841 draw_bg_fg_cd_bc (glView *view)
843 glLabel *label = view->label;
844 glTemplate *template;
845 GnomeCanvasPoints *points;
846 gint i_coords, i_theta;
847 gdouble theta1, theta2;
848 gdouble x0, y0, w, h, r1, r2;
849 GnomeCanvasItem *item;
851 gl_debug (DEBUG_VIEW, "START");
853 g_return_if_fail (GL_IS_VIEW (view));
854 g_return_if_fail (label != NULL);
856 template = gl_label_get_template (label);
857 gl_label_get_size (label, &w, &h);
861 r1 = template->label.cd.r1;
862 r2 = template->label.cd.r2;
864 theta1 = (180.0/G_PI) * acos (w / (2.0*r1));
865 theta2 = (180.0/G_PI) * asin (h / (2.0*r1));
867 points = gnome_canvas_points_new (360/ARC_FINE + 1);
870 points->coords[i_coords++] = x0 + r1 * cos (theta1 * G_PI / 180.0);
871 points->coords[i_coords++] = y0 + r1 * sin (theta1 * G_PI / 180.0);
873 for ( i_theta = theta1 + ARC_FINE; i_theta < theta2; i_theta +=ARC_FINE ) {
874 points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
875 points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
878 points->coords[i_coords++] = x0 + r1 * cos (theta2 * G_PI / 180.0);
879 points->coords[i_coords++] = y0 + r1 * sin (theta2 * G_PI / 180.0);
882 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
883 points->coords[i_coords++] = x0 + r1 * cos ((180-theta2) * G_PI / 180.0);
884 points->coords[i_coords++] = y0 + r1 * sin ((180-theta2) * G_PI / 180.0);
887 for ( i_theta = 180-theta2+ARC_FINE; i_theta < (180-theta1); i_theta +=ARC_FINE ) {
888 points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
889 points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
892 points->coords[i_coords++] = x0 + r1 * cos ((180-theta1) * G_PI / 180.0);
893 points->coords[i_coords++] = y0 + r1 * sin ((180-theta1) * G_PI / 180.0);
895 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
896 points->coords[i_coords++] = x0 + r1 * cos ((180+theta1) * G_PI / 180.0);
897 points->coords[i_coords++] = y0 + r1 * sin ((180+theta1) * G_PI / 180.0);
900 for ( i_theta = 180+theta1+ARC_FINE; i_theta < (180+theta2); i_theta +=ARC_FINE ) {
901 points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
902 points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
905 points->coords[i_coords++] = x0 + r1 * cos ((180+theta2) * G_PI / 180.0);
906 points->coords[i_coords++] = y0 + r1 * sin ((180+theta2) * G_PI / 180.0);
908 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
909 points->coords[i_coords++] = x0 + r1 * cos ((360-theta2) * G_PI / 180.0);
910 points->coords[i_coords++] = y0 + r1 * sin ((360-theta2) * G_PI / 180.0);
913 for ( i_theta = 360-theta2+ARC_FINE; i_theta < (360-theta1); i_theta +=ARC_FINE ) {
914 points->coords[i_coords++] = x0 + r1 * cos (i_theta * G_PI / 180.0);
915 points->coords[i_coords++] = y0 + r1 * sin (i_theta * G_PI / 180.0);
918 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
919 points->coords[i_coords++] = x0 + r1 * cos ((360-theta1) * G_PI / 180.0);
920 points->coords[i_coords++] = y0 + r1 * sin ((360-theta1) * G_PI / 180.0);
923 points->num_points = i_coords / 2;
927 item = gnome_canvas_item_new (view->bg_group,
928 gnome_canvas_polygon_get_type (),
930 "fill_color_rgba", PAPER_COLOR,
933 item = gnome_canvas_item_new (view->bg_group,
934 gnome_canvas_ellipse_get_type (),
939 "fill_color_rgba", GRID_COLOR,
944 item = gnome_canvas_item_new (view->fg_group,
945 gnome_canvas_polygon_get_type (),
948 "outline_color_rgba", OUTLINE_COLOR,
951 item = gnome_canvas_item_new (view->fg_group,
952 gnome_canvas_ellipse_get_type (),
958 "outline_color_rgba", OUTLINE_COLOR,
961 gnome_canvas_points_free (points);
963 gl_debug (DEBUG_VIEW, "END");
966 /*---------------------------------------------------------------------------*/
967 /* PRIVATE. Draw grid lines. */
968 /*---------------------------------------------------------------------------*/
970 draw_grid_layer (glView *view)
973 GnomeCanvasPoints *points;
974 GnomeCanvasItem *item;
975 GnomeCanvasGroup *group;
977 gl_debug (DEBUG_VIEW, "START");
979 g_return_if_fail (view && GL_IS_VIEW (view));
980 g_return_if_fail (view->label && GL_IS_LABEL(view->label));
982 gl_label_get_size (view->label, &w, &h);
984 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
985 view->grid_group = GNOME_CANVAS_GROUP(
986 gnome_canvas_item_new (group,
987 gnome_canvas_group_get_type (),
991 points = gnome_canvas_points_new (2);
993 points->coords[1] = 0.0;
994 points->coords[3] = h;
995 for ( x=0.0; x < w; x += view->grid_spacing ) {
996 points->coords[0] = points->coords[2] = x;
997 item = gnome_canvas_item_new (view->grid_group,
998 gnome_canvas_line_get_type (),
1001 "fill_color_rgba", GRID_COLOR,
1004 points->coords[0] = points->coords[2] = w;
1005 item = gnome_canvas_item_new (view->grid_group,
1006 gnome_canvas_line_get_type (),
1009 "fill_color_rgba", GRID_COLOR,
1012 points->coords[0] = 0.0;
1013 points->coords[2] = w;
1014 for ( y=0.0; y < h; y += view->grid_spacing ) {
1015 points->coords[1] = points->coords[3] = y;
1016 item = gnome_canvas_item_new (view->grid_group,
1017 gnome_canvas_line_get_type (),
1020 "fill_color_rgba", GRID_COLOR,
1023 points->coords[1] = points->coords[3] = h;
1024 item = gnome_canvas_item_new (view->grid_group,
1025 gnome_canvas_line_get_type (),
1028 "fill_color_rgba", GRID_COLOR,
1031 gnome_canvas_points_free (points);
1033 gl_debug (DEBUG_VIEW, "END");
1036 /*---------------------------------------------------------------------------*/
1037 /* PRIVATE. Draw markup lines. */
1038 /*---------------------------------------------------------------------------*/
1040 draw_markup_layer (glView *view)
1042 GnomeCanvasGroup *group;
1044 glTemplate *template;
1046 glTemplateMarkup *markup;
1048 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
1049 view->markup_group = GNOME_CANVAS_GROUP(
1050 gnome_canvas_item_new (group,
1051 gnome_canvas_group_get_type (),
1055 label = view->label;
1056 template = gl_label_get_template (label);
1058 for ( p=template->label.any.markups; p != NULL; p=p->next ) {
1059 markup = (glTemplateMarkup *)p->data;
1061 switch (markup->type) {
1062 case GL_TEMPLATE_MARKUP_MARGIN:
1063 draw_markup_margin (view,
1064 (glTemplateMarkupMargin *)markup);
1066 case GL_TEMPLATE_MARKUP_LINE:
1067 draw_markup_line (view,
1068 (glTemplateMarkupLine *)markup);
1071 g_warning ("Unknown template markup type");
1077 /*---------------------------------------------------------------------------*/
1078 /* PRIVATE. Draw margin markup. */
1079 /*---------------------------------------------------------------------------*/
1081 draw_markup_margin (glView *view,
1082 glTemplateMarkupMargin *margin)
1085 glTemplate *template;
1087 label = view->label;
1088 template = gl_label_get_template (label);
1090 switch (template->label.style) {
1092 case GL_TEMPLATE_STYLE_RECT:
1093 if (template->label.rect.r == 0.0) {
1094 /* Square corners. */
1095 draw_markup_margin_rect (view, margin);
1097 if ( margin->size < template->label.rect.r) {
1098 /* Rounded corners. */
1099 draw_markup_margin_rounded_rect (view, margin);
1101 /* Square corners. */
1102 draw_markup_margin_rect (view, margin);
1107 case GL_TEMPLATE_STYLE_ROUND:
1108 draw_markup_margin_round (view, margin);
1111 case GL_TEMPLATE_STYLE_CD:
1112 if ((template->label.cd.w == 0.0) && (template->label.cd.h == 0.0) ) {
1113 draw_markup_margin_cd (view, margin);
1115 draw_markup_margin_cd_bc (view, margin);
1120 g_warning ("Unknown template label style");
1125 /*---------------------------------------------------------------------------*/
1126 /* PRIVATE. Draw simple recangular margin. */
1127 /*---------------------------------------------------------------------------*/
1129 draw_markup_margin_rect (glView *view,
1130 glTemplateMarkupMargin *margin)
1132 glLabel *label = view->label;
1133 glTemplate *template;
1135 GnomeCanvasItem *item;
1137 gl_debug (DEBUG_VIEW, "START");
1139 g_return_if_fail (GL_IS_VIEW (view));
1140 g_return_if_fail (label != NULL);
1142 gl_label_get_size (label, &w, &h);
1143 template = gl_label_get_template (label);
1146 /* Bounding box @ margin */
1147 gnome_canvas_item_new (view->markup_group,
1148 gnome_canvas_rect_get_type (),
1154 "outline_color_rgba", MARKUP_COLOR,
1157 gl_debug (DEBUG_VIEW, "END");
1160 /*---------------------------------------------------------------------------*/
1161 /* PRIVATE. Draw rounded recangular markup. */
1162 /*---------------------------------------------------------------------------*/
1164 draw_markup_margin_rounded_rect (glView *view,
1165 glTemplateMarkupMargin *margin)
1167 glLabel *label = view->label;
1168 GnomeCanvasPoints *points;
1169 gint i_coords, i_theta;
1170 glTemplate *template;
1172 GnomeCanvasItem *item;
1174 gl_debug (DEBUG_VIEW, "START");
1176 g_return_if_fail (GL_IS_VIEW (view));
1177 g_return_if_fail (label != NULL);
1179 gl_label_get_size (label, &w, &h);
1180 template = gl_label_get_template (label);
1181 r = template->label.rect.r;
1188 /* rectangle with rounded corners */
1189 points = gnome_canvas_points_new (4 * (1 + 90 / ARC_COURSE));
1191 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1192 points->coords[i_coords++] =
1193 m + r - r * sin (i_theta * G_PI / 180.0);
1194 points->coords[i_coords++] =
1195 m + r - r * cos (i_theta * G_PI / 180.0);
1197 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1198 points->coords[i_coords++] =
1199 m + r - r * cos (i_theta * G_PI / 180.0);
1200 points->coords[i_coords++] =
1201 m + (h - r) + r * sin (i_theta * G_PI / 180.0);
1203 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1204 points->coords[i_coords++] =
1205 m + (w - r) + r * sin (i_theta * G_PI / 180.0);
1206 points->coords[i_coords++] =
1207 m + (h - r) + r * cos (i_theta * G_PI / 180.0);
1209 for (i_theta = 0; i_theta <= 90; i_theta += ARC_COURSE) {
1210 points->coords[i_coords++] =
1211 m + (w - r) + r * cos (i_theta * G_PI / 180.0);
1212 points->coords[i_coords++] =
1213 m + r - r * sin (i_theta * G_PI / 180.0);
1215 item = gnome_canvas_item_new (view->markup_group,
1216 gnome_canvas_polygon_get_type (),
1219 "outline_color_rgba", MARKUP_COLOR,
1221 gnome_canvas_points_free (points);
1223 gl_debug (DEBUG_VIEW, "END");
1226 /*---------------------------------------------------------------------------*/
1227 /* PRIVATE. Draw round margin. */
1228 /*---------------------------------------------------------------------------*/
1230 draw_markup_margin_round (glView *view,
1231 glTemplateMarkupMargin *margin)
1233 glLabel *label = view->label;
1234 glTemplate *template;
1236 GnomeCanvasItem *item;
1238 gl_debug (DEBUG_VIEW, "START");
1240 g_return_if_fail (GL_IS_VIEW (view));
1241 g_return_if_fail (label != NULL);
1243 template = gl_label_get_template (label);
1245 r = template->label.round.r;
1248 /* Margin outline */
1249 item = gnome_canvas_item_new (view->markup_group,
1250 gnome_canvas_ellipse_get_type (),
1256 "outline_color_rgba", MARKUP_COLOR,
1259 gl_debug (DEBUG_VIEW, "END");
1262 /*---------------------------------------------------------------------------*/
1263 /* PRIVATE. Draw CD margins. */
1264 /*---------------------------------------------------------------------------*/
1266 draw_markup_margin_cd (glView *view,
1267 glTemplateMarkupMargin *margin)
1269 glLabel *label = view->label;
1270 glTemplate *template;
1272 GnomeCanvasItem *item;
1274 gl_debug (DEBUG_VIEW, "START");
1276 g_return_if_fail (GL_IS_VIEW (view));
1277 g_return_if_fail (label != NULL);
1279 template = gl_label_get_template (label);
1281 r1 = template->label.cd.r1;
1282 r2 = template->label.cd.r2;
1286 item = gnome_canvas_item_new (view->markup_group,
1287 gnome_canvas_ellipse_get_type (),
1293 "outline_color_rgba", MARKUP_COLOR,
1296 item = gnome_canvas_item_new (view->markup_group,
1297 gnome_canvas_ellipse_get_type (),
1303 "outline_color_rgba", MARKUP_COLOR,
1306 gl_debug (DEBUG_VIEW, "END");
1309 /*---------------------------------------------------------------------------*/
1310 /* PRIVATE. Draw Business Card CD margins. */
1311 /*---------------------------------------------------------------------------*/
1313 draw_markup_margin_cd_bc (glView *view,
1314 glTemplateMarkupMargin *margin)
1316 glLabel *label = view->label;
1317 glTemplate *template;
1319 GnomeCanvasPoints *points;
1320 gint i_coords, i_theta;
1321 gdouble theta1, theta2;
1322 gdouble x0, y0, w, h, r;
1323 GnomeCanvasItem *item;
1325 gl_debug (DEBUG_VIEW, "START");
1327 g_return_if_fail (GL_IS_VIEW (view));
1328 g_return_if_fail (label != NULL);
1330 template = gl_label_get_template (label);
1331 gl_label_get_size (label, &w, &h);
1335 r1 = template->label.cd.r1;
1336 r2 = template->label.cd.r2;
1341 theta1 = (180.0/G_PI) * acos (w / (2.0*r1));
1342 theta2 = (180.0/G_PI) * asin (h / (2.0*r1));
1344 points = gnome_canvas_points_new (360/ARC_FINE + 1);
1347 points->coords[i_coords++] = x0 + r * cos (theta1 * G_PI / 180.0);
1348 points->coords[i_coords++] = y0 + r * sin (theta1 * G_PI / 180.0);
1350 for ( i_theta = theta1 + ARC_FINE; i_theta < theta2; i_theta +=ARC_FINE ) {
1351 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
1352 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
1355 points->coords[i_coords++] = x0 + r * cos (theta2 * G_PI / 180.0);
1356 points->coords[i_coords++] = y0 + r * sin (theta2 * G_PI / 180.0);
1359 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
1360 points->coords[i_coords++] = x0 + r * cos ((180-theta2) * G_PI / 180.0);
1361 points->coords[i_coords++] = y0 + r * sin ((180-theta2) * G_PI / 180.0);
1364 for ( i_theta = 180-theta2+ARC_FINE; i_theta < (180-theta1); i_theta +=ARC_FINE ) {
1365 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
1366 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
1369 points->coords[i_coords++] = x0 + r * cos ((180-theta1) * G_PI / 180.0);
1370 points->coords[i_coords++] = y0 + r * sin ((180-theta1) * G_PI / 180.0);
1372 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
1373 points->coords[i_coords++] = x0 + r * cos ((180+theta1) * G_PI / 180.0);
1374 points->coords[i_coords++] = y0 + r * sin ((180+theta1) * G_PI / 180.0);
1377 for ( i_theta = 180+theta1+ARC_FINE; i_theta < (180+theta2); i_theta +=ARC_FINE ) {
1378 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
1379 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
1382 points->coords[i_coords++] = x0 + r * cos ((180+theta2) * G_PI / 180.0);
1383 points->coords[i_coords++] = y0 + r * sin ((180+theta2) * G_PI / 180.0);
1385 if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
1386 points->coords[i_coords++] = x0 + r * cos ((360-theta2) * G_PI / 180.0);
1387 points->coords[i_coords++] = y0 + r * sin ((360-theta2) * G_PI / 180.0);
1390 for ( i_theta = 360-theta2+ARC_FINE; i_theta < (360-theta1); i_theta +=ARC_FINE ) {
1391 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
1392 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
1395 if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
1396 points->coords[i_coords++] = x0 + r * cos ((360-theta1) * G_PI / 180.0);
1397 points->coords[i_coords++] = y0 + r * sin ((360-theta1) * G_PI / 180.0);
1400 points->num_points = i_coords / 2;
1402 item = gnome_canvas_item_new (view->markup_group,
1403 gnome_canvas_polygon_get_type (),
1406 "outline_color_rgba", MARKUP_COLOR,
1409 gnome_canvas_points_free (points);
1412 item = gnome_canvas_item_new (view->markup_group,
1413 gnome_canvas_ellipse_get_type (),
1419 "outline_color_rgba", MARKUP_COLOR,
1422 gl_debug (DEBUG_VIEW, "END");
1425 /*---------------------------------------------------------------------------*/
1426 /* PRIVATE. Draw line markup. */
1427 /*---------------------------------------------------------------------------*/
1429 draw_markup_line (glView *view,
1430 glTemplateMarkupLine *line)
1432 GnomeCanvasPoints *points;
1434 gl_debug (DEBUG_VIEW, "START");
1436 g_return_if_fail (GL_IS_VIEW (view));
1438 points = gnome_canvas_points_new (2);
1439 points->coords[0] = line->x1;
1440 points->coords[1] = line->y1;
1441 points->coords[2] = line->x2;
1442 points->coords[3] = line->y2;
1444 /* Bounding box @ margin */
1445 gnome_canvas_item_new (view->markup_group,
1446 gnome_canvas_line_get_type (),
1449 "fill_color_rgba", MARKUP_COLOR,
1452 gnome_canvas_points_free (points);
1454 gl_debug (DEBUG_VIEW, "END");
1457 /*****************************************************************************/
1459 /*****************************************************************************/
1460 void gl_view_show_grid (glView *view)
1462 gnome_canvas_item_show (GNOME_CANVAS_ITEM(view->grid_group));
1465 /*****************************************************************************/
1467 /*****************************************************************************/
1468 void gl_view_hide_grid (glView *view)
1470 gnome_canvas_item_hide (GNOME_CANVAS_ITEM(view->grid_group));
1473 /*****************************************************************************/
1474 /* Set grid spacing. */
1475 /*****************************************************************************/
1476 void gl_view_set_grid_spacing (glView *view,
1479 view->grid_spacing = spacing;
1481 gtk_object_destroy (GTK_OBJECT(view->grid_group));
1482 draw_grid_layer (view);
1485 /*****************************************************************************/
1487 /*****************************************************************************/
1488 void gl_view_show_markup (glView *view)
1490 gnome_canvas_item_show (GNOME_CANVAS_ITEM(view->markup_group));
1493 /*****************************************************************************/
1495 /*****************************************************************************/
1496 void gl_view_hide_markup (glView *view)
1498 gnome_canvas_item_hide (GNOME_CANVAS_ITEM(view->markup_group));
1501 /*****************************************************************************/
1502 /* Set arrow mode. */
1503 /*****************************************************************************/
1505 gl_view_arrow_mode (glView *view)
1507 static GdkCursor *cursor = NULL;
1509 gl_debug (DEBUG_VIEW, "START");
1511 g_return_if_fail (GL_IS_VIEW (view));
1514 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1517 gdk_window_set_cursor (view->canvas->window, cursor);
1519 view->state = GL_VIEW_STATE_ARROW;
1521 gl_debug (DEBUG_VIEW, "END");
1524 /*****************************************************************************/
1525 /* Set create text object mode. */
1526 /*****************************************************************************/
1528 gl_view_object_create_mode (glView *view,
1529 glLabelObjectType type)
1533 gl_debug (DEBUG_VIEW, "START");
1535 g_return_if_fail (GL_IS_VIEW (view));
1538 case GL_LABEL_OBJECT_BOX:
1539 cursor = gl_view_box_get_create_cursor ();
1541 case GL_LABEL_OBJECT_ELLIPSE:
1542 cursor = gl_view_ellipse_get_create_cursor ();
1544 case GL_LABEL_OBJECT_LINE:
1545 cursor = gl_view_line_get_create_cursor ();
1547 case GL_LABEL_OBJECT_IMAGE:
1548 cursor = gl_view_image_get_create_cursor ();
1550 case GL_LABEL_OBJECT_TEXT:
1551 cursor = gl_view_text_get_create_cursor ();
1553 case GL_LABEL_OBJECT_BARCODE:
1554 cursor = gl_view_barcode_get_create_cursor ();
1557 g_warning ("Invalid label object type.");/*Should not happen!*/
1561 gdk_window_set_cursor (view->canvas->window, cursor);
1563 view->state = GL_VIEW_STATE_OBJECT_CREATE;
1564 view->create_type = type;
1566 gl_debug (DEBUG_VIEW, "END");
1569 /*****************************************************************************/
1570 /* Select given object (adding to current selection). */
1571 /*****************************************************************************/
1573 gl_view_select_object (glView *view,
1574 glViewObject *view_object)
1576 gl_debug (DEBUG_VIEW, "START");
1578 select_object_real (view, view_object);
1580 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1582 gl_debug (DEBUG_VIEW, "END");
1585 /*****************************************************************************/
1586 /* Unselect given object (removing from current selection). */
1587 /*****************************************************************************/
1589 gl_view_unselect_object (glView *view,
1590 glViewObject *view_object)
1592 gl_debug (DEBUG_VIEW, "START");
1594 unselect_object_real (view, view_object);
1596 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1598 gl_debug (DEBUG_VIEW, "END");
1601 /*****************************************************************************/
1602 /* Select all items. */
1603 /*****************************************************************************/
1605 gl_view_select_all (glView *view)
1609 gl_debug (DEBUG_VIEW, "START");
1611 g_return_if_fail (GL_IS_VIEW (view));
1613 /* 1st unselect anything already selected. */
1614 for (p = view->selected_object_list; p != NULL; p = p_next) {
1616 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1619 /* Finally select all objects. */
1620 for (p = view->object_list; p != NULL; p = p->next) {
1621 select_object_real (view, GL_VIEW_OBJECT (p->data));
1624 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1626 gl_debug (DEBUG_VIEW, "END");
1629 /*****************************************************************************/
1630 /* Remove all selections */
1631 /*****************************************************************************/
1633 gl_view_unselect_all (glView *view)
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) {
1643 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
1646 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1648 gl_debug (DEBUG_VIEW, "END");
1651 /*****************************************************************************/
1652 /* Select all objects within given rectangular region (adding to selection). */
1653 /*****************************************************************************/
1655 gl_view_select_region (glView *view,
1662 glViewObject *view_object;
1663 glLabelObject *object;
1664 gdouble i_x1, i_y1, i_x2, i_y2;
1666 gl_debug (DEBUG_VIEW, "START");
1668 g_return_if_fail (GL_IS_VIEW (view));
1669 g_return_if_fail ((x1 <= x2) && (y1 <= y2));
1671 for (p = view->object_list; p != NULL; p = p->next) {
1672 view_object = GL_VIEW_OBJECT(p->data);
1673 if (!gl_view_is_object_selected (view, view_object)) {
1675 object = gl_view_object_get_object (view_object);
1677 gl_label_object_get_extent (object, &i_x1, &i_y1, &i_x2, &i_y2);
1678 if ((i_x1 >= x1) && (i_x2 <= x2) && (i_y1 >= y1)
1680 select_object_real (view, view_object);
1686 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1688 gl_debug (DEBUG_VIEW, "END");
1691 /*---------------------------------------------------------------------------*/
1692 /* PRIVATE. Select an object. */
1693 /*---------------------------------------------------------------------------*/
1695 select_object_real (glView *view,
1696 glViewObject *view_object)
1698 gl_debug (DEBUG_VIEW, "START");
1700 g_return_if_fail (GL_IS_VIEW (view));
1701 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1703 if (!gl_view_is_object_selected (view, view_object)) {
1704 view->selected_object_list =
1705 g_list_prepend (view->selected_object_list, view_object);
1707 gl_view_object_show_highlight (view_object);
1708 gtk_widget_grab_focus (GTK_WIDGET (view->canvas));
1710 gl_debug (DEBUG_VIEW, "END");
1713 /*---------------------------------------------------------------------------*/
1714 /* PRIVATE. Un-select object. */
1715 /*---------------------------------------------------------------------------*/
1717 unselect_object_real (glView *view,
1718 glViewObject *view_object)
1720 gl_debug (DEBUG_VIEW, "START");
1722 g_return_if_fail (GL_IS_VIEW (view));
1723 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1725 gl_view_object_hide_highlight (view_object);
1727 view->selected_object_list =
1728 g_list_remove (view->selected_object_list, view_object);
1730 gl_debug (DEBUG_VIEW, "END");
1733 /*---------------------------------------------------------------------------*/
1734 /* PRIVATE. Return object at (x,y). */
1735 /*---------------------------------------------------------------------------*/
1737 object_at (glView *view,
1741 GnomeCanvasItem *item, *p_item;
1744 gl_debug (DEBUG_VIEW, "");
1746 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1748 item = gnome_canvas_get_item_at (GNOME_CANVAS (view->canvas), x, y);
1750 /* No item is at x, y */
1754 /* ignore items not in label or highlight layers, e.g. background items */
1755 if (!is_item_member_of_group(view, item, GNOME_CANVAS_ITEM(view->label_group)) &&
1756 !is_item_member_of_group(view, item, GNOME_CANVAS_ITEM(view->highlight_group)))
1762 /*---------------------------------------------------------------------------*/
1763 /* PRIVATE. Is the item a child (or grandchild, etc.) of group. */
1764 /*---------------------------------------------------------------------------*/
1766 is_item_member_of_group (glView *view,
1767 GnomeCanvasItem *item,
1768 GnomeCanvasItem *group)
1770 GnomeCanvasItem *parent;
1771 GnomeCanvasItem *root_group;
1773 root_group = GNOME_CANVAS_ITEM(gnome_canvas_root (GNOME_CANVAS (view->canvas)));
1775 for ( parent=item->parent; parent && (parent!=root_group); parent=parent->parent) {
1776 if (parent == group) return TRUE;
1781 /*****************************************************************************/
1782 /* Is the object in our current selection? */
1783 /*****************************************************************************/
1785 gl_view_is_object_selected (glView *view,
1786 glViewObject *view_object)
1788 gl_debug (DEBUG_VIEW, "");
1790 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1791 g_return_val_if_fail (GL_IS_VIEW_OBJECT (view_object), FALSE);
1793 if (g_list_find (view->selected_object_list, view_object) == NULL) {
1799 /*****************************************************************************/
1800 /* Is our current selection empty? */
1801 /*****************************************************************************/
1803 gl_view_is_selection_empty (glView *view)
1805 gl_debug (DEBUG_VIEW, "");
1807 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1809 if (view->selected_object_list == NULL) {
1816 /*****************************************************************************/
1817 /* Is our current selection atomic? I.e. only one item selected. */
1818 /*****************************************************************************/
1820 gl_view_is_selection_atomic (glView *view)
1822 gl_debug (DEBUG_VIEW, "");
1824 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1826 if (view->selected_object_list == NULL)
1828 if (view->selected_object_list->next == NULL)
1833 /*****************************************************************************/
1834 /* Delete selected objects. (Bypass clipboard) */
1835 /*****************************************************************************/
1837 gl_view_delete_selection (glView *view)
1841 gl_debug (DEBUG_VIEW, "START");
1843 g_return_if_fail (GL_IS_VIEW (view));
1845 for (p = view->selected_object_list; p != NULL; p = p_next) {
1847 g_object_unref (G_OBJECT (p->data));
1850 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1852 gl_debug (DEBUG_VIEW, "END");
1855 /*****************************************************************************/
1856 /* Edit properties of selected object. */
1857 /*****************************************************************************/
1859 gl_view_edit_object_props (glView *view)
1861 glViewObject *view_object;
1863 gl_debug (DEBUG_VIEW, "START");
1865 g_return_if_fail (GL_IS_VIEW (view));
1867 if (gl_view_is_selection_atomic (view)) {
1869 view_object = GL_VIEW_OBJECT(view->selected_object_list->data);
1870 gl_view_object_show_dialog (view_object);
1874 gl_debug (DEBUG_VIEW, "END");
1877 /*****************************************************************************/
1878 /* Raise selected items to top. */
1879 /*****************************************************************************/
1881 gl_view_raise_selection (glView *view)
1884 glViewObject *view_object;
1885 glLabelObject *object;
1887 gl_debug (DEBUG_VIEW, "START");
1889 g_return_if_fail (GL_IS_VIEW (view));
1891 for (p = view->selected_object_list; p != NULL; p = p->next) {
1892 view_object = GL_VIEW_OBJECT (p->data);
1893 object = gl_view_object_get_object (view_object);
1894 gl_label_object_raise_to_top (object);
1897 gl_debug (DEBUG_VIEW, "END");
1900 /*****************************************************************************/
1901 /* Lower selected items to bottom. */
1902 /*****************************************************************************/
1904 gl_view_lower_selection (glView *view)
1907 glViewObject *view_object;
1908 glLabelObject *object;
1910 gl_debug (DEBUG_VIEW, "START");
1912 g_return_if_fail (GL_IS_VIEW (view));
1914 for (p = view->selected_object_list; p != NULL; p = p->next) {
1915 view_object = GL_VIEW_OBJECT (p->data);
1916 object = gl_view_object_get_object (view_object);
1917 gl_label_object_lower_to_bottom (object);
1920 gl_debug (DEBUG_VIEW, "END");
1923 /*****************************************************************************/
1924 /* Rotate selected objects by given angle. */
1925 /*****************************************************************************/
1927 gl_view_rotate_selection (glView *view,
1931 glViewObject *view_object;
1932 glLabelObject *object;
1934 gl_debug (DEBUG_VIEW, "START");
1936 g_return_if_fail (GL_IS_VIEW (view));
1938 for (p = view->selected_object_list; p != NULL; p = p->next) {
1939 view_object = GL_VIEW_OBJECT (p->data);
1940 object = gl_view_object_get_object (view_object);
1941 gl_label_object_rotate (object, theta_degs);
1944 gl_debug (DEBUG_VIEW, "END");
1947 /*****************************************************************************/
1948 /* Rotate selected objects 90 degrees left. */
1949 /*****************************************************************************/
1951 gl_view_rotate_selection_left (glView *view)
1954 glViewObject *view_object;
1955 glLabelObject *object;
1957 gl_debug (DEBUG_VIEW, "START");
1959 g_return_if_fail (GL_IS_VIEW (view));
1961 for (p = view->selected_object_list; p != NULL; p = p->next) {
1962 view_object = GL_VIEW_OBJECT (p->data);
1963 object = gl_view_object_get_object (view_object);
1964 gl_label_object_rotate (object, -90.0);
1967 gl_debug (DEBUG_VIEW, "END");
1970 /*****************************************************************************/
1971 /* Rotate selected objects 90 degrees right. */
1972 /*****************************************************************************/
1974 gl_view_rotate_selection_right (glView *view)
1977 glViewObject *view_object;
1978 glLabelObject *object;
1980 gl_debug (DEBUG_VIEW, "START");
1982 g_return_if_fail (GL_IS_VIEW (view));
1984 for (p = view->selected_object_list; p != NULL; p = p->next) {
1985 view_object = GL_VIEW_OBJECT (p->data);
1986 object = gl_view_object_get_object (view_object);
1987 gl_label_object_rotate (object, 90.0);
1990 gl_debug (DEBUG_VIEW, "END");
1993 /*****************************************************************************/
1994 /* Flip selected objects horizontally. */
1995 /*****************************************************************************/
1997 gl_view_flip_selection_horiz (glView *view)
2000 glViewObject *view_object;
2001 glLabelObject *object;
2003 gl_debug (DEBUG_VIEW, "START");
2005 g_return_if_fail (GL_IS_VIEW (view));
2007 for (p = view->selected_object_list; p != NULL; p = p->next) {
2008 view_object = GL_VIEW_OBJECT (p->data);
2009 object = gl_view_object_get_object (view_object);
2010 gl_label_object_flip_horiz (object);
2013 gl_debug (DEBUG_VIEW, "END");
2016 /*****************************************************************************/
2017 /* Flip selected objects vertically. */
2018 /*****************************************************************************/
2020 gl_view_flip_selection_vert (glView *view)
2023 glViewObject *view_object;
2024 glLabelObject *object;
2026 gl_debug (DEBUG_VIEW, "START");
2028 g_return_if_fail (GL_IS_VIEW (view));
2030 for (p = view->selected_object_list; p != NULL; p = p->next) {
2031 view_object = GL_VIEW_OBJECT (p->data);
2032 object = gl_view_object_get_object (view_object);
2033 gl_label_object_flip_vert (object);
2036 gl_debug (DEBUG_VIEW, "END");
2039 /*****************************************************************************/
2040 /* Align selected objects to left most edge. */
2041 /*****************************************************************************/
2043 gl_view_align_selection_left (glView *view)
2046 glViewObject *view_object;
2047 glLabelObject *object;
2048 gdouble dx, x1min, x1, y1, x2, y2;
2050 gl_debug (DEBUG_VIEW, "START");
2052 g_return_if_fail (GL_IS_VIEW (view));
2054 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2055 !gl_view_is_selection_atomic (view));
2057 /* find left most edge */
2058 p = view->selected_object_list;
2059 view_object = GL_VIEW_OBJECT (p->data);
2060 object = gl_view_object_get_object (view_object);
2061 gl_label_object_get_extent (object, &x1min, &y1, &x2, &y2);
2062 for (p = p->next; p != NULL; p = p->next) {
2063 view_object = GL_VIEW_OBJECT (p->data);
2064 object = gl_view_object_get_object (view_object);
2065 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2066 if ( x1 < x1min ) x1min = x1;
2069 /* now adjust the object positions to line up the left edges */
2070 for (p = view->selected_object_list; p != NULL; p = p->next) {
2071 view_object = GL_VIEW_OBJECT (p->data);
2072 object = gl_view_object_get_object (view_object);
2073 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2075 gl_label_object_set_position_relative (object, dx, 0.0);
2078 gl_debug (DEBUG_VIEW, "END");
2082 /*****************************************************************************/
2083 /* Align selected objects to right most edge. */
2084 /*****************************************************************************/
2086 gl_view_align_selection_right (glView *view)
2089 glViewObject *view_object;
2090 glLabelObject *object;
2091 gdouble dx, x2max, x1, y1, x2, y2;
2093 gl_debug (DEBUG_VIEW, "START");
2095 g_return_if_fail (GL_IS_VIEW (view));
2097 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2098 !gl_view_is_selection_atomic (view));
2100 /* find right most edge */
2101 p = view->selected_object_list;
2102 view_object = GL_VIEW_OBJECT (p->data);
2103 object = gl_view_object_get_object (view_object);
2104 gl_label_object_get_extent (object, &x1, &y1, &x2max, &y2);
2105 for (p = p->next; p != NULL; p = p->next) {
2106 view_object = GL_VIEW_OBJECT (p->data);
2107 object = gl_view_object_get_object (view_object);
2108 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2109 if ( x2 > x2max ) x2max = x2;
2112 /* now adjust the object positions to line up the right edges */
2113 for (p = view->selected_object_list; p != NULL; p = p->next) {
2114 view_object = GL_VIEW_OBJECT (p->data);
2115 object = gl_view_object_get_object (view_object);
2116 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2118 gl_label_object_set_position_relative (object, dx, 0.0);
2121 gl_debug (DEBUG_VIEW, "END");
2124 /*****************************************************************************/
2125 /* Align selected objects to horizontal center of objects. */
2126 /*****************************************************************************/
2128 gl_view_align_selection_hcenter (glView *view)
2131 glViewObject *view_object;
2132 glLabelObject *object;
2133 gdouble dx, dxmin, xsum, xavg, xcenter, x1, y1, x2, y2;
2136 gl_debug (DEBUG_VIEW, "START");
2138 g_return_if_fail (GL_IS_VIEW (view));
2140 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2141 !gl_view_is_selection_atomic (view));
2143 /* find average center of objects */
2146 for (p = view->selected_object_list; p != NULL; p = p->next) {
2147 view_object = GL_VIEW_OBJECT (p->data);
2148 object = gl_view_object_get_object (view_object);
2149 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2150 xsum += (x1 + x2) / 2.0;
2155 /* find center of object closest to average center */
2156 p = view->selected_object_list;
2157 view_object = GL_VIEW_OBJECT (p->data);
2158 object = gl_view_object_get_object (view_object);
2159 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2160 dxmin = fabs (xavg - (x1 + x2)/2.0);
2161 xcenter = (x1 + x2)/2.0;
2162 for (p = p->next; p != NULL; p = p->next) {
2163 view_object = GL_VIEW_OBJECT (p->data);
2164 object = gl_view_object_get_object (view_object);
2165 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2166 dx = fabs (xavg - (x1 + x2)/2.0);
2169 xcenter = (x1 + x2)/2.0;
2173 /* now adjust the object positions to line up this center */
2174 for (p = view->selected_object_list; p != NULL; p = p->next) {
2175 view_object = GL_VIEW_OBJECT (p->data);
2176 object = gl_view_object_get_object (view_object);
2177 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2178 dx = xcenter - (x1 + x2)/2.0;
2179 gl_label_object_set_position_relative (object, dx, 0.0);
2182 gl_debug (DEBUG_VIEW, "END");
2185 /*****************************************************************************/
2186 /* Align selected objects to top most edge. */
2187 /*****************************************************************************/
2189 gl_view_align_selection_top (glView *view)
2192 glViewObject *view_object;
2193 glLabelObject *object;
2194 gdouble dy, y1min, x1, y1, x2, y2;
2196 gl_debug (DEBUG_VIEW, "START");
2198 g_return_if_fail (GL_IS_VIEW (view));
2200 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2201 !gl_view_is_selection_atomic (view));
2203 /* find top most edge */
2204 p = view->selected_object_list;
2205 view_object = GL_VIEW_OBJECT (p->data);
2206 object = gl_view_object_get_object (view_object);
2207 gl_label_object_get_extent (object, &x1, &y1min, &x2, &y2);
2208 for (p = p->next; p != NULL; p = p->next) {
2209 view_object = GL_VIEW_OBJECT (p->data);
2210 object = gl_view_object_get_object (view_object);
2211 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2212 if ( y1 < y1min ) y1min = y1;
2215 /* now adjust the object positions to line up the top edges */
2216 for (p = view->selected_object_list; p != NULL; p = p->next) {
2217 view_object = GL_VIEW_OBJECT (p->data);
2218 object = gl_view_object_get_object (view_object);
2219 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2221 gl_label_object_set_position_relative (object, 0.0, dy);
2224 gl_debug (DEBUG_VIEW, "END");
2227 /*****************************************************************************/
2228 /* Align selected objects to bottom most edge. */
2229 /*****************************************************************************/
2231 gl_view_align_selection_bottom (glView *view)
2234 glViewObject *view_object;
2235 glLabelObject *object;
2236 gdouble dy, y2max, x1, y1, x2, y2;
2238 gl_debug (DEBUG_VIEW, "START");
2240 g_return_if_fail (GL_IS_VIEW (view));
2242 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2243 !gl_view_is_selection_atomic (view));
2245 /* find bottom most edge */
2246 p = view->selected_object_list;
2247 view_object = GL_VIEW_OBJECT (p->data);
2248 object = gl_view_object_get_object (view_object);
2249 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2max);
2250 for (p = p->next; p != NULL; p = p->next) {
2251 view_object = GL_VIEW_OBJECT (p->data);
2252 object = gl_view_object_get_object (view_object);
2253 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2254 if ( y2 > y2max ) y2max = y2;
2257 /* now adjust the object positions to line up the bottom edges */
2258 for (p = view->selected_object_list; p != NULL; p = p->next) {
2259 view_object = GL_VIEW_OBJECT (p->data);
2260 object = gl_view_object_get_object (view_object);
2261 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2263 gl_label_object_set_position_relative (object, 0.0, dy);
2266 gl_debug (DEBUG_VIEW, "END");
2269 /*****************************************************************************/
2270 /* Align selected objects to viertical center of objects. */
2271 /*****************************************************************************/
2273 gl_view_align_selection_vcenter (glView *view)
2276 glViewObject *view_object;
2277 glLabelObject *object;
2278 gdouble dy, dymin, ysum, yavg, ycenter, x1, y1, x2, y2;
2281 gl_debug (DEBUG_VIEW, "START");
2283 g_return_if_fail (GL_IS_VIEW (view));
2285 g_return_if_fail (!gl_view_is_selection_empty (view) &&
2286 !gl_view_is_selection_atomic (view));
2288 /* find average center of objects */
2291 for (p = view->selected_object_list; p != NULL; p = p->next) {
2292 view_object = GL_VIEW_OBJECT (p->data);
2293 object = gl_view_object_get_object (view_object);
2294 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2295 ysum += (y1 + y2) / 2.0;
2300 /* find center of object closest to average center */
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, &y1, &x2, &y2);
2305 dymin = fabs (yavg - (y1 + y2)/2.0);
2306 ycenter = (y1 + y2)/2.0;
2307 for (p = p->next; p != NULL; p = p->next) {
2308 view_object = GL_VIEW_OBJECT (p->data);
2309 object = gl_view_object_get_object (view_object);
2310 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2311 dy = fabs (yavg - (y1 + y2)/2.0);
2314 ycenter = (y1 + y2)/2.0;
2318 /* now adjust the object positions to line up this center */
2319 for (p = view->selected_object_list; p != NULL; p = p->next) {
2320 view_object = GL_VIEW_OBJECT (p->data);
2321 object = gl_view_object_get_object (view_object);
2322 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2323 dy = ycenter - (y1 + y2)/2.0;
2324 gl_label_object_set_position_relative (object, 0.0, dy);
2327 gl_debug (DEBUG_VIEW, "END");
2330 /*****************************************************************************/
2331 /* Center selected objects to in center of label. */
2332 /*****************************************************************************/
2334 gl_view_center_selection_horiz (glView *view)
2337 glViewObject *view_object;
2338 glLabelObject *object;
2339 gdouble dx, x_label_center, x_obj_center, x1, y1, x2, y2, w, h;
2341 gl_debug (DEBUG_VIEW, "START");
2343 g_return_if_fail (GL_IS_VIEW (view));
2345 g_return_if_fail (!gl_view_is_selection_empty (view));
2347 gl_label_get_size (view->label, &w, &h);
2348 x_label_center = w / 2.0;
2350 /* adjust the object positions */
2351 for (p = view->selected_object_list; p != NULL; p = p->next) {
2352 view_object = GL_VIEW_OBJECT (p->data);
2353 object = gl_view_object_get_object (view_object);
2354 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2355 x_obj_center = (x1 + x2) / 2.0;
2356 dx = x_label_center - x_obj_center;
2357 gl_label_object_set_position_relative (object, dx, 0.0);
2360 gl_debug (DEBUG_VIEW, "END");
2364 /*****************************************************************************/
2365 /* Center selected objects to in center of label. */
2366 /*****************************************************************************/
2368 gl_view_center_selection_vert (glView *view)
2371 glViewObject *view_object;
2372 glLabelObject *object;
2373 gdouble dy, y_label_center, y_obj_center, x1, y1, x2, y2, w, h;
2375 gl_debug (DEBUG_VIEW, "START");
2377 g_return_if_fail (GL_IS_VIEW (view));
2379 g_return_if_fail (!gl_view_is_selection_empty (view));
2381 gl_label_get_size (view->label, &w, &h);
2382 y_label_center = h / 2.0;
2384 /* adjust the object positions */
2385 for (p = view->selected_object_list; p != NULL; p = p->next) {
2386 view_object = GL_VIEW_OBJECT (p->data);
2387 object = gl_view_object_get_object (view_object);
2388 gl_label_object_get_extent (object, &x1, &y1, &x2, &y2);
2389 y_obj_center = (y1 + y2) / 2.0;
2390 dy = y_label_center - y_obj_center;
2391 gl_label_object_set_position_relative (object, 0.0, dy);
2394 gl_debug (DEBUG_VIEW, "END");
2398 /*****************************************************************************/
2399 /* Move selected objects */
2400 /*****************************************************************************/
2402 gl_view_move_selection (glView *view,
2407 glLabelObject *object;
2409 gl_debug (DEBUG_VIEW, "START");
2411 g_return_if_fail (view && GL_IS_VIEW (view));
2413 for (p = view->selected_object_list; p != NULL; p = p->next) {
2415 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
2416 gl_label_object_set_position_relative (object, dx, dy);
2420 gl_debug (DEBUG_VIEW, "END");
2423 /*****************************************************************************/
2424 /* "Cut" selected items and place in clipboard selections. */
2425 /*****************************************************************************/
2427 gl_view_cut (glView *view)
2429 gl_debug (DEBUG_VIEW, "START");
2431 g_return_if_fail (GL_IS_VIEW (view));
2433 gl_view_copy (view);
2434 gl_view_delete_selection (view);
2436 gl_debug (DEBUG_VIEW, "END");
2439 /*****************************************************************************/
2440 /* "Copy" selected items to clipboard selections. */
2441 /*****************************************************************************/
2443 gl_view_copy (glView *view)
2446 glViewObject *view_object;
2447 glLabelObject *object;
2448 glTemplate *template;
2449 gboolean rotate_flag;
2451 gl_debug (DEBUG_VIEW, "START");
2453 g_return_if_fail (GL_IS_VIEW (view));
2455 if (view->selected_object_list) {
2457 if ( view->selection_data ) {
2458 g_object_unref (view->selection_data);
2460 template = gl_label_get_template (view->label);
2461 rotate_flag = gl_label_get_rotate_flag (view->label);
2462 view->selection_data = GL_LABEL(gl_label_new ());
2463 gl_label_set_template (view->selection_data, template);
2464 gl_label_set_rotate_flag (view->selection_data, rotate_flag);
2465 gl_template_free (&template);
2467 for (p = view->selected_object_list; p != NULL; p = p->next) {
2469 view_object = GL_VIEW_OBJECT (p->data);
2470 object = gl_view_object_get_object (view_object);
2472 gl_label_object_dup (object, view->selection_data);
2476 gtk_selection_owner_set (view->invisible,
2477 clipboard_atom, GDK_CURRENT_TIME);
2478 view->have_selection = TRUE;
2482 gl_debug (DEBUG_VIEW, "END");
2485 /*****************************************************************************/
2486 /* "Paste" from private clipboard selection. */
2487 /*****************************************************************************/
2489 gl_view_paste (glView *view)
2491 gl_debug (DEBUG_VIEW, "START");
2493 g_return_if_fail (GL_IS_VIEW (view));
2495 gtk_selection_convert (GTK_WIDGET (view->invisible),
2496 clipboard_atom, GDK_SELECTION_TYPE_STRING,
2499 gl_debug (DEBUG_VIEW, "END");
2502 /*****************************************************************************/
2503 /* Zoom in one "notch" */
2504 /*****************************************************************************/
2506 gl_view_zoom_in (glView *view)
2509 gdouble dist, dist_min;
2511 gl_debug (DEBUG_VIEW, "START");
2513 g_return_if_fail (GL_IS_VIEW (view));
2515 /* Find index of current scale (or best match) */
2516 i_min = 1; /* start with 2nd largest scale */
2517 dist_min = fabs (scales[1] - view->scale);
2518 for (i = 2; i < N_SCALES; i++) {
2519 dist = fabs (scales[i] - view->scale);
2520 if (dist < dist_min) {
2526 /* zoom in one "notch" */
2527 i = MAX (0, i_min - 1);
2528 gl_view_set_zoom (view, scales[i] / HOME_SCALE);
2530 gl_debug (DEBUG_VIEW, "END");
2533 /*****************************************************************************/
2534 /* Zoom out one "notch" */
2535 /*****************************************************************************/
2537 gl_view_zoom_out (glView *view)
2540 gdouble dist, dist_min;
2542 gl_debug (DEBUG_VIEW, "START");
2544 g_return_if_fail (GL_IS_VIEW (view));
2546 /* Find index of current scale (or best match) */
2547 i_min = 0; /* start with largest scale */
2548 dist_min = fabs (scales[0] - view->scale);
2549 for (i = 1; i < N_SCALES; i++) {
2550 dist = fabs (scales[i] - view->scale);
2551 if (dist < dist_min) {
2557 /* zoom out one "notch" */
2558 if (i_min >= N_SCALES)
2563 gl_view_set_zoom (view, scales[i] / HOME_SCALE);
2565 gl_debug (DEBUG_VIEW, "END");
2568 /*****************************************************************************/
2569 /* Set current zoom factor to explicit value. */
2570 /*****************************************************************************/
2572 gl_view_set_zoom (glView *view,
2575 gl_debug (DEBUG_VIEW, "START");
2577 g_return_if_fail (GL_IS_VIEW (view));
2578 g_return_if_fail (scale > 0.0);
2580 view->scale = scale * HOME_SCALE;
2581 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
2582 scale * HOME_SCALE);
2584 g_signal_emit (G_OBJECT(view), signals[ZOOM_CHANGED], 0, scale);
2586 gl_debug (DEBUG_VIEW, "END");
2589 /*****************************************************************************/
2590 /* Get current zoom factor. */
2591 /*****************************************************************************/
2593 gl_view_get_zoom (glView *view)
2595 gl_debug (DEBUG_VIEW, "");
2597 g_return_val_if_fail (GL_IS_VIEW (view), 1.0);
2599 return view->scale / HOME_SCALE;
2602 /*****************************************************************************/
2603 /* Is this the maximum zoom level. */
2604 /*****************************************************************************/
2606 gl_view_is_zoom_max (glView *view)
2608 gl_debug (DEBUG_VIEW, "");
2610 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
2612 return view->scale >= scales[0];
2615 /*****************************************************************************/
2616 /* Is this the minimum zoom level. */
2617 /*****************************************************************************/
2619 gl_view_is_zoom_min (glView *view)
2621 gl_debug (DEBUG_VIEW, "");
2623 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
2625 return view->scale <= scales[N_SCALES-1];
2628 /*****************************************************************************/
2629 /* Launch merge properties dialog. */
2630 /*****************************************************************************/
2632 gl_view_edit_merge_props (glView *view)
2634 gl_debug (DEBUG_VIEW, "");
2636 g_return_if_fail (GL_IS_VIEW (view));
2638 if (view->merge_props_dialog != NULL) {
2639 gtk_widget_show_all (view->merge_props_dialog);
2640 gtk_window_present (GTK_WINDOW(view->merge_props_dialog));
2644 view->merge_props_dialog = gl_merge_properties_dialog_new (view);
2645 gtk_widget_show_all (view->merge_props_dialog);
2647 g_signal_connect (G_OBJECT(view->merge_props_dialog), "destroy",
2648 G_CALLBACK (gtk_widget_destroyed),
2649 &view->merge_props_dialog);
2652 /*---------------------------------------------------------------------------*/
2653 /* PRIVATE. Canvas event handler. */
2654 /*---------------------------------------------------------------------------*/
2656 canvas_event (GnomeCanvas *canvas,
2662 gl_debug (DEBUG_VIEW, "");
2664 /* emit pointer signals regardless of state */
2665 switch (event->type) {
2666 case GDK_MOTION_NOTIFY:
2667 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
2668 gnome_canvas_window_to_world (canvas,
2670 event->motion.y, &x, &y);
2671 g_signal_emit (G_OBJECT(view), signals[POINTER_MOVED], 0, x, y);
2672 break; /* fall through */
2674 case GDK_LEAVE_NOTIFY:
2675 gl_debug (DEBUG_VIEW, "LEAVEW_NOTIFY");
2676 g_signal_emit (G_OBJECT(view), signals[POINTER_EXIT], 0);
2677 break; /* fall through */
2680 break; /* fall through */
2684 switch (view->state) {
2686 case GL_VIEW_STATE_ARROW:
2687 return canvas_event_arrow_mode (canvas, event, view);
2689 case GL_VIEW_STATE_OBJECT_CREATE:
2690 switch (view->create_type) {
2691 case GL_LABEL_OBJECT_BOX:
2692 return gl_view_box_create_event_handler (canvas,
2696 case GL_LABEL_OBJECT_ELLIPSE:
2697 return gl_view_ellipse_create_event_handler (canvas,
2701 case GL_LABEL_OBJECT_LINE:
2702 return gl_view_line_create_event_handler (canvas,
2706 case GL_LABEL_OBJECT_IMAGE:
2707 return gl_view_image_create_event_handler (canvas,
2711 case GL_LABEL_OBJECT_TEXT:
2712 return gl_view_text_create_event_handler (canvas,
2716 case GL_LABEL_OBJECT_BARCODE:
2717 return gl_view_barcode_create_event_handler (canvas,
2722 /*Should not happen!*/
2723 g_warning ("Invalid label object type.");
2728 g_warning ("Invalid view state."); /*Should not happen!*/
2734 /*---------------------------------------------------------------------------*/
2735 /* PRIVATE. Canvas event handler (arrow mode) */
2736 /*---------------------------------------------------------------------------*/
2738 canvas_event_arrow_mode (GnomeCanvas *canvas,
2742 static gdouble x0, y0;
2743 static gboolean dragging = FALSE;
2744 static GnomeCanvasItem *item;
2745 gdouble x, y, x1, y1, x2, y2;
2746 GnomeCanvasGroup *group;
2749 gl_debug (DEBUG_VIEW, "");
2751 switch (event->type) {
2753 case GDK_BUTTON_PRESS:
2754 gl_debug (DEBUG_VIEW, "BUTTON_PRESS");
2755 switch (event->button.button) {
2757 gnome_canvas_window_to_world (canvas,
2759 event->button.y, &x, &y);
2761 if (!object_at (view, x, y)) {
2762 if (!(event->button.state & GDK_CONTROL_MASK)) {
2763 gl_view_unselect_all (view);
2767 gnome_canvas_item_grab (canvas->root,
2768 GDK_POINTER_MOTION_MASK |
2769 GDK_BUTTON_RELEASE_MASK |
2770 GDK_BUTTON_PRESS_MASK,
2771 NULL, event->button.time);
2773 gnome_canvas_root (GNOME_CANVAS
2776 gnome_canvas_item_new (group,
2777 gnome_canvas_rect_get_type (),
2781 "outline_color_rgba",
2792 gnome_canvas_window_to_world (canvas,
2794 event->button.y, &x, &y);
2796 if (!object_at (view, x, y)) {
2797 /* bring up apropriate menu for selection. */
2798 gl_view_popup_menu (view, event);
2805 case GDK_BUTTON_RELEASE:
2806 gl_debug (DEBUG_VIEW, "BUTTON_RELEASE");
2807 switch (event->button.button) {
2811 gnome_canvas_item_ungrab (canvas->root,
2812 event->button.time);
2813 gnome_canvas_window_to_world (canvas,
2821 gl_view_select_region (view, x1, y1, x2, y2);
2822 gtk_object_destroy (GTK_OBJECT (item));
2831 case GDK_MOTION_NOTIFY:
2832 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
2833 gnome_canvas_window_to_world (canvas,
2835 event->motion.y, &x, &y);
2836 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
2837 gnome_canvas_item_set (item,
2841 "y2", MAX (y, y0), NULL);
2848 gl_debug (DEBUG_VIEW, "KEY_PRESS");
2850 switch (event->key.keyval) {
2853 gl_view_move_selection (view,
2854 -1.0 / (view->scale), 0.0);
2858 gl_view_move_selection (view,
2859 0.0, -1.0 / (view->scale));
2863 gl_view_move_selection (view,
2864 1.0 / (view->scale), 0.0);
2868 gl_view_move_selection (view,
2869 0.0, 1.0 / (view->scale));
2873 gl_view_delete_selection (view);
2874 cursor = gdk_cursor_new (GDK_LEFT_PTR);
2875 gdk_window_set_cursor (view->canvas->window,
2877 gdk_cursor_unref (cursor);
2883 return TRUE; /* We handled this or we were dragging. */
2886 gl_debug (DEBUG_VIEW, "default");
2892 /*---------------------------------------------------------------------------*/
2893 /* PRIVATE. create menu for selections. */
2894 /*---------------------------------------------------------------------------*/
2896 construct_selection_menu (glView *view)
2898 GtkWidget *menu, *menuitem, *submenu;
2900 gl_debug (DEBUG_VIEW, "START");
2902 g_return_if_fail (GL_IS_VIEW (view));
2904 menu = gtk_menu_new ();
2906 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_PROPERTIES, NULL);
2907 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2908 gtk_widget_show (menuitem);
2909 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2910 G_CALLBACK (gl_view_edit_object_props), view);
2911 view->atomic_selection_items =
2912 g_list_prepend (view->atomic_selection_items, menuitem);
2915 * Separator -------------------------
2917 menuitem = gtk_menu_item_new ();
2918 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2919 gtk_widget_show (menuitem);
2924 menuitem = gtk_menu_item_new_with_mnemonic (_("_Order"));
2925 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2926 gtk_widget_show (menuitem);
2927 submenu = gtk_menu_new ();
2928 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
2930 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ORDER_TOP, NULL);
2931 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2932 gtk_widget_show (menuitem);
2933 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2934 G_CALLBACK (gl_view_raise_selection), view);
2936 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ORDER_BOTTOM, NULL);
2937 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2938 gtk_widget_show (menuitem);
2939 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2940 G_CALLBACK (gl_view_lower_selection), view);
2943 * Submenu: Rotate/Flip
2945 menuitem = gtk_menu_item_new_with_mnemonic (_("_Rotate/Flip"));
2946 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2947 gtk_widget_show (menuitem);
2948 submenu = gtk_menu_new ();
2949 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
2951 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ROTATE_LEFT, NULL);
2952 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2953 gtk_widget_show (menuitem);
2954 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2955 G_CALLBACK (gl_view_rotate_selection_left), view);
2957 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ROTATE_RIGHT, NULL);
2958 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2959 gtk_widget_show (menuitem);
2960 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2961 G_CALLBACK (gl_view_rotate_selection_right), view);
2963 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_FLIP_HORIZ, NULL);
2964 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2965 gtk_widget_show (menuitem);
2966 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2967 G_CALLBACK (gl_view_flip_selection_horiz), view);
2969 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_FLIP_VERT, NULL);
2970 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2971 gtk_widget_show (menuitem);
2972 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2973 G_CALLBACK (gl_view_flip_selection_vert), view);
2976 * Submenu: Align Horizontally
2978 menuitem = gtk_menu_item_new_with_mnemonic (_("Align _Horizontally"));
2979 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
2980 gtk_widget_show (menuitem);
2981 submenu = gtk_menu_new ();
2982 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
2984 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_LEFT, NULL);
2985 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2986 gtk_widget_show (menuitem);
2987 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2988 G_CALLBACK (gl_view_align_selection_left), view);
2989 view->multi_selection_items =
2990 g_list_prepend (view->multi_selection_items, menuitem);
2992 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_HCENTER, NULL);
2993 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
2994 gtk_widget_show (menuitem);
2995 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
2996 G_CALLBACK (gl_view_align_selection_hcenter), view);
2997 view->multi_selection_items =
2998 g_list_prepend (view->multi_selection_items, menuitem);
3000 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_RIGHT, NULL);
3001 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3002 gtk_widget_show (menuitem);
3003 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3004 G_CALLBACK (gl_view_align_selection_right), view);
3005 view->multi_selection_items =
3006 g_list_prepend (view->multi_selection_items, menuitem);
3008 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_CENTER_HORIZ, NULL);
3009 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3010 gtk_widget_show (menuitem);
3011 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3012 G_CALLBACK (gl_view_center_selection_horiz), view);
3015 * Submenu: Align Vertically
3017 menuitem = gtk_menu_item_new_with_mnemonic (_("Align _Vertically"));
3018 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3019 gtk_widget_show (menuitem);
3020 submenu = gtk_menu_new ();
3021 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3023 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_TOP, NULL);
3024 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3025 gtk_widget_show (menuitem);
3026 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3027 G_CALLBACK (gl_view_align_selection_top), view);
3028 view->multi_selection_items =
3029 g_list_prepend (view->multi_selection_items, menuitem);
3031 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_VCENTER, NULL);
3032 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3033 gtk_widget_show (menuitem);
3034 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3035 G_CALLBACK (gl_view_align_selection_vcenter), view);
3036 view->multi_selection_items =
3037 g_list_prepend (view->multi_selection_items, menuitem);
3039 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_ALIGN_BOTTOM, NULL);
3040 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3041 gtk_widget_show (menuitem);
3042 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3043 G_CALLBACK (gl_view_align_selection_bottom), view);
3044 view->multi_selection_items =
3045 g_list_prepend (view->multi_selection_items, menuitem);
3047 menuitem = gtk_image_menu_item_new_from_stock (GL_STOCK_CENTER_VERT, NULL);
3048 gtk_menu_shell_append (GTK_MENU_SHELL (submenu), menuitem);
3049 gtk_widget_show (menuitem);
3050 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3051 G_CALLBACK (gl_view_center_selection_vert), view);
3054 * Separator -------------------------
3056 menuitem = gtk_menu_item_new ();
3057 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3058 gtk_widget_show (menuitem);
3060 menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_CUT, NULL);
3061 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3062 gtk_widget_show (menuitem);
3063 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3064 G_CALLBACK (gl_view_cut), view);
3066 menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_COPY, NULL);
3067 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3068 gtk_widget_show (menuitem);
3069 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3070 G_CALLBACK (gl_view_copy), view);
3072 menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_PASTE, NULL);
3073 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3074 gtk_widget_show (menuitem);
3075 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3076 G_CALLBACK (gl_view_paste), view);
3078 menuitem = gtk_menu_item_new_with_mnemonic (_("_Delete"));
3079 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3080 gtk_widget_show (menuitem);
3081 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3082 G_CALLBACK (gl_view_delete_selection), view);
3085 view->selection_menu = menu;
3087 gl_debug (DEBUG_VIEW, "END");
3090 /*---------------------------------------------------------------------------*/
3091 /* PRIVATE. create menu for empty selections. */
3092 /*---------------------------------------------------------------------------*/
3094 construct_empty_selection_menu (glView *view)
3096 GtkWidget *menu, *menuitem, *submenu;
3098 gl_debug (DEBUG_VIEW, "START");
3100 g_return_if_fail (GL_IS_VIEW (view));
3102 menu = gtk_menu_new ();
3104 menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_PASTE, NULL);
3105 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3106 gtk_widget_show (menuitem);
3107 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
3108 G_CALLBACK (gl_view_paste), view);
3111 view->empty_selection_menu = menu;
3113 gl_debug (DEBUG_VIEW, "END");
3116 /****************************************************************************/
3118 /****************************************************************************/
3120 gl_view_popup_menu (glView *view,
3126 gl_debug (DEBUG_VIEW, "START");
3128 g_return_if_fail (GL_IS_VIEW (view));
3130 if (gl_view_is_selection_empty (view)) {
3132 if (view->empty_selection_menu != NULL) {
3133 gtk_menu_popup (GTK_MENU (view->empty_selection_menu),
3134 NULL, NULL, NULL, NULL,
3135 event->button.button,
3136 event->button.time);
3141 for (p=view->atomic_selection_items; p!=NULL; p=p->next) {
3142 gtk_widget_set_sensitive (GTK_WIDGET(p->data),
3143 gl_view_is_selection_atomic(view));
3146 for (p=view->multi_selection_items; p!=NULL; p=p->next) {
3147 gtk_widget_set_sensitive (GTK_WIDGET(p->data),
3148 !gl_view_is_selection_atomic(view));
3151 if (view->selection_menu != NULL) {
3152 gtk_menu_popup (GTK_MENU (view->selection_menu),
3153 NULL, NULL, NULL, NULL,
3154 event->button.button,
3155 event->button.time);
3160 gl_debug (DEBUG_VIEW, "END");
3163 /*---------------------------------------------------------------------------*/
3164 /* PRIVATE. Handle "selection-clear" signal. */
3165 /*---------------------------------------------------------------------------*/
3167 selection_clear_cb (GtkWidget *widget,
3168 GdkEventSelection *event,
3171 glView *view = GL_VIEW (data);
3173 gl_debug (DEBUG_VIEW, "START");
3175 g_return_if_fail (GL_IS_VIEW (view));
3177 view->have_selection = FALSE;
3178 g_object_unref (view->selection_data);
3179 view->selection_data = NULL;
3181 gl_debug (DEBUG_VIEW, "END");
3184 /*---------------------------------------------------------------------------*/
3185 /* PRIVATE. Handle "selection-get" signal. */
3186 /*---------------------------------------------------------------------------*/
3188 selection_get_cb (GtkWidget *widget,
3189 GtkSelectionData *selection_data,
3194 glView *view = GL_VIEW (data);
3196 glXMLLabelStatus status;
3198 gl_debug (DEBUG_VIEW, "START");
3200 g_return_if_fail (GL_IS_VIEW (view));
3202 if (view->have_selection) {
3204 buffer = gl_xml_label_save_buffer (view->selection_data,
3206 gtk_selection_data_set (selection_data,
3207 GDK_SELECTION_TYPE_STRING, 8, buffer,
3212 gl_debug (DEBUG_VIEW, "END");
3215 /*---------------------------------------------------------------------------*/
3216 /* PRIVATE. Handle "selection-received" signal. (Result of Paste) */
3217 /*---------------------------------------------------------------------------*/
3219 selection_received_cb (GtkWidget *widget,
3220 GtkSelectionData *selection_data,
3224 glView *view = GL_VIEW (data);
3225 glLabel *label = NULL;
3226 glXMLLabelStatus status;
3228 glLabelObject *object, *newobject;
3229 glViewObject *view_object;
3231 gl_debug (DEBUG_VIEW, "START");
3233 g_return_if_fail (GL_IS_VIEW (view));
3235 if (selection_data->length < 0) {
3238 if (selection_data->type != GDK_SELECTION_TYPE_STRING) {
3242 gl_view_unselect_all (view);
3244 label = gl_xml_label_open_buffer (selection_data->data, &status);
3245 for (p = label->objects; p != NULL; p = p_next) {
3248 object = (glLabelObject *) p->data;
3249 gl_label_object_set_parent (object, view->label);
3251 gl_debug (DEBUG_VIEW, "object pasted");
3253 if (GL_IS_LABEL_BOX (object)) {
3254 view_object = gl_view_box_new (GL_LABEL_BOX(object),
3256 } else if (GL_IS_LABEL_ELLIPSE (object)) {
3257 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object),
3259 } else if (GL_IS_LABEL_LINE (object)) {
3260 view_object = gl_view_line_new (GL_LABEL_LINE(object),
3262 } else if (GL_IS_LABEL_IMAGE (object)) {
3263 view_object = gl_view_image_new (GL_LABEL_IMAGE(object),
3265 } else if (GL_IS_LABEL_TEXT (object)) {
3266 view_object = gl_view_text_new (GL_LABEL_TEXT(object),
3268 } else if (GL_IS_LABEL_BARCODE (object)) {
3269 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(object),
3272 /* Should not happen! */
3274 g_warning ("Invalid label object type.");
3276 gl_view_select_object (view, view_object);
3278 g_object_unref (label);
3280 gl_debug (DEBUG_VIEW, "END");