2 * (GLABELS) Label and Business Card Creation program for GNOME
4 * label.c: GLabels label module
6 * Copyright (C) 2001-2002 Jim Evins <evins@snaught.com>.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
36 #define NAME_SPACE "http://snaught.com/glabels/0.4/"
37 #define COMPAT01_NAME_SPACE "http://snaught.com/glabels/0.1/"
39 static glLabelStatus xml_doc_to_label (xmlDocPtr doc, glLabel ** label);
40 static gboolean xml_parse_media_description (xmlNodePtr node, glLabel * label);
41 static void xml_parse_object(xmlNodePtr node, glLabelObject * object,
42 gboolean compat01_flag);
43 static void xml_parse_text_props (xmlNodePtr node, glLabelObject * object);
44 static void xml_parse_text_props_compat01( xmlNodePtr node,
45 glLabelObject *object );
46 static void xml_parse_box_props (xmlNodePtr node, glLabelObject * object);
47 static void xml_parse_line_props (xmlNodePtr node, glLabelObject * object);
48 static void xml_parse_ellipse_props (xmlNodePtr node, glLabelObject * object);
49 static void xml_parse_image_props (xmlNodePtr node, glLabelObject * object);
50 static void xml_parse_barcode_props (xmlNodePtr node, glLabelObject * object);
51 static void xml_parse_merge_properties (xmlNodePtr node, glLabel * label);
53 static glLabelStatus xml_label_to_doc (glLabel * label, xmlDocPtr * doc);
54 static void xml_create_media_description (xmlNodePtr root, xmlNsPtr ns,
56 static void xml_create_object (xmlNodePtr root, xmlNsPtr ns,
57 glLabelObject * object);
58 static void xml_create_text_props (xmlNodePtr root, xmlNsPtr ns,
59 glLabelObject * object);
60 static void xml_create_box_props (xmlNodePtr root, xmlNsPtr ns,
61 glLabelObject * object);
62 static void xml_create_line_props (xmlNodePtr root, xmlNsPtr ns,
63 glLabelObject * object);
64 static void xml_create_ellipse_props (xmlNodePtr root, xmlNsPtr ns,
65 glLabelObject * object);
66 static void xml_create_image_props (xmlNodePtr root, xmlNsPtr ns,
67 glLabelObject * object);
68 static void xml_create_barcode_props (xmlNodePtr root, xmlNsPtr ns,
69 glLabelObject * object);
70 static void xml_create_merge_properties (xmlNodePtr root, xmlNsPtr ns,
73 static const gchar *just_to_text (GtkJustification just);
74 static GtkJustification text_to_just (const gchar * text);
76 static const gchar *weight_to_text (GnomeFontWeight weight);
77 static GnomeFontWeight text_to_weight (const gchar * text);
79 /****************************************************************************/
80 /* Create a new label. */
81 /****************************************************************************/
87 label = g_new0 (glLabel, 1);
92 /****************************************************************************/
93 /* Create a new label. */
94 /****************************************************************************/
96 gl_label_new_with_template (const gchar * tmplt_name,
100 glTemplate *template;
102 label = gl_label_new ();
104 label->template_name = g_strdup (tmplt_name);
105 label->template = template = gl_template_from_name (tmplt_name);
106 label->rotate_flag = rotate_flag;
108 switch (template->style) {
110 case GL_TEMPLATE_STYLE_RECT:
112 label->width = template->label_width;
113 label->height = template->label_height;
115 label->width = template->label_height;
116 label->height = template->label_width;
120 case GL_TEMPLATE_STYLE_ROUND:
121 case GL_TEMPLATE_STYLE_CD:
122 label->width = label->height = 2.0 * template->label_radius;
126 WARN ("Unknown template label style");
130 label->objects = NULL;
135 /****************************************************************************/
136 /* Free a previously allocated label. */
137 /****************************************************************************/
139 gl_label_free (glLabel ** label)
142 glLabelObject *object;
144 if (*label != NULL) {
145 g_free ((*label)->template_name);
146 (*label)->template_name = NULL;
148 gl_template_free (&(*label)->template);
150 for (p = (*label)->objects; p != NULL; p = p_next) {
151 p_next = p->next; /* NOTE: p will be left dangling */
152 object = (glLabelObject *) p->data;
153 gl_label_object_free (&object);
161 /****************************************************************************/
162 /* Open and read label from xml file. */
163 /****************************************************************************/
165 gl_label_open_xml (glLabel ** label,
166 const gchar * filename)
169 glLabelStatus status;
171 xmlUseNewParser (TRUE);
172 doc = xmlParseFile (filename);
174 WARN (_("xmlParseFile error"));
176 return LABEL_ERROR_OPEN_XML_PARSE;
179 status = xml_doc_to_label (doc, label);
186 /****************************************************************************/
187 /* Read label from xml buffer. */
188 /****************************************************************************/
190 gl_label_open_xml_buffer (glLabel ** label,
191 const gchar * buffer)
194 glLabelStatus status;
196 xmlUseNewParser (TRUE);
197 doc = xmlParseDoc ((xmlChar *) buffer);
199 WARN (_("xmlParseFile error"));
201 return LABEL_ERROR_OPEN_XML_PARSE;
204 status = xml_doc_to_label (doc, label);
211 /*--------------------------------------------------------------------------*/
212 /* PRIVATE. Parse xml doc structure and create label. */
213 /*--------------------------------------------------------------------------*/
215 xml_doc_to_label (xmlDocPtr doc,
218 xmlNodePtr root, node;
220 glLabelObject *object;
221 glLabelStatus status = LABEL_OK;
222 gboolean compat01_flag = FALSE;
226 gl_label_free (label);
228 root = xmlDocGetRootElement (doc);
229 if (!root || !root->name) {
230 WARN (_("No document root"));
231 return LABEL_ERROR_OPEN_XML_PARSE;
233 ns = xmlSearchNsByHref (doc, root, NAME_SPACE);
235 /* Try compatability mode */
236 ns = xmlSearchNsByHref (doc, root, COMPAT01_NAME_SPACE);
237 if (ns != NULL) compat01_flag = TRUE;
241 ("document of the wrong type, glabels Namespace not found"));
242 return LABEL_ERROR_OPEN_XML_PARSE;
245 if (g_strcasecmp (root->name, "Label") != 0) {
246 WARN (_("Bad root node = \"%s\""), root->name);
247 return LABEL_ERROR_OPEN_XML_PARSE;
250 *label = gl_label_new ();
252 (*label)->rotate_flag =
253 !(g_strcasecmp (xmlGetProp (root, "rotate"), "false") == 0);
254 (*label)->width = g_strtod (xmlGetProp (root, "width"), NULL);
255 (*label)->height = g_strtod (xmlGetProp (root, "height"), NULL);
257 for (node = root->xmlChildrenNode; node != NULL; node = node->next) {
259 if (g_strcasecmp (node->name, "Media_Type") == 0) {
260 if (!xml_parse_media_description (node, *label)) {
261 status = LABEL_UNKNOWN_MEDIA;
263 } else if (g_strcasecmp (node->name, "Text") == 0) {
265 gl_label_object_new (*label, GL_LABEL_OBJECT_TEXT);
266 xml_parse_object (node, object, compat01_flag);
267 } else if (g_strcasecmp (node->name, "Box") == 0) {
269 gl_label_object_new (*label, GL_LABEL_OBJECT_BOX);
270 xml_parse_object (node, object, compat01_flag);
271 } else if (g_strcasecmp (node->name, "Line") == 0) {
273 gl_label_object_new (*label, GL_LABEL_OBJECT_LINE);
274 xml_parse_object (node, object, compat01_flag);
275 } else if (g_strcasecmp (node->name, "Ellipse") == 0) {
277 gl_label_object_new (*label,
278 GL_LABEL_OBJECT_ELLIPSE);
279 xml_parse_object (node, object, compat01_flag);
280 } else if (g_strcasecmp (node->name, "Image") == 0) {
282 gl_label_object_new (*label, GL_LABEL_OBJECT_IMAGE);
283 xml_parse_object (node, object, compat01_flag);
284 } else if (g_strcasecmp (node->name, "Barcode") == 0) {
286 gl_label_object_new (*label,
287 GL_LABEL_OBJECT_BARCODE);
288 xml_parse_object (node, object, compat01_flag);
289 } else if (g_strcasecmp (node->name, "Merge_Properties") == 0) {
290 xml_parse_merge_properties (node, *label);
292 if (!xmlNodeIsText (node)) {
293 WARN (_("bad node = \"%s\""), node->name);
301 /*--------------------------------------------------------------------------*/
302 /* PRIVATE. Parse Media Description node. */
303 /*--------------------------------------------------------------------------*/
305 xml_parse_media_description (xmlNodePtr node,
308 label->template_name = xmlNodeGetContent (node);
309 label->template = gl_template_from_name (label->template_name);
310 if (label->template == NULL) {
311 WARN ("Undefined template \"%s\"", label->template_name);
313 label->template = gl_template_from_name (NULL);
319 /*--------------------------------------------------------------------------*/
320 /* PRIVATE. Parse XML Object Node */
321 /*--------------------------------------------------------------------------*/
323 xml_parse_object (xmlNodePtr object_node,
324 glLabelObject * object,
325 gboolean compat01_flag)
327 object->x = g_strtod (xmlGetProp (object_node, "x"), NULL);
328 object->y = g_strtod (xmlGetProp (object_node, "y"), NULL);
330 switch (object->type) {
331 case GL_LABEL_OBJECT_TEXT:
333 xml_parse_text_props_compat01 (object_node, object);
335 xml_parse_text_props (object_node, object);
338 case GL_LABEL_OBJECT_BOX:
339 xml_parse_box_props (object_node, object);
341 case GL_LABEL_OBJECT_LINE:
342 xml_parse_line_props (object_node, object);
344 case GL_LABEL_OBJECT_ELLIPSE:
345 xml_parse_ellipse_props (object_node, object);
347 case GL_LABEL_OBJECT_IMAGE:
348 xml_parse_image_props (object_node, object);
350 case GL_LABEL_OBJECT_BARCODE:
351 xml_parse_barcode_props (object_node, object);
358 /*--------------------------------------------------------------------------*/
359 /* PRIVATE. Parse XML Label->Text Node Properties */
360 /*--------------------------------------------------------------------------*/
362 xml_parse_text_props (xmlNodePtr object_node,
363 glLabelObject * object)
365 xmlNodePtr line_node, text_node;
366 glTextNode *node_text;
369 object->arg.text.font_family = xmlGetProp (object_node, "font_family");
370 object->arg.text.font_size =
371 g_strtod (xmlGetProp (object_node, "font_size"), NULL);
372 object->arg.text.font_weight =
373 text_to_weight (xmlGetProp (object_node, "font_weight"));
374 object->arg.text.font_italic_flag =
375 !(g_strcasecmp (xmlGetProp (object_node, "font_italic"), "false") ==
378 object->arg.text.just =
379 text_to_just (xmlGetProp (object_node, "justify"));
381 sscanf (xmlGetProp (object_node, "color"), "%x",
382 &object->arg.text.color);
384 object->arg.text.lines = NULL;
385 for (line_node = object_node->xmlChildrenNode; line_node != NULL;
386 line_node = line_node->next) {
388 if (g_strcasecmp (line_node->name, "Line") == 0) {
391 for (text_node = line_node->xmlChildrenNode;
392 text_node != NULL; text_node = text_node->next) {
394 if (g_strcasecmp (text_node->name, "Field") ==
396 node_text = g_new0 (glTextNode, 1);
397 node_text->field_flag = TRUE;
399 xmlGetProp (text_node, "name");
401 g_list_append (nodes, node_text);
402 } else if (xmlNodeIsText (text_node)) {
403 node_text = g_new0 (glTextNode, 1);
404 node_text->field_flag = FALSE;
406 xmlNodeGetContent (text_node);
408 g_list_append (nodes, node_text);
410 WARN ("Unexpected Text Line child: \"%s\"",
415 object->arg.text.lines =
416 g_list_append (object->arg.text.lines, nodes);
419 WARN ("Unexpected Text child: \"%s\"", line_node->name);
426 /*--------------------------------------------------------------------------*/
427 /* PRIVATE. Parse XML label->Text node (Compatability with 0.1 version) */
428 /*--------------------------------------------------------------------------*/
430 xml_parse_text_props_compat01( xmlNodePtr node, glLabelObject *object )
434 text = xmlNodeGetContent( node );
435 object->arg.text.lines = gl_text_node_lines_new_from_text( text );
438 object->arg.text.font_family = xmlGetProp( node, "font_family" );
439 object->arg.text.font_size = g_strtod( xmlGetProp( node, "font_size" ),
441 object->arg.text.font_weight =
442 text_to_weight( xmlGetProp( node, "font_weight" ) );
443 object->arg.text.font_italic_flag =
444 !( g_strcasecmp( xmlGetProp( node, "font_italic" ),
447 object->arg.text.just = text_to_just( xmlGetProp( node, "justify" ) );
449 sscanf( xmlGetProp( node, "color" ), "%x", &object->arg.text.color );
452 /*--------------------------------------------------------------------------*/
453 /* PRIVATE. Parse XML Label->Box Node Properties */
454 /*--------------------------------------------------------------------------*/
456 xml_parse_box_props (xmlNodePtr node,
457 glLabelObject * object)
459 object->arg.box.w = g_strtod (xmlGetProp (node, "w"), NULL);
460 object->arg.box.h = g_strtod (xmlGetProp (node, "h"), NULL);
462 object->arg.box.line_width = g_strtod (xmlGetProp (node, "line_width"),
465 sscanf (xmlGetProp (node, "line_color"), "%x",
466 &object->arg.box.line_color);
467 sscanf (xmlGetProp (node, "fill_color"), "%x",
468 &object->arg.box.fill_color);
471 /*--------------------------------------------------------------------------*/
472 /* PRIVATE. Parse XML Label->Line Node Properties */
473 /*--------------------------------------------------------------------------*/
475 xml_parse_line_props (xmlNodePtr node,
476 glLabelObject * object)
478 object->arg.line.dx = g_strtod (xmlGetProp (node, "dx"), NULL);
479 object->arg.line.dy = g_strtod (xmlGetProp (node, "dy"), NULL);
481 object->arg.line.line_width = g_strtod (xmlGetProp (node, "line_width"),
484 sscanf (xmlGetProp (node, "line_color"), "%x",
485 &object->arg.line.line_color);
489 /*--------------------------------------------------------------------------*/
490 /* PRIVATE. Parse XML Label->Ellipse Node Properties */
491 /*--------------------------------------------------------------------------*/
493 xml_parse_ellipse_props (xmlNodePtr node,
494 glLabelObject * object)
496 object->arg.ellipse.w = g_strtod (xmlGetProp (node, "w"), NULL);
497 object->arg.ellipse.h = g_strtod (xmlGetProp (node, "h"), NULL);
499 object->arg.ellipse.line_width =
500 g_strtod (xmlGetProp (node, "line_width"), NULL);
502 sscanf (xmlGetProp (node, "line_color"), "%x",
503 &object->arg.ellipse.line_color);
504 sscanf (xmlGetProp (node, "fill_color"), "%x",
505 &object->arg.ellipse.fill_color);
508 /*--------------------------------------------------------------------------*/
509 /* PRIVATE. Parse XML Label->Image Node Properties */
510 /*--------------------------------------------------------------------------*/
512 xml_parse_image_props (xmlNodePtr node,
513 glLabelObject * object)
515 object->arg.image.w = g_strtod (xmlGetProp (node, "w"), NULL);
516 object->arg.image.h = g_strtod (xmlGetProp (node, "h"), NULL);
518 object->arg.image.filename = xmlGetProp (node, "filename");
520 object->arg.image.image =
521 gdk_pixbuf_new_from_file (object->arg.image.filename);
524 /*--------------------------------------------------------------------------*/
525 /* PRIVATE. Parse XML Label->Barcode Node Properties */
526 /*--------------------------------------------------------------------------*/
528 xml_parse_barcode_props (xmlNodePtr node,
529 glLabelObject * object)
533 sscanf (xmlGetProp (node, "color"), "%x", &object->arg.barcode.color);
535 object->arg.barcode.style =
536 gl_barcode_text_to_style (xmlGetProp (node, "style"));
538 object->arg.barcode.text_flag =
539 !(g_strcasecmp (xmlGetProp (node, "text"), "false") == 0);
541 object->arg.barcode.scale =
542 g_strtod (xmlGetProp (node, "scale"), NULL);
543 if (object->arg.barcode.scale == 0.0) {
544 object->arg.barcode.scale = 0.5; /* Set to a valid value */
547 child = node->xmlChildrenNode;
548 object->arg.barcode.text_node = g_new0 (glTextNode, 1);
549 if (g_strcasecmp (child->name, "Field") == 0) {
550 object->arg.barcode.text_node->field_flag = TRUE;
551 object->arg.barcode.text_node->data =
552 xmlGetProp (child, "name");
553 } else if (xmlNodeIsText (child)) {
554 object->arg.barcode.text_node->field_flag = FALSE;
555 object->arg.barcode.text_node->data =
556 xmlNodeGetContent (child);
558 WARN ("Unexpected Barcode child: \"%s\"", child->name);
562 /*--------------------------------------------------------------------------*/
563 /* PRIVATE. Parse XML merge properties tag. */
564 /*--------------------------------------------------------------------------*/
566 xml_parse_merge_properties (xmlNodePtr node,
570 glMergeFieldDefinition *field_def;
572 label->merge_type = gl_merge_text_to_type (xmlGetProp (node, "type"));
573 label->merge_src = xmlGetProp (node, "src");
575 for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
577 if (g_strcasecmp (child->name, "Field") == 0) {
578 field_def = g_new0 (glMergeFieldDefinition, 1);
579 field_def->key = xmlGetProp (child, "key");
580 field_def->loc = xmlGetProp (child, "loc");
581 label->merge_fields =
582 g_list_append (label->merge_fields, field_def);
584 WARN ("Unexpected Merge_Properties child: \"%s\"",
592 /****************************************************************************/
593 /* Save label to xml label file. */
594 /****************************************************************************/
596 gl_label_save_xml (glLabel * label,
597 const gchar * filename)
600 glLabelStatus status;
603 status = xml_label_to_doc (label, &doc);
605 xml_ret = xmlSaveFile (filename, doc);
608 WARN (_("Problem saving xml file."));
609 return LABEL_ERROR_SAVE_XML_FILE;
615 /****************************************************************************/
616 /* Save label to xml buffer. */
617 /****************************************************************************/
619 gl_label_save_xml_buffer (glLabel * label,
623 glLabelStatus status;
626 status = xml_label_to_doc (label, &doc);
628 xmlDocDumpMemory (doc, (xmlChar **) buffer, &size);
634 /*--------------------------------------------------------------------------*/
635 /* PRIVATE. Convert label to xml doc structure. */
636 /*--------------------------------------------------------------------------*/
638 xml_label_to_doc (glLabel * label,
644 glLabelObject *object;
648 *doc = xmlNewDoc ("1.0");
649 (*doc)->xmlRootNode = xmlNewDocNode (*doc, NULL, "Label", NULL);
651 ns = xmlNewNs ((*doc)->xmlRootNode, NAME_SPACE, "glabels");
652 xmlSetNs ((*doc)->xmlRootNode, ns);
654 xmlSetProp ((*doc)->xmlRootNode, "rotate",
655 label->rotate_flag ? "True" : "False");
657 string = g_strdup_printf ("%g", label->width);
658 xmlSetProp ((*doc)->xmlRootNode, "width", string);
661 string = g_strdup_printf ("%g", label->height);
662 xmlSetProp ((*doc)->xmlRootNode, "height", string);
665 xml_create_media_description ((*doc)->xmlRootNode, ns, label);
667 for (p = label->objects; p != NULL; p = p->next) {
668 object = (glLabelObject *) p->data;
669 xml_create_object ((*doc)->xmlRootNode, ns, object);
672 if (label->merge_type != GL_MERGE_NONE) {
673 xml_create_merge_properties ((*doc)->xmlRootNode, ns, label);
679 /*--------------------------------------------------------------------------*/
680 /* PRIVATE. Parse XML Label->Text Node */
681 /*--------------------------------------------------------------------------*/
683 xml_create_media_description (xmlNodePtr root,
689 node = xmlNewTextChild (root, ns, "Media_Type", label->template_name);
692 /*--------------------------------------------------------------------------*/
693 /* PRIVATE. Add XML label object Node */
694 /*--------------------------------------------------------------------------*/
696 xml_create_object (xmlNodePtr root,
698 glLabelObject * object)
700 xmlNodePtr object_node;
703 object_node = xmlNewChild (root, ns, "Object", NULL);
705 string = g_strdup_printf ("%g", object->x);
706 xmlSetProp (object_node, "x", string);
709 string = g_strdup_printf ("%g", object->y);
710 xmlSetProp (object_node, "y", string);
713 switch (object->type) {
714 case GL_LABEL_OBJECT_TEXT:
715 xml_create_text_props (object_node, ns, object);
717 case GL_LABEL_OBJECT_BOX:
718 xml_create_box_props (object_node, ns, object);
720 case GL_LABEL_OBJECT_LINE:
721 xml_create_line_props (object_node, ns, object);
723 case GL_LABEL_OBJECT_ELLIPSE:
724 xml_create_ellipse_props (object_node, ns, object);
726 case GL_LABEL_OBJECT_IMAGE:
727 xml_create_image_props (object_node, ns, object);
729 case GL_LABEL_OBJECT_BARCODE:
730 xml_create_barcode_props (object_node, ns, object);
733 WARN ("Unknown label object");
737 /*--------------------------------------------------------------------------*/
738 /* PRIVATE. Add XML Label->Text Node Properties */
739 /*--------------------------------------------------------------------------*/
741 xml_create_text_props (xmlNodePtr object_node,
743 glLabelObject * object)
745 xmlNodePtr line_node, field_node;
747 GList *p_line, *p_node;
748 glTextNode *node_text;
750 xmlNodeSetName (object_node, "Text");
752 xmlSetProp (object_node, "font_family", object->arg.text.font_family);
754 string = g_strdup_printf ("%g", object->arg.text.font_size);
755 xmlSetProp (object_node, "font_size", string);
758 xmlSetProp (object_node, "font_weight",
759 weight_to_text (object->arg.text.font_weight));
761 if (object->arg.text.font_italic_flag) {
762 xmlSetProp (object_node, "font_italic", "True");
764 xmlSetProp (object_node, "font_italic", "False");
767 xmlSetProp (object_node, "justify",
768 just_to_text (object->arg.text.just));
770 string = g_strdup_printf ("0x%08x", object->arg.text.color);
771 xmlSetProp (object_node, "color", string);
774 for (p_line = object->arg.text.lines; p_line != NULL;
775 p_line = p_line->next) {
776 line_node = xmlNewChild (object_node, ns, "Line", NULL);
778 for (p_node = (GList *) p_line->data; p_node != NULL;
779 p_node = p_node->next) {
780 node_text = (glTextNode *) p_node->data;
782 if (node_text->field_flag) {
784 xmlNewChild (line_node, ns, "Field", NULL);
785 xmlSetProp (field_node, "name",
788 xmlNodeAddContent (line_node, node_text->data);
797 /*--------------------------------------------------------------------------*/
798 /* PRIVATE. Add XML Label->Box Node Properties */
799 /*--------------------------------------------------------------------------*/
801 xml_create_box_props (xmlNodePtr object_node,
803 glLabelObject * object)
807 xmlNodeSetName (object_node, "Box");
809 string = g_strdup_printf ("%g", object->arg.box.w);
810 xmlSetProp (object_node, "w", string);
813 string = g_strdup_printf ("%g", object->arg.box.h);
814 xmlSetProp (object_node, "h", string);
817 string = g_strdup_printf ("%g", object->arg.box.line_width);
818 xmlSetProp (object_node, "line_width", string);
821 string = g_strdup_printf ("0x%08x", object->arg.box.line_color);
822 xmlSetProp (object_node, "line_color", string);
825 string = g_strdup_printf ("0x%08x", object->arg.box.fill_color);
826 xmlSetProp (object_node, "fill_color", string);
831 /*--------------------------------------------------------------------------*/
832 /* PRIVATE. Add XML Label->Line Node Properties */
833 /*--------------------------------------------------------------------------*/
835 xml_create_line_props (xmlNodePtr object_node,
837 glLabelObject * object)
841 xmlNodeSetName (object_node, "Line");
843 string = g_strdup_printf ("%g", object->arg.line.dx);
844 xmlSetProp (object_node, "dx", string);
847 string = g_strdup_printf ("%g", object->arg.line.dy);
848 xmlSetProp (object_node, "dy", string);
851 string = g_strdup_printf ("%g", object->arg.line.line_width);
852 xmlSetProp (object_node, "line_width", string);
855 string = g_strdup_printf ("0x%08x", object->arg.line.line_color);
856 xmlSetProp (object_node, "line_color", string);
861 /*--------------------------------------------------------------------------*/
862 /* PRIVATE. Add XML Label->Ellipse Node Properties */
863 /*--------------------------------------------------------------------------*/
865 xml_create_ellipse_props (xmlNodePtr object_node,
867 glLabelObject * object)
871 xmlNodeSetName (object_node, "Ellipse");
873 string = g_strdup_printf ("%g", object->arg.ellipse.w);
874 xmlSetProp (object_node, "w", string);
877 string = g_strdup_printf ("%g", object->arg.ellipse.h);
878 xmlSetProp (object_node, "h", string);
881 string = g_strdup_printf ("%g", object->arg.ellipse.line_width);
882 xmlSetProp (object_node, "line_width", string);
885 string = g_strdup_printf ("0x%08x", object->arg.ellipse.line_color);
886 xmlSetProp (object_node, "line_color", string);
889 string = g_strdup_printf ("0x%08x", object->arg.ellipse.fill_color);
890 xmlSetProp (object_node, "fill_color", string);
895 /*--------------------------------------------------------------------------*/
896 /* PRIVATE. Add XML Label->Image Node Properties */
897 /*--------------------------------------------------------------------------*/
899 xml_create_image_props (xmlNodePtr object_node,
901 glLabelObject * object)
905 xmlNodeSetName (object_node, "Image");
907 string = g_strdup_printf ("%g", object->arg.image.w);
908 xmlSetProp (object_node, "w", string);
911 string = g_strdup_printf ("%g", object->arg.image.h);
912 xmlSetProp (object_node, "h", string);
915 xmlSetProp (object_node, "filename", object->arg.image.filename);
919 /*--------------------------------------------------------------------------*/
920 /* PRIVATE. Add XML Label->Barcode Node Properties */
921 /*--------------------------------------------------------------------------*/
923 xml_create_barcode_props (xmlNodePtr object_node,
925 glLabelObject * object)
930 xmlNodeSetName (object_node, "Barcode");
932 string = g_strdup_printf ("0x%08x", object->arg.barcode.color);
933 xmlSetProp (object_node, "color", string);
936 xmlSetProp (object_node, "style",
937 gl_barcode_style_to_text (object->arg.barcode.style));
939 if (object->arg.barcode.text_flag) {
940 xmlSetProp (object_node, "text", "True");
942 xmlSetProp (object_node, "text", "False");
945 string = g_strdup_printf ("%g", object->arg.barcode.scale);
946 xmlSetProp (object_node, "scale", string);
949 if (object->arg.barcode.text_node->field_flag) {
950 child = xmlNewChild (object_node, ns, "Field", NULL);
951 xmlSetProp (child, "name",
952 object->arg.barcode.text_node->data);
954 xmlNodeSetContent (object_node,
955 object->arg.barcode.text_node->data);
960 /*--------------------------------------------------------------------------*/
961 /* PRIVATE. Add XML Label Merge Properties Node */
962 /*--------------------------------------------------------------------------*/
964 xml_create_merge_properties (xmlNodePtr root,
968 xmlNodePtr node, child;
971 glMergeFieldDefinition *field_def;
973 node = xmlNewChild (root, ns, "Merge_Properties", NULL);
975 string = gl_merge_type_to_text (label->merge_type);
976 xmlSetProp (node, "type", string);
979 xmlSetProp (node, "src", label->merge_src);
981 for (p = label->merge_fields; p != NULL; p = p->next) {
982 field_def = (glMergeFieldDefinition *) p->data;
984 child = xmlNewChild (node, ns, "Field", NULL);
985 xmlSetProp (child, "key", field_def->key);
986 xmlSetProp (child, "loc", field_def->loc);
991 /****************************************************************************/
992 /* Create a new label object of the given type. */
993 /****************************************************************************/
995 gl_label_object_new (glLabel * label,
996 glLabelObjectType type)
998 glLabelObject *object;
1000 object = g_new0 (glLabelObject, 1);
1001 object->parent = label;
1002 object->type = type;
1004 if (label != NULL) {
1005 label->objects = g_list_append (label->objects, object);
1011 /****************************************************************************/
1012 /* Create a new label object from an existing object */
1013 /****************************************************************************/
1015 gl_label_object_new_from_object (glLabel * label,
1016 glLabelObject * src_object)
1018 glLabelObject *object;
1019 GList *p_line, *nodes, *p_node;
1020 glTextNode *node, *src_node;
1022 object = g_new0 (glLabelObject, 1);
1023 *object = *src_object;
1026 switch (object->type) {
1028 case GL_LABEL_OBJECT_TEXT:
1030 gl_text_node_lines_print (src_object->arg.text.lines);
1031 object->arg.text.lines = NULL;
1032 for (p_line = src_object->arg.text.lines; p_line != NULL;
1033 p_line = p_line->next) {
1035 for (p_node = (GList *) p_line->data; p_node != NULL;
1036 p_node = p_node->next) {
1037 src_node = (glTextNode *) p_node->data;
1038 node = g_new0 (glTextNode, 1);
1039 node->field_flag = src_node->field_flag;
1040 node->data = g_strdup (src_node->data);
1041 nodes = g_list_append (nodes, node);
1043 object->arg.text.lines =
1044 g_list_append (object->arg.text.lines, nodes);
1046 object->arg.text.font_family =
1047 g_strdup (src_object->arg.text.font_family);
1050 case GL_LABEL_OBJECT_IMAGE:
1051 object->arg.image.filename
1052 = g_strdup (src_object->arg.image.filename);
1053 object->arg.image.image
1054 = gdk_pixbuf_copy (src_object->arg.image.image);
1057 case GL_LABEL_OBJECT_BARCODE:
1058 object->arg.barcode.text_node = g_new0 (glTextNode, 1);
1059 object->arg.barcode.text_node->field_flag =
1060 src_object->arg.barcode.text_node->field_flag;
1061 object->arg.barcode.text_node->data =
1062 g_strdup (src_object->arg.barcode.text_node->data);
1071 object->parent = label;
1072 if (label != NULL) {
1073 label->objects = g_list_append (label->objects, object);
1079 /****************************************************************************/
1080 /* Free a previously allocated label object. */
1081 /****************************************************************************/
1083 gl_label_object_free (glLabelObject ** object)
1087 switch ((*object)->type) {
1089 case GL_LABEL_OBJECT_TEXT:
1090 gl_text_node_lines_free (&((*object)->arg.text.lines));
1091 g_free ((*object)->arg.text.font_family);
1092 (*object)->arg.text.font_family = NULL;
1095 case GL_LABEL_OBJECT_IMAGE:
1096 g_free ((*object)->arg.image.filename);
1097 (*object)->arg.image.filename = NULL;
1098 gdk_pixbuf_unref ((*object)->arg.image.image);
1099 (*object)->arg.image.image = NULL;
1102 case GL_LABEL_OBJECT_BARCODE:
1103 gl_text_node_free (&((*object)->arg.barcode.text_node));
1111 label = (*object)->parent;
1112 if (label != NULL) {
1113 label->objects = g_list_remove (label->objects, *object);
1120 /****************************************************************************/
1121 /* Bring label object to front/top. */
1122 /****************************************************************************/
1124 gl_label_object_raise_to_front (glLabelObject * object)
1128 label = object->parent;
1130 /* Move to end of list, representing front most object */
1131 label->objects = g_list_remove (label->objects, object);
1132 label->objects = g_list_append (label->objects, object);
1135 /****************************************************************************/
1136 /* Send label object to rear/bottom. */
1137 /****************************************************************************/
1139 gl_label_object_lower_to_back (glLabelObject * object)
1143 label = object->parent;
1145 /* Move to front of list, representing rear most object */
1146 label->objects = g_list_remove (label->objects, object);
1147 label->objects = g_list_prepend (label->objects, object);
1150 /*--------------------------------------------------------------------------*/
1151 /* PRIVATE. Utilities to deal with GTK_JUSTIFICATION types */
1152 /*--------------------------------------------------------------------------*/
1153 static const gchar *
1154 just_to_text (GtkJustification just)
1157 case GTK_JUSTIFY_LEFT:
1159 case GTK_JUSTIFY_CENTER:
1161 case GTK_JUSTIFY_RIGHT:
1168 static GtkJustification
1169 text_to_just (const gchar * text)
1172 if (g_strcasecmp (text, "Left") == 0) {
1173 return GTK_JUSTIFY_LEFT;
1174 } else if (g_strcasecmp (text, "Center") == 0) {
1175 return GTK_JUSTIFY_CENTER;
1176 } else if (g_strcasecmp (text, "Right") == 0) {
1177 return GTK_JUSTIFY_RIGHT;
1179 return GTK_JUSTIFY_LEFT;
1184 /*--------------------------------------------------------------------------*/
1185 /* PRIVATE. Utilities to deal with GNOME_FONT_WEIGHT types */
1186 /*--------------------------------------------------------------------------*/
1187 static const gchar *
1188 weight_to_text (GnomeFontWeight weight)
1191 case GNOME_FONT_BOOK:
1193 case GNOME_FONT_BOLD:
1200 static GnomeFontWeight
1201 text_to_weight (const gchar * text)
1204 if (g_strcasecmp (text, "Regular") == 0) {
1205 return GNOME_FONT_BOOK;
1206 } else if (g_strcasecmp (text, "Bold") == 0) {
1207 return GNOME_FONT_BOLD;
1209 return GNOME_FONT_BOOK;