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 /* set merge information structure. */
708 /****************************************************************************/
710 gl_label_set_merge (glLabel *label,
714 gl_debug (DEBUG_LABEL, "START");
716 g_return_if_fail (label && GL_IS_LABEL (label));
720 gl_label_checkpoint (label, _("Merge properties"));
723 if ( label->priv->merge != NULL )
725 g_object_unref (G_OBJECT(label->priv->merge));
727 label->priv->merge = gl_merge_dup (merge);
730 g_signal_emit (G_OBJECT(label), signals[MERGE_CHANGED], 0);
732 gl_debug (DEBUG_LABEL, "END");
736 /****************************************************************************/
737 /* Get merge information structure. */
738 /****************************************************************************/
740 gl_label_get_merge (glLabel *label)
742 gl_debug (DEBUG_LABEL, "START");
744 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
746 gl_debug (DEBUG_LABEL, "END");
748 return gl_merge_dup (label->priv->merge);
752 /****************************************************************************/
753 /* Get pixbuf cache. */
754 /****************************************************************************/
756 gl_label_get_pixbuf_cache (glLabel *label)
758 return label->priv->pixbuf_cache;
762 /****************************************************************************/
764 /****************************************************************************/
766 gl_label_get_svg_cache (glLabel *label)
768 return label->priv->svg_cache;
772 /*****************************************************************************/
773 /* Add object to label. */
774 /*****************************************************************************/
776 gl_label_add_object (glLabel *label,
777 glLabelObject *object)
779 gl_debug (DEBUG_LABEL, "START");
781 g_return_if_fail (label && GL_IS_LABEL (label));
782 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
784 gl_label_object_set_parent (object, label);
785 label->priv->object_list = g_list_append (label->priv->object_list, object);
787 g_signal_connect (G_OBJECT (object), "changed",
788 G_CALLBACK (object_changed_cb), label);
789 g_signal_connect (G_OBJECT (object), "moved",
790 G_CALLBACK (object_moved_cb), label);
794 gl_debug (DEBUG_LABEL, "END");
798 /*****************************************************************************/
799 /* Delete object from label. */
800 /*****************************************************************************/
802 gl_label_delete_object (glLabel *label,
803 glLabelObject *object)
805 gl_debug (DEBUG_LABEL, "START");
807 g_return_if_fail (label && GL_IS_LABEL (label));
808 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
810 label->priv->object_list = g_list_remove (label->priv->object_list, object);
812 g_signal_handlers_disconnect_by_func (G_OBJECT (object),
813 G_CALLBACK (object_changed_cb), label);
814 g_signal_handlers_disconnect_by_func (G_OBJECT (object),
815 G_CALLBACK (object_moved_cb), label);
816 g_object_unref (object);
820 gl_debug (DEBUG_LABEL, "END");
824 /*****************************************************************************/
825 /* Get object list. */
826 /*****************************************************************************/
828 gl_label_get_object_list (glLabel *label)
830 return label->priv->object_list;
834 /*****************************************************************************/
836 /*****************************************************************************/
838 gl_label_select_object (glLabel *label,
839 glLabelObject *object)
841 gl_debug (DEBUG_LABEL, "START");
843 g_return_if_fail (label && GL_IS_LABEL (label));
844 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
846 gl_label_object_select (object);
848 label->priv->cp_cleared_flag = TRUE;
849 g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
851 gl_debug (DEBUG_LABEL, "END");
855 /*****************************************************************************/
856 /* Unselect object. */
857 /*****************************************************************************/
859 gl_label_unselect_object (glLabel *label,
860 glLabelObject *object)
862 gl_debug (DEBUG_LABEL, "START");
864 g_return_if_fail (label && GL_IS_LABEL (label));
865 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
867 gl_label_object_unselect (object);
869 label->priv->cp_cleared_flag = TRUE;
870 g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
872 gl_debug (DEBUG_LABEL, "END");
876 /*****************************************************************************/
877 /* Select all objects. */
878 /*****************************************************************************/
880 gl_label_select_all (glLabel *label)
883 glLabelObject *object;
885 gl_debug (DEBUG_LABEL, "START");
887 g_return_if_fail (label && GL_IS_LABEL (label));
889 for ( p = label->priv->object_list; p != NULL; p = p->next )
891 object = GL_LABEL_OBJECT (p->data);
893 gl_label_object_select (object);
896 label->priv->cp_cleared_flag = TRUE;
897 g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
899 gl_debug (DEBUG_LABEL, "END");
903 /*****************************************************************************/
904 /* Unselect all objects. */
905 /*****************************************************************************/
907 gl_label_unselect_all (glLabel *label)
910 glLabelObject *object;
912 gl_debug (DEBUG_LABEL, "START");
914 g_return_if_fail (label && GL_IS_LABEL (label));
916 for ( p = label->priv->object_list; p != NULL; p = p->next )
918 object = GL_LABEL_OBJECT (p->data);
920 gl_label_object_unselect (object);
923 label->priv->cp_cleared_flag = TRUE;
924 g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
926 gl_debug (DEBUG_LABEL, "END");
930 /*****************************************************************************/
931 /* Select all objects contained in region. */
932 /*****************************************************************************/
934 gl_label_select_region (glLabel *label,
935 glLabelRegion *region)
938 glLabelObject *object;
941 glLabelRegion obj_extent;
943 gl_debug (DEBUG_LABEL, "START");
945 g_return_if_fail (label && GL_IS_LABEL (label));
947 r_x1 = MIN (region->x1, region->x2);
948 r_y1 = MIN (region->y1, region->y2);
949 r_x2 = MAX (region->x1, region->x2);
950 r_y2 = MAX (region->y1, region->y2);
952 for (p = label->priv->object_list; p != NULL; p = p->next)
954 object = GL_LABEL_OBJECT(p->data);
956 gl_label_object_get_extent (object, &obj_extent);
957 if ((obj_extent.x1 >= r_x1) &&
958 (obj_extent.x2 <= r_x2) &&
959 (obj_extent.y1 >= r_y1) &&
960 (obj_extent.y2 <= r_y2))
962 gl_label_object_select (object);
966 label->priv->cp_cleared_flag = TRUE;
967 g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
969 gl_debug (DEBUG_LABEL, "END");
973 /*****************************************************************************/
974 /* Is selection empty? */
975 /*****************************************************************************/
977 gl_label_is_selection_empty (glLabel *label)
980 glLabelObject *object;
982 for ( p = label->priv->object_list; p != NULL; p = p->next )
984 object = GL_LABEL_OBJECT (p->data);
986 if ( gl_label_object_is_selected (object) )
996 /*****************************************************************************/
997 /* Is selection atomic? */
998 /*****************************************************************************/
1000 gl_label_is_selection_atomic (glLabel *label)
1003 glLabelObject *object;
1004 gint n_selected = 0;
1006 for ( p = label->priv->object_list; p != NULL; p = p->next )
1008 object = GL_LABEL_OBJECT (p->data);
1010 if ( gl_label_object_is_selected (object) )
1021 return (n_selected == 1);
1025 /*****************************************************************************/
1026 /* Get first selected object. */
1027 /*****************************************************************************/
1029 gl_label_get_1st_selected_object (glLabel *label)
1032 glLabelObject *object;
1034 for ( p = label->priv->object_list; p != NULL; p = p->next )
1036 object = GL_LABEL_OBJECT (p->data);
1038 if ( gl_label_object_is_selected (object) )
1048 /*****************************************************************************/
1049 /* Get list of selected objects. */
1050 /*****************************************************************************/
1052 gl_label_get_selection_list (glLabel *label)
1054 GList *selection_list = NULL;
1056 glLabelObject *object;
1058 for ( p = label->priv->object_list; p != NULL; p = p->next )
1060 object = GL_LABEL_OBJECT (p->data);
1062 if ( gl_label_object_is_selected (object) )
1064 selection_list = g_list_append (selection_list, object);
1068 return (selection_list);
1072 /*****************************************************************************/
1073 /* Can text properties be set for selection? */
1074 /*****************************************************************************/
1076 gl_label_can_selection_text (glLabel *label)
1078 GList *selection_list;
1080 glLabelObject *object;
1082 gl_debug (DEBUG_LABEL, "");
1084 g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
1086 selection_list = gl_label_get_selection_list (label);
1088 for (p = selection_list; p != NULL; p = p->next)
1090 object = GL_LABEL_OBJECT (p->data);
1092 if (gl_label_object_can_text (object))
1094 g_list_free (selection_list);
1099 g_list_free (selection_list);
1104 /*****************************************************************************/
1105 /* Can fill properties be set for selection? */
1106 /*****************************************************************************/
1108 gl_label_can_selection_fill (glLabel *label)
1110 GList *selection_list;
1112 glLabelObject *object;
1114 gl_debug (DEBUG_LABEL, "");
1116 g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
1118 selection_list = gl_label_get_selection_list (label);
1120 for (p = selection_list; p != NULL; p = p->next)
1122 object = GL_LABEL_OBJECT (p->data);
1124 if (gl_label_object_can_fill (object))
1126 g_list_free (selection_list);
1132 g_list_free (selection_list);
1137 /*****************************************************************************/
1138 /* Can line color properties be set for selection? */
1139 /*****************************************************************************/
1141 gl_label_can_selection_line_color (glLabel *label)
1143 GList *selection_list;
1145 glLabelObject *object;
1147 gl_debug (DEBUG_LABEL, "");
1149 g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
1151 selection_list = gl_label_get_selection_list (label);
1153 for (p = selection_list; p != NULL; p = p->next)
1155 object = GL_LABEL_OBJECT (p->data);
1157 if (gl_label_object_can_line_color (object))
1159 g_list_free (selection_list);
1164 g_list_free (selection_list);
1169 /*****************************************************************************/
1170 /* Can line width properties be set for selection? */
1171 /*****************************************************************************/
1173 gl_label_can_selection_line_width (glLabel *label)
1175 GList *selection_list;
1177 glLabelObject *object;
1179 gl_debug (DEBUG_LABEL, "");
1181 g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
1183 selection_list = gl_label_get_selection_list (label);
1185 for (p = selection_list; p != NULL; p = p->next)
1187 object = GL_LABEL_OBJECT (p->data);
1189 if (gl_label_object_can_line_width (object))
1191 g_list_free (selection_list);
1197 g_list_free (selection_list);
1202 /*****************************************************************************/
1203 /* Delete selection from label. */
1204 /*****************************************************************************/
1206 gl_label_delete_selection (glLabel *label)
1208 GList *selection_list;
1210 glLabelObject *object;
1212 gl_debug (DEBUG_LABEL, "START");
1214 g_return_if_fail (label && GL_IS_LABEL (label));
1216 gl_label_checkpoint (label, _("Delete"));
1218 begin_selection_op (label);
1220 selection_list = gl_label_get_selection_list (label);
1222 for ( p = selection_list; p != NULL; p = p->next )
1224 object = GL_LABEL_OBJECT (p->data);
1226 gl_label_delete_object (label, object);
1229 g_list_free (selection_list);
1231 end_selection_op (label);
1233 gl_debug (DEBUG_LABEL, "END");
1237 /****************************************************************************/
1238 /* Bring selection object to front/top. */
1239 /****************************************************************************/
1241 gl_label_raise_selection_to_top (glLabel *label)
1243 GList *selection_list;
1245 glLabelObject *object;
1247 gl_debug (DEBUG_LABEL, "START");
1249 gl_label_checkpoint (label, _("Bring to front"));
1251 begin_selection_op (label);
1253 selection_list = gl_label_get_selection_list (label);
1255 for ( p = selection_list; p != NULL; p = p->next )
1257 object = GL_LABEL_OBJECT (p->data);
1259 label->priv->object_list = g_list_remove (label->priv->object_list, object);
1262 /* Move to end of list, representing front most object */
1263 label->priv->object_list = g_list_concat (label->priv->object_list, selection_list);
1267 end_selection_op (label);
1269 gl_debug (DEBUG_LABEL, "END");
1273 /****************************************************************************/
1274 /* Send selection to rear/bottom. */
1275 /****************************************************************************/
1277 gl_label_lower_selection_to_bottom (glLabel *label)
1279 GList *selection_list;
1281 glLabelObject *object;
1283 gl_debug (DEBUG_LABEL, "START");
1285 gl_label_checkpoint (label, _("Send to back"));
1287 begin_selection_op (label);
1289 selection_list = gl_label_get_selection_list (label);
1291 for ( p = selection_list; p != NULL; p = p->next )
1293 object = GL_LABEL_OBJECT (p->data);
1295 label->priv->object_list = g_list_remove (label->priv->object_list, object);
1298 /* Move to front of list, representing rear most object */
1299 label->priv->object_list = g_list_concat (selection_list, label->priv->object_list);
1303 end_selection_op (label);
1305 gl_debug (DEBUG_LABEL, "END");
1309 /*****************************************************************************/
1310 /* Rotate selected objects by given angle. */
1311 /*****************************************************************************/
1313 gl_label_rotate_selection (glLabel *label,
1316 GList *selection_list;
1318 glLabelObject *object;
1320 gl_debug (DEBUG_LABEL, "START");
1322 g_return_if_fail (label && GL_IS_LABEL (label));
1324 begin_selection_op (label);
1326 gl_label_checkpoint (label, _("Rotate"));
1328 selection_list = gl_label_get_selection_list (label);
1330 for ( p = selection_list; p != NULL; p = p->next )
1332 object = GL_LABEL_OBJECT (p->data);
1334 gl_label_object_rotate (object, theta_degs);
1337 g_list_free (selection_list);
1339 end_selection_op (label);
1341 gl_debug (DEBUG_LABEL, "END");
1345 /*****************************************************************************/
1346 /* Rotate selected objects 90 degrees left. */
1347 /*****************************************************************************/
1349 gl_label_rotate_selection_left (glLabel *label)
1351 GList *selection_list;
1353 glLabelObject *object;
1355 gl_debug (DEBUG_LABEL, "START");
1357 g_return_if_fail (label && GL_IS_LABEL (label));
1359 begin_selection_op (label);
1361 gl_label_checkpoint (label, _("Rotate left"));
1363 selection_list = gl_label_get_selection_list (label);
1365 for ( p = selection_list; p != NULL; p = p->next )
1367 object = GL_LABEL_OBJECT (p->data);
1369 gl_label_object_rotate (object, -90.0);
1372 g_list_free (selection_list);
1374 end_selection_op (label);
1376 gl_debug (DEBUG_LABEL, "END");
1380 /*****************************************************************************/
1381 /* Rotate selected objects 90 degrees right. */
1382 /*****************************************************************************/
1384 gl_label_rotate_selection_right (glLabel *label)
1386 GList *selection_list;
1388 glLabelObject *object;
1390 gl_debug (DEBUG_LABEL, "START");
1392 g_return_if_fail (label && GL_IS_LABEL (label));
1394 gl_label_checkpoint (label, _("Rotate right"));
1396 begin_selection_op (label);
1398 selection_list = gl_label_get_selection_list (label);
1400 for ( p = selection_list; p != NULL; p = p->next )
1402 object = GL_LABEL_OBJECT (p->data);
1404 gl_label_object_rotate (object, 90.0);
1407 g_list_free (selection_list);
1409 end_selection_op (label);
1411 gl_debug (DEBUG_LABEL, "END");
1415 /*****************************************************************************/
1416 /* Flip selected objects horizontally. */
1417 /*****************************************************************************/
1419 gl_label_flip_selection_horiz (glLabel *label)
1421 GList *selection_list;
1423 glLabelObject *object;
1425 gl_debug (DEBUG_LABEL, "START");
1427 g_return_if_fail (label && GL_IS_LABEL (label));
1429 gl_label_checkpoint (label, _("Flip horizontally"));
1431 begin_selection_op (label);
1433 selection_list = gl_label_get_selection_list (label);
1435 for ( p = selection_list; p != NULL; p = p->next )
1437 object = GL_LABEL_OBJECT (p->data);
1439 gl_label_object_flip_horiz (object);
1442 g_list_free (selection_list);
1444 end_selection_op (label);
1446 gl_debug (DEBUG_LABEL, "END");
1450 /*****************************************************************************/
1451 /* Flip selected objects vertically. */
1452 /*****************************************************************************/
1454 gl_label_flip_selection_vert (glLabel *label)
1456 GList *selection_list;
1458 glLabelObject *object;
1460 gl_debug (DEBUG_LABEL, "START");
1462 g_return_if_fail (label && GL_IS_LABEL (label));
1464 gl_label_checkpoint (label, _("Flip vertically"));
1466 begin_selection_op (label);
1468 selection_list = gl_label_get_selection_list (label);
1470 for ( p = selection_list; p != NULL; p = p->next )
1472 object = GL_LABEL_OBJECT (p->data);
1474 gl_label_object_flip_vert (object);
1477 g_list_free (selection_list);
1479 end_selection_op (label);
1481 gl_debug (DEBUG_LABEL, "END");
1485 /*****************************************************************************/
1486 /* Align selected objects to left most edge. */
1487 /*****************************************************************************/
1489 gl_label_align_selection_left (glLabel *label)
1491 GList *selection_list;
1493 glLabelObject *object;
1495 glLabelRegion obj_extent;
1497 gl_debug (DEBUG_LABEL, "START");
1499 g_return_if_fail (label && GL_IS_LABEL (label));
1501 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1502 !gl_label_is_selection_atomic (label));
1504 gl_label_checkpoint (label, _("Align left"));
1506 begin_selection_op (label);
1508 selection_list = gl_label_get_selection_list (label);
1510 /* find left most edge */
1512 object = GL_LABEL_OBJECT (p->data);
1514 gl_label_object_get_extent (object, &obj_extent);
1515 x1_min = obj_extent.x1;
1516 for (p = p->next; p != NULL; p = p->next)
1518 object = GL_LABEL_OBJECT (p->data);
1520 gl_label_object_get_extent (object, &obj_extent);
1521 if ( obj_extent.x1 < x1_min ) x1_min = obj_extent.x1;
1524 /* now adjust the object positions to line up the left edges */
1525 for (p = selection_list; p != NULL; p = p->next)
1527 object = GL_LABEL_OBJECT (p->data);
1529 gl_label_object_get_extent (object, &obj_extent);
1530 dx = x1_min - obj_extent.x1;
1531 gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1534 g_list_free (selection_list);
1536 end_selection_op (label);
1538 gl_debug (DEBUG_LABEL, "END");
1542 /*****************************************************************************/
1543 /* Align selected objects to right most edge. */
1544 /*****************************************************************************/
1546 gl_label_align_selection_right (glLabel *label)
1548 GList *selection_list;
1550 glLabelObject *object;
1552 glLabelRegion obj_extent;
1554 gl_debug (DEBUG_LABEL, "START");
1556 g_return_if_fail (label && GL_IS_LABEL (label));
1558 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1559 !gl_label_is_selection_atomic (label));
1561 gl_label_checkpoint (label, _("Align right"));
1563 begin_selection_op (label);
1565 selection_list = gl_label_get_selection_list (label);
1567 /* find left most edge */
1569 object = GL_LABEL_OBJECT (p->data);
1571 gl_label_object_get_extent (object, &obj_extent);
1572 x2_max = obj_extent.x2;
1573 for (p = p->next; p != NULL; p = p->next)
1575 object = GL_LABEL_OBJECT (p->data);
1577 gl_label_object_get_extent (object, &obj_extent);
1578 if ( obj_extent.x2 > x2_max ) x2_max = obj_extent.x2;
1581 /* now adjust the object positions to line up the left edges */
1582 for (p = selection_list; p != NULL; p = p->next)
1584 object = GL_LABEL_OBJECT (p->data);
1586 gl_label_object_get_extent (object, &obj_extent);
1587 dx = x2_max - obj_extent.x2;
1588 gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1591 g_list_free (selection_list);
1593 end_selection_op (label);
1595 gl_debug (DEBUG_LABEL, "END");
1599 /*****************************************************************************/
1600 /* Align selected objects to horizontal center of objects. */
1601 /*****************************************************************************/
1603 gl_label_align_selection_hcenter (glLabel *label)
1605 GList *selection_list;
1607 glLabelObject *object;
1611 glLabelRegion obj_extent;
1615 gl_debug (DEBUG_LABEL, "START");
1617 g_return_if_fail (label && GL_IS_LABEL (label));
1619 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1620 !gl_label_is_selection_atomic (label));
1622 gl_label_checkpoint (label, _("Align horizontal center"));
1624 begin_selection_op (label);
1626 selection_list = gl_label_get_selection_list (label);
1628 /* find average center of objects */
1631 for (p = selection_list; p != NULL; p = p->next)
1633 object = GL_LABEL_OBJECT (p->data);
1635 gl_label_object_get_extent (object, &obj_extent);
1636 xsum += (obj_extent.x1 + obj_extent.x2) / 2.0;
1641 /* find center of object closest to average center */
1643 object = GL_LABEL_OBJECT (p->data);
1645 gl_label_object_get_extent (object, &obj_extent);
1646 dxmin = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
1647 xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
1648 for (p = p->next; p != NULL; p = p->next)
1650 object = GL_LABEL_OBJECT (p->data);
1652 gl_label_object_get_extent (object, &obj_extent);
1653 dx = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
1657 xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
1661 /* now adjust the object positions to line up this center */
1662 for (p = selection_list; p != NULL; p = p->next)
1664 object = GL_LABEL_OBJECT (p->data);
1666 gl_label_object_get_extent (object, &obj_extent);
1667 dx = xcenter - (obj_extent.x1 + obj_extent.x2)/2.0;
1668 gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1671 g_list_free (selection_list);
1673 end_selection_op (label);
1675 gl_debug (DEBUG_LABEL, "END");
1679 /*****************************************************************************/
1680 /* Align selected objects to top most edge. */
1681 /*****************************************************************************/
1683 gl_label_align_selection_top (glLabel *label)
1685 GList *selection_list;
1687 glLabelObject *object;
1689 glLabelRegion obj_extent;
1691 gl_debug (DEBUG_LABEL, "START");
1693 g_return_if_fail (label && GL_IS_LABEL (label));
1695 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1696 !gl_label_is_selection_atomic (label));
1698 gl_label_checkpoint (label, _("Align tops"));
1700 begin_selection_op (label);
1702 selection_list = gl_label_get_selection_list (label);
1704 /* find top most edge */
1706 object = GL_LABEL_OBJECT (p->data);
1708 gl_label_object_get_extent (object, &obj_extent);
1709 y1_min = obj_extent.y1;
1710 for (p = p->next; p != NULL; p = p->next)
1712 object = GL_LABEL_OBJECT (p->data);
1714 gl_label_object_get_extent (object, &obj_extent);
1715 if ( obj_extent.y1 < y1_min ) y1_min = obj_extent.y1;
1718 /* now adjust the object positions to line up the top edges */
1719 for (p = selection_list; p != NULL; p = p->next)
1721 object = GL_LABEL_OBJECT (p->data);
1723 gl_label_object_get_extent (object, &obj_extent);
1724 dy = y1_min - obj_extent.y1;
1725 gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1728 g_list_free (selection_list);
1730 end_selection_op (label);
1732 gl_debug (DEBUG_LABEL, "END");
1736 /*****************************************************************************/
1737 /* Align selected objects to bottom most edge. */
1738 /*****************************************************************************/
1740 gl_label_align_selection_bottom (glLabel *label)
1742 GList *selection_list;
1744 glLabelObject *object;
1746 glLabelRegion obj_extent;
1748 gl_debug (DEBUG_LABEL, "START");
1750 g_return_if_fail (label && GL_IS_LABEL (label));
1752 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1753 !gl_label_is_selection_atomic (label));
1755 gl_label_checkpoint (label, _("Align bottoms"));
1757 begin_selection_op (label);
1759 selection_list = gl_label_get_selection_list (label);
1761 /* find bottom most edge */
1763 object = GL_LABEL_OBJECT (p->data);
1765 gl_label_object_get_extent (object, &obj_extent);
1766 y2_max = obj_extent.y2;
1767 for (p = p->next; p != NULL; p = p->next)
1769 object = GL_LABEL_OBJECT (p->data);
1771 gl_label_object_get_extent (object, &obj_extent);
1772 if ( obj_extent.y2 > y2_max ) y2_max = obj_extent.y2;
1775 /* now adjust the object positions to line up the bottom edges */
1776 for (p = selection_list; p != NULL; p = p->next)
1778 object = GL_LABEL_OBJECT (p->data);
1780 gl_label_object_get_extent (object, &obj_extent);
1781 dy = y2_max - obj_extent.y2;
1782 gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1785 g_list_free (selection_list);
1787 end_selection_op (label);
1789 gl_debug (DEBUG_LABEL, "END");
1793 /*****************************************************************************/
1794 /* Align selected objects to viertical center of objects. */
1795 /*****************************************************************************/
1797 gl_label_align_selection_vcenter (glLabel *label)
1799 GList *selection_list;
1801 glLabelObject *object;
1805 glLabelRegion obj_extent;
1809 gl_debug (DEBUG_LABEL, "START");
1811 g_return_if_fail (label && GL_IS_LABEL (label));
1813 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1814 !gl_label_is_selection_atomic (label));
1816 gl_label_checkpoint (label, _("Align vertical center"));
1818 begin_selection_op (label);
1820 selection_list = gl_label_get_selection_list (label);
1822 /* find average center of objects */
1825 for (p = selection_list; p != NULL; p = p->next)
1827 object = GL_LABEL_OBJECT (p->data);
1829 gl_label_object_get_extent (object, &obj_extent);
1830 ysum += (obj_extent.y1 + obj_extent.y2) / 2.0;
1835 /* find center of object closest to average center */
1837 object = GL_LABEL_OBJECT (p->data);
1839 gl_label_object_get_extent (object, &obj_extent);
1840 dymin = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
1841 ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
1842 for (p = p->next; p != NULL; p = p->next)
1844 object = GL_LABEL_OBJECT (p->data);
1846 gl_label_object_get_extent (object, &obj_extent);
1847 dy = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
1851 ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
1855 /* now adjust the object positions to line up this center */
1856 for (p = selection_list; p != NULL; p = p->next)
1858 object = GL_LABEL_OBJECT (p->data);
1860 gl_label_object_get_extent (object, &obj_extent);
1861 dy = ycenter - (obj_extent.y1 + obj_extent.y2)/2.0;
1862 gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1865 g_list_free (selection_list);
1867 end_selection_op (label);
1869 gl_debug (DEBUG_LABEL, "END");
1873 /*****************************************************************************/
1874 /* Center selected objects to in center of label. */
1875 /*****************************************************************************/
1877 gl_label_center_selection_horiz (glLabel *label)
1879 GList *selection_list;
1881 glLabelObject *object;
1883 gdouble x_label_center;
1884 gdouble x_obj_center;
1885 glLabelRegion obj_extent;
1888 gl_debug (DEBUG_LABEL, "START");
1890 g_return_if_fail (label && GL_IS_LABEL (label));
1892 g_return_if_fail (!gl_label_is_selection_empty (label));
1894 gl_label_checkpoint (label, _("Center horizontally"));
1896 begin_selection_op (label);
1898 gl_label_get_size (label, &w, &h);
1899 x_label_center = w / 2.0;
1901 /* adjust the object positions */
1902 selection_list = gl_label_get_selection_list (label);
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 x_obj_center = (obj_extent.x1 + obj_extent.x2) / 2.0;
1909 dx = x_label_center - x_obj_center;
1910 gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1912 g_list_free (selection_list);
1914 end_selection_op (label);
1916 gl_debug (DEBUG_LABEL, "END");
1920 /*****************************************************************************/
1921 /* Center selected objects to in center of label. */
1922 /*****************************************************************************/
1924 gl_label_center_selection_vert (glLabel *label)
1926 GList *selection_list;
1928 glLabelObject *object;
1930 gdouble y_label_center;
1931 gdouble y_obj_center;
1932 glLabelRegion obj_extent;
1935 gl_debug (DEBUG_LABEL, "START");
1937 g_return_if_fail (label && GL_IS_LABEL (label));
1939 g_return_if_fail (!gl_label_is_selection_empty (label));
1941 gl_label_checkpoint (label, _("Center vertically"));
1943 begin_selection_op (label);
1945 gl_label_get_size (label, &w, &h);
1946 y_label_center = h / 2.0;
1948 /* adjust the object positions */
1949 selection_list = gl_label_get_selection_list (label);
1950 for (p = selection_list; p != NULL; p = p->next)
1952 object = GL_LABEL_OBJECT (p->data);
1954 gl_label_object_get_extent (object, &obj_extent);
1955 y_obj_center = (obj_extent.y1 + obj_extent.y2) / 2.0;
1956 dy = y_label_center - y_obj_center;
1957 gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1959 g_list_free (selection_list);
1961 end_selection_op (label);
1963 gl_debug (DEBUG_LABEL, "END");
1967 /*****************************************************************************/
1968 /* Move selected objects */
1969 /*****************************************************************************/
1971 gl_label_move_selection (glLabel *label,
1975 GList *selection_list;
1977 glLabelObject *object;
1979 gl_debug (DEBUG_LABEL, "START");
1981 g_return_if_fail (label && GL_IS_LABEL (label));
1983 begin_selection_op (label);
1985 selection_list = gl_label_get_selection_list (label);
1987 for (p = selection_list; p != NULL; p = p->next)
1989 object = GL_LABEL_OBJECT (p->data);
1991 gl_label_object_set_position_relative (object, dx, dy, TRUE);
1994 g_list_free (selection_list);
1996 end_selection_op (label);
1998 gl_debug (DEBUG_LABEL, "END");
2002 /*****************************************************************************/
2003 /* Set font family for all text contained in selected objects. */
2004 /*****************************************************************************/
2006 gl_label_set_selection_font_family (glLabel *label,
2007 const gchar *font_family)
2009 GList *selection_list;
2011 glLabelObject *object;
2013 gl_debug (DEBUG_LABEL, "START");
2015 g_return_if_fail (label && GL_IS_LABEL (label));
2017 begin_selection_op (label);
2019 selection_list = gl_label_get_selection_list (label);
2021 for (p = selection_list; p != NULL; p = p->next)
2023 object = GL_LABEL_OBJECT (p->data);
2024 gl_label_object_set_font_family (object, font_family, TRUE);
2027 g_list_free (selection_list);
2029 end_selection_op (label);
2031 gl_debug (DEBUG_LABEL, "END");
2035 /*****************************************************************************/
2036 /* Set font size for all text contained in selected objects. */
2037 /*****************************************************************************/
2039 gl_label_set_selection_font_size (glLabel *label,
2042 GList *selection_list;
2044 glLabelObject *object;
2046 gl_debug (DEBUG_LABEL, "START");
2048 g_return_if_fail (label && GL_IS_LABEL (label));
2050 begin_selection_op (label);
2052 selection_list = gl_label_get_selection_list (label);
2054 for (p = selection_list; p != NULL; p = p->next)
2056 object = GL_LABEL_OBJECT (p->data);
2057 gl_label_object_set_font_size (object, font_size, TRUE);
2060 g_list_free (selection_list);
2062 end_selection_op (label);
2064 gl_debug (DEBUG_LABEL, "END");
2068 /*****************************************************************************/
2069 /* Set font weight for all text contained in selected objects. */
2070 /*****************************************************************************/
2072 gl_label_set_selection_font_weight (glLabel *label,
2073 PangoWeight font_weight)
2075 GList *selection_list;
2077 glLabelObject *object;
2079 gl_debug (DEBUG_LABEL, "START");
2081 g_return_if_fail (label && GL_IS_LABEL (label));
2083 begin_selection_op (label);
2085 selection_list = gl_label_get_selection_list (label);
2087 for (p = selection_list; p != NULL; p = p->next)
2089 object = GL_LABEL_OBJECT (p->data);
2090 gl_label_object_set_font_weight (object, font_weight, TRUE);
2093 g_list_free (selection_list);
2095 end_selection_op (label);
2097 gl_debug (DEBUG_LABEL, "END");
2101 /*****************************************************************************/
2102 /* Set font italic flag for all text contained in selected objects. */
2103 /*****************************************************************************/
2105 gl_label_set_selection_font_italic_flag (glLabel *label,
2106 gboolean font_italic_flag)
2108 GList *selection_list;
2110 glLabelObject *object;
2112 gl_debug (DEBUG_LABEL, "START");
2114 g_return_if_fail (label && GL_IS_LABEL (label));
2116 begin_selection_op (label);
2118 selection_list = gl_label_get_selection_list (label);
2120 for (p = selection_list; p != NULL; p = p->next)
2122 object = GL_LABEL_OBJECT (p->data);
2123 gl_label_object_set_font_italic_flag (object, font_italic_flag, TRUE);
2126 g_list_free (selection_list);
2128 end_selection_op (label);
2130 gl_debug (DEBUG_LABEL, "END");
2134 /*****************************************************************************/
2135 /* Set text alignment for all text contained in selected objects. */
2136 /*****************************************************************************/
2138 gl_label_set_selection_text_alignment (glLabel *label,
2139 PangoAlignment text_alignment)
2141 GList *selection_list;
2143 glLabelObject *object;
2145 gl_debug (DEBUG_LABEL, "START");
2147 g_return_if_fail (label && GL_IS_LABEL (label));
2149 begin_selection_op (label);
2151 selection_list = gl_label_get_selection_list (label);
2153 for (p = selection_list; p != NULL; p = p->next)
2155 object = GL_LABEL_OBJECT (p->data);
2156 gl_label_object_set_text_alignment (object, text_alignment, TRUE);
2159 g_list_free (selection_list);
2161 end_selection_op (label);
2163 gl_debug (DEBUG_LABEL, "END");
2167 /*****************************************************************************/
2168 /* Set vertical text alignment for all text contained in selected objects. */
2169 /*****************************************************************************/
2171 gl_label_set_selection_text_valignment (glLabel *label,
2172 glValignment text_valignment)
2174 GList *selection_list;
2176 glLabelObject *object;
2178 gl_debug (DEBUG_LABEL, "START");
2180 g_return_if_fail (label && GL_IS_LABEL (label));
2182 begin_selection_op (label);
2184 selection_list = gl_label_get_selection_list (label);
2186 for (p = selection_list; p != NULL; p = p->next)
2188 object = GL_LABEL_OBJECT (p->data);
2189 gl_label_object_set_text_valignment (object, text_valignment, TRUE);
2192 g_list_free (selection_list);
2194 end_selection_op (label);
2196 gl_debug (DEBUG_LABEL, "END");
2200 /*****************************************************************************/
2201 /* Set text line spacing for all text contained in selected objects. */
2202 /*****************************************************************************/
2204 gl_label_set_selection_text_line_spacing (glLabel *label,
2205 gdouble text_line_spacing)
2207 GList *selection_list;
2209 glLabelObject *object;
2211 gl_debug (DEBUG_LABEL, "START");
2213 g_return_if_fail (label && GL_IS_LABEL (label));
2215 begin_selection_op (label);
2217 selection_list = gl_label_get_selection_list (label);
2219 for (p = selection_list; p != NULL; p = p->next)
2221 object = GL_LABEL_OBJECT (p->data);
2222 gl_label_object_set_text_line_spacing (object, text_line_spacing, TRUE);
2225 g_list_free (selection_list);
2227 end_selection_op (label);
2229 gl_debug (DEBUG_LABEL, "END");
2233 /*****************************************************************************/
2234 /* Set text color for all text contained in selected objects. */
2235 /*****************************************************************************/
2237 gl_label_set_selection_text_color (glLabel *label,
2238 glColorNode *text_color_node)
2240 GList *selection_list;
2242 glLabelObject *object;
2244 gl_debug (DEBUG_LABEL, "START");
2246 g_return_if_fail (label && GL_IS_LABEL (label));
2248 begin_selection_op (label);
2250 selection_list = gl_label_get_selection_list (label);
2252 for (p = selection_list; p != NULL; p = p->next)
2254 object = GL_LABEL_OBJECT (p->data);
2255 gl_label_object_set_text_color (object, text_color_node, TRUE);
2258 g_list_free (selection_list);
2260 end_selection_op (label);
2262 gl_debug (DEBUG_LABEL, "END");
2266 /*****************************************************************************/
2267 /* Set fill color for all selected objects. */
2268 /*****************************************************************************/
2270 gl_label_set_selection_fill_color (glLabel *label,
2271 glColorNode *fill_color_node)
2273 GList *selection_list;
2275 glLabelObject *object;
2277 gl_debug (DEBUG_LABEL, "START");
2279 g_return_if_fail (label && GL_IS_LABEL (label));
2281 begin_selection_op (label);
2283 selection_list = gl_label_get_selection_list (label);
2285 for (p = selection_list; p != NULL; p = p->next)
2287 object = GL_LABEL_OBJECT (p->data);
2288 gl_label_object_set_fill_color (object, fill_color_node, TRUE);
2291 g_list_free (selection_list);
2293 end_selection_op (label);
2295 gl_debug (DEBUG_LABEL, "END");
2299 /*****************************************************************************/
2300 /* Set line color for all selected objects. */
2301 /*****************************************************************************/
2303 gl_label_set_selection_line_color (glLabel *label,
2304 glColorNode *line_color_node)
2306 GList *selection_list;
2308 glLabelObject *object;
2310 gl_debug (DEBUG_LABEL, "START");
2312 g_return_if_fail (label && GL_IS_LABEL (label));
2314 begin_selection_op (label);
2316 selection_list = gl_label_get_selection_list (label);
2318 for (p = selection_list; p != NULL; p = p->next)
2320 object = GL_LABEL_OBJECT (p->data);
2321 gl_label_object_set_line_color (object, line_color_node, TRUE);
2324 g_list_free (selection_list);
2326 end_selection_op (label);
2328 gl_debug (DEBUG_LABEL, "END");
2332 /*****************************************************************************/
2333 /* Set line width for all selected objects. */
2334 /*****************************************************************************/
2336 gl_label_set_selection_line_width (glLabel *label,
2339 GList *selection_list;
2341 glLabelObject *object;
2343 gl_debug (DEBUG_LABEL, "START");
2345 g_return_if_fail (label && GL_IS_LABEL (label));
2347 begin_selection_op (label);
2349 selection_list = gl_label_get_selection_list (label);
2351 for (p = selection_list; p != NULL; p = p->next)
2353 object = GL_LABEL_OBJECT (p->data);
2354 gl_label_object_set_line_width (object, line_width, TRUE);
2357 g_list_free (selection_list);
2359 end_selection_op (label);
2361 gl_debug (DEBUG_LABEL, "END");
2365 /*****************************************************************************/
2366 /* "Cut" selected items and place on clipboard. */
2367 /*****************************************************************************/
2369 gl_label_cut_selection (glLabel *label)
2371 gl_debug (DEBUG_LABEL, "START");
2373 g_return_if_fail (label && GL_IS_LABEL (label));
2375 gl_label_copy_selection (label);
2376 gl_label_delete_selection (label);
2378 gl_debug (DEBUG_LABEL, "END");
2382 /*****************************************************************************/
2383 /* "Copy" selected items to clipboard. */
2384 /*****************************************************************************/
2386 gl_label_copy_selection (glLabel *label)
2388 GtkClipboard *clipboard;
2389 GList *selection_list;
2390 glLabel *label_copy;
2392 glLabelObject *object;
2393 glXMLLabelStatus status;
2395 ClipboardData *data;
2397 static GtkTargetEntry glabels_targets[] = { { "application/glabels", 0, 0 },
2398 { "text/xml", 0, 0 },
2401 GtkTargetList *target_list;
2402 GtkTargetEntry *target_table;
2405 gl_debug (DEBUG_LABEL, "START");
2407 g_return_if_fail (label && GL_IS_LABEL (label));
2409 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2411 selection_list = gl_label_get_selection_list (label);
2416 data = g_new0 (ClipboardData, 1);
2418 target_list = gtk_target_list_new (glabels_targets, G_N_ELEMENTS(glabels_targets));
2421 * Serialize selection by encoding as an XML label document.
2423 label_copy = GL_LABEL(gl_label_new ());
2425 gl_label_set_template (label_copy, label->priv->template, FALSE);
2426 gl_label_set_rotate_flag (label_copy, label->priv->rotate_flag, FALSE);
2428 for (p = selection_list; p != NULL; p = p->next)
2430 object = GL_LABEL_OBJECT (p->data);
2432 gl_label_add_object (label_copy, gl_label_object_dup (object, label_copy));
2435 data->xml_buffer = gl_xml_label_save_buffer (label_copy, &status);
2437 g_object_unref (G_OBJECT (label_copy));
2441 * Is it an atomic text selection? If so, also make available as text.
2443 if ( gl_label_is_selection_atomic (label) &&
2444 GL_IS_LABEL_TEXT (selection_list->data) )
2446 glLabelText *text_object = GL_LABEL_TEXT (selection_list->data);
2448 gtk_target_list_add_text_targets (target_list, 1);
2450 data->text = gl_label_text_get_text (text_object);
2455 * Is it an atomic image selection? If so, also make available as pixbuf.
2457 if ( gl_label_is_selection_atomic (label) &&
2458 GL_IS_LABEL_IMAGE (selection_list->data) )
2460 glLabelImage *image_object = GL_LABEL_IMAGE (selection_list->data);
2461 GdkPixbuf *pixbuf = gl_label_image_get_pixbuf (image_object, NULL);
2465 gtk_target_list_add_image_targets (target_list, 2, TRUE);
2466 data->pixbuf = pixbuf;
2471 target_table = gtk_target_table_new_from_list (target_list, &n_targets);
2473 gtk_clipboard_set_with_data (clipboard,
2474 target_table, n_targets,
2475 (GtkClipboardGetFunc)clipboard_get_cb,
2476 (GtkClipboardClearFunc)clipboard_clear_cb,
2479 gtk_target_table_free (target_table, n_targets);
2480 gtk_target_list_unref (target_list);
2484 g_list_free (selection_list);
2486 gl_debug (DEBUG_LABEL, "END");
2490 /*****************************************************************************/
2491 /* "Paste" from clipboard. */
2492 /*****************************************************************************/
2494 gl_label_paste (glLabel *label)
2496 GtkClipboard *clipboard;
2498 gl_debug (DEBUG_LABEL, "START");
2500 g_return_if_fail (label && GL_IS_LABEL (label));
2502 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2504 gtk_clipboard_request_targets (clipboard,
2505 (GtkClipboardTargetsReceivedFunc)receive_targets_cb,
2508 gl_debug (DEBUG_LABEL, "END");
2512 /*****************************************************************************/
2513 /* Is there anything that can be pasted? */
2514 /*****************************************************************************/
2516 gl_label_can_paste (glLabel *label)
2518 GtkClipboard *clipboard;
2521 gl_debug (DEBUG_LABEL, "START");
2523 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2525 can_flag = gtk_clipboard_wait_is_target_available (clipboard,
2526 gdk_atom_intern("application/glabels", TRUE))
2527 || gtk_clipboard_wait_is_text_available (clipboard)
2528 || gtk_clipboard_wait_is_image_available (clipboard);
2530 gl_debug (DEBUG_LABEL, "END");
2535 /****************************************************************************/
2536 /* Clipboard "Get" function. */
2537 /****************************************************************************/
2539 clipboard_get_cb (GtkClipboard *clipboard,
2540 GtkSelectionData *selection_data,
2542 ClipboardData *data)
2544 gl_debug (DEBUG_LABEL, "START");
2550 gtk_selection_data_set (selection_data,
2551 gtk_selection_data_get_target (selection_data),
2553 (guchar *)data->xml_buffer, strlen (data->xml_buffer));
2557 gtk_selection_data_set_text (selection_data, data->text, -1);
2561 gtk_selection_data_set_pixbuf (selection_data, data->pixbuf);
2565 g_assert_not_reached ();
2570 gl_debug (DEBUG_LABEL, "END");
2574 /****************************************************************************/
2575 /* Clipboard "Clear" function. */
2576 /****************************************************************************/
2578 clipboard_clear_cb (GtkClipboard *clipboard,
2579 ClipboardData *data)
2581 gl_debug (DEBUG_LABEL, "START");
2583 g_free (data->xml_buffer);
2584 g_free (data->text);
2587 g_object_unref (data->pixbuf);
2592 gl_debug (DEBUG_LABEL, "END");
2596 /****************************************************************************/
2597 /* Deal with clipboard data. */
2598 /****************************************************************************/
2600 receive_targets_cb (GtkClipboard *clipboard,
2608 * Application/glabels
2610 for ( i = 0; i < n_targets; i++ )
2612 if ( strcmp(gdk_atom_name(targets[i]), "application/glabels") == 0 )
2614 gtk_clipboard_request_contents (clipboard,
2615 gdk_atom_intern("application/glabels", TRUE),
2616 (GtkClipboardReceivedFunc)paste_xml_received_cb,
2625 if ( gtk_targets_include_text (targets, n_targets) )
2627 gtk_clipboard_request_text (clipboard,
2628 (GtkClipboardTextReceivedFunc)paste_text_received_cb,
2636 if ( gtk_targets_include_image (targets, n_targets, TRUE) )
2638 gtk_clipboard_request_image (clipboard,
2639 (GtkClipboardImageReceivedFunc)paste_image_received_cb,
2646 /****************************************************************************/
2647 /* Paste received glabels XML callback. */
2648 /****************************************************************************/
2650 paste_xml_received_cb (GtkClipboard *clipboard,
2651 GtkSelectionData *selection_data,
2655 glLabel *label_copy;
2656 glXMLLabelStatus status;
2658 glLabelObject *object, *newobject;
2660 gl_debug (DEBUG_LABEL, "START");
2662 gl_label_checkpoint (label, _("Paste"));
2664 xml_buffer = (gchar *)gtk_selection_data_get_data (selection_data);
2667 * Deserialize XML label document and extract objects.
2669 label_copy = gl_xml_label_open_buffer (xml_buffer, &status);
2672 gl_label_unselect_all (label);
2674 for (p = label_copy->priv->object_list; p != NULL; p = p->next)
2676 object = (glLabelObject *) p->data;
2677 newobject = gl_label_object_dup (object, label);
2678 gl_label_add_object( label, newobject );
2680 gl_label_select_object (label, newobject);
2682 gl_debug (DEBUG_LABEL, "object pasted");
2685 g_object_unref (G_OBJECT (label_copy));
2688 gl_debug (DEBUG_LABEL, "END");
2692 /****************************************************************************/
2693 /* Paste received text callback. */
2694 /****************************************************************************/
2696 paste_text_received_cb (GtkClipboard *clipboard,
2700 glLabelObject *object;
2702 gl_debug (DEBUG_LABEL, "START");
2704 gl_label_checkpoint (label, _("Paste"));
2706 gl_label_unselect_all (label);
2708 object = GL_LABEL_OBJECT (gl_label_text_new (label, FALSE));
2709 gl_label_text_set_text (GL_LABEL_TEXT (object), text, FALSE);
2710 gl_label_object_set_position (object, 18, 18, FALSE);
2712 gl_label_select_object (label, object);
2714 gl_debug (DEBUG_LABEL, "END");
2718 /****************************************************************************/
2719 /* Paste received image callback. */
2720 /****************************************************************************/
2722 paste_image_received_cb (GtkClipboard *clipboard,
2726 glLabelObject *object;
2728 gl_debug (DEBUG_LABEL, "START");
2730 gl_label_checkpoint (label, _("Paste"));
2732 gl_label_unselect_all (label);
2734 object = GL_LABEL_OBJECT (gl_label_image_new (label, FALSE));
2735 gl_label_image_set_pixbuf (GL_LABEL_IMAGE (object), pixbuf, FALSE);
2736 gl_label_object_set_position (object, 18, 18, FALSE);
2738 gl_label_select_object (label, object);
2740 gl_debug (DEBUG_LABEL, "END");
2744 /****************************************************************************/
2745 /* Set default font family. */
2746 /****************************************************************************/
2748 gl_label_set_default_font_family (glLabel *label,
2749 const gchar *font_family)
2751 gl_debug (DEBUG_LABEL, "START");
2753 g_return_if_fail (label && GL_IS_LABEL (label));
2755 g_free (label->priv->default_font_family);
2756 label->priv->default_font_family = g_strdup (font_family);
2758 gl_debug (DEBUG_LABEL, "END");
2762 /****************************************************************************/
2763 /* Set default font size. */
2764 /****************************************************************************/
2766 gl_label_set_default_font_size (glLabel *label,
2769 gl_debug (DEBUG_LABEL, "START");
2771 g_return_if_fail (label && GL_IS_LABEL (label));
2773 label->priv->default_font_size = font_size;
2775 gl_debug (DEBUG_LABEL, "END");
2779 /****************************************************************************/
2780 /* Set default font weight. */
2781 /****************************************************************************/
2783 gl_label_set_default_font_weight (glLabel *label,
2784 PangoWeight font_weight)
2786 gl_debug (DEBUG_LABEL, "START");
2788 g_return_if_fail (label && GL_IS_LABEL (label));
2790 label->priv->default_font_weight = font_weight;
2792 gl_debug (DEBUG_LABEL, "END");
2796 /****************************************************************************/
2797 /* Set default font italic flag. */
2798 /****************************************************************************/
2800 gl_label_set_default_font_italic_flag (glLabel *label,
2801 gboolean font_italic_flag)
2803 gl_debug (DEBUG_LABEL, "START");
2805 g_return_if_fail (label && GL_IS_LABEL (label));
2807 label->priv->default_font_italic_flag = font_italic_flag;
2809 gl_debug (DEBUG_LABEL, "END");
2813 /****************************************************************************/
2814 /* Set default text color. */
2815 /****************************************************************************/
2817 gl_label_set_default_text_color (glLabel *label,
2820 gl_debug (DEBUG_LABEL, "START");
2822 g_return_if_fail (label && GL_IS_LABEL (label));
2824 label->priv->default_text_color = text_color;
2826 gl_debug (DEBUG_LABEL, "END");
2830 /****************************************************************************/
2831 /* Set default text alignment. */
2832 /****************************************************************************/
2834 gl_label_set_default_text_alignment (glLabel *label,
2835 PangoAlignment text_alignment)
2837 gl_debug (DEBUG_LABEL, "START");
2839 g_return_if_fail (label && GL_IS_LABEL (label));
2841 label->priv->default_text_alignment = text_alignment;
2842 gl_debug (DEBUG_LABEL, "END");
2846 /****************************************************************************/
2847 /* Set default vertical text alignment. */
2848 /****************************************************************************/
2850 gl_label_set_default_text_valignment (glLabel *label,
2851 glValignment text_valignment)
2853 gl_debug (DEBUG_LABEL, "START");
2855 g_return_if_fail (label && GL_IS_LABEL (label));
2857 label->priv->default_text_valignment = text_valignment;
2858 gl_debug (DEBUG_LABEL, "END");
2862 /****************************************************************************/
2863 /* Set default text line spacing. */
2864 /****************************************************************************/
2866 gl_label_set_default_text_line_spacing (glLabel *label,
2867 gdouble text_line_spacing)
2869 gl_debug (DEBUG_LABEL, "START");
2871 g_return_if_fail (label && GL_IS_LABEL (label));
2873 label->priv->default_text_line_spacing = text_line_spacing;
2875 gl_debug (DEBUG_LABEL, "END");
2879 /****************************************************************************/
2880 /* Set default line width. */
2881 /****************************************************************************/
2883 gl_label_set_default_line_width (glLabel *label,
2886 gl_debug (DEBUG_LABEL, "START");
2888 g_return_if_fail (label && GL_IS_LABEL (label));
2890 label->priv->default_line_width = line_width;
2892 gl_debug (DEBUG_LABEL, "END");
2896 /****************************************************************************/
2897 /* Set default line color. */
2898 /****************************************************************************/
2900 gl_label_set_default_line_color (glLabel *label,
2903 gl_debug (DEBUG_LABEL, "START");
2905 g_return_if_fail (label && GL_IS_LABEL (label));
2907 label->priv->default_line_color = line_color;
2909 gl_debug (DEBUG_LABEL, "END");
2913 /****************************************************************************/
2914 /* Set default fill color. */
2915 /****************************************************************************/
2917 gl_label_set_default_fill_color (glLabel *label,
2920 gl_debug (DEBUG_LABEL, "START");
2922 g_return_if_fail (label && GL_IS_LABEL (label));
2924 label->priv->default_fill_color = fill_color;
2926 gl_debug (DEBUG_LABEL, "END");
2930 /****************************************************************************/
2931 /* Get default font family. */
2932 /****************************************************************************/
2934 gl_label_get_default_font_family (glLabel *label)
2936 gl_debug (DEBUG_LABEL, "START");
2938 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
2940 gl_debug (DEBUG_LABEL, "END");
2942 return g_strdup (label->priv->default_font_family);
2946 /****************************************************************************/
2947 /* Get default font size. */
2948 /****************************************************************************/
2950 gl_label_get_default_font_size (glLabel *label)
2952 gl_debug (DEBUG_LABEL, "START");
2954 g_return_val_if_fail (label && GL_IS_LABEL (label), 12.0);
2956 gl_debug (DEBUG_LABEL, "END");
2958 return label->priv->default_font_size;
2962 /****************************************************************************/
2963 /* Get default font weight. */
2964 /****************************************************************************/
2966 gl_label_get_default_font_weight (glLabel *label)
2968 gl_debug (DEBUG_LABEL, "START");
2970 g_return_val_if_fail (label && GL_IS_LABEL (label), PANGO_WEIGHT_NORMAL);
2972 gl_debug (DEBUG_LABEL, "END");
2974 return label->priv->default_font_weight;
2978 /****************************************************************************/
2979 /* Get default font italic flag. */
2980 /****************************************************************************/
2982 gl_label_get_default_font_italic_flag (glLabel *label)
2984 gl_debug (DEBUG_LABEL, "START");
2986 g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
2988 gl_debug (DEBUG_LABEL, "END");
2990 return label->priv->default_font_italic_flag;
2994 /****************************************************************************/
2995 /* Get default text color. */
2996 /****************************************************************************/
2998 gl_label_get_default_text_color (glLabel *label)
3000 gl_debug (DEBUG_LABEL, "START");
3002 g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
3004 gl_debug (DEBUG_LABEL, "END");
3006 return label->priv->default_text_color;
3010 /****************************************************************************/
3011 /* Get default text alignment. */
3012 /****************************************************************************/
3014 gl_label_get_default_text_alignment (glLabel *label)
3016 gl_debug (DEBUG_LABEL, "START");
3018 g_return_val_if_fail (label && GL_IS_LABEL (label), PANGO_ALIGN_LEFT);
3020 gl_debug (DEBUG_LABEL, "END");
3022 return label->priv->default_text_alignment;
3026 /****************************************************************************/
3027 /* Get default vertical text alignment. */
3028 /****************************************************************************/
3030 gl_label_get_default_text_valignment (glLabel *label)
3032 gl_debug (DEBUG_LABEL, "START");
3034 g_return_val_if_fail (label && GL_IS_LABEL (label), GL_VALIGN_TOP);
3036 gl_debug (DEBUG_LABEL, "END");
3038 return label->priv->default_text_valignment;
3042 /****************************************************************************/
3043 /* Get default text line spacing. */
3044 /****************************************************************************/
3046 gl_label_get_default_text_line_spacing (glLabel *label)
3048 gl_debug (DEBUG_LABEL, "START");
3050 g_return_val_if_fail (label && GL_IS_LABEL (label), 1.0);
3052 gl_debug (DEBUG_LABEL, "END");
3054 return label->priv->default_text_line_spacing;
3058 /****************************************************************************/
3059 /* Get default line width. */
3060 /****************************************************************************/
3062 gl_label_get_default_line_width (glLabel *label)
3064 gl_debug (DEBUG_LABEL, "START");
3066 g_return_val_if_fail (label && GL_IS_LABEL (label), 1.0);
3068 gl_debug (DEBUG_LABEL, "END");
3070 return label->priv->default_line_width;
3074 /****************************************************************************/
3075 /* Get default line color. */
3076 /****************************************************************************/
3078 gl_label_get_default_line_color (glLabel *label)
3080 gl_debug (DEBUG_LABEL, "START");
3082 g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
3084 gl_debug (DEBUG_LABEL, "END");
3086 return label->priv->default_line_color;
3090 /****************************************************************************/
3091 /* Get default fill color. */
3092 /****************************************************************************/
3094 gl_label_get_default_fill_color (glLabel *label)
3096 gl_debug (DEBUG_LABEL, "START");
3098 g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
3100 gl_debug (DEBUG_LABEL, "END");
3102 return label->priv->default_fill_color;
3106 /****************************************************************************/
3108 /****************************************************************************/
3110 gl_label_draw (glLabel *label,
3112 gboolean screen_flag,
3113 glMergeRecord *record)
3116 glLabelObject *object;
3118 g_return_if_fail (label && GL_IS_LABEL (label));
3120 for (p_obj = label->priv->object_list; p_obj != NULL; p_obj = p_obj->next)
3122 object = GL_LABEL_OBJECT (p_obj->data);
3124 gl_label_object_draw (object, cr, screen_flag, record);
3129 /****************************************************************************/
3130 /* Get object located at coordinates. */
3131 /****************************************************************************/
3132 glLabelObject *gl_label_object_at (glLabel *label,
3138 glLabelObject *object;
3140 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
3142 for (p_obj = g_list_last (label->priv->object_list); p_obj != NULL; p_obj = p_obj->prev)
3144 object = GL_LABEL_OBJECT (p_obj->data);
3146 if (gl_label_object_is_located_at (object, cr, x_pixels, y_pixels))
3157 /****************************************************************************/
3158 /* Return handle and associated object at coordinates. */
3159 /****************************************************************************/
3161 gl_label_get_handle_at (glLabel *label,
3165 glLabelObjectHandle *handle)
3167 GList *selection_list;
3169 glLabelObject *object;
3171 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
3173 selection_list = gl_label_get_selection_list (label);
3175 for (p_obj = g_list_last (selection_list); p_obj != NULL; p_obj = p_obj->prev)
3178 object = GL_LABEL_OBJECT (p_obj->data);
3180 if ((*handle = gl_label_object_handle_at (object, cr, x_pixels, y_pixels)))
3182 g_list_free (selection_list);
3188 g_list_free (selection_list);
3190 *handle = GL_LABEL_OBJECT_HANDLE_NONE;
3195 /****************************************************************************/
3196 /* Checkpoint state. */
3197 /****************************************************************************/
3199 gl_label_checkpoint (glLabel *this,
3200 const gchar *description)
3204 gl_debug (DEBUG_LABEL, "START");
3207 * Do not perform consecutive checkpoints that are identical.
3208 * E.g. moving an object by dragging, would produce a large number
3209 * of incremental checkpoints -- what we really want is a single
3210 * checkpoint so that we can undo the entire dragging effort with
3213 if ( this->priv->cp_cleared_flag
3214 || (this->priv->cp_desc == NULL)
3215 || (strcmp (description, this->priv->cp_desc) != 0) )
3218 /* Sever old redo "thread" */
3219 stack_clear (this->priv->redo_stack);
3221 /* Save state onto undo stack. */
3222 state = state_new (this, description);
3223 stack_push_state (this->priv->undo_stack, state);
3225 /* Track consecutive checkpoints. */
3226 this->priv->cp_cleared_flag = FALSE;
3227 this->priv->cp_desc = g_strdup (description);
3230 gl_debug (DEBUG_LABEL, "END");
3234 /****************************************************************************/
3236 /****************************************************************************/
3238 gl_label_undo (glLabel *this)
3243 gl_debug (DEBUG_LABEL, "START");
3245 state_old = stack_pop_state (this->priv->undo_stack);
3246 state_now = state_new (this, state_old->description);
3248 stack_push_state (this->priv->redo_stack, state_now);
3250 state_restore (state_old, this);
3251 state_free (state_old);
3253 this->priv->cp_cleared_flag = TRUE;
3255 gl_debug (DEBUG_LABEL, "END");
3259 /****************************************************************************/
3261 /****************************************************************************/
3263 gl_label_redo (glLabel *this)
3268 gl_debug (DEBUG_LABEL, "START");
3270 state_old = stack_pop_state (this->priv->redo_stack);
3271 state_now = state_new (this, state_old->description);
3273 stack_push_state (this->priv->undo_stack, state_now);
3275 state_restore (state_old, this);
3276 state_free (state_old);
3278 this->priv->cp_cleared_flag = TRUE;
3280 gl_debug (DEBUG_LABEL, "END");
3284 /****************************************************************************/
3286 /****************************************************************************/
3288 gl_label_can_undo (glLabel *this)
3290 return (!g_queue_is_empty (this->priv->undo_stack));
3294 /****************************************************************************/
3296 /****************************************************************************/
3298 gl_label_can_redo (glLabel *this)
3300 return (!g_queue_is_empty (this->priv->redo_stack));
3304 /****************************************************************************/
3305 /* Get undo description string. */
3306 /****************************************************************************/
3308 gl_label_get_undo_description (glLabel *this)
3313 state = g_queue_peek_head (this->priv->undo_stack);
3316 description = g_strdup (state->description);
3320 description = g_strdup ("");
3327 /****************************************************************************/
3328 /* Get redo description string. */
3329 /****************************************************************************/
3331 gl_label_get_redo_description (glLabel *this)
3336 state = g_queue_peek_head (this->priv->redo_stack);
3339 description = g_strdup (state->description);
3343 description = g_strdup ("");
3350 /****************************************************************************/
3351 /* Clear undo or redo stack. */
3352 /****************************************************************************/
3354 stack_clear (GQueue *stack)
3358 gl_debug (DEBUG_LABEL, "START");
3360 while ( (state = g_queue_pop_head (stack)) != NULL )
3365 gl_debug (DEBUG_LABEL, "END");
3369 /****************************************************************************/
3370 /* Push state onto stack. */
3371 /****************************************************************************/
3373 stack_push_state (GQueue *stack,
3376 gl_debug (DEBUG_LABEL, "START");
3378 g_queue_push_head( stack, state );
3380 gl_debug (DEBUG_LABEL, "END");
3384 /****************************************************************************/
3385 /* Pop state from stack. */
3386 /****************************************************************************/
3388 stack_pop_state (GQueue *stack)
3392 gl_debug (DEBUG_LABEL, "START");
3394 state = g_queue_pop_head (stack);
3396 gl_debug (DEBUG_LABEL, "END");
3401 /****************************************************************************/
3402 /* New state from label. */
3403 /****************************************************************************/
3405 state_new (glLabel *this,
3406 const gchar *description)
3410 glLabelObject *object;
3412 gl_debug (DEBUG_LABEL, "START");
3414 state = g_new0 (State, 1);
3416 state->description = g_strdup (description);
3418 state->template = lgl_template_dup (this->priv->template);
3419 state->rotate_flag = this->priv->rotate_flag;
3421 for ( p_obj = this->priv->object_list; p_obj != NULL; p_obj = p_obj->next )
3423 object = GL_LABEL_OBJECT (p_obj->data);
3425 state->object_list = g_list_append (state->object_list,
3426 gl_label_object_dup (object, this));
3429 state->merge = gl_merge_dup (this->priv->merge);
3431 state->modified_flag = this->priv->modified_flag;
3432 state->time_stamp = this->priv->time_stamp;
3435 gl_debug (DEBUG_LABEL, "END");
3440 /****************************************************************************/
3441 /* Restore label from saved state. */
3442 /****************************************************************************/
3444 state_free (State *state)
3448 gl_debug (DEBUG_LABEL, "START");
3450 g_free (state->description);
3452 lgl_template_free (state->template);
3455 g_object_unref (G_OBJECT (state->merge));
3458 for ( p_obj = state->object_list; p_obj != NULL; p_obj = p_obj->next )
3460 g_object_unref (G_OBJECT (p_obj->data));
3462 g_list_free (state->object_list);
3466 gl_debug (DEBUG_LABEL, "END");
3470 /****************************************************************************/
3471 /* Restore label from saved state. */
3472 /****************************************************************************/
3474 state_restore (State *state,
3478 GList *p_obj, *p_next;
3479 glLabelObject *object;
3481 gl_debug (DEBUG_LABEL, "START");
3483 gl_label_set_rotate_flag (this, state->rotate_flag, FALSE);
3484 gl_label_set_template (this, state->template, FALSE);
3486 for ( p_obj = this->priv->object_list; p_obj != NULL; p_obj = p_next )
3488 p_next = p_obj->next; /* Hold on to next; delete is destructive */
3489 object = GL_LABEL_OBJECT (p_obj->data);
3491 gl_label_delete_object (this, object);
3494 for ( p_obj = state->object_list; p_obj != NULL; p_obj = p_obj->next )
3496 object = GL_LABEL_OBJECT (p_obj->data);
3498 gl_label_add_object (this, gl_label_object_dup (object, this));
3500 g_signal_emit (G_OBJECT(this), signals[SELECTION_CHANGED], 0);
3502 gl_label_set_merge (this, state->merge, FALSE);
3505 if ( !state->modified_flag &&
3506 (state->time_stamp.tv_sec == this->priv->time_stamp.tv_sec) &&
3507 (state->time_stamp.tv_usec == this->priv->time_stamp.tv_usec) )
3509 gl_label_clear_modified (this);
3512 gl_debug (DEBUG_LABEL, "END");
3519 * Local Variables: -- emacs
3521 * c-basic-offset: 8 -- emacs
3522 * tab-width: 8 -- emacs
3523 * indent-tabs-mode: nil -- emacs