]> git.sur5r.net Git - glabels/blob - glabels2/libglabels/paper.c
2006-09-12 Jim Evins <evins@snaught.com>
[glabels] / glabels2 / libglabels / paper.c
1 /*
2  *  (LIBGLABELS) Template library for GLABELS
3  *
4  *  paper.c:  paper module
5  *
6  *  Copyright (C) 2003, 2004  Jim Evins <evins@snaught.com>.
7  *
8  *  This file is part of the LIBGLABELS library.
9  *
10  *  This library is free software; you can redistribute it and/or
11  *  modify it under the terms of the GNU Library General Public
12  *  License as published by the Free Software Foundation; either
13  *  version 2 of the License, or (at your option) any later version.
14  *
15  *  This library is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  *  Library General Public License for more details.
19  *
20  *  You should have received a copy of the GNU Library General Public
21  *  License along with this library; if not, write to the Free
22  *  Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23  *  MA 02111-1307, USA
24  */
25 #include <config.h>
26
27 #include "paper.h"
28
29 #include <glib/gi18n.h>
30 #include <glib/gmem.h>
31 #include <glib/gstrfuncs.h>
32 #include <glib/gdir.h>
33 #include <glib/gmessages.h>
34 #include <string.h>
35
36 #include "libglabels-private.h"
37
38 #include "xml-paper.h"
39
40 /*===========================================*/
41 /* Private types                             */
42 /*===========================================*/
43
44 /*===========================================*/
45 /* Private globals                           */
46 /*===========================================*/
47
48 static GList *papers = NULL;
49
50 /*===========================================*/
51 /* Local function prototypes                 */
52 /*===========================================*/
53
54 static GList *read_papers (void);
55 static GList *read_paper_files_from_dir (GList       *papers,
56                                          const gchar *dirname);
57
58 /**
59  * gl_paper_init:
60  *
61  * Initialize libglabels paper module by reading all paper definition
62  * files located in system and user template directories.
63  */
64 void
65 gl_paper_init (void)
66 {
67         glPaper *other;
68
69         if (papers) {
70                 return; /* Already initialized. */
71         }
72
73         papers = read_papers ();
74
75         /* Create and append an "Other" entry. */
76         other = gl_paper_new ("Other", _("Other"), 0.0, 0.0);
77         papers = g_list_append (papers, other);
78 }
79
80
81 /**
82  * gl_paper_new:
83  * @id:     Id of paper definition. (E.g. US-Letter, A4, etc.)  Should be
84  *          unique.
85  * @name:   Localized name of paper.
86  * @width:  Width of paper in points.
87  * @height: Height of paper in points.
88  *
89  * Allocates and constructs a new #glPaper structure.
90  *
91  * Returns: a pointer to a newly allocated #glPaper structure.
92  *
93  */
94 glPaper *
95 gl_paper_new (gchar             *id,
96               gchar             *name,
97               gdouble            width,
98               gdouble            height)
99 {
100         glPaper *paper;
101
102         paper         = g_new0 (glPaper,1);
103         paper->id     = g_strdup (id);
104         paper->name   = g_strdup (name);
105         paper->width  = width;
106         paper->height = height;
107
108         return paper;
109 }
110
111
112 /**
113  * gl_paper_dup:
114  * @orig:  #glPaper structure to be duplicated.
115  *
116  * Duplicates an existing #glPaper structure.
117  *
118  * Returns: a pointer to a newly allocated #glPaper structure.
119  *
120  */
121 glPaper *gl_paper_dup (const glPaper *orig)
122 {
123         glPaper       *paper;
124
125         g_return_val_if_fail (orig, NULL);
126
127         paper = g_new0 (glPaper,1);
128
129         paper->id     = g_strdup (orig->id);
130         paper->name   = g_strdup (orig->name);
131         paper->width  = orig->width;
132         paper->height = orig->height;
133
134         return paper;
135 }
136
137
138 /**
139  * gl_paper_free:
140  * @paper:  pointer to #glPaper structure to be freed.
141  *
142  * Free all memory associated with an existing #glPaper structure.
143  *
144  */
145 void gl_paper_free (glPaper *paper)
146 {
147
148         if ( paper != NULL ) {
149
150                 g_free (paper->id);
151                 paper->id = NULL;
152
153                 g_free (paper->name);
154                 paper->name = NULL;
155
156                 g_free (paper);
157         }
158
159 }
160
161
162 /**
163  * gl_paper_get_id_list:
164  *
165  * Get a list of all paper ids known to libglabels.
166  *
167  * Returns: a list of paper ids.
168  *
169  */
170 GList *
171 gl_paper_get_id_list (void)
172 {
173         GList           *ids = NULL;
174         GList           *p;
175         glPaper         *paper;
176
177         if (!papers) {
178                 gl_paper_init ();
179         }
180
181         for ( p=papers; p != NULL; p=p->next ) {
182                 paper = (glPaper *)p->data;
183                 ids = g_list_append (ids, g_strdup (paper->id));
184         }
185
186         return ids;
187 }
188
189 /**
190  * gl_paper_free_id_list:
191  * @ids: List of id strings to be freed.
192  *
193  * Free up all storage associated with an id list obtained with
194  * gl_paper_get_id_list().
195  *
196  */
197 void
198 gl_paper_free_id_list (GList *ids)
199 {
200         GList *p;
201
202         for (p = ids; p != NULL; p = p->next) {
203                 g_free (p->data);
204                 p->data = NULL;
205         }
206
207         g_list_free (ids);
208 }
209
210
211 /**
212  * gl_paper_get_name_list:
213  *
214  * Get a list of all localized paper names known to libglabels.
215  *
216  * Returns: a list of localized paper names.
217  *
218  */
219 GList *
220 gl_paper_get_name_list (void)
221 {
222         GList           *names = NULL;
223         GList           *p;
224         glPaper         *paper;
225
226         if (!papers) {
227                 gl_paper_init ();
228         }
229
230         for ( p=papers; p != NULL; p=p->next ) {
231                 paper = (glPaper *)p->data;
232                 names = g_list_append (names, g_strdup (paper->name));
233         }
234
235         return names;
236 }
237
238
239 /**
240  * gl_paper_free_name_list:
241  * @names: List of localized paper name strings to be freed.
242  *
243  * Free up all storage associated with a name list obtained with
244  * gl_paper_get_name_list().
245  *
246  */
247 void
248 gl_paper_free_name_list (GList *names)
249 {
250         GList *p;
251
252         for (p = names; p != NULL; p = p->next) {
253                 g_free (p->data);
254                 p->data = NULL;
255         }
256
257         g_list_free (names);
258 }
259
260
261 /**
262  * gl_paper_is_id_known:
263  * @id: paper id to test
264  *
265  * Determine if given paper id is known to libglabels.
266  *
267  * Returns: TRUE if id is known, otherwise FALSE.
268  *
269  */
270 gboolean
271 gl_paper_is_id_known (const gchar *id)
272 {
273         GList       *p;
274         glPaper     *paper;
275
276         if (!papers) {
277                 gl_paper_init ();
278         }
279
280         if (id == NULL) {
281                 return FALSE;
282         }
283
284         for (p = papers; p != NULL; p = p->next) {
285                 paper = (glPaper *) p->data;
286                 if (g_strcasecmp (paper->id, id) == 0) {
287                         return TRUE;
288                 }
289         }
290
291         return FALSE;
292 }
293
294
295 /**
296  * gl_paper_is_id_other:
297  * @id: paper id to test
298  *
299  * Determine if given paper id is the special id "Other."
300  *
301  * Returns: TRUE if id is "Other", otherwise FALSE.
302  *
303  */
304 gboolean
305 gl_paper_is_id_other (const gchar *id)
306 {
307         if (id == NULL) {
308                 return FALSE;
309         }
310
311         return (g_strcasecmp (id, "Other") == 0);
312 }
313
314
315 /**
316  * gl_paper_from_id:
317  * @id: paper id string
318  *
319  * Lookup paper definition from id string.
320  *
321  * Returns: pointer to a newly allocated #glPaper structure.
322  *
323  */
324 glPaper *
325 gl_paper_from_id (const gchar *id)
326 {
327         GList       *p;
328         glPaper     *paper;
329
330         if (!papers) {
331                 gl_paper_init ();
332         }
333
334         if (id == NULL) {
335                 /* If no id, return first paper as a default */
336                 return gl_paper_dup ((glPaper *) papers->data);
337         }
338
339         for (p = papers; p != NULL; p = p->next) {
340                 paper = (glPaper *) p->data;
341                 if (g_strcasecmp (paper->id, id) == 0) {
342                         return gl_paper_dup (paper);
343                 }
344         }
345
346         return NULL;
347 }
348
349
350 /**
351  * gl_paper_from_name:
352  * @name: localized paper name string
353  *
354  * Lookup paper definition from localized paper name string.
355  *
356  * Returns: pointer to a newly allocated #glPaper structure.
357  *
358  */
359 glPaper *
360 gl_paper_from_name (const gchar *name)
361 {
362         GList       *p;
363         glPaper     *paper;
364
365         if (!papers) {
366                 gl_paper_init ();
367         }
368
369         if (name == NULL) {
370                 /* If no name, return first paper as a default */
371                 return gl_paper_dup ((glPaper *) papers->data);
372         }
373
374         for (p = papers; p != NULL; p = p->next) {
375                 paper = (glPaper *) p->data;
376                 if (g_strcasecmp (paper->name, name) == 0) {
377                         return gl_paper_dup (paper);
378                 }
379         }
380
381         return NULL;
382 }
383
384
385 /**
386  * gl_paper_lookup_id_from_name:
387  * @name: localized paper name stringp
388  *
389  * Lookup paper name string from localized paper name string.
390  *
391  * Returns: pointer to a newly allocated id string.
392  *
393  */
394 gchar *
395 gl_paper_lookup_id_from_name (const gchar       *name)
396 {
397         glPaper *paper = NULL;
398         gchar   *id = NULL;
399
400         if (name != NULL)
401         {
402                 paper = gl_paper_from_name (name);
403                 if ( paper != NULL )
404                 {
405                         id = g_strdup (paper->id);
406                         gl_paper_free (paper);
407                         paper = NULL;
408                 }
409         }
410
411         return id;
412 }
413
414 /**
415  * gl_paper_lookup_name_from_id:
416  * @id: paper id string
417  *
418  * Lookup localized paper name string from paper id string.
419  *
420  * Returns: pointer to a newly allocated localized paper name string.
421  *
422  */
423 gchar *
424 gl_paper_lookup_name_from_id (const gchar       *id)
425 {
426         glPaper *paper = NULL;
427         gchar   *name = NULL;
428
429         if (id != NULL)
430         {
431                 paper = gl_paper_from_id (id);
432                 if ( paper != NULL )
433                 {
434                         name = g_strdup (paper->name);
435                         gl_paper_free (paper);
436                         paper = NULL;
437                 }
438         }
439
440         return name;
441 }
442
443 /*--------------------------------------------------------------------------*/
444 /* PRIVATE.  Read papers from various  files.                               */
445 /*--------------------------------------------------------------------------*/
446 static GList *
447 read_papers (void)
448 {
449         gchar *data_dir;
450         GList *papers = NULL;
451
452         data_dir = GL_SYSTEM_DATA_DIR;
453         papers = read_paper_files_from_dir (papers, data_dir);
454         g_free (data_dir);
455
456         data_dir = GL_USER_DATA_DIR;
457         papers = read_paper_files_from_dir (papers, data_dir);
458         g_free (data_dir);
459
460         if (papers == NULL) {
461                 g_critical (_("Unable to locate paper size definitions.  Libglabels may not be installed correctly!"));
462         }
463
464         return papers;
465 }
466
467 /*--------------------------------------------------------------------------*/
468 /* PRIVATE.  Read all paper files from given directory.  Append to list.    */
469 /*--------------------------------------------------------------------------*/
470 static GList *
471 read_paper_files_from_dir (GList       *papers,
472                            const gchar *dirname)
473 {
474         GDir        *dp;
475         const gchar *filename, *extension;
476         gchar       *full_filename = NULL;
477         GError      *gerror = NULL;
478         GList       *new_papers = NULL;
479
480         if (dirname == NULL) {
481                 return papers;
482         }
483
484         if (!g_file_test (dirname, G_FILE_TEST_EXISTS)) {
485                 return papers;
486         }
487
488         dp = g_dir_open (dirname, 0, &gerror);
489         if (gerror != NULL) {
490                 g_message ("cannot open data directory: %s", gerror->message );
491                 return papers;
492         }
493
494         while ((filename = g_dir_read_name (dp)) != NULL) {
495
496                 extension = strrchr (filename, '.');
497
498                 if (extension != NULL) {
499
500                         if ( (g_strcasecmp (extension, ".paper") == 0)
501                              || (g_strcasecmp (filename, "paper-sizes.xml") == 0) ) {
502
503                                 full_filename =
504                                     g_build_filename (dirname, filename, NULL);
505                                 new_papers =
506                                     gl_xml_paper_read_papers_from_file (full_filename);
507                                 g_free (full_filename);
508
509                                 papers = g_list_concat (papers, new_papers);
510                                 new_papers = NULL;
511
512                         }
513
514                 }
515
516         }
517
518         g_dir_close (dp);
519
520         return papers;
521 }
522
523
524 /**
525  * gl_paper_print_known_papers:
526  *
527  * For debugging purposes: print a list of all paper definitions known to
528  * libglabels.
529  *
530  */
531 void
532 gl_paper_print_known_papers (void)
533 {
534         GList       *p;
535         glPaper     *paper;
536
537         if (!papers) {
538                 gl_paper_init ();
539         }
540
541         g_print ("%s():\n", __FUNCTION__);
542         for (p = papers; p != NULL; p = p->next) {
543                 paper = (glPaper *) p->data;
544
545                 g_print ("PAPER id=\"%s\", name=\"%s\", width=%gpts, height=%gpts\n",
546                          paper->id, paper->name, paper->width, paper->height);
547
548         }
549         g_print ("\n");
550
551 }
552
553