]> git.sur5r.net Git - glabels/blob - glabels2/libglabels/paper.c
2007-10-01 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  * lgl_paper_init:
60  *
61  * Initialize libglabels paper module by reading all paper definition
62  * files located in system and user template directories.
63  *
64  * The end user would typically call lgl_init() instead.
65  */
66 void
67 lgl_paper_init (void)
68 {
69         lglPaper *other;
70
71         if (papers) {
72                 return; /* Already initialized. */
73         }
74
75         papers = read_papers ();
76
77         /* Create and append an "Other" entry. */
78         other = lgl_paper_new ("Other", _("Other"), 0.0, 0.0);
79         papers = g_list_append (papers, other);
80 }
81
82
83 /**
84  * lgl_paper_new:
85  * @id:     Id of paper definition. (E.g. US-Letter, A4, etc.)  Should be
86  *          unique.
87  * @name:   Localized name of paper.
88  * @width:  Width of paper in points.
89  * @height: Height of paper in points.
90  *
91  * Allocates and constructs a new #lglPaper structure.
92  *
93  * Returns: a pointer to a newly allocated #lglPaper structure.
94  *
95  */
96 lglPaper *
97 lgl_paper_new (gchar             *id,
98                gchar             *name,
99                gdouble            width,
100                gdouble            height)
101 {
102         lglPaper *paper;
103
104         paper         = g_new0 (lglPaper,1);
105         paper->id     = g_strdup (id);
106         paper->name   = g_strdup (name);
107         paper->width  = width;
108         paper->height = height;
109
110         return paper;
111 }
112
113
114 /**
115  * lgl_paper_dup:
116  * @orig:  #lglPaper structure to be duplicated.
117  *
118  * Duplicates an existing #lglPaper structure.
119  *
120  * Returns: a pointer to a newly allocated #lglPaper structure.
121  *
122  */
123 lglPaper *lgl_paper_dup (const lglPaper *orig)
124 {
125         lglPaper       *paper;
126
127         g_return_val_if_fail (orig, NULL);
128
129         paper = g_new0 (lglPaper,1);
130
131         paper->id     = g_strdup (orig->id);
132         paper->name   = g_strdup (orig->name);
133         paper->width  = orig->width;
134         paper->height = orig->height;
135
136         return paper;
137 }
138
139
140 /**
141  * lgl_paper_free:
142  * @paper:  pointer to #lglPaper structure to be freed.
143  *
144  * Free all memory associated with an existing #lglPaper structure.
145  *
146  */
147 void lgl_paper_free (lglPaper *paper)
148 {
149
150         if ( paper != NULL ) {
151
152                 g_free (paper->id);
153                 paper->id = NULL;
154
155                 g_free (paper->name);
156                 paper->name = NULL;
157
158                 g_free (paper);
159         }
160
161 }
162
163
164 /**
165  * lgl_paper_get_id_list:
166  *
167  * Get a list of all paper ids known to libglabels.
168  *
169  * Returns: a list of paper ids.
170  *
171  */
172 GList *
173 lgl_paper_get_id_list (void)
174 {
175         GList           *ids = NULL;
176         GList           *p;
177         lglPaper        *paper;
178
179         if (!papers) {
180                 lgl_paper_init ();
181         }
182
183         for ( p=papers; p != NULL; p=p->next ) {
184                 paper = (lglPaper *)p->data;
185                 ids = g_list_append (ids, g_strdup (paper->id));
186         }
187
188         return ids;
189 }
190
191 /**
192  * lgl_paper_free_id_list:
193  * @ids: List of id strings to be freed.
194  *
195  * Free up all storage associated with an id list obtained with
196  * lgl_paper_get_id_list().
197  *
198  */
199 void
200 lgl_paper_free_id_list (GList *ids)
201 {
202         GList *p;
203
204         for (p = ids; p != NULL; p = p->next) {
205                 g_free (p->data);
206                 p->data = NULL;
207         }
208
209         g_list_free (ids);
210 }
211
212
213 /**
214  * lgl_paper_get_name_list:
215  *
216  * Get a list of all localized paper names known to libglabels.
217  *
218  * Returns: a list of localized paper names.
219  *
220  */
221 GList *
222 lgl_paper_get_name_list (void)
223 {
224         GList           *names = NULL;
225         GList           *p;
226         lglPaper        *paper;
227
228         if (!papers) {
229                 lgl_paper_init ();
230         }
231
232         for ( p=papers; p != NULL; p=p->next ) {
233                 paper = (lglPaper *)p->data;
234                 names = g_list_append (names, g_strdup (paper->name));
235         }
236
237         return names;
238 }
239
240
241 /**
242  * lgl_paper_free_name_list:
243  * @names: List of localized paper name strings to be freed.
244  *
245  * Free up all storage associated with a name list obtained with
246  * lgl_paper_get_name_list().
247  *
248  */
249 void
250 lgl_paper_free_name_list (GList *names)
251 {
252         GList *p;
253
254         for (p = names; p != NULL; p = p->next) {
255                 g_free (p->data);
256                 p->data = NULL;
257         }
258
259         g_list_free (names);
260 }
261
262
263 /**
264  * lgl_paper_is_id_known:
265  * @id: paper id to test
266  *
267  * Determine if given paper id is known to libglabels.
268  *
269  * Returns: TRUE if id is known, otherwise FALSE.
270  *
271  */
272 gboolean
273 lgl_paper_is_id_known (const gchar *id)
274 {
275         GList       *p;
276         lglPaper    *paper;
277
278         if (!papers) {
279                 lgl_paper_init ();
280         }
281
282         if (id == NULL) {
283                 return FALSE;
284         }
285
286         for (p = papers; p != NULL; p = p->next) {
287                 paper = (lglPaper *) p->data;
288                 if (g_strcasecmp (paper->id, id) == 0) {
289                         return TRUE;
290                 }
291         }
292
293         return FALSE;
294 }
295
296
297 /**
298  * lgl_paper_is_id_other:
299  * @id: paper id to test
300  *
301  * Determine if given paper id is the special id "Other."
302  *
303  * Returns: TRUE if id is "Other", otherwise FALSE.
304  *
305  */
306 gboolean
307 lgl_paper_is_id_other (const gchar *id)
308 {
309         if (id == NULL) {
310                 return FALSE;
311         }
312
313         return (g_strcasecmp (id, "Other") == 0);
314 }
315
316
317 /**
318  * lgl_paper_from_id:
319  * @id: paper id string
320  *
321  * Lookup paper definition from id string.
322  *
323  * Returns: pointer to a newly allocated #lglPaper structure.
324  *
325  */
326 lglPaper *
327 lgl_paper_from_id (const gchar *id)
328 {
329         GList       *p;
330         lglPaper    *paper;
331
332         if (!papers) {
333                 lgl_paper_init ();
334         }
335
336         if (id == NULL) {
337                 /* If no id, return first paper as a default */
338                 return lgl_paper_dup ((lglPaper *) papers->data);
339         }
340
341         for (p = papers; p != NULL; p = p->next) {
342                 paper = (lglPaper *) p->data;
343                 if (g_strcasecmp (paper->id, id) == 0) {
344                         return lgl_paper_dup (paper);
345                 }
346         }
347
348         return NULL;
349 }
350
351
352 /**
353  * lgl_paper_from_name:
354  * @name: localized paper name string
355  *
356  * Lookup paper definition from localized paper name string.
357  *
358  * Returns: pointer to a newly allocated #lglPaper structure.
359  *
360  */
361 lglPaper *
362 lgl_paper_from_name (const gchar *name)
363 {
364         GList       *p;
365         lglPaper    *paper;
366
367         if (!papers) {
368                 lgl_paper_init ();
369         }
370
371         if (name == NULL) {
372                 /* If no name, return first paper as a default */
373                 return lgl_paper_dup ((lglPaper *) papers->data);
374         }
375
376         for (p = papers; p != NULL; p = p->next) {
377                 paper = (lglPaper *) p->data;
378                 if (g_strcasecmp (paper->name, name) == 0) {
379                         return lgl_paper_dup (paper);
380                 }
381         }
382
383         return NULL;
384 }
385
386
387 /**
388  * lgl_paper_lookup_id_from_name:
389  * @name: localized paper name stringp
390  *
391  * Lookup paper name string from localized paper name string.
392  *
393  * Returns: pointer to a newly allocated id string.
394  *
395  */
396 gchar *
397 lgl_paper_lookup_id_from_name (const gchar       *name)
398 {
399         lglPaper *paper = NULL;
400         gchar    *id = NULL;
401
402         if (name != NULL)
403         {
404                 paper = lgl_paper_from_name (name);
405                 if ( paper != NULL )
406                 {
407                         id = g_strdup (paper->id);
408                         lgl_paper_free (paper);
409                         paper = NULL;
410                 }
411         }
412
413         return id;
414 }
415
416 /**
417  * lgl_paper_lookup_name_from_id:
418  * @id: paper id string
419  *
420  * Lookup localized paper name string from paper id string.
421  *
422  * Returns: pointer to a newly allocated localized paper name string.
423  *
424  */
425 gchar *
426 lgl_paper_lookup_name_from_id (const gchar       *id)
427 {
428         lglPaper *paper = NULL;
429         gchar    *name = NULL;
430
431         if (id != NULL)
432         {
433                 paper = lgl_paper_from_id (id);
434                 if ( paper != NULL )
435                 {
436                         name = g_strdup (paper->name);
437                         lgl_paper_free (paper);
438                         paper = NULL;
439                 }
440         }
441
442         return name;
443 }
444
445 /*--------------------------------------------------------------------------*/
446 /* PRIVATE.  Read papers from various  files.                               */
447 /*--------------------------------------------------------------------------*/
448 static GList *
449 read_papers (void)
450 {
451         gchar *data_dir;
452         GList *papers = NULL;
453
454         data_dir = LGL_SYSTEM_DATA_DIR;
455         papers = read_paper_files_from_dir (papers, data_dir);
456         g_free (data_dir);
457
458         data_dir = LGL_USER_DATA_DIR;
459         papers = read_paper_files_from_dir (papers, data_dir);
460         g_free (data_dir);
461
462         if (papers == NULL) {
463                 g_critical (_("Unable to locate paper size definitions.  Libglabels may not be installed correctly!"));
464         }
465
466         return papers;
467 }
468
469 /*--------------------------------------------------------------------------*/
470 /* PRIVATE.  Read all paper files from given directory.  Append to list.    */
471 /*--------------------------------------------------------------------------*/
472 static GList *
473 read_paper_files_from_dir (GList       *papers,
474                            const gchar *dirname)
475 {
476         GDir        *dp;
477         const gchar *filename, *extension;
478         gchar       *full_filename = NULL;
479         GError      *gerror = NULL;
480         GList       *new_papers = NULL;
481
482         if (dirname == NULL) {
483                 return papers;
484         }
485
486         if (!g_file_test (dirname, G_FILE_TEST_EXISTS)) {
487                 return papers;
488         }
489
490         dp = g_dir_open (dirname, 0, &gerror);
491         if (gerror != NULL) {
492                 g_message ("cannot open data directory: %s", gerror->message );
493                 return papers;
494         }
495
496         while ((filename = g_dir_read_name (dp)) != NULL) {
497
498                 extension = strrchr (filename, '.');
499
500                 if (extension != NULL) {
501
502                         if ( (g_strcasecmp (extension, ".paper") == 0)
503                              || (g_strcasecmp (filename, "paper-sizes.xml") == 0) ) {
504
505                                 full_filename =
506                                     g_build_filename (dirname, filename, NULL);
507                                 new_papers =
508                                     lgl_xml_paper_read_papers_from_file (full_filename);
509                                 g_free (full_filename);
510
511                                 papers = g_list_concat (papers, new_papers);
512                                 new_papers = NULL;
513
514                         }
515
516                 }
517
518         }
519
520         g_dir_close (dp);
521
522         return papers;
523 }
524
525
526 /**
527  * lgl_paper_print_known_papers:
528  *
529  * For debugging purposes: print a list of all paper definitions known to
530  * libglabels.
531  *
532  */
533 void
534 lgl_paper_print_known_papers (void)
535 {
536         GList       *p;
537         lglPaper    *paper;
538
539         if (!papers) {
540                 lgl_paper_init ();
541         }
542
543         g_print ("%s():\n", __FUNCTION__);
544         for (p = papers; p != NULL; p = p->next) {
545                 paper = (lglPaper *) p->data;
546
547                 g_print ("PAPER id=\"%s\", name=\"%s\", width=%gpts, height=%gpts\n",
548                          paper->id, paper->name, paper->width, paper->height);
549
550         }
551         g_print ("\n");
552
553 }
554
555