1 /*
2  *  label.c
3  *  Copyright (C) 2001-2009  Jim Evins <evins@snaught.com>.
4  *
5  *  This file is part of gLabels.
6  *
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.
11  *
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.
16  *
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/>.
19  */
20 
21 #include <config.h>
22 
23 #include "label.h"
24 
25 #include <glib/gi18n.h>
26 #include <math.h>
27 
28 #include "template-history.h"
29 #include "file-util.h"
30 #include "xml-label.h"
31 #include "prefs.h"
32 #include "label-text.h"
33 #include "label-image.h"
34 #include "marshal.h"
35 
36 #include "debug.h"
37 
38 
39 /*========================================================*/
40 /* Private macros and constants.                          */
41 /*========================================================*/
42 
43 
44 /*========================================================*/
45 /* Private types.                                         */
46 /*========================================================*/
47 
48 struct _glLabelPrivate {
49 
50 	gchar       *filename;
51 	gint         compression;
52 	gint         untitled_instance;
53 
54 	gboolean     modified_flag;
55         GTimeVal     time_stamp;
56 
57         lglTemplate *template;
58         gboolean     rotate_flag;
59 
60         GList       *object_list;
61 
62 	glMerge     *merge;
63 
64 	GHashTable  *pixbuf_cache;
65 	GHashTable  *svg_cache;
66 
67         /* Delay changed signals while operating on selections of multiple objects. */
68         gboolean     selection_op_flag;
69         gboolean     delayed_change_flag;
70 
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;
80 
81 	/* Default object line properties */
82 	gdouble            default_line_width;
83 	guint              default_line_color;
84 
85 	/* Default object fill properties */
86 	guint              default_fill_color;
87 
88         /* Undo/Redo state */
89         GQueue      *undo_stack;
90         GQueue      *redo_stack;
91         gboolean     cp_cleared_flag;
92         gchar       *cp_desc;
93 };
94 
95 typedef struct {
96         gchar             *xml_buffer;
97         gchar             *text;
98         GdkPixbuf         *pixbuf;
99 } ClipboardData;
100 
101 enum {
102 	SELECTION_CHANGED,
103 	CHANGED,
104 	NAME_CHANGED,
105 	MODIFIED_CHANGED,
106 	MERGE_CHANGED,
107 	SIZE_CHANGED,
108 	LAST_SIGNAL
109 };
110 
111 typedef struct {
112         gchar       *description;
113 
114 	gboolean     modified_flag;
115         GTimeVal     time_stamp;
116 
117         lglTemplate *template;
118         gboolean     rotate_flag;
119 
120         GList       *object_list;
121 
122 	glMerge     *merge;
123 
124 } State;
125 
126 
127 /*========================================================*/
128 /* Private globals.                                       */
129 /*========================================================*/
130 
131 static guint signals[LAST_SIGNAL] = {0};
132 
133 static guint untitled = 0;
134 
135 
136 /*========================================================*/
137 /* Private function prototypes.                           */
138 /*========================================================*/
139 
140 static void gl_label_finalize      (GObject *object);
141 
142 static void object_changed_cb      (glLabelObject *object,
143                                     glLabel       *label);
144 
145 static void object_moved_cb        (glLabelObject *object,
146                                     glLabel       *label);
147 
148 static void do_modify              (glLabel       *label);
149 
150 static void begin_selection_op     (glLabel       *label);
151 static void end_selection_op       (glLabel       *label);
152 
153 static void clipboard_get_cb       (GtkClipboard     *clipboard,
154                                     GtkSelectionData *selection_data,
155                                     guint             info,
156                                     ClipboardData    *data);
157 
158 static void clipboard_clear_cb     (GtkClipboard     *clipboard,
159                                     ClipboardData    *data);
160 
161 static void receive_targets_cb     (GtkClipboard     *clipboard,
162                                     GdkAtom          *targets,
163                                     gint              n_targets,
164                                     glLabel          *label);
165 
166 static void paste_xml_received_cb  (GtkClipboard     *clipboard,
167                                     GtkSelectionData *selection_data,
168                                     glLabel          *label);
169 
170 static void paste_text_received_cb (GtkClipboard     *clipboard,
171                                     const gchar      *text,
172                                     glLabel          *label);
173 
174 static void paste_image_received_cb(GtkClipboard     *clipboard,
175                                     GdkPixbuf        *pixbuf,
176                                     glLabel          *label);
177 
178 static void   stack_clear          (GQueue           *stack);
179 static void   stack_push_state     (GQueue           *stack,
180                                     State            *state);
181 static State *stack_pop_state      (GQueue           *stack);
182 
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,
187                                     glLabel          *this);
188 
189 
190 /*****************************************************************************/
191 /* Boilerplate object stuff.                                                 */
192 /*****************************************************************************/
G_DEFINE_TYPE(glLabel,gl_label,G_TYPE_OBJECT)193 G_DEFINE_TYPE (glLabel, gl_label, G_TYPE_OBJECT)
194 
195 
196 static void
197 gl_label_class_init (glLabelClass *class)
198 {
199 	GObjectClass *object_class = G_OBJECT_CLASS (class);
200 
201 	gl_debug (DEBUG_LABEL, "START");
202 
203 	gl_label_parent_class = g_type_class_peek_parent (class);
204 
205 	object_class->finalize = gl_label_finalize;
206 
207 	signals[SELECTION_CHANGED] =
208 		g_signal_new ("selection_changed",
209 			      G_OBJECT_CLASS_TYPE (object_class),
210 			      G_SIGNAL_RUN_LAST,
211 			      G_STRUCT_OFFSET (glLabelClass, selection_changed),
212 			      NULL, NULL,
213 			      gl_marshal_VOID__VOID,
214 			      G_TYPE_NONE,
215 			      0);
216 	signals[CHANGED] =
217 		g_signal_new ("changed",
218 			      G_OBJECT_CLASS_TYPE (object_class),
219 			      G_SIGNAL_RUN_LAST,
220 			      G_STRUCT_OFFSET (glLabelClass, changed),
221 			      NULL, NULL,
222 			      gl_marshal_VOID__VOID,
223 			      G_TYPE_NONE,
224 			      0);
225 	signals[NAME_CHANGED] =
226 		g_signal_new ("name_changed",
227 			      G_OBJECT_CLASS_TYPE (object_class),
228 			      G_SIGNAL_RUN_LAST,
229 			      G_STRUCT_OFFSET (glLabelClass, name_changed),
230 			      NULL, NULL,
231 			      gl_marshal_VOID__VOID,
232 			      G_TYPE_NONE,
233 			      0);
234 	signals[MODIFIED_CHANGED] =
235 		g_signal_new ("modified_changed",
236 			      G_OBJECT_CLASS_TYPE (object_class),
237 			      G_SIGNAL_RUN_LAST,
238 			      G_STRUCT_OFFSET (glLabelClass, modified_changed),
239 			      NULL, NULL,
240 			      gl_marshal_VOID__VOID,
241 			      G_TYPE_NONE,
242 			      0);
243 	signals[MERGE_CHANGED] =
244 		g_signal_new ("merge_changed",
245 			      G_OBJECT_CLASS_TYPE (object_class),
246 			      G_SIGNAL_RUN_LAST,
247 			      G_STRUCT_OFFSET (glLabelClass, merge_changed),
248 			      NULL, NULL,
249 			      gl_marshal_VOID__VOID,
250 			      G_TYPE_NONE,
251 			      0);
252 	signals[SIZE_CHANGED] =
253 		g_signal_new ("size_changed",
254 			      G_OBJECT_CLASS_TYPE (object_class),
255 			      G_SIGNAL_RUN_LAST,
256 			      G_STRUCT_OFFSET (glLabelClass, size_changed),
257 			      NULL, NULL,
258 			      gl_marshal_VOID__VOID,
259 			      G_TYPE_NONE,
260 			      0);
261 
262 	gl_debug (DEBUG_LABEL, "END");
263 }
264 
265 
266 static void
gl_label_init(glLabel * label)267 gl_label_init (glLabel *label)
268 {
269 	gl_debug (DEBUG_LABEL, "START");
270 
271 	label->priv = g_new0 (glLabelPrivate, 1);
272 
273 	label->priv->template      = NULL;
274 	label->priv->rotate_flag   = FALSE;
275         label->priv->object_list   = NULL;
276 
277 	label->priv->filename      = NULL;
278 	label->priv->modified_flag = FALSE;
279 	label->priv->compression   = 9;
280 
281 	label->priv->merge         = NULL;
282 	label->priv->pixbuf_cache  = gl_pixbuf_cache_new ();
283 	label->priv->svg_cache     = gl_svg_cache_new ();
284 
285         label->priv->undo_stack    = g_queue_new ();
286         label->priv->redo_stack    = g_queue_new ();
287 
288         /*
289          * Defaults from preferences
290          */
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);
301 
302 	gl_debug (DEBUG_LABEL, "END");
303 }
304 
305 
306 static void
gl_label_finalize(GObject * object)307 gl_label_finalize (GObject *object)
308 {
309 	glLabel *label = GL_LABEL (object);
310 	GList   *p;
311 
312 	gl_debug (DEBUG_LABEL, "START");
313 
314 	g_return_if_fail (object && GL_IS_LABEL (object));
315 
316 	for (p = label->priv->object_list; p != NULL; p = p->next)
317         {
318 		g_object_unref (G_OBJECT(p->data));
319 	}
320         g_list_free (label->priv->object_list);
321 
322 	lgl_template_free (label->priv->template);
323 	g_free (label->priv->filename);
324 	if (label->priv->merge != NULL)
325         {
326 		g_object_unref (G_OBJECT(label->priv->merge));
327 	}
328         g_free (label->priv->default_font_family);
329 
330         stack_clear (label->priv->undo_stack);
331         stack_clear (label->priv->redo_stack);
332 
333         g_queue_free (label->priv->undo_stack);
334         g_queue_free (label->priv->redo_stack);
335 
336 	gl_pixbuf_cache_free (label->priv->pixbuf_cache);
337 	gl_svg_cache_free (label->priv->svg_cache);
338 
339 	g_free (label->priv);
340 
341 	G_OBJECT_CLASS (gl_label_parent_class)->finalize (object);
342 
343 	gl_debug (DEBUG_LABEL, "END");
344 }
345 
346 
347 /*****************************************************************************/
348 /* New label.                                                                */
349 /*****************************************************************************/
350 GObject *
gl_label_new(void)351 gl_label_new (void)
352 {
353 	glLabel *label;
354 
355 	gl_debug (DEBUG_LABEL, "START");
356 
357 	label = g_object_new (gl_label_get_type(), NULL);
358 
359 	gl_debug (DEBUG_LABEL, "END");
360 
361 	return G_OBJECT (label);
362 }
363 
364 
365 /****************************************************************************/
366 /* Set filename.                                                            */
367 /****************************************************************************/
368 void
gl_label_set_filename(glLabel * label,const gchar * filename)369 gl_label_set_filename (glLabel     *label,
370 		       const gchar *filename)
371 {
372 	label->priv->filename = g_strdup (filename);
373 
374 	g_signal_emit (G_OBJECT(label), signals[NAME_CHANGED], 0);
375 }
376 
377 
378 /****************************************************************************/
379 /* return filename.                                                         */
380 /****************************************************************************/
381 gchar *
gl_label_get_filename(glLabel * label)382 gl_label_get_filename (glLabel *label)
383 {
384 	gl_debug (DEBUG_LABEL, "");
385 
386 	return g_strdup ( label->priv->filename );
387 }
388 
389 
390 /****************************************************************************/
391 /* return short filename.                                                   */
392 /****************************************************************************/
393 gchar *
gl_label_get_short_name(glLabel * label)394 gl_label_get_short_name (glLabel *label)
395 {
396 	gl_debug (DEBUG_LABEL, "");
397 
398 	if ( label->priv->filename == NULL )
399         {
400 
401 		if ( label->priv->untitled_instance == 0 )
402                 {
403 			label->priv->untitled_instance = ++untitled;
404 		}
405 
406 		return g_strdup_printf ( "%s %d", _("Untitled"),
407 					 label->priv->untitled_instance );
408 
409 	}
410         else
411         {
412 		gchar *temp_name, *short_name;
413 
414 		temp_name = g_path_get_basename ( label->priv->filename );
415 		short_name = gl_file_util_remove_extension (temp_name);
416 		g_free (temp_name);
417 
418 		return short_name;
419 	}
420 }
421 
422 
423 /****************************************************************************/
424 /* Is label untitled?                                                       */
425 /****************************************************************************/
426 gboolean
gl_label_is_untitled(glLabel * label)427 gl_label_is_untitled (glLabel *label)
428 {
429 	gl_debug (DEBUG_LABEL, "return %d",(label->priv->filename == NULL));
430 	return (label->priv->filename == NULL);
431 }
432 
433 
434 /****************************************************************************/
435 /* Set compression level.                                                   */
436 /****************************************************************************/
437 void
gl_label_set_compression(glLabel * label,gint compression)438 gl_label_set_compression (glLabel  *label,
439 			  gint      compression)
440 {
441 	gl_debug (DEBUG_LABEL, "set %d", compression);
442 
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))
446         {
447 		compression = 9;
448 	}
449 
450 	gl_debug (DEBUG_LABEL, "actual set %d", compression);
451 	label->priv->compression = compression;
452 }
453 
454 
455 /****************************************************************************/
456 /* Get compression level.                                                   */
457 /****************************************************************************/
458 gint
gl_label_get_compression(glLabel * label)459 gl_label_get_compression (glLabel *label)
460 {
461 	gl_debug (DEBUG_LABEL, "return %d", label->priv->compression);
462 	return label->priv->compression;
463 }
464 
465 
466 /****************************************************************************/
467 /* Set modified flag.                                                       */
468 /****************************************************************************/
469 void
gl_label_set_modified(glLabel * label)470 gl_label_set_modified (glLabel *label)
471 {
472 
473 	if ( !label->priv->modified_flag )
474         {
475 
476 		label->priv->modified_flag = TRUE;
477 
478 		g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
479 	}
480 
481 }
482 
483 
484 /****************************************************************************/
485 /* Clear modified flag.                                                     */
486 /****************************************************************************/
487 void
gl_label_clear_modified(glLabel * label)488 gl_label_clear_modified (glLabel *label)
489 {
490 
491 	if ( label->priv->modified_flag )
492         {
493 
494                 g_get_current_time (&label->priv->time_stamp);
495 		label->priv->modified_flag = FALSE;
496 
497 		g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
498 	}
499 
500 }
501 
502 
503 /****************************************************************************/
504 /* Is label modified?                                                       */
505 /****************************************************************************/
506 gboolean
gl_label_is_modified(glLabel * label)507 gl_label_is_modified (glLabel *label)
508 {
509 	gl_debug (DEBUG_LABEL, "return %d", label->priv->modified_flag);
510 	return label->priv->modified_flag;
511 }
512 
513 
514 /****************************************************************************/
515 /* Object "changed" callback.                                               */
516 /****************************************************************************/
517 static void
object_changed_cb(glLabelObject * object,glLabel * label)518 object_changed_cb (glLabelObject *object,
519                    glLabel       *label)
520 {
521         do_modify (label);
522 }
523 
524 
525 /****************************************************************************/
526 /* Object "moved" callback.                                                 */
527 /****************************************************************************/
528 static void
object_moved_cb(glLabelObject * object,glLabel * label)529 object_moved_cb (glLabelObject *object,
530                  glLabel       *label)
531 {
532         do_modify (label);
533 }
534 
535 
536 /****************************************************************************/
537 /* Do modify.                                                               */
538 /****************************************************************************/
539 static void
do_modify(glLabel * label)540 do_modify (glLabel  *label)
541 {
542         if ( label->priv->selection_op_flag )
543         {
544                 label->priv->delayed_change_flag = TRUE;
545         }
546         else
547         {
548                 label->priv->modified_flag = TRUE;
549 
550                 g_signal_emit (G_OBJECT(label), signals[MODIFIED_CHANGED], 0);
551                 g_signal_emit (G_OBJECT(label), signals[CHANGED], 0);
552         }
553 }
554 
555 
556 /****************************************************************************/
557 /* Begin selection operation.                                               */
558 /****************************************************************************/
559 static void
begin_selection_op(glLabel * label)560 begin_selection_op (glLabel  *label)
561 {
562         label->priv->selection_op_flag = TRUE;
563 }
564 
565 
566 /****************************************************************************/
567 /* End selection operation.                                                 */
568 /****************************************************************************/
569 static void
end_selection_op(glLabel * label)570 end_selection_op (glLabel  *label)
571 {
572         label->priv->selection_op_flag = FALSE;
573         if ( label->priv->delayed_change_flag )
574         {
575                 label->priv->delayed_change_flag = FALSE;
576                 do_modify (label);
577         }
578 }
579 
580 
581 /****************************************************************************/
582 /* set template.                                                            */
583 /****************************************************************************/
584 void
gl_label_set_template(glLabel * label,const lglTemplate * template,gboolean checkpoint)585 gl_label_set_template (glLabel           *label,
586 		       const lglTemplate *template,
587                        gboolean           checkpoint)
588 {
589         gchar *name;
590 
591 	gl_debug (DEBUG_LABEL, "START");
592 
593 	g_return_if_fail (label && GL_IS_LABEL (label));
594 	g_return_if_fail (template);
595 
596 	if ((label->priv->template == NULL) ||
597             !lgl_template_do_templates_match (template, label->priv->template))
598         {
599 
600                 if ( checkpoint )
601                 {
602                         gl_label_checkpoint (label, _("Label properties"));
603                 }
604 
605 		lgl_template_free (label->priv->template);
606 		label->priv->template = lgl_template_dup (template);
607 
608                 do_modify (label);
609 		g_signal_emit (G_OBJECT(label), signals[SIZE_CHANGED], 0);
610 
611                 name = lgl_template_get_name (template);
612                 gl_template_history_model_add_name (gl_template_history, name);
613                 g_free (name);
614 	}
615 
616 	gl_debug (DEBUG_LABEL, "END");
617 }
618 
619 
620 /****************************************************************************/
621 /* get template.                                                            */
622 /****************************************************************************/
623 const lglTemplate *
gl_label_get_template(glLabel * label)624 gl_label_get_template (glLabel            *label)
625 {
626         return label->priv->template;
627 }
628 
629 
630 /****************************************************************************/
631 /* set rotate flag.                                                         */
632 /****************************************************************************/
633 void
gl_label_set_rotate_flag(glLabel * label,gboolean rotate_flag,gboolean checkpoint)634 gl_label_set_rotate_flag (glLabel *label,
635 			  gboolean rotate_flag,
636                           gboolean checkpoint)
637 {
638 	gl_debug (DEBUG_LABEL, "START");
639 
640 	g_return_if_fail (label && GL_IS_LABEL (label));
641 
642 	if (rotate_flag != label->priv->rotate_flag)
643         {
644                 if ( checkpoint )
645                 {
646                         gl_label_checkpoint (label, _("Label properties"));
647                 }
648 
649 		label->priv->rotate_flag = rotate_flag;
650 
651                 do_modify (label);
652 		g_signal_emit (G_OBJECT(label), signals[SIZE_CHANGED], 0);
653 	}
654 
655 	gl_debug (DEBUG_LABEL, "END");
656 }
657 
658 
659 /****************************************************************************/
660 /* Get rotate flag.                                                         */
661 /****************************************************************************/
662 gboolean
gl_label_get_rotate_flag(glLabel * label)663 gl_label_get_rotate_flag (glLabel       *label)
664 {
665         return label->priv->rotate_flag;
666 }
667 
668 
669 /****************************************************************************/
670 /* Get label size.                                                          */
671 /****************************************************************************/
672 void
gl_label_get_size(glLabel * label,gdouble * w,gdouble * h)673 gl_label_get_size (glLabel *label,
674 		   gdouble *w,
675 		   gdouble *h)
676 {
677 	lglTemplate            *template;
678 	const lglTemplateFrame *frame;
679 
680 	gl_debug (DEBUG_LABEL, "START");
681 
682 	g_return_if_fail (label && GL_IS_LABEL (label));
683 
684 	template = label->priv->template;
685 	if ( !template )
686         {
687 		gl_debug (DEBUG_LABEL, "END -- template NULL");
688 		*w = *h = 0;
689 		return;
690 	}
691         frame = (lglTemplateFrame *)template->frames->data;
692 
693 	if (!label->priv->rotate_flag)
694         {
695 		lgl_template_frame_get_size (frame, w, h);
696 	}
697         else
698         {
699 		lgl_template_frame_get_size (frame, h, w);
700 	}
701 
702 	gl_debug (DEBUG_LABEL, "END");
703 }
704 
705 
706 /****************************************************************************/
707 /* get string with info about dimensions                                    */
708 /****************************************************************************/
709 gchar *
gl_label_get_dimensions_string(glLabel * label)710 gl_label_get_dimensions_string (glLabel *label)
711 {
712 	gchar                  *dims;
713 	lglTemplate            *template;
714 	const lglTemplateFrame *frame;
715 	lglUnits                units;
716 	gdouble                 units_per_point;
717 	gchar                  *s1 = NULL;
718 	gchar                  *s2 = NULL;
719 	gchar                  *s3 = NULL;
720 
721 	gl_debug (DEBUG_LABEL, "START");
722 
723 	g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
724 
725 	template = label->priv->template;
726 	if (!template)
727 		return g_strdup("");
728         frame = (lglTemplateFrame *)template->frames->data;
729 	units = gl_prefs_model_get_units (gl_prefs);
730 	units_per_point = lgl_units_get_units_per_point (units);
731 
732 	switch (frame->shape)
733 	{
734 	case LGL_TEMPLATE_FRAME_SHAPE_RECT:
735 		if (units == LGL_UNITS_INCH)
736 		{
737 			s1 = lgl_str_format_fraction (frame->rect.w*units_per_point);
738 			s2 = lgl_str_format_fraction (frame->rect.h*units_per_point);
739 			s3 = lgl_str_format_fraction (frame->rect.r*units_per_point);
740 		}
741 		else
742 		{
743 			s1 = g_strdup_printf ("%.5g", frame->rect.w*units_per_point);
744 			s2 = g_strdup_printf ("%.5g", frame->rect.h*units_per_point);
745 			s3 = g_strdup_printf ("%.5g", frame->rect.r*units_per_point);
746 		}
747 		if (frame->rect.r == 0)
748 			/*Translators: A rectangular label dimensions. first param is numeric value*/
749 			/* of width, second is numeric value of height and third is unit. Example:*/
750 			/*"60 × 22.5 mm (width / height)"*/
751 			dims = g_strdup_printf (_("%s × %s %s (width × height)"),
752 			                        s1, s2, lgl_units_get_name (units));
753 		else
754 			/*Translators: A rounded rectangular label dimensions. first param is numeric*/
755 			/*value of width, second is numeric value of height, third is numeric value*/
756 			/*of round and fourth is unit. Example:*/
757 			/*"50 × 30 / 1.5 mm (width × height / round)"*/
758 			dims = g_strdup_printf (_("%s × %s / %s %s (width × height / round)"),
759 			                        s1, s2, s3, lgl_units_get_name (units));
760 		break;
761 
762 	case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
763 		if (units == LGL_UNITS_INCH)
764 		{
765 			s1 = lgl_str_format_fraction (frame->ellipse.w*units_per_point);
766 			s2 = lgl_str_format_fraction (frame->ellipse.h*units_per_point);
767 		}
768 		else
769 		{
770 			s1 = g_strdup_printf ("%.5g", frame->ellipse.w*units_per_point);
771 			s2 = g_strdup_printf ("%.5g", frame->ellipse.h*units_per_point);
772 		}
773 		/*Translators: A elliptical label dimensions. first param is numeric value of*/
774 		/*width, second is numeric value of height and third is unit. Example:*/
775 		/*"60 × 22.5 mm (width / height)"*/
776 		dims = g_strdup_printf (_("%s × %s %s (width × height)"),
777 		                        s1, s2, lgl_units_get_name (units));
778 		break;
779 
780 	case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
781 		if (units == LGL_UNITS_INCH)
782 			s1 = lgl_str_format_fraction (2*frame->round.r*units_per_point);
783 		else
784 			s1 = g_strdup_printf ("%.5g", 2*frame->round.r*units_per_point);
785 		/*Translators: A round label dimensions. first param is numeric value of*/
786 		/*diameter and second is unit. Example:*/
787 		/*"120.5 mm (diameter)"*/
788 		dims = g_strdup_printf (_("%s %s (diameter)"),
789 		                        s1, lgl_units_get_name (units));
790 		break;
791 
792 	case LGL_TEMPLATE_FRAME_SHAPE_CD:
793 		if (units == LGL_UNITS_INCH)
794 		{
795 			s1 = lgl_str_format_fraction (2*frame->cd.r1*units_per_point);
796 			s2 = lgl_str_format_fraction (2*frame->cd.r2*units_per_point);
797 		}
798 		else
799 		{
800 			s1 = g_strdup_printf ("%.5g", 2*frame->cd.r1*units_per_point);
801 			s2 = g_strdup_printf ("%.5g", 2*frame->cd.r2*units_per_point);
802 		}
803 		/*Translators: A CD/DVD label dimensions. first param is numeric value of*/
804 		/*diameter, second is numeric value of hole and third is unit. Example:*/
805 		/*"120.5 / 30 mm (diameter / hole)"*/
806 		dims = g_strdup_printf (_("%s / %s %s (diameter / hole)"),
807 		                        s1, s2, lgl_units_get_name (units));
808 		break;
809 	}
810 
811 	g_free (s1);
812 	g_free (s2);
813 	g_free (s3);
814 
815 	gl_debug (DEBUG_LABEL, "END");
816 
817 	return dims;
818 }
819 
820 
821 /****************************************************************************/
822 /* set merge information structure.                                         */
823 /****************************************************************************/
824 void
gl_label_set_merge(glLabel * label,glMerge * merge,gboolean checkpoint)825 gl_label_set_merge (glLabel *label,
826 		    glMerge *merge,
827                     gboolean checkpoint)
828 {
829 	gl_debug (DEBUG_LABEL, "START");
830 
831 	g_return_if_fail (label && GL_IS_LABEL (label));
832 
833         if ( checkpoint )
834         {
835                 gl_label_checkpoint (label, _("Merge properties"));
836         }
837 
838 	if ( label->priv->merge != NULL )
839         {
840 		g_object_unref (G_OBJECT(label->priv->merge));
841 	}
842 	label->priv->merge = gl_merge_dup (merge);
843 
844         do_modify (label);
845 	g_signal_emit (G_OBJECT(label), signals[MERGE_CHANGED], 0);
846 
847 	gl_debug (DEBUG_LABEL, "END");
848 }
849 
850 
851 /****************************************************************************/
852 /* Get merge information structure.                                         */
853 /****************************************************************************/
854 glMerge *
gl_label_get_merge(glLabel * label)855 gl_label_get_merge (glLabel *label)
856 {
857 	gl_debug (DEBUG_LABEL, "START");
858 
859 	g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
860 
861 	gl_debug (DEBUG_LABEL, "END");
862 
863 	return gl_merge_dup (label->priv->merge);
864 }
865 
866 
867 /****************************************************************************/
868 /* Get pixbuf cache.                                                        */
869 /****************************************************************************/
870 GHashTable *
gl_label_get_pixbuf_cache(glLabel * label)871 gl_label_get_pixbuf_cache (glLabel       *label)
872 {
873 	return label->priv->pixbuf_cache;
874 }
875 
876 
877 /****************************************************************************/
878 /* Get svg cache.                                                           */
879 /****************************************************************************/
880 GHashTable *
gl_label_get_svg_cache(glLabel * label)881 gl_label_get_svg_cache (glLabel       *label)
882 {
883 	return label->priv->svg_cache;
884 }
885 
886 
887 /*****************************************************************************/
888 /* Add object to label.                                                      */
889 /*****************************************************************************/
890 void
gl_label_add_object(glLabel * label,glLabelObject * object)891 gl_label_add_object (glLabel       *label,
892 		     glLabelObject *object)
893 {
894 	gl_debug (DEBUG_LABEL, "START");
895 
896 	g_return_if_fail (label && GL_IS_LABEL (label));
897 	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
898 
899 	gl_label_object_set_parent (object, label);
900 	label->priv->object_list = g_list_append (label->priv->object_list, object);
901 
902         g_signal_connect (G_OBJECT (object), "changed",
903                           G_CALLBACK (object_changed_cb), label);
904         g_signal_connect (G_OBJECT (object), "moved",
905                           G_CALLBACK (object_moved_cb), label);
906 
907         do_modify (label);
908 
909 	gl_debug (DEBUG_LABEL, "END");
910 }
911 
912 
913 /*****************************************************************************/
914 /* Delete object from label.                                                 */
915 /*****************************************************************************/
916 void
gl_label_delete_object(glLabel * label,glLabelObject * object)917 gl_label_delete_object (glLabel       *label,
918                         glLabelObject *object)
919 {
920 	gl_debug (DEBUG_LABEL, "START");
921 
922 	g_return_if_fail (label && GL_IS_LABEL (label));
923 	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
924 
925         label->priv->object_list = g_list_remove (label->priv->object_list, object);
926 
927         g_signal_handlers_disconnect_by_func (G_OBJECT (object),
928                                               G_CALLBACK (object_changed_cb), label);
929         g_signal_handlers_disconnect_by_func (G_OBJECT (object),
930                                               G_CALLBACK (object_moved_cb), label);
931         g_object_unref (object);
932 
933         do_modify (label);
934 
935 	gl_debug (DEBUG_LABEL, "END");
936 }
937 
938 
939 /*****************************************************************************/
940 /* Get object list.                                                          */
941 /*****************************************************************************/
942 const GList *
gl_label_get_object_list(glLabel * label)943 gl_label_get_object_list (glLabel       *label)
944 {
945         return label->priv->object_list;
946 }
947 
948 
949 /*****************************************************************************/
950 /* Select object.                                                            */
951 /*****************************************************************************/
952 void
gl_label_select_object(glLabel * label,glLabelObject * object)953 gl_label_select_object (glLabel       *label,
954                         glLabelObject *object)
955 {
956 	gl_debug (DEBUG_LABEL, "START");
957 
958 	g_return_if_fail (label && GL_IS_LABEL (label));
959 	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
960 
961         gl_label_object_select (object);
962 
963         label->priv->cp_cleared_flag = TRUE;
964 	g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
965 
966 	gl_debug (DEBUG_LABEL, "END");
967 }
968 
969 
970 /*****************************************************************************/
971 /* Unselect object.                                                          */
972 /*****************************************************************************/
973 void
gl_label_unselect_object(glLabel * label,glLabelObject * object)974 gl_label_unselect_object (glLabel       *label,
975                           glLabelObject *object)
976 {
977 	gl_debug (DEBUG_LABEL, "START");
978 
979 	g_return_if_fail (label && GL_IS_LABEL (label));
980 	g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
981 
982         gl_label_object_unselect (object);
983 
984         label->priv->cp_cleared_flag = TRUE;
985 	g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
986 
987 	gl_debug (DEBUG_LABEL, "END");
988 }
989 
990 
991 /*****************************************************************************/
992 /* Select all objects.                                                       */
993 /*****************************************************************************/
994 void
gl_label_select_all(glLabel * label)995 gl_label_select_all (glLabel       *label)
996 {
997 	GList         *p;
998         glLabelObject *object;
999 
1000 	gl_debug (DEBUG_LABEL, "START");
1001 
1002 	g_return_if_fail (label && GL_IS_LABEL (label));
1003 
1004         for ( p = label->priv->object_list; p != NULL; p = p->next )
1005         {
1006                 object = GL_LABEL_OBJECT (p->data);
1007 
1008                 gl_label_object_select (object);
1009         }
1010 
1011         label->priv->cp_cleared_flag = TRUE;
1012 	g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
1013 
1014 	gl_debug (DEBUG_LABEL, "END");
1015 }
1016 
1017 
1018 /*****************************************************************************/
1019 /* Unselect all objects.                                                     */
1020 /*****************************************************************************/
1021 void
gl_label_unselect_all(glLabel * label)1022 gl_label_unselect_all (glLabel       *label)
1023 {
1024 	GList         *p;
1025         glLabelObject *object;
1026 
1027 	gl_debug (DEBUG_LABEL, "START");
1028 
1029 	g_return_if_fail (label && GL_IS_LABEL (label));
1030 
1031         for ( p = label->priv->object_list; p != NULL; p = p->next )
1032         {
1033                 object = GL_LABEL_OBJECT (p->data);
1034 
1035                 gl_label_object_unselect (object);
1036         }
1037 
1038         label->priv->cp_cleared_flag = TRUE;
1039 	g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
1040 
1041 	gl_debug (DEBUG_LABEL, "END");
1042 }
1043 
1044 
1045 /*****************************************************************************/
1046 /* Select all objects contained in region.                                   */
1047 /*****************************************************************************/
1048 void
gl_label_select_region(glLabel * label,glLabelRegion * region)1049 gl_label_select_region (glLabel       *label,
1050                         glLabelRegion *region)
1051 {
1052 	GList         *p;
1053 	glLabelObject *object;
1054         gdouble        r_x1, r_y1;
1055         gdouble        r_x2, r_y2;
1056         glLabelRegion  obj_extent;
1057 
1058 	gl_debug (DEBUG_LABEL, "START");
1059 
1060 	g_return_if_fail (label && GL_IS_LABEL (label));
1061 
1062         r_x1 = MIN (region->x1, region->x2);
1063         r_y1 = MIN (region->y1, region->y2);
1064         r_x2 = MAX (region->x1, region->x2);
1065         r_y2 = MAX (region->y1, region->y2);
1066 
1067 	for (p = label->priv->object_list; p != NULL; p = p->next)
1068         {
1069 		object = GL_LABEL_OBJECT(p->data);
1070 
1071                 gl_label_object_get_extent (object, &obj_extent);
1072                 if ((obj_extent.x1 >= r_x1) &&
1073                     (obj_extent.x2 <= r_x2) &&
1074                     (obj_extent.y1 >= r_y1) &&
1075                     (obj_extent.y2 <= r_y2))
1076                 {
1077                         gl_label_object_select (object);
1078                 }
1079 	}
1080 
1081         label->priv->cp_cleared_flag = TRUE;
1082 	g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
1083 
1084 	gl_debug (DEBUG_LABEL, "END");
1085 }
1086 
1087 
1088 /*****************************************************************************/
1089 /* Is selection empty?                                                       */
1090 /*****************************************************************************/
1091 gboolean
gl_label_is_selection_empty(glLabel * label)1092 gl_label_is_selection_empty (glLabel       *label)
1093 {
1094         GList         *p;
1095         glLabelObject *object;
1096 
1097         for ( p = label->priv->object_list; p != NULL; p = p->next )
1098         {
1099                 object = GL_LABEL_OBJECT (p->data);
1100 
1101                 if ( gl_label_object_is_selected (object) )
1102                 {
1103                         return FALSE;
1104                 }
1105         }
1106 
1107         return TRUE;
1108 }
1109 
1110 
1111 /*****************************************************************************/
1112 /* Is selection atomic?                                                      */
1113 /*****************************************************************************/
1114 gboolean
gl_label_is_selection_atomic(glLabel * label)1115 gl_label_is_selection_atomic (glLabel       *label)
1116 {
1117         GList         *p;
1118         glLabelObject *object;
1119         gint           n_selected = 0;
1120 
1121         for ( p = label->priv->object_list; p != NULL; p = p->next )
1122         {
1123                 object = GL_LABEL_OBJECT (p->data);
1124 
1125                 if ( gl_label_object_is_selected (object) )
1126                 {
1127                         n_selected++;
1128 
1129                         if (n_selected > 1)
1130                         {
1131                                 return FALSE;
1132                         }
1133                 }
1134         }
1135 
1136         return (n_selected == 1);
1137 }
1138 
1139 
1140 /*****************************************************************************/
1141 /* Get first selected object.                                                */
1142 /*****************************************************************************/
1143 glLabelObject *
gl_label_get_1st_selected_object(glLabel * label)1144 gl_label_get_1st_selected_object (glLabel  *label)
1145 {
1146         GList         *p;
1147         glLabelObject *object;
1148 
1149         for ( p = label->priv->object_list; p != NULL; p = p->next )
1150         {
1151                 object = GL_LABEL_OBJECT (p->data);
1152 
1153                 if ( gl_label_object_is_selected (object) )
1154                 {
1155                         return object;
1156                 }
1157         }
1158 
1159         return NULL;
1160 }
1161 
1162 
1163 /*****************************************************************************/
1164 /* Get list of selected objects.                                             */
1165 /*****************************************************************************/
1166 GList *
gl_label_get_selection_list(glLabel * label)1167 gl_label_get_selection_list (glLabel *label)
1168 {
1169         GList         *selection_list = NULL;
1170         GList         *p;
1171         glLabelObject *object;
1172 
1173         for ( p = label->priv->object_list; p != NULL; p = p->next )
1174         {
1175                 object = GL_LABEL_OBJECT (p->data);
1176 
1177                 if ( gl_label_object_is_selected (object) )
1178                 {
1179                         selection_list = g_list_append (selection_list, object);
1180                 }
1181         }
1182 
1183         return (selection_list);
1184 }
1185 
1186 
1187 /*****************************************************************************/
1188 /* Can text properties be set for selection?                                 */
1189 /*****************************************************************************/
1190 gboolean
gl_label_can_selection_text(glLabel * label)1191 gl_label_can_selection_text (glLabel *label)
1192 {
1193         GList         *selection_list;
1194 	GList         *p;
1195 	glLabelObject *object;
1196 
1197 	gl_debug (DEBUG_LABEL, "");
1198 
1199 	g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
1200 
1201         selection_list = gl_label_get_selection_list (label);
1202 
1203 	for (p = selection_list; p != NULL; p = p->next)
1204         {
1205 		object = GL_LABEL_OBJECT (p->data);
1206 
1207 		if (gl_label_object_can_text (object))
1208                 {
1209                         g_list_free (selection_list);
1210 			return TRUE;
1211 		}
1212 	}
1213 
1214         g_list_free (selection_list);
1215 	return FALSE;
1216 }
1217 
1218 
1219 /*****************************************************************************/
1220 /* Can fill properties be set for selection?                                 */
1221 /*****************************************************************************/
1222 gboolean
gl_label_can_selection_fill(glLabel * label)1223 gl_label_can_selection_fill (glLabel *label)
1224 {
1225         GList         *selection_list;
1226 	GList         *p;
1227 	glLabelObject *object;
1228 
1229 	gl_debug (DEBUG_LABEL, "");
1230 
1231 	g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
1232 
1233         selection_list = gl_label_get_selection_list (label);
1234 
1235 	for (p = selection_list; p != NULL; p = p->next)
1236         {
1237 		object = GL_LABEL_OBJECT (p->data);
1238 
1239 		if (gl_label_object_can_fill (object))
1240                 {
1241                         g_list_free (selection_list);
1242 			return TRUE;
1243 		}
1244 
1245 	}
1246 
1247         g_list_free (selection_list);
1248 	return FALSE;
1249 }
1250 
1251 
1252 /*****************************************************************************/
1253 /* Can line color properties be set for selection?                           */
1254 /*****************************************************************************/
1255 gboolean
gl_label_can_selection_line_color(glLabel * label)1256 gl_label_can_selection_line_color (glLabel *label)
1257 {
1258         GList         *selection_list;
1259 	GList         *p;
1260 	glLabelObject *object;
1261 
1262 	gl_debug (DEBUG_LABEL, "");
1263 
1264 	g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
1265 
1266         selection_list = gl_label_get_selection_list (label);
1267 
1268 	for (p = selection_list; p != NULL; p = p->next)
1269         {
1270 		object = GL_LABEL_OBJECT (p->data);
1271 
1272 		if (gl_label_object_can_line_color (object))
1273                 {
1274                         g_list_free (selection_list);
1275 			return TRUE;
1276 		}
1277 	}
1278 
1279         g_list_free (selection_list);
1280 	return FALSE;
1281 }
1282 
1283 
1284 /*****************************************************************************/
1285 /* Can line width properties be set for selection?                           */
1286 /*****************************************************************************/
1287 gboolean
gl_label_can_selection_line_width(glLabel * label)1288 gl_label_can_selection_line_width (glLabel *label)
1289 {
1290         GList         *selection_list;
1291 	GList         *p;
1292 	glLabelObject *object;
1293 
1294 	gl_debug (DEBUG_LABEL, "");
1295 
1296 	g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
1297 
1298         selection_list = gl_label_get_selection_list (label);
1299 
1300 	for (p = selection_list; p != NULL; p = p->next)
1301         {
1302 		object = GL_LABEL_OBJECT (p->data);
1303 
1304 		if (gl_label_object_can_line_width (object))
1305                 {
1306                         g_list_free (selection_list);
1307 			return TRUE;
1308 		}
1309 
1310 	}
1311 
1312         g_list_free (selection_list);
1313 	return FALSE;
1314 }
1315 
1316 
1317 /*****************************************************************************/
1318 /* Delete selection from label.                                              */
1319 /*****************************************************************************/
1320 void
gl_label_delete_selection(glLabel * label)1321 gl_label_delete_selection (glLabel       *label)
1322 {
1323         GList         *selection_list;
1324         GList         *p;
1325         glLabelObject *object;
1326 
1327 	gl_debug (DEBUG_LABEL, "START");
1328 
1329 	g_return_if_fail (label && GL_IS_LABEL (label));
1330 
1331         gl_label_checkpoint (label, _("Delete"));
1332 
1333         begin_selection_op (label);
1334 
1335         selection_list = gl_label_get_selection_list (label);
1336 
1337         for ( p = selection_list; p != NULL; p = p->next )
1338         {
1339                 object = GL_LABEL_OBJECT (p->data);
1340 
1341                 gl_label_delete_object (label, object);
1342         }
1343 
1344         g_list_free (selection_list);
1345 
1346         end_selection_op (label);
1347 
1348 	g_signal_emit (G_OBJECT(label), signals[SELECTION_CHANGED], 0);
1349 
1350 	gl_debug (DEBUG_LABEL, "END");
1351 }
1352 
1353 
1354 /****************************************************************************/
1355 /* Bring selection object to front/top.                                     */
1356 /****************************************************************************/
1357 void
gl_label_raise_selection_to_top(glLabel * label)1358 gl_label_raise_selection_to_top (glLabel       *label)
1359 {
1360         GList         *selection_list;
1361         GList         *p;
1362         glLabelObject *object;
1363 
1364 	gl_debug (DEBUG_LABEL, "START");
1365 
1366         gl_label_checkpoint (label, _("Bring to front"));
1367 
1368         begin_selection_op (label);
1369 
1370         selection_list = gl_label_get_selection_list (label);
1371 
1372         for ( p = selection_list; p != NULL; p = p->next )
1373         {
1374                 object = GL_LABEL_OBJECT (p->data);
1375 
1376                 label->priv->object_list = g_list_remove (label->priv->object_list, object);
1377         }
1378 
1379 	/* Move to end of list, representing front most object */
1380 	label->priv->object_list = g_list_concat (label->priv->object_list, selection_list);
1381 
1382         do_modify (label);
1383 
1384         end_selection_op (label);
1385 
1386 	gl_debug (DEBUG_LABEL, "END");
1387 }
1388 
1389 
1390 /****************************************************************************/
1391 /* Send selection to rear/bottom.                                           */
1392 /****************************************************************************/
1393 void
gl_label_lower_selection_to_bottom(glLabel * label)1394 gl_label_lower_selection_to_bottom (glLabel       *label)
1395 {
1396         GList         *selection_list;
1397         GList         *p;
1398         glLabelObject *object;
1399 
1400 	gl_debug (DEBUG_LABEL, "START");
1401 
1402         gl_label_checkpoint (label, _("Send to back"));
1403 
1404         begin_selection_op (label);
1405 
1406         selection_list = gl_label_get_selection_list (label);
1407 
1408         for ( p = selection_list; p != NULL; p = p->next )
1409         {
1410                 object = GL_LABEL_OBJECT (p->data);
1411 
1412                 label->priv->object_list = g_list_remove (label->priv->object_list, object);
1413         }
1414 
1415 	/* Move to front of list, representing rear most object */
1416 	label->priv->object_list = g_list_concat (selection_list, label->priv->object_list);
1417 
1418         do_modify (label);
1419 
1420         end_selection_op (label);
1421 
1422 	gl_debug (DEBUG_LABEL, "END");
1423 }
1424 
1425 
1426 /*****************************************************************************/
1427 /* Rotate selected objects by given angle.                                   */
1428 /*****************************************************************************/
1429 void
gl_label_rotate_selection(glLabel * label,gdouble theta_degs)1430 gl_label_rotate_selection (glLabel *label,
1431                            gdouble  theta_degs)
1432 {
1433         GList         *selection_list;
1434 	GList         *p;
1435 	glLabelObject *object;
1436 
1437 	gl_debug (DEBUG_LABEL, "START");
1438 
1439 	g_return_if_fail (label && GL_IS_LABEL (label));
1440 
1441         begin_selection_op (label);
1442 
1443         gl_label_checkpoint (label, _("Rotate"));
1444 
1445         selection_list = gl_label_get_selection_list (label);
1446 
1447         for ( p = selection_list; p != NULL; p = p->next )
1448         {
1449 		object = GL_LABEL_OBJECT (p->data);
1450 
1451 		gl_label_object_rotate (object, theta_degs);
1452 	}
1453 
1454 	g_list_free (selection_list);
1455 
1456 	do_modify (label);
1457 
1458 	end_selection_op (label);
1459 
1460 	gl_debug (DEBUG_LABEL, "END");
1461 }
1462 
1463 
1464 /*****************************************************************************/
1465 /* Rotate selected objects 90 degrees left.                                  */
1466 /*****************************************************************************/
1467 void
gl_label_rotate_selection_left(glLabel * label)1468 gl_label_rotate_selection_left (glLabel *label)
1469 {
1470         GList         *selection_list;
1471 	GList         *p;
1472 	glLabelObject *object;
1473 
1474 	gl_debug (DEBUG_LABEL, "START");
1475 
1476 	g_return_if_fail (label && GL_IS_LABEL (label));
1477 
1478         begin_selection_op (label);
1479 
1480         gl_label_checkpoint (label, _("Rotate left"));
1481 
1482         selection_list = gl_label_get_selection_list (label);
1483 
1484         for ( p = selection_list; p != NULL; p = p->next )
1485         {
1486 		object = GL_LABEL_OBJECT (p->data);
1487 
1488 		gl_label_object_rotate (object, -90.0);
1489 	}
1490 
1491 	g_list_free (selection_list);
1492 
1493 	do_modify (label);
1494 
1495 	end_selection_op (label);
1496 
1497 	gl_debug (DEBUG_LABEL, "END");
1498 }
1499 
1500 
1501 /*****************************************************************************/
1502 /* Rotate selected objects 90 degrees right.                                 */
1503 /*****************************************************************************/
1504 void
gl_label_rotate_selection_right(glLabel * label)1505 gl_label_rotate_selection_right (glLabel *label)
1506 {
1507         GList         *selection_list;
1508 	GList         *p;
1509 	glLabelObject *object;
1510 
1511 	gl_debug (DEBUG_LABEL, "START");
1512 
1513 	g_return_if_fail (label && GL_IS_LABEL (label));
1514 
1515         gl_label_checkpoint (label, _("Rotate right"));
1516 
1517         begin_selection_op (label);
1518 
1519         selection_list = gl_label_get_selection_list (label);
1520 
1521         for ( p = selection_list; p != NULL; p = p->next )
1522         {
1523 		object = GL_LABEL_OBJECT (p->data);
1524 
1525 		gl_label_object_rotate (object, 90.0);
1526 	}
1527 
1528 	g_list_free (selection_list);
1529 
1530 	do_modify (label);
1531 
1532 	end_selection_op (label);
1533 
1534 	gl_debug (DEBUG_LABEL, "END");
1535 }
1536 
1537 
1538 /*****************************************************************************/
1539 /* Flip selected objects horizontally.                                       */
1540 /*****************************************************************************/
1541 void
gl_label_flip_selection_horiz(glLabel * label)1542 gl_label_flip_selection_horiz (glLabel *label)
1543 {
1544         GList         *selection_list;
1545 	GList         *p;
1546 	glLabelObject *object;
1547 
1548 	gl_debug (DEBUG_LABEL, "START");
1549 
1550 	g_return_if_fail (label && GL_IS_LABEL (label));
1551 
1552         gl_label_checkpoint (label, _("Flip horizontally"));
1553 
1554         begin_selection_op (label);
1555 
1556         selection_list = gl_label_get_selection_list (label);
1557 
1558         for ( p = selection_list; p != NULL; p = p->next )
1559         {
1560 		object = GL_LABEL_OBJECT (p->data);
1561 
1562 		gl_label_object_flip_horiz (object);
1563 	}
1564 
1565 	g_list_free (selection_list);
1566 
1567 	do_modify (label);
1568 
1569 	end_selection_op (label);
1570 
1571 	gl_debug (DEBUG_LABEL, "END");
1572 }
1573 
1574 
1575 /*****************************************************************************/
1576 /* Flip selected objects vertically.                                         */
1577 /*****************************************************************************/
1578 void
gl_label_flip_selection_vert(glLabel * label)1579 gl_label_flip_selection_vert (glLabel *label)
1580 {
1581         GList         *selection_list;
1582 	GList         *p;
1583 	glLabelObject *object;
1584 
1585 	gl_debug (DEBUG_LABEL, "START");
1586 
1587 	g_return_if_fail (label && GL_IS_LABEL (label));
1588 
1589         gl_label_checkpoint (label, _("Flip vertically"));
1590 
1591         begin_selection_op (label);
1592 
1593         selection_list = gl_label_get_selection_list (label);
1594 
1595         for ( p = selection_list; p != NULL; p = p->next )
1596         {
1597 		object = GL_LABEL_OBJECT (p->data);
1598 
1599 		gl_label_object_flip_vert (object);
1600 	}
1601 
1602 	g_list_free (selection_list);
1603 
1604 	do_modify (label);
1605 
1606 	end_selection_op (label);
1607 
1608 	gl_debug (DEBUG_LABEL, "END");
1609 }
1610 
1611 
1612 /*****************************************************************************/
1613 /* Align selected objects to left most edge.                                 */
1614 /*****************************************************************************/
1615 void
gl_label_align_selection_left(glLabel * label)1616 gl_label_align_selection_left (glLabel *label)
1617 {
1618         GList         *selection_list;
1619 	GList         *p;
1620 	glLabelObject *object;
1621 	gdouble        dx, x1_min;
1622         glLabelRegion  obj_extent;
1623 
1624 	gl_debug (DEBUG_LABEL, "START");
1625 
1626 	g_return_if_fail (label && GL_IS_LABEL (label));
1627 
1628 	g_return_if_fail (!gl_label_is_selection_empty (label) &&
1629 			  !gl_label_is_selection_atomic (label));
1630 
1631         gl_label_checkpoint (label, _("Align left"));
1632 
1633         begin_selection_op (label);
1634 
1635         selection_list = gl_label_get_selection_list (label);
1636 
1637 	/* find left most edge */
1638 	p = selection_list;
1639 	object = GL_LABEL_OBJECT (p->data);
1640 
1641 	gl_label_object_get_extent (object, &obj_extent);
1642         x1_min = obj_extent.x1;
1643 	for (p = p->next; p != NULL; p = p->next)
1644         {
1645 		object = GL_LABEL_OBJECT (p->data);
1646 
1647 		gl_label_object_get_extent (object, &obj_extent);
1648 		if ( obj_extent.x1 < x1_min ) x1_min = obj_extent.x1;
1649 	}
1650 
1651 	/* now adjust the object positions to line up the left edges */
1652 	for (p = selection_list; p != NULL; p = p->next)
1653         {
1654 		object = GL_LABEL_OBJECT (p->data);
1655 
1656 		gl_label_object_get_extent (object, &obj_extent);
1657 		dx = x1_min - obj_extent.x1;
1658 		gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1659 	}
1660 
1661         g_list_free (selection_list);
1662 
1663         end_selection_op (label);
1664 
1665 	gl_debug (DEBUG_LABEL, "END");
1666 }
1667 
1668 
1669 /*****************************************************************************/
1670 /* Align selected objects to right most edge.                                */
1671 /*****************************************************************************/
1672 void
gl_label_align_selection_right(glLabel * label)1673 gl_label_align_selection_right (glLabel *label)
1674 {
1675         GList         *selection_list;
1676 	GList         *p;
1677 	glLabelObject *object;
1678 	gdouble        dx, x2_max;
1679         glLabelRegion  obj_extent;
1680 
1681 	gl_debug (DEBUG_LABEL, "START");
1682 
1683 	g_return_if_fail (label && GL_IS_LABEL (label));
1684 
1685 	g_return_if_fail (!gl_label_is_selection_empty (label) &&
1686 			  !gl_label_is_selection_atomic (label));
1687 
1688         gl_label_checkpoint (label, _("Align right"));
1689 
1690         begin_selection_op (label);
1691 
1692         selection_list = gl_label_get_selection_list (label);
1693 
1694 	/* find left most edge */
1695 	p = selection_list;
1696 	object = GL_LABEL_OBJECT (p->data);
1697 
1698 	gl_label_object_get_extent (object, &obj_extent);
1699         x2_max = obj_extent.x2;
1700 	for (p = p->next; p != NULL; p = p->next)
1701         {
1702 		object = GL_LABEL_OBJECT (p->data);
1703 
1704 		gl_label_object_get_extent (object, &obj_extent);
1705 		if ( obj_extent.x2 > x2_max ) x2_max = obj_extent.x2;
1706 	}
1707 
1708 	/* now adjust the object positions to line up the left edges */
1709 	for (p = selection_list; p != NULL; p = p->next)
1710         {
1711 		object = GL_LABEL_OBJECT (p->data);
1712 
1713 		gl_label_object_get_extent (object, &obj_extent);
1714 		dx = x2_max - obj_extent.x2;
1715 		gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1716 	}
1717 
1718         g_list_free (selection_list);
1719 
1720         end_selection_op (label);
1721 
1722 	gl_debug (DEBUG_LABEL, "END");
1723 }
1724 
1725 
1726 /*****************************************************************************/
1727 /* Align selected objects to horizontal center of objects.                   */
1728 /*****************************************************************************/
1729 void
gl_label_align_selection_hcenter(glLabel * label)1730 gl_label_align_selection_hcenter (glLabel *label)
1731 {
1732         GList         *selection_list;
1733 	GList         *p;
1734 	glLabelObject *object;
1735 	gdouble        dx;
1736 	gdouble        dxmin;
1737 	gdouble        xsum, xavg;
1738         glLabelRegion  obj_extent;
1739 	gdouble        xcenter;
1740 	gint           n;
1741 
1742 	gl_debug (DEBUG_LABEL, "START");
1743 
1744 	g_return_if_fail (label && GL_IS_LABEL (label));
1745 
1746 	g_return_if_fail (!gl_label_is_selection_empty (label) &&
1747 			  !gl_label_is_selection_atomic (label));
1748 
1749         gl_label_checkpoint (label, _("Align horizontal center"));
1750 
1751         begin_selection_op (label);
1752 
1753         selection_list = gl_label_get_selection_list (label);
1754 
1755 	/* find average center of objects */
1756 	xsum = 0.0;
1757 	n = 0;
1758 	for (p = selection_list; p != NULL; p = p->next)
1759         {
1760 		object = GL_LABEL_OBJECT (p->data);
1761 
1762 		gl_label_object_get_extent (object, &obj_extent);
1763 		xsum += (obj_extent.x1 + obj_extent.x2) / 2.0;
1764 		n++;
1765 	}
1766 	xavg = xsum / n;
1767 
1768 	/* find center of object closest to average center */
1769 	p = selection_list;
1770 	object = GL_LABEL_OBJECT (p->data);
1771 
1772 	gl_label_object_get_extent (object, &obj_extent);
1773 	dxmin = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
1774 	xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
1775 	for (p = p->next; p != NULL; p = p->next)
1776         {
1777 		object = GL_LABEL_OBJECT (p->data);
1778 
1779 		gl_label_object_get_extent (object, &obj_extent);
1780 		dx = fabs (xavg - (obj_extent.x1 + obj_extent.x2)/2.0);
1781 		if ( dx < dxmin )
1782                 {
1783 			dxmin = dx;
1784 			xcenter = (obj_extent.x1 + obj_extent.x2)/2.0;
1785 		}
1786 	}
1787 
1788 	/* now adjust the object positions to line up this center */
1789 	for (p = selection_list; p != NULL; p = p->next)
1790         {
1791 		object = GL_LABEL_OBJECT (p->data);
1792 
1793 		gl_label_object_get_extent (object, &obj_extent);
1794 		dx = xcenter - (obj_extent.x1 + obj_extent.x2)/2.0;
1795 		gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
1796 	}
1797 
1798         g_list_free (selection_list);
1799 
1800         end_selection_op (label);
1801 
1802 	gl_debug (DEBUG_LABEL, "END");
1803 }
1804 
1805 
1806 /*****************************************************************************/
1807 /* Align selected objects to top most edge.                                  */
1808 /*****************************************************************************/
1809 void
gl_label_align_selection_top(glLabel * label)1810 gl_label_align_selection_top (glLabel *label)
1811 {
1812         GList         *selection_list;
1813 	GList         *p;
1814 	glLabelObject *object;
1815 	gdouble        dy, y1_min;
1816         glLabelRegion  obj_extent;
1817 
1818 	gl_debug (DEBUG_LABEL, "START");
1819 
1820 	g_return_if_fail (label && GL_IS_LABEL (label));
1821 
1822 	g_return_if_fail (!gl_label_is_selection_empty (label) &&
1823 			  !gl_label_is_selection_atomic (label));
1824 
1825         gl_label_checkpoint (label, _("Align tops"));
1826 
1827         begin_selection_op (label);
1828 
1829         selection_list = gl_label_get_selection_list (label);
1830 
1831 	/* find top most edge */
1832 	p = selection_list;
1833 	object = GL_LABEL_OBJECT (p->data);
1834 
1835 	gl_label_object_get_extent (object, &obj_extent);
1836         y1_min = obj_extent.y1;
1837 	for (p = p->next; p != NULL; p = p->next)
1838         {
1839 		object = GL_LABEL_OBJECT (p->data);
1840 
1841 		gl_label_object_get_extent (object, &obj_extent);
1842 		if ( obj_extent.y1 < y1_min ) y1_min = obj_extent.y1;
1843 	}
1844 
1845 	/* now adjust the object positions to line up the top edges */
1846 	for (p = selection_list; p != NULL; p = p->next)
1847         {
1848 		object = GL_LABEL_OBJECT (p->data);
1849 
1850 		gl_label_object_get_extent (object, &obj_extent);
1851 		dy = y1_min - obj_extent.y1;
1852 		gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1853 	}
1854 
1855         g_list_free (selection_list);
1856 
1857         end_selection_op (label);
1858 
1859 	gl_debug (DEBUG_LABEL, "END");
1860 }
1861 
1862 
1863 /*****************************************************************************/
1864 /* Align selected objects to bottom most edge.                               */
1865 /*****************************************************************************/
1866 void
gl_label_align_selection_bottom(glLabel * label)1867 gl_label_align_selection_bottom (glLabel *label)
1868 {
1869         GList         *selection_list;
1870 	GList         *p;
1871 	glLabelObject *object;
1872 	gdouble        dy, y2_max;
1873         glLabelRegion  obj_extent;
1874 
1875 	gl_debug (DEBUG_LABEL, "START");
1876 
1877 	g_return_if_fail (label && GL_IS_LABEL (label));
1878 
1879 	g_return_if_fail (!gl_label_is_selection_empty (label) &&
1880 			  !gl_label_is_selection_atomic (label));
1881 
1882         gl_label_checkpoint (label, _("Align bottoms"));
1883 
1884         begin_selection_op (label);
1885 
1886         selection_list = gl_label_get_selection_list (label);
1887 
1888 	/* find bottom most edge */
1889 	p = selection_list;
1890 	object = GL_LABEL_OBJECT (p->data);
1891 
1892 	gl_label_object_get_extent (object, &obj_extent);
1893         y2_max = obj_extent.y2;
1894 	for (p = p->next; p != NULL; p = p->next)
1895         {
1896 		object = GL_LABEL_OBJECT (p->data);
1897 
1898 		gl_label_object_get_extent (object, &obj_extent);
1899 		if ( obj_extent.y2 > y2_max ) y2_max = obj_extent.y2;
1900 	}
1901 
1902 	/* now adjust the object positions to line up the bottom edges */
1903 	for (p = selection_list; p != NULL; p = p->next)
1904         {
1905 		object = GL_LABEL_OBJECT (p->data);
1906 
1907 		gl_label_object_get_extent (object, &obj_extent);
1908 		dy = y2_max - obj_extent.y2;
1909 		gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1910 	}
1911 
1912         g_list_free (selection_list);
1913 
1914         end_selection_op (label);
1915 
1916 	gl_debug (DEBUG_LABEL, "END");
1917 }
1918 
1919 
1920 /*****************************************************************************/
1921 /* Align selected objects to viertical center of objects.                    */
1922 /*****************************************************************************/
1923 void
gl_label_align_selection_vcenter(glLabel * label)1924 gl_label_align_selection_vcenter (glLabel *label)
1925 {
1926         GList         *selection_list;
1927 	GList         *p;
1928 	glLabelObject *object;
1929 	gdouble        dy;
1930 	gdouble        dymin;
1931 	gdouble        ysum, yavg;
1932         glLabelRegion  obj_extent;
1933 	gdouble        ycenter;
1934 	gint           n;
1935 
1936 	gl_debug (DEBUG_LABEL, "START");
1937 
1938 	g_return_if_fail (label && GL_IS_LABEL (label));
1939 
1940 	g_return_if_fail (!gl_label_is_selection_empty (label) &&
1941 			  !gl_label_is_selection_atomic (label));
1942 
1943         gl_label_checkpoint (label, _("Align vertical center"));
1944 
1945         begin_selection_op (label);
1946 
1947         selection_list = gl_label_get_selection_list (label);
1948 
1949 	/* find average center of objects */
1950 	ysum = 0.0;
1951 	n = 0;
1952 	for (p = selection_list; p != NULL; p = p->next)
1953         {
1954 		object = GL_LABEL_OBJECT (p->data);
1955 
1956 		gl_label_object_get_extent (object, &obj_extent);
1957 		ysum += (obj_extent.y1 + obj_extent.y2) / 2.0;
1958 		n++;
1959 	}
1960 	yavg = ysum / n;
1961 
1962 	/* find center of object closest to average center */
1963 	p = selection_list;
1964 	object = GL_LABEL_OBJECT (p->data);
1965 
1966 	gl_label_object_get_extent (object, &obj_extent);
1967 	dymin = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
1968 	ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
1969 	for (p = p->next; p != NULL; p = p->next)
1970         {
1971 		object = GL_LABEL_OBJECT (p->data);
1972 
1973 		gl_label_object_get_extent (object, &obj_extent);
1974 		dy = fabs (yavg - (obj_extent.y1 + obj_extent.y2)/2.0);
1975 		if ( dy < dymin )
1976                 {
1977 			dymin = dy;
1978 			ycenter = (obj_extent.y1 + obj_extent.y2)/2.0;
1979 		}
1980 	}
1981 
1982 	/* now adjust the object positions to line up this center */
1983 	for (p = selection_list; p != NULL; p = p->next)
1984         {
1985 		object = GL_LABEL_OBJECT (p->data);
1986 
1987 		gl_label_object_get_extent (object, &obj_extent);
1988 		dy = ycenter - (obj_extent.y1 + obj_extent.y2)/2.0;
1989 		gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
1990 	}
1991 
1992         g_list_free (selection_list);
1993 
1994         end_selection_op (label);
1995 
1996 	gl_debug (DEBUG_LABEL, "END");
1997 }
1998 
1999 
2000 /*****************************************************************************/
2001 /* Center selected objects to in center of label.                            */
2002 /*****************************************************************************/
2003 void
gl_label_center_selection_horiz(glLabel * label)2004 gl_label_center_selection_horiz (glLabel *label)
2005 {
2006         GList         *selection_list;
2007 	GList         *p;
2008 	glLabelObject *object;
2009 	gdouble        dx;
2010 	gdouble        x_label_center;
2011 	gdouble        x_obj_center;
2012 	glLabelRegion  obj_extent;
2013 	gdouble        w, h;
2014 
2015 	gl_debug (DEBUG_LABEL, "START");
2016 
2017 	g_return_if_fail (label && GL_IS_LABEL (label));
2018 
2019 	g_return_if_fail (!gl_label_is_selection_empty (label));
2020 
2021         gl_label_checkpoint (label, _("Center horizontally"));
2022 
2023         begin_selection_op (label);
2024 
2025 	gl_label_get_size (label, &w, &h);
2026 	x_label_center = w / 2.0;
2027 
2028 	/* adjust the object positions */
2029         selection_list = gl_label_get_selection_list (label);
2030 	for (p = selection_list; p != NULL; p = p->next)
2031         {
2032 		object = GL_LABEL_OBJECT (p->data);
2033 
2034 		gl_label_object_get_extent (object, &obj_extent);
2035 		x_obj_center = (obj_extent.x1 + obj_extent.x2) / 2.0;
2036 		dx = x_label_center - x_obj_center;
2037 		gl_label_object_set_position_relative (object, dx, 0.0, FALSE);
2038 	}
2039         g_list_free (selection_list);
2040 
2041         end_selection_op (label);
2042 
2043 	gl_debug (DEBUG_LABEL, "END");
2044 }
2045 
2046 
2047 /*****************************************************************************/
2048 /* Center selected objects to in center of label.                            */
2049 /*****************************************************************************/
2050 void
gl_label_center_selection_vert(glLabel * label)2051 gl_label_center_selection_vert (glLabel *label)
2052 {
2053         GList         *selection_list;
2054 	GList         *p;
2055 	glLabelObject *object;
2056 	gdouble        dy;
2057 	gdouble        y_label_center;
2058 	gdouble        y_obj_center;
2059 	glLabelRegion  obj_extent;
2060 	gdouble        w, h;
2061 
2062 	gl_debug (DEBUG_LABEL, "START");
2063 
2064 	g_return_if_fail (label && GL_IS_LABEL (label));
2065 
2066 	g_return_if_fail (!gl_label_is_selection_empty (label));
2067 
2068         gl_label_checkpoint (label, _("Center vertically"));
2069 
2070         begin_selection_op (label);
2071 
2072 	gl_label_get_size (label, &w, &h);
2073 	y_label_center = h / 2.0;
2074 
2075 	/* adjust the object positions */
2076         selection_list = gl_label_get_selection_list (label);
2077 	for (p = selection_list; p != NULL; p = p->next)
2078         {
2079 		object = GL_LABEL_OBJECT (p->data);
2080 
2081 		gl_label_object_get_extent (object, &obj_extent);
2082 		y_obj_center = (obj_extent.y1 + obj_extent.y2) / 2.0;
2083 		dy = y_label_center - y_obj_center;
2084 		gl_label_object_set_position_relative (object, 0.0, dy, FALSE);
2085 	}
2086         g_list_free (selection_list);
2087 
2088         end_selection_op (label);
2089 
2090 	gl_debug (DEBUG_LABEL, "END");
2091 }
2092 
2093 
2094 /*****************************************************************************/
2095 /* Move selected objects                                                     */
2096 /*****************************************************************************/
2097 void
gl_label_move_selection(glLabel * label,gdouble dx,gdouble dy)2098 gl_label_move_selection (glLabel  *label,
2099                          gdouble   dx,
2100                          gdouble   dy)
2101 {
2102         GList         *selection_list;
2103 	GList         *p;
2104 	glLabelObject *object;
2105 
2106 	gl_debug (DEBUG_LABEL, "START");
2107 
2108 	g_return_if_fail (label && GL_IS_LABEL (label));
2109 
2110         begin_selection_op (label);
2111 
2112         selection_list = gl_label_get_selection_list (label);
2113 
2114 	for (p = selection_list; p != NULL; p = p->next)
2115         {
2116 		object = GL_LABEL_OBJECT (p->data);
2117 
2118 		gl_label_object_set_position_relative (object, dx, dy, TRUE);
2119 	}
2120 
2121         g_list_free (selection_list);
2122 
2123         end_selection_op (label);
2124 
2125 	gl_debug (DEBUG_LABEL, "END");
2126 }
2127 
2128 
2129 /*****************************************************************************/
2130 /* Set font family for all text contained in selected objects.               */
2131 /*****************************************************************************/
2132 void
gl_label_set_selection_font_family(glLabel * label,const gchar * font_family)2133 gl_label_set_selection_font_family (glLabel      *label,
2134                                     const gchar  *font_family)
2135 {
2136         GList         *selection_list;
2137 	GList         *p;
2138 	glLabelObject *object;
2139 
2140 	gl_debug (DEBUG_LABEL, "START");
2141 
2142 	g_return_if_fail (label && GL_IS_LABEL (label));
2143 
2144         begin_selection_op (label);
2145 
2146         selection_list = gl_label_get_selection_list (label);
2147 
2148 	for (p = selection_list; p != NULL; p = p->next)
2149         {
2150 		object = GL_LABEL_OBJECT (p->data);
2151 		gl_label_object_set_font_family (object, font_family, TRUE);
2152 	}
2153 
2154         g_list_free (selection_list);
2155 
2156         end_selection_op (label);
2157 
2158 	gl_debug (DEBUG_LABEL, "END");
2159 }
2160 
2161 
2162 /*****************************************************************************/
2163 /* Set font size for all text contained in selected objects.                 */
2164 /*****************************************************************************/
2165 void
gl_label_set_selection_font_size(glLabel * label,gdouble font_size)2166 gl_label_set_selection_font_size (glLabel  *label,
2167                                   gdouble   font_size)
2168 {
2169         GList         *selection_list;
2170 	GList         *p;
2171 	glLabelObject *object;
2172 
2173 	gl_debug (DEBUG_LABEL, "START");
2174 
2175 	g_return_if_fail (label && GL_IS_LABEL (label));
2176 
2177         begin_selection_op (label);
2178 
2179         selection_list = gl_label_get_selection_list (label);
2180 
2181 	for (p = selection_list; p != NULL; p = p->next)
2182         {
2183 		object = GL_LABEL_OBJECT (p->data);
2184 		gl_label_object_set_font_size (object, font_size, TRUE);
2185 	}
2186 
2187         g_list_free (selection_list);
2188 
2189         end_selection_op (label);
2190 
2191 	gl_debug (DEBUG_LABEL, "END");
2192 }
2193 
2194 
2195 /*****************************************************************************/
2196 /* Set font weight for all text contained in selected objects.               */
2197 /*****************************************************************************/
2198 void
gl_label_set_selection_font_weight(glLabel * label,PangoWeight font_weight)2199 gl_label_set_selection_font_weight (glLabel      *label,
2200                                     PangoWeight   font_weight)
2201 {
2202         GList         *selection_list;
2203 	GList         *p;
2204 	glLabelObject *object;
2205 
2206 	gl_debug (DEBUG_LABEL, "START");
2207 
2208 	g_return_if_fail (label && GL_IS_LABEL (label));
2209 
2210         begin_selection_op (label);
2211 
2212         selection_list = gl_label_get_selection_list (label);
2213 
2214 	for (p = selection_list; p != NULL; p = p->next)
2215         {
2216 		object = GL_LABEL_OBJECT (p->data);
2217 		gl_label_object_set_font_weight (object, font_weight, TRUE);
2218 	}
2219 
2220         g_list_free (selection_list);
2221 
2222         end_selection_op (label);
2223 
2224 	gl_debug (DEBUG_LABEL, "END");
2225 }
2226 
2227 
2228 /*****************************************************************************/
2229 /* Set font italic flag for all text contained in selected objects.          */
2230 /*****************************************************************************/
2231 void
gl_label_set_selection_font_italic_flag(glLabel * label,gboolean font_italic_flag)2232 gl_label_set_selection_font_italic_flag (glLabel   *label,
2233                                          gboolean   font_italic_flag)
2234 {
2235         GList         *selection_list;
2236 	GList         *p;
2237 	glLabelObject *object;
2238 
2239 	gl_debug (DEBUG_LABEL, "START");
2240 
2241 	g_return_if_fail (label && GL_IS_LABEL (label));
2242 
2243         begin_selection_op (label);
2244 
2245         selection_list = gl_label_get_selection_list (label);
2246 
2247 	for (p = selection_list; p != NULL; p = p->next)
2248         {
2249 		object = GL_LABEL_OBJECT (p->data);
2250 		gl_label_object_set_font_italic_flag (object, font_italic_flag, TRUE);
2251 	}
2252 
2253         g_list_free (selection_list);
2254 
2255         end_selection_op (label);
2256 
2257 	gl_debug (DEBUG_LABEL, "END");
2258 }
2259 
2260 
2261 /*****************************************************************************/
2262 /* Set text alignment for all text contained in selected objects.            */
2263 /*****************************************************************************/
2264 void
gl_label_set_selection_text_alignment(glLabel * label,PangoAlignment text_alignment)2265 gl_label_set_selection_text_alignment (glLabel        *label,
2266                                        PangoAlignment  text_alignment)
2267 {
2268         GList         *selection_list;
2269 	GList         *p;
2270 	glLabelObject *object;
2271 
2272 	gl_debug (DEBUG_LABEL, "START");
2273 
2274 	g_return_if_fail (label && GL_IS_LABEL (label));
2275 
2276         begin_selection_op (label);
2277 
2278         selection_list = gl_label_get_selection_list (label);
2279 
2280 	for (p = selection_list; p != NULL; p = p->next)
2281         {
2282 		object = GL_LABEL_OBJECT (p->data);
2283 		gl_label_object_set_text_alignment (object, text_alignment, TRUE);
2284 	}
2285 
2286         g_list_free (selection_list);
2287 
2288         end_selection_op (label);
2289 
2290 	gl_debug (DEBUG_LABEL, "END");
2291 }
2292 
2293 
2294 /*****************************************************************************/
2295 /* Set vertical text alignment for all text contained in selected objects.   */
2296 /*****************************************************************************/
2297 void
gl_label_set_selection_text_valignment(glLabel * label,glValignment text_valignment)2298 gl_label_set_selection_text_valignment (glLabel        *label,
2299                                         glValignment    text_valignment)
2300 {
2301         GList         *selection_list;
2302 	GList         *p;
2303 	glLabelObject *object;
2304 
2305 	gl_debug (DEBUG_LABEL, "START");
2306 
2307 	g_return_if_fail (label && GL_IS_LABEL (label));
2308 
2309         begin_selection_op (label);
2310 
2311         selection_list = gl_label_get_selection_list (label);
2312 
2313 	for (p = selection_list; p != NULL; p = p->next)
2314         {
2315 		object = GL_LABEL_OBJECT (p->data);
2316 		gl_label_object_set_text_valignment (object, text_valignment, TRUE);
2317 	}
2318 
2319         g_list_free (selection_list);
2320 
2321         end_selection_op (label);
2322 
2323 	gl_debug (DEBUG_LABEL, "END");
2324 }
2325 
2326 
2327 /*****************************************************************************/
2328 /* Set text line spacing for all text contained in selected objects.         */
2329 /*****************************************************************************/
2330 void
gl_label_set_selection_text_line_spacing(glLabel * label,gdouble text_line_spacing)2331 gl_label_set_selection_text_line_spacing (glLabel  *label,
2332                                           gdouble   text_line_spacing)
2333 {
2334         GList         *selection_list;
2335 	GList         *p;
2336 	glLabelObject *object;
2337 
2338 	gl_debug (DEBUG_LABEL, "START");
2339 
2340 	g_return_if_fail (label && GL_IS_LABEL (label));
2341 
2342         begin_selection_op (label);
2343 
2344         selection_list = gl_label_get_selection_list (label);
2345 
2346 	for (p = selection_list; p != NULL; p = p->next)
2347         {
2348 		object = GL_LABEL_OBJECT (p->data);
2349 		gl_label_object_set_text_line_spacing (object, text_line_spacing, TRUE);
2350 	}
2351 
2352         g_list_free (selection_list);
2353 
2354         end_selection_op (label);
2355 
2356 	gl_debug (DEBUG_LABEL, "END");
2357 }
2358 
2359 
2360 /*****************************************************************************/
2361 /* Set text color for all text contained in selected objects.                */
2362 /*****************************************************************************/
2363 void
gl_label_set_selection_text_color(glLabel * label,glColorNode * text_color_node)2364 gl_label_set_selection_text_color (glLabel      *label,
2365                                    glColorNode  *text_color_node)
2366 {
2367         GList         *selection_list;
2368 	GList         *p;
2369 	glLabelObject *object;
2370 
2371 	gl_debug (DEBUG_LABEL, "START");
2372 
2373 	g_return_if_fail (label && GL_IS_LABEL (label));
2374 
2375         begin_selection_op (label);
2376 
2377         selection_list = gl_label_get_selection_list (label);
2378 
2379 	for (p = selection_list; p != NULL; p = p->next)
2380         {
2381 		object = GL_LABEL_OBJECT (p->data);
2382 		gl_label_object_set_text_color (object, text_color_node, TRUE);
2383 	}
2384 
2385         g_list_free (selection_list);
2386 
2387         end_selection_op (label);
2388 
2389 	gl_debug (DEBUG_LABEL, "END");
2390 }
2391 
2392 
2393 /*****************************************************************************/
2394 /* Set fill color for all selected objects.                                  */
2395 /*****************************************************************************/
2396 void
gl_label_set_selection_fill_color(glLabel * label,glColorNode * fill_color_node)2397 gl_label_set_selection_fill_color (glLabel      *label,
2398                                    glColorNode  *fill_color_node)
2399 {
2400         GList         *selection_list;
2401 	GList         *p;
2402 	glLabelObject *object;
2403 
2404 	gl_debug (DEBUG_LABEL, "START");
2405 
2406 	g_return_if_fail (label && GL_IS_LABEL (label));
2407 
2408         begin_selection_op (label);
2409 
2410         selection_list = gl_label_get_selection_list (label);
2411 
2412 	for (p = selection_list; p != NULL; p = p->next)
2413         {
2414 		object = GL_LABEL_OBJECT (p->data);
2415 		gl_label_object_set_fill_color (object, fill_color_node, TRUE);
2416 	}
2417 
2418         g_list_free (selection_list);
2419 
2420         end_selection_op (label);
2421 
2422 	gl_debug (DEBUG_LABEL, "END");
2423 }
2424 
2425 
2426 /*****************************************************************************/
2427 /* Set line color for all selected objects.                                  */
2428 /*****************************************************************************/
2429 void
gl_label_set_selection_line_color(glLabel * label,glColorNode * line_color_node)2430 gl_label_set_selection_line_color (glLabel      *label,
2431                                    glColorNode  *line_color_node)
2432 {
2433         GList         *selection_list;
2434 	GList         *p;
2435 	glLabelObject *object;
2436 
2437 	gl_debug (DEBUG_LABEL, "START");
2438 
2439 	g_return_if_fail (label && GL_IS_LABEL (label));
2440 
2441         begin_selection_op (label);
2442 
2443         selection_list = gl_label_get_selection_list (label);
2444 
2445 	for (p = selection_list; p != NULL; p = p->next)
2446         {
2447 		object = GL_LABEL_OBJECT (p->data);
2448 		gl_label_object_set_line_color (object, line_color_node, TRUE);
2449 	}
2450 
2451         g_list_free (selection_list);
2452 
2453         end_selection_op (label);
2454 
2455 	gl_debug (DEBUG_LABEL, "END");
2456 }
2457 
2458 
2459 /*****************************************************************************/
2460 /* Set line width for all selected objects.                                  */
2461 /*****************************************************************************/
2462 void
gl_label_set_selection_line_width(glLabel * label,gdouble line_width)2463 gl_label_set_selection_line_width (glLabel  *label,
2464 				  gdouble  line_width)
2465 {
2466         GList         *selection_list;
2467 	GList         *p;
2468 	glLabelObject *object;
2469 
2470 	gl_debug (DEBUG_LABEL, "START");
2471 
2472 	g_return_if_fail (label && GL_IS_LABEL (label));
2473 
2474         begin_selection_op (label);
2475 
2476         selection_list = gl_label_get_selection_list (label);
2477 
2478 	for (p = selection_list; p != NULL; p = p->next)
2479         {
2480 		object = GL_LABEL_OBJECT (p->data);
2481 		gl_label_object_set_line_width (object, line_width, TRUE);
2482 	}
2483 
2484         g_list_free (selection_list);
2485 
2486         end_selection_op (label);
2487 
2488 	gl_debug (DEBUG_LABEL, "END");
2489 }
2490 
2491 
2492 /*****************************************************************************/
2493 /* "Cut" selected items and place on clipboard.                              */
2494 /*****************************************************************************/
2495 void
gl_label_cut_selection(glLabel * label)2496 gl_label_cut_selection (glLabel       *label)
2497 {
2498 	gl_debug (DEBUG_LABEL, "START");
2499 
2500 	g_return_if_fail (label && GL_IS_LABEL (label));
2501 
2502 	gl_label_copy_selection (label);
2503 	gl_label_delete_selection (label);
2504 
2505 	gl_debug (DEBUG_LABEL, "END");
2506 }
2507 
2508 
2509 /*****************************************************************************/
2510 /* "Copy" selected items to clipboard.                                       */
2511 /*****************************************************************************/
2512 void
gl_label_copy_selection(glLabel * label)2513 gl_label_copy_selection (glLabel       *label)
2514 {
2515         GtkClipboard      *clipboard;
2516 	GList             *selection_list;
2517         glLabel           *label_copy;
2518 	GList             *p;
2519 	glLabelObject     *object;
2520         glXMLLabelStatus   status;
2521 
2522         ClipboardData     *data;
2523 
2524         static GtkTargetEntry glabels_targets[] = { { "application/glabels", 0, 0 },
2525                                                     { "text/xml",            0, 0 },
2526         };
2527 
2528         GtkTargetList  *target_list;
2529         GtkTargetEntry *target_table;
2530         gint            n_targets;
2531 
2532 	gl_debug (DEBUG_LABEL, "START");
2533 
2534 	g_return_if_fail (label && GL_IS_LABEL (label));
2535 
2536         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2537 
2538         selection_list = gl_label_get_selection_list (label);
2539 
2540 	if (selection_list)
2541         {
2542 
2543                 data = g_new0 (ClipboardData, 1);
2544 
2545                 target_list = gtk_target_list_new (glabels_targets, G_N_ELEMENTS(glabels_targets));
2546 
2547                 /*
2548                  * Serialize selection by encoding as an XML label document.
2549                  */
2550 		label_copy = GL_LABEL(gl_label_new ());
2551 
2552 		gl_label_set_template (label_copy, label->priv->template, FALSE);
2553 		gl_label_set_rotate_flag (label_copy, label->priv->rotate_flag, FALSE);
2554 
2555 		for (p = selection_list; p != NULL; p = p->next)
2556                 {
2557 			object = GL_LABEL_OBJECT (p->data);
2558 
2559 			gl_label_add_object (label_copy, gl_label_object_dup (object, label_copy));
2560 		}
2561 
2562                 data->xml_buffer = gl_xml_label_save_buffer (label_copy, &status);
2563 
2564                 g_object_unref (G_OBJECT (label_copy));
2565 
2566 
2567                 /*
2568                  * Is it an atomic text selection?  If so, also make available as text.
2569                  */
2570                 if ( gl_label_is_selection_atomic (label) &&
2571                      GL_IS_LABEL_TEXT (selection_list->data) )
2572                 {
2573                         glLabelText *text_object = GL_LABEL_TEXT (selection_list->data);
2574 
2575                         gtk_target_list_add_text_targets (target_list, 1);
2576 
2577                         data->text = gl_label_text_get_text (text_object);
2578                 }
2579 
2580 
2581                 /*
2582                  * Is it an atomic image selection?  If so, also make available as pixbuf.
2583                  */
2584                 if ( gl_label_is_selection_atomic (label) &&
2585                      GL_IS_LABEL_IMAGE (selection_list->data) )
2586                 {
2587                         glLabelImage  *image_object = GL_LABEL_IMAGE (selection_list->data);
2588                         GdkPixbuf     *pixbuf = gl_label_image_get_pixbuf (image_object, NULL);
2589 
2590                         if (pixbuf)
2591                         {
2592                                 gtk_target_list_add_image_targets (target_list, 2, TRUE);
2593                                 data->pixbuf = pixbuf;
2594                         }
2595                 }
2596 
2597 
2598                 target_table = gtk_target_table_new_from_list (target_list, &n_targets);
2599 
2600                 gtk_clipboard_set_with_data (clipboard,
2601                                              target_table, n_targets,
2602                                              (GtkClipboardGetFunc)clipboard_get_cb,
2603                                              (GtkClipboardClearFunc)clipboard_clear_cb,
2604                                              data);
2605 
2606                 gtk_target_table_free (target_table, n_targets);
2607                 gtk_target_list_unref (target_list);
2608 	}
2609 
2610 
2611         g_list_free (selection_list);
2612 
2613 	gl_debug (DEBUG_LABEL, "END");
2614 }
2615 
2616 
2617 /*****************************************************************************/
2618 /* "Paste" from clipboard.                                                   */
2619 /*****************************************************************************/
2620 void
gl_label_paste(glLabel * label)2621 gl_label_paste (glLabel       *label)
2622 {
2623         GtkClipboard  *clipboard;
2624 
2625 	gl_debug (DEBUG_LABEL, "START");
2626 
2627 	g_return_if_fail (label && GL_IS_LABEL (label));
2628 
2629         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2630 
2631         gtk_clipboard_request_targets (clipboard,
2632                                        (GtkClipboardTargetsReceivedFunc)receive_targets_cb,
2633                                        label);
2634 
2635 	gl_debug (DEBUG_LABEL, "END");
2636 }
2637 
2638 
2639 /*****************************************************************************/
2640 /* Is there anything that can be pasted?                                     */
2641 /*****************************************************************************/
2642 gboolean
gl_label_can_paste(glLabel * label)2643 gl_label_can_paste (glLabel       *label)
2644 {
2645         GtkClipboard *clipboard;
2646         gboolean      can_flag;
2647 
2648 	gl_debug (DEBUG_LABEL, "START");
2649 
2650         clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2651 
2652         can_flag = gtk_clipboard_wait_is_target_available (clipboard,
2653                                                            gdk_atom_intern("application/glabels", TRUE))
2654                 || gtk_clipboard_wait_is_text_available (clipboard)
2655                 || gtk_clipboard_wait_is_image_available (clipboard);
2656 
2657 	gl_debug (DEBUG_LABEL, "END");
2658         return can_flag;
2659 }
2660 
2661 
2662 /****************************************************************************/
2663 /* Clipboard "Get" function.                                                */
2664 /****************************************************************************/
2665 static void
clipboard_get_cb(GtkClipboard * clipboard,GtkSelectionData * selection_data,guint info,ClipboardData * data)2666 clipboard_get_cb (GtkClipboard     *clipboard,
2667                   GtkSelectionData *selection_data,
2668                   guint             info,
2669                   ClipboardData    *data)
2670 {
2671 	gl_debug (DEBUG_LABEL, "START");
2672 
2673         switch (info)
2674         {
2675 
2676         case 0:
2677                 gtk_selection_data_set (selection_data,
2678                                         gtk_selection_data_get_target (selection_data),
2679                                         8,
2680                                         (guchar *)data->xml_buffer, strlen (data->xml_buffer));
2681                 break;
2682 
2683         case 1:
2684                 gtk_selection_data_set_text (selection_data, data->text, -1);
2685                 break;
2686 
2687         case 2:
2688                 gtk_selection_data_set_pixbuf (selection_data, data->pixbuf);
2689                 break;
2690 
2691         default:
2692                 g_assert_not_reached ();
2693                 break;
2694 
2695         }
2696 
2697 	gl_debug (DEBUG_LABEL, "END");
2698 }
2699 
2700 
2701 /****************************************************************************/
2702 /* Clipboard "Clear" function.                                              */
2703 /****************************************************************************/
2704 static void
clipboard_clear_cb(GtkClipboard * clipboard,ClipboardData * data)2705 clipboard_clear_cb (GtkClipboard     *clipboard,
2706                     ClipboardData    *data)
2707 {
2708 	gl_debug (DEBUG_LABEL, "START");
2709 
2710         g_free (data->xml_buffer);
2711         g_free (data->text);
2712         if (data->pixbuf)
2713         {
2714                 g_object_unref (data->pixbuf);
2715         }
2716 
2717         g_free (data);
2718 
2719 	gl_debug (DEBUG_LABEL, "END");
2720 }
2721 
2722 
2723 /****************************************************************************/
2724 /* Deal with clipboard data.                                                */
2725 /****************************************************************************/
2726 static void
receive_targets_cb(GtkClipboard * clipboard,GdkAtom * targets,gint n_targets,glLabel * label)2727 receive_targets_cb (GtkClipboard *clipboard,
2728                     GdkAtom      *targets,
2729                     gint          n_targets,
2730                     glLabel      *label)
2731 {
2732         gint i;
2733 
2734         /*
2735          * Application/glabels
2736          */
2737         for ( i = 0; i < n_targets; i++ )
2738         {
2739                 if ( strcmp(gdk_atom_name(targets[i]), "application/glabels") == 0 )
2740                 {
2741                         gtk_clipboard_request_contents (clipboard,
2742                                                         gdk_atom_intern("application/glabels", TRUE),
2743                                                         (GtkClipboardReceivedFunc)paste_xml_received_cb,
2744                                                         label);
2745                         return;
2746                 }
2747         }
2748 
2749         /*
2750          * Text
2751          */
2752         if ( gtk_targets_include_text (targets, n_targets) )
2753         {
2754                 gtk_clipboard_request_text (clipboard,
2755                                             (GtkClipboardTextReceivedFunc)paste_text_received_cb,
2756                                             label);
2757                 return;
2758         }
2759 
2760         /*
2761          * Image
2762          */
2763         if ( gtk_targets_include_image (targets, n_targets, TRUE) )
2764         {
2765                 gtk_clipboard_request_image (clipboard,
2766                                              (GtkClipboardImageReceivedFunc)paste_image_received_cb,
2767                                              label);
2768                 return;
2769         }
2770 }
2771 
2772 
2773 /****************************************************************************/
2774 /* Paste received glabels XML callback.                                     */
2775 /****************************************************************************/
2776 static void
paste_xml_received_cb(GtkClipboard * clipboard,GtkSelectionData * selection_data,glLabel * label)2777 paste_xml_received_cb (GtkClipboard     *clipboard,
2778                        GtkSelectionData *selection_data,
2779                        glLabel          *label)
2780 {
2781         gchar            *xml_buffer;
2782         glLabel          *label_copy;
2783         glXMLLabelStatus  status;
2784         GList            *p;
2785         glLabelObject    *object, *newobject;
2786 
2787 	gl_debug (DEBUG_LABEL, "START");
2788 
2789         gl_label_checkpoint (label, _("Paste"));
2790 
2791         xml_buffer = (gchar *)gtk_selection_data_get_data (selection_data);
2792 
2793         /*
2794          * Deserialize XML label document and extract objects.
2795          */
2796         label_copy = gl_xml_label_open_buffer (xml_buffer, &status);
2797         if ( label_copy )
2798         {
2799                 gl_label_unselect_all (label);
2800 
2801                 for (p = label_copy->priv->object_list; p != NULL; p = p->next)
2802                 {
2803                         object = (glLabelObject *) p->data;
2804                         newobject = gl_label_object_dup (object, label);
2805                         gl_label_add_object( label, newobject );
2806 
2807                         gl_label_select_object (label, newobject);
2808 
2809                         gl_debug (DEBUG_LABEL, "object pasted");
2810                 }
2811 
2812                 g_object_unref (G_OBJECT (label_copy));
2813         }
2814 
2815 	gl_debug (DEBUG_LABEL, "END");
2816 }
2817 
2818 
2819 /****************************************************************************/
2820 /* Paste received text callback.                                            */
2821 /****************************************************************************/
2822 static void
paste_text_received_cb(GtkClipboard * clipboard,const gchar * text,glLabel * label)2823 paste_text_received_cb (GtkClipboard     *clipboard,
2824                         const gchar      *text,
2825                         glLabel          *label)
2826 {
2827         glLabelObject    *object;
2828 
2829 	gl_debug (DEBUG_LABEL, "START");
2830 
2831         gl_label_checkpoint (label, _("Paste"));
2832 
2833         gl_label_unselect_all (label);
2834 
2835         object = GL_LABEL_OBJECT (gl_label_text_new (label, FALSE));
2836         gl_label_text_set_text (GL_LABEL_TEXT (object), text, FALSE);
2837         gl_label_object_set_position (object, 18, 18, FALSE);
2838 
2839         gl_label_select_object (label, object);
2840 
2841 	gl_debug (DEBUG_LABEL, "END");
2842 }
2843 
2844 
2845 /****************************************************************************/
2846 /* Paste received image callback.                                           */
2847 /****************************************************************************/
2848 static void
paste_image_received_cb(GtkClipboard * clipboard,GdkPixbuf * pixbuf,glLabel * label)2849 paste_image_received_cb (GtkClipboard     *clipboard,
2850                          GdkPixbuf        *pixbuf,
2851                          glLabel          *label)
2852 {
2853         glLabelObject    *object;
2854 
2855 	gl_debug (DEBUG_LABEL, "START");
2856 
2857         gl_label_checkpoint (label, _("Paste"));
2858 
2859         gl_label_unselect_all (label);
2860 
2861         object = GL_LABEL_OBJECT (gl_label_image_new (label, FALSE));
2862         gl_label_image_set_pixbuf (GL_LABEL_IMAGE (object), pixbuf, FALSE);
2863         gl_label_object_set_position (object, 18, 18, FALSE);
2864 
2865         gl_label_select_object (label, object);
2866 
2867 	gl_debug (DEBUG_LABEL, "END");
2868 }
2869 
2870 
2871 /****************************************************************************/
2872 /* Set default font family.                                                 */
2873 /****************************************************************************/
2874 void
gl_label_set_default_font_family(glLabel * label,const gchar * font_family)2875 gl_label_set_default_font_family (glLabel     *label,
2876                                   const gchar *font_family)
2877 {
2878 	gl_debug (DEBUG_LABEL, "START");
2879 
2880 	g_return_if_fail (label && GL_IS_LABEL (label));
2881 
2882         g_free (label->priv->default_font_family);
2883 	label->priv->default_font_family = g_strdup (font_family);
2884 
2885 	gl_debug (DEBUG_LABEL, "END");
2886 }
2887 
2888 
2889 /****************************************************************************/
2890 /* Set default font size.                                                   */
2891 /****************************************************************************/
2892 void
gl_label_set_default_font_size(glLabel * label,gdouble font_size)2893 gl_label_set_default_font_size (glLabel *label,
2894                                 gdouble  font_size)
2895 {
2896 	gl_debug (DEBUG_LABEL, "START");
2897 
2898 	g_return_if_fail (label && GL_IS_LABEL (label));
2899 
2900 	label->priv->default_font_size = font_size;
2901 
2902 	gl_debug (DEBUG_LABEL, "END");
2903 }
2904 
2905 
2906 /****************************************************************************/
2907 /* Set default font weight.                                                 */
2908 /****************************************************************************/
2909 void
gl_label_set_default_font_weight(glLabel * label,PangoWeight font_weight)2910 gl_label_set_default_font_weight (glLabel     *label,
2911                                   PangoWeight  font_weight)
2912 {
2913 	gl_debug (DEBUG_LABEL, "START");
2914 
2915 	g_return_if_fail (label && GL_IS_LABEL (label));
2916 
2917 	label->priv->default_font_weight = font_weight;
2918 
2919 	gl_debug (DEBUG_LABEL, "END");
2920 }
2921 
2922 
2923 /****************************************************************************/
2924 /* Set default font italic flag.                                            */
2925 /****************************************************************************/
2926 void
gl_label_set_default_font_italic_flag(glLabel * label,gboolean font_italic_flag)2927 gl_label_set_default_font_italic_flag (glLabel  *label,
2928                                        gboolean  font_italic_flag)
2929 {
2930 	gl_debug (DEBUG_LABEL, "START");
2931 
2932 	g_return_if_fail (label && GL_IS_LABEL (label));
2933 
2934 	label->priv->default_font_italic_flag = font_italic_flag;
2935 
2936 	gl_debug (DEBUG_LABEL, "END");
2937 }
2938 
2939 
2940 /****************************************************************************/
2941 /* Set default text color.                                                  */
2942 /****************************************************************************/
2943 void
gl_label_set_default_text_color(glLabel * label,guint text_color)2944 gl_label_set_default_text_color (glLabel *label,
2945                                  guint    text_color)
2946 {
2947 	gl_debug (DEBUG_LABEL, "START");
2948 
2949 	g_return_if_fail (label && GL_IS_LABEL (label));
2950 
2951 	label->priv->default_text_color = text_color;
2952 
2953 	gl_debug (DEBUG_LABEL, "END");
2954 }
2955 
2956 
2957 /****************************************************************************/
2958 /* Set default text alignment.                                              */
2959 /****************************************************************************/
2960 void
gl_label_set_default_text_alignment(glLabel * label,PangoAlignment text_alignment)2961 gl_label_set_default_text_alignment (glLabel        *label,
2962                                      PangoAlignment  text_alignment)
2963 {
2964 	gl_debug (DEBUG_LABEL, "START");
2965 
2966 	g_return_if_fail (label && GL_IS_LABEL (label));
2967 
2968 	label->priv->default_text_alignment = text_alignment;
2969 	gl_debug (DEBUG_LABEL, "END");
2970 }
2971 
2972 
2973 /****************************************************************************/
2974 /* Set default vertical text alignment.                                     */
2975 /****************************************************************************/
2976 void
gl_label_set_default_text_valignment(glLabel * label,glValignment text_valignment)2977 gl_label_set_default_text_valignment (glLabel        *label,
2978                                       glValignment    text_valignment)
2979 {
2980 	gl_debug (DEBUG_LABEL, "START");
2981 
2982 	g_return_if_fail (label && GL_IS_LABEL (label));
2983 
2984 	label->priv->default_text_valignment = text_valignment;
2985 	gl_debug (DEBUG_LABEL, "END");
2986 }
2987 
2988 
2989 /****************************************************************************/
2990 /* Set default text line spacing.                                           */
2991 /****************************************************************************/
2992 void
gl_label_set_default_text_line_spacing(glLabel * label,gdouble text_line_spacing)2993 gl_label_set_default_text_line_spacing (glLabel *label,
2994                                         gdouble  text_line_spacing)
2995 {
2996 	gl_debug (DEBUG_LABEL, "START");
2997 
2998 	g_return_if_fail (label && GL_IS_LABEL (label));
2999 
3000 	label->priv->default_text_line_spacing = text_line_spacing;
3001 
3002 	gl_debug (DEBUG_LABEL, "END");
3003 }
3004 
3005 
3006 /****************************************************************************/
3007 /* Set default line width.                                                  */
3008 /****************************************************************************/
3009 void
gl_label_set_default_line_width(glLabel * label,gdouble line_width)3010 gl_label_set_default_line_width (glLabel *label,
3011                                  gdouble  line_width)
3012 {
3013 	gl_debug (DEBUG_LABEL, "START");
3014 
3015 	g_return_if_fail (label && GL_IS_LABEL (label));
3016 
3017 	label->priv->default_line_width = line_width;
3018 
3019 	gl_debug (DEBUG_LABEL, "END");
3020 }
3021 
3022 
3023 /****************************************************************************/
3024 /* Set default line color.                                                  */
3025 /****************************************************************************/
3026 void
gl_label_set_default_line_color(glLabel * label,guint line_color)3027 gl_label_set_default_line_color (glLabel *label,
3028                                  guint    line_color)
3029 {
3030 	gl_debug (DEBUG_LABEL, "START");
3031 
3032 	g_return_if_fail (label && GL_IS_LABEL (label));
3033 
3034 	label->priv->default_line_color = line_color;
3035 
3036 	gl_debug (DEBUG_LABEL, "END");
3037 }
3038 
3039 
3040 /****************************************************************************/
3041 /* Set default fill color.                                                  */
3042 /****************************************************************************/
3043 void
gl_label_set_default_fill_color(glLabel * label,guint fill_color)3044 gl_label_set_default_fill_color (glLabel *label,
3045                                  guint    fill_color)
3046 {
3047 	gl_debug (DEBUG_LABEL, "START");
3048 
3049 	g_return_if_fail (label && GL_IS_LABEL (label));
3050 
3051 	label->priv->default_fill_color = fill_color;
3052 
3053 	gl_debug (DEBUG_LABEL, "END");
3054 }
3055 
3056 
3057 /****************************************************************************/
3058 /* Get default font family.                                                 */
3059 /****************************************************************************/
3060 gchar *
gl_label_get_default_font_family(glLabel * label)3061 gl_label_get_default_font_family (glLabel *label)
3062 {
3063 	gl_debug (DEBUG_LABEL, "START");
3064 
3065 	g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
3066 
3067 	gl_debug (DEBUG_LABEL, "END");
3068 
3069 	return g_strdup (label->priv->default_font_family);
3070 }
3071 
3072 
3073 /****************************************************************************/
3074 /* Get default font size.                                                   */
3075 /****************************************************************************/
3076 gdouble
gl_label_get_default_font_size(glLabel * label)3077 gl_label_get_default_font_size (glLabel *label)
3078 {
3079 	gl_debug (DEBUG_LABEL, "START");
3080 
3081 	g_return_val_if_fail (label && GL_IS_LABEL (label), 12.0);
3082 
3083 	gl_debug (DEBUG_LABEL, "END");
3084 
3085 	return label->priv->default_font_size;
3086 }
3087 
3088 
3089 /****************************************************************************/
3090 /* Get default font weight.                                                 */
3091 /****************************************************************************/
3092 PangoWeight
gl_label_get_default_font_weight(glLabel * label)3093 gl_label_get_default_font_weight (glLabel *label)
3094 {
3095 	gl_debug (DEBUG_LABEL, "START");
3096 
3097 	g_return_val_if_fail (label && GL_IS_LABEL (label), PANGO_WEIGHT_NORMAL);
3098 
3099 	gl_debug (DEBUG_LABEL, "END");
3100 
3101 	return label->priv->default_font_weight;
3102 }
3103 
3104 
3105 /****************************************************************************/
3106 /* Get default font italic flag.                                            */
3107 /****************************************************************************/
3108 gboolean
gl_label_get_default_font_italic_flag(glLabel * label)3109 gl_label_get_default_font_italic_flag (glLabel *label)
3110 {
3111 	gl_debug (DEBUG_LABEL, "START");
3112 
3113 	g_return_val_if_fail (label && GL_IS_LABEL (label), FALSE);
3114 
3115 	gl_debug (DEBUG_LABEL, "END");
3116 
3117 	return label->priv->default_font_italic_flag;
3118 }
3119 
3120 
3121 /****************************************************************************/
3122 /* Get default text color.                                                  */
3123 /****************************************************************************/
3124 guint
gl_label_get_default_text_color(glLabel * label)3125 gl_label_get_default_text_color (glLabel *label)
3126 {
3127 	gl_debug (DEBUG_LABEL, "START");
3128 
3129 	g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
3130 
3131 	gl_debug (DEBUG_LABEL, "END");
3132 
3133 	return label->priv->default_text_color;
3134 }
3135 
3136 
3137 /****************************************************************************/
3138 /* Get default text alignment.                                              */
3139 /****************************************************************************/
3140 PangoAlignment
gl_label_get_default_text_alignment(glLabel * label)3141 gl_label_get_default_text_alignment (glLabel *label)
3142 {
3143 	gl_debug (DEBUG_LABEL, "START");
3144 
3145 	g_return_val_if_fail (label && GL_IS_LABEL (label), PANGO_ALIGN_LEFT);
3146 
3147 	gl_debug (DEBUG_LABEL, "END");
3148 
3149 	return label->priv->default_text_alignment;
3150 }
3151 
3152 
3153 /****************************************************************************/
3154 /* Get default vertical text alignment.                                     */
3155 /****************************************************************************/
3156 glValignment
gl_label_get_default_text_valignment(glLabel * label)3157 gl_label_get_default_text_valignment (glLabel *label)
3158 {
3159 	gl_debug (DEBUG_LABEL, "START");
3160 
3161 	g_return_val_if_fail (label && GL_IS_LABEL (label), GL_VALIGN_TOP);
3162 
3163 	gl_debug (DEBUG_LABEL, "END");
3164 
3165 	return label->priv->default_text_valignment;
3166 }
3167 
3168 
3169 /****************************************************************************/
3170 /* Get default text line spacing.                                           */
3171 /****************************************************************************/
3172 gdouble
gl_label_get_default_text_line_spacing(glLabel * label)3173 gl_label_get_default_text_line_spacing (glLabel *label)
3174 {
3175 	gl_debug (DEBUG_LABEL, "START");
3176 
3177 	g_return_val_if_fail (label && GL_IS_LABEL (label), 1.0);
3178 
3179 	gl_debug (DEBUG_LABEL, "END");
3180 
3181 	return label->priv->default_text_line_spacing;
3182 }
3183 
3184 
3185 /****************************************************************************/
3186 /* Get default line width.                                                  */
3187 /****************************************************************************/
3188 gdouble
gl_label_get_default_line_width(glLabel * label)3189 gl_label_get_default_line_width (glLabel *label)
3190 {
3191 	gl_debug (DEBUG_LABEL, "START");
3192 
3193 	g_return_val_if_fail (label && GL_IS_LABEL (label), 1.0);
3194 
3195 	gl_debug (DEBUG_LABEL, "END");
3196 
3197 	return label->priv->default_line_width;
3198 }
3199 
3200 
3201 /****************************************************************************/
3202 /* Get default line color.                                                  */
3203 /****************************************************************************/
3204 guint
gl_label_get_default_line_color(glLabel * label)3205 gl_label_get_default_line_color (glLabel *label)
3206 {
3207 	gl_debug (DEBUG_LABEL, "START");
3208 
3209 	g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
3210 
3211 	gl_debug (DEBUG_LABEL, "END");
3212 
3213 	return label->priv->default_line_color;
3214 }
3215 
3216 
3217 /****************************************************************************/
3218 /* Get default fill color.                                                  */
3219 /****************************************************************************/
3220 guint
gl_label_get_default_fill_color(glLabel * label)3221 gl_label_get_default_fill_color (glLabel *label)
3222 {
3223 	gl_debug (DEBUG_LABEL, "START");
3224 
3225 	g_return_val_if_fail (label && GL_IS_LABEL (label), 0);
3226 
3227 	gl_debug (DEBUG_LABEL, "END");
3228 
3229 	return label->priv->default_fill_color;
3230 }
3231 
3232 
3233 /****************************************************************************/
3234 /* Draw label.                                                              */
3235 /****************************************************************************/
3236 void
gl_label_draw(glLabel * label,cairo_t * cr,gboolean screen_flag,glMergeRecord * record)3237 gl_label_draw (glLabel       *label,
3238                cairo_t       *cr,
3239                gboolean       screen_flag,
3240                glMergeRecord *record)
3241 {
3242 	GList            *p_obj;
3243 	glLabelObject    *object;
3244 
3245 	g_return_if_fail (label && GL_IS_LABEL (label));
3246 
3247 	for (p_obj = label->priv->object_list; p_obj != NULL; p_obj = p_obj->next)
3248         {
3249 		object = GL_LABEL_OBJECT (p_obj->data);
3250 
3251                 gl_label_object_draw (object, cr, screen_flag, record);
3252 	}
3253 }
3254 
3255 
3256 /****************************************************************************/
3257 /* Get object located at coordinates.                                       */
3258 /****************************************************************************/
gl_label_object_at(glLabel * label,cairo_t * cr,gdouble x_pixels,gdouble y_pixels)3259 glLabelObject *gl_label_object_at              (glLabel       *label,
3260                                                 cairo_t       *cr,
3261                                                 gdouble        x_pixels,
3262                                                 gdouble        y_pixels)
3263 {
3264 	GList            *p_obj;
3265 	glLabelObject    *object;
3266 
3267 	g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
3268 
3269 	for (p_obj = g_list_last (label->priv->object_list); p_obj != NULL; p_obj = p_obj->prev)
3270         {
3271 		object = GL_LABEL_OBJECT (p_obj->data);
3272 
3273                 if (gl_label_object_is_located_at (object, cr, x_pixels, y_pixels))
3274                 {
3275                         return object;
3276                 }
3277 
3278 	}
3279 
3280         return NULL;
3281 }
3282 
3283 
3284 /****************************************************************************/
3285 /* Return handle and associated object at coordinates.                      */
3286 /****************************************************************************/
3287 glLabelObject *
gl_label_get_handle_at(glLabel * label,cairo_t * cr,gdouble x_pixels,gdouble y_pixels,glLabelObjectHandle * handle)3288 gl_label_get_handle_at (glLabel             *label,
3289                         cairo_t             *cr,
3290                         gdouble              x_pixels,
3291                         gdouble              y_pixels,
3292                         glLabelObjectHandle *handle)
3293 {
3294         GList            *selection_list;
3295 	GList            *p_obj;
3296 	glLabelObject    *object;
3297 
3298 	g_return_val_if_fail (label && GL_IS_LABEL (label), NULL);
3299 
3300         selection_list = gl_label_get_selection_list (label);
3301 
3302 	for (p_obj = g_list_last (selection_list); p_obj != NULL; p_obj = p_obj->prev)
3303         {
3304 
3305 		object = GL_LABEL_OBJECT (p_obj->data);
3306 
3307                 if ((*handle = gl_label_object_handle_at (object, cr, x_pixels, y_pixels)))
3308                 {
3309                         g_list_free (selection_list);
3310                         return object;
3311                 }
3312 
3313 	}
3314 
3315         g_list_free (selection_list);
3316 
3317         *handle = GL_LABEL_OBJECT_HANDLE_NONE;
3318         return NULL;
3319 }
3320 
3321 
3322 /****************************************************************************/
3323 /* Checkpoint state.                                                        */
3324 /****************************************************************************/
3325 void
gl_label_checkpoint(glLabel * this,const gchar * description)3326 gl_label_checkpoint (glLabel       *this,
3327                      const gchar   *description)
3328 {
3329         State *state;
3330 
3331 	gl_debug (DEBUG_LABEL, "START");
3332 
3333         /*
3334          * Do not perform consecutive checkpoints that are identical.
3335          * E.g. moving an object by dragging, would produce a large number
3336          * of incremental checkpoints -- what we really want is a single
3337          * checkpoint so that we can undo the entire dragging effort with
3338          * one "undo"
3339          */
3340         if ( this->priv->cp_cleared_flag
3341              || (this->priv->cp_desc == NULL)
3342              || (strcmp (description, this->priv->cp_desc) != 0) )
3343         {
3344 
3345                 /* Sever old redo "thread" */
3346                 stack_clear (this->priv->redo_stack);
3347 
3348                 /* Save state onto undo stack. */
3349                 state = state_new (this, description);
3350                 stack_push_state (this->priv->undo_stack, state);
3351 
3352                 /* Track consecutive checkpoints. */
3353                 this->priv->cp_cleared_flag = FALSE;
3354                 this->priv->cp_desc         = g_strdup (description);
3355         }
3356 
3357         gl_debug (DEBUG_LABEL, "END");
3358 }
3359 
3360 
3361 /****************************************************************************/
3362 /* Undo.                                                                    */
3363 /****************************************************************************/
3364 void
gl_label_undo(glLabel * this)3365 gl_label_undo (glLabel       *this)
3366 {
3367         State *state_old;
3368         State *state_now;
3369 
3370 	gl_debug (DEBUG_LABEL, "START");
3371 
3372         state_old = stack_pop_state (this->priv->undo_stack);
3373         state_now = state_new (this, state_old->description);
3374 
3375         stack_push_state (this->priv->redo_stack, state_now);
3376 
3377         state_restore (state_old, this);
3378         state_free (state_old);
3379 
3380         this->priv->cp_cleared_flag = TRUE;
3381 
3382 	gl_debug (DEBUG_LABEL, "END");
3383 }
3384 
3385 
3386 /****************************************************************************/
3387 /* Redo.                                                                    */
3388 /****************************************************************************/
3389 void
gl_label_redo(glLabel * this)3390 gl_label_redo (glLabel       *this)
3391 {
3392         State *state_old;
3393         State *state_now;
3394 
3395 	gl_debug (DEBUG_LABEL, "START");
3396 
3397         state_old = stack_pop_state (this->priv->redo_stack);
3398         state_now = state_new (this, state_old->description);
3399 
3400         stack_push_state (this->priv->undo_stack, state_now);
3401 
3402         state_restore (state_old, this);
3403         state_free (state_old);
3404 
3405         this->priv->cp_cleared_flag = TRUE;
3406 
3407 	gl_debug (DEBUG_LABEL, "END");
3408 }
3409 
3410 
3411 /****************************************************************************/
3412 /* Can undo?                                                                */
3413 /****************************************************************************/
3414 gboolean
gl_label_can_undo(glLabel * this)3415 gl_label_can_undo (glLabel *this)
3416 {
3417 	return (!g_queue_is_empty (this->priv->undo_stack));
3418 }
3419 
3420 
3421 /****************************************************************************/
3422 /* Can redo?                                                                */
3423 /****************************************************************************/
3424 gboolean
gl_label_can_redo(glLabel * this)3425 gl_label_can_redo (glLabel *this)
3426 {
3427 	return (!g_queue_is_empty (this->priv->redo_stack));
3428 }
3429 
3430 
3431 /****************************************************************************/
3432 /* Get undo description string.                                             */
3433 /****************************************************************************/
3434 gchar *
gl_label_get_undo_description(glLabel * this)3435 gl_label_get_undo_description (glLabel *this)
3436 {
3437         State *state;
3438         gchar *description;
3439 
3440         state = g_queue_peek_head (this->priv->undo_stack);
3441         if ( state )
3442         {
3443                 description = g_strdup (state->description);
3444         }
3445         else
3446         {
3447                 description = g_strdup ("");
3448         }
3449 
3450         return description;
3451 }
3452 
3453 
3454 /****************************************************************************/
3455 /* Get redo description string.                                             */
3456 /****************************************************************************/
3457 gchar *
gl_label_get_redo_description(glLabel * this)3458 gl_label_get_redo_description (glLabel *this)
3459 {
3460         State *state;
3461         gchar *description;
3462 
3463         state = g_queue_peek_head (this->priv->redo_stack);
3464         if ( state )
3465         {
3466                 description = g_strdup (state->description);
3467         }
3468         else
3469         {
3470                 description = g_strdup ("");
3471         }
3472 
3473         return description;
3474 }
3475 
3476 
3477 /****************************************************************************/
3478 /* Clear undo or redo stack.                                                */
3479 /****************************************************************************/
3480 static void
stack_clear(GQueue * stack)3481 stack_clear (GQueue *stack)
3482 {
3483         State *state;
3484 
3485 	gl_debug (DEBUG_LABEL, "START");
3486 
3487         while ( (state = g_queue_pop_head (stack)) != NULL )
3488         {
3489                 state_free (state);
3490         }
3491 
3492 	gl_debug (DEBUG_LABEL, "END");
3493 }
3494 
3495 
3496 /****************************************************************************/
3497 /* Push state onto stack.                                                   */
3498 /****************************************************************************/
3499 static void
stack_push_state(GQueue * stack,State * state)3500 stack_push_state (GQueue *stack,
3501                   State  *state)
3502 {
3503 	gl_debug (DEBUG_LABEL, "START");
3504 
3505         g_queue_push_head( stack, state );
3506 
3507 	gl_debug (DEBUG_LABEL, "END");
3508 }
3509 
3510 
3511 /****************************************************************************/
3512 /* Pop state from stack.                                                    */
3513 /****************************************************************************/
3514 static State *
stack_pop_state(GQueue * stack)3515 stack_pop_state (GQueue *stack)
3516 {
3517         State *state;
3518 
3519 	gl_debug (DEBUG_LABEL, "START");
3520 
3521         state = g_queue_pop_head (stack);
3522 
3523 	gl_debug (DEBUG_LABEL, "END");
3524         return state;
3525 }
3526 
3527 
3528 /****************************************************************************/
3529 /* New state from label.                                                    */
3530 /****************************************************************************/
3531 static State *
state_new(glLabel * this,const gchar * description)3532 state_new (glLabel       *this,
3533            const gchar   *description)
3534 {
3535         State          *state;
3536         GList          *p_obj;
3537         glLabelObject  *object;
3538 
3539 	gl_debug (DEBUG_LABEL, "START");
3540 
3541         state = g_new0 (State, 1);
3542 
3543         state->description = g_strdup (description);
3544 
3545         state->template    = lgl_template_dup (this->priv->template);
3546         state->rotate_flag = this->priv->rotate_flag;
3547 
3548         for ( p_obj = this->priv->object_list; p_obj != NULL; p_obj = p_obj->next )
3549         {
3550                 object = GL_LABEL_OBJECT (p_obj->data);
3551 
3552                 state->object_list = g_list_append (state->object_list,
3553                                                     gl_label_object_dup (object, this));
3554         }
3555 
3556         state->merge = gl_merge_dup (this->priv->merge);
3557 
3558         state->modified_flag = this->priv->modified_flag;
3559         state->time_stamp    = this->priv->time_stamp;
3560 
3561 
3562 	gl_debug (DEBUG_LABEL, "END");
3563         return state;
3564 }
3565 
3566 
3567 /****************************************************************************/
3568 /* Restore label from saved state.                                          */
3569 /****************************************************************************/
3570 static void
state_free(State * state)3571 state_free (State   *state)
3572 {
3573         GList          *p_obj;
3574 
3575 	gl_debug (DEBUG_LABEL, "START");
3576 
3577         g_free (state->description);
3578 
3579         lgl_template_free (state->template);
3580         if ( state->merge )
3581         {
3582                 g_object_unref (G_OBJECT (state->merge));
3583         }
3584 
3585         for ( p_obj = state->object_list; p_obj != NULL; p_obj = p_obj->next )
3586         {
3587                 g_object_unref (G_OBJECT (p_obj->data));
3588         }
3589         g_list_free (state->object_list);
3590 
3591         g_free (state);
3592 
3593 	gl_debug (DEBUG_LABEL, "END");
3594 }
3595 
3596 
3597 /****************************************************************************/
3598 /* Restore label from saved state.                                          */
3599 /****************************************************************************/
3600 static void
state_restore(State * state,glLabel * this)3601 state_restore (State   *state,
3602                glLabel *this)
3603 
3604 {
3605         GList          *p_obj, *p_next;
3606         glLabelObject  *object;
3607 
3608 	gl_debug (DEBUG_LABEL, "START");
3609 
3610         gl_label_set_rotate_flag (this, state->rotate_flag, FALSE);
3611         gl_label_set_template (this, state->template, FALSE);
3612 
3613         for ( p_obj = this->priv->object_list; p_obj != NULL; p_obj = p_next )
3614         {
3615                 p_next = p_obj->next; /* Hold on to next; delete is destructive */
3616                 object = GL_LABEL_OBJECT (p_obj->data);
3617 
3618                 gl_label_delete_object (this, object);
3619         }
3620 
3621         for ( p_obj = state->object_list; p_obj != NULL; p_obj = p_obj->next )
3622         {
3623                 object = GL_LABEL_OBJECT (p_obj->data);
3624 
3625                 gl_label_add_object (this, gl_label_object_dup (object, this));
3626         }
3627 	g_signal_emit (G_OBJECT(this), signals[SELECTION_CHANGED], 0);
3628 
3629         gl_label_set_merge (this, state->merge, FALSE);
3630 
3631 
3632         if ( !state->modified_flag &&
3633              (state->time_stamp.tv_sec  == this->priv->time_stamp.tv_sec) &&
3634              (state->time_stamp.tv_usec == this->priv->time_stamp.tv_usec) )
3635         {
3636                 gl_label_clear_modified (this);
3637         }
3638 
3639 	gl_debug (DEBUG_LABEL, "END");
3640 }
3641 
3642 
3643 
3644 
3645 /*
3646  * Local Variables:       -- emacs
3647  * mode: C                -- emacs
3648  * c-basic-offset: 8      -- emacs
3649  * tab-width: 8           -- emacs
3650  * indent-tabs-mode: nil  -- emacs
3651  * End:                   -- emacs
3652  */
3653