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 g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
1235 gl_debug (DEBUG_LABEL, "END");
1239 /****************************************************************************/
1240 /* Bring selection object to front/top. */
1241 /****************************************************************************/
1243 gl_label_raise_selection_to_top (glLabel *label)
1245 GList *selection_list;
1247 glLabelObject *object;
1249 gl_debug (DEBUG_LABEL, "START");
1251 gl_label_checkpoint (label, _("Bring to front"));
1253 begin_selection_op (label);
1255 selection_list = gl_label_get_selection_list (label);
1257 for ( p = selection_list; p != NULL; p = p->next )
1259 object = GL_LABEL_OBJECT (p->data);
1261 label->priv->object_list = g_list_remove (label->priv->object_list, object);
1264 /* Move to end of list, representing front most object */
1265 label->priv->object_list = g_list_concat (label->priv->object_list, selection_list);
1269 end_selection_op (label);
1271 gl_debug (DEBUG_LABEL, "END");
1275 /****************************************************************************/
1276 /* Send selection to rear/bottom. */
1277 /****************************************************************************/
1279 gl_label_lower_selection_to_bottom (glLabel *label)
1281 GList *selection_list;
1283 glLabelObject *object;
1285 gl_debug (DEBUG_LABEL, "START");
1287 gl_label_checkpoint (label, _("Send to back"));
1289 begin_selection_op (label);
1291 selection_list = gl_label_get_selection_list (label);
1293 for ( p = selection_list; p != NULL; p = p->next )
1295 object = GL_LABEL_OBJECT (p->data);
1297 label->priv->object_list = g_list_remove (label->priv->object_list, object);
1300 /* Move to front of list, representing rear most object */
1301 label->priv->object_list = g_list_concat (selection_list, label->priv->object_list);
1305 end_selection_op (label);
1307 gl_debug (DEBUG_LABEL, "END");
1311 /*****************************************************************************/
1312 /* Rotate selected objects by given angle. */
1313 /*****************************************************************************/
1315 gl_label_rotate_selection (glLabel *label,
1318 GList *selection_list;
1320 glLabelObject *object;
1322 gl_debug (DEBUG_LABEL, "START");
1324 g_return_if_fail (label && GL_IS_LABEL (label));
1326 begin_selection_op (label);
1328 gl_label_checkpoint (label, _("Rotate"));
1330 selection_list = gl_label_get_selection_list (label);
1332 for ( p = selection_list; p != NULL; p = p->next )
1334 object = GL_LABEL_OBJECT (p->data);
1336 gl_label_object_rotate (object, theta_degs);
1339 g_list_free (selection_list);
1341 end_selection_op (label);
1343 gl_debug (DEBUG_LABEL, "END");
1347 /*****************************************************************************/
1348 /* Rotate selected objects 90 degrees left. */
1349 /*****************************************************************************/
1351 gl_label_rotate_selection_left (glLabel *label)
1353 GList *selection_list;
1355 glLabelObject *object;
1357 gl_debug (DEBUG_LABEL, "START");
1359 g_return_if_fail (label && GL_IS_LABEL (label));
1361 begin_selection_op (label);
1363 gl_label_checkpoint (label, _("Rotate left"));
1365 selection_list = gl_label_get_selection_list (label);
1367 for ( p = selection_list; p != NULL; p = p->next )
1369 object = GL_LABEL_OBJECT (p->data);
1371 gl_label_object_rotate (object, -90.0);
1374 g_list_free (selection_list);
1376 end_selection_op (label);
1378 gl_debug (DEBUG_LABEL, "END");
1382 /*****************************************************************************/
1383 /* Rotate selected objects 90 degrees right. */
1384 /*****************************************************************************/
1386 gl_label_rotate_selection_right (glLabel *label)
1388 GList *selection_list;
1390 glLabelObject *object;
1392 gl_debug (DEBUG_LABEL, "START");
1394 g_return_if_fail (label && GL_IS_LABEL (label));
1396 gl_label_checkpoint (label, _("Rotate right"));
1398 begin_selection_op (label);
1400 selection_list = gl_label_get_selection_list (label);
1402 for ( p = selection_list; p != NULL; p = p->next )
1404 object = GL_LABEL_OBJECT (p->data);
1406 gl_label_object_rotate (object, 90.0);
1409 g_list_free (selection_list);
1411 end_selection_op (label);
1413 gl_debug (DEBUG_LABEL, "END");
1417 /*****************************************************************************/
1418 /* Flip selected objects horizontally. */
1419 /*****************************************************************************/
1421 gl_label_flip_selection_horiz (glLabel *label)
1423 GList *selection_list;
1425 glLabelObject *object;
1427 gl_debug (DEBUG_LABEL, "START");
1429 g_return_if_fail (label && GL_IS_LABEL (label));
1431 gl_label_checkpoint (label, _("Flip horizontally"));
1433 begin_selection_op (label);
1435 selection_list = gl_label_get_selection_list (label);
1437 for ( p = selection_list; p != NULL; p = p->next )
1439 object = GL_LABEL_OBJECT (p->data);
1441 gl_label_object_flip_horiz (object);
1444 g_list_free (selection_list);
1446 end_selection_op (label);
1448 gl_debug (DEBUG_LABEL, "END");
1452 /*****************************************************************************/
1453 /* Flip selected objects vertically. */
1454 /*****************************************************************************/
1456 gl_label_flip_selection_vert (glLabel *label)
1458 GList *selection_list;
1460 glLabelObject *object;
1462 gl_debug (DEBUG_LABEL, "START");
1464 g_return_if_fail (label && GL_IS_LABEL (label));
1466 gl_label_checkpoint (label, _("Flip vertically"));
1468 begin_selection_op (label);
1470 selection_list = gl_label_get_selection_list (label);
1472 for ( p = selection_list; p != NULL; p = p->next )
1474 object = GL_LABEL_OBJECT (p->data);
1476 gl_label_object_flip_vert (object);
1479 g_list_free (selection_list);
1481 end_selection_op (label);
1483 gl_debug (DEBUG_LABEL, "END");
1487 /*****************************************************************************/
1488 /* Align selected objects to left most edge. */
1489 /*****************************************************************************/
1491 gl_label_align_selection_left (glLabel *label)
1493 GList *selection_list;
1495 glLabelObject *object;
1497 glLabelRegion obj_extent;
1499 gl_debug (DEBUG_LABEL, "START");
1501 g_return_if_fail (label && GL_IS_LABEL (label));
1503 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1504 !gl_label_is_selection_atomic (label));
1506 gl_label_checkpoint (label, _("Align left"));
1508 begin_selection_op (label);
1510 selection_list = gl_label_get_selection_list (label);
1512 /* find left most edge */
1514 object = GL_LABEL_OBJECT (p->data);
1516 gl_label_object_get_extent (object, &obj_extent);
1517 x1_min = obj_extent.x1;
1518 for (p = p->next; p != NULL; p = p->next)
1520 object = GL_LABEL_OBJECT (p->data);
1522 gl_label_object_get_extent (object, &obj_extent);
1523 if ( obj_extent.x1 < x1_min ) x1_min = obj_extent.x1;
1526 /* now adjust the object positions to line up the left edges */
1527 for (p = selection_list; p != NULL; p = p->next)
1529 object = GL_LABEL_OBJECT (p->data);
1531 gl_label_object_get_extent (object, &obj_extent);
1532 dx = x1_min - obj_extent.x1;
1533 gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1536 g_list_free (selection_list);
1538 end_selection_op (label);
1540 gl_debug (DEBUG_LABEL, "END");
1544 /*****************************************************************************/
1545 /* Align selected objects to right most edge. */
1546 /*****************************************************************************/
1548 gl_label_align_selection_right (glLabel *label)
1550 GList *selection_list;
1552 glLabelObject *object;
1554 glLabelRegion obj_extent;
1556 gl_debug (DEBUG_LABEL, "START");
1558 g_return_if_fail (label && GL_IS_LABEL (label));
1560 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1561 !gl_label_is_selection_atomic (label));
1563 gl_label_checkpoint (label, _("Align right"));
1565 begin_selection_op (label);
1567 selection_list = gl_label_get_selection_list (label);
1569 /* find left most edge */
1571 object = GL_LABEL_OBJECT (p->data);
1573 gl_label_object_get_extent (object, &obj_extent);
1574 x2_max = obj_extent.x2;
1575 for (p = p->next; p != NULL; p = p->next)
1577 object = GL_LABEL_OBJECT (p->data);
1579 gl_label_object_get_extent (object, &obj_extent);
1580 if ( obj_extent.x2 > x2_max ) x2_max = obj_extent.x2;
1583 /* now adjust the object positions to line up the left edges */
1584 for (p = selection_list; p != NULL; p = p->next)
1586 object = GL_LABEL_OBJECT (p->data);
1588 gl_label_object_get_extent (object, &obj_extent);
1589 dx = x2_max - obj_extent.x2;
1590 gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1593 g_list_free (selection_list);
1595 end_selection_op (label);
1597 gl_debug (DEBUG_LABEL, "END");
1601 /*****************************************************************************/
1602 /* Align selected objects to horizontal center of objects. */
1603 /*****************************************************************************/
1605 gl_label_align_selection_hcenter (glLabel *label)
1607 GList *selection_list;
1609 glLabelObject *object;
1613 glLabelRegion obj_extent;
1617 gl_debug (DEBUG_LABEL, "START");
1619 g_return_if_fail (label && GL_IS_LABEL (label));
1621 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1622 !gl_label_is_selection_atomic (label));
1624 gl_label_checkpoint (label, _("Align horizontal center"));
1626 begin_selection_op (label);
1628 selection_list = gl_label_get_selection_list (label);
1630 /* find average center of objects */
1633 for (p = selection_list; p != NULL; p = p->next)
1635 object = GL_LABEL_OBJECT (p->data);
1637 gl_label_object_get_extent (object, &obj_extent);
1638 xsum += (obj_extent.x1 + obj_extent.x2) / 2.0;
1643 /* find center of object closest to average center */
1645 object = GL_LABEL_OBJECT (p->data);
1647 gl_label_object_get_extent (object, &obj_extent);
1648 dxmin = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
1649 xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
1650 for (p = p->next; p != NULL; p = p->next)
1652 object = GL_LABEL_OBJECT (p->data);
1654 gl_label_object_get_extent (object, &obj_extent);
1655 dx = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
1659 xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
1663 /* now adjust the object positions to line up this center */
1664 for (p = selection_list; p != NULL; p = p->next)
1666 object = GL_LABEL_OBJECT (p->data);
1668 gl_label_object_get_extent (object, &obj_extent);
1669 dx = xcenter - (obj_extent.x1 + obj_extent.x2)/2.0;
1670 gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1673 g_list_free (selection_list);
1675 end_selection_op (label);
1677 gl_debug (DEBUG_LABEL, "END");
1681 /*****************************************************************************/
1682 /* Align selected objects to top most edge. */
1683 /*****************************************************************************/
1685 gl_label_align_selection_top (glLabel *label)
1687 GList *selection_list;
1689 glLabelObject *object;
1691 glLabelRegion obj_extent;
1693 gl_debug (DEBUG_LABEL, "START");
1695 g_return_if_fail (label && GL_IS_LABEL (label));
1697 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1698 !gl_label_is_selection_atomic (label));
1700 gl_label_checkpoint (label, _("Align tops"));
1702 begin_selection_op (label);
1704 selection_list = gl_label_get_selection_list (label);
1706 /* find top most edge */
1708 object = GL_LABEL_OBJECT (p->data);
1710 gl_label_object_get_extent (object, &obj_extent);
1711 y1_min = obj_extent.y1;
1712 for (p = p->next; p != NULL; p = p->next)
1714 object = GL_LABEL_OBJECT (p->data);
1716 gl_label_object_get_extent (object, &obj_extent);
1717 if ( obj_extent.y1 < y1_min ) y1_min = obj_extent.y1;
1720 /* now adjust the object positions to line up the top edges */
1721 for (p = selection_list; p != NULL; p = p->next)
1723 object = GL_LABEL_OBJECT (p->data);
1725 gl_label_object_get_extent (object, &obj_extent);
1726 dy = y1_min - obj_extent.y1;
1727 gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1730 g_list_free (selection_list);
1732 end_selection_op (label);
1734 gl_debug (DEBUG_LABEL, "END");
1738 /*****************************************************************************/
1739 /* Align selected objects to bottom most edge. */
1740 /*****************************************************************************/
1742 gl_label_align_selection_bottom (glLabel *label)
1744 GList *selection_list;
1746 glLabelObject *object;
1748 glLabelRegion obj_extent;
1750 gl_debug (DEBUG_LABEL, "START");
1752 g_return_if_fail (label && GL_IS_LABEL (label));
1754 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1755 !gl_label_is_selection_atomic (label));
1757 gl_label_checkpoint (label, _("Align bottoms"));
1759 begin_selection_op (label);
1761 selection_list = gl_label_get_selection_list (label);
1763 /* find bottom most edge */
1765 object = GL_LABEL_OBJECT (p->data);
1767 gl_label_object_get_extent (object, &obj_extent);
1768 y2_max = obj_extent.y2;
1769 for (p = p->next; p != NULL; p = p->next)
1771 object = GL_LABEL_OBJECT (p->data);
1773 gl_label_object_get_extent (object, &obj_extent);
1774 if ( obj_extent.y2 > y2_max ) y2_max = obj_extent.y2;
1777 /* now adjust the object positions to line up the bottom edges */
1778 for (p = selection_list; p != NULL; p = p->next)
1780 object = GL_LABEL_OBJECT (p->data);
1782 gl_label_object_get_extent (object, &obj_extent);
1783 dy = y2_max - obj_extent.y2;
1784 gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1787 g_list_free (selection_list);
1789 end_selection_op (label);
1791 gl_debug (DEBUG_LABEL, "END");
1795 /*****************************************************************************/
1796 /* Align selected objects to viertical center of objects. */
1797 /*****************************************************************************/
1799 gl_label_align_selection_vcenter (glLabel *label)
1801 GList *selection_list;
1803 glLabelObject *object;
1807 glLabelRegion obj_extent;
1811 gl_debug (DEBUG_LABEL, "START");
1813 g_return_if_fail (label && GL_IS_LABEL (label));
1815 g_return_if_fail (!gl_label_is_selection_empty (label) &&
1816 !gl_label_is_selection_atomic (label));
1818 gl_label_checkpoint (label, _("Align vertical center"));
1820 begin_selection_op (label);
1822 selection_list = gl_label_get_selection_list (label);
1824 /* find average center of objects */
1827 for (p = selection_list; p != NULL; p = p->next)
1829 object = GL_LABEL_OBJECT (p->data);
1831 gl_label_object_get_extent (object, &obj_extent);
1832 ysum += (obj_extent.y1 + obj_extent.y2) / 2.0;
1837 /* find center of object closest to average center */
1839 object = GL_LABEL_OBJECT (p->data);
1841 gl_label_object_get_extent (object, &obj_extent);
1842 dymin = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
1843 ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
1844 for (p = p->next; p != NULL; p = p->next)
1846 object = GL_LABEL_OBJECT (p->data);
1848 gl_label_object_get_extent (object, &obj_extent);
1849 dy = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
1853 ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
1857 /* now adjust the object positions to line up this center */
1858 for (p = selection_list; p != NULL; p = p->next)
1860 object = GL_LABEL_OBJECT (p->data);
1862 gl_label_object_get_extent (object, &obj_extent);
1863 dy = ycenter - (obj_extent.y1 + obj_extent.y2)/2.0;
1864 gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1867 g_list_free (selection_list);
1869 end_selection_op (label);
1871 gl_debug (DEBUG_LABEL, "END");
1875 /*****************************************************************************/
1876 /* Center selected objects to in center of label. */
1877 /*****************************************************************************/
1879 gl_label_center_selection_horiz (glLabel *label)
1881 GList *selection_list;
1883 glLabelObject *object;
1885 gdouble x_label_center;
1886 gdouble x_obj_center;
1887 glLabelRegion obj_extent;
1890 gl_debug (DEBUG_LABEL, "START");
1892 g_return_if_fail (label && GL_IS_LABEL (label));
1894 g_return_if_fail (!gl_label_is_selection_empty (label));
1896 gl_label_checkpoint (label, _("Center horizontally"));
1898 begin_selection_op (label);
1900 gl_label_get_size (label, &w, &h);
1901 x_label_center = w / 2.0;
1903 /* adjust the object positions */
1904 selection_list = gl_label_get_selection_list (label);
1905 for (p = selection_list; p != NULL; p = p->next)
1907 object = GL_LABEL_OBJECT (p->data);
1909 gl_label_object_get_extent (object, &obj_extent);
1910 x_obj_center = (obj_extent.x1 + obj_extent.x2) / 2.0;
1911 dx = x_label_center - x_obj_center;
1912 gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1914 g_list_free (selection_list);
1916 end_selection_op (label);
1918 gl_debug (DEBUG_LABEL, "END");
1922 /*****************************************************************************/
1923 /* Center selected objects to in center of label. */
1924 /*****************************************************************************/
1926 gl_label_center_selection_vert (glLabel *label)
1928 GList *selection_list;
1930 glLabelObject *object;
1932 gdouble y_label_center;
1933 gdouble y_obj_center;
1934 glLabelRegion obj_extent;
1937 gl_debug (DEBUG_LABEL, "START");
1939 g_return_if_fail (label && GL_IS_LABEL (label));
1941 g_return_if_fail (!gl_label_is_selection_empty (label));
1943 gl_label_checkpoint (label, _("Center vertically"));
1945 begin_selection_op (label);
1947 gl_label_get_size (label, &w, &h);
1948 y_label_center = h / 2.0;
1950 /* adjust the object positions */
1951 selection_list = gl_label_get_selection_list (label);
1952 for (p = selection_list; p != NULL; p = p->next)
1954 object = GL_LABEL_OBJECT (p->data);
1956 gl_label_object_get_extent (object, &obj_extent);
1957 y_obj_center = (obj_extent.y1 + obj_extent.y2) / 2.0;
1958 dy = y_label_center - y_obj_center;
1959 gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1961 g_list_free (selection_list);
1963 end_selection_op (label);
1965 gl_debug (DEBUG_LABEL, "END");
1969 /*****************************************************************************/
1970 /* Move selected objects */
1971 /*****************************************************************************/
1973 gl_label_move_selection (glLabel *label,
1977 GList *selection_list;
1979 glLabelObject *object;
1981 gl_debug (DEBUG_LABEL, "START");
1983 g_return_if_fail (label && GL_IS_LABEL (label));
1985 begin_selection_op (label);
1987 selection_list = gl_label_get_selection_list (label);
1989 for (p = selection_list; p != NULL; p = p->next)
1991 object = GL_LABEL_OBJECT (p->data);
1993 gl_label_object_set_position_relative (object, dx, dy, TRUE);
1996 g_list_free (selection_list);
1998 end_selection_op (label);
2000 gl_debug (DEBUG_LABEL, "END");
2004 /*****************************************************************************/
2005 /* Set font family for all text contained in selected objects. */
2006 /*****************************************************************************/
2008 gl_label_set_selection_font_family (glLabel *label,
2009 const gchar *font_family)
2011 GList *selection_list;
2013 glLabelObject *object;
2015 gl_debug (DEBUG_LABEL, "START");
2017 g_return_if_fail (label && GL_IS_LABEL (label));
2019 begin_selection_op (label);
2021 selection_list = gl_label_get_selection_list (label);
2023 for (p = selection_list; p != NULL; p = p->next)
2025 object = GL_LABEL_OBJECT (p->data);
2026 gl_label_object_set_font_family (object, font_family, TRUE);
2029 g_list_free (selection_list);
2031 end_selection_op (label);
2033 gl_debug (DEBUG_LABEL, "END");
2037 /*****************************************************************************/
2038 /* Set font size for all text contained in selected objects. */
2039 /*****************************************************************************/
2041 gl_label_set_selection_font_size (glLabel *label,
2044 GList *selection_list;
2046 glLabelObject *object;
2048 gl_debug (DEBUG_LABEL, "START");
2050 g_return_if_fail (label && GL_IS_LABEL (label));
2052 begin_selection_op (label);
2054 selection_list = gl_label_get_selection_list (label);
2056 for (p = selection_list; p != NULL; p = p->next)
2058 object = GL_LABEL_OBJECT (p->data);
2059 gl_label_object_set_font_size (object, font_size, TRUE);
2062 g_list_free (selection_list);
2064 end_selection_op (label);
2066 gl_debug (DEBUG_LABEL, "END");
2070 /*****************************************************************************/
2071 /* Set font weight for all text contained in selected objects. */
2072 /*****************************************************************************/
2074 gl_label_set_selection_font_weight (glLabel *label,
2075 PangoWeight font_weight)
2077 GList *selection_list;
2079 glLabelObject *object;
2081 gl_debug (DEBUG_LABEL, "START");
2083 g_return_if_fail (label && GL_IS_LABEL (label));
2085 begin_selection_op (label);
2087 selection_list = gl_label_get_selection_list (label);
2089 for (p = selection_list; p != NULL; p = p->next)
2091 object = GL_LABEL_OBJECT (p->data);
2092 gl_label_object_set_font_weight (object, font_weight, TRUE);
2095 g_list_free (selection_list);
2097 end_selection_op (label);
2099 gl_debug (DEBUG_LABEL, "END");
2103 /*****************************************************************************/
2104 /* Set font italic flag for all text contained in selected objects. */
2105 /*****************************************************************************/
2107 gl_label_set_selection_font_italic_flag (glLabel *label,
2108 gboolean font_italic_flag)
2110 GList *selection_list;
2112 glLabelObject *object;
2114 gl_debug (DEBUG_LABEL, "START");
2116 g_return_if_fail (label && GL_IS_LABEL (label));
2118 begin_selection_op (label);
2120 selection_list = gl_label_get_selection_list (label);
2122 for (p = selection_list; p != NULL; p = p->next)
2124 object = GL_LABEL_OBJECT (p->data);
2125 gl_label_object_set_font_italic_flag (object, font_italic_flag, TRUE);
2128 g_list_free (selection_list);
2130 end_selection_op (label);
2132 gl_debug (DEBUG_LABEL, "END");
2136 /*****************************************************************************/
2137 /* Set text alignment for all text contained in selected objects. */
2138 /*****************************************************************************/
2140 gl_label_set_selection_text_alignment (glLabel *label,
2141 PangoAlignment text_alignment)
2143 GList *selection_list;
2145 glLabelObject *object;
2147 gl_debug (DEBUG_LABEL, "START");
2149 g_return_if_fail (label && GL_IS_LABEL (label));
2151 begin_selection_op (label);
2153 selection_list = gl_label_get_selection_list (label);
2155 for (p = selection_list; p != NULL; p = p->next)
2157 object = GL_LABEL_OBJECT (p->data);
2158 gl_label_object_set_text_alignment (object, text_alignment, TRUE);
2161 g_list_free (selection_list);
2163 end_selection_op (label);
2165 gl_debug (DEBUG_LABEL, "END");
2169 /*****************************************************************************/
2170 /* Set vertical text alignment for all text contained in selected objects. */
2171 /*****************************************************************************/
2173 gl_label_set_selection_text_valignment (glLabel *label,
2174 glValignment text_valignment)
2176 GList *selection_list;
2178 glLabelObject *object;
2180 gl_debug (DEBUG_LABEL, "START");
2182 g_return_if_fail (label && GL_IS_LABEL (label));
2184 begin_selection_op (label);
2186 selection_list = gl_label_get_selection_list (label);
2188 for (p = selection_list; p != NULL; p = p->next)
2190 object = GL_LABEL_OBJECT (p->data);
2191 gl_label_object_set_text_valignment (object, text_valignment, TRUE);
2194 g_list_free (selection_list);
2196 end_selection_op (label);
2198 gl_debug (DEBUG_LABEL, "END");
2202 /*****************************************************************************/
2203 /* Set text line spacing for all text contained in selected objects. */
2204 /*****************************************************************************/
2206 gl_label_set_selection_text_line_spacing (glLabel *label,
2207 gdouble text_line_spacing)
2209 GList *selection_list;
2211 glLabelObject *object;
2213 gl_debug (DEBUG_LABEL, "START");
2215 g_return_if_fail (label && GL_IS_LABEL (label));
2217 begin_selection_op (label);
2219 selection_list = gl_label_get_selection_list (label);
2221 for (p = selection_list; p != NULL; p = p->next)
2223 object = GL_LABEL_OBJECT (p->data);
2224 gl_label_object_set_text_line_spacing (object, text_line_spacing, TRUE);
2227 g_list_free (selection_list);
2229 end_selection_op (label);
2231 gl_debug (DEBUG_LABEL, "END");
2235 /*****************************************************************************/
2236 /* Set text color for all text contained in selected objects. */
2237 /*****************************************************************************/
2239 gl_label_set_selection_text_color (glLabel *label,
2240 glColorNode *text_color_node)
2242 GList *selection_list;
2244 glLabelObject *object;
2246 gl_debug (DEBUG_LABEL, "START");
2248 g_return_if_fail (label && GL_IS_LABEL (label));
2250 begin_selection_op (label);
2252 selection_list = gl_label_get_selection_list (label);
2254 for (p = selection_list; p != NULL; p = p->next)
2256 object = GL_LABEL_OBJECT (p->data);
2257 gl_label_object_set_text_color (object, text_color_node, TRUE);
2260 g_list_free (selection_list);
2262 end_selection_op (label);
2264 gl_debug (DEBUG_LABEL, "END");
2268 /*****************************************************************************/
2269 /* Set fill color for all selected objects. */
2270 /*****************************************************************************/
2272 gl_label_set_selection_fill_color (glLabel *label,
2273 glColorNode *fill_color_node)
2275 GList *selection_list;
2277 glLabelObject *object;
2279 gl_debug (DEBUG_LABEL, "START");
2281 g_return_if_fail (label && GL_IS_LABEL (label));
2283 begin_selection_op (label);
2285 selection_list = gl_label_get_selection_list (label);
2287 for (p = selection_list; p != NULL; p = p->next)
2289 object = GL_LABEL_OBJECT (p->data);
2290 gl_label_object_set_fill_color (object, fill_color_node, TRUE);
2293 g_list_free (selection_list);
2295 end_selection_op (label);
2297 gl_debug (DEBUG_LABEL, "END");
2301 /*****************************************************************************/
2302 /* Set line color for all selected objects. */
2303 /*****************************************************************************/
2305 gl_label_set_selection_line_color (glLabel *label,
2306 glColorNode *line_color_node)
2308 GList *selection_list;
2310 glLabelObject *object;
2312 gl_debug (DEBUG_LABEL, "START");
2314 g_return_if_fail (label && GL_IS_LABEL (label));
2316 begin_selection_op (label);
2318 selection_list = gl_label_get_selection_list (label);
2320 for (p = selection_list; p != NULL; p = p->next)
2322 object = GL_LABEL_OBJECT (p->data);
2323 gl_label_object_set_line_color (object, line_color_node, TRUE);
2326 g_list_free (selection_list);
2328 end_selection_op (label);
2330 gl_debug (DEBUG_LABEL, "END");
2334 /*****************************************************************************/
2335 /* Set line width for all selected objects. */
2336 /*****************************************************************************/
2338 gl_label_set_selection_line_width (glLabel *label,
2341 GList *selection_list;
2343 glLabelObject *object;
2345 gl_debug (DEBUG_LABEL, "START");
2347 g_return_if_fail (label && GL_IS_LABEL (label));
2349 begin_selection_op (label);
2351 selection_list = gl_label_get_selection_list (label);
2353 for (p = selection_list; p != NULL; p = p->next)
2355 object = GL_LABEL_OBJECT (p->data);
2356 gl_label_object_set_line_width (object, line_width, TRUE);
2359 g_list_free (selection_list);
2361 end_selection_op (label);
2363 gl_debug (DEBUG_LABEL, "END");
2367 /*****************************************************************************/
2368 /* "Cut" selected items and place on clipboard. */
2369 /*****************************************************************************/
2371 gl_label_cut_selection (glLabel *label)
2373 gl_debug (DEBUG_LABEL, "START");
2375 g_return_if_fail (label && GL_IS_LABEL (label));
2377 gl_label_copy_selection (label);
2378 gl_label_delete_selection (label);
2380 gl_debug (DEBUG_LABEL, "END");
2384 /*****************************************************************************/
2385 /* "Copy" selected items to clipboard. */
2386 /*****************************************************************************/
2388 gl_label_copy_selection (glLabel *label)
2390 GtkClipboard *clipboard;
2391 GList *selection_list;
2392 glLabel *label_copy;
2394 glLabelObject *object;
2395 glXMLLabelStatus status;
2397 ClipboardData *data;
2399 static GtkTargetEntry glabels_targets[] = { { "application/glabels", 0, 0 },
2400 { "text/xml", 0, 0 },
2403 GtkTargetList *target_list;
2404 GtkTargetEntry *target_table;
2407 gl_debug (DEBUG_LABEL, "START");
2409 g_return_if_fail (label && GL_IS_LABEL (label));
2411 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2413 selection_list = gl_label_get_selection_list (label);
2418 data = g_new0 (ClipboardData, 1);
2420 target_list = gtk_target_list_new (glabels_targets, G_N_ELEMENTS(glabels_targets));
2423 * Serialize selection by encoding as an XML label document.
2425 label_copy = GL_LABEL(gl_label_new ());
2427 gl_label_set_template (label_copy, label->priv->template, FALSE);
2428 gl_label_set_rotate_flag (label_copy, label->priv->rotate_flag, FALSE);
2430 for (p = selection_list; p != NULL; p = p->next)
2432 object = GL_LABEL_OBJECT (p->data);
2434 gl_label_add_object (label_copy, gl_label_object_dup (object, label_copy));
2437 data->xml_buffer = gl_xml_label_save_buffer (label_copy, &status);
2439 g_object_unref (G_OBJECT (label_copy));
2443 * Is it an atomic text selection? If so, also make available as text.
2445 if ( gl_label_is_selection_atomic (label) &&
2446 GL_IS_LABEL_TEXT (selection_list->data) )
2448 glLabelText *text_object = GL_LABEL_TEXT (selection_list->data);
2450 gtk_target_list_add_text_targets (target_list, 1);
2452 data->text = gl_label_text_get_text (text_object);
2457 * Is it an atomic image selection? If so, also make available as pixbuf.
2459 if ( gl_label_is_selection_atomic (label) &&
2460 GL_IS_LABEL_IMAGE (selection_list->data) )
2462 glLabelImage *image_object = GL_LABEL_IMAGE (selection_list->data);
2463 GdkPixbuf *pixbuf = gl_label_image_get_pixbuf (image_object, NULL);
2467 gtk_target_list_add_image_targets (target_list, 2, TRUE);
2468 data->pixbuf = pixbuf;
2473 target_table = gtk_target_table_new_from_list (target_list, &n_targets);
2475 gtk_clipboard_set_with_data (clipboard,
2476 target_table, n_targets,
2477 (GtkClipboardGetFunc)clipboard_get_cb,
2478 (GtkClipboardClearFunc)clipboard_clear_cb,
2481 gtk_target_table_free (target_table, n_targets);
2482 gtk_target_list_unref (target_list);
2486 g_list_free (selection_list);
2488 gl_debug (DEBUG_LABEL, "END");
2492 /*****************************************************************************/
2493 /* "Paste" from clipboard. */
2494 /*****************************************************************************/
2496 gl_label_paste (glLabel *label)
2498 GtkClipboard *clipboard;
2500 gl_debug (DEBUG_LABEL, "START");
2502 g_return_if_fail (label && GL_IS_LABEL (label));
2504 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2506 gtk_clipboard_request_targets (clipboard,
2507 (GtkClipboardTargetsReceivedFunc)receive_targets_cb,
2510 gl_debug (DEBUG_LABEL, "END");
2514 /*****************************************************************************/
2515 /* Is there anything that can be pasted? */
2516 /*****************************************************************************/
2518 gl_label_can_paste (glLabel *label)
2520 GtkClipboard *clipboard;
2523 gl_debug (DEBUG_LABEL, "START");
2525 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2527 can_flag = gtk_clipboard_wait_is_target_available (clipboard,
2528 gdk_atom_intern("application/glabels", TRUE))
2529 || gtk_clipboard_wait_is_text_available (clipboard)
2530 || gtk_clipboard_wait_is_image_available (clipboard);
2532 gl_debug (DEBUG_LABEL, "END");
2537 /****************************************************************************/
2538 /* Clipboard "Get" function. */
2539 /****************************************************************************/
2541 clipboard_get_cb (GtkClipboard *clipboard,
2542 GtkSelectionData *selection_data,
2544 ClipboardData *data)
2546 gl_debug (DEBUG_LABEL, "START");
2552 gtk_selection_data_set (selection_data,
2553 gtk_selection_data_get_target (selection_data),
2555 (guchar *)data->xml_buffer, strlen (data->xml_buffer));
2559 gtk_selection_data_set_text (selection_data, data->text, -1);
2563 gtk_selection_data_set_pixbuf (selection_data, data->pixbuf);
2567 g_assert_not_reached ();
2572 gl_debug (DEBUG_LABEL, "END");
2576 /****************************************************************************/
2577 /* Clipboard "Clear" function. */
2578 /****************************************************************************/
2580 clipboard_clear_cb (GtkClipboard *clipboard,
2581 ClipboardData *data)
2583 gl_debug (DEBUG_LABEL, "START");
2585 g_free (data->xml_buffer);
2586 g_free (data->text);
2589 g_object_unref (data->pixbuf);
2594 gl_debug (DEBUG_LABEL, "END");
2598 /****************************************************************************/
2599 /* Deal with clipboard data. */
2600 /****************************************************************************/
2602 receive_targets_cb (GtkClipboard *clipboard,
2610 * Application/glabels
2612 for ( i = 0; i < n_targets; i++ )
2614 if ( strcmp(gdk_atom_name(targets[i]), "application/glabels") == 0 )
2616 gtk_clipboard_request_contents (clipboard,
2617 gdk_atom_intern("application/glabels", TRUE),
2618 (GtkClipboardReceivedFunc)paste_xml_received_cb,
2627 if ( gtk_targets_include_text (targets, n_targets) )
2629 gtk_clipboard_request_text (clipboard,
2630 (GtkClipboardTextReceivedFunc)paste_text_received_cb,
2638 if ( gtk_targets_include_image (targets, n_targets, TRUE) )
2640 gtk_clipboard_request_image (clipboard,
2641 (GtkClipboardImageReceivedFunc)paste_image_received_cb,
2648 /****************************************************************************/
2649 /* Paste received glabels XML callback. */
2650 /****************************************************************************/
2652 paste_xml_received_cb (GtkClipboard *clipboard,
2653 GtkSelectionData *selection_data,
2657 glLabel *label_copy;
2658 glXMLLabelStatus status;
2660 glLabelObject *object, *newobject;
2662 gl_debug (DEBUG_LABEL, "START");
2664 gl_label_checkpoint (label, _("Paste"));
2666 xml_buffer = (gchar *)gtk_selection_data_get_data (selection_data);
2669 * Deserialize XML label document and extract objects.
2671 label_copy = gl_xml_label_open_buffer (xml_buffer, &status);
2674 gl_label_unselect_all (label);
2676 for (p = label_copy->priv->object_list; p != NULL; p = p->next)
2678 object = (glLabelObject *) p->data;
2679 newobject = gl_label_object_dup (object, label);
2680 gl_label_add_object( label, newobject );
2682 gl_label_select_object (label, newobject);
2684 gl_debug (DEBUG_LABEL, "object pasted");
2687 g_object_unref (G_OBJECT (label_copy));
2690 gl_debug (DEBUG_LABEL, "END");
2694 /****************************************************************************/
2695 /* Paste received text callback. */
2696 /****************************************************************************/
2698 paste_text_received_cb (GtkClipboard *clipboard,
2702 glLabelObject *object;
2704 gl_debug (DEBUG_LABEL, "START");
2706 gl_label_checkpoint (label, _("Paste"));
2708 gl_label_unselect_all (label);
2710 object = GL_LABEL_OBJECT (gl_label_text_new (label, FALSE));
2711 gl_label_text_set_text (GL_LABEL_TEXT (object), text, FALSE);
2712 gl_label_object_set_position (object, 18, 18, FALSE);
2714 gl_label_select_object (label, object);
2716 gl_debug (DEBUG_LABEL, "END");
2720 /****************************************************************************/
2721 /* Paste received image callback. */
2722 /****************************************************************************/
2724 paste_image_received_cb (GtkClipboard *clipboard,
2728 glLabelObject *object;
2730 gl_debug (DEBUG_LABEL, "START");
2732 gl_label_checkpoint (label, _("Paste"));
2734 gl_label_unselect_all (label);
2736 object = GL_LABEL_OBJECT (gl_label_image_new (label, FALSE));
2737 gl_label_image_set_pixbuf (GL_LABEL_IMAGE (object), pixbuf, FALSE);
2738 gl_label_object_set_position (object, 18, 18, FALSE);
2740 gl_label_select_object (label, object);
2742 gl_debug (DEBUG_LABEL, "END");
2746 /****************************************************************************/
2747 /* Set default font family. */
2748 /****************************************************************************/
2750 gl_label_set_default_font_family (glLabel *label,
2751 const gchar *font_family)
2753 gl_debug (DEBUG_LABEL, "START");
2755 g_return_if_fail (label && GL_IS_LABEL (label));
2757 g_free (label->priv->default_font_family);
2758 label->priv->default_font_family = g_strdup (font_family);
2760 gl_debug (DEBUG_LABEL, "END");
2764 /****************************************************************************/
2765 /* Set default font size. */
2766 /****************************************************************************/
2768 gl_label_set_default_font_size (glLabel *label,
2771 gl_debug (DEBUG_LABEL, "START");
2773 g_return_if_fail (label && GL_IS_LABEL (label));
2775 label->priv->default_font_size = font_size;
2777 gl_debug (DEBUG_LABEL, "END");
2781 /****************************************************************************/
2782 /* Set default font weight. */
2783 /****************************************************************************/
2785 gl_label_set_default_font_weight (glLabel *label,
2786 PangoWeight font_weight)
2788 gl_debug (DEBUG_LABEL, "START");
2790 g_return_if_fail (label && GL_IS_LABEL (label));
2792 label->priv->default_font_weight = font_weight;
2794 gl_debug (DEBUG_LABEL, "END");
2798 /****************************************************************************/
2799 /* Set default font italic flag. */
2800 /****************************************************************************/
2802 gl_label_set_default_font_italic_flag (glLabel *label,
2803 gboolean font_italic_flag)
2805 gl_debug (DEBUG_LABEL, "START");
2807 g_return_if_fail (label && GL_IS_LABEL (label));
2809 label->priv->default_font_italic_flag = font_italic_flag;
2811 gl_debug (DEBUG_LABEL, "END");
2815 /****************************************************************************/
2816 /* Set default text color. */
2817 /****************************************************************************/
2819 gl_label_set_default_text_color (glLabel *label,
2822 gl_debug (DEBUG_LABEL, "START");
2824 g_return_if_fail (label && GL_IS_LABEL (label));
2826 label->priv->default_text_color = text_color;
2828 gl_debug (DEBUG_LABEL, "END");
2832 /****************************************************************************/
2833 /* Set default text alignment. */
2834 /****************************************************************************/
2836 gl_label_set_default_text_alignment (glLabel *label,
2837 PangoAlignment text_alignment)
2839 gl_debug (DEBUG_LABEL, "START");
2841 g_return_if_fail (label && GL_IS_LABEL (label));
2843 label->priv->default_text_alignment = text_alignment;
2844 gl_debug (DEBUG_LABEL, "END");
2848 /****************************************************************************/
2849 /* Set default vertical text alignment. */
2850 /****************************************************************************/
2852 gl_label_set_default_text_valignment (glLabel *label,
2853 glValignment text_valignment)
2855 gl_debug (DEBUG_LABEL, "START");
2857 g_return_if_fail (label && GL_IS_LABEL (label));
2859 label->priv->default_text_valignment = text_valignment;
2860 gl_debug (DEBUG_LABEL, "END");
2864 /****************************************************************************/
2865 /* Set default text line spacing. */
2866 /****************************************************************************/
2868 gl_label_set_default_text_line_spacing (glLabel *label,
2869 gdouble text_line_spacing)
2871 gl_debug (DEBUG_LABEL, "START");
2873 g_return_if_fail (label && GL_IS_LABEL (label));
2875 label->priv->default_text_line_spacing = text_line_spacing;
2877 gl_debug (DEBUG_LABEL, "END");
2881 /****************************************************************************/
2882 /* Set default line width. */
2883 /****************************************************************************/
2885 gl_label_set_default_line_width (glLabel *label,
2888 gl_debug (DEBUG_LABEL, "START");
2890 g_return_if_fail (label && GL_IS_LABEL (label));
2892 label->priv->default_line_width = line_width;
2894 gl_debug (DEBUG_LABEL, "END");
2898 /****************************************************************************/
2899 /* Set default line color. */
2900 /****************************************************************************/
2902 gl_label_set_default_line_color (glLabel *label,
2905 gl_debug (DEBUG_LABEL, "START");
2907 g_return_if_fail (label && GL_IS_LABEL (label));
2909 label->priv->default_line_color = line_color;
2911 gl_debug (DEBUG_LABEL, "END");
2915 /****************************************************************************/
2916 /* Set default fill color. */
2917 /****************************************************************************/
2919 gl_label_set_default_fill_color (glLabel *label,
2922 gl_debug (DEBUG_LABEL, "START");
2924 g_return_if_fail (label && GL_IS_LABEL (label));
2926 label->priv->default_fill_color = fill_color;
2928 gl_debug (DEBUG_LABEL, "END");
2932 /****************************************************************************/
2933 /* Get default font family. */
2934 /****************************************************************************/
2936 gl_label_get_default_font_family (glLabel *label)
2938 gl_debug (DEBUG_LABEL, "START");
2940 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
2942 gl_debug (DEBUG_LABEL, "END");
2944 return g_strdup (label->priv->default_font_family);
2948 /****************************************************************************/
2949 /* Get default font size. */
2950 /****************************************************************************/
2952 gl_label_get_default_font_size (glLabel *label)
2954 gl_debug (DEBUG_LABEL, "START");
2956 g_return_val_if_fail (label && GL_IS_LABEL (label), 12.0);
2958 gl_debug (DEBUG_LABEL, "END");
2960 return label->priv->default_font_size;
2964 /****************************************************************************/
2965 /* Get default font weight. */
2966 /****************************************************************************/
2968 gl_label_get_default_font_weight (glLabel *label)
2970 gl_debug (DEBUG_LABEL, "START");
2972 g_return_val_if_fail (label && GL_IS_LABEL (label), PANGO_WEIGHT_NORMAL);
2974 gl_debug (DEBUG_LABEL, "END");
2976 return label->priv->default_font_weight;
2980 /****************************************************************************/
2981 /* Get default font italic flag. */
2982 /****************************************************************************/
2984 gl_label_get_default_font_italic_flag (glLabel *label)
2986 gl_debug (DEBUG_LABEL, "START");
2988 g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
2990 gl_debug (DEBUG_LABEL, "END");
2992 return label->priv->default_font_italic_flag;
2996 /****************************************************************************/
2997 /* Get default text color. */
2998 /****************************************************************************/
3000 gl_label_get_default_text_color (glLabel *label)
3002 gl_debug (DEBUG_LABEL, "START");
3004 g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
3006 gl_debug (DEBUG_LABEL, "END");
3008 return label->priv->default_text_color;
3012 /****************************************************************************/
3013 /* Get default text alignment. */
3014 /****************************************************************************/
3016 gl_label_get_default_text_alignment (glLabel *label)
3018 gl_debug (DEBUG_LABEL, "START");
3020 g_return_val_if_fail (label && GL_IS_LABEL (label), PANGO_ALIGN_LEFT);
3022 gl_debug (DEBUG_LABEL, "END");
3024 return label->priv->default_text_alignment;
3028 /****************************************************************************/
3029 /* Get default vertical text alignment. */
3030 /****************************************************************************/
3032 gl_label_get_default_text_valignment (glLabel *label)
3034 gl_debug (DEBUG_LABEL, "START");
3036 g_return_val_if_fail (label && GL_IS_LABEL (label), GL_VALIGN_TOP);
3038 gl_debug (DEBUG_LABEL, "END");
3040 return label->priv->default_text_valignment;
3044 /****************************************************************************/
3045 /* Get default text line spacing. */
3046 /****************************************************************************/
3048 gl_label_get_default_text_line_spacing (glLabel *label)
3050 gl_debug (DEBUG_LABEL, "START");
3052 g_return_val_if_fail (label && GL_IS_LABEL (label), 1.0);
3054 gl_debug (DEBUG_LABEL, "END");
3056 return label->priv->default_text_line_spacing;
3060 /****************************************************************************/
3061 /* Get default line width. */
3062 /****************************************************************************/
3064 gl_label_get_default_line_width (glLabel *label)
3066 gl_debug (DEBUG_LABEL, "START");
3068 g_return_val_if_fail (label && GL_IS_LABEL (label), 1.0);
3070 gl_debug (DEBUG_LABEL, "END");
3072 return label->priv->default_line_width;
3076 /****************************************************************************/
3077 /* Get default line color. */
3078 /****************************************************************************/
3080 gl_label_get_default_line_color (glLabel *label)
3082 gl_debug (DEBUG_LABEL, "START");
3084 g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
3086 gl_debug (DEBUG_LABEL, "END");
3088 return label->priv->default_line_color;
3092 /****************************************************************************/
3093 /* Get default fill color. */
3094 /****************************************************************************/
3096 gl_label_get_default_fill_color (glLabel *label)
3098 gl_debug (DEBUG_LABEL, "START");
3100 g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
3102 gl_debug (DEBUG_LABEL, "END");
3104 return label->priv->default_fill_color;
3108 /****************************************************************************/
3110 /****************************************************************************/
3112 gl_label_draw (glLabel *label,
3114 gboolean screen_flag,
3115 glMergeRecord *record)
3118 glLabelObject *object;
3120 g_return_if_fail (label && GL_IS_LABEL (label));
3122 for (p_obj = label->priv->object_list; p_obj != NULL; p_obj = p_obj->next)
3124 object = GL_LABEL_OBJECT (p_obj->data);
3126 gl_label_object_draw (object, cr, screen_flag, record);
3131 /****************************************************************************/
3132 /* Get object located at coordinates. */
3133 /****************************************************************************/
3134 glLabelObject *gl_label_object_at (glLabel *label,
3140 glLabelObject *object;
3142 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
3144 for (p_obj = g_list_last (label->priv->object_list); p_obj != NULL; p_obj = p_obj->prev)
3146 object = GL_LABEL_OBJECT (p_obj->data);
3148 if (gl_label_object_is_located_at (object, cr, x_pixels, y_pixels))
3159 /****************************************************************************/
3160 /* Return handle and associated object at coordinates. */
3161 /****************************************************************************/
3163 gl_label_get_handle_at (glLabel *label,
3167 glLabelObjectHandle *handle)
3169 GList *selection_list;
3171 glLabelObject *object;
3173 g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
3175 selection_list = gl_label_get_selection_list (label);
3177 for (p_obj = g_list_last (selection_list); p_obj != NULL; p_obj = p_obj->prev)
3180 object = GL_LABEL_OBJECT (p_obj->data);
3182 if ((*handle = gl_label_object_handle_at (object, cr, x_pixels, y_pixels)))
3184 g_list_free (selection_list);
3190 g_list_free (selection_list);
3192 *handle = GL_LABEL_OBJECT_HANDLE_NONE;
3197 /****************************************************************************/
3198 /* Checkpoint state. */
3199 /****************************************************************************/
3201 gl_label_checkpoint (glLabel *this,
3202 const gchar *description)
3206 gl_debug (DEBUG_LABEL, "START");
3209 * Do not perform consecutive checkpoints that are identical.
3210 * E.g. moving an object by dragging, would produce a large number
3211 * of incremental checkpoints -- what we really want is a single
3212 * checkpoint so that we can undo the entire dragging effort with
3215 if ( this->priv->cp_cleared_flag
3216 || (this->priv->cp_desc == NULL)
3217 || (strcmp (description, this->priv->cp_desc) != 0) )
3220 /* Sever old redo "thread" */
3221 stack_clear (this->priv->redo_stack);
3223 /* Save state onto undo stack. */
3224 state = state_new (this, description);
3225 stack_push_state (this->priv->undo_stack, state);
3227 /* Track consecutive checkpoints. */
3228 this->priv->cp_cleared_flag = FALSE;
3229 this->priv->cp_desc = g_strdup (description);
3232 gl_debug (DEBUG_LABEL, "END");
3236 /****************************************************************************/
3238 /****************************************************************************/
3240 gl_label_undo (glLabel *this)
3245 gl_debug (DEBUG_LABEL, "START");
3247 state_old = stack_pop_state (this->priv->undo_stack);
3248 state_now = state_new (this, state_old->description);
3250 stack_push_state (this->priv->redo_stack, state_now);
3252 state_restore (state_old, this);
3253 state_free (state_old);
3255 this->priv->cp_cleared_flag = TRUE;
3257 gl_debug (DEBUG_LABEL, "END");
3261 /****************************************************************************/
3263 /****************************************************************************/
3265 gl_label_redo (glLabel *this)
3270 gl_debug (DEBUG_LABEL, "START");
3272 state_old = stack_pop_state (this->priv->redo_stack);
3273 state_now = state_new (this, state_old->description);
3275 stack_push_state (this->priv->undo_stack, state_now);
3277 state_restore (state_old, this);
3278 state_free (state_old);
3280 this->priv->cp_cleared_flag = TRUE;
3282 gl_debug (DEBUG_LABEL, "END");
3286 /****************************************************************************/
3288 /****************************************************************************/
3290 gl_label_can_undo (glLabel *this)
3292 return (!g_queue_is_empty (this->priv->undo_stack));
3296 /****************************************************************************/
3298 /****************************************************************************/
3300 gl_label_can_redo (glLabel *this)
3302 return (!g_queue_is_empty (this->priv->redo_stack));
3306 /****************************************************************************/
3307 /* Get undo description string. */
3308 /****************************************************************************/
3310 gl_label_get_undo_description (glLabel *this)
3315 state = g_queue_peek_head (this->priv->undo_stack);
3318 description = g_strdup (state->description);
3322 description = g_strdup ("");
3329 /****************************************************************************/
3330 /* Get redo description string. */
3331 /****************************************************************************/
3333 gl_label_get_redo_description (glLabel *this)
3338 state = g_queue_peek_head (this->priv->redo_stack);
3341 description = g_strdup (state->description);
3345 description = g_strdup ("");
3352 /****************************************************************************/
3353 /* Clear undo or redo stack. */
3354 /****************************************************************************/
3356 stack_clear (GQueue *stack)
3360 gl_debug (DEBUG_LABEL, "START");
3362 while ( (state = g_queue_pop_head (stack)) != NULL )
3367 gl_debug (DEBUG_LABEL, "END");
3371 /****************************************************************************/
3372 /* Push state onto stack. */
3373 /****************************************************************************/
3375 stack_push_state (GQueue *stack,
3378 gl_debug (DEBUG_LABEL, "START");
3380 g_queue_push_head( stack, state );
3382 gl_debug (DEBUG_LABEL, "END");
3386 /****************************************************************************/
3387 /* Pop state from stack. */
3388 /****************************************************************************/
3390 stack_pop_state (GQueue *stack)
3394 gl_debug (DEBUG_LABEL, "START");
3396 state = g_queue_pop_head (stack);
3398 gl_debug (DEBUG_LABEL, "END");
3403 /****************************************************************************/
3404 /* New state from label. */
3405 /****************************************************************************/
3407 state_new (glLabel *this,
3408 const gchar *description)
3412 glLabelObject *object;
3414 gl_debug (DEBUG_LABEL, "START");
3416 state = g_new0 (State, 1);
3418 state->description = g_strdup (description);
3420 state->template = lgl_template_dup (this->priv->template);
3421 state->rotate_flag = this->priv->rotate_flag;
3423 for ( p_obj = this->priv->object_list; p_obj != NULL; p_obj = p_obj->next )
3425 object = GL_LABEL_OBJECT (p_obj->data);
3427 state->object_list = g_list_append (state->object_list,
3428 gl_label_object_dup (object, this));
3431 state->merge = gl_merge_dup (this->priv->merge);
3433 state->modified_flag = this->priv->modified_flag;
3434 state->time_stamp = this->priv->time_stamp;
3437 gl_debug (DEBUG_LABEL, "END");
3442 /****************************************************************************/
3443 /* Restore label from saved state. */
3444 /****************************************************************************/
3446 state_free (State *state)
3450 gl_debug (DEBUG_LABEL, "START");
3452 g_free (state->description);
3454 lgl_template_free (state->template);
3457 g_object_unref (G_OBJECT (state->merge));
3460 for ( p_obj = state->object_list; p_obj != NULL; p_obj = p_obj->next )
3462 g_object_unref (G_OBJECT (p_obj->data));
3464 g_list_free (state->object_list);
3468 gl_debug (DEBUG_LABEL, "END");
3472 /****************************************************************************/
3473 /* Restore label from saved state. */
3474 /****************************************************************************/
3476 state_restore (State *state,
3480 GList *p_obj, *p_next;
3481 glLabelObject *object;
3483 gl_debug (DEBUG_LABEL, "START");
3485 gl_label_set_rotate_flag (this, state->rotate_flag, FALSE);
3486 gl_label_set_template (this, state->template, FALSE);
3488 for ( p_obj = this->priv->object_list; p_obj != NULL; p_obj = p_next )
3490 p_next = p_obj->next; /* Hold on to next; delete is destructive */
3491 object = GL_LABEL_OBJECT (p_obj->data);
3493 gl_label_delete_object (this, object);
3496 for ( p_obj = state->object_list; p_obj != NULL; p_obj = p_obj->next )
3498 object = GL_LABEL_OBJECT (p_obj->data);
3500 gl_label_add_object (this, gl_label_object_dup (object, this));
3502 g_signal_emit (G_OBJECT(this), signals[SELECTION_CHANGED], 0);
3504 gl_label_set_merge (this, state->merge, FALSE);
3507 if ( !state->modified_flag &&
3508 (state->time_stamp.tv_sec == this->priv->time_stamp.tv_sec) &&
3509 (state->time_stamp.tv_usec == this->priv->time_stamp.tv_usec) )
3511 gl_label_clear_modified (this);
3514 gl_debug (DEBUG_LABEL, "END");
3521 * Local Variables: -- emacs
3523 * c-basic-offset: 8 -- emacs
3524 * tab-width: 8 -- emacs
3525 * indent-tabs-mode: nil -- emacs