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 gdouble default_text_line_spacing;
80 /* Default object line properties */
81 gdouble default_line_width;
82 guint default_line_color;
84 /* Default object fill properties */
85 guint default_fill_color;
90 gboolean cp_cleared_flag;
113 gboolean modified_flag;
116 lglTemplate *template;
117 gboolean rotate_flag;
126 /*========================================================*/
127 /* Private globals. */
128 /*========================================================*/
130 static guint signals[LAST_SIGNAL] = {0};
132 static guint untitled = 0;
135 /*========================================================*/
136 /* Private function prototypes. */
137 /*========================================================*/
139 static void gl_label_finalize (GObject *object);
141 static void object_changed_cb (glLabelObject *object,
144 static void do_modify (glLabel *label);
146 static void begin_selection_op (glLabel *label);
147 static void end_selection_op (glLabel *label);
149 static void clipboard_get_cb (GtkClipboard *clipboard,
150 GtkSelectionData *selection_data,
152 ClipboardData *data);
154 static void clipboard_clear_cb (GtkClipboard *clipboard,
155 ClipboardData *data);
157 static void receive_targets_cb (GtkClipboard *clipboard,
162 static void paste_xml_received_cb (GtkClipboard *clipboard,
163 GtkSelectionData *selection_data,
166 static void paste_text_received_cb (GtkClipboard *clipboard,
170 static void paste_image_received_cb(GtkClipboard *clipboard,
174 static void stack_clear (GQueue *stack);
175 static void stack_push_state (GQueue *stack,
177 static State *stack_pop_state (GQueue *stack);
179 static State *state_new (glLabel *this,
180 const gchar *description);
181 static void state_free (State *state);
182 static void state_restore (State *state,
186 /*****************************************************************************/
187 /* Boilerplate object stuff. */
188 /*****************************************************************************/
189 G_DEFINE_TYPE (glLabel, gl_label, G_TYPE_OBJECT);
193 gl_label_class_init (glLabelClass *class)
195 GObjectClass *object_class = G_OBJECT_CLASS (class);
197 gl_debug (DEBUG_LABEL, "START");
199 gl_label_parent_class = g_type_class_peek_parent (class);
201 object_class->finalize = gl_label_finalize;
203 signals[SELECTION_CHANGED] =
204 g_signal_new ("selection_changed",
205 G_OBJECT_CLASS_TYPE (object_class),
207 G_STRUCT_OFFSET (glLabelClass, selection_changed),
209 gl_marshal_VOID__VOID,
213 g_signal_new ("changed",
214 G_OBJECT_CLASS_TYPE (object_class),
216 G_STRUCT_OFFSET (glLabelClass, changed),
218 gl_marshal_VOID__VOID,
221 signals[NAME_CHANGED] =
222 g_signal_new ("name_changed",
223 G_OBJECT_CLASS_TYPE (object_class),
225 G_STRUCT_OFFSET (glLabelClass, name_changed),
227 gl_marshal_VOID__VOID,
230 signals[MODIFIED_CHANGED] =
231 g_signal_new ("modified_changed",
232 G_OBJECT_CLASS_TYPE (object_class),
234 G_STRUCT_OFFSET (glLabelClass, modified_changed),
236 gl_marshal_VOID__VOID,
239 signals[MERGE_CHANGED] =
240 g_signal_new ("merge_changed",
241 G_OBJECT_CLASS_TYPE (object_class),
243 G_STRUCT_OFFSET (glLabelClass, merge_changed),
245 gl_marshal_VOID__VOID,
248 signals[SIZE_CHANGED] =
249 g_signal_new ("size_changed",
250 G_OBJECT_CLASS_TYPE (object_class),
252 G_STRUCT_OFFSET (glLabelClass, size_changed),
254 gl_marshal_VOID__VOID,
258 gl_debug (DEBUG_LABEL, "END");
263 gl_label_init (glLabel *label)
265 gl_debug (DEBUG_LABEL, "START");
267 label->priv = g_new0 (glLabelPrivate, 1);
269 label->priv->template = NULL;
270 label->priv->rotate_flag = FALSE;
271 label->priv->object_list = NULL;
273 label->priv->filename = NULL;
274 label->priv->modified_flag = FALSE;
275 label->priv->compression = 9;
277 label->priv->merge = NULL;
278 label->priv->pixbuf_cache = gl_pixbuf_cache_new ();
279 label->priv->svg_cache = gl_svg_cache_new ();
281 label->priv->undo_stack = g_queue_new ();
282 label->priv->redo_stack = g_queue_new ();
285 * Defaults from preferences
287 label->priv->default_font_family = gl_prefs_model_get_default_font_family (gl_prefs);
288 label->priv->default_font_size = gl_prefs_model_get_default_font_size (gl_prefs);
289 label->priv->default_font_weight = gl_prefs_model_get_default_font_weight (gl_prefs);
290 label->priv->default_font_italic_flag = gl_prefs_model_get_default_font_italic_flag (gl_prefs);
291 label->priv->default_text_color = gl_prefs_model_get_default_text_color (gl_prefs);
292 label->priv->default_text_alignment = gl_prefs_model_get_default_text_alignment (gl_prefs);
293 label->priv->default_text_line_spacing = gl_prefs_model_get_default_text_line_spacing (gl_prefs);
294 label->priv->default_line_width = gl_prefs_model_get_default_line_width (gl_prefs);
295 label->priv->default_line_color = gl_prefs_model_get_default_line_color (gl_prefs);
296 label->priv->default_fill_color = gl_prefs_model_get_default_fill_color (gl_prefs);
298 gl_debug (DEBUG_LABEL, "END");
303 gl_label_finalize (GObject *object)
305 glLabel *label = GL_LABEL (object);
308 gl_debug (DEBUG_LABEL, "START");
310 g_return_if_fail (object && GL_IS_LABEL (object));
312 for (p = label->priv->object_list; p != NULL; p = p->next)
314 g_object_unref (G_OBJECT(p->data));
316 g_list_free (label->priv->object_list);
318 lgl_template_free (label->priv->template);
319 g_free (label->priv->filename);
320 if (label->priv->merge != NULL)
322 g_object_unref (G_OBJECT(label->priv->merge));
324 g_free (label->priv->default_font_family);
326 stack_clear (label->priv->undo_stack);
327 stack_clear (label->priv->redo_stack);
329 g_queue_free (label->priv->undo_stack);
330 g_queue_free (label->priv->redo_stack);
332 gl_pixbuf_cache_free (label->priv->pixbuf_cache);
333 gl_svg_cache_free (label->priv->svg_cache);
335 g_free (label->priv);
337 G_OBJECT_CLASS (gl_label_parent_class)->finalize (object);
339 gl_debug (DEBUG_LABEL, "END");
343 /*****************************************************************************/
345 /*****************************************************************************/
351 gl_debug (DEBUG_LABEL, "START");
353 label = g_object_new (gl_label_get_type(), NULL);
355 gl_debug (DEBUG_LABEL, "END");
357 return G_OBJECT (label);
361 /****************************************************************************/
363 /****************************************************************************/
365 gl_label_set_filename (glLabel *label,
366 const gchar *filename)
368 label->priv->filename = g_strdup (filename);
370 g_signal_emit (G_OBJECT(label), signals[NAME_CHANGED], 0);
374 /****************************************************************************/
375 /* return filename. */
376 /****************************************************************************/
378 gl_label_get_filename (glLabel *label)
380 gl_debug (DEBUG_LABEL, "");
382 return g_strdup ( label->priv->filename );
386 /****************************************************************************/
387 /* return short filename. */
388 /****************************************************************************/
390 gl_label_get_short_name (glLabel *label)
392 gl_debug (DEBUG_LABEL, "");
394 if ( label->priv->filename == NULL )
397 if ( label->priv->untitled_instance == 0 )
399 label->priv->untitled_instance = ++untitled;
402 return g_strdup_printf ( "%s %d", _("Untitled"),
403 label->priv->untitled_instance );
408 gchar *temp_name, *short_name;
410 temp_name = g_path_get_basename ( label->priv->filename );
411 short_name = gl_file_util_remove_extension (temp_name);
419 /****************************************************************************/
420 /* Is label untitled? */
421 /****************************************************************************/
423 gl_label_is_untitled (glLabel *label)
425 gl_debug (DEBUG_LABEL, "return %d",(label->priv->filename == NULL));
426 return (label->priv->filename == NULL);
430 /****************************************************************************/
431 /* Set compression level. */
432 /****************************************************************************/
434 gl_label_set_compression (glLabel *label,
437 gl_debug (DEBUG_LABEL, "set %d", compression);
439 /* Older versions of libxml2 always return a -1 for documents "read in," so
440 * default to 9. Also, default to 9 for anything else out of range. */
441 if ((compression < 0) || (compression >9))
446 gl_debug (DEBUG_LABEL, "actual set %d", compression);
447 label->priv->compression = compression;
451 /****************************************************************************/
452 /* Get compression level. */
453 /****************************************************************************/
455 gl_label_get_compression (glLabel *label)
457 gl_debug (DEBUG_LABEL, "return %d", label->priv->compression);
458 return label->priv->compression;
462 /****************************************************************************/
463 /* Set modified flag. */
464 /****************************************************************************/
466 gl_label_set_modified (glLabel *label)
469 if ( !label->priv->modified_flag )
472 label->priv->modified_flag = TRUE;
474 g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
480 /****************************************************************************/
481 /* Clear modified flag. */
482 /****************************************************************************/
484 gl_label_clear_modified (glLabel *label)
487 if ( label->priv->modified_flag )
490 g_get_current_time (&label->priv->time_stamp);
491 label->priv->modified_flag = FALSE;
493 g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
499 /****************************************************************************/
500 /* Is label modified? */
501 /****************************************************************************/
503 gl_label_is_modified (glLabel *label)
505 gl_debug (DEBUG_LABEL, "return %d", label->priv->modified_flag);
506 return label->priv->modified_flag;
510 /****************************************************************************/
511 /* Object "changed" callback. */
512 /****************************************************************************/
514 object_changed_cb (glLabelObject *object,
521 /****************************************************************************/
523 /****************************************************************************/
525 do_modify (glLabel *label)
527 if ( label->priv->selection_op_flag )
529 label->priv->delayed_change_flag = TRUE;
533 label->priv->modified_flag = TRUE;
535 g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
536 g_signal_emit (G_OBJECT(label), signals[CHANGED], 0);
541 /****************************************************************************/
542 /* Begin selection operation. */
543 /****************************************************************************/
545 begin_selection_op (glLabel *label)
547 label->priv->selection_op_flag = TRUE;
551 /****************************************************************************/
552 /* End selection operation. */
553 /****************************************************************************/
555 end_selection_op (glLabel *label)
557 label->priv->selection_op_flag = FALSE;
558 if ( label->priv->delayed_change_flag )
560 label->priv->delayed_change_flag = FALSE;
566 /****************************************************************************/
568 /****************************************************************************/
570 gl_label_set_template (glLabel *label,
571 const lglTemplate *template,
576 gl_debug (DEBUG_LABEL, "START");
578 g_return_if_fail (label && GL_IS_LABEL (label));
579 g_return_if_fail (template);
581 if ((label->priv->template == NULL) ||
582 !lgl_template_do_templates_match (template, label->priv->template))
587 gl_label_checkpoint (label, _("Label properties"));
590 lgl_template_free (label->priv->template);
591 label->priv->template = lgl_template_dup (template);
594 g_signal_emit (G_OBJECT(label), signals[SIZE_CHANGED], 0);
596 name = lgl_template_get_name (template);
597 gl_template_history_model_add_name (gl_template_history, name);
601 gl_debug (DEBUG_LABEL, "END");
605 /****************************************************************************/
607 /****************************************************************************/
609 gl_label_get_template (glLabel *label)
611 return label->priv->template;
615 /****************************************************************************/
616 /* set rotate flag. */
617 /****************************************************************************/
619 gl_label_set_rotate_flag (glLabel *label,
620 gboolean rotate_flag,
623 gl_debug (DEBUG_LABEL, "START");
625 g_return_if_fail (label && GL_IS_LABEL (label));
627 if (rotate_flag != label->priv->rotate_flag)
631 gl_label_checkpoint (label, _("Label properties"));
634 label->priv->rotate_flag = rotate_flag;
637 g_signal_emit (G_OBJECT(label), signals[SIZE_CHANGED], 0);
640 gl_debug (DEBUG_LABEL, "END");
644 /****************************************************************************/
645 /* Get rotate flag. */
646 /****************************************************************************/
648 gl_label_get_rotate_flag (glLabel *label)
650 return label->priv->rotate_flag;
654 /****************************************************************************/
655 /* Get label size. */
656 /****************************************************************************/
658 gl_label_get_size (glLabel *label,
662 lglTemplate *template;
663 const lglTemplateFrame *frame;
665 gl_debug (DEBUG_LABEL, "START");
667 g_return_if_fail (label && GL_IS_LABEL (label));
669 template = label->priv->template;
672 gl_debug (DEBUG_LABEL, "END -- template NULL");
676 frame = (lglTemplateFrame *)template->frames->data;
678 if (!label->priv->rotate_flag)
680 lgl_template_frame_get_size (frame, w, h);
684 lgl_template_frame_get_size (frame, h, w);
687 gl_debug (DEBUG_LABEL, "END");
691 /****************************************************************************/
692 /* set merge information structure. */
693 /****************************************************************************/
695 gl_label_set_merge (glLabel *label,
699 gl_debug (DEBUG_LABEL, "START");
701 g_return_if_fail (label && GL_IS_LABEL (label));
705 gl_label_checkpoint (label, _("Merge properties"));
708 if ( label->priv->merge != NULL )
710 g_object_unref (G_OBJECT(label->priv->merge));
712 label->priv->merge = gl_merge_dup (merge);
715 g_signal_emit (G_OBJECT(label), signals[MERGE_CHANGED], 0);
717 gl_debug (DEBUG_LABEL, "END");
721 /****************************************************************************/
722 /* Get merge information structure. */
723 /****************************************************************************/
725 gl_label_get_merge (glLabel *label)
727 gl_debug (DEBUG_LABEL, "START");
729 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
731 gl_debug (DEBUG_LABEL, "END");
733 return gl_merge_dup (label->priv->merge);
737 /****************************************************************************/
738 /* Get pixbuf cache. */
739 /****************************************************************************/
741 gl_label_get_pixbuf_cache (glLabel *label)
743 return label->priv->pixbuf_cache;
747 /****************************************************************************/
749 /****************************************************************************/
751 gl_label_get_svg_cache (glLabel *label)
753 return label->priv->svg_cache;
757 /*****************************************************************************/
758 /* Add object to label. */
759 /*****************************************************************************/
761 gl_label_add_object (glLabel *label,
762 glLabelObject *object)
764 gl_debug (DEBUG_LABEL, "START");
766 g_return_if_fail (label && GL_IS_LABEL (label));
767 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
769 gl_label_object_set_parent (object, label);
770 label->priv->object_list = g_list_append (label->priv->object_list, object);
772 g_signal_connect (G_OBJECT (object), "changed",
773 G_CALLBACK (object_changed_cb), label);
777 gl_debug (DEBUG_LABEL, "END");
781 /*****************************************************************************/
782 /* Delete object from label. */
783 /*****************************************************************************/
785 gl_label_delete_object (glLabel *label,
786 glLabelObject *object)
788 gl_debug (DEBUG_LABEL, "START");
790 g_return_if_fail (label && GL_IS_LABEL (label));
791 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
793 label->priv->object_list = g_list_remove (label->priv->object_list, object);
795 g_signal_handlers_disconnect_by_func (G_OBJECT (object),
796 G_CALLBACK (object_changed_cb), label);
797 g_object_unref (object);
801 gl_debug (DEBUG_LABEL, "END");
805 /*****************************************************************************/
806 /* Get object list. */
807 /*****************************************************************************/
809 gl_label_get_object_list (glLabel *label)
811 return label->priv->object_list;
815 /*****************************************************************************/
817 /*****************************************************************************/
819 gl_label_select_object (glLabel *label,
820 glLabelObject *object)
822 gl_debug (DEBUG_LABEL, "START");
824 g_return_if_fail (label && GL_IS_LABEL (label));
825 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
827 gl_label_object_select (object);
829 label->priv->cp_cleared_flag = TRUE;
830 g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
832 gl_debug (DEBUG_LABEL, "END");
836 /*****************************************************************************/
837 /* Unselect object. */
838 /*****************************************************************************/
840 gl_label_unselect_object (glLabel *label,
841 glLabelObject *object)
843 gl_debug (DEBUG_LABEL, "START");
845 g_return_if_fail (label && GL_IS_LABEL (label));
846 g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
848 gl_label_object_unselect (object);
850 label->priv->cp_cleared_flag = TRUE;
851 g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
853 gl_debug (DEBUG_LABEL, "END");
857 /*****************************************************************************/
858 /* Select all objects. */
859 /*****************************************************************************/
861 gl_label_select_all (glLabel *label)
864 glLabelObject *object;
866 gl_debug (DEBUG_LABEL, "START");
868 g_return_if_fail (label && GL_IS_LABEL (label));
870 for ( p = label->priv->object_list; p != NULL; p = p->next )
872 object = GL_LABEL_OBJECT (p->data);
874 gl_label_object_select (object);
877 label->priv->cp_cleared_flag = TRUE;
878 g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
880 gl_debug (DEBUG_LABEL, "END");
884 /*****************************************************************************/
885 /* Unselect all objects. */
886 /*****************************************************************************/
888 gl_label_unselect_all (glLabel *label)
891 glLabelObject *object;
893 gl_debug (DEBUG_LABEL, "START");
895 g_return_if_fail (label && GL_IS_LABEL (label));
897 for ( p = label->priv->object_list; p != NULL; p = p->next )
899 object = GL_LABEL_OBJECT (p->data);
901 gl_label_object_unselect (object);
904 label->priv->cp_cleared_flag = TRUE;
905 g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
907 gl_debug (DEBUG_LABEL, "END");
911 /*****************************************************************************/
912 /* Select all objects contained in region. */
913 /*****************************************************************************/
915 gl_label_select_region (glLabel *label,
916 glLabelRegion *region)
919 glLabelObject *object;
922 glLabelRegion obj_extent;
924 gl_debug (DEBUG_LABEL, "START");
926 g_return_if_fail (label && GL_IS_LABEL (label));
928 r_x1 = MIN (region->x1, region->x2);
929 r_y1 = MIN (region->y1, region->y2);
930 r_x2 = MAX (region->x1, region->x2);
931 r_y2 = MAX (region->y1, region->y2);
933 for (p = label->priv->object_list; p != NULL; p = p->next)
935 object = GL_LABEL_OBJECT(p->data);
937 gl_label_object_get_extent (object, &obj_extent);
938 if ((obj_extent.x1 >= r_x1) &&
939 (obj_extent.x2 <= r_x2) &&
940 (obj_extent.y1 >= r_y1) &&
941 (obj_extent.y2 <= r_y2))
943 gl_label_object_select (object);
947 label->priv->cp_cleared_flag = TRUE;
948 g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
950 gl_debug (DEBUG_LABEL, "END");
954 /*****************************************************************************/
955 /* Is selection empty? */
956 /*****************************************************************************/
958 gl_label_is_selection_empty (glLabel *label)
961 glLabelObject *object;
963 for ( p = label->priv->object_list; p != NULL; p = p->next )
965 object = GL_LABEL_OBJECT (p->data);
967 if ( gl_label_object_is_selected (object) )
977 /*****************************************************************************/
978 /* Is selection atomic? */
979 /*****************************************************************************/
981 gl_label_is_selection_atomic (glLabel *label)
984 glLabelObject *object;
987 for ( p = label->priv->object_list; p != NULL; p = p->next )
989 object = GL_LABEL_OBJECT (p->data);
991 if ( gl_label_object_is_selected (object) )
1002 return (n_selected == 1);
1006 /*****************************************************************************/
1007 /* Get first selected object. */
1008 /*****************************************************************************/
1010 gl_label_get_1st_selected_object (glLabel *label)
1013 glLabelObject *object;
1015 for ( p = label->priv->object_list; p != NULL; p = p->next )
1017 object = GL_LABEL_OBJECT (p->data);
1019 if ( gl_label_object_is_selected (object) )
1029 /*****************************************************************************/
1030 /* Get list of selected objects. */
1031 /*****************************************************************************/
1033 gl_label_get_selection_list (glLabel *label)
1035 GList *selection_list = NULL;
1037 glLabelObject *object;
1039 for ( p = label->priv->object_list; p != NULL; p = p->next )
1041 object = GL_LABEL_OBJECT (p->data);
1043 if ( gl_label_object_is_selected (object) )
1045 selection_list = g_list_append (selection_list, object);
1049 return (selection_list);
1053 /*****************************************************************************/
1054 /* Can text properties be set for selection? */
1055 /*****************************************************************************/
1057 gl_label_can_selection_text (glLabel *label)
1059 GList *selection_list;
1061 glLabelObject *object;
1063 gl_debug (DEBUG_LABEL, "");
1065 g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
1067 selection_list = gl_label_get_selection_list (label);
1069 for (p = selection_list; p != NULL; p = p->next)
1071 object = GL_LABEL_OBJECT (p->data);
1073 if (gl_label_object_can_text (object))
1075 g_list_free (selection_list);
1080 g_list_free (selection_list);
1085 /*****************************************************************************/
1086 /* Can fill properties be set for selection? */
1087 /*****************************************************************************/
1089 gl_label_can_selection_fill (glLabel *label)
1091 GList *selection_list;
1093 glLabelObject *object;
1095 gl_debug (DEBUG_LABEL, "");
1097 g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
1099 selection_list = gl_label_get_selection_list (label);
1101 for (p = selection_list; p != NULL; p = p->next)
1103 object = GL_LABEL_OBJECT (p->data);
1105 if (gl_label_object_can_fill (object))
1107 g_list_free (selection_list);
1113 g_list_free (selection_list);
1118 /*****************************************************************************/
1119 /* Can line color properties be set for selection? */
1120 /*****************************************************************************/
1122 gl_label_can_selection_line_color (glLabel *label)
1124 GList *selection_list;
1126 glLabelObject *object;
1128 gl_debug (DEBUG_LABEL, "");
1130 g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
1132 selection_list = gl_label_get_selection_list (label);
1134 for (p = selection_list; p != NULL; p = p->next)
1136 object = GL_LABEL_OBJECT (p->data);
1138 if (gl_label_object_can_line_color (object))
1140 g_list_free (selection_list);
1145 g_list_free (selection_list);
1150 /*****************************************************************************/
1151 /* Can line width properties be set for selection? */
1152 /*****************************************************************************/
1154 gl_label_can_selection_line_width (glLabel *label)
1156 GList *selection_list;
1158 glLabelObject *object;
1160 gl_debug (DEBUG_LABEL, "");
1162 g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
1164 selection_list = gl_label_get_selection_list (label);
1166 for (p = selection_list; p != NULL; p = p->next)
1168 object = GL_LABEL_OBJECT (p->data);
1170 if (gl_label_object_can_line_width (object))
1172 g_list_free (selection_list);
1178 g_list_free (selection_list);
1183 /*****************************************************************************/
1184 /* Delete selection from label. */
1185 /*****************************************************************************/
1187 gl_label_delete_selection (glLabel *label)
1189 GList *selection_list;
1191 glLabelObject *object;
1193 gl_debug (DEBUG_LABEL, "START");
1195 g_return_if_fail (label && GL_IS_LABEL (label));
1197 gl_label_checkpoint (label, _("Delete"));
1199 begin_selection_op (label);
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 gl_label_delete_object (label, object);
1210 g_list_free (selection_list);
1212 end_selection_op (label);
1214 gl_debug (DEBUG_LABEL, "END");
1218 /****************************************************************************/
1219 /* Bring selection object to front/top. */
1220 /****************************************************************************/
1222 gl_label_raise_selection_to_top (glLabel *label)
1224 GList *selection_list;
1226 glLabelObject *object;
1228 gl_debug (DEBUG_LABEL, "START");
1230 gl_label_checkpoint (label, _("Bring to front"));
1232 begin_selection_op (label);
1234 selection_list = gl_label_get_selection_list (label);
1236 for ( p = selection_list; p != NULL; p = p->next )
1238 object = GL_LABEL_OBJECT (p->data);
1240 label->priv->object_list = g_list_remove (label->priv->object_list, object);
1243 /* Move to end of list, representing front most object */
1244 label->priv->object_list = g_list_concat (label->priv->object_list, selection_list);
1248 end_selection_op (label);
1250 gl_debug (DEBUG_LABEL, "END");
1254 /****************************************************************************/
1255 /* Send selection to rear/bottom. */
1256 /****************************************************************************/
1258 gl_label_lower_selection_to_bottom (glLabel *label)
1260 GList *selection_list;
1262 glLabelObject *object;
1264 gl_debug (DEBUG_LABEL, "START");
1266 gl_label_checkpoint (label, _("Send to back"));
1268 begin_selection_op (label);
1270 selection_list = gl_label_get_selection_list (label);
1272 for ( p = selection_list; p != NULL; p = p->next )
1274 object = GL_LABEL_OBJECT (p->data);
1276 label->priv->object_list = g_list_remove (label->priv->object_list, object);
1279 /* Move to front of list, representing rear most object */
1280 label->priv->object_list = g_list_concat (selection_list, label->priv->object_list);
1284 end_selection_op (label);
1286 gl_debug (DEBUG_LABEL, "END");
1290 /*****************************************************************************/
1291 /* Rotate selected objects by given angle. */
1292 /*****************************************************************************/
1294 gl_label_rotate_selection (glLabel *label,
1297 GList *selection_list;
1299 glLabelObject *object;
1301 gl_debug (DEBUG_LABEL, "START");
1303 g_return_if_fail (label && GL_IS_LABEL (label));
1305 begin_selection_op (label);
1307 gl_label_checkpoint (label, _("Rotate"));
1309 selection_list = gl_label_get_selection_list (label);
1311 for ( p = selection_list; p != NULL; p = p->next )
1313 object = GL_LABEL_OBJECT (p->data);
1315 gl_label_object_rotate (object, theta_degs);
1318 g_list_free (selection_list);
1320 end_selection_op (label);
1322 gl_debug (DEBUG_LABEL, "END");
1326 /*****************************************************************************/
1327 /* Rotate selected objects 90 degrees left. */
1328 /*****************************************************************************/
1330 gl_label_rotate_selection_left (glLabel *label)
1332 GList *selection_list;
1334 glLabelObject *object;
1336 gl_debug (DEBUG_LABEL, "START");
1338 g_return_if_fail (label && GL_IS_LABEL (label));
1340 begin_selection_op (label);
1342 gl_label_checkpoint (label, _("Rotate left"));
1344 selection_list = gl_label_get_selection_list (label);
1346 for ( p = selection_list; p != NULL; p = p->next )
1348 object = GL_LABEL_OBJECT (p->data);
1350 gl_label_object_rotate (object, -90.0);
1353 g_list_free (selection_list);
1355 end_selection_op (label);
1357 gl_debug (DEBUG_LABEL, "END");
1361 /*****************************************************************************/
1362 /* Rotate selected objects 90 degrees right. */
1363 /*****************************************************************************/
1365 gl_label_rotate_selection_right (glLabel *label)
1367 GList *selection_list;
1369 glLabelObject *object;
1371 gl_debug (DEBUG_LABEL, "START");
1373 g_return_if_fail (label && GL_IS_LABEL (label));
1375 gl_label_checkpoint (label, _("Rotate right"));
1377 begin_selection_op (label);
1379 selection_list = gl_label_get_selection_list (label);
1381 for ( p = selection_list; p != NULL; p = p->next )
1383 object = GL_LABEL_OBJECT (p->data);
1385 gl_label_object_rotate (object, 90.0);
1388 g_list_free (selection_list);
1390 end_selection_op (label);
1392 gl_debug (DEBUG_LABEL, "END");
1396 /*****************************************************************************/
1397 /* Flip selected objects horizontally. */
1398 /*****************************************************************************/
1400 gl_label_flip_selection_horiz (glLabel *label)
1402 GList *selection_list;
1404 glLabelObject *object;
1406 gl_debug (DEBUG_LABEL, "START");
1408 g_return_if_fail (label && GL_IS_LABEL (label));
1410 gl_label_checkpoint (label, _("Flip horizontally"));
1412 begin_selection_op (label);
1414 selection_list = gl_label_get_selection_list (label);
1416 for ( p = selection_list; p != NULL; p = p->next )
1418 object = GL_LABEL_OBJECT (p->data);
1420 gl_label_object_flip_horiz (object);
1423 g_list_free (selection_list);
1425 end_selection_op (label);
1427 gl_debug (DEBUG_LABEL, "END");
1431 /*****************************************************************************/
1432 /* Flip selected objects vertically. */
1433 /*****************************************************************************/
1435 gl_label_flip_selection_vert (glLabel *label)
1437 GList *selection_list;
1439 glLabelObject *object;
1441 gl_debug (DEBUG_LABEL, "START");
1443 g_return_if_fail (label && GL_IS_LABEL (label));
1445 gl_label_checkpoint (label, _("Flip vertically"));
1447 begin_selection_op (label);
1449 selection_list = gl_label_get_selection_list (label);
1451 for ( p = selection_list; p != NULL; p = p->next )
1453 object = GL_LABEL_OBJECT (p->data);
1455 gl_label_object_flip_vert (object);
1458 g_list_free (selection_list);
1460 end_selection_op (label);
1462 gl_debug (DEBUG_LABEL, "END");
1466 /*****************************************************************************/
1467 /* Align selected objects to left most edge. */
1468 /*****************************************************************************/
1470 gl_label_align_selection_left (glLabel *label)
1472 GList *selection_list;
1474 glLabelObject *object;
1476 glLabelRegion obj_extent;
1478 gl_debug (DEBUG_LABEL, "START");
1480 g_return_if_fail (label && GL_IS_LABEL (label));
1482 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1483 !gl_label_is_selection_atomic (label));
1485 gl_label_checkpoint (label, _("Align left"));
1487 begin_selection_op (label);
1489 selection_list = gl_label_get_selection_list (label);
1491 /* find left most edge */
1493 object = GL_LABEL_OBJECT (p->data);
1495 gl_label_object_get_extent (object, &obj_extent);
1496 x1_min = obj_extent.x1;
1497 for (p = p->next; p != NULL; p = p->next)
1499 object = GL_LABEL_OBJECT (p->data);
1501 gl_label_object_get_extent (object, &obj_extent);
1502 if ( obj_extent.x1 < x1_min ) x1_min = obj_extent.x1;
1505 /* now adjust the object positions to line up the left edges */
1506 for (p = selection_list; p != NULL; p = p->next)
1508 object = GL_LABEL_OBJECT (p->data);
1510 gl_label_object_get_extent (object, &obj_extent);
1511 dx = x1_min - obj_extent.x1;
1512 gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1515 g_list_free (selection_list);
1517 end_selection_op (label);
1519 gl_debug (DEBUG_LABEL, "END");
1523 /*****************************************************************************/
1524 /* Align selected objects to right most edge. */
1525 /*****************************************************************************/
1527 gl_label_align_selection_right (glLabel *label)
1529 GList *selection_list;
1531 glLabelObject *object;
1533 glLabelRegion obj_extent;
1535 gl_debug (DEBUG_LABEL, "START");
1537 g_return_if_fail (label && GL_IS_LABEL (label));
1539 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1540 !gl_label_is_selection_atomic (label));
1542 gl_label_checkpoint (label, _("Align right"));
1544 begin_selection_op (label);
1546 selection_list = gl_label_get_selection_list (label);
1548 /* find left most edge */
1550 object = GL_LABEL_OBJECT (p->data);
1552 gl_label_object_get_extent (object, &obj_extent);
1553 x2_max = obj_extent.x2;
1554 for (p = p->next; p != NULL; p = p->next)
1556 object = GL_LABEL_OBJECT (p->data);
1558 gl_label_object_get_extent (object, &obj_extent);
1559 if ( obj_extent.x2 > x2_max ) x2_max = obj_extent.x2;
1562 /* now adjust the object positions to line up the left edges */
1563 for (p = selection_list; p != NULL; p = p->next)
1565 object = GL_LABEL_OBJECT (p->data);
1567 gl_label_object_get_extent (object, &obj_extent);
1568 dx = x2_max - obj_extent.x2;
1569 gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1572 g_list_free (selection_list);
1574 end_selection_op (label);
1576 gl_debug (DEBUG_LABEL, "END");
1580 /*****************************************************************************/
1581 /* Align selected objects to horizontal center of objects. */
1582 /*****************************************************************************/
1584 gl_label_align_selection_hcenter (glLabel *label)
1586 GList *selection_list;
1588 glLabelObject *object;
1592 glLabelRegion obj_extent;
1596 gl_debug (DEBUG_LABEL, "START");
1598 g_return_if_fail (label && GL_IS_LABEL (label));
1600 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1601 !gl_label_is_selection_atomic (label));
1603 gl_label_checkpoint (label, _("Align horizontal center"));
1605 begin_selection_op (label);
1607 selection_list = gl_label_get_selection_list (label);
1609 /* find average center of objects */
1612 for (p = selection_list; p != NULL; p = p->next)
1614 object = GL_LABEL_OBJECT (p->data);
1616 gl_label_object_get_extent (object, &obj_extent);
1617 xsum += (obj_extent.x1 + obj_extent.x2) / 2.0;
1622 /* find center of object closest to average center */
1624 object = GL_LABEL_OBJECT (p->data);
1626 gl_label_object_get_extent (object, &obj_extent);
1627 dxmin = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
1628 xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
1629 for (p = p->next; p != NULL; p = p->next)
1631 object = GL_LABEL_OBJECT (p->data);
1633 gl_label_object_get_extent (object, &obj_extent);
1634 dx = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
1638 xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
1642 /* now adjust the object positions to line up this center */
1643 for (p = selection_list; p != NULL; p = p->next)
1645 object = GL_LABEL_OBJECT (p->data);
1647 gl_label_object_get_extent (object, &obj_extent);
1648 dx = xcenter - (obj_extent.x1 + obj_extent.x2)/2.0;
1649 gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1652 g_list_free (selection_list);
1654 end_selection_op (label);
1656 gl_debug (DEBUG_LABEL, "END");
1660 /*****************************************************************************/
1661 /* Align selected objects to top most edge. */
1662 /*****************************************************************************/
1664 gl_label_align_selection_top (glLabel *label)
1666 GList *selection_list;
1668 glLabelObject *object;
1670 glLabelRegion obj_extent;
1672 gl_debug (DEBUG_LABEL, "START");
1674 g_return_if_fail (label && GL_IS_LABEL (label));
1676 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1677 !gl_label_is_selection_atomic (label));
1679 gl_label_checkpoint (label, _("Align tops"));
1681 begin_selection_op (label);
1683 selection_list = gl_label_get_selection_list (label);
1685 /* find top most edge */
1687 object = GL_LABEL_OBJECT (p->data);
1689 gl_label_object_get_extent (object, &obj_extent);
1690 y1_min = obj_extent.y1;
1691 for (p = p->next; p != NULL; p = p->next)
1693 object = GL_LABEL_OBJECT (p->data);
1695 gl_label_object_get_extent (object, &obj_extent);
1696 if ( obj_extent.y1 < y1_min ) y1_min = obj_extent.y1;
1699 /* now adjust the object positions to line up the top edges */
1700 for (p = selection_list; p != NULL; p = p->next)
1702 object = GL_LABEL_OBJECT (p->data);
1704 gl_label_object_get_extent (object, &obj_extent);
1705 dy = y1_min - obj_extent.y1;
1706 gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1709 g_list_free (selection_list);
1711 end_selection_op (label);
1713 gl_debug (DEBUG_LABEL, "END");
1717 /*****************************************************************************/
1718 /* Align selected objects to bottom most edge. */
1719 /*****************************************************************************/
1721 gl_label_align_selection_bottom (glLabel *label)
1723 GList *selection_list;
1725 glLabelObject *object;
1727 glLabelRegion obj_extent;
1729 gl_debug (DEBUG_LABEL, "START");
1731 g_return_if_fail (label && GL_IS_LABEL (label));
1733 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1734 !gl_label_is_selection_atomic (label));
1736 gl_label_checkpoint (label, _("Align bottoms"));
1738 begin_selection_op (label);
1740 selection_list = gl_label_get_selection_list (label);
1742 /* find bottom most edge */
1744 object = GL_LABEL_OBJECT (p->data);
1746 gl_label_object_get_extent (object, &obj_extent);
1747 y2_max = obj_extent.y2;
1748 for (p = p->next; p != NULL; p = p->next)
1750 object = GL_LABEL_OBJECT (p->data);
1752 gl_label_object_get_extent (object, &obj_extent);
1753 if ( obj_extent.y2 > y2_max ) y2_max = obj_extent.y2;
1756 /* now adjust the object positions to line up the bottom edges */
1757 for (p = selection_list; p != NULL; p = p->next)
1759 object = GL_LABEL_OBJECT (p->data);
1761 gl_label_object_get_extent (object, &obj_extent);
1762 dy = y2_max - obj_extent.y2;
1763 gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1766 g_list_free (selection_list);
1768 end_selection_op (label);
1770 gl_debug (DEBUG_LABEL, "END");
1774 /*****************************************************************************/
1775 /* Align selected objects to viertical center of objects. */
1776 /*****************************************************************************/
1778 gl_label_align_selection_vcenter (glLabel *label)
1780 GList *selection_list;
1782 glLabelObject *object;
1786 glLabelRegion obj_extent;
1790 gl_debug (DEBUG_LABEL, "START");
1792 g_return_if_fail (label && GL_IS_LABEL (label));
1794 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1795 !gl_label_is_selection_atomic (label));
1797 gl_label_checkpoint (label, _("Align vertical center"));
1799 begin_selection_op (label);
1801 selection_list = gl_label_get_selection_list (label);
1803 /* find average center of objects */
1806 for (p = selection_list; p != NULL; p = p->next)
1808 object = GL_LABEL_OBJECT (p->data);
1810 gl_label_object_get_extent (object, &obj_extent);
1811 ysum += (obj_extent.y1 + obj_extent.y2) / 2.0;
1816 /* find center of object closest to average center */
1818 object = GL_LABEL_OBJECT (p->data);
1820 gl_label_object_get_extent (object, &obj_extent);
1821 dymin = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
1822 ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
1823 for (p = p->next; p != NULL; p = p->next)
1825 object = GL_LABEL_OBJECT (p->data);
1827 gl_label_object_get_extent (object, &obj_extent);
1828 dy = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
1832 ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
1836 /* now adjust the object positions to line up this center */
1837 for (p = selection_list; p != NULL; p = p->next)
1839 object = GL_LABEL_OBJECT (p->data);
1841 gl_label_object_get_extent (object, &obj_extent);
1842 dy = ycenter - (obj_extent.y1 + obj_extent.y2)/2.0;
1843 gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1846 g_list_free (selection_list);
1848 end_selection_op (label);
1850 gl_debug (DEBUG_LABEL, "END");
1854 /*****************************************************************************/
1855 /* Center selected objects to in center of label. */
1856 /*****************************************************************************/
1858 gl_label_center_selection_horiz (glLabel *label)
1860 GList *selection_list;
1862 glLabelObject *object;
1864 gdouble x_label_center;
1865 gdouble x_obj_center;
1866 glLabelRegion obj_extent;
1869 gl_debug (DEBUG_LABEL, "START");
1871 g_return_if_fail (label && GL_IS_LABEL (label));
1873 g_return_if_fail (!gl_label_is_selection_empty (label));
1875 gl_label_checkpoint (label, _("Center horizontally"));
1877 begin_selection_op (label);
1879 gl_label_get_size (label, &w, &h);
1880 x_label_center = w / 2.0;
1882 /* adjust the object positions */
1883 selection_list = gl_label_get_selection_list (label);
1884 for (p = selection_list; p != NULL; p = p->next)
1886 object = GL_LABEL_OBJECT (p->data);
1888 gl_label_object_get_extent (object, &obj_extent);
1889 x_obj_center = (obj_extent.x1 + obj_extent.x2) / 2.0;
1890 dx = x_label_center - x_obj_center;
1891 gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1893 g_list_free (selection_list);
1895 end_selection_op (label);
1897 gl_debug (DEBUG_LABEL, "END");
1901 /*****************************************************************************/
1902 /* Center selected objects to in center of label. */
1903 /*****************************************************************************/
1905 gl_label_center_selection_vert (glLabel *label)
1907 GList *selection_list;
1909 glLabelObject *object;
1911 gdouble y_label_center;
1912 gdouble y_obj_center;
1913 glLabelRegion obj_extent;
1916 gl_debug (DEBUG_LABEL, "START");
1918 g_return_if_fail (label && GL_IS_LABEL (label));
1920 g_return_if_fail (!gl_label_is_selection_empty (label));
1922 gl_label_checkpoint (label, _("Center vertically"));
1924 begin_selection_op (label);
1926 gl_label_get_size (label, &w, &h);
1927 y_label_center = h / 2.0;
1929 /* adjust the object positions */
1930 selection_list = gl_label_get_selection_list (label);
1931 for (p = selection_list; p != NULL; p = p->next)
1933 object = GL_LABEL_OBJECT (p->data);
1935 gl_label_object_get_extent (object, &obj_extent);
1936 y_obj_center = (obj_extent.y1 + obj_extent.y2) / 2.0;
1937 dy = y_label_center - y_obj_center;
1938 gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1940 g_list_free (selection_list);
1942 end_selection_op (label);
1944 gl_debug (DEBUG_LABEL, "END");
1948 /*****************************************************************************/
1949 /* Move selected objects */
1950 /*****************************************************************************/
1952 gl_label_move_selection (glLabel *label,
1956 GList *selection_list;
1958 glLabelObject *object;
1960 gl_debug (DEBUG_LABEL, "START");
1962 g_return_if_fail (label && GL_IS_LABEL (label));
1964 begin_selection_op (label);
1966 selection_list = gl_label_get_selection_list (label);
1968 for (p = selection_list; p != NULL; p = p->next)
1970 object = GL_LABEL_OBJECT (p->data);
1972 gl_label_object_set_position_relative (object, dx, dy, TRUE);
1975 g_list_free (selection_list);
1977 end_selection_op (label);
1979 gl_debug (DEBUG_LABEL, "END");
1983 /*****************************************************************************/
1984 /* Set font family for all text contained in selected objects. */
1985 /*****************************************************************************/
1987 gl_label_set_selection_font_family (glLabel *label,
1988 const gchar *font_family)
1990 GList *selection_list;
1992 glLabelObject *object;
1994 gl_debug (DEBUG_LABEL, "START");
1996 g_return_if_fail (label && GL_IS_LABEL (label));
1998 begin_selection_op (label);
2000 selection_list = gl_label_get_selection_list (label);
2002 for (p = selection_list; p != NULL; p = p->next)
2004 object = GL_LABEL_OBJECT (p->data);
2005 gl_label_object_set_font_family (object, font_family, TRUE);
2008 g_list_free (selection_list);
2010 end_selection_op (label);
2012 gl_debug (DEBUG_LABEL, "END");
2016 /*****************************************************************************/
2017 /* Set font size for all text contained in selected objects. */
2018 /*****************************************************************************/
2020 gl_label_set_selection_font_size (glLabel *label,
2023 GList *selection_list;
2025 glLabelObject *object;
2027 gl_debug (DEBUG_LABEL, "START");
2029 g_return_if_fail (label && GL_IS_LABEL (label));
2031 begin_selection_op (label);
2033 selection_list = gl_label_get_selection_list (label);
2035 for (p = selection_list; p != NULL; p = p->next)
2037 object = GL_LABEL_OBJECT (p->data);
2038 gl_label_object_set_font_size (object, font_size, TRUE);
2041 g_list_free (selection_list);
2043 end_selection_op (label);
2045 gl_debug (DEBUG_LABEL, "END");
2049 /*****************************************************************************/
2050 /* Set font weight for all text contained in selected objects. */
2051 /*****************************************************************************/
2053 gl_label_set_selection_font_weight (glLabel *label,
2054 PangoWeight font_weight)
2056 GList *selection_list;
2058 glLabelObject *object;
2060 gl_debug (DEBUG_LABEL, "START");
2062 g_return_if_fail (label && GL_IS_LABEL (label));
2064 begin_selection_op (label);
2066 selection_list = gl_label_get_selection_list (label);
2068 for (p = selection_list; p != NULL; p = p->next)
2070 object = GL_LABEL_OBJECT (p->data);
2071 gl_label_object_set_font_weight (object, font_weight, TRUE);
2074 g_list_free (selection_list);
2076 end_selection_op (label);
2078 gl_debug (DEBUG_LABEL, "END");
2082 /*****************************************************************************/
2083 /* Set font italic flag for all text contained in selected objects. */
2084 /*****************************************************************************/
2086 gl_label_set_selection_font_italic_flag (glLabel *label,
2087 gboolean font_italic_flag)
2089 GList *selection_list;
2091 glLabelObject *object;
2093 gl_debug (DEBUG_LABEL, "START");
2095 g_return_if_fail (label && GL_IS_LABEL (label));
2097 begin_selection_op (label);
2099 selection_list = gl_label_get_selection_list (label);
2101 for (p = selection_list; p != NULL; p = p->next)
2103 object = GL_LABEL_OBJECT (p->data);
2104 gl_label_object_set_font_italic_flag (object, font_italic_flag, TRUE);
2107 g_list_free (selection_list);
2109 end_selection_op (label);
2111 gl_debug (DEBUG_LABEL, "END");
2115 /*****************************************************************************/
2116 /* Set text alignment for all text contained in selected objects. */
2117 /*****************************************************************************/
2119 gl_label_set_selection_text_alignment (glLabel *label,
2120 PangoAlignment text_alignment)
2122 GList *selection_list;
2124 glLabelObject *object;
2126 gl_debug (DEBUG_LABEL, "START");
2128 g_return_if_fail (label && GL_IS_LABEL (label));
2130 begin_selection_op (label);
2132 selection_list = gl_label_get_selection_list (label);
2134 for (p = selection_list; p != NULL; p = p->next)
2136 object = GL_LABEL_OBJECT (p->data);
2137 gl_label_object_set_text_alignment (object, text_alignment, TRUE);
2140 g_list_free (selection_list);
2142 end_selection_op (label);
2144 gl_debug (DEBUG_LABEL, "END");
2148 /*****************************************************************************/
2149 /* Set text line spacing for all text contained in selected objects. */
2150 /*****************************************************************************/
2152 gl_label_set_selection_text_line_spacing (glLabel *label,
2153 gdouble text_line_spacing)
2155 GList *selection_list;
2157 glLabelObject *object;
2159 gl_debug (DEBUG_LABEL, "START");
2161 g_return_if_fail (label && GL_IS_LABEL (label));
2163 begin_selection_op (label);
2165 selection_list = gl_label_get_selection_list (label);
2167 for (p = selection_list; p != NULL; p = p->next)
2169 object = GL_LABEL_OBJECT (p->data);
2170 gl_label_object_set_text_line_spacing (object, text_line_spacing, TRUE);
2173 g_list_free (selection_list);
2175 end_selection_op (label);
2177 gl_debug (DEBUG_LABEL, "END");
2181 /*****************************************************************************/
2182 /* Set text color for all text contained in selected objects. */
2183 /*****************************************************************************/
2185 gl_label_set_selection_text_color (glLabel *label,
2186 glColorNode *text_color_node)
2188 GList *selection_list;
2190 glLabelObject *object;
2192 gl_debug (DEBUG_LABEL, "START");
2194 g_return_if_fail (label && GL_IS_LABEL (label));
2196 begin_selection_op (label);
2198 selection_list = gl_label_get_selection_list (label);
2200 for (p = selection_list; p != NULL; p = p->next)
2202 object = GL_LABEL_OBJECT (p->data);
2203 gl_label_object_set_text_color (object, text_color_node, TRUE);
2206 g_list_free (selection_list);
2208 end_selection_op (label);
2210 gl_debug (DEBUG_LABEL, "END");
2214 /*****************************************************************************/
2215 /* Set fill color for all selected objects. */
2216 /*****************************************************************************/
2218 gl_label_set_selection_fill_color (glLabel *label,
2219 glColorNode *fill_color_node)
2221 GList *selection_list;
2223 glLabelObject *object;
2225 gl_debug (DEBUG_LABEL, "START");
2227 g_return_if_fail (label && GL_IS_LABEL (label));
2229 begin_selection_op (label);
2231 selection_list = gl_label_get_selection_list (label);
2233 for (p = selection_list; p != NULL; p = p->next)
2235 object = GL_LABEL_OBJECT (p->data);
2236 gl_label_object_set_fill_color (object, fill_color_node, TRUE);
2239 g_list_free (selection_list);
2241 end_selection_op (label);
2243 gl_debug (DEBUG_LABEL, "END");
2247 /*****************************************************************************/
2248 /* Set line color for all selected objects. */
2249 /*****************************************************************************/
2251 gl_label_set_selection_line_color (glLabel *label,
2252 glColorNode *line_color_node)
2254 GList *selection_list;
2256 glLabelObject *object;
2258 gl_debug (DEBUG_LABEL, "START");
2260 g_return_if_fail (label && GL_IS_LABEL (label));
2262 begin_selection_op (label);
2264 selection_list = gl_label_get_selection_list (label);
2266 for (p = selection_list; p != NULL; p = p->next)
2268 object = GL_LABEL_OBJECT (p->data);
2269 gl_label_object_set_line_color (object, line_color_node, TRUE);
2272 g_list_free (selection_list);
2274 end_selection_op (label);
2276 gl_debug (DEBUG_LABEL, "END");
2280 /*****************************************************************************/
2281 /* Set line width for all selected objects. */
2282 /*****************************************************************************/
2284 gl_label_set_selection_line_width (glLabel *label,
2287 GList *selection_list;
2289 glLabelObject *object;
2291 gl_debug (DEBUG_LABEL, "START");
2293 g_return_if_fail (label && GL_IS_LABEL (label));
2295 begin_selection_op (label);
2297 selection_list = gl_label_get_selection_list (label);
2299 for (p = selection_list; p != NULL; p = p->next)
2301 object = GL_LABEL_OBJECT (p->data);
2302 gl_label_object_set_line_width (object, line_width, TRUE);
2305 g_list_free (selection_list);
2307 end_selection_op (label);
2309 gl_debug (DEBUG_LABEL, "END");
2313 /*****************************************************************************/
2314 /* "Cut" selected items and place on clipboard. */
2315 /*****************************************************************************/
2317 gl_label_cut_selection (glLabel *label)
2319 gl_debug (DEBUG_LABEL, "START");
2321 g_return_if_fail (label && GL_IS_LABEL (label));
2323 gl_label_copy_selection (label);
2324 gl_label_delete_selection (label);
2326 gl_debug (DEBUG_LABEL, "END");
2330 /*****************************************************************************/
2331 /* "Copy" selected items to clipboard. */
2332 /*****************************************************************************/
2334 gl_label_copy_selection (glLabel *label)
2336 GtkClipboard *clipboard;
2337 GList *selection_list;
2338 glLabel *label_copy;
2340 glLabelObject *object;
2341 glXMLLabelStatus status;
2343 ClipboardData *data;
2345 static GtkTargetEntry glabels_targets[] = { { "application/glabels", 0, 0 },
2346 { "text/xml", 0, 0 },
2349 GtkTargetList *target_list;
2350 GtkTargetEntry *target_table;
2353 gl_debug (DEBUG_LABEL, "START");
2355 g_return_if_fail (label && GL_IS_LABEL (label));
2357 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2359 selection_list = gl_label_get_selection_list (label);
2364 data = g_new0 (ClipboardData, 1);
2366 target_list = gtk_target_list_new (glabels_targets, G_N_ELEMENTS(glabels_targets));
2369 * Serialize selection by encoding as an XML label document.
2371 label_copy = GL_LABEL(gl_label_new ());
2373 gl_label_set_template (label_copy, label->priv->template, FALSE);
2374 gl_label_set_rotate_flag (label_copy, label->priv->rotate_flag, FALSE);
2376 for (p = selection_list; p != NULL; p = p->next)
2378 object = GL_LABEL_OBJECT (p->data);
2380 gl_label_add_object (label_copy, gl_label_object_dup (object, label_copy));
2383 data->xml_buffer = gl_xml_label_save_buffer (label_copy, &status);
2385 g_object_unref (G_OBJECT (label_copy));
2389 * Is it an atomic text selection? If so, also make available as text.
2391 if ( gl_label_is_selection_atomic (label) &&
2392 GL_IS_LABEL_TEXT (selection_list->data) )
2394 glLabelText *text_object = GL_LABEL_TEXT (selection_list->data);
2396 gtk_target_list_add_text_targets (target_list, 1);
2398 data->text = gl_label_text_get_text (text_object);
2403 * Is it an atomic image selection? If so, also make available as pixbuf.
2405 if ( gl_label_is_selection_atomic (label) &&
2406 GL_IS_LABEL_IMAGE (selection_list->data) )
2408 glLabelImage *image_object = GL_LABEL_IMAGE (selection_list->data);
2409 GdkPixbuf *pixbuf = gl_label_image_get_pixbuf (image_object, NULL);
2413 gtk_target_list_add_image_targets (target_list, 2, TRUE);
2414 data->pixbuf = pixbuf;
2419 target_table = gtk_target_table_new_from_list (target_list, &n_targets);
2421 gtk_clipboard_set_with_data (clipboard,
2422 target_table, n_targets,
2423 (GtkClipboardGetFunc)clipboard_get_cb,
2424 (GtkClipboardClearFunc)clipboard_clear_cb,
2427 gtk_target_table_free (target_table, n_targets);
2428 gtk_target_list_unref (target_list);
2432 g_list_free (selection_list);
2434 gl_debug (DEBUG_LABEL, "END");
2438 /*****************************************************************************/
2439 /* "Paste" from clipboard. */
2440 /*****************************************************************************/
2442 gl_label_paste (glLabel *label)
2444 GtkClipboard *clipboard;
2446 gl_debug (DEBUG_LABEL, "START");
2448 g_return_if_fail (label && GL_IS_LABEL (label));
2450 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2452 gtk_clipboard_request_targets (clipboard,
2453 (GtkClipboardTargetsReceivedFunc)receive_targets_cb,
2456 gl_debug (DEBUG_LABEL, "END");
2460 /*****************************************************************************/
2461 /* Is there anything that can be pasted? */
2462 /*****************************************************************************/
2464 gl_label_can_paste (glLabel *label)
2466 GtkClipboard *clipboard;
2469 gl_debug (DEBUG_LABEL, "START");
2471 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2473 can_flag = gtk_clipboard_wait_is_target_available (clipboard,
2474 gdk_atom_intern("application/glabels", TRUE))
2475 || gtk_clipboard_wait_is_text_available (clipboard)
2476 || gtk_clipboard_wait_is_image_available (clipboard);
2478 gl_debug (DEBUG_LABEL, "END");
2483 /****************************************************************************/
2484 /* Clipboard "Get" function. */
2485 /****************************************************************************/
2487 clipboard_get_cb (GtkClipboard *clipboard,
2488 GtkSelectionData *selection_data,
2490 ClipboardData *data)
2492 gl_debug (DEBUG_LABEL, "START");
2498 gtk_selection_data_set (selection_data,
2499 gtk_selection_data_get_target (selection_data),
2501 (guchar *)data->xml_buffer, strlen (data->xml_buffer));
2505 gtk_selection_data_set_text (selection_data, data->text, -1);
2509 gtk_selection_data_set_pixbuf (selection_data, data->pixbuf);
2513 g_assert_not_reached ();
2518 gl_debug (DEBUG_LABEL, "END");
2522 /****************************************************************************/
2523 /* Clipboard "Clear" function. */
2524 /****************************************************************************/
2526 clipboard_clear_cb (GtkClipboard *clipboard,
2527 ClipboardData *data)
2529 gl_debug (DEBUG_LABEL, "START");
2531 g_free (data->xml_buffer);
2532 g_free (data->text);
2535 g_object_unref (data->pixbuf);
2540 gl_debug (DEBUG_LABEL, "END");
2544 /****************************************************************************/
2545 /* Deal with clipboard data. */
2546 /****************************************************************************/
2548 receive_targets_cb (GtkClipboard *clipboard,
2556 * Application/glabels
2558 for ( i = 0; i < n_targets; i++ )
2560 if ( strcmp(gdk_atom_name(targets[i]), "application/glabels") == 0 )
2562 gtk_clipboard_request_contents (clipboard,
2563 gdk_atom_intern("application/glabels", TRUE),
2564 (GtkClipboardReceivedFunc)paste_xml_received_cb,
2573 if ( gtk_targets_include_text (targets, n_targets) )
2575 gtk_clipboard_request_text (clipboard,
2576 (GtkClipboardTextReceivedFunc)paste_text_received_cb,
2584 if ( gtk_targets_include_image (targets, n_targets, TRUE) )
2586 gtk_clipboard_request_image (clipboard,
2587 (GtkClipboardImageReceivedFunc)paste_image_received_cb,
2594 /****************************************************************************/
2595 /* Paste received glabels XML callback. */
2596 /****************************************************************************/
2598 paste_xml_received_cb (GtkClipboard *clipboard,
2599 GtkSelectionData *selection_data,
2603 glLabel *label_copy;
2604 glXMLLabelStatus status;
2606 glLabelObject *object, *newobject;
2608 gl_debug (DEBUG_LABEL, "START");
2610 gl_label_checkpoint (label, _("Paste"));
2612 xml_buffer = (gchar *)gtk_selection_data_get_data (selection_data);
2615 * Deserialize XML label document and extract objects.
2617 label_copy = gl_xml_label_open_buffer (xml_buffer, &status);
2620 gl_label_unselect_all (label);
2622 for (p = label_copy->priv->object_list; p != NULL; p = p->next)
2624 object = (glLabelObject *) p->data;
2625 newobject = gl_label_object_dup (object, label);
2626 gl_label_add_object( label, newobject );
2628 gl_label_select_object (label, newobject);
2630 gl_debug (DEBUG_LABEL, "object pasted");
2633 g_object_unref (G_OBJECT (label_copy));
2636 gl_debug (DEBUG_LABEL, "END");
2640 /****************************************************************************/
2641 /* Paste received text callback. */
2642 /****************************************************************************/
2644 paste_text_received_cb (GtkClipboard *clipboard,
2648 glLabelObject *object;
2650 gl_debug (DEBUG_LABEL, "START");
2652 gl_label_checkpoint (label, _("Paste"));
2654 gl_label_unselect_all (label);
2656 object = GL_LABEL_OBJECT (gl_label_text_new (label, FALSE));
2657 gl_label_text_set_text (GL_LABEL_TEXT (object), text, FALSE);
2658 gl_label_object_set_position (object, 18, 18, FALSE);
2660 gl_label_select_object (label, object);
2662 gl_debug (DEBUG_LABEL, "END");
2666 /****************************************************************************/
2667 /* Paste received image callback. */
2668 /****************************************************************************/
2670 paste_image_received_cb (GtkClipboard *clipboard,
2674 glLabelObject *object;
2676 gl_debug (DEBUG_LABEL, "START");
2678 gl_label_checkpoint (label, _("Paste"));
2680 gl_label_unselect_all (label);
2682 object = GL_LABEL_OBJECT (gl_label_image_new (label, FALSE));
2683 gl_label_image_set_pixbuf (GL_LABEL_IMAGE (object), pixbuf, FALSE);
2684 gl_label_object_set_position (object, 18, 18, FALSE);
2686 gl_label_select_object (label, object);
2688 gl_debug (DEBUG_LABEL, "END");
2692 /****************************************************************************/
2693 /* Set default font family. */
2694 /****************************************************************************/
2696 gl_label_set_default_font_family (glLabel *label,
2697 const gchar *font_family)
2699 gl_debug (DEBUG_LABEL, "START");
2701 g_return_if_fail (label && GL_IS_LABEL (label));
2703 g_free (label->priv->default_font_family);
2704 label->priv->default_font_family = g_strdup (font_family);
2706 gl_debug (DEBUG_LABEL, "END");
2710 /****************************************************************************/
2711 /* Set default font size. */
2712 /****************************************************************************/
2714 gl_label_set_default_font_size (glLabel *label,
2717 gl_debug (DEBUG_LABEL, "START");
2719 g_return_if_fail (label && GL_IS_LABEL (label));
2721 label->priv->default_font_size = font_size;
2723 gl_debug (DEBUG_LABEL, "END");
2727 /****************************************************************************/
2728 /* Set default font weight. */
2729 /****************************************************************************/
2731 gl_label_set_default_font_weight (glLabel *label,
2732 PangoWeight font_weight)
2734 gl_debug (DEBUG_LABEL, "START");
2736 g_return_if_fail (label && GL_IS_LABEL (label));
2738 label->priv->default_font_weight = font_weight;
2740 gl_debug (DEBUG_LABEL, "END");
2744 /****************************************************************************/
2745 /* Set default font italic flag. */
2746 /****************************************************************************/
2748 gl_label_set_default_font_italic_flag (glLabel *label,
2749 gboolean font_italic_flag)
2751 gl_debug (DEBUG_LABEL, "START");
2753 g_return_if_fail (label && GL_IS_LABEL (label));
2755 label->priv->default_font_italic_flag = font_italic_flag;
2757 gl_debug (DEBUG_LABEL, "END");
2761 /****************************************************************************/
2762 /* Set default text color. */
2763 /****************************************************************************/
2765 gl_label_set_default_text_color (glLabel *label,
2768 gl_debug (DEBUG_LABEL, "START");
2770 g_return_if_fail (label && GL_IS_LABEL (label));
2772 label->priv->default_text_color = text_color;
2774 gl_debug (DEBUG_LABEL, "END");
2778 /****************************************************************************/
2779 /* Set default text alignment. */
2780 /****************************************************************************/
2782 gl_label_set_default_text_alignment (glLabel *label,
2783 PangoAlignment text_alignment)
2785 gl_debug (DEBUG_LABEL, "START");
2787 g_return_if_fail (label && GL_IS_LABEL (label));
2789 label->priv->default_text_alignment = text_alignment;
2790 gl_debug (DEBUG_LABEL, "END");
2794 /****************************************************************************/
2795 /* Set default text line spacing. */
2796 /****************************************************************************/
2798 gl_label_set_default_text_line_spacing (glLabel *label,
2799 gdouble text_line_spacing)
2801 gl_debug (DEBUG_LABEL, "START");
2803 g_return_if_fail (label && GL_IS_LABEL (label));
2805 label->priv->default_text_line_spacing = text_line_spacing;
2807 gl_debug (DEBUG_LABEL, "END");
2811 /****************************************************************************/
2812 /* Set default line width. */
2813 /****************************************************************************/
2815 gl_label_set_default_line_width (glLabel *label,
2818 gl_debug (DEBUG_LABEL, "START");
2820 g_return_if_fail (label && GL_IS_LABEL (label));
2822 label->priv->default_line_width = line_width;
2824 gl_debug (DEBUG_LABEL, "END");
2828 /****************************************************************************/
2829 /* Set default line color. */
2830 /****************************************************************************/
2832 gl_label_set_default_line_color (glLabel *label,
2835 gl_debug (DEBUG_LABEL, "START");
2837 g_return_if_fail (label && GL_IS_LABEL (label));
2839 label->priv->default_line_color = line_color;
2841 gl_debug (DEBUG_LABEL, "END");
2845 /****************************************************************************/
2846 /* Set default fill color. */
2847 /****************************************************************************/
2849 gl_label_set_default_fill_color (glLabel *label,
2852 gl_debug (DEBUG_LABEL, "START");
2854 g_return_if_fail (label && GL_IS_LABEL (label));
2856 label->priv->default_fill_color = fill_color;
2858 gl_debug (DEBUG_LABEL, "END");
2862 /****************************************************************************/
2863 /* Get default font family. */
2864 /****************************************************************************/
2866 gl_label_get_default_font_family (glLabel *label)
2868 gl_debug (DEBUG_LABEL, "START");
2870 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
2872 gl_debug (DEBUG_LABEL, "END");
2874 return g_strdup (label->priv->default_font_family);
2878 /****************************************************************************/
2879 /* Get default font size. */
2880 /****************************************************************************/
2882 gl_label_get_default_font_size (glLabel *label)
2884 gl_debug (DEBUG_LABEL, "START");
2886 g_return_val_if_fail (label && GL_IS_LABEL (label), 12.0);
2888 gl_debug (DEBUG_LABEL, "END");
2890 return label->priv->default_font_size;
2894 /****************************************************************************/
2895 /* Get default font weight. */
2896 /****************************************************************************/
2898 gl_label_get_default_font_weight (glLabel *label)
2900 gl_debug (DEBUG_LABEL, "START");
2902 g_return_val_if_fail (label && GL_IS_LABEL (label), PANGO_WEIGHT_NORMAL);
2904 gl_debug (DEBUG_LABEL, "END");
2906 return label->priv->default_font_weight;
2910 /****************************************************************************/
2911 /* Get default font italic flag. */
2912 /****************************************************************************/
2914 gl_label_get_default_font_italic_flag (glLabel *label)
2916 gl_debug (DEBUG_LABEL, "START");
2918 g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
2920 gl_debug (DEBUG_LABEL, "END");
2922 return label->priv->default_font_italic_flag;
2926 /****************************************************************************/
2927 /* Get default text color. */
2928 /****************************************************************************/
2930 gl_label_get_default_text_color (glLabel *label)
2932 gl_debug (DEBUG_LABEL, "START");
2934 g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
2936 gl_debug (DEBUG_LABEL, "END");
2938 return label->priv->default_text_color;
2942 /****************************************************************************/
2943 /* Get default text alignment. */
2944 /****************************************************************************/
2946 gl_label_get_default_text_alignment (glLabel *label)
2948 gl_debug (DEBUG_LABEL, "START");
2950 g_return_val_if_fail (label && GL_IS_LABEL (label), PANGO_ALIGN_LEFT);
2952 gl_debug (DEBUG_LABEL, "END");
2954 return label->priv->default_text_alignment;
2958 /****************************************************************************/
2959 /* Get default text line spacing. */
2960 /****************************************************************************/
2962 gl_label_get_default_text_line_spacing (glLabel *label)
2964 gl_debug (DEBUG_LABEL, "START");
2966 g_return_val_if_fail (label && GL_IS_LABEL (label), 1.0);
2968 gl_debug (DEBUG_LABEL, "END");
2970 return label->priv->default_text_line_spacing;
2974 /****************************************************************************/
2975 /* Get default line width. */
2976 /****************************************************************************/
2978 gl_label_get_default_line_width (glLabel *label)
2980 gl_debug (DEBUG_LABEL, "START");
2982 g_return_val_if_fail (label && GL_IS_LABEL (label), 1.0);
2984 gl_debug (DEBUG_LABEL, "END");
2986 return label->priv->default_line_width;
2990 /****************************************************************************/
2991 /* Get default line color. */
2992 /****************************************************************************/
2994 gl_label_get_default_line_color (glLabel *label)
2996 gl_debug (DEBUG_LABEL, "START");
2998 g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
3000 gl_debug (DEBUG_LABEL, "END");
3002 return label->priv->default_line_color;
3006 /****************************************************************************/
3007 /* Get default fill color. */
3008 /****************************************************************************/
3010 gl_label_get_default_fill_color (glLabel *label)
3012 gl_debug (DEBUG_LABEL, "START");
3014 g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
3016 gl_debug (DEBUG_LABEL, "END");
3018 return label->priv->default_fill_color;
3022 /****************************************************************************/
3024 /****************************************************************************/
3026 gl_label_draw (glLabel *label,
3028 gboolean screen_flag,
3029 glMergeRecord *record)
3032 glLabelObject *object;
3034 g_return_if_fail (label && GL_IS_LABEL (label));
3036 for (p_obj = label->priv->object_list; p_obj != NULL; p_obj = p_obj->next)
3038 object = GL_LABEL_OBJECT (p_obj->data);
3040 gl_label_object_draw (object, cr, screen_flag, record);
3045 /****************************************************************************/
3046 /* Get object located at coordinates. */
3047 /****************************************************************************/
3048 glLabelObject *gl_label_object_at (glLabel *label,
3054 glLabelObject *object;
3056 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
3058 for (p_obj = g_list_last (label->priv->object_list); p_obj != NULL; p_obj = p_obj->prev)
3060 object = GL_LABEL_OBJECT (p_obj->data);
3062 if (gl_label_object_is_located_at (object, cr, x_pixels, y_pixels))
3073 /****************************************************************************/
3074 /* Return handle and associated object at coordinates. */
3075 /****************************************************************************/
3077 gl_label_get_handle_at (glLabel *label,
3081 glLabelObjectHandle *handle)
3083 GList *selection_list;
3085 glLabelObject *object;
3087 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
3089 selection_list = gl_label_get_selection_list (label);
3091 for (p_obj = g_list_last (selection_list); p_obj != NULL; p_obj = p_obj->prev)
3094 object = GL_LABEL_OBJECT (p_obj->data);
3096 if ((*handle = gl_label_object_handle_at (object, cr, x_pixels, y_pixels)))
3098 g_list_free (selection_list);
3104 g_list_free (selection_list);
3106 *handle = GL_LABEL_OBJECT_HANDLE_NONE;
3111 /****************************************************************************/
3112 /* Checkpoint state. */
3113 /****************************************************************************/
3115 gl_label_checkpoint (glLabel *this,
3116 const gchar *description)
3120 gl_debug (DEBUG_LABEL, "START");
3123 * Do not perform consecutive checkpoints that are identical.
3124 * E.g. moving an object by dragging, would produce a large number
3125 * of incremental checkpoints -- what we really want is a single
3126 * checkpoint so that we can undo the entire dragging effort with
3129 if ( this->priv->cp_cleared_flag
3130 || (this->priv->cp_desc == NULL)
3131 || (strcmp (description, this->priv->cp_desc) != 0) )
3134 /* Sever old redo "thread" */
3135 stack_clear (this->priv->redo_stack);
3137 /* Save state onto undo stack. */
3138 state = state_new (this, description);
3139 stack_push_state (this->priv->undo_stack, state);
3141 /* Track consecutive checkpoints. */
3142 this->priv->cp_cleared_flag = FALSE;
3143 this->priv->cp_desc = g_strdup (description);
3146 gl_debug (DEBUG_LABEL, "END");
3150 /****************************************************************************/
3152 /****************************************************************************/
3154 gl_label_undo (glLabel *this)
3159 gl_debug (DEBUG_LABEL, "START");
3161 state_old = stack_pop_state (this->priv->undo_stack);
3162 state_now = state_new (this, state_old->description);
3164 stack_push_state (this->priv->redo_stack, state_now);
3166 state_restore (state_old, this);
3167 state_free (state_old);
3169 this->priv->cp_cleared_flag = TRUE;
3171 gl_debug (DEBUG_LABEL, "END");
3175 /****************************************************************************/
3177 /****************************************************************************/
3179 gl_label_redo (glLabel *this)
3184 gl_debug (DEBUG_LABEL, "START");
3186 state_old = stack_pop_state (this->priv->redo_stack);
3187 state_now = state_new (this, state_old->description);
3189 stack_push_state (this->priv->undo_stack, state_now);
3191 state_restore (state_old, this);
3192 state_free (state_old);
3194 this->priv->cp_cleared_flag = TRUE;
3196 gl_debug (DEBUG_LABEL, "END");
3200 /****************************************************************************/
3202 /****************************************************************************/
3204 gl_label_can_undo (glLabel *this)
3206 return (!g_queue_is_empty (this->priv->undo_stack));
3210 /****************************************************************************/
3212 /****************************************************************************/
3214 gl_label_can_redo (glLabel *this)
3216 return (!g_queue_is_empty (this->priv->redo_stack));
3220 /****************************************************************************/
3221 /* Get undo description string. */
3222 /****************************************************************************/
3224 gl_label_get_undo_description (glLabel *this)
3229 state = g_queue_peek_head (this->priv->undo_stack);
3232 description = g_strdup (state->description);
3236 description = g_strdup ("");
3243 /****************************************************************************/
3244 /* Get redo description string. */
3245 /****************************************************************************/
3247 gl_label_get_redo_description (glLabel *this)
3252 state = g_queue_peek_head (this->priv->redo_stack);
3255 description = g_strdup (state->description);
3259 description = g_strdup ("");
3266 /****************************************************************************/
3267 /* Clear undo or redo stack. */
3268 /****************************************************************************/
3270 stack_clear (GQueue *stack)
3274 gl_debug (DEBUG_LABEL, "START");
3276 while ( (state = g_queue_pop_head (stack)) != NULL )
3281 gl_debug (DEBUG_LABEL, "END");
3285 /****************************************************************************/
3286 /* Push state onto stack. */
3287 /****************************************************************************/
3289 stack_push_state (GQueue *stack,
3292 gl_debug (DEBUG_LABEL, "START");
3294 g_queue_push_head( stack, state );
3296 gl_debug (DEBUG_LABEL, "END");
3300 /****************************************************************************/
3301 /* Pop state from stack. */
3302 /****************************************************************************/
3304 stack_pop_state (GQueue *stack)
3308 gl_debug (DEBUG_LABEL, "START");
3310 state = g_queue_pop_head (stack);
3312 gl_debug (DEBUG_LABEL, "END");
3317 /****************************************************************************/
3318 /* New state from label. */
3319 /****************************************************************************/
3321 state_new (glLabel *this,
3322 const gchar *description)
3326 glLabelObject *object;
3328 gl_debug (DEBUG_LABEL, "START");
3330 state = g_new0 (State, 1);
3332 state->description = g_strdup (description);
3334 state->template = lgl_template_dup (this->priv->template);
3335 state->rotate_flag = this->priv->rotate_flag;
3337 for ( p_obj = this->priv->object_list; p_obj != NULL; p_obj = p_obj->next )
3339 object = GL_LABEL_OBJECT (p_obj->data);
3341 state->object_list = g_list_append (state->object_list,
3342 gl_label_object_dup (object, this));
3345 state->merge = gl_merge_dup (this->priv->merge);
3347 state->modified_flag = this->priv->modified_flag;
3348 state->time_stamp = this->priv->time_stamp;
3351 gl_debug (DEBUG_LABEL, "END");
3356 /****************************************************************************/
3357 /* Restore label from saved state. */
3358 /****************************************************************************/
3360 state_free (State *state)
3364 gl_debug (DEBUG_LABEL, "START");
3366 g_free (state->description);
3368 lgl_template_free (state->template);
3371 g_object_unref (G_OBJECT (state->merge));
3374 for ( p_obj = state->object_list; p_obj != NULL; p_obj = p_obj->next )
3376 g_object_unref (G_OBJECT (p_obj->data));
3378 g_list_free (state->object_list);
3382 gl_debug (DEBUG_LABEL, "END");
3386 /****************************************************************************/
3387 /* Restore label from saved state. */
3388 /****************************************************************************/
3390 state_restore (State *state,
3394 GList *p_obj, *p_next;
3395 glLabelObject *object;
3397 gl_debug (DEBUG_LABEL, "START");
3399 gl_label_set_rotate_flag (this, state->rotate_flag, FALSE);
3400 gl_label_set_template (this, state->template, FALSE);
3402 for ( p_obj = this->priv->object_list; p_obj != NULL; p_obj = p_next )
3404 p_next = p_obj->next; /* Hold on to next; delete is destructive */
3405 object = GL_LABEL_OBJECT (p_obj->data);
3407 gl_label_delete_object (this, object);
3410 for ( p_obj = state->object_list; p_obj != NULL; p_obj = p_obj->next )
3412 object = GL_LABEL_OBJECT (p_obj->data);
3414 gl_label_add_object (this, gl_label_object_dup (object, this));
3416 g_signal_emit (G_OBJECT(this), signals[SELECTION_CHANGED], 0);
3418 gl_label_set_merge (this, state->merge, FALSE);
3421 if ( !state->modified_flag &&
3422 (state->time_stamp.tv_sec == this->priv->time_stamp.tv_sec) &&
3423 (state->time_stamp.tv_usec == this->priv->time_stamp.tv_usec) )
3425 gl_label_clear_modified (this);
3428 gl_debug (DEBUG_LABEL, "END");
3435 * Local Variables: -- emacs
3437 * c-basic-offset: 8 -- emacs
3438 * tab-width: 8 -- emacs
3439 * indent-tabs-mode: nil -- emacs