3 * Copyright (C) 2001-2009 Jim Evins <evins@snaught.com>.
5 * This file is part of gLabels.
7 * gLabels is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * gLabels is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
25 #include <glib/gi18n.h>
28 #include "template-history.h"
29 #include "file-util.h"
30 #include "xml-label.h"
32 #include "label-text.h"
33 #include "label-image.h"
39 /*========================================================*/
40 /* Private macros and constants. */
41 /*========================================================*/
44 /*========================================================*/
46 /*========================================================*/
48 struct _glLabelPrivate {
52 gint untitled_instance;
54 gboolean modified_flag;
57 lglTemplate *template;
64 GHashTable *pixbuf_cache;
65 GHashTable *svg_cache;
67 /* Delay changed signals while operating on selections of multiple objects. */
68 gboolean selection_op_flag;
69 gboolean delayed_change_flag;
71 /* Default object text properties */
72 gchar *default_font_family;
73 gdouble default_font_size;
74 PangoWeight default_font_weight;
75 gboolean default_font_italic_flag;
76 guint default_text_color;
77 PangoAlignment default_text_alignment;
78 glValignment default_text_valignment;
79 gdouble default_text_line_spacing;
81 /* Default object line properties */
82 gdouble default_line_width;
83 guint default_line_color;
85 /* Default object fill properties */
86 guint default_fill_color;
91 gboolean cp_cleared_flag;
114 gboolean modified_flag;
117 lglTemplate *template;
118 gboolean rotate_flag;
127 /*========================================================*/
128 /* Private globals. */
129 /*========================================================*/
131 static guint signals[LAST_SIGNAL] = {0};
133 static guint untitled = 0;
136 /*========================================================*/
137 /* Private function prototypes. */
138 /*========================================================*/
140 static void gl_label_finalize (GObject *object);
142 static void object_changed_cb (glLabelObject *object,
145 static void object_moved_cb (glLabelObject *object,
148 static void do_modify (glLabel *label);
150 static void begin_selection_op (glLabel *label);
151 static void end_selection_op (glLabel *label);
153 static void clipboard_get_cb (GtkClipboard *clipboard,
154 GtkSelectionData *selection_data,
156 ClipboardData *data);
158 static void clipboard_clear_cb (GtkClipboard *clipboard,
159 ClipboardData *data);
161 static void receive_targets_cb (GtkClipboard *clipboard,
166 static void paste_xml_received_cb (GtkClipboard *clipboard,
167 GtkSelectionData *selection_data,
170 static void paste_text_received_cb (GtkClipboard *clipboard,
174 static void paste_image_received_cb(GtkClipboard *clipboard,
178 static void stack_clear (GQueue *stack);
179 static void stack_push_state (GQueue *stack,
181 static State *stack_pop_state (GQueue *stack);
183 static State *state_new (glLabel *this,
184 const gchar *description);
185 static void state_free (State *state);
186 static void state_restore (State *state,
190 /*****************************************************************************/
191 /* Boilerplate object stuff. */
192 /*****************************************************************************/
193 G_DEFINE_TYPE (glLabel, gl_label, G_TYPE_OBJECT)
197 gl_label_class_init (glLabelClass *class)
199 GObjectClass *object_class = G_OBJECT_CLASS (class);
201 gl_debug (DEBUG_LABEL, "START");
203 gl_label_parent_class = g_type_class_peek_parent (class);
205 object_class->finalize = gl_label_finalize;
207 signals[SELECTION_CHANGED] =
208 g_signal_new ("selection_changed",
209 G_OBJECT_CLASS_TYPE (object_class),
211 G_STRUCT_OFFSET (glLabelClass, selection_changed),
213 gl_marshal_VOID__VOID,
217 g_signal_new ("changed",
218 G_OBJECT_CLASS_TYPE (object_class),
220 G_STRUCT_OFFSET (glLabelClass, changed),
222 gl_marshal_VOID__VOID,
225 signals[NAME_CHANGED] =
226 g_signal_new ("name_changed",
227 G_OBJECT_CLASS_TYPE (object_class),
229 G_STRUCT_OFFSET (glLabelClass, name_changed),
231 gl_marshal_VOID__VOID,
234 signals[MODIFIED_CHANGED] =
235 g_signal_new ("modified_changed",
236 G_OBJECT_CLASS_TYPE (object_class),
238 G_STRUCT_OFFSET (glLabelClass, modified_changed),
240 gl_marshal_VOID__VOID,
243 signals[MERGE_CHANGED] =
244 g_signal_new ("merge_changed",
245 G_OBJECT_CLASS_TYPE (object_class),
247 G_STRUCT_OFFSET (glLabelClass, merge_changed),
249 gl_marshal_VOID__VOID,
252 signals[SIZE_CHANGED] =
253 g_signal_new ("size_changed",
254 G_OBJECT_CLASS_TYPE (object_class),
256 G_STRUCT_OFFSET (glLabelClass, size_changed),
258 gl_marshal_VOID__VOID,
262 gl_debug (DEBUG_LABEL, "END");
267 gl_label_init (glLabel *label)
269 gl_debug (DEBUG_LABEL, "START");
271 label->priv = g_new0 (glLabelPrivate, 1);
273 label->priv->template = NULL;
274 label->priv->rotate_flag = FALSE;
275 label->priv->object_list = NULL;
277 label->priv->filename = NULL;
278 label->priv->modified_flag = FALSE;
279 label->priv->compression = 9;
281 label->priv->merge = NULL;
282 label->priv->pixbuf_cache = gl_pixbuf_cache_new ();
283 label->priv->svg_cache = gl_svg_cache_new ();
285 label->priv->undo_stack = g_queue_new ();
286 label->priv->redo_stack = g_queue_new ();
289 * Defaults from preferences
291 label->priv->default_font_family = gl_prefs_model_get_default_font_family (gl_prefs);
292 label->priv->default_font_size = gl_prefs_model_get_default_font_size (gl_prefs);
293 label->priv->default_font_weight = gl_prefs_model_get_default_font_weight (gl_prefs);
294 label->priv->default_font_italic_flag = gl_prefs_model_get_default_font_italic_flag (gl_prefs);
295 label->priv->default_text_color = gl_prefs_model_get_default_text_color (gl_prefs);
296 label->priv->default_text_alignment = gl_prefs_model_get_default_text_alignment (gl_prefs);
297 label->priv->default_text_line_spacing = gl_prefs_model_get_default_text_line_spacing (gl_prefs);
298 label->priv->default_line_width = gl_prefs_model_get_default_line_width (gl_prefs);
299 label->priv->default_line_color = gl_prefs_model_get_default_line_color (gl_prefs);
300 label->priv->default_fill_color = gl_prefs_model_get_default_fill_color (gl_prefs);
302 gl_debug (DEBUG_LABEL, "END");
307 gl_label_finalize (GObject *object)
309 glLabel *label = GL_LABEL (object);
312 gl_debug (DEBUG_LABEL, "START");
314 g_return_if_fail (object && GL_IS_LABEL (object));
316 for (p = label->priv->object_list; p != NULL; p = p->next)
318 g_object_unref (G_OBJECT(p->data));
320 g_list_free (label->priv->object_list);
322 lgl_template_free (label->priv->template);
323 g_free (label->priv->filename);
324 if (label->priv->merge != NULL)
326 g_object_unref (G_OBJECT(label->priv->merge));
328 g_free (label->priv->default_font_family);
330 stack_clear (label->priv->undo_stack);
331 stack_clear (label->priv->redo_stack);
333 g_queue_free (label->priv->undo_stack);
334 g_queue_free (label->priv->redo_stack);
336 gl_pixbuf_cache_free (label->priv->pixbuf_cache);
337 gl_svg_cache_free (label->priv->svg_cache);
339 g_free (label->priv);
341 G_OBJECT_CLASS (gl_label_parent_class)->finalize (object);
343 gl_debug (DEBUG_LABEL, "END");
347 /*****************************************************************************/
349 /*****************************************************************************/
355 gl_debug (DEBUG_LABEL, "START");
357 label = g_object_new (gl_label_get_type(), NULL);
359 gl_debug (DEBUG_LABEL, "END");
361 return G_OBJECT (label);
365 /****************************************************************************/
367 /****************************************************************************/
369 gl_label_set_filename (glLabel *label,
370 const gchar *filename)
372 label->priv->filename = g_strdup (filename);
374 g_signal_emit (G_OBJECT(label), signals[NAME_CHANGED], 0);
378 /****************************************************************************/
379 /* return filename. */
380 /****************************************************************************/
382 gl_label_get_filename (glLabel *label)
384 gl_debug (DEBUG_LABEL, "");
386 return g_strdup ( label->priv->filename );
390 /****************************************************************************/
391 /* return short filename. */
392 /****************************************************************************/
394 gl_label_get_short_name (glLabel *label)
396 gl_debug (DEBUG_LABEL, "");
398 if ( label->priv->filename == NULL )
401 if ( label->priv->untitled_instance == 0 )
403 label->priv->untitled_instance = ++untitled;
406 return g_strdup_printf ( "%s %d", _("Untitled"),
407 label->priv->untitled_instance );
412 gchar *temp_name, *short_name;
414 temp_name = g_path_get_basename ( label->priv->filename );
415 short_name = gl_file_util_remove_extension (temp_name);
423 /****************************************************************************/
424 /* Is label untitled? */
425 /****************************************************************************/
427 gl_label_is_untitled (glLabel *label)
429 gl_debug (DEBUG_LABEL, "return %d",(label->priv->filename == NULL));
430 return (label->priv->filename == NULL);
434 /****************************************************************************/
435 /* Set compression level. */
436 /****************************************************************************/
438 gl_label_set_compression (glLabel *label,
441 gl_debug (DEBUG_LABEL, "set %d", compression);
443 /* Older versions of libxml2 always return a -1 for documents "read in," so
444 * default to 9. Also, default to 9 for anything else out of range. */
445 if ((compression < 0) || (compression >9))
450 gl_debug (DEBUG_LABEL, "actual set %d", compression);
451 label->priv->compression = compression;
455 /****************************************************************************/
456 /* Get compression level. */
457 /****************************************************************************/
459 gl_label_get_compression (glLabel *label)
461 gl_debug (DEBUG_LABEL, "return %d", label->priv->compression);
462 return label->priv->compression;
466 /****************************************************************************/
467 /* Set modified flag. */
468 /****************************************************************************/
470 gl_label_set_modified (glLabel *label)
473 if ( !label->priv->modified_flag )
476 label->priv->modified_flag = TRUE;
478 g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
484 /****************************************************************************/
485 /* Clear modified flag. */
486 /****************************************************************************/
488 gl_label_clear_modified (glLabel *label)
491 if ( label->priv->modified_flag )
494 g_get_current_time (&label->priv->time_stamp);
495 label->priv->modified_flag = FALSE;
497 g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
503 /****************************************************************************/
504 /* Is label modified? */
505 /****************************************************************************/
507 gl_label_is_modified (glLabel *label)
509 gl_debug (DEBUG_LABEL, "return %d", label->priv->modified_flag);
510 return label->priv->modified_flag;
514 /****************************************************************************/
515 /* Object "changed" callback. */
516 /****************************************************************************/
518 object_changed_cb (glLabelObject *object,
525 /****************************************************************************/
526 /* Object "moved" callback. */
527 /****************************************************************************/
529 object_moved_cb (glLabelObject *object,
536 /****************************************************************************/
538 /****************************************************************************/
540 do_modify (glLabel *label)
542 if ( label->priv->selection_op_flag )
544 label->priv->delayed_change_flag = TRUE;
548 label->priv->modified_flag = TRUE;
550 g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
551 g_signal_emit (G_OBJECT(label), signals[CHANGED], 0);
556 /****************************************************************************/
557 /* Begin selection operation. */
558 /****************************************************************************/
560 begin_selection_op (glLabel *label)
562 label->priv->selection_op_flag = TRUE;
566 /****************************************************************************/
567 /* End selection operation. */
568 /****************************************************************************/
570 end_selection_op (glLabel *label)
572 label->priv->selection_op_flag = FALSE;
573 if ( label->priv->delayed_change_flag )
575 label->priv->delayed_change_flag = FALSE;
581 /****************************************************************************/
583 /****************************************************************************/
585 gl_label_set_template (glLabel *label,
586 const lglTemplate *template,
591 gl_debug (DEBUG_LABEL, "START");
593 g_return_if_fail (label && GL_IS_LABEL (label));
594 g_return_if_fail (template);
596 if ((label->priv->template == NULL) ||
597 !lgl_template_do_templates_match (template, label->priv->template))
602 gl_label_checkpoint (label, _("Label properties"));
605 lgl_template_free (label->priv->template);
606 label->priv->template = lgl_template_dup (template);
609 g_signal_emit (G_OBJECT(label), signals[SIZE_CHANGED], 0);
611 name = lgl_template_get_name (template);
612 gl_template_history_model_add_name (gl_template_history, name);
616 gl_debug (DEBUG_LABEL, "END");
620 /****************************************************************************/
622 /****************************************************************************/
624 gl_label_get_template (glLabel *label)
626 return label->priv->template;
630 /****************************************************************************/
631 /* set rotate flag. */
632 /****************************************************************************/
634 gl_label_set_rotate_flag (glLabel *label,
635 gboolean rotate_flag,
638 gl_debug (DEBUG_LABEL, "START");
640 g_return_if_fail (label && GL_IS_LABEL (label));
642 if (rotate_flag != label->priv->rotate_flag)
646 gl_label_checkpoint (label, _("Label properties"));
649 label->priv->rotate_flag = rotate_flag;
652 g_signal_emit (G_OBJECT(label), signals[SIZE_CHANGED], 0);
655 gl_debug (DEBUG_LABEL, "END");
659 /****************************************************************************/
660 /* Get rotate flag. */
661 /****************************************************************************/
663 gl_label_get_rotate_flag (glLabel *label)
665 return label->priv->rotate_flag;
669 /****************************************************************************/
670 /* Get label size. */
671 /****************************************************************************/
673 gl_label_get_size (glLabel *label,
677 lglTemplate *template;
678 const lglTemplateFrame *frame;
680 gl_debug (DEBUG_LABEL, "START");
682 g_return_if_fail (label && GL_IS_LABEL (label));
684 template = label->priv->template;
687 gl_debug (DEBUG_LABEL, "END -- template NULL");
691 frame = (lglTemplateFrame *)template->frames->data;
693 if (!label->priv->rotate_flag)
695 lgl_template_frame_get_size (frame, w, h);
699 lgl_template_frame_get_size (frame, h, w);
702 gl_debug (DEBUG_LABEL, "END");
706 /****************************************************************************/
707 /* get string with info about dimensions */
708 /****************************************************************************/
710 gl_label_get_dimensions_string (glLabel *label)
713 lglTemplate *template;
714 const lglTemplateFrame *frame;
716 gdouble units_per_point;
721 gl_debug (DEBUG_LABEL, "START");
723 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
725 template = label->priv->template;
728 frame = (lglTemplateFrame *)template->frames->data;
729 units = gl_prefs_model_get_units (gl_prefs);
730 units_per_point = lgl_units_get_units_per_point (units);
732 switch (frame->shape)
734 case LGL_TEMPLATE_FRAME_SHAPE_RECT:
735 if (units == LGL_UNITS_INCH)
737 s1 = lgl_str_format_fraction (frame->rect.w*units_per_point);
738 s2 = lgl_str_format_fraction (frame->rect.h*units_per_point);
739 s3 = lgl_str_format_fraction (frame->rect.r*units_per_point);
743 s1 = g_strdup_printf ("%.5g", frame->rect.w*units_per_point);
744 s2 = g_strdup_printf ("%.5g", frame->rect.h*units_per_point);
745 s3 = g_strdup_printf ("%.5g", frame->rect.r*units_per_point);
747 if (frame->rect.r == 0)
748 /*Translators: A rectangular label dimensions. first param is numeric value*/
749 /* of width, second is numeric value of height and third is unit. Example:*/
750 /*"60 × 22.5 mm (width / height)"*/
751 dims = g_strdup_printf (_("%s × %s %s (width × height)"),
752 s1, s2, lgl_units_get_name (units));
754 /*Translators: A rounded rectangular label dimensions. first param is numeric*/
755 /*value of width, second is numeric value of height, third is numeric value*/
756 /*of round and fourth is unit. Example:*/
757 /*"50 × 30 / 1.5 mm (width × height / round)"*/
758 dims = g_strdup_printf (_("%s × %s / %s %s (width × height / round)"),
759 s1, s2, s3, lgl_units_get_name (units));
762 case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
763 if (units == LGL_UNITS_INCH)
765 s1 = lgl_str_format_fraction (frame->ellipse.w*units_per_point);
766 s2 = lgl_str_format_fraction (frame->ellipse.h*units_per_point);
770 s1 = g_strdup_printf ("%.5g", frame->ellipse.w*units_per_point);
771 s2 = g_strdup_printf ("%.5g", frame->ellipse.h*units_per_point);
773 /*Translators: A elliptical label dimensions. first param is numeric value of*/
774 /*width, second is numeric value of height and third is unit. Example:*/
775 /*"60 × 22.5 mm (width / height)"*/
776 dims = g_strdup_printf (_("%s × %s %s (width × height)"),
777 s1, s2, lgl_units_get_name (units));
780 case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
781 if (units == LGL_UNITS_INCH)
782 s1 = lgl_str_format_fraction (2*frame->round.r*units_per_point);
784 s1 = g_strdup_printf ("%.5g", 2*frame->round.r*units_per_point);
785 /*Translators: A round label dimensions. first param is numeric value of*/
786 /*diameter and secons is unit. Example:*/
787 /*"120.5 mm (diameter)"*/
788 dims = g_strdup_printf (_("%s %s (diameter)"),
789 s1, lgl_units_get_name (units));
792 case LGL_TEMPLATE_FRAME_SHAPE_CD:
793 if (units == LGL_UNITS_INCH)
795 s1 = lgl_str_format_fraction (2*frame->cd.r1*units_per_point);
796 s2 = lgl_str_format_fraction (2*frame->cd.r2*units_per_point);
800 s1 = g_strdup_printf ("%.5g", 2*frame->cd.r1*units_per_point);
801 s2 = g_strdup_printf ("%.5g", 2*frame->cd.r2*units_per_point);
803 /*Translators: A CD/DVD label dimensions. first param is numeric value of*/
804 /*diameter, second is numeric value of hole and third is unit. Example:*/
805 /*"120.5 / 30 mm (diameter / hole)"*/
806 dims = g_strdup_printf (_("%s / %s %s (diameter / hole)"),
807 s1, s2, lgl_units_get_name (units));
815 gl_debug (DEBUG_LABEL, "END");
821 /****************************************************************************/
822 /* set merge information structure. */
823 /****************************************************************************/
825 gl_label_set_merge (glLabel *label,
829 gl_debug (DEBUG_LABEL, "START");
831 g_return_if_fail (label && GL_IS_LABEL (label));
835 gl_label_checkpoint (label, _("Merge properties"));
838 if ( label->priv->merge != NULL )
840 g_object_unref (G_OBJECT(label->priv->merge));
842 label->priv->merge = gl_merge_dup (merge);
845 g_signal_emit (G_OBJECT(label), signals[MERGE_CHANGED], 0);
847 gl_debug (DEBUG_LABEL, "END");
851 /****************************************************************************/
852 /* Get merge information structure. */
853 /****************************************************************************/
855 gl_label_get_merge (glLabel *label)
857 gl_debug (DEBUG_LABEL, "START");
859 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
861 gl_debug (DEBUG_LABEL, "END");
863 return gl_merge_dup (label->priv->merge);
867 /****************************************************************************/
868 /* Get pixbuf cache. */
869 /****************************************************************************/
871 gl_label_get_pixbuf_cache (glLabel *label)
873 return label->priv->pixbuf_cache;
877 /****************************************************************************/
879 /****************************************************************************/
881 gl_label_get_svg_cache (glLabel *label)
883 return label->priv->svg_cache;
887 /*****************************************************************************/
888 /* Add object to label. */
889 /*****************************************************************************/
891 gl_label_add_object (glLabel *label,
892 glLabelObject *object)
894 gl_debug (DEBUG_LABEL, "START");
896 g_return_if_fail (label && GL_IS_LABEL (label));
897 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
899 gl_label_object_set_parent (object, label);
900 label->priv->object_list = g_list_append (label->priv->object_list, object);
902 g_signal_connect (G_OBJECT (object), "changed",
903 G_CALLBACK (object_changed_cb), label);
904 g_signal_connect (G_OBJECT (object), "moved",
905 G_CALLBACK (object_moved_cb), label);
909 gl_debug (DEBUG_LABEL, "END");
913 /*****************************************************************************/
914 /* Delete object from label. */
915 /*****************************************************************************/
917 gl_label_delete_object (glLabel *label,
918 glLabelObject *object)
920 gl_debug (DEBUG_LABEL, "START");
922 g_return_if_fail (label && GL_IS_LABEL (label));
923 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
925 label->priv->object_list = g_list_remove (label->priv->object_list, object);
927 g_signal_handlers_disconnect_by_func (G_OBJECT (object),
928 G_CALLBACK (object_changed_cb), label);
929 g_signal_handlers_disconnect_by_func (G_OBJECT (object),
930 G_CALLBACK (object_moved_cb), label);
931 g_object_unref (object);
935 gl_debug (DEBUG_LABEL, "END");
939 /*****************************************************************************/
940 /* Get object list. */
941 /*****************************************************************************/
943 gl_label_get_object_list (glLabel *label)
945 return label->priv->object_list;
949 /*****************************************************************************/
951 /*****************************************************************************/
953 gl_label_select_object (glLabel *label,
954 glLabelObject *object)
956 gl_debug (DEBUG_LABEL, "START");
958 g_return_if_fail (label && GL_IS_LABEL (label));
959 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
961 gl_label_object_select (object);
963 label->priv->cp_cleared_flag = TRUE;
964 g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
966 gl_debug (DEBUG_LABEL, "END");
970 /*****************************************************************************/
971 /* Unselect object. */
972 /*****************************************************************************/
974 gl_label_unselect_object (glLabel *label,
975 glLabelObject *object)
977 gl_debug (DEBUG_LABEL, "START");
979 g_return_if_fail (label && GL_IS_LABEL (label));
980 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
982 gl_label_object_unselect (object);
984 label->priv->cp_cleared_flag = TRUE;
985 g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
987 gl_debug (DEBUG_LABEL, "END");
991 /*****************************************************************************/
992 /* Select all objects. */
993 /*****************************************************************************/
995 gl_label_select_all (glLabel *label)
998 glLabelObject *object;
1000 gl_debug (DEBUG_LABEL, "START");
1002 g_return_if_fail (label && GL_IS_LABEL (label));
1004 for ( p = label->priv->object_list; p != NULL; p = p->next )
1006 object = GL_LABEL_OBJECT (p->data);
1008 gl_label_object_select (object);
1011 label->priv->cp_cleared_flag = TRUE;
1012 g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
1014 gl_debug (DEBUG_LABEL, "END");
1018 /*****************************************************************************/
1019 /* Unselect all objects. */
1020 /*****************************************************************************/
1022 gl_label_unselect_all (glLabel *label)
1025 glLabelObject *object;
1027 gl_debug (DEBUG_LABEL, "START");
1029 g_return_if_fail (label && GL_IS_LABEL (label));
1031 for ( p = label->priv->object_list; p != NULL; p = p->next )
1033 object = GL_LABEL_OBJECT (p->data);
1035 gl_label_object_unselect (object);
1038 label->priv->cp_cleared_flag = TRUE;
1039 g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
1041 gl_debug (DEBUG_LABEL, "END");
1045 /*****************************************************************************/
1046 /* Select all objects contained in region. */
1047 /*****************************************************************************/
1049 gl_label_select_region (glLabel *label,
1050 glLabelRegion *region)
1053 glLabelObject *object;
1056 glLabelRegion obj_extent;
1058 gl_debug (DEBUG_LABEL, "START");
1060 g_return_if_fail (label && GL_IS_LABEL (label));
1062 r_x1 = MIN (region->x1, region->x2);
1063 r_y1 = MIN (region->y1, region->y2);
1064 r_x2 = MAX (region->x1, region->x2);
1065 r_y2 = MAX (region->y1, region->y2);
1067 for (p = label->priv->object_list; p != NULL; p = p->next)
1069 object = GL_LABEL_OBJECT(p->data);
1071 gl_label_object_get_extent (object, &obj_extent);
1072 if ((obj_extent.x1 >= r_x1) &&
1073 (obj_extent.x2 <= r_x2) &&
1074 (obj_extent.y1 >= r_y1) &&
1075 (obj_extent.y2 <= r_y2))
1077 gl_label_object_select (object);
1081 label->priv->cp_cleared_flag = TRUE;
1082 g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
1084 gl_debug (DEBUG_LABEL, "END");
1088 /*****************************************************************************/
1089 /* Is selection empty? */
1090 /*****************************************************************************/
1092 gl_label_is_selection_empty (glLabel *label)
1095 glLabelObject *object;
1097 for ( p = label->priv->object_list; p != NULL; p = p->next )
1099 object = GL_LABEL_OBJECT (p->data);
1101 if ( gl_label_object_is_selected (object) )
1111 /*****************************************************************************/
1112 /* Is selection atomic? */
1113 /*****************************************************************************/
1115 gl_label_is_selection_atomic (glLabel *label)
1118 glLabelObject *object;
1119 gint n_selected = 0;
1121 for ( p = label->priv->object_list; p != NULL; p = p->next )
1123 object = GL_LABEL_OBJECT (p->data);
1125 if ( gl_label_object_is_selected (object) )
1136 return (n_selected == 1);
1140 /*****************************************************************************/
1141 /* Get first selected object. */
1142 /*****************************************************************************/
1144 gl_label_get_1st_selected_object (glLabel *label)
1147 glLabelObject *object;
1149 for ( p = label->priv->object_list; p != NULL; p = p->next )
1151 object = GL_LABEL_OBJECT (p->data);
1153 if ( gl_label_object_is_selected (object) )
1163 /*****************************************************************************/
1164 /* Get list of selected objects. */
1165 /*****************************************************************************/
1167 gl_label_get_selection_list (glLabel *label)
1169 GList *selection_list = NULL;
1171 glLabelObject *object;
1173 for ( p = label->priv->object_list; p != NULL; p = p->next )
1175 object = GL_LABEL_OBJECT (p->data);
1177 if ( gl_label_object_is_selected (object) )
1179 selection_list = g_list_append (selection_list, object);
1183 return (selection_list);
1187 /*****************************************************************************/
1188 /* Can text properties be set for selection? */
1189 /*****************************************************************************/
1191 gl_label_can_selection_text (glLabel *label)
1193 GList *selection_list;
1195 glLabelObject *object;
1197 gl_debug (DEBUG_LABEL, "");
1199 g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
1201 selection_list = gl_label_get_selection_list (label);
1203 for (p = selection_list; p != NULL; p = p->next)
1205 object = GL_LABEL_OBJECT (p->data);
1207 if (gl_label_object_can_text (object))
1209 g_list_free (selection_list);
1214 g_list_free (selection_list);
1219 /*****************************************************************************/
1220 /* Can fill properties be set for selection? */
1221 /*****************************************************************************/
1223 gl_label_can_selection_fill (glLabel *label)
1225 GList *selection_list;
1227 glLabelObject *object;
1229 gl_debug (DEBUG_LABEL, "");
1231 g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
1233 selection_list = gl_label_get_selection_list (label);
1235 for (p = selection_list; p != NULL; p = p->next)
1237 object = GL_LABEL_OBJECT (p->data);
1239 if (gl_label_object_can_fill (object))
1241 g_list_free (selection_list);
1247 g_list_free (selection_list);
1252 /*****************************************************************************/
1253 /* Can line color properties be set for selection? */
1254 /*****************************************************************************/
1256 gl_label_can_selection_line_color (glLabel *label)
1258 GList *selection_list;
1260 glLabelObject *object;
1262 gl_debug (DEBUG_LABEL, "");
1264 g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
1266 selection_list = gl_label_get_selection_list (label);
1268 for (p = selection_list; p != NULL; p = p->next)
1270 object = GL_LABEL_OBJECT (p->data);
1272 if (gl_label_object_can_line_color (object))
1274 g_list_free (selection_list);
1279 g_list_free (selection_list);
1284 /*****************************************************************************/
1285 /* Can line width properties be set for selection? */
1286 /*****************************************************************************/
1288 gl_label_can_selection_line_width (glLabel *label)
1290 GList *selection_list;
1292 glLabelObject *object;
1294 gl_debug (DEBUG_LABEL, "");
1296 g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
1298 selection_list = gl_label_get_selection_list (label);
1300 for (p = selection_list; p != NULL; p = p->next)
1302 object = GL_LABEL_OBJECT (p->data);
1304 if (gl_label_object_can_line_width (object))
1306 g_list_free (selection_list);
1312 g_list_free (selection_list);
1317 /*****************************************************************************/
1318 /* Delete selection from label. */
1319 /*****************************************************************************/
1321 gl_label_delete_selection (glLabel *label)
1323 GList *selection_list;
1325 glLabelObject *object;
1327 gl_debug (DEBUG_LABEL, "START");
1329 g_return_if_fail (label && GL_IS_LABEL (label));
1331 gl_label_checkpoint (label, _("Delete"));
1333 begin_selection_op (label);
1335 selection_list = gl_label_get_selection_list (label);
1337 for ( p = selection_list; p != NULL; p = p->next )
1339 object = GL_LABEL_OBJECT (p->data);
1341 gl_label_delete_object (label, object);
1344 g_list_free (selection_list);
1346 end_selection_op (label);
1348 g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
1350 gl_debug (DEBUG_LABEL, "END");
1354 /****************************************************************************/
1355 /* Bring selection object to front/top. */
1356 /****************************************************************************/
1358 gl_label_raise_selection_to_top (glLabel *label)
1360 GList *selection_list;
1362 glLabelObject *object;
1364 gl_debug (DEBUG_LABEL, "START");
1366 gl_label_checkpoint (label, _("Bring to front"));
1368 begin_selection_op (label);
1370 selection_list = gl_label_get_selection_list (label);
1372 for ( p = selection_list; p != NULL; p = p->next )
1374 object = GL_LABEL_OBJECT (p->data);
1376 label->priv->object_list = g_list_remove (label->priv->object_list, object);
1379 /* Move to end of list, representing front most object */
1380 label->priv->object_list = g_list_concat (label->priv->object_list, selection_list);
1384 end_selection_op (label);
1386 gl_debug (DEBUG_LABEL, "END");
1390 /****************************************************************************/
1391 /* Send selection to rear/bottom. */
1392 /****************************************************************************/
1394 gl_label_lower_selection_to_bottom (glLabel *label)
1396 GList *selection_list;
1398 glLabelObject *object;
1400 gl_debug (DEBUG_LABEL, "START");
1402 gl_label_checkpoint (label, _("Send to back"));
1404 begin_selection_op (label);
1406 selection_list = gl_label_get_selection_list (label);
1408 for ( p = selection_list; p != NULL; p = p->next )
1410 object = GL_LABEL_OBJECT (p->data);
1412 label->priv->object_list = g_list_remove (label->priv->object_list, object);
1415 /* Move to front of list, representing rear most object */
1416 label->priv->object_list = g_list_concat (selection_list, label->priv->object_list);
1420 end_selection_op (label);
1422 gl_debug (DEBUG_LABEL, "END");
1426 /*****************************************************************************/
1427 /* Rotate selected objects by given angle. */
1428 /*****************************************************************************/
1430 gl_label_rotate_selection (glLabel *label,
1433 GList *selection_list;
1435 glLabelObject *object;
1437 gl_debug (DEBUG_LABEL, "START");
1439 g_return_if_fail (label && GL_IS_LABEL (label));
1441 begin_selection_op (label);
1443 gl_label_checkpoint (label, _("Rotate"));
1445 selection_list = gl_label_get_selection_list (label);
1447 for ( p = selection_list; p != NULL; p = p->next )
1449 object = GL_LABEL_OBJECT (p->data);
1451 gl_label_object_rotate (object, theta_degs);
1454 g_list_free (selection_list);
1456 end_selection_op (label);
1458 gl_debug (DEBUG_LABEL, "END");
1462 /*****************************************************************************/
1463 /* Rotate selected objects 90 degrees left. */
1464 /*****************************************************************************/
1466 gl_label_rotate_selection_left (glLabel *label)
1468 GList *selection_list;
1470 glLabelObject *object;
1472 gl_debug (DEBUG_LABEL, "START");
1474 g_return_if_fail (label && GL_IS_LABEL (label));
1476 begin_selection_op (label);
1478 gl_label_checkpoint (label, _("Rotate left"));
1480 selection_list = gl_label_get_selection_list (label);
1482 for ( p = selection_list; p != NULL; p = p->next )
1484 object = GL_LABEL_OBJECT (p->data);
1486 gl_label_object_rotate (object, -90.0);
1489 g_list_free (selection_list);
1491 end_selection_op (label);
1493 gl_debug (DEBUG_LABEL, "END");
1497 /*****************************************************************************/
1498 /* Rotate selected objects 90 degrees right. */
1499 /*****************************************************************************/
1501 gl_label_rotate_selection_right (glLabel *label)
1503 GList *selection_list;
1505 glLabelObject *object;
1507 gl_debug (DEBUG_LABEL, "START");
1509 g_return_if_fail (label && GL_IS_LABEL (label));
1511 gl_label_checkpoint (label, _("Rotate right"));
1513 begin_selection_op (label);
1515 selection_list = gl_label_get_selection_list (label);
1517 for ( p = selection_list; p != NULL; p = p->next )
1519 object = GL_LABEL_OBJECT (p->data);
1521 gl_label_object_rotate (object, 90.0);
1524 g_list_free (selection_list);
1526 end_selection_op (label);
1528 gl_debug (DEBUG_LABEL, "END");
1532 /*****************************************************************************/
1533 /* Flip selected objects horizontally. */
1534 /*****************************************************************************/
1536 gl_label_flip_selection_horiz (glLabel *label)
1538 GList *selection_list;
1540 glLabelObject *object;
1542 gl_debug (DEBUG_LABEL, "START");
1544 g_return_if_fail (label && GL_IS_LABEL (label));
1546 gl_label_checkpoint (label, _("Flip horizontally"));
1548 begin_selection_op (label);
1550 selection_list = gl_label_get_selection_list (label);
1552 for ( p = selection_list; p != NULL; p = p->next )
1554 object = GL_LABEL_OBJECT (p->data);
1556 gl_label_object_flip_horiz (object);
1559 g_list_free (selection_list);
1561 end_selection_op (label);
1563 gl_debug (DEBUG_LABEL, "END");
1567 /*****************************************************************************/
1568 /* Flip selected objects vertically. */
1569 /*****************************************************************************/
1571 gl_label_flip_selection_vert (glLabel *label)
1573 GList *selection_list;
1575 glLabelObject *object;
1577 gl_debug (DEBUG_LABEL, "START");
1579 g_return_if_fail (label && GL_IS_LABEL (label));
1581 gl_label_checkpoint (label, _("Flip vertically"));
1583 begin_selection_op (label);
1585 selection_list = gl_label_get_selection_list (label);
1587 for ( p = selection_list; p != NULL; p = p->next )
1589 object = GL_LABEL_OBJECT (p->data);
1591 gl_label_object_flip_vert (object);
1594 g_list_free (selection_list);
1596 end_selection_op (label);
1598 gl_debug (DEBUG_LABEL, "END");
1602 /*****************************************************************************/
1603 /* Align selected objects to left most edge. */
1604 /*****************************************************************************/
1606 gl_label_align_selection_left (glLabel *label)
1608 GList *selection_list;
1610 glLabelObject *object;
1612 glLabelRegion obj_extent;
1614 gl_debug (DEBUG_LABEL, "START");
1616 g_return_if_fail (label && GL_IS_LABEL (label));
1618 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1619 !gl_label_is_selection_atomic (label));
1621 gl_label_checkpoint (label, _("Align left"));
1623 begin_selection_op (label);
1625 selection_list = gl_label_get_selection_list (label);
1627 /* find left most edge */
1629 object = GL_LABEL_OBJECT (p->data);
1631 gl_label_object_get_extent (object, &obj_extent);
1632 x1_min = obj_extent.x1;
1633 for (p = p->next; p != NULL; p = p->next)
1635 object = GL_LABEL_OBJECT (p->data);
1637 gl_label_object_get_extent (object, &obj_extent);
1638 if ( obj_extent.x1 < x1_min ) x1_min = obj_extent.x1;
1641 /* now adjust the object positions to line up the left edges */
1642 for (p = selection_list; p != NULL; p = p->next)
1644 object = GL_LABEL_OBJECT (p->data);
1646 gl_label_object_get_extent (object, &obj_extent);
1647 dx = x1_min - obj_extent.x1;
1648 gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1651 g_list_free (selection_list);
1653 end_selection_op (label);
1655 gl_debug (DEBUG_LABEL, "END");
1659 /*****************************************************************************/
1660 /* Align selected objects to right most edge. */
1661 /*****************************************************************************/
1663 gl_label_align_selection_right (glLabel *label)
1665 GList *selection_list;
1667 glLabelObject *object;
1669 glLabelRegion obj_extent;
1671 gl_debug (DEBUG_LABEL, "START");
1673 g_return_if_fail (label && GL_IS_LABEL (label));
1675 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1676 !gl_label_is_selection_atomic (label));
1678 gl_label_checkpoint (label, _("Align right"));
1680 begin_selection_op (label);
1682 selection_list = gl_label_get_selection_list (label);
1684 /* find left most edge */
1686 object = GL_LABEL_OBJECT (p->data);
1688 gl_label_object_get_extent (object, &obj_extent);
1689 x2_max = obj_extent.x2;
1690 for (p = p->next; p != NULL; p = p->next)
1692 object = GL_LABEL_OBJECT (p->data);
1694 gl_label_object_get_extent (object, &obj_extent);
1695 if ( obj_extent.x2 > x2_max ) x2_max = obj_extent.x2;
1698 /* now adjust the object positions to line up the left edges */
1699 for (p = selection_list; p != NULL; p = p->next)
1701 object = GL_LABEL_OBJECT (p->data);
1703 gl_label_object_get_extent (object, &obj_extent);
1704 dx = x2_max - obj_extent.x2;
1705 gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1708 g_list_free (selection_list);
1710 end_selection_op (label);
1712 gl_debug (DEBUG_LABEL, "END");
1716 /*****************************************************************************/
1717 /* Align selected objects to horizontal center of objects. */
1718 /*****************************************************************************/
1720 gl_label_align_selection_hcenter (glLabel *label)
1722 GList *selection_list;
1724 glLabelObject *object;
1728 glLabelRegion obj_extent;
1732 gl_debug (DEBUG_LABEL, "START");
1734 g_return_if_fail (label && GL_IS_LABEL (label));
1736 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1737 !gl_label_is_selection_atomic (label));
1739 gl_label_checkpoint (label, _("Align horizontal center"));
1741 begin_selection_op (label);
1743 selection_list = gl_label_get_selection_list (label);
1745 /* find average center of objects */
1748 for (p = selection_list; p != NULL; p = p->next)
1750 object = GL_LABEL_OBJECT (p->data);
1752 gl_label_object_get_extent (object, &obj_extent);
1753 xsum += (obj_extent.x1 + obj_extent.x2) / 2.0;
1758 /* find center of object closest to average center */
1760 object = GL_LABEL_OBJECT (p->data);
1762 gl_label_object_get_extent (object, &obj_extent);
1763 dxmin = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
1764 xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
1765 for (p = p->next; p != NULL; p = p->next)
1767 object = GL_LABEL_OBJECT (p->data);
1769 gl_label_object_get_extent (object, &obj_extent);
1770 dx = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
1774 xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
1778 /* now adjust the object positions to line up this center */
1779 for (p = selection_list; p != NULL; p = p->next)
1781 object = GL_LABEL_OBJECT (p->data);
1783 gl_label_object_get_extent (object, &obj_extent);
1784 dx = xcenter - (obj_extent.x1 + obj_extent.x2)/2.0;
1785 gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1788 g_list_free (selection_list);
1790 end_selection_op (label);
1792 gl_debug (DEBUG_LABEL, "END");
1796 /*****************************************************************************/
1797 /* Align selected objects to top most edge. */
1798 /*****************************************************************************/
1800 gl_label_align_selection_top (glLabel *label)
1802 GList *selection_list;
1804 glLabelObject *object;
1806 glLabelRegion obj_extent;
1808 gl_debug (DEBUG_LABEL, "START");
1810 g_return_if_fail (label && GL_IS_LABEL (label));
1812 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1813 !gl_label_is_selection_atomic (label));
1815 gl_label_checkpoint (label, _("Align tops"));
1817 begin_selection_op (label);
1819 selection_list = gl_label_get_selection_list (label);
1821 /* find top most edge */
1823 object = GL_LABEL_OBJECT (p->data);
1825 gl_label_object_get_extent (object, &obj_extent);
1826 y1_min = obj_extent.y1;
1827 for (p = p->next; p != NULL; p = p->next)
1829 object = GL_LABEL_OBJECT (p->data);
1831 gl_label_object_get_extent (object, &obj_extent);
1832 if ( obj_extent.y1 < y1_min ) y1_min = obj_extent.y1;
1835 /* now adjust the object positions to line up the top edges */
1836 for (p = selection_list; p != NULL; p = p->next)
1838 object = GL_LABEL_OBJECT (p->data);
1840 gl_label_object_get_extent (object, &obj_extent);
1841 dy = y1_min - obj_extent.y1;
1842 gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1845 g_list_free (selection_list);
1847 end_selection_op (label);
1849 gl_debug (DEBUG_LABEL, "END");
1853 /*****************************************************************************/
1854 /* Align selected objects to bottom most edge. */
1855 /*****************************************************************************/
1857 gl_label_align_selection_bottom (glLabel *label)
1859 GList *selection_list;
1861 glLabelObject *object;
1863 glLabelRegion obj_extent;
1865 gl_debug (DEBUG_LABEL, "START");
1867 g_return_if_fail (label && GL_IS_LABEL (label));
1869 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1870 !gl_label_is_selection_atomic (label));
1872 gl_label_checkpoint (label, _("Align bottoms"));
1874 begin_selection_op (label);
1876 selection_list = gl_label_get_selection_list (label);
1878 /* find bottom most edge */
1880 object = GL_LABEL_OBJECT (p->data);
1882 gl_label_object_get_extent (object, &obj_extent);
1883 y2_max = obj_extent.y2;
1884 for (p = p->next; p != NULL; p = p->next)
1886 object = GL_LABEL_OBJECT (p->data);
1888 gl_label_object_get_extent (object, &obj_extent);
1889 if ( obj_extent.y2 > y2_max ) y2_max = obj_extent.y2;
1892 /* now adjust the object positions to line up the bottom edges */
1893 for (p = selection_list; p != NULL; p = p->next)
1895 object = GL_LABEL_OBJECT (p->data);
1897 gl_label_object_get_extent (object, &obj_extent);
1898 dy = y2_max - obj_extent.y2;
1899 gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1902 g_list_free (selection_list);
1904 end_selection_op (label);
1906 gl_debug (DEBUG_LABEL, "END");
1910 /*****************************************************************************/
1911 /* Align selected objects to viertical center of objects. */
1912 /*****************************************************************************/
1914 gl_label_align_selection_vcenter (glLabel *label)
1916 GList *selection_list;
1918 glLabelObject *object;
1922 glLabelRegion obj_extent;
1926 gl_debug (DEBUG_LABEL, "START");
1928 g_return_if_fail (label && GL_IS_LABEL (label));
1930 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1931 !gl_label_is_selection_atomic (label));
1933 gl_label_checkpoint (label, _("Align vertical center"));
1935 begin_selection_op (label);
1937 selection_list = gl_label_get_selection_list (label);
1939 /* find average center of objects */
1942 for (p = selection_list; p != NULL; p = p->next)
1944 object = GL_LABEL_OBJECT (p->data);
1946 gl_label_object_get_extent (object, &obj_extent);
1947 ysum += (obj_extent.y1 + obj_extent.y2) / 2.0;
1952 /* find center of object closest to average center */
1954 object = GL_LABEL_OBJECT (p->data);
1956 gl_label_object_get_extent (object, &obj_extent);
1957 dymin = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
1958 ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
1959 for (p = p->next; p != NULL; p = p->next)
1961 object = GL_LABEL_OBJECT (p->data);
1963 gl_label_object_get_extent (object, &obj_extent);
1964 dy = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
1968 ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
1972 /* now adjust the object positions to line up this center */
1973 for (p = selection_list; p != NULL; p = p->next)
1975 object = GL_LABEL_OBJECT (p->data);
1977 gl_label_object_get_extent (object, &obj_extent);
1978 dy = ycenter - (obj_extent.y1 + obj_extent.y2)/2.0;
1979 gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1982 g_list_free (selection_list);
1984 end_selection_op (label);
1986 gl_debug (DEBUG_LABEL, "END");
1990 /*****************************************************************************/
1991 /* Center selected objects to in center of label. */
1992 /*****************************************************************************/
1994 gl_label_center_selection_horiz (glLabel *label)
1996 GList *selection_list;
1998 glLabelObject *object;
2000 gdouble x_label_center;
2001 gdouble x_obj_center;
2002 glLabelRegion obj_extent;
2005 gl_debug (DEBUG_LABEL, "START");
2007 g_return_if_fail (label && GL_IS_LABEL (label));
2009 g_return_if_fail (!gl_label_is_selection_empty (label));
2011 gl_label_checkpoint (label, _("Center horizontally"));
2013 begin_selection_op (label);
2015 gl_label_get_size (label, &w, &h);
2016 x_label_center = w / 2.0;
2018 /* adjust the object positions */
2019 selection_list = gl_label_get_selection_list (label);
2020 for (p = selection_list; p != NULL; p = p->next)
2022 object = GL_LABEL_OBJECT (p->data);
2024 gl_label_object_get_extent (object, &obj_extent);
2025 x_obj_center = (obj_extent.x1 + obj_extent.x2) / 2.0;
2026 dx = x_label_center - x_obj_center;
2027 gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
2029 g_list_free (selection_list);
2031 end_selection_op (label);
2033 gl_debug (DEBUG_LABEL, "END");
2037 /*****************************************************************************/
2038 /* Center selected objects to in center of label. */
2039 /*****************************************************************************/
2041 gl_label_center_selection_vert (glLabel *label)
2043 GList *selection_list;
2045 glLabelObject *object;
2047 gdouble y_label_center;
2048 gdouble y_obj_center;
2049 glLabelRegion obj_extent;
2052 gl_debug (DEBUG_LABEL, "START");
2054 g_return_if_fail (label && GL_IS_LABEL (label));
2056 g_return_if_fail (!gl_label_is_selection_empty (label));
2058 gl_label_checkpoint (label, _("Center vertically"));
2060 begin_selection_op (label);
2062 gl_label_get_size (label, &w, &h);
2063 y_label_center = h / 2.0;
2065 /* adjust the object positions */
2066 selection_list = gl_label_get_selection_list (label);
2067 for (p = selection_list; p != NULL; p = p->next)
2069 object = GL_LABEL_OBJECT (p->data);
2071 gl_label_object_get_extent (object, &obj_extent);
2072 y_obj_center = (obj_extent.y1 + obj_extent.y2) / 2.0;
2073 dy = y_label_center - y_obj_center;
2074 gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
2076 g_list_free (selection_list);
2078 end_selection_op (label);
2080 gl_debug (DEBUG_LABEL, "END");
2084 /*****************************************************************************/
2085 /* Move selected objects */
2086 /*****************************************************************************/
2088 gl_label_move_selection (glLabel *label,
2092 GList *selection_list;
2094 glLabelObject *object;
2096 gl_debug (DEBUG_LABEL, "START");
2098 g_return_if_fail (label && GL_IS_LABEL (label));
2100 begin_selection_op (label);
2102 selection_list = gl_label_get_selection_list (label);
2104 for (p = selection_list; p != NULL; p = p->next)
2106 object = GL_LABEL_OBJECT (p->data);
2108 gl_label_object_set_position_relative (object, dx, dy, TRUE);
2111 g_list_free (selection_list);
2113 end_selection_op (label);
2115 gl_debug (DEBUG_LABEL, "END");
2119 /*****************************************************************************/
2120 /* Set font family for all text contained in selected objects. */
2121 /*****************************************************************************/
2123 gl_label_set_selection_font_family (glLabel *label,
2124 const gchar *font_family)
2126 GList *selection_list;
2128 glLabelObject *object;
2130 gl_debug (DEBUG_LABEL, "START");
2132 g_return_if_fail (label && GL_IS_LABEL (label));
2134 begin_selection_op (label);
2136 selection_list = gl_label_get_selection_list (label);
2138 for (p = selection_list; p != NULL; p = p->next)
2140 object = GL_LABEL_OBJECT (p->data);
2141 gl_label_object_set_font_family (object, font_family, TRUE);
2144 g_list_free (selection_list);
2146 end_selection_op (label);
2148 gl_debug (DEBUG_LABEL, "END");
2152 /*****************************************************************************/
2153 /* Set font size for all text contained in selected objects. */
2154 /*****************************************************************************/
2156 gl_label_set_selection_font_size (glLabel *label,
2159 GList *selection_list;
2161 glLabelObject *object;
2163 gl_debug (DEBUG_LABEL, "START");
2165 g_return_if_fail (label && GL_IS_LABEL (label));
2167 begin_selection_op (label);
2169 selection_list = gl_label_get_selection_list (label);
2171 for (p = selection_list; p != NULL; p = p->next)
2173 object = GL_LABEL_OBJECT (p->data);
2174 gl_label_object_set_font_size (object, font_size, TRUE);
2177 g_list_free (selection_list);
2179 end_selection_op (label);
2181 gl_debug (DEBUG_LABEL, "END");
2185 /*****************************************************************************/
2186 /* Set font weight for all text contained in selected objects. */
2187 /*****************************************************************************/
2189 gl_label_set_selection_font_weight (glLabel *label,
2190 PangoWeight font_weight)
2192 GList *selection_list;
2194 glLabelObject *object;
2196 gl_debug (DEBUG_LABEL, "START");
2198 g_return_if_fail (label && GL_IS_LABEL (label));
2200 begin_selection_op (label);
2202 selection_list = gl_label_get_selection_list (label);
2204 for (p = selection_list; p != NULL; p = p->next)
2206 object = GL_LABEL_OBJECT (p->data);
2207 gl_label_object_set_font_weight (object, font_weight, TRUE);
2210 g_list_free (selection_list);
2212 end_selection_op (label);
2214 gl_debug (DEBUG_LABEL, "END");
2218 /*****************************************************************************/
2219 /* Set font italic flag for all text contained in selected objects. */
2220 /*****************************************************************************/
2222 gl_label_set_selection_font_italic_flag (glLabel *label,
2223 gboolean font_italic_flag)
2225 GList *selection_list;
2227 glLabelObject *object;
2229 gl_debug (DEBUG_LABEL, "START");
2231 g_return_if_fail (label && GL_IS_LABEL (label));
2233 begin_selection_op (label);
2235 selection_list = gl_label_get_selection_list (label);
2237 for (p = selection_list; p != NULL; p = p->next)
2239 object = GL_LABEL_OBJECT (p->data);
2240 gl_label_object_set_font_italic_flag (object, font_italic_flag, TRUE);
2243 g_list_free (selection_list);
2245 end_selection_op (label);
2247 gl_debug (DEBUG_LABEL, "END");
2251 /*****************************************************************************/
2252 /* Set text alignment for all text contained in selected objects. */
2253 /*****************************************************************************/
2255 gl_label_set_selection_text_alignment (glLabel *label,
2256 PangoAlignment text_alignment)
2258 GList *selection_list;
2260 glLabelObject *object;
2262 gl_debug (DEBUG_LABEL, "START");
2264 g_return_if_fail (label && GL_IS_LABEL (label));
2266 begin_selection_op (label);
2268 selection_list = gl_label_get_selection_list (label);
2270 for (p = selection_list; p != NULL; p = p->next)
2272 object = GL_LABEL_OBJECT (p->data);
2273 gl_label_object_set_text_alignment (object, text_alignment, TRUE);
2276 g_list_free (selection_list);
2278 end_selection_op (label);
2280 gl_debug (DEBUG_LABEL, "END");
2284 /*****************************************************************************/
2285 /* Set vertical text alignment for all text contained in selected objects. */
2286 /*****************************************************************************/
2288 gl_label_set_selection_text_valignment (glLabel *label,
2289 glValignment text_valignment)
2291 GList *selection_list;
2293 glLabelObject *object;
2295 gl_debug (DEBUG_LABEL, "START");
2297 g_return_if_fail (label && GL_IS_LABEL (label));
2299 begin_selection_op (label);
2301 selection_list = gl_label_get_selection_list (label);
2303 for (p = selection_list; p != NULL; p = p->next)
2305 object = GL_LABEL_OBJECT (p->data);
2306 gl_label_object_set_text_valignment (object, text_valignment, TRUE);
2309 g_list_free (selection_list);
2311 end_selection_op (label);
2313 gl_debug (DEBUG_LABEL, "END");
2317 /*****************************************************************************/
2318 /* Set text line spacing for all text contained in selected objects. */
2319 /*****************************************************************************/
2321 gl_label_set_selection_text_line_spacing (glLabel *label,
2322 gdouble text_line_spacing)
2324 GList *selection_list;
2326 glLabelObject *object;
2328 gl_debug (DEBUG_LABEL, "START");
2330 g_return_if_fail (label && GL_IS_LABEL (label));
2332 begin_selection_op (label);
2334 selection_list = gl_label_get_selection_list (label);
2336 for (p = selection_list; p != NULL; p = p->next)
2338 object = GL_LABEL_OBJECT (p->data);
2339 gl_label_object_set_text_line_spacing (object, text_line_spacing, TRUE);
2342 g_list_free (selection_list);
2344 end_selection_op (label);
2346 gl_debug (DEBUG_LABEL, "END");
2350 /*****************************************************************************/
2351 /* Set text color for all text contained in selected objects. */
2352 /*****************************************************************************/
2354 gl_label_set_selection_text_color (glLabel *label,
2355 glColorNode *text_color_node)
2357 GList *selection_list;
2359 glLabelObject *object;
2361 gl_debug (DEBUG_LABEL, "START");
2363 g_return_if_fail (label && GL_IS_LABEL (label));
2365 begin_selection_op (label);
2367 selection_list = gl_label_get_selection_list (label);
2369 for (p = selection_list; p != NULL; p = p->next)
2371 object = GL_LABEL_OBJECT (p->data);
2372 gl_label_object_set_text_color (object, text_color_node, TRUE);
2375 g_list_free (selection_list);
2377 end_selection_op (label);
2379 gl_debug (DEBUG_LABEL, "END");
2383 /*****************************************************************************/
2384 /* Set fill color for all selected objects. */
2385 /*****************************************************************************/
2387 gl_label_set_selection_fill_color (glLabel *label,
2388 glColorNode *fill_color_node)
2390 GList *selection_list;
2392 glLabelObject *object;
2394 gl_debug (DEBUG_LABEL, "START");
2396 g_return_if_fail (label && GL_IS_LABEL (label));
2398 begin_selection_op (label);
2400 selection_list = gl_label_get_selection_list (label);
2402 for (p = selection_list; p != NULL; p = p->next)
2404 object = GL_LABEL_OBJECT (p->data);
2405 gl_label_object_set_fill_color (object, fill_color_node, TRUE);
2408 g_list_free (selection_list);
2410 end_selection_op (label);
2412 gl_debug (DEBUG_LABEL, "END");
2416 /*****************************************************************************/
2417 /* Set line color for all selected objects. */
2418 /*****************************************************************************/
2420 gl_label_set_selection_line_color (glLabel *label,
2421 glColorNode *line_color_node)
2423 GList *selection_list;
2425 glLabelObject *object;
2427 gl_debug (DEBUG_LABEL, "START");
2429 g_return_if_fail (label && GL_IS_LABEL (label));
2431 begin_selection_op (label);
2433 selection_list = gl_label_get_selection_list (label);
2435 for (p = selection_list; p != NULL; p = p->next)
2437 object = GL_LABEL_OBJECT (p->data);
2438 gl_label_object_set_line_color (object, line_color_node, TRUE);
2441 g_list_free (selection_list);
2443 end_selection_op (label);
2445 gl_debug (DEBUG_LABEL, "END");
2449 /*****************************************************************************/
2450 /* Set line width for all selected objects. */
2451 /*****************************************************************************/
2453 gl_label_set_selection_line_width (glLabel *label,
2456 GList *selection_list;
2458 glLabelObject *object;
2460 gl_debug (DEBUG_LABEL, "START");
2462 g_return_if_fail (label && GL_IS_LABEL (label));
2464 begin_selection_op (label);
2466 selection_list = gl_label_get_selection_list (label);
2468 for (p = selection_list; p != NULL; p = p->next)
2470 object = GL_LABEL_OBJECT (p->data);
2471 gl_label_object_set_line_width (object, line_width, TRUE);
2474 g_list_free (selection_list);
2476 end_selection_op (label);
2478 gl_debug (DEBUG_LABEL, "END");
2482 /*****************************************************************************/
2483 /* "Cut" selected items and place on clipboard. */
2484 /*****************************************************************************/
2486 gl_label_cut_selection (glLabel *label)
2488 gl_debug (DEBUG_LABEL, "START");
2490 g_return_if_fail (label && GL_IS_LABEL (label));
2492 gl_label_copy_selection (label);
2493 gl_label_delete_selection (label);
2495 gl_debug (DEBUG_LABEL, "END");
2499 /*****************************************************************************/
2500 /* "Copy" selected items to clipboard. */
2501 /*****************************************************************************/
2503 gl_label_copy_selection (glLabel *label)
2505 GtkClipboard *clipboard;
2506 GList *selection_list;
2507 glLabel *label_copy;
2509 glLabelObject *object;
2510 glXMLLabelStatus status;
2512 ClipboardData *data;
2514 static GtkTargetEntry glabels_targets[] = { { "application/glabels", 0, 0 },
2515 { "text/xml", 0, 0 },
2518 GtkTargetList *target_list;
2519 GtkTargetEntry *target_table;
2522 gl_debug (DEBUG_LABEL, "START");
2524 g_return_if_fail (label && GL_IS_LABEL (label));
2526 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2528 selection_list = gl_label_get_selection_list (label);
2533 data = g_new0 (ClipboardData, 1);
2535 target_list = gtk_target_list_new (glabels_targets, G_N_ELEMENTS(glabels_targets));
2538 * Serialize selection by encoding as an XML label document.
2540 label_copy = GL_LABEL(gl_label_new ());
2542 gl_label_set_template (label_copy, label->priv->template, FALSE);
2543 gl_label_set_rotate_flag (label_copy, label->priv->rotate_flag, FALSE);
2545 for (p = selection_list; p != NULL; p = p->next)
2547 object = GL_LABEL_OBJECT (p->data);
2549 gl_label_add_object (label_copy, gl_label_object_dup (object, label_copy));
2552 data->xml_buffer = gl_xml_label_save_buffer (label_copy, &status);
2554 g_object_unref (G_OBJECT (label_copy));
2558 * Is it an atomic text selection? If so, also make available as text.
2560 if ( gl_label_is_selection_atomic (label) &&
2561 GL_IS_LABEL_TEXT (selection_list->data) )
2563 glLabelText *text_object = GL_LABEL_TEXT (selection_list->data);
2565 gtk_target_list_add_text_targets (target_list, 1);
2567 data->text = gl_label_text_get_text (text_object);
2572 * Is it an atomic image selection? If so, also make available as pixbuf.
2574 if ( gl_label_is_selection_atomic (label) &&
2575 GL_IS_LABEL_IMAGE (selection_list->data) )
2577 glLabelImage *image_object = GL_LABEL_IMAGE (selection_list->data);
2578 GdkPixbuf *pixbuf = gl_label_image_get_pixbuf (image_object, NULL);
2582 gtk_target_list_add_image_targets (target_list, 2, TRUE);
2583 data->pixbuf = pixbuf;
2588 target_table = gtk_target_table_new_from_list (target_list, &n_targets);
2590 gtk_clipboard_set_with_data (clipboard,
2591 target_table, n_targets,
2592 (GtkClipboardGetFunc)clipboard_get_cb,
2593 (GtkClipboardClearFunc)clipboard_clear_cb,
2596 gtk_target_table_free (target_table, n_targets);
2597 gtk_target_list_unref (target_list);
2601 g_list_free (selection_list);
2603 gl_debug (DEBUG_LABEL, "END");
2607 /*****************************************************************************/
2608 /* "Paste" from clipboard. */
2609 /*****************************************************************************/
2611 gl_label_paste (glLabel *label)
2613 GtkClipboard *clipboard;
2615 gl_debug (DEBUG_LABEL, "START");
2617 g_return_if_fail (label && GL_IS_LABEL (label));
2619 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2621 gtk_clipboard_request_targets (clipboard,
2622 (GtkClipboardTargetsReceivedFunc)receive_targets_cb,
2625 gl_debug (DEBUG_LABEL, "END");
2629 /*****************************************************************************/
2630 /* Is there anything that can be pasted? */
2631 /*****************************************************************************/
2633 gl_label_can_paste (glLabel *label)
2635 GtkClipboard *clipboard;
2638 gl_debug (DEBUG_LABEL, "START");
2640 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2642 can_flag = gtk_clipboard_wait_is_target_available (clipboard,
2643 gdk_atom_intern("application/glabels", TRUE))
2644 || gtk_clipboard_wait_is_text_available (clipboard)
2645 || gtk_clipboard_wait_is_image_available (clipboard);
2647 gl_debug (DEBUG_LABEL, "END");
2652 /****************************************************************************/
2653 /* Clipboard "Get" function. */
2654 /****************************************************************************/
2656 clipboard_get_cb (GtkClipboard *clipboard,
2657 GtkSelectionData *selection_data,
2659 ClipboardData *data)
2661 gl_debug (DEBUG_LABEL, "START");
2667 gtk_selection_data_set (selection_data,
2668 gtk_selection_data_get_target (selection_data),
2670 (guchar *)data->xml_buffer, strlen (data->xml_buffer));
2674 gtk_selection_data_set_text (selection_data, data->text, -1);
2678 gtk_selection_data_set_pixbuf (selection_data, data->pixbuf);
2682 g_assert_not_reached ();
2687 gl_debug (DEBUG_LABEL, "END");
2691 /****************************************************************************/
2692 /* Clipboard "Clear" function. */
2693 /****************************************************************************/
2695 clipboard_clear_cb (GtkClipboard *clipboard,
2696 ClipboardData *data)
2698 gl_debug (DEBUG_LABEL, "START");
2700 g_free (data->xml_buffer);
2701 g_free (data->text);
2704 g_object_unref (data->pixbuf);
2709 gl_debug (DEBUG_LABEL, "END");
2713 /****************************************************************************/
2714 /* Deal with clipboard data. */
2715 /****************************************************************************/
2717 receive_targets_cb (GtkClipboard *clipboard,
2725 * Application/glabels
2727 for ( i = 0; i < n_targets; i++ )
2729 if ( strcmp(gdk_atom_name(targets[i]), "application/glabels") == 0 )
2731 gtk_clipboard_request_contents (clipboard,
2732 gdk_atom_intern("application/glabels", TRUE),
2733 (GtkClipboardReceivedFunc)paste_xml_received_cb,
2742 if ( gtk_targets_include_text (targets, n_targets) )
2744 gtk_clipboard_request_text (clipboard,
2745 (GtkClipboardTextReceivedFunc)paste_text_received_cb,
2753 if ( gtk_targets_include_image (targets, n_targets, TRUE) )
2755 gtk_clipboard_request_image (clipboard,
2756 (GtkClipboardImageReceivedFunc)paste_image_received_cb,
2763 /****************************************************************************/
2764 /* Paste received glabels XML callback. */
2765 /****************************************************************************/
2767 paste_xml_received_cb (GtkClipboard *clipboard,
2768 GtkSelectionData *selection_data,
2772 glLabel *label_copy;
2773 glXMLLabelStatus status;
2775 glLabelObject *object, *newobject;
2777 gl_debug (DEBUG_LABEL, "START");
2779 gl_label_checkpoint (label, _("Paste"));
2781 xml_buffer = (gchar *)gtk_selection_data_get_data (selection_data);
2784 * Deserialize XML label document and extract objects.
2786 label_copy = gl_xml_label_open_buffer (xml_buffer, &status);
2789 gl_label_unselect_all (label);
2791 for (p = label_copy->priv->object_list; p != NULL; p = p->next)
2793 object = (glLabelObject *) p->data;
2794 newobject = gl_label_object_dup (object, label);
2795 gl_label_add_object( label, newobject );
2797 gl_label_select_object (label, newobject);
2799 gl_debug (DEBUG_LABEL, "object pasted");
2802 g_object_unref (G_OBJECT (label_copy));
2805 gl_debug (DEBUG_LABEL, "END");
2809 /****************************************************************************/
2810 /* Paste received text callback. */
2811 /****************************************************************************/
2813 paste_text_received_cb (GtkClipboard *clipboard,
2817 glLabelObject *object;
2819 gl_debug (DEBUG_LABEL, "START");
2821 gl_label_checkpoint (label, _("Paste"));
2823 gl_label_unselect_all (label);
2825 object = GL_LABEL_OBJECT (gl_label_text_new (label, FALSE));
2826 gl_label_text_set_text (GL_LABEL_TEXT (object), text, FALSE);
2827 gl_label_object_set_position (object, 18, 18, FALSE);
2829 gl_label_select_object (label, object);
2831 gl_debug (DEBUG_LABEL, "END");
2835 /****************************************************************************/
2836 /* Paste received image callback. */
2837 /****************************************************************************/
2839 paste_image_received_cb (GtkClipboard *clipboard,
2843 glLabelObject *object;
2845 gl_debug (DEBUG_LABEL, "START");
2847 gl_label_checkpoint (label, _("Paste"));
2849 gl_label_unselect_all (label);
2851 object = GL_LABEL_OBJECT (gl_label_image_new (label, FALSE));
2852 gl_label_image_set_pixbuf (GL_LABEL_IMAGE (object), pixbuf, FALSE);
2853 gl_label_object_set_position (object, 18, 18, FALSE);
2855 gl_label_select_object (label, object);
2857 gl_debug (DEBUG_LABEL, "END");
2861 /****************************************************************************/
2862 /* Set default font family. */
2863 /****************************************************************************/
2865 gl_label_set_default_font_family (glLabel *label,
2866 const gchar *font_family)
2868 gl_debug (DEBUG_LABEL, "START");
2870 g_return_if_fail (label && GL_IS_LABEL (label));
2872 g_free (label->priv->default_font_family);
2873 label->priv->default_font_family = g_strdup (font_family);
2875 gl_debug (DEBUG_LABEL, "END");
2879 /****************************************************************************/
2880 /* Set default font size. */
2881 /****************************************************************************/
2883 gl_label_set_default_font_size (glLabel *label,
2886 gl_debug (DEBUG_LABEL, "START");
2888 g_return_if_fail (label && GL_IS_LABEL (label));
2890 label->priv->default_font_size = font_size;
2892 gl_debug (DEBUG_LABEL, "END");
2896 /****************************************************************************/
2897 /* Set default font weight. */
2898 /****************************************************************************/
2900 gl_label_set_default_font_weight (glLabel *label,
2901 PangoWeight font_weight)
2903 gl_debug (DEBUG_LABEL, "START");
2905 g_return_if_fail (label && GL_IS_LABEL (label));
2907 label->priv->default_font_weight = font_weight;
2909 gl_debug (DEBUG_LABEL, "END");
2913 /****************************************************************************/
2914 /* Set default font italic flag. */
2915 /****************************************************************************/
2917 gl_label_set_default_font_italic_flag (glLabel *label,
2918 gboolean font_italic_flag)
2920 gl_debug (DEBUG_LABEL, "START");
2922 g_return_if_fail (label && GL_IS_LABEL (label));
2924 label->priv->default_font_italic_flag = font_italic_flag;
2926 gl_debug (DEBUG_LABEL, "END");
2930 /****************************************************************************/
2931 /* Set default text color. */
2932 /****************************************************************************/
2934 gl_label_set_default_text_color (glLabel *label,
2937 gl_debug (DEBUG_LABEL, "START");
2939 g_return_if_fail (label && GL_IS_LABEL (label));
2941 label->priv->default_text_color = text_color;
2943 gl_debug (DEBUG_LABEL, "END");
2947 /****************************************************************************/
2948 /* Set default text alignment. */
2949 /****************************************************************************/
2951 gl_label_set_default_text_alignment (glLabel *label,
2952 PangoAlignment text_alignment)
2954 gl_debug (DEBUG_LABEL, "START");
2956 g_return_if_fail (label && GL_IS_LABEL (label));
2958 label->priv->default_text_alignment = text_alignment;
2959 gl_debug (DEBUG_LABEL, "END");
2963 /****************************************************************************/
2964 /* Set default vertical text alignment. */
2965 /****************************************************************************/
2967 gl_label_set_default_text_valignment (glLabel *label,
2968 glValignment text_valignment)
2970 gl_debug (DEBUG_LABEL, "START");
2972 g_return_if_fail (label && GL_IS_LABEL (label));
2974 label->priv->default_text_valignment = text_valignment;
2975 gl_debug (DEBUG_LABEL, "END");
2979 /****************************************************************************/
2980 /* Set default text line spacing. */
2981 /****************************************************************************/
2983 gl_label_set_default_text_line_spacing (glLabel *label,
2984 gdouble text_line_spacing)
2986 gl_debug (DEBUG_LABEL, "START");
2988 g_return_if_fail (label && GL_IS_LABEL (label));
2990 label->priv->default_text_line_spacing = text_line_spacing;
2992 gl_debug (DEBUG_LABEL, "END");
2996 /****************************************************************************/
2997 /* Set default line width. */
2998 /****************************************************************************/
3000 gl_label_set_default_line_width (glLabel *label,
3003 gl_debug (DEBUG_LABEL, "START");
3005 g_return_if_fail (label && GL_IS_LABEL (label));
3007 label->priv->default_line_width = line_width;
3009 gl_debug (DEBUG_LABEL, "END");
3013 /****************************************************************************/
3014 /* Set default line color. */
3015 /****************************************************************************/
3017 gl_label_set_default_line_color (glLabel *label,
3020 gl_debug (DEBUG_LABEL, "START");
3022 g_return_if_fail (label && GL_IS_LABEL (label));
3024 label->priv->default_line_color = line_color;
3026 gl_debug (DEBUG_LABEL, "END");
3030 /****************************************************************************/
3031 /* Set default fill color. */
3032 /****************************************************************************/
3034 gl_label_set_default_fill_color (glLabel *label,
3037 gl_debug (DEBUG_LABEL, "START");
3039 g_return_if_fail (label && GL_IS_LABEL (label));
3041 label->priv->default_fill_color = fill_color;
3043 gl_debug (DEBUG_LABEL, "END");
3047 /****************************************************************************/
3048 /* Get default font family. */
3049 /****************************************************************************/
3051 gl_label_get_default_font_family (glLabel *label)
3053 gl_debug (DEBUG_LABEL, "START");
3055 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
3057 gl_debug (DEBUG_LABEL, "END");
3059 return g_strdup (label->priv->default_font_family);
3063 /****************************************************************************/
3064 /* Get default font size. */
3065 /****************************************************************************/
3067 gl_label_get_default_font_size (glLabel *label)
3069 gl_debug (DEBUG_LABEL, "START");
3071 g_return_val_if_fail (label && GL_IS_LABEL (label), 12.0);
3073 gl_debug (DEBUG_LABEL, "END");
3075 return label->priv->default_font_size;
3079 /****************************************************************************/
3080 /* Get default font weight. */
3081 /****************************************************************************/
3083 gl_label_get_default_font_weight (glLabel *label)
3085 gl_debug (DEBUG_LABEL, "START");
3087 g_return_val_if_fail (label && GL_IS_LABEL (label), PANGO_WEIGHT_NORMAL);
3089 gl_debug (DEBUG_LABEL, "END");
3091 return label->priv->default_font_weight;
3095 /****************************************************************************/
3096 /* Get default font italic flag. */
3097 /****************************************************************************/
3099 gl_label_get_default_font_italic_flag (glLabel *label)
3101 gl_debug (DEBUG_LABEL, "START");
3103 g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
3105 gl_debug (DEBUG_LABEL, "END");
3107 return label->priv->default_font_italic_flag;
3111 /****************************************************************************/
3112 /* Get default text color. */
3113 /****************************************************************************/
3115 gl_label_get_default_text_color (glLabel *label)
3117 gl_debug (DEBUG_LABEL, "START");
3119 g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
3121 gl_debug (DEBUG_LABEL, "END");
3123 return label->priv->default_text_color;
3127 /****************************************************************************/
3128 /* Get default text alignment. */
3129 /****************************************************************************/
3131 gl_label_get_default_text_alignment (glLabel *label)
3133 gl_debug (DEBUG_LABEL, "START");
3135 g_return_val_if_fail (label && GL_IS_LABEL (label), PANGO_ALIGN_LEFT);
3137 gl_debug (DEBUG_LABEL, "END");
3139 return label->priv->default_text_alignment;
3143 /****************************************************************************/
3144 /* Get default vertical text alignment. */
3145 /****************************************************************************/
3147 gl_label_get_default_text_valignment (glLabel *label)
3149 gl_debug (DEBUG_LABEL, "START");
3151 g_return_val_if_fail (label && GL_IS_LABEL (label), GL_VALIGN_TOP);
3153 gl_debug (DEBUG_LABEL, "END");
3155 return label->priv->default_text_valignment;
3159 /****************************************************************************/
3160 /* Get default text line spacing. */
3161 /****************************************************************************/
3163 gl_label_get_default_text_line_spacing (glLabel *label)
3165 gl_debug (DEBUG_LABEL, "START");
3167 g_return_val_if_fail (label && GL_IS_LABEL (label), 1.0);
3169 gl_debug (DEBUG_LABEL, "END");
3171 return label->priv->default_text_line_spacing;
3175 /****************************************************************************/
3176 /* Get default line width. */
3177 /****************************************************************************/
3179 gl_label_get_default_line_width (glLabel *label)
3181 gl_debug (DEBUG_LABEL, "START");
3183 g_return_val_if_fail (label && GL_IS_LABEL (label), 1.0);
3185 gl_debug (DEBUG_LABEL, "END");
3187 return label->priv->default_line_width;
3191 /****************************************************************************/
3192 /* Get default line color. */
3193 /****************************************************************************/
3195 gl_label_get_default_line_color (glLabel *label)
3197 gl_debug (DEBUG_LABEL, "START");
3199 g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
3201 gl_debug (DEBUG_LABEL, "END");
3203 return label->priv->default_line_color;
3207 /****************************************************************************/
3208 /* Get default fill color. */
3209 /****************************************************************************/
3211 gl_label_get_default_fill_color (glLabel *label)
3213 gl_debug (DEBUG_LABEL, "START");
3215 g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
3217 gl_debug (DEBUG_LABEL, "END");
3219 return label->priv->default_fill_color;
3223 /****************************************************************************/
3225 /****************************************************************************/
3227 gl_label_draw (glLabel *label,
3229 gboolean screen_flag,
3230 glMergeRecord *record)
3233 glLabelObject *object;
3235 g_return_if_fail (label && GL_IS_LABEL (label));
3237 for (p_obj = label->priv->object_list; p_obj != NULL; p_obj = p_obj->next)
3239 object = GL_LABEL_OBJECT (p_obj->data);
3241 gl_label_object_draw (object, cr, screen_flag, record);
3246 /****************************************************************************/
3247 /* Get object located at coordinates. */
3248 /****************************************************************************/
3249 glLabelObject *gl_label_object_at (glLabel *label,
3255 glLabelObject *object;
3257 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
3259 for (p_obj = g_list_last (label->priv->object_list); p_obj != NULL; p_obj = p_obj->prev)
3261 object = GL_LABEL_OBJECT (p_obj->data);
3263 if (gl_label_object_is_located_at (object, cr, x_pixels, y_pixels))
3274 /****************************************************************************/
3275 /* Return handle and associated object at coordinates. */
3276 /****************************************************************************/
3278 gl_label_get_handle_at (glLabel *label,
3282 glLabelObjectHandle *handle)
3284 GList *selection_list;
3286 glLabelObject *object;
3288 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
3290 selection_list = gl_label_get_selection_list (label);
3292 for (p_obj = g_list_last (selection_list); p_obj != NULL; p_obj = p_obj->prev)
3295 object = GL_LABEL_OBJECT (p_obj->data);
3297 if ((*handle = gl_label_object_handle_at (object, cr, x_pixels, y_pixels)))
3299 g_list_free (selection_list);
3305 g_list_free (selection_list);
3307 *handle = GL_LABEL_OBJECT_HANDLE_NONE;
3312 /****************************************************************************/
3313 /* Checkpoint state. */
3314 /****************************************************************************/
3316 gl_label_checkpoint (glLabel *this,
3317 const gchar *description)
3321 gl_debug (DEBUG_LABEL, "START");
3324 * Do not perform consecutive checkpoints that are identical.
3325 * E.g. moving an object by dragging, would produce a large number
3326 * of incremental checkpoints -- what we really want is a single
3327 * checkpoint so that we can undo the entire dragging effort with
3330 if ( this->priv->cp_cleared_flag
3331 || (this->priv->cp_desc == NULL)
3332 || (strcmp (description, this->priv->cp_desc) != 0) )
3335 /* Sever old redo "thread" */
3336 stack_clear (this->priv->redo_stack);
3338 /* Save state onto undo stack. */
3339 state = state_new (this, description);
3340 stack_push_state (this->priv->undo_stack, state);
3342 /* Track consecutive checkpoints. */
3343 this->priv->cp_cleared_flag = FALSE;
3344 this->priv->cp_desc = g_strdup (description);
3347 gl_debug (DEBUG_LABEL, "END");
3351 /****************************************************************************/
3353 /****************************************************************************/
3355 gl_label_undo (glLabel *this)
3360 gl_debug (DEBUG_LABEL, "START");
3362 state_old = stack_pop_state (this->priv->undo_stack);
3363 state_now = state_new (this, state_old->description);
3365 stack_push_state (this->priv->redo_stack, state_now);
3367 state_restore (state_old, this);
3368 state_free (state_old);
3370 this->priv->cp_cleared_flag = TRUE;
3372 gl_debug (DEBUG_LABEL, "END");
3376 /****************************************************************************/
3378 /****************************************************************************/
3380 gl_label_redo (glLabel *this)
3385 gl_debug (DEBUG_LABEL, "START");
3387 state_old = stack_pop_state (this->priv->redo_stack);
3388 state_now = state_new (this, state_old->description);
3390 stack_push_state (this->priv->undo_stack, state_now);
3392 state_restore (state_old, this);
3393 state_free (state_old);
3395 this->priv->cp_cleared_flag = TRUE;
3397 gl_debug (DEBUG_LABEL, "END");
3401 /****************************************************************************/
3403 /****************************************************************************/
3405 gl_label_can_undo (glLabel *this)
3407 return (!g_queue_is_empty (this->priv->undo_stack));
3411 /****************************************************************************/
3413 /****************************************************************************/
3415 gl_label_can_redo (glLabel *this)
3417 return (!g_queue_is_empty (this->priv->redo_stack));
3421 /****************************************************************************/
3422 /* Get undo description string. */
3423 /****************************************************************************/
3425 gl_label_get_undo_description (glLabel *this)
3430 state = g_queue_peek_head (this->priv->undo_stack);
3433 description = g_strdup (state->description);
3437 description = g_strdup ("");
3444 /****************************************************************************/
3445 /* Get redo description string. */
3446 /****************************************************************************/
3448 gl_label_get_redo_description (glLabel *this)
3453 state = g_queue_peek_head (this->priv->redo_stack);
3456 description = g_strdup (state->description);
3460 description = g_strdup ("");
3467 /****************************************************************************/
3468 /* Clear undo or redo stack. */
3469 /****************************************************************************/
3471 stack_clear (GQueue *stack)
3475 gl_debug (DEBUG_LABEL, "START");
3477 while ( (state = g_queue_pop_head (stack)) != NULL )
3482 gl_debug (DEBUG_LABEL, "END");
3486 /****************************************************************************/
3487 /* Push state onto stack. */
3488 /****************************************************************************/
3490 stack_push_state (GQueue *stack,
3493 gl_debug (DEBUG_LABEL, "START");
3495 g_queue_push_head( stack, state );
3497 gl_debug (DEBUG_LABEL, "END");
3501 /****************************************************************************/
3502 /* Pop state from stack. */
3503 /****************************************************************************/
3505 stack_pop_state (GQueue *stack)
3509 gl_debug (DEBUG_LABEL, "START");
3511 state = g_queue_pop_head (stack);
3513 gl_debug (DEBUG_LABEL, "END");
3518 /****************************************************************************/
3519 /* New state from label. */
3520 /****************************************************************************/
3522 state_new (glLabel *this,
3523 const gchar *description)
3527 glLabelObject *object;
3529 gl_debug (DEBUG_LABEL, "START");
3531 state = g_new0 (State, 1);
3533 state->description = g_strdup (description);
3535 state->template = lgl_template_dup (this->priv->template);
3536 state->rotate_flag = this->priv->rotate_flag;
3538 for ( p_obj = this->priv->object_list; p_obj != NULL; p_obj = p_obj->next )
3540 object = GL_LABEL_OBJECT (p_obj->data);
3542 state->object_list = g_list_append (state->object_list,
3543 gl_label_object_dup (object, this));
3546 state->merge = gl_merge_dup (this->priv->merge);
3548 state->modified_flag = this->priv->modified_flag;
3549 state->time_stamp = this->priv->time_stamp;
3552 gl_debug (DEBUG_LABEL, "END");
3557 /****************************************************************************/
3558 /* Restore label from saved state. */
3559 /****************************************************************************/
3561 state_free (State *state)
3565 gl_debug (DEBUG_LABEL, "START");
3567 g_free (state->description);
3569 lgl_template_free (state->template);
3572 g_object_unref (G_OBJECT (state->merge));
3575 for ( p_obj = state->object_list; p_obj != NULL; p_obj = p_obj->next )
3577 g_object_unref (G_OBJECT (p_obj->data));
3579 g_list_free (state->object_list);
3583 gl_debug (DEBUG_LABEL, "END");
3587 /****************************************************************************/
3588 /* Restore label from saved state. */
3589 /****************************************************************************/
3591 state_restore (State *state,
3595 GList *p_obj, *p_next;
3596 glLabelObject *object;
3598 gl_debug (DEBUG_LABEL, "START");
3600 gl_label_set_rotate_flag (this, state->rotate_flag, FALSE);
3601 gl_label_set_template (this, state->template, FALSE);
3603 for ( p_obj = this->priv->object_list; p_obj != NULL; p_obj = p_next )
3605 p_next = p_obj->next; /* Hold on to next; delete is destructive */
3606 object = GL_LABEL_OBJECT (p_obj->data);
3608 gl_label_delete_object (this, object);
3611 for ( p_obj = state->object_list; p_obj != NULL; p_obj = p_obj->next )
3613 object = GL_LABEL_OBJECT (p_obj->data);
3615 gl_label_add_object (this, gl_label_object_dup (object, this));
3617 g_signal_emit (G_OBJECT(this), signals[SELECTION_CHANGED], 0);
3619 gl_label_set_merge (this, state->merge, FALSE);
3622 if ( !state->modified_flag &&
3623 (state->time_stamp.tv_sec == this->priv->time_stamp.tv_sec) &&
3624 (state->time_stamp.tv_usec == this->priv->time_stamp.tv_usec) )
3626 gl_label_clear_modified (this);
3629 gl_debug (DEBUG_LABEL, "END");
3636 * Local Variables: -- emacs
3638 * c-basic-offset: 8 -- emacs
3639 * tab-width: 8 -- emacs
3640 * indent-tabs-mode: nil -- emacs