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 SEL_LINE_COLOR GL_COLOR_A (0, 0, 255, 128)
50 #define SEL_FILL_COLOR GL_COLOR_A (192, 192, 255, 128)
52 /*========================================================*/
54 /*========================================================*/
61 /*===========================================*/
63 /*===========================================*/
65 static GtkContainerClass *parent_class;
67 static guint signals[LAST_SIGNAL] = {0};
69 /* "CLIPBOARD" selection */
70 static GdkAtom clipboard_atom = GDK_NONE;
72 #define HOME_SCALE 2.0
73 static gdouble scales[] = {
80 /*===========================================*/
81 /* Local function prototypes */
82 /*===========================================*/
84 static void gl_view_class_init (glViewClass *class);
85 static void gl_view_init (glView *view);
86 static void gl_view_finalize (GObject *object);
88 static void gl_view_construct (glView *view);
89 static GtkWidget *gl_view_construct_canvas (glView *view);
90 static void gl_view_construct_selection (glView *view);
92 static gdouble get_apropriate_scale (gdouble w, gdouble h);
94 static void draw_rect_bg_fg (glView *view);
95 static void draw_rounded_rect_bg_fg (glView *view);
96 static void draw_round_bg_fg (glView *view);
97 static void draw_cd_bg_fg (glView *view);
99 static void select_object_real (glView *view,
100 glViewObject *view_object);
101 static void unselect_object_real (glView *view,
102 glViewObject *view_object);
104 static gboolean object_at (glView *view,
105 gdouble x, gdouble y);
106 static gboolean is_object_selected (glView *view,
107 glViewObject *view_object);
109 static void move_selection (glView *view,
110 gdouble dx, gdouble dy);
112 static int canvas_event (GnomeCanvas *canvas,
115 static int canvas_event_arrow_mode (GnomeCanvas *canvas,
119 static int item_event_arrow_mode (GnomeCanvasItem *item,
121 glViewObject *view_object);
123 static GtkWidget *new_selection_menu (glView *view);
125 static void popup_selection_menu (glView *view,
126 glViewObject *view_object,
129 static void selection_clear_cb (GtkWidget *widget,
130 GdkEventSelection *event,
133 static void selection_get_cb (GtkWidget *widget,
134 GtkSelectionData *selection_data,
139 static void selection_received_cb (GtkWidget *widget,
140 GtkSelectionData *selection_data,
144 /****************************************************************************/
145 /* Boilerplate Object stuff. */
146 /****************************************************************************/
148 gl_view_get_type (void)
150 static guint view_type = 0;
153 GTypeInfo view_info = {
154 sizeof (glViewClass),
157 (GClassInitFunc) gl_view_class_init,
162 (GInstanceInitFunc) gl_view_init,
166 g_type_register_static (gtk_vbox_get_type (),
167 "glView", &view_info, 0);
174 gl_view_class_init (glViewClass *class)
176 GObjectClass *object_class = (GObjectClass *) class;
178 gl_debug (DEBUG_VIEW, "START");
180 parent_class = g_type_class_peek_parent (class);
182 object_class->finalize = gl_view_finalize;
184 signals[SELECTION_CHANGED] =
185 g_signal_new ("selection_changed",
186 G_OBJECT_CLASS_TYPE (object_class),
188 G_STRUCT_OFFSET (glViewClass, selection_changed),
190 gl_marshal_VOID__VOID,
194 gl_debug (DEBUG_VIEW, "END");
198 gl_view_init (glView *view)
200 gl_debug (DEBUG_VIEW, "START");
204 gl_debug (DEBUG_VIEW, "END");
208 gl_view_finalize (GObject *object)
212 gl_debug (DEBUG_VIEW, "START");
214 g_return_if_fail (object != NULL);
215 g_return_if_fail (GL_IS_VIEW (object));
217 view = GL_VIEW (object);
219 G_OBJECT_CLASS (parent_class)->finalize (object);
221 gl_debug (DEBUG_VIEW, "END");
224 /****************************************************************************/
225 /* NEW view object. */
226 /****************************************************************************/
228 gl_view_new (glLabel *label)
230 glView *view = g_object_new (gl_view_get_type (), NULL);
232 gl_debug (DEBUG_VIEW, "START");
236 gl_view_construct (view);
238 gl_debug (DEBUG_VIEW, "END");
240 return GTK_WIDGET (view);
243 /*---------------------------------------------------------------------------*/
244 /* PRIVATE. Construct composite widget. */
245 /*---------------------------------------------------------------------------*/
247 gl_view_construct (glView *view)
249 GtkWidget *wvbox, *wscroll;
251 gl_debug (DEBUG_VIEW, "START");
253 g_return_if_fail (GL_IS_VIEW (view));
255 wvbox = GTK_WIDGET (view);
257 view->state = GL_VIEW_STATE_ARROW;
258 view->object_list = NULL;
260 gl_view_construct_canvas (view);
261 wscroll = gtk_scrolled_window_new (NULL, NULL);
262 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (wscroll),
263 GTK_POLICY_AUTOMATIC,
264 GTK_POLICY_AUTOMATIC);
265 gtk_box_pack_start (GTK_BOX (wvbox), wscroll, TRUE, TRUE, 0);
266 gtk_container_add (GTK_CONTAINER (wscroll), view->canvas);
268 gl_view_construct_selection (view);
270 view->menu = new_selection_menu (view);
272 gl_debug (DEBUG_VIEW, "END");
275 /*---------------------------------------------------------------------------*/
276 /* PRIVATE. Create canvas w/ a background in the shape of the label/card. */
277 /*---------------------------------------------------------------------------*/
279 gl_view_construct_canvas (glView *view)
282 glLabel *label = view->label;
283 gdouble label_width, label_height;
284 glTemplate *label_template;
286 glLabelObject *object;
287 glViewObject *view_object;
289 gl_debug (DEBUG_VIEW, "START");
291 g_return_val_if_fail (GL_IS_VIEW (view), NULL);
292 g_return_val_if_fail (label != NULL, NULL);
294 gtk_widget_push_colormap (gdk_rgb_get_colormap ());
295 view->canvas = gnome_canvas_new_aa ();
296 gtk_widget_pop_colormap ();
298 gl_label_get_size (label, &label_width, &label_height);
299 gl_debug (DEBUG_VIEW, "Label size: w=%lf, h=%lf",
300 label_width, label_height);
301 label_template = gl_label_get_template (label);
303 scale = get_apropriate_scale (label_width, label_height);
304 gl_debug (DEBUG_VIEW, "scale =%lf", scale);
306 gl_debug (DEBUG_VIEW, "Canvas size: w=%lf, h=%lf",
307 scale * label_width + 40,
308 scale * label_height + 40);
309 gtk_widget_set_size_request (GTK_WIDGET(view->canvas),
310 scale * label_width + 40,
311 scale * label_height + 40);
312 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
316 gnome_canvas_set_scroll_region (GNOME_CANVAS (view->canvas),
317 0.0, 0.0, label_width, label_height);
319 /* Draw background shape of label/card */
320 switch (label_template->style) {
322 case GL_TEMPLATE_STYLE_RECT:
323 if (label_template->label_round == 0.0) {
324 /* Square corners. */
325 draw_rect_bg_fg (view);
327 /* Rounded corners. */
328 draw_rounded_rect_bg_fg (view);
332 case GL_TEMPLATE_STYLE_ROUND:
333 draw_round_bg_fg (view);
336 case GL_TEMPLATE_STYLE_CD:
337 draw_cd_bg_fg (view);
341 g_warning ("Unknown template label style");
344 gl_debug (DEBUG_VIEW, "n_bg_items = %d, n_fg_items = %d",
345 view->n_bg_items, view->n_fg_items);
347 g_signal_connect (G_OBJECT (view->canvas), "event",
348 G_CALLBACK (canvas_event), view);
350 for (p_obj = label->objects; p_obj != NULL; p_obj = p_obj->next) {
351 object = (glLabelObject *) p_obj->data;
353 if (GL_IS_LABEL_BOX (object)) {
354 view_object = gl_view_box_new (GL_LABEL_BOX(object),
356 } else if (GL_IS_LABEL_ELLIPSE (object)) {
357 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object),
359 } else if (GL_IS_LABEL_LINE (object)) {
360 view_object = gl_view_line_new (GL_LABEL_LINE(object),
362 } else if (GL_IS_LABEL_IMAGE (object)) {
363 view_object = gl_view_image_new (GL_LABEL_IMAGE(object),
365 } else if (GL_IS_LABEL_TEXT (object)) {
366 view_object = gl_view_text_new (GL_LABEL_TEXT(object),
368 } else if (GL_IS_LABEL_BARCODE (object)) {
369 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(object),
372 /* Should not happen! */
374 g_warning ("Invalid label object type.");
378 gl_debug (DEBUG_VIEW, "END");
383 /*---------------------------------------------------------------------------*/
384 /* PRIVATE. Create clipboard selection targets. */
385 /*---------------------------------------------------------------------------*/
387 gl_view_construct_selection (glView *view)
389 gl_debug (DEBUG_VIEW, "START");
391 g_return_if_fail (GL_IS_VIEW (view));
393 view->have_selection = FALSE;
394 view->selection_data = NULL;
395 view->invisible = gtk_invisible_new ();
397 view->selected_object_list = NULL;
399 if (!clipboard_atom) {
400 clipboard_atom = gdk_atom_intern ("GLABELS_CLIPBOARD", FALSE);
403 gtk_selection_add_target (view->invisible,
404 clipboard_atom, GDK_SELECTION_TYPE_STRING, 1);
406 g_signal_connect (G_OBJECT (view->invisible),
407 "selection_clear_event",
408 G_CALLBACK (selection_clear_cb), view);
410 g_signal_connect (G_OBJECT (view->invisible), "selection_get",
411 G_CALLBACK (selection_get_cb), view);
413 g_signal_connect (G_OBJECT (view->invisible),
414 "selection_received",
415 G_CALLBACK (selection_received_cb), view);
417 gl_debug (DEBUG_VIEW, "END");
420 /*---------------------------------------------------------------------------*/
421 /* PRIVATE. Determine an apropriate scale for given label & screen size */
422 /*---------------------------------------------------------------------------*/
424 get_apropriate_scale (gdouble w, gdouble h)
426 gdouble w_screen, h_screen;
430 gl_debug (DEBUG_VIEW, "");
432 w_screen = (gdouble) gdk_screen_width ();
433 h_screen = (gdouble) gdk_screen_height ();
435 for (i = 0; scales[i] > 0.0; i++) {
437 if (k <= HOME_SCALE) {
438 if ((k * w < (w_screen - 256))
439 && (k * h < (h_screen - 256)))
447 /*---------------------------------------------------------------------------*/
448 /* PRIVATE. Draw simple recangular background. */
449 /*---------------------------------------------------------------------------*/
451 draw_rect_bg_fg (glView *view)
453 glLabel *label = view->label;
454 glTemplate *template;
455 gdouble w, h, margin;
456 GnomeCanvasItem *item;
457 GnomeCanvasGroup *group;
459 gl_debug (DEBUG_VIEW, "START");
461 g_return_if_fail (GL_IS_VIEW (view));
462 g_return_if_fail (label != NULL);
464 gl_label_get_size (label, &w, &h);
465 template = gl_label_get_template (label);
466 margin = template->label_margin;
468 view->n_bg_items = 0;
469 view->bg_item_list = NULL;
470 view->n_fg_items = 0;
471 view->fg_item_list = NULL;
473 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
475 item = gnome_canvas_item_new (group,
476 gnome_canvas_rect_get_type (),
481 "fill_color", "white",
484 view->bg_item_list = g_list_append (view->bg_item_list, item);
486 /* Bounding box @ margin */
487 gnome_canvas_item_new (group,
488 gnome_canvas_rect_get_type (),
494 "outline_color", "light blue",
497 view->bg_item_list = g_list_append (view->bg_item_list, item);
499 item = gnome_canvas_item_new (group,
500 gnome_canvas_rect_get_type (),
506 "outline_color", "light blue",
509 view->fg_item_list = g_list_append (view->fg_item_list, item);
511 gl_debug (DEBUG_VIEW, "END");
514 /*---------------------------------------------------------------------------*/
515 /* PRIVATE. Draw rounded recangular background. */
516 /*---------------------------------------------------------------------------*/
518 draw_rounded_rect_bg_fg (glView *view)
520 glLabel *label = view->label;
521 GnomeCanvasPoints *label_points, *margin_points;
522 gint i_coords, i_theta;
523 glTemplate *template;
525 GnomeCanvasItem *item;
526 GnomeCanvasGroup *group;
528 gl_debug (DEBUG_VIEW, "START");
530 g_return_if_fail (GL_IS_VIEW (view));
531 g_return_if_fail (label != NULL);
533 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
535 view->n_bg_items = 0;
536 view->bg_item_list = NULL;
537 view->n_fg_items = 0;
538 view->fg_item_list = NULL;
540 gl_label_get_size (label, &w, &h);
541 template = gl_label_get_template (label);
542 r = template->label_round;
543 m = template->label_margin;
545 label_points = gnome_canvas_points_new (4 * (1 + 90 / 5));
547 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
548 label_points->coords[i_coords++] =
549 r - r * sin (i_theta * M_PI / 180.0);
550 label_points->coords[i_coords++] =
551 r - r * cos (i_theta * M_PI / 180.0);
553 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
554 label_points->coords[i_coords++] =
555 r - r * cos (i_theta * M_PI / 180.0);
556 label_points->coords[i_coords++] =
557 (h - r) + r * sin (i_theta * M_PI / 180.0);
559 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
560 label_points->coords[i_coords++] =
561 (w - r) + r * sin (i_theta * M_PI / 180.0);
562 label_points->coords[i_coords++] =
563 (h - r) + r * cos (i_theta * M_PI / 180.0);
565 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
566 label_points->coords[i_coords++] =
567 (w - r) + r * cos (i_theta * M_PI / 180.0);
568 label_points->coords[i_coords++] =
569 r - r * sin (i_theta * M_PI / 180.0);
572 /* Basic background */
573 item = gnome_canvas_item_new (group,
574 gnome_canvas_polygon_get_type (),
575 "points", label_points,
576 "fill_color", "white",
579 view->bg_item_list = g_list_append (view->bg_item_list, item);
582 if (template->label_margin >= template->label_round) {
583 /* simple rectangle */
584 item = gnome_canvas_item_new (group,
585 gnome_canvas_rect_get_type (),
591 "outline_color", "light blue",
595 g_list_append (view->bg_item_list, item);
601 /* rectangle with rounded corners */
602 margin_points = gnome_canvas_points_new (4 * (1 + 90 / 5));
604 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
605 margin_points->coords[i_coords++] =
606 m + r - r * sin (i_theta * M_PI / 180.0);
607 margin_points->coords[i_coords++] =
608 m + r - r * cos (i_theta * M_PI / 180.0);
610 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
611 margin_points->coords[i_coords++] =
612 m + r - r * cos (i_theta * M_PI / 180.0);
613 margin_points->coords[i_coords++] =
614 m + (h - r) + r * sin (i_theta * M_PI / 180.0);
616 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
617 margin_points->coords[i_coords++] =
618 m + (w - r) + r * sin (i_theta * M_PI / 180.0);
619 margin_points->coords[i_coords++] =
620 m + (h - r) + r * cos (i_theta * M_PI / 180.0);
622 for (i_theta = 0; i_theta <= 90; i_theta += 5) {
623 margin_points->coords[i_coords++] =
624 m + (w - r) + r * cos (i_theta * M_PI / 180.0);
625 margin_points->coords[i_coords++] =
626 m + r - r * sin (i_theta * M_PI / 180.0);
628 item = gnome_canvas_item_new (group,
629 gnome_canvas_polygon_get_type (),
630 "points", margin_points,
632 "outline_color", "light blue",
634 gnome_canvas_points_free (margin_points);
637 g_list_append (view->bg_item_list, item);
640 /* Foreground outline */
641 item = gnome_canvas_item_new (group,
642 gnome_canvas_polygon_get_type (),
643 "points", label_points,
645 "outline_color", "light blue",
648 view->fg_item_list = g_list_append (view->fg_item_list, item);
650 gnome_canvas_points_free (label_points);
652 gl_debug (DEBUG_VIEW, "END");
655 /*---------------------------------------------------------------------------*/
656 /* PRIVATE. Draw round background. */
657 /*---------------------------------------------------------------------------*/
659 draw_round_bg_fg (glView *view)
661 glLabel *label = view->label;
662 glTemplate *template;
664 GnomeCanvasItem *item;
665 GnomeCanvasGroup *group;
667 gl_debug (DEBUG_VIEW, "START");
669 g_return_if_fail (GL_IS_VIEW (view));
670 g_return_if_fail (label != NULL);
672 template = gl_label_get_template (label);
674 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
676 view->n_bg_items = 0;
677 view->bg_item_list = NULL;
678 view->n_fg_items = 0;
679 view->fg_item_list = NULL;
681 r = template->label_radius;
682 m = template->label_margin;
684 /* Basic background */
685 item = gnome_canvas_item_new (group,
686 gnome_canvas_ellipse_get_type (),
691 "fill_color", "white",
694 view->bg_item_list = g_list_append (view->bg_item_list, item);
697 item = gnome_canvas_item_new (group,
698 gnome_canvas_ellipse_get_type (),
704 "outline_color", "light blue", NULL);
706 view->bg_item_list = g_list_append (view->bg_item_list, item);
708 /* Foreground outline */
709 r = template->label_radius;
710 item = gnome_canvas_item_new (group,
711 gnome_canvas_ellipse_get_type (),
717 "outline_color", "light blue",
720 view->fg_item_list = g_list_append (view->fg_item_list, item);
722 gl_debug (DEBUG_VIEW, "END");
725 /*---------------------------------------------------------------------------*/
726 /* PRIVATE. Draw CD style background, circular w/ concentric hole. */
727 /*---------------------------------------------------------------------------*/
729 draw_cd_bg_fg (glView *view)
731 glLabel *label = view->label;
732 glTemplate *template;
734 GnomeCanvasItem *item;
735 GnomeCanvasGroup *group;
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 group = gnome_canvas_root (GNOME_CANVAS (view->canvas));
746 view->n_bg_items = 0;
747 view->bg_item_list = NULL;
748 view->n_fg_items = 0;
749 view->fg_item_list = NULL;
751 r1 = template->label_radius;
752 r2 = template->label_hole;
753 m = template->label_margin;
755 /* Basic background */
757 item = gnome_canvas_item_new (group,
758 gnome_canvas_ellipse_get_type (),
763 "fill_color", "white",
766 view->bg_item_list = g_list_append (view->bg_item_list, item);
768 item = gnome_canvas_item_new (group,
769 gnome_canvas_ellipse_get_type (),
774 "fill_color", "gray",
777 view->bg_item_list = g_list_append (view->bg_item_list, item);
781 item = gnome_canvas_item_new (group,
782 gnome_canvas_ellipse_get_type (),
788 "outline_color", "light blue", NULL);
790 view->bg_item_list = g_list_append (view->bg_item_list, item);
792 item = gnome_canvas_item_new (group,
793 gnome_canvas_ellipse_get_type (),
799 "outline_color", "light blue",
802 view->bg_item_list = g_list_append (view->bg_item_list, item);
804 /* Foreground outline */
806 item = gnome_canvas_item_new (group,
807 gnome_canvas_ellipse_get_type (),
813 "outline_color", "light blue",
816 view->fg_item_list = g_list_append (view->fg_item_list, item);
818 item = gnome_canvas_item_new (group,
819 gnome_canvas_ellipse_get_type (),
825 "outline_color", "light blue",
828 view->fg_item_list = g_list_append (view->fg_item_list, item);
830 gl_debug (DEBUG_VIEW, "END");
833 /*****************************************************************************/
834 /* Raise foreground items to top. */
835 /*****************************************************************************/
836 void gl_view_raise_fg (glView *view)
840 for (p = view->fg_item_list; p != NULL; p = p->next) {
841 gnome_canvas_item_raise_to_top (GNOME_CANVAS_ITEM(p->data));
845 /*****************************************************************************/
846 /* Set arrow mode. */
847 /*****************************************************************************/
849 gl_view_arrow_mode (glView *view)
851 static GdkCursor *cursor = NULL;
853 gl_debug (DEBUG_VIEW, "START");
855 g_return_if_fail (GL_IS_VIEW (view));
858 cursor = gdk_cursor_new (GDK_LEFT_PTR);
861 gdk_window_set_cursor (view->canvas->window, cursor);
863 view->state = GL_VIEW_STATE_ARROW;
865 gl_debug (DEBUG_VIEW, "END");
868 /*****************************************************************************/
869 /* Set create text object mode. */
870 /*****************************************************************************/
872 gl_view_object_create_mode (glView *view,
873 glLabelObjectType type)
877 gl_debug (DEBUG_VIEW, "START");
879 g_return_if_fail (GL_IS_VIEW (view));
882 case GL_LABEL_OBJECT_BOX:
883 cursor = gl_view_box_get_create_cursor ();
885 case GL_LABEL_OBJECT_ELLIPSE:
886 cursor = gl_view_ellipse_get_create_cursor ();
888 case GL_LABEL_OBJECT_LINE:
889 cursor = gl_view_line_get_create_cursor ();
891 case GL_LABEL_OBJECT_IMAGE:
892 cursor = gl_view_image_get_create_cursor ();
894 case GL_LABEL_OBJECT_TEXT:
895 cursor = gl_view_text_get_create_cursor ();
897 case GL_LABEL_OBJECT_BARCODE:
898 cursor = gl_view_barcode_get_create_cursor ();
901 g_warning ("Invalid label object type.");/*Should not happen!*/
905 gdk_window_set_cursor (view->canvas->window, cursor);
907 view->state = GL_VIEW_STATE_OBJECT_CREATE;
908 view->create_type = type;
910 gl_debug (DEBUG_VIEW, "END");
913 /*****************************************************************************/
914 /* Select given object (adding to current selection). */
915 /*****************************************************************************/
917 gl_view_select_object (glView *view,
918 glViewObject *view_object)
920 gl_debug (DEBUG_VIEW, "START");
922 select_object_real (view, view_object);
924 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
926 gl_debug (DEBUG_VIEW, "END");
929 /*****************************************************************************/
930 /* Unselect given object (removing from current selection). */
931 /*****************************************************************************/
933 gl_view_unselect_object (glView *view,
934 glViewObject *view_object)
936 gl_debug (DEBUG_VIEW, "START");
938 unselect_object_real (view, view_object);
940 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
942 gl_debug (DEBUG_VIEW, "END");
945 /*****************************************************************************/
946 /* Select all items. */
947 /*****************************************************************************/
949 gl_view_select_all (glView *view)
953 gl_debug (DEBUG_VIEW, "START");
955 g_return_if_fail (GL_IS_VIEW (view));
957 /* 1st unselect anything already selected. */
958 for (p = view->selected_object_list; p != NULL; p = p_next) {
960 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
963 /* Finally select all objects. */
964 for (p = view->object_list; p != NULL; p = p->next) {
965 select_object_real (view, GL_VIEW_OBJECT (p->data));
968 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
970 gl_debug (DEBUG_VIEW, "END");
973 /*****************************************************************************/
974 /* Remove all selections */
975 /*****************************************************************************/
977 gl_view_unselect_all (glView *view)
981 gl_debug (DEBUG_VIEW, "START");
983 g_return_if_fail (GL_IS_VIEW (view));
985 for (p = view->selected_object_list; p != NULL; p = p_next) {
987 unselect_object_real (view, GL_VIEW_OBJECT (p->data));
990 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
992 gl_debug (DEBUG_VIEW, "END");
995 /*****************************************************************************/
996 /* Select all objects within given rectangular region (adding to selection). */
997 /*****************************************************************************/
999 gl_view_select_region (glView *view,
1006 glViewObject *view_object;
1007 glLabelObject *object;
1008 gdouble i_x1, i_y1, i_x2, i_y2, w, h;
1010 gl_debug (DEBUG_VIEW, "START");
1012 g_return_if_fail (GL_IS_VIEW (view));
1013 g_return_if_fail ((x1 <= x2) && (y1 <= y2));
1015 for (p = view->object_list; p != NULL; p = p->next) {
1016 view_object = GL_VIEW_OBJECT(p->data);
1017 if (!is_object_selected (view, view_object)) {
1019 object = gl_view_object_get_object (view_object);
1021 gl_label_object_get_position (object, &i_x1, &i_y1);
1022 gl_label_object_get_size (object, &w, &h);
1025 if ((i_x1 >= x1) && (i_x2 <= x2) && (i_y1 >= y1)
1027 select_object_real (view, view_object);
1033 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1035 gl_debug (DEBUG_VIEW, "END");
1038 /*---------------------------------------------------------------------------*/
1039 /* PRIVATE. Select an object. */
1040 /*---------------------------------------------------------------------------*/
1042 select_object_real (glView *view,
1043 glViewObject *view_object)
1045 gl_debug (DEBUG_VIEW, "START");
1047 g_return_if_fail (GL_IS_VIEW (view));
1048 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1050 if (!is_object_selected (view, view_object)) {
1051 view->selected_object_list =
1052 g_list_prepend (view->selected_object_list, view_object);
1054 gl_view_object_show_highlight (view_object);
1055 gtk_widget_grab_focus (GTK_WIDGET (view->canvas));
1057 gl_debug (DEBUG_VIEW, "END");
1060 /*---------------------------------------------------------------------------*/
1061 /* PRIVATE. Un-select object. */
1062 /*---------------------------------------------------------------------------*/
1064 unselect_object_real (glView *view,
1065 glViewObject *view_object)
1067 gl_debug (DEBUG_VIEW, "START");
1069 g_return_if_fail (GL_IS_VIEW (view));
1070 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1072 gl_view_object_hide_highlight (view_object);
1074 view->selected_object_list =
1075 g_list_remove (view->selected_object_list, view_object);
1077 gl_debug (DEBUG_VIEW, "END");
1080 /*---------------------------------------------------------------------------*/
1081 /* PRIVATE. Return object at (x,y). */
1082 /*---------------------------------------------------------------------------*/
1084 object_at (glView *view,
1088 GnomeCanvasItem *item, *p_item;
1091 gl_debug (DEBUG_VIEW, "");
1093 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1095 item = gnome_canvas_get_item_at (GNOME_CANVAS (view->canvas), x, y);
1097 /* No item is at x, y */
1101 /* ignore our background items */
1102 if (g_list_find (view->bg_item_list, item) != NULL)
1108 /*---------------------------------------------------------------------------*/
1109 /* PRIVATE. Is the object in our current selection? */
1110 /*---------------------------------------------------------------------------*/
1112 is_object_selected (glView *view,
1113 glViewObject *view_object)
1115 gl_debug (DEBUG_VIEW, "");
1117 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1118 g_return_val_if_fail (GL_IS_VIEW_OBJECT (view_object), FALSE);
1120 if (g_list_find (view->selected_object_list, view_object) == NULL) {
1126 /*****************************************************************************/
1127 /* Is our current selection empty? */
1128 /*****************************************************************************/
1130 gl_view_is_selection_empty (glView *view)
1132 gl_debug (DEBUG_VIEW, "");
1134 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1136 if (view->selected_object_list == NULL) {
1143 /*****************************************************************************/
1144 /* Is our current selection atomic? I.e. only one item selected. */
1145 /*****************************************************************************/
1147 gl_view_is_selection_atomic (glView *view)
1149 gl_debug (DEBUG_VIEW, "");
1151 g_return_val_if_fail (GL_IS_VIEW (view), FALSE);
1153 if (view->selected_object_list == NULL)
1155 if (view->selected_object_list->next == NULL)
1160 /*****************************************************************************/
1161 /* Delete selected objects. (Bypass clipboard) */
1162 /*****************************************************************************/
1164 gl_view_delete_selection (glView *view)
1168 gl_debug (DEBUG_VIEW, "START");
1170 g_return_if_fail (GL_IS_VIEW (view));
1172 for (p = view->selected_object_list; p != NULL; p = p_next) {
1174 g_object_unref (G_OBJECT (p->data));
1177 g_signal_emit (G_OBJECT(view), signals[SELECTION_CHANGED], 0);
1179 gl_debug (DEBUG_VIEW, "END");
1182 /*****************************************************************************/
1183 /* Edit properties of selected object. */
1184 /*****************************************************************************/
1186 gl_view_edit_object_props (glView *view)
1188 glViewObject *view_object;
1190 gl_debug (DEBUG_VIEW, "START");
1192 g_return_if_fail (GL_IS_VIEW (view));
1194 if (gl_view_is_selection_atomic (view)) {
1196 view_object = GL_VIEW_OBJECT(view->selected_object_list->data);
1197 gl_view_object_show_dialog (view_object);
1201 gl_debug (DEBUG_VIEW, "END");
1204 /*****************************************************************************/
1205 /* Raise selected items to top. */
1206 /*****************************************************************************/
1208 gl_view_raise_selection (glView *view)
1211 glViewObject *view_object;
1212 glLabelObject *label_object;
1214 gl_debug (DEBUG_VIEW, "START");
1216 g_return_if_fail (GL_IS_VIEW (view));
1218 for (p = view->selected_object_list; p != NULL; p = p->next) {
1219 view_object = GL_VIEW_OBJECT (p->data);
1220 label_object = gl_view_object_get_object (view_object);
1221 gl_label_object_raise_to_top (label_object);
1224 gl_debug (DEBUG_VIEW, "END");
1227 /*****************************************************************************/
1228 /* Lower selected items to bottom. */
1229 /*****************************************************************************/
1231 gl_view_lower_selection (glView *view)
1234 glViewObject *view_object;
1235 glLabelObject *label_object;
1237 gl_debug (DEBUG_VIEW, "START");
1239 g_return_if_fail (GL_IS_VIEW (view));
1241 for (p = view->selected_object_list; p != NULL; p = p->next) {
1242 view_object = GL_VIEW_OBJECT (p->data);
1243 label_object = gl_view_object_get_object (view_object);
1244 gl_label_object_lower_to_bottom (label_object);
1247 gl_debug (DEBUG_VIEW, "END");
1250 /*****************************************************************************/
1251 /* "Cut" selected items and place in clipboard selections. */
1252 /*****************************************************************************/
1254 gl_view_cut (glView *view)
1256 gl_debug (DEBUG_VIEW, "START");
1258 g_return_if_fail (GL_IS_VIEW (view));
1260 gl_view_copy (view);
1261 gl_view_delete_selection (view);
1263 gl_debug (DEBUG_VIEW, "END");
1266 /*****************************************************************************/
1267 /* "Copy" selected items to clipboard selections. */
1268 /*****************************************************************************/
1270 gl_view_copy (glView *view)
1273 glViewObject *view_object;
1274 glLabelObject *object;
1275 glTemplate *template;
1276 gboolean rotate_flag;
1278 gl_debug (DEBUG_VIEW, "START");
1280 g_return_if_fail (GL_IS_VIEW (view));
1282 if (view->selected_object_list) {
1284 if ( view->selection_data ) {
1285 g_object_unref (view->selection_data);
1287 template = gl_label_get_template (view->label);
1288 rotate_flag = gl_label_get_rotate_flag (view->label);
1289 view->selection_data = GL_LABEL(gl_label_new ());
1290 gl_label_set_template (view->selection_data, template);
1291 gl_label_set_rotate_flag (view->selection_data, rotate_flag);
1292 gl_template_free (&template);
1294 for (p = view->selected_object_list; p != NULL; p = p->next) {
1296 view_object = GL_VIEW_OBJECT (p->data);
1297 object = gl_view_object_get_object (view_object);
1299 gl_debug (DEBUG_VIEW, "Object copied");
1301 if (GL_IS_LABEL_BOX (object)) {
1302 gl_label_box_dup (GL_LABEL_BOX(object),
1303 view->selection_data);
1304 } else if (GL_IS_LABEL_ELLIPSE (object)) {
1305 gl_label_ellipse_dup (GL_LABEL_ELLIPSE(object),
1306 view->selection_data);
1307 } else if (GL_IS_LABEL_LINE (object)) {
1308 gl_label_line_dup (GL_LABEL_LINE(object),
1309 view->selection_data);
1310 } else if (GL_IS_LABEL_IMAGE (object)) {
1311 gl_label_image_dup (GL_LABEL_IMAGE(object),
1312 view->selection_data);
1313 } else if (GL_IS_LABEL_TEXT (object)) {
1314 gl_label_text_dup (GL_LABEL_TEXT(object),
1315 view->selection_data);
1316 } else if (GL_IS_LABEL_BARCODE (object)) {
1317 gl_label_barcode_dup (GL_LABEL_BARCODE(object),
1318 view->selection_data);
1320 /* Should not happen! */
1321 g_warning ("Invalid label object type.");
1327 gtk_selection_owner_set (view->invisible,
1328 clipboard_atom, GDK_CURRENT_TIME);
1329 view->have_selection = TRUE;
1333 gl_debug (DEBUG_VIEW, "END");
1336 /*****************************************************************************/
1337 /* "Paste" from private clipboard selection. */
1338 /*****************************************************************************/
1340 gl_view_paste (glView *view)
1342 gl_debug (DEBUG_VIEW, "START");
1344 g_return_if_fail (GL_IS_VIEW (view));
1346 gtk_selection_convert (GTK_WIDGET (view->invisible),
1347 clipboard_atom, GDK_SELECTION_TYPE_STRING,
1350 gl_debug (DEBUG_VIEW, "END");
1353 /*---------------------------------------------------------------------------*/
1354 /* PRIVATE. move selected objects */
1355 /*---------------------------------------------------------------------------*/
1357 move_selection (glView *view,
1362 glLabelObject *object;
1364 gl_debug (DEBUG_VIEW, "START");
1366 g_return_if_fail (GL_IS_VIEW (view));
1368 for (p = view->selected_object_list; p != NULL; p = p->next) {
1370 object = gl_view_object_get_object(GL_VIEW_OBJECT (p->data));
1371 gl_label_object_set_position_relative (object, dx, dy);
1375 gl_debug (DEBUG_VIEW, "END");
1378 /*****************************************************************************/
1379 /* Zoom in one "notch" */
1380 /*****************************************************************************/
1382 gl_view_zoom_in (glView *view)
1385 gdouble dist, dist_min;
1387 gl_debug (DEBUG_VIEW, "START");
1389 g_return_if_fail (GL_IS_VIEW (view));
1391 /* Find index of current scale (or best match) */
1392 i_min = 1; /* start with 2nd largest scale */
1393 dist_min = fabs (scales[1] - view->scale);
1394 for (i = 2; scales[i] != 0.0; i++) {
1395 dist = fabs (scales[i] - view->scale);
1396 if (dist < dist_min) {
1402 /* zoom in one "notch" */
1403 i = MAX (0, i_min - 1);
1404 gl_view_set_zoom (view, scales[i] / HOME_SCALE);
1406 gl_debug (DEBUG_VIEW, "END");
1409 /*****************************************************************************/
1410 /* Zoom out one "notch" */
1411 /*****************************************************************************/
1413 gl_view_zoom_out (glView *view)
1416 gdouble dist, dist_min;
1418 gl_debug (DEBUG_VIEW, "START");
1420 g_return_if_fail (GL_IS_VIEW (view));
1422 /* Find index of current scale (or best match) */
1423 i_min = 0; /* start with largest scale */
1424 dist_min = fabs (scales[0] - view->scale);
1425 for (i = 1; scales[i] != 0.0; i++) {
1426 dist = fabs (scales[i] - view->scale);
1427 if (dist < dist_min) {
1433 /* zoom out one "notch" */
1434 if (scales[i_min] == 0.0)
1437 if (scales[i] == 0.0)
1439 gl_view_set_zoom (view, scales[i] / HOME_SCALE);
1441 gl_debug (DEBUG_VIEW, "END");
1444 /*****************************************************************************/
1445 /* Set current zoom factor to explicit value. */
1446 /*****************************************************************************/
1448 gl_view_set_zoom (glView *view,
1451 gl_debug (DEBUG_VIEW, "START");
1453 g_return_if_fail (GL_IS_VIEW (view));
1454 g_return_if_fail (scale > 0.0);
1456 view->scale = scale * HOME_SCALE;
1457 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (view->canvas),
1458 scale * HOME_SCALE);
1460 gl_debug (DEBUG_VIEW, "END");
1463 /*****************************************************************************/
1464 /* Get current zoom factor. */
1465 /*****************************************************************************/
1467 gl_view_get_zoom (glView *view)
1469 gl_debug (DEBUG_VIEW, "");
1471 g_return_val_if_fail (GL_IS_VIEW (view), 1.0);
1473 return view->scale / HOME_SCALE;
1476 /*---------------------------------------------------------------------------*/
1477 /* PRIVATE. Canvas event handler. */
1478 /*---------------------------------------------------------------------------*/
1480 canvas_event (GnomeCanvas *canvas,
1484 gl_debug (DEBUG_VIEW, "");
1486 switch (view->state) {
1488 case GL_VIEW_STATE_ARROW:
1489 return canvas_event_arrow_mode (canvas, event, view);
1491 case GL_VIEW_STATE_OBJECT_CREATE:
1492 switch (view->create_type) {
1493 case GL_LABEL_OBJECT_BOX:
1494 return gl_view_box_create_event_handler (canvas,
1498 case GL_LABEL_OBJECT_ELLIPSE:
1499 return gl_view_ellipse_create_event_handler (canvas,
1503 case GL_LABEL_OBJECT_LINE:
1504 return gl_view_line_create_event_handler (canvas,
1508 case GL_LABEL_OBJECT_IMAGE:
1509 return gl_view_image_create_event_handler (canvas,
1513 case GL_LABEL_OBJECT_TEXT:
1514 return gl_view_text_create_event_handler (canvas,
1518 case GL_LABEL_OBJECT_BARCODE:
1519 return gl_view_barcode_create_event_handler (canvas,
1524 /*Should not happen!*/
1525 g_warning ("Invalid label object type.");
1530 g_warning ("Invalid view state."); /*Should not happen!*/
1536 /*---------------------------------------------------------------------------*/
1537 /* PRIVATE. Canvas event handler (arrow mode) */
1538 /*---------------------------------------------------------------------------*/
1540 canvas_event_arrow_mode (GnomeCanvas *canvas,
1544 static gdouble x0, y0;
1545 static gboolean dragging = FALSE;
1546 static GnomeCanvasItem *item;
1547 gdouble x, y, x1, y1, x2, y2;
1548 GnomeCanvasGroup *group;
1551 gl_debug (DEBUG_VIEW, "");
1553 switch (event->type) {
1555 case GDK_BUTTON_PRESS:
1556 gl_debug (DEBUG_VIEW, "BUTTON_PRESS");
1557 switch (event->button.button) {
1559 gnome_canvas_window_to_world (canvas,
1561 event->button.y, &x, &y);
1563 if (!object_at (view, x, y)) {
1564 if (!(event->button.state & GDK_CONTROL_MASK)) {
1565 gl_view_unselect_all (view);
1569 gdk_pointer_grab (GTK_WIDGET (view->canvas)->
1571 GDK_POINTER_MOTION_MASK |
1572 GDK_BUTTON_RELEASE_MASK |
1573 GDK_BUTTON_PRESS_MASK, NULL,
1574 NULL, event->button.time);
1576 gnome_canvas_root (GNOME_CANVAS
1579 gnome_canvas_item_new (group,
1580 gnome_canvas_rect_get_type (),
1584 "outline_color_rgba",
1599 case GDK_BUTTON_RELEASE:
1600 gl_debug (DEBUG_VIEW, "BUTTON_RELEASE");
1601 switch (event->button.button) {
1605 gdk_pointer_ungrab (event->button.time);
1606 gnome_canvas_window_to_world (canvas,
1614 gl_view_select_region (view, x1, y1, x2, y2);
1615 gtk_object_destroy (GTK_OBJECT (item));
1624 case GDK_MOTION_NOTIFY:
1625 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
1626 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
1627 gnome_canvas_window_to_world (canvas,
1629 event->button.y, &x, &y);
1631 gnome_canvas_item_set (item,
1635 "y2", MAX (y, y0), NULL);
1642 gl_debug (DEBUG_VIEW, "KEY_PRESS");
1644 switch (event->key.keyval) {
1647 move_selection (view,
1648 -1.0 / (view->scale), 0.0);
1652 move_selection (view,
1653 0.0, -1.0 / (view->scale));
1657 move_selection (view,
1658 1.0 / (view->scale), 0.0);
1662 move_selection (view,
1663 0.0, 1.0 / (view->scale));
1667 gl_view_delete_selection (view);
1668 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1669 gdk_window_set_cursor (view->canvas->window,
1671 gdk_cursor_unref (cursor);
1677 return TRUE; /* We handled this or we were dragging. */
1680 gl_debug (DEBUG_VIEW, "default");
1686 /*****************************************************************************/
1687 /* Item event handler. */
1688 /*****************************************************************************/
1690 gl_view_item_event_handler (GnomeCanvasItem *item,
1692 glViewObject *view_object)
1696 gl_debug (DEBUG_VIEW, "");
1698 view = gl_view_object_get_view(view_object);
1699 switch (view->state) {
1701 case GL_VIEW_STATE_ARROW:
1702 return item_event_arrow_mode (item, event, view_object);
1711 /*---------------------------------------------------------------------------*/
1712 /* PRIVATE. Item event handler (arrow mode) */
1713 /*---------------------------------------------------------------------------*/
1715 item_event_arrow_mode (GnomeCanvasItem *item,
1717 glViewObject *view_object)
1719 static gdouble x, y;
1720 static gboolean dragging = FALSE;
1723 gdouble item_x, item_y;
1724 gdouble new_x, new_y;
1725 gboolean control_key_pressed;
1727 gl_debug (DEBUG_VIEW, "");
1729 item_x = event->button.x;
1730 item_y = event->button.y;
1731 gnome_canvas_item_w2i (item->parent, &item_x, &item_y);
1733 view = gl_view_object_get_view(view_object);
1735 switch (event->type) {
1737 case GDK_BUTTON_PRESS:
1738 gl_debug (DEBUG_VIEW, "BUTTON_PRESS");
1739 control_key_pressed = event->button.state & GDK_CONTROL_MASK;
1740 switch (event->button.button) {
1742 if (control_key_pressed) {
1743 if (is_object_selected (view, view_object)) {
1744 /* Un-selecting a selected item */
1745 gl_view_unselect_object (view,
1749 /* Add to current selection */
1750 gl_view_select_object (view,
1754 if (!is_object_selected (view, view_object)) {
1755 /* No control, key so remove any selections before adding */
1756 gl_view_unselect_all (view);
1757 /* Add to current selection */
1758 gl_view_select_object (view,
1762 /* Go into dragging mode while button remains pressed. */
1765 cursor = gdk_cursor_new (GDK_FLEUR);
1766 gnome_canvas_item_grab (item,
1767 GDK_POINTER_MOTION_MASK |
1768 GDK_BUTTON_RELEASE_MASK |
1769 GDK_BUTTON_PRESS_MASK,
1770 cursor, event->button.time);
1771 gdk_cursor_unref (cursor);
1776 if (!is_object_selected (view, view_object)) {
1777 if (!control_key_pressed) {
1778 /* No control, key so remove any selections before adding */
1779 gl_view_unselect_all (view);
1782 /* Add to current selection */
1783 gl_view_select_object (view, view_object);
1784 /* bring up apropriate menu for selection. */
1785 popup_selection_menu (view, view_object, event);
1792 case GDK_BUTTON_RELEASE:
1793 gl_debug (DEBUG_VIEW, "BUTTON_RELEASE");
1794 switch (event->button.button) {
1796 /* Exit dragging mode */
1797 gnome_canvas_item_ungrab (item, event->button.time);
1805 case GDK_MOTION_NOTIFY:
1806 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
1807 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
1808 /* Dragging mode, move selection */
1811 move_selection (view, (new_x - x), (new_y - y));
1819 case GDK_2BUTTON_PRESS:
1820 gl_debug (DEBUG_VIEW, "2BUTTON_PRESS");
1821 switch (event->button.button) {
1823 /* Also exit dragging mode w/ double-click, run dlg */
1824 gnome_canvas_item_ungrab (item, event->button.time);
1826 gl_view_select_object (view, view_object);
1827 gl_view_object_show_dialog (view_object);
1834 case GDK_ENTER_NOTIFY:
1835 gl_debug (DEBUG_VIEW, "ENTER_NOTIFY");
1836 cursor = gdk_cursor_new (GDK_FLEUR);
1837 gdk_window_set_cursor (view->canvas->window, cursor);
1838 gdk_cursor_unref (cursor);
1841 case GDK_LEAVE_NOTIFY:
1842 gl_debug (DEBUG_VIEW, "LEAVE_NOTIFY");
1843 cursor = gdk_cursor_new (GDK_LEFT_PTR);
1844 gdk_window_set_cursor (view->canvas->window, cursor);
1845 gdk_cursor_unref (cursor);
1849 gl_debug (DEBUG_VIEW, "default");
1855 /*---------------------------------------------------------------------------*/
1856 /* PRIVATE. create menu for multiple selections. */
1857 /*---------------------------------------------------------------------------*/
1859 new_selection_menu (glView *view)
1861 GtkWidget *menu, *menuitem;
1863 gl_debug (DEBUG_VIEW, "START");
1865 g_return_val_if_fail (GL_IS_VIEW (view), NULL);
1867 menu = gtk_menu_new ();
1869 menuitem = gtk_menu_item_new_with_label (_("Delete"));
1870 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1871 gtk_widget_show (menuitem);
1872 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
1873 G_CALLBACK (gl_view_delete_selection), view);
1875 menuitem = gtk_menu_item_new ();
1876 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1877 gtk_widget_show (menuitem);
1879 menuitem = gtk_menu_item_new_with_label (_("Bring to front"));
1880 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1881 gtk_widget_show (menuitem);
1882 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
1883 G_CALLBACK (gl_view_raise_selection), view);
1885 menuitem = gtk_menu_item_new_with_label (_("Send to back"));
1886 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1887 gtk_widget_show (menuitem);
1888 g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
1889 G_CALLBACK (gl_view_lower_selection), view);
1891 gl_debug (DEBUG_VIEW, "END");
1896 /*---------------------------------------------------------------------------*/
1897 /* PRIVATE. popup menu for given item. */
1898 /*---------------------------------------------------------------------------*/
1900 popup_selection_menu (glView *view,
1901 glViewObject *view_object,
1906 gl_debug (DEBUG_VIEW, "START");
1908 g_return_if_fail (GL_IS_VIEW (view));
1909 g_return_if_fail (GL_IS_VIEW_OBJECT (view_object));
1911 if (gl_view_is_selection_atomic (view)) {
1913 menu = gl_view_object_get_menu (view_object);
1915 gtk_menu_popup (GTK_MENU (menu),
1916 NULL, NULL, NULL, NULL,
1917 event->button.button,
1918 event->button.time);
1923 if (view->menu != NULL) {
1924 gtk_menu_popup (GTK_MENU (view->menu),
1925 NULL, NULL, NULL, NULL,
1926 event->button.button,
1927 event->button.time);
1932 gl_debug (DEBUG_VIEW, "END");
1935 /*---------------------------------------------------------------------------*/
1936 /* PRIVATE. Handle "selection-clear" signal. */
1937 /*---------------------------------------------------------------------------*/
1939 selection_clear_cb (GtkWidget *widget,
1940 GdkEventSelection *event,
1943 glView *view = GL_VIEW (data);
1945 gl_debug (DEBUG_VIEW, "START");
1947 g_return_if_fail (GL_IS_VIEW (view));
1949 view->have_selection = FALSE;
1950 g_object_unref (view->selection_data);
1951 view->selection_data = NULL;
1953 gl_debug (DEBUG_VIEW, "END");
1956 /*---------------------------------------------------------------------------*/
1957 /* PRIVATE. Handle "selection-get" signal. */
1958 /*---------------------------------------------------------------------------*/
1960 selection_get_cb (GtkWidget *widget,
1961 GtkSelectionData *selection_data,
1966 glView *view = GL_VIEW (data);
1968 glXMLLabelStatus status;
1970 gl_debug (DEBUG_VIEW, "START");
1972 g_return_if_fail (GL_IS_VIEW (view));
1974 if (view->have_selection) {
1976 buffer = gl_xml_label_save_buffer (view->selection_data,
1978 gtk_selection_data_set (selection_data,
1979 GDK_SELECTION_TYPE_STRING, 8, buffer,
1984 gl_debug (DEBUG_VIEW, "END");
1987 /*---------------------------------------------------------------------------*/
1988 /* PRIVATE. Handle "selection-received" signal. (Result of Paste) */
1989 /*---------------------------------------------------------------------------*/
1991 selection_received_cb (GtkWidget *widget,
1992 GtkSelectionData *selection_data,
1996 glView *view = GL_VIEW (data);
1997 glLabel *label = NULL;
1998 glXMLLabelStatus status;
2000 glLabelObject *object, *newobject;
2001 glViewObject *view_object;
2003 gl_debug (DEBUG_VIEW, "START");
2005 g_return_if_fail (GL_IS_VIEW (view));
2007 if (selection_data->length < 0) {
2010 if (selection_data->type != GDK_SELECTION_TYPE_STRING) {
2014 gl_view_unselect_all (view);
2016 label = gl_xml_label_open_buffer (selection_data->data, &status);
2017 for (p = label->objects; p != NULL; p = p_next) {
2020 object = (glLabelObject *) p->data;
2021 gl_label_object_set_parent (object, view->label);
2023 gl_debug (DEBUG_VIEW, "object pasted");
2025 if (GL_IS_LABEL_BOX (object)) {
2026 view_object = gl_view_box_new (GL_LABEL_BOX(object),
2028 } else if (GL_IS_LABEL_ELLIPSE (object)) {
2029 view_object = gl_view_ellipse_new (GL_LABEL_ELLIPSE(object),
2031 } else if (GL_IS_LABEL_LINE (object)) {
2032 view_object = gl_view_line_new (GL_LABEL_LINE(object),
2034 } else if (GL_IS_LABEL_IMAGE (object)) {
2035 view_object = gl_view_image_new (GL_LABEL_IMAGE(object),
2037 } else if (GL_IS_LABEL_TEXT (object)) {
2038 view_object = gl_view_text_new (GL_LABEL_TEXT(object),
2040 } else if (GL_IS_LABEL_BARCODE (object)) {
2041 view_object = gl_view_barcode_new (GL_LABEL_BARCODE(object),
2044 /* Should not happen! */
2046 g_warning ("Invalid label object type.");
2048 gl_view_select_object (view, view_object);
2050 g_object_unref (label);
2052 gl_debug (DEBUG_VIEW, "END");