]> git.sur5r.net Git - glabels/blob - glabels2/src/xml-label-191.c
09552b5cd41b9abdc42301e1432b1496b6520302
[glabels] / glabels2 / src / xml-label-191.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  label.c:  GLabels xml label 1.91 compat module
5  *
6  *  Copyright (C) 2001-2002  Jim Evins <evins@snaught.com>.
7  *
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.
12  *
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.
17  *
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
21  */
22
23 #include <config.h>
24
25 #include <gnome.h>
26
27 #include <libxml/tree.h>
28 #include <libxml/parser.h>
29 #include <gdk-pixbuf/gdk-pixdata.h>
30
31 #include "label.h"
32 #include "label-object.h"
33 #include "label-text.h"
34 #include "label-box.h"
35 #include "label-line.h"
36 #include "label-ellipse.h"
37 #include "label-image.h"
38 #include "label-barcode.h"
39 #include "paper.h"
40 #include "template.h"
41 #include "base64.h"
42 #include "xml-label.h"
43 #include "xml-label-04.h"
44 #include "xml-template.h"
45 #include "xml.h"
46 #include "util.h"
47
48 #include "debug.h"
49
50 /*========================================================*/
51 /* Private macros and constants.                          */
52 /*========================================================*/
53
54 /*========================================================*/
55 /* Private types.                                         */
56 /*========================================================*/
57
58 /*========================================================*/
59 /* Private globals.                                       */
60 /*========================================================*/
61
62 /*========================================================*/
63 /* Private function prototypes.                           */
64 /*========================================================*/
65
66 static void           xml191_parse_objects        (xmlNodePtr        node,
67                                                    glLabel          *label);
68
69 static void           xml191_parse_object         (xmlNodePtr        node,
70                                                    glLabel          *label);
71
72 static glLabelObject *xml191_parse_text_props     (xmlNodePtr        node,
73                                                    glLabel          *label);
74
75 static glLabelObject *xml191_parse_box_props      (xmlNodePtr        node,
76                                                    glLabel          *label);
77
78 static glLabelObject *xml191_parse_line_props     (xmlNodePtr        node,
79                                                    glLabel          *label);
80
81 static glLabelObject *xml191_parse_ellipse_props  (xmlNodePtr        node,
82                                                    glLabel          *label);
83
84 static glLabelObject *xml191_parse_image_props    (xmlNodePtr        node,
85                                                    glLabel          *label);
86
87 static glLabelObject *xml191_parse_barcode_props  (xmlNodePtr        node,
88                                                    glLabel          *label);
89
90 static void           xml191_parse_merge_fields   (xmlNodePtr        node,
91                                                    glLabel          *label);
92
93 static void           xml191_parse_data           (xmlNodePtr        node,
94                                                    glLabel          *label);
95
96 static void           xml191_parse_pixdata        (xmlNodePtr        node,
97                                                    glLabel          *label);
98
99 static glTemplate    *xml191_parse_sheet          (xmlNodePtr        node);
100
101 static void           xml191_parse_label          (xmlNodePtr        label_node,
102                                                    glTemplate       *template);
103
104 static void           xml191_parse_layout         (xmlNodePtr        layout_node,
105                                                    glTemplate       *template);
106
107 static void           xml191_parse_markup         (xmlNodePtr        markup_node,
108                                                    glTemplate       *template);
109
110 static void           xml191_parse_alias          (xmlNodePtr        alias_node,
111                                                    glTemplate       *template);
112
113
114
115 /****************************************************************************/
116 /* Parse xml root node and create label.                                    */
117 /****************************************************************************/
118 glLabel *
119 gl_xml_label_191_parse (xmlNodePtr        root,
120                         glXMLLabelStatus *status)
121 {
122         xmlNodePtr  node;
123         glLabel    *label;
124         glTemplate *template;
125
126         gl_debug (DEBUG_XML, "START");
127
128         *status = XML_LABEL_OK;
129
130         if (!xmlStrEqual (root->name, "Document")) {
131                 g_warning (_("Bad root node = \"%s\""), root->name);
132                 *status = XML_LABEL_ERROR_OPEN_PARSE;
133                 return NULL;
134         }
135
136         label = GL_LABEL(gl_label_new ());
137
138         /* Pass 1, extract data nodes to pre-load cache. */
139         for (node = root->xmlChildrenNode; node != NULL; node = node->next) {
140                 if (xmlStrEqual (node->name, "Data")) {
141                         xml191_parse_data (node, label);
142                 }
143         }
144
145         /* Pass 2, now extract everything else. */
146         for (node = root->xmlChildrenNode; node != NULL; node = node->next) {
147
148                 if (xmlStrEqual (node->name, "Sheet")) {
149                         template = xml191_parse_sheet (node);
150                         if (!template) {
151                                 *status = XML_LABEL_UNKNOWN_MEDIA;
152                                 return NULL;
153                         }
154                         gl_template_register (template);
155                         gl_label_set_template (label, template);
156                         gl_template_free (&template);
157                 } else if (xmlStrEqual (node->name, "Objects")) {
158                         xml191_parse_objects (node, label);
159                 } else if (xmlStrEqual (node->name, "Merge_Fields")) {
160                         xml191_parse_merge_fields (node, label);
161                 } else if (xmlStrEqual (node->name, "Data")) {
162                         /* Handled in pass 1. */
163                 } else {
164                         if (!xmlNodeIsText (node)) {
165                                 g_warning (_("bad node in Document node =  \"%s\""),
166                                            node->name);
167                         }
168                 }
169         }
170
171         gl_debug (DEBUG_XML, "END");
172
173         return label;
174 }
175
176 /*--------------------------------------------------------------------------*/
177 /* PRIVATE.  Parse Objects node.                                            */
178 /*--------------------------------------------------------------------------*/
179 static void
180 xml191_parse_objects (xmlNodePtr  objects_node,
181                       glLabel    *label)
182 {
183         gboolean    rotate_flag;
184         xmlNodePtr  node;
185
186         gl_debug (DEBUG_XML, "START");
187
188         rotate_flag = gl_xml_get_prop_boolean (objects_node, "rotate", FALSE);
189         gl_label_set_rotate_flag (label, rotate_flag);
190
191         for (node = objects_node->xmlChildrenNode; node != NULL; node = node->next) {
192
193                 if (xmlStrEqual (node->name, "Object")) {
194                         xml191_parse_object (node, label);
195                 } else {
196                         if (!xmlNodeIsText (node)) {
197                                 g_warning (_("bad node =  \"%s\""), node->name);
198                         }
199                 }
200         }
201
202         gl_debug (DEBUG_XML, "END");
203 }
204
205 /*--------------------------------------------------------------------------*/
206 /* PRIVATE.  Parse XML Object Node                                          */
207 /*--------------------------------------------------------------------------*/
208 static void
209 xml191_parse_object (xmlNodePtr  object_node,
210                      glLabel    *label)
211 {
212         glLabelObject *object;
213         gdouble        x, y;
214         gchar         *string;
215         gdouble        affine[6];
216
217         gl_debug (DEBUG_XML, "START");
218
219         string = xmlGetProp (object_node, "type");
220
221         if ( xmlStrEqual (string, "Text") ) {
222                 object = xml191_parse_text_props (object_node, label);
223         } else if ( xmlStrEqual (string, "Box") ) {
224                 object = xml191_parse_box_props (object_node, label);
225         } else if ( xmlStrEqual (string, "Line") ) {
226                 object = xml191_parse_line_props (object_node, label);
227         } else if ( xmlStrEqual (string, "Ellipse") ) {
228                 object = xml191_parse_ellipse_props (object_node, label);
229         } else if ( xmlStrEqual (string, "Image") ) {
230                 object = xml191_parse_image_props (object_node, label);
231         } else if ( xmlStrEqual (string, "Barcode") ) {
232                 object = xml191_parse_barcode_props (object_node, label);
233         } else {
234                 g_warning ("Unknown label object type \"%s\"", string);
235                 g_free (string);
236                 return;
237         }
238         g_free (string);
239
240
241         x = gl_xml_get_prop_length (object_node, "x", 0.0);
242         y = gl_xml_get_prop_length (object_node, "y", 0.0);
243
244         gl_label_object_set_position (object, x, y);
245
246
247         affine[0] = gl_xml_get_prop_double (object_node, "a0", 0.0);
248         affine[1] = gl_xml_get_prop_double (object_node, "a1", 0.0);
249         affine[2] = gl_xml_get_prop_double (object_node, "a2", 0.0);
250         affine[3] = gl_xml_get_prop_double (object_node, "a3", 0.0);
251         affine[4] = gl_xml_get_prop_double (object_node, "a4", 0.0);
252         affine[5] = gl_xml_get_prop_double (object_node, "a5", 0.0);
253
254         gl_label_object_set_affine (object, affine);
255
256
257         gl_debug (DEBUG_XML, "END");
258 }
259
260 /*--------------------------------------------------------------------------*/
261 /* PRIVATE.  Parse XML Label->Text Node Properties                          */
262 /*--------------------------------------------------------------------------*/
263 static glLabelObject *
264 xml191_parse_text_props (xmlNodePtr  object_node,
265                          glLabel    *label)
266 {
267         GObject          *object;
268         GList            *lines;
269         gdouble           w, h;
270         gchar            *font_family;
271         gdouble           font_size;
272         GnomeFontWeight   font_weight;
273         gboolean          font_italic_flag;
274         guint             color;
275         GtkJustification  just;
276         xmlNodePtr        line_node, text_node;
277         glTextNode       *node_text;
278         GList            *nodes;
279         gchar            *string;
280
281         gl_debug (DEBUG_XML, "START");
282
283         object = gl_label_text_new (label);
284
285         w = gl_xml_get_prop_length (object_node, "w", 0);
286         h = gl_xml_get_prop_length (object_node, "h", 0);
287
288         font_family = xmlGetProp (object_node, "font_family");
289
290         font_size = gl_xml_get_prop_double (object_node, "font_size", 0.0);
291
292         string = xmlGetProp (object_node, "font_weight");
293         font_weight = gl_util_string_to_weight (string);
294         g_free (string);
295
296         font_italic_flag = gl_xml_get_prop_boolean (object_node, "font_italic", FALSE);
297
298         string = xmlGetProp (object_node, "justify");
299         just = gl_util_string_to_just (string);
300         g_free (string);
301
302         color = gl_xml_get_prop_uint (object_node, "color", 0);
303
304         lines = NULL;
305         for (line_node = object_node->xmlChildrenNode;
306              line_node != NULL;
307              line_node = line_node->next) {
308
309                 if (xmlStrEqual (line_node->name, "Line")) {
310
311                         nodes = NULL;
312                         for (text_node = line_node->xmlChildrenNode;
313                              text_node != NULL; text_node = text_node->next) {
314
315                                 if (xmlStrEqual (text_node->name, "Field")) {
316                                         node_text = g_new0 (glTextNode, 1);
317                                         node_text->field_flag = TRUE;
318                                         node_text->data = xmlGetProp (text_node, "name");
319                                         nodes = g_list_append (nodes, node_text);
320                                 } else if (xmlStrEqual (text_node->name, "Literal")) {
321                                         node_text = g_new0 (glTextNode, 1);
322                                         node_text->field_flag = FALSE;
323                                         node_text->data =
324                                                 xmlNodeGetContent (text_node);
325                                         nodes =
326                                                 g_list_append (nodes, node_text);
327                                 } else if (!xmlNodeIsText (text_node)) {
328                                         g_warning ("Unexpected Text Line child: \"%s\"",
329                                                    text_node->name);
330                                 }
331
332                         }
333                         lines = g_list_append (lines, nodes);
334
335                 } else if (!xmlNodeIsText (line_node)) {
336                         g_warning ("Unexpected Text child: \"%s\"",
337                                    line_node->name);
338                 }
339
340         }
341
342         gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
343         gl_label_text_set_lines  (GL_LABEL_TEXT(object), lines);
344         gl_label_object_set_font_family (GL_LABEL_OBJECT(object), font_family);
345         gl_label_object_set_font_size (GL_LABEL_OBJECT(object), font_size);
346         gl_label_object_set_font_weight (GL_LABEL_OBJECT(object), font_weight);
347         gl_label_object_set_font_italic_flag (GL_LABEL_OBJECT(object), font_italic_flag);
348         gl_label_object_set_text_color (GL_LABEL_OBJECT(object), color);
349         gl_label_object_set_text_alignment (GL_LABEL_OBJECT(object), just);
350
351         gl_text_node_lines_free (&lines);
352         g_free (font_family);
353
354         gl_debug (DEBUG_XML, "END");
355
356         return GL_LABEL_OBJECT(object);
357 }
358
359 /*--------------------------------------------------------------------------*/
360 /* PRIVATE.  Parse XML Label->Box Node Properties                           */
361 /*--------------------------------------------------------------------------*/
362 static glLabelObject *
363 xml191_parse_box_props (xmlNodePtr  node,
364                         glLabel    *label)
365 {
366         GObject *object;
367         gdouble  line_width;
368         guint    line_color, fill_color;
369         gdouble  w, h;
370
371         gl_debug (DEBUG_XML, "START");
372
373         object = gl_label_box_new (label);
374
375         w = gl_xml_get_prop_length (node, "w", 0);
376         h = gl_xml_get_prop_length (node, "h", 0);
377
378         line_width = gl_xml_get_prop_length (node, "line_width", 1.0);
379
380         line_color = gl_xml_get_prop_uint (node, "line_color", 0);
381         fill_color = gl_xml_get_prop_uint (node, "fill_color", 0);
382
383         gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
384         gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width);
385         gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color);
386         gl_label_object_set_fill_color (GL_LABEL_OBJECT(object), fill_color);
387
388         gl_debug (DEBUG_XML, "END");
389
390         return GL_LABEL_OBJECT(object);
391 }
392
393 /*--------------------------------------------------------------------------*/
394 /* PRIVATE.  Parse XML Label->Line Node Properties                          */
395 /*--------------------------------------------------------------------------*/
396 static glLabelObject *
397 xml191_parse_line_props (xmlNodePtr  node,
398                          glLabel    *label)
399 {
400         GObject *object;
401         gdouble  line_width;
402         guint    line_color;
403         gdouble  w, h;
404
405         gl_debug (DEBUG_XML, "START");
406
407         object = gl_label_line_new (label);
408
409         w = gl_xml_get_prop_length (node, "dx", 0);
410         h = gl_xml_get_prop_length (node, "dy", 0);
411
412         line_width = gl_xml_get_prop_length (node, "line_width", 1.0);
413
414         line_color = gl_xml_get_prop_uint (node, "line_color", 0);
415
416         gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
417         gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width);
418         gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color);
419
420         gl_debug (DEBUG_XML, "END");
421
422         return GL_LABEL_OBJECT(object);
423 }
424
425 /*--------------------------------------------------------------------------*/
426 /* PRIVATE.  Parse XML Label->Ellipse Node Properties                       */
427 /*--------------------------------------------------------------------------*/
428 static glLabelObject *
429 xml191_parse_ellipse_props (xmlNodePtr  node,
430                             glLabel    *label)
431 {
432         GObject *object;
433         gdouble  line_width;
434         guint    line_color, fill_color;
435         gdouble  w, h;
436
437         gl_debug (DEBUG_XML, "START");
438
439         object = gl_label_ellipse_new (label);
440
441         w = gl_xml_get_prop_length (node, "w", 0);
442         h = gl_xml_get_prop_length (node, "h", 0);
443
444         line_width = gl_xml_get_prop_length (node, "line_width", 1.0);
445
446         line_color = gl_xml_get_prop_uint (node, "line_color", 0);
447         fill_color = gl_xml_get_prop_uint (node, "fill_color", 0);
448
449         gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
450         gl_label_object_set_line_width (GL_LABEL_OBJECT(object), line_width);
451         gl_label_object_set_line_color (GL_LABEL_OBJECT(object), line_color);
452         gl_label_object_set_fill_color (GL_LABEL_OBJECT(object), fill_color);
453
454         gl_debug (DEBUG_XML, "END");
455
456         return GL_LABEL_OBJECT(object);
457 }
458
459 /*--------------------------------------------------------------------------*/
460 /* PRIVATE.  Parse XML Label->Image Node Properties                         */
461 /*--------------------------------------------------------------------------*/
462 static glLabelObject *
463 xml191_parse_image_props (xmlNodePtr  node,
464                           glLabel    *label)
465 {
466         GObject      *object;
467         xmlNodePtr    child;
468         gdouble       w, h;
469         glTextNode   *filename;
470
471         gl_debug (DEBUG_XML, "START");
472
473         object = gl_label_image_new (label);
474
475         w = gl_xml_get_prop_length (node, "w", 0);
476         h = gl_xml_get_prop_length (node, "h", 0);
477
478         filename = g_new0 (glTextNode, 1);
479         for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
480                 if (xmlStrEqual (child->name, "Field")) {
481                         filename->field_flag = TRUE;
482                         filename->data = xmlGetProp (child, "name");
483                 } else if (xmlStrEqual (child->name, "File")) {
484                         filename->field_flag = FALSE;
485                         filename->data = xmlGetProp (child, "src");
486                 } else if (!xmlNodeIsText (child)) {
487                         g_warning ("Unexpected Image child: \"%s\"", child->name);
488                 }
489         }
490
491         gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
492         gl_label_image_set_filename (GL_LABEL_IMAGE(object), filename);
493
494         gl_text_node_free (&filename);
495
496         gl_debug (DEBUG_XML, "END");
497
498         return GL_LABEL_OBJECT(object);
499 }
500
501 /*--------------------------------------------------------------------------*/
502 /* PRIVATE.  Parse XML Label->Barcode Node Properties                       */
503 /*--------------------------------------------------------------------------*/
504 static glLabelObject *
505 xml191_parse_barcode_props (xmlNodePtr  node,
506                             glLabel    *label)
507 {
508         GObject            *object;
509         xmlNodePtr          child;
510         gdouble             w, h;
511         gchar              *string;
512         glTextNode         *text_node;
513         glBarcodeStyle      style;
514         gboolean            text_flag;
515         gboolean            checksum_flag;
516         guint               color;
517
518         gl_debug (DEBUG_XML, "START");
519
520         object = gl_label_barcode_new (label);
521
522         w = gl_xml_get_prop_length (node, "w", 0);
523         h = gl_xml_get_prop_length (node, "h", 0);
524
525         color = gl_xml_get_prop_uint (node, "color", 0);
526
527         string = xmlGetProp (node, "style");
528         style = gl_barcode_text_to_style (string);
529         g_free (string);
530
531         text_flag = gl_xml_get_prop_boolean (node, "text", FALSE);
532         checksum_flag = gl_xml_get_prop_boolean (node, "checksum", TRUE);
533
534         text_node = g_new0 (glTextNode, 1);
535         for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
536                 if (xmlStrEqual (child->name, "Field")) {
537                         text_node->field_flag = TRUE;
538                         text_node->data = xmlGetProp (child, "name");
539                 } else if (xmlStrEqual (child->name, "Literal")) {
540                         text_node->field_flag = FALSE;
541                         text_node->data = xmlNodeGetContent (child);
542                 } else if (!xmlNodeIsText (child)) {
543                         g_warning ("Unexpected Barcode child: \"%s\"", child->name);
544                 }
545         }
546
547         gl_label_object_set_size (GL_LABEL_OBJECT(object), w, h);
548
549         gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node);
550         gl_label_barcode_set_props (GL_LABEL_BARCODE(object),
551                                     style, text_flag, checksum_flag);
552         gl_label_object_set_line_color (GL_LABEL_OBJECT(object), color);
553
554         gl_text_node_free (&text_node);
555
556         gl_debug (DEBUG_XML, "END");
557
558         return GL_LABEL_OBJECT(object);
559 }
560
561 /*--------------------------------------------------------------------------*/
562 /* PRIVATE.  Parse XML merge fields tag.                                */
563 /*--------------------------------------------------------------------------*/
564 static void
565 xml191_parse_merge_fields (xmlNodePtr  node,
566                            glLabel    *label)
567 {
568         xmlNodePtr  child;
569         gchar      *string;
570         glMerge    *merge;
571
572         gl_debug (DEBUG_XML, "START");
573
574         string = xmlGetProp (node, "type");
575         merge = gl_merge_new (string);
576         g_free (string);
577
578         string = xmlGetProp (node, "src");
579         gl_merge_set_src (merge, string);
580         g_free (string);
581
582         gl_label_set_merge (label, merge);
583
584         g_object_unref (G_OBJECT(merge));
585
586         gl_debug (DEBUG_XML, "END");
587 }
588
589 /*--------------------------------------------------------------------------*/
590 /* PRIVATE.  Parse XML data tag.                                            */
591 /*--------------------------------------------------------------------------*/
592 static void
593 xml191_parse_data (xmlNodePtr  node,
594                    glLabel    *label)
595 {
596         xmlNodePtr  child;
597
598         gl_debug (DEBUG_XML, "START");
599
600         for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
601
602                 if (xmlStrEqual (child->name, "Pixdata")) {
603                         xml191_parse_pixdata (child, label);
604                 } else {
605                         if (!xmlNodeIsText (child)) {
606                                 g_warning (_("bad node in Data node =  \"%s\""),
607                                            child->name);
608                         }
609                 }
610         }
611
612         gl_debug (DEBUG_XML, "END");
613 }
614
615 /*--------------------------------------------------------------------------*/
616 /* PRIVATE.  Parse XML pixbuf data tag.                                     */
617 /*--------------------------------------------------------------------------*/
618 static void
619 xml191_parse_pixdata (xmlNodePtr  node,
620                       glLabel    *label)
621 {
622         gchar      *name, *base64;
623         guchar     *stream;
624         guint       stream_length;
625         gboolean    ret;
626         GdkPixdata *pixdata;
627         GdkPixbuf  *pixbuf;
628         GHashTable *pixbuf_cache;
629
630         gl_debug (DEBUG_XML, "START");
631
632         name = xmlGetProp (node, "name");
633         base64 = xmlNodeGetContent (node);
634
635         stream = gl_base64_decode (base64, &stream_length);
636         pixdata = g_new0 (GdkPixdata, 1);
637         ret = gdk_pixdata_deserialize (pixdata, stream_length, stream, NULL);
638
639         if (ret) {
640                 pixbuf = gdk_pixbuf_from_pixdata (pixdata, TRUE, NULL);
641
642                 pixbuf_cache = gl_label_get_pixbuf_cache (label);
643                 gl_pixbuf_cache_add_pixbuf (pixbuf_cache, name, pixbuf);
644         }
645
646         g_free (name);
647         g_free (base64);
648         g_free (stream);
649         g_free (pixdata);
650
651         gl_debug (DEBUG_XML, "END");
652 }
653
654 /*--------------------------------------------------------------------------*/
655 /* PRIVATE.  Parse XML template Node.                                       */
656 /*--------------------------------------------------------------------------*/
657 static glTemplate *
658 xml191_parse_sheet (xmlNodePtr sheet_node)
659 {
660         glTemplate            *template;
661         xmlNodePtr             node;
662         gchar                 *description;
663         glPaper               *paper;
664
665         gl_debug (DEBUG_TEMPLATE, "START");
666
667         template = g_new0 (glTemplate, 1);
668
669         template->name  = xmlGetProp (sheet_node, "name");
670         template->alias = g_list_append (template->alias, g_strdup (template->name));
671         gl_debug (DEBUG_TEMPLATE, "Sheet = %s", template->name);
672
673         template->page_size = xmlGetProp (sheet_node, "size");
674         if (xmlStrEqual (template->page_size, "Other")) {
675
676                 template->page_width = gl_xml_get_prop_length (sheet_node, "width", 0);
677                 template->page_height = gl_xml_get_prop_length (sheet_node, "height", 0);
678
679         } else {
680                 paper = gl_paper_from_id (template->page_size);
681                 if (paper == NULL) {
682                         /* This should always be an id, but just in case a name
683                            slips by! */
684                         g_warning (_("Unknown page size id \"%s\", trying as name"),
685                                    template->page_size);
686                         paper = gl_paper_from_name (template->page_size);
687                         g_free (template->page_size);
688                         template->page_size = g_strdup (paper->id);
689                 }
690                 if (paper != NULL) {
691                         template->page_width  = paper->width;
692                         template->page_height = paper->height;
693                 } else {
694                         g_warning (_("Unknown page size id or name \"%s\""),
695                                    template->page_size);
696                 }
697                 gl_paper_free (&paper);
698         }
699
700         description = xmlGetProp (sheet_node, "_description");
701         if (description != NULL) {
702                 template->description = gettext (description);
703         } else {
704                 template->description = xmlGetProp (sheet_node, "description");
705         }
706
707         for (node = sheet_node->xmlChildrenNode; node != NULL;
708              node = node->next) {
709                 if (xmlStrEqual (node->name, "Label")) {
710                         xml191_parse_label (node, template);
711                 } else if (xmlStrEqual (node->name, "Alias")) {
712                         xml191_parse_alias (node, template);
713                 } else {
714                         if (!xmlNodeIsText (node)) {
715                                 g_warning ("bad node =  \"%s\"", node->name);
716                         }
717                 }
718         }
719
720         gl_debug (DEBUG_TEMPLATE, "END");
721
722         return template;
723 }
724
725 /*--------------------------------------------------------------------------*/
726 /* PRIVATE.  Parse XML Sheet->Label Node.                                   */
727 /*--------------------------------------------------------------------------*/
728 static void
729 xml191_parse_label (xmlNodePtr  label_node,
730                     glTemplate *template)
731 {
732         xmlNodePtr  node;
733         gchar      *style;
734
735         gl_debug (DEBUG_TEMPLATE, "START");
736
737         style = xmlGetProp (label_node, "style");
738         if (xmlStrEqual (style, "rectangle")) {
739                 template->label.style = GL_TEMPLATE_STYLE_RECT;
740         } else if (xmlStrEqual (style, "round")) {
741                 template->label.style = GL_TEMPLATE_STYLE_ROUND;
742         } else if (xmlStrEqual (style, "cd")) {
743                 template->label.style = GL_TEMPLATE_STYLE_CD;
744         } else {
745                 template->label.style = GL_TEMPLATE_STYLE_RECT;
746                 g_warning ("Unknown label style in template");
747         }
748         g_free (style);
749
750         switch (template->label.style) {
751
752         case GL_TEMPLATE_STYLE_RECT:
753                 template->label.rect.w = gl_xml_get_prop_length (label_node, "width", 0);
754                 template->label.rect.h = gl_xml_get_prop_length (label_node, "height", 0);
755                 template->label.rect.r = gl_xml_get_prop_length (label_node, "round", 0);
756                 break;
757
758         case GL_TEMPLATE_STYLE_ROUND:
759                 template->label.round.r = gl_xml_get_prop_length (label_node, "radius", 0);
760                 break;
761
762         case GL_TEMPLATE_STYLE_CD:
763                 template->label.cd.r1 = gl_xml_get_prop_length (label_node, "radius", 0);
764                 template->label.cd.r2 = gl_xml_get_prop_length (label_node, "hole", 0);
765                 template->label.cd.w  = gl_xml_get_prop_length (label_node, "width", 0);
766                 template->label.cd.h  = gl_xml_get_prop_length (label_node, "height", 0);
767                 break;
768
769         default:
770                 break;
771
772         }
773
774         for (node = label_node->xmlChildrenNode; node != NULL;
775              node = node->next) {
776                 if (xmlStrEqual (node->name, "Layout")) {
777                         xml191_parse_layout (node, template);
778                 } else if (xmlStrEqual (node->name, "Markup")) {
779                         xml191_parse_markup (node, template);
780                 } else if (!xmlNodeIsText (node)) {
781                         g_warning ("bad node =  \"%s\"", node->name);
782                 }
783         }
784
785         gl_debug (DEBUG_TEMPLATE, "END");
786 }
787
788 /*--------------------------------------------------------------------------*/
789 /* PRIVATE.  Parse XML Sheet->Label->Layout Node.                           */
790 /*--------------------------------------------------------------------------*/
791 static void
792 xml191_parse_layout (xmlNodePtr  layout_node,
793                      glTemplate *template)
794 {
795         gint        nx, ny;
796         gdouble     x0, y0, dx, dy;
797         xmlNodePtr  node;
798
799         gl_debug (DEBUG_TEMPLATE, "START");
800
801         nx = gl_xml_get_prop_int (layout_node, "nx", 1);
802         ny = gl_xml_get_prop_int (layout_node, "ny", 1);
803
804         x0 = gl_xml_get_prop_length (layout_node, "x0", 0);
805         y0 = gl_xml_get_prop_length (layout_node, "y0", 0);
806
807         dx = gl_xml_get_prop_length (layout_node, "dx", 0);
808         dy = gl_xml_get_prop_length (layout_node, "dy", 0);
809
810         for (node = layout_node->xmlChildrenNode; node != NULL;
811              node = node->next) {
812                 if (!xmlNodeIsText (node)) {
813                         g_warning ("bad node =  \"%s\"", node->name);
814                 }
815         }
816
817         template->label.any.layouts =
818                 g_list_append (template->label.any.layouts,
819                                gl_template_layout_new (nx, ny, x0, y0, dx, dy));
820
821         gl_debug (DEBUG_TEMPLATE, "END");
822 }
823
824 /*--------------------------------------------------------------------------*/
825 /* PRIVATE.  Parse XML Sheet->Label->Markup Node.                           */
826 /*--------------------------------------------------------------------------*/
827 static void
828 xml191_parse_markup (xmlNodePtr  markup_node,
829                      glTemplate *template)
830 {
831         gchar      *type;
832         gdouble     size;
833         gdouble     x1, y1, x2, y2;
834         xmlNodePtr  node;
835
836         gl_debug (DEBUG_TEMPLATE, "START");
837
838         type = xmlGetProp (markup_node, "type");
839         if (xmlStrEqual (type, "margin")) {
840
841                 size = gl_xml_get_prop_length (markup_node, "size", 0);
842
843                 template->label.any.markups =
844                         g_list_append (template->label.any.markups,
845                                        gl_template_markup_margin_new (size));
846
847         } else if (xmlStrEqual (type, "line")) {
848
849                 x1 = gl_xml_get_prop_length (markup_node, "x1", 0);
850                 y1 = gl_xml_get_prop_length (markup_node, "y1", 0);
851                 x2 = gl_xml_get_prop_length (markup_node, "x2", 0);
852                 y2 = gl_xml_get_prop_length (markup_node, "y2", 0);
853
854                 template->label.any.markups =
855                         g_list_append (template->label.any.markups,
856                                        gl_template_markup_line_new (x1, y1, x2, y2));
857         }
858         g_free (type);
859
860         for (node = markup_node->xmlChildrenNode; node != NULL;
861              node = node->next) {
862                 if (!xmlNodeIsText (node)) {
863                         g_warning ("bad node =  \"%s\"", node->name);
864                 }
865         }
866
867         gl_debug (DEBUG_TEMPLATE, "END");
868 }
869
870 /*--------------------------------------------------------------------------*/
871 /* PRIVATE.  Parse XML Sheet->Alias Node.                                   */
872 /*--------------------------------------------------------------------------*/
873 static void
874 xml191_parse_alias (xmlNodePtr  alias_node,
875                     glTemplate *template)
876 {
877         gl_debug (DEBUG_TEMPLATE, "START");
878
879         template->alias = g_list_append (template->alias,
880                                         xmlGetProp (alias_node, "name"));
881
882         gl_debug (DEBUG_TEMPLATE, "END");
883 }
884