]> git.sur5r.net Git - glabels/blob - glabels2/src/xml-template.c
5fc3b22e2bdef8aa33ce65ea21aeef28fc412d18
[glabels] / glabels2 / src / xml-template.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  xml-template.c:  template xml module
5  *
6  *  Copyright (C) 2001-2003  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 <string.h>
26 #include <libgnomeprint/gnome-print-paper.h>
27
28 #include "util.h"
29 #include "xml.h"
30 #include "xml-template.h"
31
32 #include "debug.h"
33
34 /*===========================================*/
35 /* Private types                             */
36 /*===========================================*/
37
38 /*===========================================*/
39 /* Private globals                           */
40 /*===========================================*/
41
42 /*===========================================*/
43 /* Local function prototypes                 */
44 /*===========================================*/
45 static void        xml_parse_label              (xmlNodePtr              label_node,
46                                                  glTemplate             *template);
47 static void        xml_parse_layout             (xmlNodePtr              layout_node,
48                                                  glTemplate             *template);
49 static void        xml_parse_markup             (xmlNodePtr              markup_node,
50                                                  glTemplate             *template);
51 static void        xml_parse_alias              (xmlNodePtr              alias_node,
52                                                  glTemplate             *template);
53
54 static void        xml_add_label                (const glTemplate       *template,
55                                                  xmlNodePtr              root,
56                                                  xmlNsPtr                ns);
57 static void        xml_add_layout               (glTemplateLayout       *layout,
58                                                  xmlNodePtr              root,
59                                                  xmlNsPtr                ns);
60 static void        xml_add_markup_margin        (glTemplateMarkupMargin *margin,
61                                                  xmlNodePtr              root,
62                                                  xmlNsPtr                ns);
63 static void        xml_add_markup_line          (glTemplateMarkupLine   *line,
64                                                  xmlNodePtr              root,
65                                                  xmlNsPtr                ns);
66 static void        xml_add_alias                (gchar                  *name,
67                                                  xmlNodePtr              root,
68                                                  xmlNsPtr                ns);
69
70
71 /*****************************************************************************/
72 /* Read templates from template file.                                        */
73 /*****************************************************************************/
74 GList *
75 gl_xml_template_read_templates_from_file (GList *templates,
76                                           gchar *xml_filename)
77 {
78         xmlDocPtr   doc;
79         xmlNodePtr  root, node;
80         glTemplate *template;
81
82         gl_debug (DEBUG_TEMPLATE, "START");
83
84         doc = xmlParseFile (xml_filename);
85         if (!doc) {
86                 g_warning ("\"%s\" is not a glabels template file (not XML)",
87                       xml_filename);
88                 return templates;
89         }
90
91         root = xmlDocGetRootElement (doc);
92         if (!root || !root->name) {
93                 g_warning ("\"%s\" is not a glabels template file (no root node)",
94                       xml_filename);
95                 xmlFreeDoc (doc);
96                 return templates;
97         }
98         if (g_strcasecmp (root->name, "glabels-templates") != 0) {
99                 g_warning ("\"%s\" is not a glabels template file (wrong root node)",
100                       xml_filename);
101                 xmlFreeDoc (doc);
102                 return templates;
103         }
104
105         for (node = root->xmlChildrenNode; node != NULL; node = node->next) {
106
107                 if (g_strcasecmp (node->name, "Sheet") == 0) {
108                         template = gl_xml_template_parse_sheet (node);
109                         templates = g_list_append (templates, template);
110                 } else {
111                         if ( !xmlNodeIsText(node) ) {
112                                 if (g_strcasecmp (node->name,"comment") != 0) {
113                                         g_warning ("bad node =  \"%s\"",node->name);
114                                 }
115                         }
116                 }
117         }
118
119         xmlFreeDoc (doc);
120
121         gl_debug (DEBUG_TEMPLATE, "END");
122         return templates;
123 }
124
125 /*****************************************************************************/
126 /* Parse XML template Node.                                                  */
127 /*****************************************************************************/
128 glTemplate *
129 gl_xml_template_parse_sheet (xmlNodePtr sheet_node)
130 {
131         glTemplate            *template;
132         xmlNodePtr             node;
133         const GnomePrintPaper *paper;
134
135         gl_debug (DEBUG_TEMPLATE, "START");
136
137         template = g_new0 (glTemplate, 1);
138
139         template->name = g_list_append (template->name,
140                                         xmlGetProp (sheet_node, "name"));
141         gl_debug (DEBUG_TEMPLATE, "Sheet = %s", template->name->data);
142
143         template->page_size = xmlGetProp (sheet_node, "size");
144         if ( strcmp (template->page_size,"US-Letter") == 0 ) {
145                 template->page_size = "US Letter";
146         }
147         if (g_strcasecmp (template->page_size, "Other") == 0) {
148
149                 template->page_width = gl_xml_get_prop_double (sheet_node, "width", 0);
150                 template->page_height = gl_xml_get_prop_double (sheet_node, "height", 0);
151
152         } else {
153                 paper = gnome_print_paper_get_by_name (template->page_size);
154                 if (paper != NULL) {
155                         template->page_width  = paper->width;
156                         template->page_height = paper->height;
157                 } else {
158                         g_warning (_("Unknown page size \"%s\""), template->page_size);
159                 }
160         }
161
162         template->description = xmlGetProp (sheet_node, "description");
163
164         for (node = sheet_node->xmlChildrenNode; node != NULL;
165              node = node->next) {
166                 if (g_strcasecmp (node->name, "Label") == 0) {
167                         xml_parse_label (node, template);
168                 } else if (g_strcasecmp (node->name, "Alias") == 0) {
169                         xml_parse_alias (node, template);
170                 } else {
171                         if (g_strcasecmp (node->name, "text") != 0) {
172                                 g_warning ("bad node =  \"%s\"", node->name);
173                         }
174                 }
175         }
176
177         gl_debug (DEBUG_TEMPLATE, "END");
178
179         return template;
180 }
181
182 /*--------------------------------------------------------------------------*/
183 /* PRIVATE.  Parse XML Sheet->Label Node.                                   */
184 /*--------------------------------------------------------------------------*/
185 static void
186 xml_parse_label (xmlNodePtr  label_node,
187                  glTemplate *template)
188 {
189         xmlNodePtr  node;
190         gchar      *style;
191
192         gl_debug (DEBUG_TEMPLATE, "START");
193
194         style = xmlGetProp (label_node, "style");
195         if (g_strcasecmp (style, "rectangle") == 0) {
196                 template->label.style = GL_TEMPLATE_STYLE_RECT;
197         } else if (g_strcasecmp (style, "round") == 0) {
198                 template->label.style = GL_TEMPLATE_STYLE_ROUND;
199         } else if (g_strcasecmp (style, "cd") == 0) {
200                 template->label.style = GL_TEMPLATE_STYLE_CD;
201         } else {
202                 template->label.style = GL_TEMPLATE_STYLE_RECT;
203                 g_warning ("Unknown label style in template");
204         }
205         g_free (style);
206
207         switch (template->label.style) {
208
209         case GL_TEMPLATE_STYLE_RECT:
210                 template->label.rect.w = gl_xml_get_prop_double (label_node, "width", 0);
211                 template->label.rect.h = gl_xml_get_prop_double (label_node, "height", 0);
212                 template->label.rect.r = gl_xml_get_prop_double (label_node, "round", 0);
213                 break;
214
215         case GL_TEMPLATE_STYLE_ROUND:
216                 template->label.round.r = gl_xml_get_prop_double (label_node, "radius", 0);
217                 break;
218
219         case GL_TEMPLATE_STYLE_CD:
220                 template->label.cd.r1 = gl_xml_get_prop_double (label_node, "radius", 0);
221                 template->label.cd.r2 = gl_xml_get_prop_double (label_node, "hole", 0);
222                 template->label.cd.w  = gl_xml_get_prop_double (label_node, "width", 0);
223                 template->label.cd.h  = gl_xml_get_prop_double (label_node, "height", 0);
224                 break;
225
226         default:
227                 break;
228
229         }
230
231         for (node = label_node->xmlChildrenNode; node != NULL;
232              node = node->next) {
233                 if (g_strcasecmp (node->name, "Layout") == 0) {
234                         xml_parse_layout (node, template);
235                 } else if (g_strcasecmp (node->name, "Markup") == 0) {
236                         xml_parse_markup (node, template);
237                 } else if (g_strcasecmp (node->name, "text") != 0) {
238                         g_warning ("bad node =  \"%s\"", node->name);
239                 }
240         }
241
242         gl_debug (DEBUG_TEMPLATE, "END");
243 }
244
245 /*--------------------------------------------------------------------------*/
246 /* PRIVATE.  Parse XML Sheet->Label->Layout Node.                           */
247 /*--------------------------------------------------------------------------*/
248 static void
249 xml_parse_layout (xmlNodePtr  layout_node,
250                   glTemplate *template)
251 {
252         gint        nx, ny;
253         gdouble     x0, y0, dx, dy;
254         xmlNodePtr  node;
255
256         gl_debug (DEBUG_TEMPLATE, "START");
257
258         nx = gl_xml_get_prop_int (layout_node, "nx", 1);
259         ny = gl_xml_get_prop_int (layout_node, "ny", 1);
260
261         x0 = gl_xml_get_prop_double (layout_node, "x0", 0);
262         y0 = gl_xml_get_prop_double (layout_node, "y0", 0);
263
264         dx = gl_xml_get_prop_double (layout_node, "dx", 0);
265         dy = gl_xml_get_prop_double (layout_node, "dy", 0);
266
267         for (node = layout_node->xmlChildrenNode; node != NULL;
268              node = node->next) {
269                 if (g_strcasecmp (node->name, "text") != 0) {
270                         g_warning ("bad node =  \"%s\"", node->name);
271                 }
272         }
273
274         template->label.any.layouts =
275                 g_list_append (template->label.any.layouts,
276                                gl_template_layout_new (nx, ny, x0, y0, dx, dy));
277
278         gl_debug (DEBUG_TEMPLATE, "END");
279 }
280
281 /*--------------------------------------------------------------------------*/
282 /* PRIVATE.  Parse XML Sheet->Label->Markup Node.                           */
283 /*--------------------------------------------------------------------------*/
284 static void
285 xml_parse_markup (xmlNodePtr  markup_node,
286                   glTemplate *template)
287 {
288         gchar      *type;
289         gdouble     size;
290         gdouble     x1, y1, x2, y2;
291         xmlNodePtr  node;
292
293         gl_debug (DEBUG_TEMPLATE, "START");
294
295         type = xmlGetProp (markup_node, "type");
296         if (g_strcasecmp (type, "margin") == 0) {
297
298                 size = gl_xml_get_prop_double (markup_node, "size", 0);
299
300                 template->label.any.markups =
301                         g_list_append (template->label.any.markups,
302                                        gl_template_markup_margin_new (size));
303
304         } else if (g_strcasecmp (type, "line") == 0) {
305
306                 x1 = gl_xml_get_prop_double (markup_node, "x1", 0);
307                 y1 = gl_xml_get_prop_double (markup_node, "y1", 0);
308                 x2 = gl_xml_get_prop_double (markup_node, "x2", 0);
309                 y2 = gl_xml_get_prop_double (markup_node, "y2", 0);
310
311                 template->label.any.markups =
312                         g_list_append (template->label.any.markups,
313                                        gl_template_markup_line_new (x1, y1, x2, y2));
314         }
315         g_free (type);
316
317         for (node = markup_node->xmlChildrenNode; node != NULL;
318              node = node->next) {
319                 if (g_strcasecmp (node->name, "text") != 0) {
320                         g_warning ("bad node =  \"%s\"", node->name);
321                 }
322         }
323
324         gl_debug (DEBUG_TEMPLATE, "END");
325 }
326
327 /*--------------------------------------------------------------------------*/
328 /* PRIVATE.  Parse XML Sheet->Alias Node.                                   */
329 /*--------------------------------------------------------------------------*/
330 static void
331 xml_parse_alias (xmlNodePtr  alias_node,
332                  glTemplate *template)
333 {
334         gl_debug (DEBUG_TEMPLATE, "START");
335
336         template->name = g_list_append (template->name,
337                                         xmlGetProp (alias_node, "name"));
338
339         gl_debug (DEBUG_TEMPLATE, "END");
340 }
341
342 /****************************************************************************/
343 /* Add XML Template Node                                                    */
344 /****************************************************************************/
345 void
346 gl_xml_template_add_sheet (const glTemplate *template,
347                            xmlNodePtr        root,
348                            xmlNsPtr          ns)
349 {
350         xmlNodePtr  node;
351         GList      *p;
352
353         gl_debug (DEBUG_TEMPLATE, "START");
354
355         node = xmlNewChild (root, ns, "Sheet", NULL);
356
357         xmlSetProp (node, "name", template->name->data);
358
359         xmlSetProp (node, "size", template->page_size);
360         if (g_strcasecmp (template->page_size, "Other") == 0) {
361
362                 gl_xml_set_prop_double (node, "width", template->page_width);
363                 gl_xml_set_prop_double (node, "height", template->page_height);
364
365         }
366
367         xmlSetProp (node, "description", template->description);
368
369         xml_add_label (template, node, ns);
370
371         for ( p=template->name->next; p != NULL; p=p->next ) {
372                 xml_add_alias( p->data, node, ns );
373         }
374
375         gl_debug (DEBUG_TEMPLATE, "END");
376 }
377
378 /*--------------------------------------------------------------------------*/
379 /* PRIVATE.  Add XML Sheet->Label Node.                                     */
380 /*--------------------------------------------------------------------------*/
381 static void
382 xml_add_label (const glTemplate *template,
383                xmlNodePtr        root,
384                xmlNsPtr          ns)
385 {
386         xmlNodePtr        node;
387         GList            *p;
388         glTemplateMarkup *markup;
389         glTemplateLayout *layout;
390
391         gl_debug (DEBUG_TEMPLATE, "START");
392
393         node = xmlNewChild(root, ns, "Label", NULL);
394
395         xmlSetProp (node, "id", "0");
396
397         switch (template->label.style) {
398
399         case GL_TEMPLATE_STYLE_RECT:
400                 xmlSetProp (node, "style", "rectangle");
401                 gl_xml_set_prop_double (node, "width",  template->label.rect.w);
402                 gl_xml_set_prop_double (node, "height", template->label.rect.h);
403                 gl_xml_set_prop_double (node, "round",  template->label.rect.r);
404                 break;
405
406         case GL_TEMPLATE_STYLE_ROUND:
407                 xmlSetProp (node, "style", "round");
408                 gl_xml_set_prop_double (node, "radius",  template->label.round.r);
409                 break;
410
411         case GL_TEMPLATE_STYLE_CD:
412                 xmlSetProp (node, "style", "cd");
413                 gl_xml_set_prop_double (node, "radius",  template->label.cd.r1);
414                 gl_xml_set_prop_double (node, "hole",    template->label.cd.r2);
415                 if (template->label.cd.w != 0.0) {
416                         gl_xml_set_prop_double (node, "width",  template->label.cd.w);
417                 }
418                 if (template->label.cd.h != 0.0) {
419                         gl_xml_set_prop_double (node, "height", template->label.cd.h);
420                 }
421                 break;
422
423         default:
424                 g_warning ("Unknown label style");
425                 break;
426
427         }
428
429         for ( p=template->label.any.markups; p != NULL; p=p->next ) {
430                 markup = (glTemplateMarkup *)p->data;
431                 switch (markup->type) {
432                 case GL_TEMPLATE_MARKUP_MARGIN:
433                         xml_add_markup_margin ((glTemplateMarkupMargin *)markup,
434                                                node, ns);
435                         break;
436                 case GL_TEMPLATE_MARKUP_LINE:
437                         xml_add_markup_line ((glTemplateMarkupLine *)markup,
438                                              node, ns);
439                         break;
440                 default:
441                         g_warning ("Unknown markup type");
442                         break;
443                 }
444         }
445
446         for ( p=template->label.any.layouts; p != NULL; p=p->next ) {
447                 layout = (glTemplateLayout *)p->data;
448                 xml_add_layout (layout, node, ns);
449         }
450
451         gl_debug (DEBUG_TEMPLATE, "END");
452 }
453
454 /*--------------------------------------------------------------------------*/
455 /* PRIVATE.  Add XML Sheet->Label->Layout Node.                             */
456 /*--------------------------------------------------------------------------*/
457 static void
458 xml_add_layout (glTemplateLayout *layout,
459                 xmlNodePtr        root,
460                 xmlNsPtr          ns)
461 {
462         xmlNodePtr  node;
463
464         gl_debug (DEBUG_TEMPLATE, "START");
465
466         node = xmlNewChild(root, ns, "Layout", NULL);
467         gl_xml_set_prop_int (node, "nx", layout->nx);
468         gl_xml_set_prop_int (node, "ny", layout->ny);
469         gl_xml_set_prop_double (node, "x0", layout->x0);
470         gl_xml_set_prop_double (node, "y0", layout->y0);
471         gl_xml_set_prop_double (node, "dx", layout->dx);
472         gl_xml_set_prop_double (node, "dy", layout->dy);
473
474         gl_debug (DEBUG_TEMPLATE, "END");
475 }
476
477 /*--------------------------------------------------------------------------*/
478 /* PRIVATE.  Add XML Sheet->Label->Markup (margin) Node.                    */
479 /*--------------------------------------------------------------------------*/
480 static void
481 xml_add_markup_margin (glTemplateMarkupMargin *margin,
482                        xmlNodePtr              root,
483                        xmlNsPtr                ns)
484 {
485         xmlNodePtr  node;
486
487         gl_debug (DEBUG_TEMPLATE, "START");
488
489         node = xmlNewChild(root, ns, "Markup", NULL);
490         xmlSetProp (node, "type", "margin");
491
492         gl_xml_set_prop_double (node, "size", margin->size);
493
494         gl_debug (DEBUG_TEMPLATE, "END");
495 }
496
497 /*--------------------------------------------------------------------------*/
498 /* PRIVATE.  Add XML Sheet->Label->Markup (line) Node.                      */
499 /*--------------------------------------------------------------------------*/
500 static void
501 xml_add_markup_line (glTemplateMarkupLine *line,
502                      xmlNodePtr            root,
503                      xmlNsPtr              ns)
504 {
505         xmlNodePtr  node;
506
507         gl_debug (DEBUG_TEMPLATE, "START");
508
509         node = xmlNewChild(root, ns, "Markup", NULL);
510         xmlSetProp (node, "type", "line");
511
512         gl_xml_set_prop_double (node, "x1", line->x1);
513         gl_xml_set_prop_double (node, "y1", line->y1);
514         gl_xml_set_prop_double (node, "x2", line->x2);
515         gl_xml_set_prop_double (node, "y2", line->y2);
516
517         gl_debug (DEBUG_TEMPLATE, "END");
518 }
519
520 /*--------------------------------------------------------------------------*/
521 /* PRIVATE.  Add XML Sheet->Alias Node.                                     */
522 /*--------------------------------------------------------------------------*/
523 static void
524 xml_add_alias (gchar      *name,
525                xmlNodePtr  root,
526                xmlNsPtr    ns)
527 {
528         xmlNodePtr node;
529
530         gl_debug (DEBUG_TEMPLATE, "START");
531
532         node = xmlNewChild (root, ns, "Alias", NULL);
533         xmlSetProp (node, "name", name);
534
535         gl_debug (DEBUG_TEMPLATE, "END");
536 }
537