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 second 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);
1458 end_selection_op (label);
1460 gl_debug (DEBUG_LABEL, "END");
1464 /*****************************************************************************/
1465 /* Rotate selected objects 90 degrees left. */
1466 /*****************************************************************************/
1468 gl_label_rotate_selection_left (glLabel *label)
1470 GList *selection_list;
1472 glLabelObject *object;
1474 gl_debug (DEBUG_LABEL, "START");
1476 g_return_if_fail (label && GL_IS_LABEL (label));
1478 begin_selection_op (label);
1480 gl_label_checkpoint (label, _("Rotate left"));
1482 selection_list = gl_label_get_selection_list (label);
1484 for ( p = selection_list; p != NULL; p = p->next )
1486 object = GL_LABEL_OBJECT (p->data);
1488 gl_label_object_rotate (object, -90.0);
1491 g_list_free (selection_list);
1495 end_selection_op (label);
1497 gl_debug (DEBUG_LABEL, "END");
1501 /*****************************************************************************/
1502 /* Rotate selected objects 90 degrees right. */
1503 /*****************************************************************************/
1505 gl_label_rotate_selection_right (glLabel *label)
1507 GList *selection_list;
1509 glLabelObject *object;
1511 gl_debug (DEBUG_LABEL, "START");
1513 g_return_if_fail (label && GL_IS_LABEL (label));
1515 gl_label_checkpoint (label, _("Rotate right"));
1517 begin_selection_op (label);
1519 selection_list = gl_label_get_selection_list (label);
1521 for ( p = selection_list; p != NULL; p = p->next )
1523 object = GL_LABEL_OBJECT (p->data);
1525 gl_label_object_rotate (object, 90.0);
1528 g_list_free (selection_list);
1532 end_selection_op (label);
1534 gl_debug (DEBUG_LABEL, "END");
1538 /*****************************************************************************/
1539 /* Flip selected objects horizontally. */
1540 /*****************************************************************************/
1542 gl_label_flip_selection_horiz (glLabel *label)
1544 GList *selection_list;
1546 glLabelObject *object;
1548 gl_debug (DEBUG_LABEL, "START");
1550 g_return_if_fail (label && GL_IS_LABEL (label));
1552 gl_label_checkpoint (label, _("Flip horizontally"));
1554 begin_selection_op (label);
1556 selection_list = gl_label_get_selection_list (label);
1558 for ( p = selection_list; p != NULL; p = p->next )
1560 object = GL_LABEL_OBJECT (p->data);
1562 gl_label_object_flip_horiz (object);
1565 g_list_free (selection_list);
1569 end_selection_op (label);
1571 gl_debug (DEBUG_LABEL, "END");
1575 /*****************************************************************************/
1576 /* Flip selected objects vertically. */
1577 /*****************************************************************************/
1579 gl_label_flip_selection_vert (glLabel *label)
1581 GList *selection_list;
1583 glLabelObject *object;
1585 gl_debug (DEBUG_LABEL, "START");
1587 g_return_if_fail (label && GL_IS_LABEL (label));
1589 gl_label_checkpoint (label, _("Flip vertically"));
1591 begin_selection_op (label);
1593 selection_list = gl_label_get_selection_list (label);
1595 for ( p = selection_list; p != NULL; p = p->next )
1597 object = GL_LABEL_OBJECT (p->data);
1599 gl_label_object_flip_vert (object);
1602 g_list_free (selection_list);
1606 end_selection_op (label);
1608 gl_debug (DEBUG_LABEL, "END");
1612 /*****************************************************************************/
1613 /* Align selected objects to left most edge. */
1614 /*****************************************************************************/
1616 gl_label_align_selection_left (glLabel *label)
1618 GList *selection_list;
1620 glLabelObject *object;
1622 glLabelRegion obj_extent;
1624 gl_debug (DEBUG_LABEL, "START");
1626 g_return_if_fail (label && GL_IS_LABEL (label));
1628 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1629 !gl_label_is_selection_atomic (label));
1631 gl_label_checkpoint (label, _("Align left"));
1633 begin_selection_op (label);
1635 selection_list = gl_label_get_selection_list (label);
1637 /* find left most edge */
1639 object = GL_LABEL_OBJECT (p->data);
1641 gl_label_object_get_extent (object, &obj_extent);
1642 x1_min = obj_extent.x1;
1643 for (p = p->next; p != NULL; p = p->next)
1645 object = GL_LABEL_OBJECT (p->data);
1647 gl_label_object_get_extent (object, &obj_extent);
1648 if ( obj_extent.x1 < x1_min ) x1_min = obj_extent.x1;
1651 /* now adjust the object positions to line up the left edges */
1652 for (p = selection_list; p != NULL; p = p->next)
1654 object = GL_LABEL_OBJECT (p->data);
1656 gl_label_object_get_extent (object, &obj_extent);
1657 dx = x1_min - obj_extent.x1;
1658 gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1661 g_list_free (selection_list);
1663 end_selection_op (label);
1665 gl_debug (DEBUG_LABEL, "END");
1669 /*****************************************************************************/
1670 /* Align selected objects to right most edge. */
1671 /*****************************************************************************/
1673 gl_label_align_selection_right (glLabel *label)
1675 GList *selection_list;
1677 glLabelObject *object;
1679 glLabelRegion obj_extent;
1681 gl_debug (DEBUG_LABEL, "START");
1683 g_return_if_fail (label && GL_IS_LABEL (label));
1685 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1686 !gl_label_is_selection_atomic (label));
1688 gl_label_checkpoint (label, _("Align right"));
1690 begin_selection_op (label);
1692 selection_list = gl_label_get_selection_list (label);
1694 /* find left most edge */
1696 object = GL_LABEL_OBJECT (p->data);
1698 gl_label_object_get_extent (object, &obj_extent);
1699 x2_max = obj_extent.x2;
1700 for (p = p->next; p != NULL; p = p->next)
1702 object = GL_LABEL_OBJECT (p->data);
1704 gl_label_object_get_extent (object, &obj_extent);
1705 if ( obj_extent.x2 > x2_max ) x2_max = obj_extent.x2;
1708 /* now adjust the object positions to line up the left edges */
1709 for (p = selection_list; p != NULL; p = p->next)
1711 object = GL_LABEL_OBJECT (p->data);
1713 gl_label_object_get_extent (object, &obj_extent);
1714 dx = x2_max - obj_extent.x2;
1715 gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1718 g_list_free (selection_list);
1720 end_selection_op (label);
1722 gl_debug (DEBUG_LABEL, "END");
1726 /*****************************************************************************/
1727 /* Align selected objects to horizontal center of objects. */
1728 /*****************************************************************************/
1730 gl_label_align_selection_hcenter (glLabel *label)
1732 GList *selection_list;
1734 glLabelObject *object;
1738 glLabelRegion obj_extent;
1742 gl_debug (DEBUG_LABEL, "START");
1744 g_return_if_fail (label && GL_IS_LABEL (label));
1746 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1747 !gl_label_is_selection_atomic (label));
1749 gl_label_checkpoint (label, _("Align horizontal center"));
1751 begin_selection_op (label);
1753 selection_list = gl_label_get_selection_list (label);
1755 /* find average center of objects */
1758 for (p = selection_list; p != NULL; p = p->next)
1760 object = GL_LABEL_OBJECT (p->data);
1762 gl_label_object_get_extent (object, &obj_extent);
1763 xsum += (obj_extent.x1 + obj_extent.x2) / 2.0;
1768 /* find center of object closest to average center */
1770 object = GL_LABEL_OBJECT (p->data);
1772 gl_label_object_get_extent (object, &obj_extent);
1773 dxmin = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
1774 xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
1775 for (p = p->next; p != NULL; p = p->next)
1777 object = GL_LABEL_OBJECT (p->data);
1779 gl_label_object_get_extent (object, &obj_extent);
1780 dx = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
1784 xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
1788 /* now adjust the object positions to line up this center */
1789 for (p = selection_list; p != NULL; p = p->next)
1791 object = GL_LABEL_OBJECT (p->data);
1793 gl_label_object_get_extent (object, &obj_extent);
1794 dx = xcenter - (obj_extent.x1 + obj_extent.x2)/2.0;
1795 gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1798 g_list_free (selection_list);
1800 end_selection_op (label);
1802 gl_debug (DEBUG_LABEL, "END");
1806 /*****************************************************************************/
1807 /* Align selected objects to top most edge. */
1808 /*****************************************************************************/
1810 gl_label_align_selection_top (glLabel *label)
1812 GList *selection_list;
1814 glLabelObject *object;
1816 glLabelRegion obj_extent;
1818 gl_debug (DEBUG_LABEL, "START");
1820 g_return_if_fail (label && GL_IS_LABEL (label));
1822 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1823 !gl_label_is_selection_atomic (label));
1825 gl_label_checkpoint (label, _("Align tops"));
1827 begin_selection_op (label);
1829 selection_list = gl_label_get_selection_list (label);
1831 /* find top most edge */
1833 object = GL_LABEL_OBJECT (p->data);
1835 gl_label_object_get_extent (object, &obj_extent);
1836 y1_min = obj_extent.y1;
1837 for (p = p->next; p != NULL; p = p->next)
1839 object = GL_LABEL_OBJECT (p->data);
1841 gl_label_object_get_extent (object, &obj_extent);
1842 if ( obj_extent.y1 < y1_min ) y1_min = obj_extent.y1;
1845 /* now adjust the object positions to line up the top edges */
1846 for (p = selection_list; p != NULL; p = p->next)
1848 object = GL_LABEL_OBJECT (p->data);
1850 gl_label_object_get_extent (object, &obj_extent);
1851 dy = y1_min - obj_extent.y1;
1852 gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1855 g_list_free (selection_list);
1857 end_selection_op (label);
1859 gl_debug (DEBUG_LABEL, "END");
1863 /*****************************************************************************/
1864 /* Align selected objects to bottom most edge. */
1865 /*****************************************************************************/
1867 gl_label_align_selection_bottom (glLabel *label)
1869 GList *selection_list;
1871 glLabelObject *object;
1873 glLabelRegion obj_extent;
1875 gl_debug (DEBUG_LABEL, "START");
1877 g_return_if_fail (label && GL_IS_LABEL (label));
1879 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1880 !gl_label_is_selection_atomic (label));
1882 gl_label_checkpoint (label, _("Align bottoms"));
1884 begin_selection_op (label);
1886 selection_list = gl_label_get_selection_list (label);
1888 /* find bottom most edge */
1890 object = GL_LABEL_OBJECT (p->data);
1892 gl_label_object_get_extent (object, &obj_extent);
1893 y2_max = obj_extent.y2;
1894 for (p = p->next; p != NULL; p = p->next)
1896 object = GL_LABEL_OBJECT (p->data);
1898 gl_label_object_get_extent (object, &obj_extent);
1899 if ( obj_extent.y2 > y2_max ) y2_max = obj_extent.y2;
1902 /* now adjust the object positions to line up the bottom edges */
1903 for (p = selection_list; p != NULL; p = p->next)
1905 object = GL_LABEL_OBJECT (p->data);
1907 gl_label_object_get_extent (object, &obj_extent);
1908 dy = y2_max - obj_extent.y2;
1909 gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1912 g_list_free (selection_list);
1914 end_selection_op (label);
1916 gl_debug (DEBUG_LABEL, "END");
1920 /*****************************************************************************/
1921 /* Align selected objects to viertical center of objects. */
1922 /*****************************************************************************/
1924 gl_label_align_selection_vcenter (glLabel *label)
1926 GList *selection_list;
1928 glLabelObject *object;
1932 glLabelRegion obj_extent;
1936 gl_debug (DEBUG_LABEL, "START");
1938 g_return_if_fail (label && GL_IS_LABEL (label));
1940 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1941 !gl_label_is_selection_atomic (label));
1943 gl_label_checkpoint (label, _("Align vertical center"));
1945 begin_selection_op (label);
1947 selection_list = gl_label_get_selection_list (label);
1949 /* find average center of objects */
1952 for (p = selection_list; p != NULL; p = p->next)
1954 object = GL_LABEL_OBJECT (p->data);
1956 gl_label_object_get_extent (object, &obj_extent);
1957 ysum += (obj_extent.y1 + obj_extent.y2) / 2.0;
1962 /* find center of object closest to average center */
1964 object = GL_LABEL_OBJECT (p->data);
1966 gl_label_object_get_extent (object, &obj_extent);
1967 dymin = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
1968 ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
1969 for (p = p->next; p != NULL; p = p->next)
1971 object = GL_LABEL_OBJECT (p->data);
1973 gl_label_object_get_extent (object, &obj_extent);
1974 dy = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
1978 ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
1982 /* now adjust the object positions to line up this center */
1983 for (p = selection_list; p != NULL; p = p->next)
1985 object = GL_LABEL_OBJECT (p->data);
1987 gl_label_object_get_extent (object, &obj_extent);
1988 dy = ycenter - (obj_extent.y1 + obj_extent.y2)/2.0;
1989 gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1992 g_list_free (selection_list);
1994 end_selection_op (label);
1996 gl_debug (DEBUG_LABEL, "END");
2000 /*****************************************************************************/
2001 /* Center selected objects to in center of label. */
2002 /*****************************************************************************/
2004 gl_label_center_selection_horiz (glLabel *label)
2006 GList *selection_list;
2008 glLabelObject *object;
2010 gdouble x_label_center;
2011 gdouble x_obj_center;
2012 glLabelRegion obj_extent;
2015 gl_debug (DEBUG_LABEL, "START");
2017 g_return_if_fail (label && GL_IS_LABEL (label));
2019 g_return_if_fail (!gl_label_is_selection_empty (label));
2021 gl_label_checkpoint (label, _("Center horizontally"));
2023 begin_selection_op (label);
2025 gl_label_get_size (label, &w, &h);
2026 x_label_center = w / 2.0;
2028 /* adjust the object positions */
2029 selection_list = gl_label_get_selection_list (label);
2030 for (p = selection_list; p != NULL; p = p->next)
2032 object = GL_LABEL_OBJECT (p->data);
2034 gl_label_object_get_extent (object, &obj_extent);
2035 x_obj_center = (obj_extent.x1 + obj_extent.x2) / 2.0;
2036 dx = x_label_center - x_obj_center;
2037 gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
2039 g_list_free (selection_list);
2041 end_selection_op (label);
2043 gl_debug (DEBUG_LABEL, "END");
2047 /*****************************************************************************/
2048 /* Center selected objects to in center of label. */
2049 /*****************************************************************************/
2051 gl_label_center_selection_vert (glLabel *label)
2053 GList *selection_list;
2055 glLabelObject *object;
2057 gdouble y_label_center;
2058 gdouble y_obj_center;
2059 glLabelRegion obj_extent;
2062 gl_debug (DEBUG_LABEL, "START");
2064 g_return_if_fail (label && GL_IS_LABEL (label));
2066 g_return_if_fail (!gl_label_is_selection_empty (label));
2068 gl_label_checkpoint (label, _("Center vertically"));
2070 begin_selection_op (label);
2072 gl_label_get_size (label, &w, &h);
2073 y_label_center = h / 2.0;
2075 /* adjust the object positions */
2076 selection_list = gl_label_get_selection_list (label);
2077 for (p = selection_list; p != NULL; p = p->next)
2079 object = GL_LABEL_OBJECT (p->data);
2081 gl_label_object_get_extent (object, &obj_extent);
2082 y_obj_center = (obj_extent.y1 + obj_extent.y2) / 2.0;
2083 dy = y_label_center - y_obj_center;
2084 gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
2086 g_list_free (selection_list);
2088 end_selection_op (label);
2090 gl_debug (DEBUG_LABEL, "END");
2094 /*****************************************************************************/
2095 /* Move selected objects */
2096 /*****************************************************************************/
2098 gl_label_move_selection (glLabel *label,
2102 GList *selection_list;
2104 glLabelObject *object;
2106 gl_debug (DEBUG_LABEL, "START");
2108 g_return_if_fail (label && GL_IS_LABEL (label));
2110 begin_selection_op (label);
2112 selection_list = gl_label_get_selection_list (label);
2114 for (p = selection_list; p != NULL; p = p->next)
2116 object = GL_LABEL_OBJECT (p->data);
2118 gl_label_object_set_position_relative (object, dx, dy, TRUE);
2121 g_list_free (selection_list);
2123 end_selection_op (label);
2125 gl_debug (DEBUG_LABEL, "END");
2129 /*****************************************************************************/
2130 /* Set font family for all text contained in selected objects. */
2131 /*****************************************************************************/
2133 gl_label_set_selection_font_family (glLabel *label,
2134 const gchar *font_family)
2136 GList *selection_list;
2138 glLabelObject *object;
2140 gl_debug (DEBUG_LABEL, "START");
2142 g_return_if_fail (label && GL_IS_LABEL (label));
2144 begin_selection_op (label);
2146 selection_list = gl_label_get_selection_list (label);
2148 for (p = selection_list; p != NULL; p = p->next)
2150 object = GL_LABEL_OBJECT (p->data);
2151 gl_label_object_set_font_family (object, font_family, TRUE);
2154 g_list_free (selection_list);
2156 end_selection_op (label);
2158 gl_debug (DEBUG_LABEL, "END");
2162 /*****************************************************************************/
2163 /* Set font size for all text contained in selected objects. */
2164 /*****************************************************************************/
2166 gl_label_set_selection_font_size (glLabel *label,
2169 GList *selection_list;
2171 glLabelObject *object;
2173 gl_debug (DEBUG_LABEL, "START");
2175 g_return_if_fail (label && GL_IS_LABEL (label));
2177 begin_selection_op (label);
2179 selection_list = gl_label_get_selection_list (label);
2181 for (p = selection_list; p != NULL; p = p->next)
2183 object = GL_LABEL_OBJECT (p->data);
2184 gl_label_object_set_font_size (object, font_size, TRUE);
2187 g_list_free (selection_list);
2189 end_selection_op (label);
2191 gl_debug (DEBUG_LABEL, "END");
2195 /*****************************************************************************/
2196 /* Set font weight for all text contained in selected objects. */
2197 /*****************************************************************************/
2199 gl_label_set_selection_font_weight (glLabel *label,
2200 PangoWeight font_weight)
2202 GList *selection_list;
2204 glLabelObject *object;
2206 gl_debug (DEBUG_LABEL, "START");
2208 g_return_if_fail (label && GL_IS_LABEL (label));
2210 begin_selection_op (label);
2212 selection_list = gl_label_get_selection_list (label);
2214 for (p = selection_list; p != NULL; p = p->next)
2216 object = GL_LABEL_OBJECT (p->data);
2217 gl_label_object_set_font_weight (object, font_weight, TRUE);
2220 g_list_free (selection_list);
2222 end_selection_op (label);
2224 gl_debug (DEBUG_LABEL, "END");
2228 /*****************************************************************************/
2229 /* Set font italic flag for all text contained in selected objects. */
2230 /*****************************************************************************/
2232 gl_label_set_selection_font_italic_flag (glLabel *label,
2233 gboolean font_italic_flag)
2235 GList *selection_list;
2237 glLabelObject *object;
2239 gl_debug (DEBUG_LABEL, "START");
2241 g_return_if_fail (label && GL_IS_LABEL (label));
2243 begin_selection_op (label);
2245 selection_list = gl_label_get_selection_list (label);
2247 for (p = selection_list; p != NULL; p = p->next)
2249 object = GL_LABEL_OBJECT (p->data);
2250 gl_label_object_set_font_italic_flag (object, font_italic_flag, TRUE);
2253 g_list_free (selection_list);
2255 end_selection_op (label);
2257 gl_debug (DEBUG_LABEL, "END");
2261 /*****************************************************************************/
2262 /* Set text alignment for all text contained in selected objects. */
2263 /*****************************************************************************/
2265 gl_label_set_selection_text_alignment (glLabel *label,
2266 PangoAlignment text_alignment)
2268 GList *selection_list;
2270 glLabelObject *object;
2272 gl_debug (DEBUG_LABEL, "START");
2274 g_return_if_fail (label && GL_IS_LABEL (label));
2276 begin_selection_op (label);
2278 selection_list = gl_label_get_selection_list (label);
2280 for (p = selection_list; p != NULL; p = p->next)
2282 object = GL_LABEL_OBJECT (p->data);
2283 gl_label_object_set_text_alignment (object, text_alignment, TRUE);
2286 g_list_free (selection_list);
2288 end_selection_op (label);
2290 gl_debug (DEBUG_LABEL, "END");
2294 /*****************************************************************************/
2295 /* Set vertical text alignment for all text contained in selected objects. */
2296 /*****************************************************************************/
2298 gl_label_set_selection_text_valignment (glLabel *label,
2299 glValignment text_valignment)
2301 GList *selection_list;
2303 glLabelObject *object;
2305 gl_debug (DEBUG_LABEL, "START");
2307 g_return_if_fail (label && GL_IS_LABEL (label));
2309 begin_selection_op (label);
2311 selection_list = gl_label_get_selection_list (label);
2313 for (p = selection_list; p != NULL; p = p->next)
2315 object = GL_LABEL_OBJECT (p->data);
2316 gl_label_object_set_text_valignment (object, text_valignment, TRUE);
2319 g_list_free (selection_list);
2321 end_selection_op (label);
2323 gl_debug (DEBUG_LABEL, "END");
2327 /*****************************************************************************/
2328 /* Set text line spacing for all text contained in selected objects. */
2329 /*****************************************************************************/
2331 gl_label_set_selection_text_line_spacing (glLabel *label,
2332 gdouble text_line_spacing)
2334 GList *selection_list;
2336 glLabelObject *object;
2338 gl_debug (DEBUG_LABEL, "START");
2340 g_return_if_fail (label && GL_IS_LABEL (label));
2342 begin_selection_op (label);
2344 selection_list = gl_label_get_selection_list (label);
2346 for (p = selection_list; p != NULL; p = p->next)
2348 object = GL_LABEL_OBJECT (p->data);
2349 gl_label_object_set_text_line_spacing (object, text_line_spacing, TRUE);
2352 g_list_free (selection_list);
2354 end_selection_op (label);
2356 gl_debug (DEBUG_LABEL, "END");
2360 /*****************************************************************************/
2361 /* Set text color for all text contained in selected objects. */
2362 /*****************************************************************************/
2364 gl_label_set_selection_text_color (glLabel *label,
2365 glColorNode *text_color_node)
2367 GList *selection_list;
2369 glLabelObject *object;
2371 gl_debug (DEBUG_LABEL, "START");
2373 g_return_if_fail (label && GL_IS_LABEL (label));
2375 begin_selection_op (label);
2377 selection_list = gl_label_get_selection_list (label);
2379 for (p = selection_list; p != NULL; p = p->next)
2381 object = GL_LABEL_OBJECT (p->data);
2382 gl_label_object_set_text_color (object, text_color_node, TRUE);
2385 g_list_free (selection_list);
2387 end_selection_op (label);
2389 gl_debug (DEBUG_LABEL, "END");
2393 /*****************************************************************************/
2394 /* Set fill color for all selected objects. */
2395 /*****************************************************************************/
2397 gl_label_set_selection_fill_color (glLabel *label,
2398 glColorNode *fill_color_node)
2400 GList *selection_list;
2402 glLabelObject *object;
2404 gl_debug (DEBUG_LABEL, "START");
2406 g_return_if_fail (label && GL_IS_LABEL (label));
2408 begin_selection_op (label);
2410 selection_list = gl_label_get_selection_list (label);
2412 for (p = selection_list; p != NULL; p = p->next)
2414 object = GL_LABEL_OBJECT (p->data);
2415 gl_label_object_set_fill_color (object, fill_color_node, TRUE);
2418 g_list_free (selection_list);
2420 end_selection_op (label);
2422 gl_debug (DEBUG_LABEL, "END");
2426 /*****************************************************************************/
2427 /* Set line color for all selected objects. */
2428 /*****************************************************************************/
2430 gl_label_set_selection_line_color (glLabel *label,
2431 glColorNode *line_color_node)
2433 GList *selection_list;
2435 glLabelObject *object;
2437 gl_debug (DEBUG_LABEL, "START");
2439 g_return_if_fail (label && GL_IS_LABEL (label));
2441 begin_selection_op (label);
2443 selection_list = gl_label_get_selection_list (label);
2445 for (p = selection_list; p != NULL; p = p->next)
2447 object = GL_LABEL_OBJECT (p->data);
2448 gl_label_object_set_line_color (object, line_color_node, TRUE);
2451 g_list_free (selection_list);
2453 end_selection_op (label);
2455 gl_debug (DEBUG_LABEL, "END");
2459 /*****************************************************************************/
2460 /* Set line width for all selected objects. */
2461 /*****************************************************************************/
2463 gl_label_set_selection_line_width (glLabel *label,
2466 GList *selection_list;
2468 glLabelObject *object;
2470 gl_debug (DEBUG_LABEL, "START");
2472 g_return_if_fail (label && GL_IS_LABEL (label));
2474 begin_selection_op (label);
2476 selection_list = gl_label_get_selection_list (label);
2478 for (p = selection_list; p != NULL; p = p->next)
2480 object = GL_LABEL_OBJECT (p->data);
2481 gl_label_object_set_line_width (object, line_width, TRUE);
2484 g_list_free (selection_list);
2486 end_selection_op (label);
2488 gl_debug (DEBUG_LABEL, "END");
2492 /*****************************************************************************/
2493 /* "Cut" selected items and place on clipboard. */
2494 /*****************************************************************************/
2496 gl_label_cut_selection (glLabel *label)
2498 gl_debug (DEBUG_LABEL, "START");
2500 g_return_if_fail (label && GL_IS_LABEL (label));
2502 gl_label_copy_selection (label);
2503 gl_label_delete_selection (label);
2505 gl_debug (DEBUG_LABEL, "END");
2509 /*****************************************************************************/
2510 /* "Copy" selected items to clipboard. */
2511 /*****************************************************************************/
2513 gl_label_copy_selection (glLabel *label)
2515 GtkClipboard *clipboard;
2516 GList *selection_list;
2517 glLabel *label_copy;
2519 glLabelObject *object;
2520 glXMLLabelStatus status;
2522 ClipboardData *data;
2524 static GtkTargetEntry glabels_targets[] = { { "application/glabels", 0, 0 },
2525 { "text/xml", 0, 0 },
2528 GtkTargetList *target_list;
2529 GtkTargetEntry *target_table;
2532 gl_debug (DEBUG_LABEL, "START");
2534 g_return_if_fail (label && GL_IS_LABEL (label));
2536 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2538 selection_list = gl_label_get_selection_list (label);
2543 data = g_new0 (ClipboardData, 1);
2545 target_list = gtk_target_list_new (glabels_targets, G_N_ELEMENTS(glabels_targets));
2548 * Serialize selection by encoding as an XML label document.
2550 label_copy = GL_LABEL(gl_label_new ());
2552 gl_label_set_template (label_copy, label->priv->template, FALSE);
2553 gl_label_set_rotate_flag (label_copy, label->priv->rotate_flag, FALSE);
2555 for (p = selection_list; p != NULL; p = p->next)
2557 object = GL_LABEL_OBJECT (p->data);
2559 gl_label_add_object (label_copy, gl_label_object_dup (object, label_copy));
2562 data->xml_buffer = gl_xml_label_save_buffer (label_copy, &status);
2564 g_object_unref (G_OBJECT (label_copy));
2568 * Is it an atomic text selection? If so, also make available as text.
2570 if ( gl_label_is_selection_atomic (label) &&
2571 GL_IS_LABEL_TEXT (selection_list->data) )
2573 glLabelText *text_object = GL_LABEL_TEXT (selection_list->data);
2575 gtk_target_list_add_text_targets (target_list, 1);
2577 data->text = gl_label_text_get_text (text_object);
2582 * Is it an atomic image selection? If so, also make available as pixbuf.
2584 if ( gl_label_is_selection_atomic (label) &&
2585 GL_IS_LABEL_IMAGE (selection_list->data) )
2587 glLabelImage *image_object = GL_LABEL_IMAGE (selection_list->data);
2588 GdkPixbuf *pixbuf = gl_label_image_get_pixbuf (image_object, NULL);
2592 gtk_target_list_add_image_targets (target_list, 2, TRUE);
2593 data->pixbuf = pixbuf;
2598 target_table = gtk_target_table_new_from_list (target_list, &n_targets);
2600 gtk_clipboard_set_with_data (clipboard,
2601 target_table, n_targets,
2602 (GtkClipboardGetFunc)clipboard_get_cb,
2603 (GtkClipboardClearFunc)clipboard_clear_cb,
2606 gtk_target_table_free (target_table, n_targets);
2607 gtk_target_list_unref (target_list);
2611 g_list_free (selection_list);
2613 gl_debug (DEBUG_LABEL, "END");
2617 /*****************************************************************************/
2618 /* "Paste" from clipboard. */
2619 /*****************************************************************************/
2621 gl_label_paste (glLabel *label)
2623 GtkClipboard *clipboard;
2625 gl_debug (DEBUG_LABEL, "START");
2627 g_return_if_fail (label && GL_IS_LABEL (label));
2629 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2631 gtk_clipboard_request_targets (clipboard,
2632 (GtkClipboardTargetsReceivedFunc)receive_targets_cb,
2635 gl_debug (DEBUG_LABEL, "END");
2639 /*****************************************************************************/
2640 /* Is there anything that can be pasted? */
2641 /*****************************************************************************/
2643 gl_label_can_paste (glLabel *label)
2645 GtkClipboard *clipboard;
2648 gl_debug (DEBUG_LABEL, "START");
2650 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2652 can_flag = gtk_clipboard_wait_is_target_available (clipboard,
2653 gdk_atom_intern("application/glabels", TRUE))
2654 || gtk_clipboard_wait_is_text_available (clipboard)
2655 || gtk_clipboard_wait_is_image_available (clipboard);
2657 gl_debug (DEBUG_LABEL, "END");
2662 /****************************************************************************/
2663 /* Clipboard "Get" function. */
2664 /****************************************************************************/
2666 clipboard_get_cb (GtkClipboard *clipboard,
2667 GtkSelectionData *selection_data,
2669 ClipboardData *data)
2671 gl_debug (DEBUG_LABEL, "START");
2677 gtk_selection_data_set (selection_data,
2678 gtk_selection_data_get_target (selection_data),
2680 (guchar *)data->xml_buffer, strlen (data->xml_buffer));
2684 gtk_selection_data_set_text (selection_data, data->text, -1);
2688 gtk_selection_data_set_pixbuf (selection_data, data->pixbuf);
2692 g_assert_not_reached ();
2697 gl_debug (DEBUG_LABEL, "END");
2701 /****************************************************************************/
2702 /* Clipboard "Clear" function. */
2703 /****************************************************************************/
2705 clipboard_clear_cb (GtkClipboard *clipboard,
2706 ClipboardData *data)
2708 gl_debug (DEBUG_LABEL, "START");
2710 g_free (data->xml_buffer);
2711 g_free (data->text);
2714 g_object_unref (data->pixbuf);
2719 gl_debug (DEBUG_LABEL, "END");
2723 /****************************************************************************/
2724 /* Deal with clipboard data. */
2725 /****************************************************************************/
2727 receive_targets_cb (GtkClipboard *clipboard,
2735 * Application/glabels
2737 for ( i = 0; i < n_targets; i++ )
2739 if ( strcmp(gdk_atom_name(targets[i]), "application/glabels") == 0 )
2741 gtk_clipboard_request_contents (clipboard,
2742 gdk_atom_intern("application/glabels", TRUE),
2743 (GtkClipboardReceivedFunc)paste_xml_received_cb,
2752 if ( gtk_targets_include_text (targets, n_targets) )
2754 gtk_clipboard_request_text (clipboard,
2755 (GtkClipboardTextReceivedFunc)paste_text_received_cb,
2763 if ( gtk_targets_include_image (targets, n_targets, TRUE) )
2765 gtk_clipboard_request_image (clipboard,
2766 (GtkClipboardImageReceivedFunc)paste_image_received_cb,
2773 /****************************************************************************/
2774 /* Paste received glabels XML callback. */
2775 /****************************************************************************/
2777 paste_xml_received_cb (GtkClipboard *clipboard,
2778 GtkSelectionData *selection_data,
2782 glLabel *label_copy;
2783 glXMLLabelStatus status;
2785 glLabelObject *object, *newobject;
2787 gl_debug (DEBUG_LABEL, "START");
2789 gl_label_checkpoint (label, _("Paste"));
2791 xml_buffer = (gchar *)gtk_selection_data_get_data (selection_data);
2794 * Deserialize XML label document and extract objects.
2796 label_copy = gl_xml_label_open_buffer (xml_buffer, &status);
2799 gl_label_unselect_all (label);
2801 for (p = label_copy->priv->object_list; p != NULL; p = p->next)
2803 object = (glLabelObject *) p->data;
2804 newobject = gl_label_object_dup (object, label);
2805 gl_label_add_object( label, newobject );
2807 gl_label_select_object (label, newobject);
2809 gl_debug (DEBUG_LABEL, "object pasted");
2812 g_object_unref (G_OBJECT (label_copy));
2815 gl_debug (DEBUG_LABEL, "END");
2819 /****************************************************************************/
2820 /* Paste received text callback. */
2821 /****************************************************************************/
2823 paste_text_received_cb (GtkClipboard *clipboard,
2827 glLabelObject *object;
2829 gl_debug (DEBUG_LABEL, "START");
2831 gl_label_checkpoint (label, _("Paste"));
2833 gl_label_unselect_all (label);
2835 object = GL_LABEL_OBJECT (gl_label_text_new (label, FALSE));
2836 gl_label_text_set_text (GL_LABEL_TEXT (object), text, FALSE);
2837 gl_label_object_set_position (object, 18, 18, FALSE);
2839 gl_label_select_object (label, object);
2841 gl_debug (DEBUG_LABEL, "END");
2845 /****************************************************************************/
2846 /* Paste received image callback. */
2847 /****************************************************************************/
2849 paste_image_received_cb (GtkClipboard *clipboard,
2853 glLabelObject *object;
2855 gl_debug (DEBUG_LABEL, "START");
2857 gl_label_checkpoint (label, _("Paste"));
2859 gl_label_unselect_all (label);
2861 object = GL_LABEL_OBJECT (gl_label_image_new (label, FALSE));
2862 gl_label_image_set_pixbuf (GL_LABEL_IMAGE (object), pixbuf, FALSE);
2863 gl_label_object_set_position (object, 18, 18, FALSE);
2865 gl_label_select_object (label, object);
2867 gl_debug (DEBUG_LABEL, "END");
2871 /****************************************************************************/
2872 /* Set default font family. */
2873 /****************************************************************************/
2875 gl_label_set_default_font_family (glLabel *label,
2876 const gchar *font_family)
2878 gl_debug (DEBUG_LABEL, "START");
2880 g_return_if_fail (label && GL_IS_LABEL (label));
2882 g_free (label->priv->default_font_family);
2883 label->priv->default_font_family = g_strdup (font_family);
2885 gl_debug (DEBUG_LABEL, "END");
2889 /****************************************************************************/
2890 /* Set default font size. */
2891 /****************************************************************************/
2893 gl_label_set_default_font_size (glLabel *label,
2896 gl_debug (DEBUG_LABEL, "START");
2898 g_return_if_fail (label && GL_IS_LABEL (label));
2900 label->priv->default_font_size = font_size;
2902 gl_debug (DEBUG_LABEL, "END");
2906 /****************************************************************************/
2907 /* Set default font weight. */
2908 /****************************************************************************/
2910 gl_label_set_default_font_weight (glLabel *label,
2911 PangoWeight font_weight)
2913 gl_debug (DEBUG_LABEL, "START");
2915 g_return_if_fail (label && GL_IS_LABEL (label));
2917 label->priv->default_font_weight = font_weight;
2919 gl_debug (DEBUG_LABEL, "END");
2923 /****************************************************************************/
2924 /* Set default font italic flag. */
2925 /****************************************************************************/
2927 gl_label_set_default_font_italic_flag (glLabel *label,
2928 gboolean font_italic_flag)
2930 gl_debug (DEBUG_LABEL, "START");
2932 g_return_if_fail (label && GL_IS_LABEL (label));
2934 label->priv->default_font_italic_flag = font_italic_flag;
2936 gl_debug (DEBUG_LABEL, "END");
2940 /****************************************************************************/
2941 /* Set default text color. */
2942 /****************************************************************************/
2944 gl_label_set_default_text_color (glLabel *label,
2947 gl_debug (DEBUG_LABEL, "START");
2949 g_return_if_fail (label && GL_IS_LABEL (label));
2951 label->priv->default_text_color = text_color;
2953 gl_debug (DEBUG_LABEL, "END");
2957 /****************************************************************************/
2958 /* Set default text alignment. */
2959 /****************************************************************************/
2961 gl_label_set_default_text_alignment (glLabel *label,
2962 PangoAlignment text_alignment)
2964 gl_debug (DEBUG_LABEL, "START");
2966 g_return_if_fail (label && GL_IS_LABEL (label));
2968 label->priv->default_text_alignment = text_alignment;
2969 gl_debug (DEBUG_LABEL, "END");
2973 /****************************************************************************/
2974 /* Set default vertical text alignment. */
2975 /****************************************************************************/
2977 gl_label_set_default_text_valignment (glLabel *label,
2978 glValignment text_valignment)
2980 gl_debug (DEBUG_LABEL, "START");
2982 g_return_if_fail (label && GL_IS_LABEL (label));
2984 label->priv->default_text_valignment = text_valignment;
2985 gl_debug (DEBUG_LABEL, "END");
2989 /****************************************************************************/
2990 /* Set default text line spacing. */
2991 /****************************************************************************/
2993 gl_label_set_default_text_line_spacing (glLabel *label,
2994 gdouble text_line_spacing)
2996 gl_debug (DEBUG_LABEL, "START");
2998 g_return_if_fail (label && GL_IS_LABEL (label));
3000 label->priv->default_text_line_spacing = text_line_spacing;
3002 gl_debug (DEBUG_LABEL, "END");
3006 /****************************************************************************/
3007 /* Set default line width. */
3008 /****************************************************************************/
3010 gl_label_set_default_line_width (glLabel *label,
3013 gl_debug (DEBUG_LABEL, "START");
3015 g_return_if_fail (label && GL_IS_LABEL (label));
3017 label->priv->default_line_width = line_width;
3019 gl_debug (DEBUG_LABEL, "END");
3023 /****************************************************************************/
3024 /* Set default line color. */
3025 /****************************************************************************/
3027 gl_label_set_default_line_color (glLabel *label,
3030 gl_debug (DEBUG_LABEL, "START");
3032 g_return_if_fail (label && GL_IS_LABEL (label));
3034 label->priv->default_line_color = line_color;
3036 gl_debug (DEBUG_LABEL, "END");
3040 /****************************************************************************/
3041 /* Set default fill color. */
3042 /****************************************************************************/
3044 gl_label_set_default_fill_color (glLabel *label,
3047 gl_debug (DEBUG_LABEL, "START");
3049 g_return_if_fail (label && GL_IS_LABEL (label));
3051 label->priv->default_fill_color = fill_color;
3053 gl_debug (DEBUG_LABEL, "END");
3057 /****************************************************************************/
3058 /* Get default font family. */
3059 /****************************************************************************/
3061 gl_label_get_default_font_family (glLabel *label)
3063 gl_debug (DEBUG_LABEL, "START");
3065 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
3067 gl_debug (DEBUG_LABEL, "END");
3069 return g_strdup (label->priv->default_font_family);
3073 /****************************************************************************/
3074 /* Get default font size. */
3075 /****************************************************************************/
3077 gl_label_get_default_font_size (glLabel *label)
3079 gl_debug (DEBUG_LABEL, "START");
3081 g_return_val_if_fail (label && GL_IS_LABEL (label), 12.0);
3083 gl_debug (DEBUG_LABEL, "END");
3085 return label->priv->default_font_size;
3089 /****************************************************************************/
3090 /* Get default font weight. */
3091 /****************************************************************************/
3093 gl_label_get_default_font_weight (glLabel *label)
3095 gl_debug (DEBUG_LABEL, "START");
3097 g_return_val_if_fail (label && GL_IS_LABEL (label), PANGO_WEIGHT_NORMAL);
3099 gl_debug (DEBUG_LABEL, "END");
3101 return label->priv->default_font_weight;
3105 /****************************************************************************/
3106 /* Get default font italic flag. */
3107 /****************************************************************************/
3109 gl_label_get_default_font_italic_flag (glLabel *label)
3111 gl_debug (DEBUG_LABEL, "START");
3113 g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
3115 gl_debug (DEBUG_LABEL, "END");
3117 return label->priv->default_font_italic_flag;
3121 /****************************************************************************/
3122 /* Get default text color. */
3123 /****************************************************************************/
3125 gl_label_get_default_text_color (glLabel *label)
3127 gl_debug (DEBUG_LABEL, "START");
3129 g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
3131 gl_debug (DEBUG_LABEL, "END");
3133 return label->priv->default_text_color;
3137 /****************************************************************************/
3138 /* Get default text alignment. */
3139 /****************************************************************************/
3141 gl_label_get_default_text_alignment (glLabel *label)
3143 gl_debug (DEBUG_LABEL, "START");
3145 g_return_val_if_fail (label && GL_IS_LABEL (label), PANGO_ALIGN_LEFT);
3147 gl_debug (DEBUG_LABEL, "END");
3149 return label->priv->default_text_alignment;
3153 /****************************************************************************/
3154 /* Get default vertical text alignment. */
3155 /****************************************************************************/
3157 gl_label_get_default_text_valignment (glLabel *label)
3159 gl_debug (DEBUG_LABEL, "START");
3161 g_return_val_if_fail (label && GL_IS_LABEL (label), GL_VALIGN_TOP);
3163 gl_debug (DEBUG_LABEL, "END");
3165 return label->priv->default_text_valignment;
3169 /****************************************************************************/
3170 /* Get default text line spacing. */
3171 /****************************************************************************/
3173 gl_label_get_default_text_line_spacing (glLabel *label)
3175 gl_debug (DEBUG_LABEL, "START");
3177 g_return_val_if_fail (label && GL_IS_LABEL (label), 1.0);
3179 gl_debug (DEBUG_LABEL, "END");
3181 return label->priv->default_text_line_spacing;
3185 /****************************************************************************/
3186 /* Get default line width. */
3187 /****************************************************************************/
3189 gl_label_get_default_line_width (glLabel *label)
3191 gl_debug (DEBUG_LABEL, "START");
3193 g_return_val_if_fail (label && GL_IS_LABEL (label), 1.0);
3195 gl_debug (DEBUG_LABEL, "END");
3197 return label->priv->default_line_width;
3201 /****************************************************************************/
3202 /* Get default line color. */
3203 /****************************************************************************/
3205 gl_label_get_default_line_color (glLabel *label)
3207 gl_debug (DEBUG_LABEL, "START");
3209 g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
3211 gl_debug (DEBUG_LABEL, "END");
3213 return label->priv->default_line_color;
3217 /****************************************************************************/
3218 /* Get default fill color. */
3219 /****************************************************************************/
3221 gl_label_get_default_fill_color (glLabel *label)
3223 gl_debug (DEBUG_LABEL, "START");
3225 g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
3227 gl_debug (DEBUG_LABEL, "END");
3229 return label->priv->default_fill_color;
3233 /****************************************************************************/
3235 /****************************************************************************/
3237 gl_label_draw (glLabel *label,
3239 gboolean screen_flag,
3240 glMergeRecord *record)
3243 glLabelObject *object;
3245 g_return_if_fail (label && GL_IS_LABEL (label));
3247 for (p_obj = label->priv->object_list; p_obj != NULL; p_obj = p_obj->next)
3249 object = GL_LABEL_OBJECT (p_obj->data);
3251 gl_label_object_draw (object, cr, screen_flag, record);
3256 /****************************************************************************/
3257 /* Get object located at coordinates. */
3258 /****************************************************************************/
3259 glLabelObject *gl_label_object_at (glLabel *label,
3265 glLabelObject *object;
3267 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
3269 for (p_obj = g_list_last (label->priv->object_list); p_obj != NULL; p_obj = p_obj->prev)
3271 object = GL_LABEL_OBJECT (p_obj->data);
3273 if (gl_label_object_is_located_at (object, cr, x_pixels, y_pixels))
3284 /****************************************************************************/
3285 /* Return handle and associated object at coordinates. */
3286 /****************************************************************************/
3288 gl_label_get_handle_at (glLabel *label,
3292 glLabelObjectHandle *handle)
3294 GList *selection_list;
3296 glLabelObject *object;
3298 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
3300 selection_list = gl_label_get_selection_list (label);
3302 for (p_obj = g_list_last (selection_list); p_obj != NULL; p_obj = p_obj->prev)
3305 object = GL_LABEL_OBJECT (p_obj->data);
3307 if ((*handle = gl_label_object_handle_at (object, cr, x_pixels, y_pixels)))
3309 g_list_free (selection_list);
3315 g_list_free (selection_list);
3317 *handle = GL_LABEL_OBJECT_HANDLE_NONE;
3322 /****************************************************************************/
3323 /* Checkpoint state. */
3324 /****************************************************************************/
3326 gl_label_checkpoint (glLabel *this,
3327 const gchar *description)
3331 gl_debug (DEBUG_LABEL, "START");
3334 * Do not perform consecutive checkpoints that are identical.
3335 * E.g. moving an object by dragging, would produce a large number
3336 * of incremental checkpoints -- what we really want is a single
3337 * checkpoint so that we can undo the entire dragging effort with
3340 if ( this->priv->cp_cleared_flag
3341 || (this->priv->cp_desc == NULL)
3342 || (strcmp (description, this->priv->cp_desc) != 0) )
3345 /* Sever old redo "thread" */
3346 stack_clear (this->priv->redo_stack);
3348 /* Save state onto undo stack. */
3349 state = state_new (this, description);
3350 stack_push_state (this->priv->undo_stack, state);
3352 /* Track consecutive checkpoints. */
3353 this->priv->cp_cleared_flag = FALSE;
3354 this->priv->cp_desc = g_strdup (description);
3357 gl_debug (DEBUG_LABEL, "END");
3361 /****************************************************************************/
3363 /****************************************************************************/
3365 gl_label_undo (glLabel *this)
3370 gl_debug (DEBUG_LABEL, "START");
3372 state_old = stack_pop_state (this->priv->undo_stack);
3373 state_now = state_new (this, state_old->description);
3375 stack_push_state (this->priv->redo_stack, state_now);
3377 state_restore (state_old, this);
3378 state_free (state_old);
3380 this->priv->cp_cleared_flag = TRUE;
3382 gl_debug (DEBUG_LABEL, "END");
3386 /****************************************************************************/
3388 /****************************************************************************/
3390 gl_label_redo (glLabel *this)
3395 gl_debug (DEBUG_LABEL, "START");
3397 state_old = stack_pop_state (this->priv->redo_stack);
3398 state_now = state_new (this, state_old->description);
3400 stack_push_state (this->priv->undo_stack, state_now);
3402 state_restore (state_old, this);
3403 state_free (state_old);
3405 this->priv->cp_cleared_flag = TRUE;
3407 gl_debug (DEBUG_LABEL, "END");
3411 /****************************************************************************/
3413 /****************************************************************************/
3415 gl_label_can_undo (glLabel *this)
3417 return (!g_queue_is_empty (this->priv->undo_stack));
3421 /****************************************************************************/
3423 /****************************************************************************/
3425 gl_label_can_redo (glLabel *this)
3427 return (!g_queue_is_empty (this->priv->redo_stack));
3431 /****************************************************************************/
3432 /* Get undo description string. */
3433 /****************************************************************************/
3435 gl_label_get_undo_description (glLabel *this)
3440 state = g_queue_peek_head (this->priv->undo_stack);
3443 description = g_strdup (state->description);
3447 description = g_strdup ("");
3454 /****************************************************************************/
3455 /* Get redo description string. */
3456 /****************************************************************************/
3458 gl_label_get_redo_description (glLabel *this)
3463 state = g_queue_peek_head (this->priv->redo_stack);
3466 description = g_strdup (state->description);
3470 description = g_strdup ("");
3477 /****************************************************************************/
3478 /* Clear undo or redo stack. */
3479 /****************************************************************************/
3481 stack_clear (GQueue *stack)
3485 gl_debug (DEBUG_LABEL, "START");
3487 while ( (state = g_queue_pop_head (stack)) != NULL )
3492 gl_debug (DEBUG_LABEL, "END");
3496 /****************************************************************************/
3497 /* Push state onto stack. */
3498 /****************************************************************************/
3500 stack_push_state (GQueue *stack,
3503 gl_debug (DEBUG_LABEL, "START");
3505 g_queue_push_head( stack, state );
3507 gl_debug (DEBUG_LABEL, "END");
3511 /****************************************************************************/
3512 /* Pop state from stack. */
3513 /****************************************************************************/
3515 stack_pop_state (GQueue *stack)
3519 gl_debug (DEBUG_LABEL, "START");
3521 state = g_queue_pop_head (stack);
3523 gl_debug (DEBUG_LABEL, "END");
3528 /****************************************************************************/
3529 /* New state from label. */
3530 /****************************************************************************/
3532 state_new (glLabel *this,
3533 const gchar *description)
3537 glLabelObject *object;
3539 gl_debug (DEBUG_LABEL, "START");
3541 state = g_new0 (State, 1);
3543 state->description = g_strdup (description);
3545 state->template = lgl_template_dup (this->priv->template);
3546 state->rotate_flag = this->priv->rotate_flag;
3548 for ( p_obj = this->priv->object_list; p_obj != NULL; p_obj = p_obj->next )
3550 object = GL_LABEL_OBJECT (p_obj->data);
3552 state->object_list = g_list_append (state->object_list,
3553 gl_label_object_dup (object, this));
3556 state->merge = gl_merge_dup (this->priv->merge);
3558 state->modified_flag = this->priv->modified_flag;
3559 state->time_stamp = this->priv->time_stamp;
3562 gl_debug (DEBUG_LABEL, "END");
3567 /****************************************************************************/
3568 /* Restore label from saved state. */
3569 /****************************************************************************/
3571 state_free (State *state)
3575 gl_debug (DEBUG_LABEL, "START");
3577 g_free (state->description);
3579 lgl_template_free (state->template);
3582 g_object_unref (G_OBJECT (state->merge));
3585 for ( p_obj = state->object_list; p_obj != NULL; p_obj = p_obj->next )
3587 g_object_unref (G_OBJECT (p_obj->data));
3589 g_list_free (state->object_list);
3593 gl_debug (DEBUG_LABEL, "END");
3597 /****************************************************************************/
3598 /* Restore label from saved state. */
3599 /****************************************************************************/
3601 state_restore (State *state,
3605 GList *p_obj, *p_next;
3606 glLabelObject *object;
3608 gl_debug (DEBUG_LABEL, "START");
3610 gl_label_set_rotate_flag (this, state->rotate_flag, FALSE);
3611 gl_label_set_template (this, state->template, FALSE);
3613 for ( p_obj = this->priv->object_list; p_obj != NULL; p_obj = p_next )
3615 p_next = p_obj->next; /* Hold on to next; delete is destructive */
3616 object = GL_LABEL_OBJECT (p_obj->data);
3618 gl_label_delete_object (this, object);
3621 for ( p_obj = state->object_list; p_obj != NULL; p_obj = p_obj->next )
3623 object = GL_LABEL_OBJECT (p_obj->data);
3625 gl_label_add_object (this, gl_label_object_dup (object, this));
3627 g_signal_emit (G_OBJECT(this), signals[SELECTION_CHANGED], 0);
3629 gl_label_set_merge (this, state->merge, FALSE);
3632 if ( !state->modified_flag &&
3633 (state->time_stamp.tv_sec == this->priv->time_stamp.tv_sec) &&
3634 (state->time_stamp.tv_usec == this->priv->time_stamp.tv_usec) )
3636 gl_label_clear_modified (this);
3639 gl_debug (DEBUG_LABEL, "END");
3646 * Local Variables: -- emacs
3648 * c-basic-offset: 8 -- emacs
3649 * tab-width: 8 -- emacs
3650 * indent-tabs-mode: nil -- emacs