]> git.sur5r.net Git - glabels/commitdiff
Renamed libglabels source files to have "lgl-" prefix.
authorJim Evins <evins@snaught.com>
Sun, 19 Dec 2010 04:11:04 +0000 (23:11 -0500)
committerJim Evins <evins@snaught.com>
Sun, 19 Dec 2010 04:11:04 +0000 (23:11 -0500)
Improve odds that source files (headers in particular) remain
unique.

53 files changed:
docs/libglabels/libglabels-3.0-sections.txt
libglabels/Makefile.am
libglabels/category.c [deleted file]
libglabels/category.h [deleted file]
libglabels/db.c [deleted file]
libglabels/db.h [deleted file]
libglabels/lgl-category.c [new file with mode: 0644]
libglabels/lgl-category.h [new file with mode: 0644]
libglabels/lgl-db.c [new file with mode: 0644]
libglabels/lgl-db.h [new file with mode: 0644]
libglabels/lgl-paper.c [new file with mode: 0644]
libglabels/lgl-paper.h [new file with mode: 0644]
libglabels/lgl-str.c [new file with mode: 0644]
libglabels/lgl-str.h [new file with mode: 0644]
libglabels/lgl-template.c [new file with mode: 0644]
libglabels/lgl-template.h [new file with mode: 0644]
libglabels/lgl-units.c [new file with mode: 0644]
libglabels/lgl-units.h [new file with mode: 0644]
libglabels/lgl-vendor.c [new file with mode: 0644]
libglabels/lgl-vendor.h [new file with mode: 0644]
libglabels/lgl-xml-category.c [new file with mode: 0644]
libglabels/lgl-xml-category.h [new file with mode: 0644]
libglabels/lgl-xml-paper.c [new file with mode: 0644]
libglabels/lgl-xml-paper.h [new file with mode: 0644]
libglabels/lgl-xml-template.c [new file with mode: 0644]
libglabels/lgl-xml-template.h [new file with mode: 0644]
libglabels/lgl-xml-vendor.c [new file with mode: 0644]
libglabels/lgl-xml-vendor.h [new file with mode: 0644]
libglabels/lgl-xml.c [new file with mode: 0644]
libglabels/lgl-xml.h [new file with mode: 0644]
libglabels/libglabels-private.h
libglabels/libglabels.h
libglabels/paper.c [deleted file]
libglabels/paper.h [deleted file]
libglabels/str.c [deleted file]
libglabels/str.h [deleted file]
libglabels/template.c [deleted file]
libglabels/template.h [deleted file]
libglabels/units.c [deleted file]
libglabels/units.h [deleted file]
libglabels/vendor.c [deleted file]
libglabels/vendor.h [deleted file]
libglabels/xml-category.c [deleted file]
libglabels/xml-category.h [deleted file]
libglabels/xml-paper.c [deleted file]
libglabels/xml-paper.h [deleted file]
libglabels/xml-template.c [deleted file]
libglabels/xml-template.h [deleted file]
libglabels/xml-vendor.c [deleted file]
libglabels/xml-vendor.h [deleted file]
libglabels/xml.c [deleted file]
libglabels/xml.h [deleted file]
po/POTFILES.in

index 5323ab0fc664d0d57b3cd0668d61235550e4f5c0..7efab0c5a732b328f70a9713e45596a5c829d006 100644 (file)
@@ -1,6 +1,6 @@
 <SECTION>
 <FILE>db</FILE>
-<INCLUDE>libglabels/db.h</INCLUDE>
+<INCLUDE>libglabels/lgl-db.h</INCLUDE>
 lglDbRegStatus
 lglDbDeleteStatus
 <SUBSECTION Init Functions>
@@ -58,7 +58,7 @@ lgl_db_print_known_vendors
 
 <SECTION>
 <FILE>template</FILE>
-<INCLUDE>libglabels/template.h</INCLUDE>
+<INCLUDE>libglabels/lgl-template.h</INCLUDE>
 lglTemplate
 <SUBSECTION Frame Structure>
 lglTemplateFrameShape
@@ -127,7 +127,7 @@ lgl_template_print
 
 <SECTION>
 <FILE>paper</FILE>
-<INCLUDE>libglabels/paper.h</INCLUDE>
+<INCLUDE>libglabels/lgl-paper.h</INCLUDE>
 lglPaper
 lgl_paper_new
 lgl_paper_dup
@@ -136,7 +136,7 @@ lgl_paper_free
 
 <SECTION>
 <FILE>category</FILE>
-<INCLUDE>libglabels/category.h</INCLUDE>
+<INCLUDE>libglabels/lgl-category.h</INCLUDE>
 lglCategory
 lgl_category_new
 lgl_category_dup
@@ -145,7 +145,7 @@ lgl_category_free
 
 <SECTION>
 <FILE>vendor</FILE>
-<INCLUDE>libglabels/vendor.h</INCLUDE>
+<INCLUDE>libglabels/lgl-vendor.h</INCLUDE>
 lglVendor
 lgl_vendor_new
 lgl_vendor_dup
@@ -154,7 +154,7 @@ lgl_vendor_free
 
 <SECTION>
 <FILE>xml-paper</FILE>
-<INCLUDE>libglabels/xml-paper.h</INCLUDE>
+<INCLUDE>libglabels/lgl-xml-paper.h</INCLUDE>
 lgl_xml_paper_read_papers_from_file
 lgl_xml_paper_parse_papers_doc
 lgl_xml_paper_parse_paper_node
@@ -162,7 +162,7 @@ lgl_xml_paper_parse_paper_node
 
 <SECTION>
 <FILE>xml-category</FILE>
-<INCLUDE>libglabels/xml-category.h</INCLUDE>
+<INCLUDE>libglabels/lgl-xml-category.h</INCLUDE>
 lgl_xml_category_read_categories_from_file
 lgl_xml_category_parse_categories_doc
 lgl_xml_category_parse_category_node
@@ -170,7 +170,7 @@ lgl_xml_category_parse_category_node
 
 <SECTION>
 <FILE>xml-template</FILE>
-<INCLUDE>libglabels/xml-templates.h</INCLUDE>
+<INCLUDE>libglabels/lgl-xml-templates.h</INCLUDE>
 lgl_xml_template_read_templates_from_file
 lgl_xml_template_parse_templates_doc
 lgl_xml_template_parse_template_node
@@ -181,7 +181,7 @@ lgl_xml_template_create_template_node
 
 <SECTION>
 <FILE>xml-vendor</FILE>
-<INCLUDE>libglabels/xml-vendor.h</INCLUDE>
+<INCLUDE>libglabels/lgl-xml-vendor.h</INCLUDE>
 lgl_xml_vendor_read_vendors_from_file
 lgl_xml_vendor_parse_vendors_doc
 lgl_xml_vendor_parse_vendor_node
@@ -189,7 +189,7 @@ lgl_xml_vendor_parse_vendor_node
 
 <SECTION>
 <FILE>xml</FILE>
-<INCLUDE>libglabels/xml.h</INCLUDE>
+<INCLUDE>libglabels/lgl-xml.h</INCLUDE>
 LGL_XML_NAME_SPACE
 <SUBSECTION Get Property Functions>
 lgl_xml_get_prop_string
@@ -215,7 +215,7 @@ lgl_xml_set_default_units
 
 <SECTION>
 <FILE>units</FILE>
-<INCLUDE>libglabels/units.h</INCLUDE>
+<INCLUDE>libglabels/lgl-units.h</INCLUDE>
 lglUnits
 lgl_units_get_id
 lgl_units_from_id
@@ -227,7 +227,7 @@ lgl_units_get_units_per_point
 
 <SECTION>
 <FILE>str</FILE>
-<INCLUDE>libglabels/str.h</INCLUDE>
+<INCLUDE>libglabels/lgl-str.h</INCLUDE>
 lgl_str_utf8_casecmp
 lgl_str_part_name_cmp
 lgl_str_format_fraction
index 4d43f5c02c2af0fae2b52e95849a4555f69faeda..f9013460da0d913f7038e26dcfd598433ebf6edf 100644 (file)
@@ -12,32 +12,32 @@ libglabels_3_0_la_LDFLAGS=\
 
 lib_LTLIBRARIES = libglabels-3.0.la
 
-libglabels_3_0_la_SOURCES =            \
+libglabels_3_0_la_SOURCES =    \
        libglabels-private.h    \
-       db.h                    \
-       db.c                    \
-       units.h                 \
-       units.c                 \
-       paper.h                 \
-       paper.c                 \
-       category.h              \
-       category.c              \
-       vendor.h                \
-       vendor.c                \
-       template.h              \
-       template.c              \
-       xml-paper.h             \
-       xml-paper.c             \
-       xml-category.h          \
-       xml-category.c          \
-       xml-vendor.h            \
-       xml-vendor.c            \
-       xml-template.h          \
-       xml-template.c          \
-       xml.h                   \
-       xml.c                   \
-       str.h                   \
-       str.c
+       lgl-db.h                \
+       lgl-db.c                \
+       lgl-units.h             \
+       lgl-units.c             \
+       lgl-paper.h             \
+       lgl-paper.c             \
+       lgl-category.h          \
+       lgl-category.c          \
+       lgl-vendor.h            \
+       lgl-vendor.c            \
+       lgl-template.h          \
+       lgl-template.c          \
+       lgl-xml-paper.h         \
+       lgl-xml-paper.c         \
+       lgl-xml-category.h      \
+       lgl-xml-category.c      \
+       lgl-xml-vendor.h        \
+       lgl-xml-vendor.c        \
+       lgl-xml-template.h      \
+       lgl-xml-template.c      \
+       lgl-xml.h               \
+       lgl-xml.c               \
+       lgl-str.h               \
+       lgl-str.c
 
 libglabels_3_0includedir=$(includedir)/$(LIBGLABELS_BRANCH)
 
@@ -46,17 +46,17 @@ libglabels_3_0include_HEADERS =     \
 
 libglabels_3_0subincludedir=$(includedir)/$(LIBGLABELS_BRANCH)/libglabels
 
-libglabels_3_0subinclude_HEADERS =     \
-       db.h                    \
-       units.h                 \
-       paper.h                 \
-       category.h              \
-       template.h              \
-       xml-paper.h             \
-       xml-category.h          \
-       xml-template.h          \
-       xml.h                   \
-       str.h                   
+libglabels_3_0subinclude_HEADERS =  \
+       lgl-db.h                \
+       lgl-units.h             \
+       lgl-paper.h             \
+       lgl-category.h          \
+       lgl-template.h          \
+       lgl-xml-paper.h         \
+       lgl-xml-category.h      \
+       lgl-xml-template.h      \
+       lgl-xml.h               \
+       lgl-str.h                       
 
 EXTRA_DIST =                   \
        $(LIBGLABELS_BRANCH).pc.in
diff --git a/libglabels/category.c b/libglabels/category.c
deleted file mode 100644 (file)
index f7f4052..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- *  category.c
- *  Copyright (C) 2006-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-
-#include "category.h"
-
-#include <glib/gi18n.h>
-#include <glib.h>
-#include <string.h>
-
-#include "libglabels-private.h"
-
-
-/*===========================================*/
-/* Private types                             */
-/*===========================================*/
-
-
-/*===========================================*/
-/* Private globals                           */
-/*===========================================*/
-
-
-/*===========================================*/
-/* Local function prototypes                 */
-/*===========================================*/
-
-
-/*===========================================*/
-/* Functions.                                */
-/*===========================================*/
-
-/**
- * lgl_category_new:
- * @id:     Id of category definition. (E.g. label, card, etc.)  Should be
- *          unique.
- * @name:   Localized name of category.
- *
- * Allocates and constructs a new #lglCategory structure.
- *
- * Returns: a pointer to a newly allocated #lglCategory structure.
- *
- */
-lglCategory *
-lgl_category_new (gchar             *id,
-                  gchar             *name)
-{
-       lglCategory *category;
-
-       category         = g_new0 (lglCategory,1);
-       category->id     = g_strdup (id);
-       category->name   = g_strdup (name);
-
-       return category;
-}
-
-
-/**
- * lgl_category_dup:
- * @orig:  #lglCategory structure to be duplicated.
- *
- * Duplicates an existing #lglCategory structure.
- *
- * Returns: a pointer to a newly allocated #lglCategory structure.
- *
- */
-lglCategory *lgl_category_dup (const lglCategory *orig)
-{
-       lglCategory       *category;
-
-       g_return_val_if_fail (orig, NULL);
-
-       category = g_new0 (lglCategory,1);
-
-       category->id     = g_strdup (orig->id);
-       category->name   = g_strdup (orig->name);
-
-       return category;
-}
-
-
-/**
- * lgl_category_free:
- * @category:  pointer to #lglCategory structure to be freed.
- *
- * Free all memory associated with an existing #lglCategory structure.
- *
- */
-void lgl_category_free (lglCategory *category)
-{
-
-       if ( category != NULL ) {
-
-               g_free (category->id);
-               category->id = NULL;
-
-               g_free (category->name);
-               category->name = NULL;
-
-               g_free (category);
-       }
-
-}
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/category.h b/libglabels/category.h
deleted file mode 100644 (file)
index b62b906..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *  category.h
- *  Copyright (C) 2006-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __LGL_CATEGORY_H__
-#define __LGL_CATEGORY_H__
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-/*
- *   Template class
- */
-typedef struct _lglCategory lglCategory;
-
-struct _lglCategory {
-       gchar               *id;     /* Unique ID of category */
-       gchar               *name;   /* Localized name of category */
-};
-
-
-/*
- * Category construction
- */
-lglCategory      *lgl_category_new                 (gchar             *id,
-                                                    gchar             *name);
-
-lglCategory      *lgl_category_dup                 (const lglCategory *orig);
-void              lgl_category_free                (lglCategory       *category);
-
-
-G_END_DECLS
-
-#endif /* __LGL_CATEGORY_H__ */
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/db.c b/libglabels/db.c
deleted file mode 100644 (file)
index daf914c..0000000
+++ /dev/null
@@ -1,2103 +0,0 @@
-/*
- *  db.c
- *  Copyright (C) 2003-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-
-#include "db.h"
-
-#include <glib/gi18n.h>
-#include <glib.h>
-#include <glib/gstdio.h>
-#include <glib-object.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "libglabels-private.h"
-
-#include "xml-paper.h"
-#include "xml-category.h"
-#include "xml-vendor.h"
-#include "xml-template.h"
-
-/*===========================================*/
-/* Private macros and constants.             */
-/*===========================================*/
-
-/* Data system and user data directories.  (must free w/ g_free()) */
-#define SYSTEM_CONFIG_DIR     g_build_filename (LIBGLABELS_CONFIG_DIR, "templates", NULL)
-#define USER_CONFIG_DIR       g_build_filename (g_get_user_config_dir (), "libglabels", "templates" , NULL)
-#define ALT_USER_CONFIG_DIR   g_build_filename (g_get_home_dir (), ".glabels", NULL)
-
-
-/*===========================================*/
-/* Private types                             */
-/*===========================================*/
-
-#define TYPE_LGL_DB_MODEL              (lgl_db_model_get_type ())
-#define LGL_DB_MODEL(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_LGL_DB_MODEL, lglDbModel))
-#define LGL_DB_MODEL_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_LGL_DB_MODEL, lglDbModelClass))
-#define IS_LGL_DB_MODEL(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_LGL_DB_MODEL))
-#define IS_LGL_DB_MODEL_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_LGL_DB_MODEL))
-#define LGL_DB_MODEL_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), TYPE_LGL_DB_MODEL, lglDbModelClass))
-
-
-typedef struct _lglDbModel          lglDbModel;
-typedef struct _lglDbModelClass     lglDbModelClass;
-
-
-struct _lglDbModel {
-        GObject     parent;
-
-        GList      *papers;
-        GList      *categories;
-        GList      *vendors;
-        GList      *templates;
-
-        GHashTable *template_cache;
-};
-
-
-struct _lglDbModelClass {
-        GObjectClass  parent_class;
-
-        /*
-         * Signals
-         */
-        void (*changed)     (lglDbModel *this,
-                             gpointer    user_data);
-
-};
-
-
-enum {
-        CHANGED,
-        LAST_SIGNAL
-};
-
-
-/*===========================================*/
-/* Private globals                           */
-/*===========================================*/
-
-static guint signals[LAST_SIGNAL] = {0};
-
-static lglDbModel *model = NULL;
-
-
-/*===========================================*/
-/* Local function prototypes                 */
-/*===========================================*/
-
-static void   lgl_db_model_finalize        (GObject     *object);
-
-static void   add_to_template_cache        (lglTemplate *template);
-
-static GList *read_papers                  (void);
-static GList *read_paper_files_from_dir    (GList       *papers,
-                                           const gchar *dirname);
-
-static GList *read_categories              (void);
-static GList *read_category_files_from_dir (GList       *categories,
-                                            const gchar *dirname);
-
-static GList *read_vendors                 (void);
-static GList *read_vendor_files_from_dir   (GList       *vendors,
-                                           const gchar *dirname);
-
-static void   read_templates               (void);
-static void   read_template_files_from_dir (const gchar *dirname);
-
-static lglTemplate *template_full_page     (const gchar *page_size);
-
-
-/*****************************************************************************/
-/* Object infrastructure.                                                    */
-/*****************************************************************************/
-G_DEFINE_TYPE (lglDbModel, lgl_db_model, G_TYPE_OBJECT);
-
-
-/*****************************************************************************/
-/* Class Init Function.                                                      */
-/*****************************************************************************/
-static void
-lgl_db_model_class_init (lglDbModelClass *class)
-{
-        GObjectClass  *gobject_class = (GObjectClass *) class;
-
-        lgl_db_model_parent_class = g_type_class_peek_parent (class);
-
-        gobject_class->finalize = lgl_db_model_finalize;
-
-        signals[CHANGED] =
-                g_signal_new ("changed",
-                              G_OBJECT_CLASS_TYPE (gobject_class),
-                              G_SIGNAL_RUN_LAST,
-                              G_STRUCT_OFFSET (lglDbModelClass, changed),
-                              NULL, NULL,
-                              g_cclosure_marshal_VOID__VOID,
-                              G_TYPE_NONE,
-                              0);
-}
-
-
-/*****************************************************************************/
-/* Object Instance Init Function.                                            */
-/*****************************************************************************/
-static void
-lgl_db_model_init (lglDbModel *this)
-{
-        this->template_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)lgl_template_free);
-}
-
-
-/*****************************************************************************/
-/* Finalize Method.                                                          */
-/*****************************************************************************/
-static void
-lgl_db_model_finalize (GObject *object)
-{
-        lglDbModel    *this;
-        GList         *p;
-
-        g_return_if_fail (object && IS_LGL_DB_MODEL (object));
-        this = LGL_DB_MODEL (object);
-
-        g_hash_table_unref (this->template_cache);
-
-       for (p = this->papers; p != NULL; p = p->next)
-        {
-               g_free (p->data);
-               p->data = NULL;
-       }
-       g_list_free (this->papers);
-
-       for (p = this->categories; p != NULL; p = p->next)
-        {
-               g_free (p->data);
-               p->data = NULL;
-       }
-       g_list_free (this->categories);
-
-       for (p = this->vendors; p != NULL; p = p->next)
-        {
-               g_free (p->data);
-               p->data = NULL;
-       }
-       g_list_free (this->vendors);
-
-       for (p = this->templates; p != NULL; p = p->next)
-        {
-               lgl_template_free ((lglTemplate *)p->data);
-               p->data = NULL;
-       }
-       g_list_free (this->templates);
-
-        G_OBJECT_CLASS (lgl_db_model_parent_class)->finalize (object);
-}
-
-
-/*****************************************************************************/
-/** New Object Generator.                                                    */
-/*****************************************************************************/
-lglDbModel *
-lgl_db_model_new (void)
-{
-        lglDbModel *this;
-
-        this = g_object_new (TYPE_LGL_DB_MODEL, NULL);
-
-        return this;
-}
-
-
-/*===========================================*/
-/* Module initialization                     */
-/*===========================================*/
-
-/**
- * lgl_db_init:
- *
- * Initialize all libglabels subsystems.  It is not necessary for an application to call
- * lgl_db_init(), because libglabels will initialize on demand.  An application programmer may
- * choose to call lgl_db_init() at startup to minimize the impact of the first libglabels call
- * on GUI response time.
- *
- * This function initializes its paper definitions, category definitions, vendor definitions,
- * and its template database. It will search both system and user template directories to locate
- * this data.
- */
-void
-lgl_db_init (void)
-{
-       lglPaper    *paper_other;
-        lglCategory *category_user_defined;
-        lglTemplate *template;
-        GList       *page_sizes;
-        GList       *p;
-
-        model = lgl_db_model_new ();
-
-        /*
-         * Paper definitions
-         */
-        model->papers = read_papers ();
-
-        /* Create and append an "Other" entry. */
-        /* Translators: "Other" here means other page size.  Meaning a page size
-         * other than the standard ones that libglabels knows about such as
-         * "letter", "A4", etc. */
-        paper_other = lgl_paper_new ("Other", _("Other"), 0.0, 0.0, NULL);
-        model->papers = g_list_append (model->papers, paper_other);
-
-        /*
-         * Categories
-         */
-        model->categories = read_categories ();
-
-        /* Create and append a "User defined" entry. */
-        category_user_defined = lgl_category_new ("user-defined", _("User defined"));
-        model->categories = g_list_append (model->categories, category_user_defined);
-
-        /*
-         * Vendors
-         */
-        model->vendors = read_vendors ();
-
-        /*
-         * Templates
-         */
-        read_templates ();
-
-        /* Create and append generic full page templates. */
-        page_sizes = lgl_db_get_paper_id_list ();
-        for ( p=page_sizes; p != NULL; p=p->next )
-        {
-                if ( !lgl_db_is_paper_id_other (p->data) )
-                {
-                        template = template_full_page (p->data);
-                        _lgl_db_register_template_internal (template);
-                        lgl_template_free (template);
-                }
-        }
-        lgl_db_free_paper_id_list (page_sizes);
-
-}
-
-
-/**
- * lgl_db_notify_add:
- * @func: Callback function to be called when database changes.
- * @user_data: Passback user data to supply to callback function.
- *
- * Register a notification callback function to be called when the database changes.
- *
- * Returns: an ID for this notification registration.
- */
-gulong
-lgl_db_notify_add (lglDbNotifyFunc func,
-                   gpointer        user_data)
-{
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-        return g_signal_connect_swapped (G_OBJECT (model), "changed", G_CALLBACK (func), user_data);
-}
-
-
-/**
- * lgl_db_notify_remove:
- * @id: ID of notification registration to cancel (see lgl_db_notify_add()).
- *
- * Cancel a previous registration a notification callback function.
- */
-void
-lgl_db_notify_remove  (gulong id)
-{
-        g_signal_handler_disconnect (G_OBJECT (model), id);
-}
-
-
-/*===========================================*/
-/* Paper db functions.                       */
-/*===========================================*/
-
-/**
- * lgl_db_get_paper_id_list:
- *
- * Get a list of all paper ids known to libglabels.
- *
- * Returns: a list of paper ids.
- *
- */
-GList *
-lgl_db_get_paper_id_list (void)
-{
-       GList           *ids = NULL;
-       GList           *p;
-       lglPaper        *paper;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-       for ( p=model->papers; p != NULL; p=p->next )
-        {
-               paper = (lglPaper *)p->data;
-               ids = g_list_append (ids, g_strdup (paper->id));
-       }
-
-       return ids;
-}
-
-
-/**
- * lgl_db_free_paper_id_list:
- * @ids: List of id strings to be freed.
- *
- * Free up all storage associated with an id list obtained with
- * lgl_db_get_paper_id_list().
- *
- */
-void
-lgl_db_free_paper_id_list (GList *ids)
-{
-       GList *p;
-
-       for (p = ids; p != NULL; p = p->next)
-        {
-               g_free (p->data);
-               p->data = NULL;
-       }
-
-       g_list_free (ids);
-}
-
-
-/**
- * lgl_db_get_paper_name_list:
- *
- * Get a list of all localized paper names known to libglabels.
- *
- * Returns: a list of localized paper names.
- *
- */
-GList *
-lgl_db_get_paper_name_list (void)
-{
-       GList           *names = NULL;
-       GList           *p;
-       lglPaper        *paper;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-       for ( p=model->papers; p != NULL; p=p->next )
-        {
-               paper = (lglPaper *)p->data;
-               names = g_list_append (names, g_strdup (paper->name));
-       }
-
-       return names;
-}
-
-
-/**
- * lgl_db_free_paper_name_list:
- * @names: List of localized paper name strings to be freed.
- *
- * Free up all storage associated with a name list obtained with
- * lgl_db_get_paper_name_list().
- *
- */
-void
-lgl_db_free_paper_name_list (GList *names)
-{
-       GList *p;
-
-       for (p = names; p != NULL; p = p->next)
-        {
-               g_free (p->data);
-               p->data = NULL;
-       }
-
-       g_list_free (names);
-}
-
-
-/**
- * lgl_db_lookup_paper_from_name:
- * @name: localized paper name string
- *
- * Lookup paper definition from localized paper name string.
- *
- * Returns: pointer to a newly allocated #lglPaper structure.
- *
- */
-lglPaper *
-lgl_db_lookup_paper_from_name (const gchar *name)
-{
-       GList       *p;
-       lglPaper    *paper;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-       if (name == NULL)
-        {
-               /* If no name, return first paper as a default */
-               return lgl_paper_dup ((lglPaper *) model->papers->data);
-       }
-
-       for (p = model->papers; p != NULL; p = p->next)
-        {
-               paper = (lglPaper *) p->data;
-               if (UTF8_EQUAL (paper->name, name))
-                {
-                       return lgl_paper_dup (paper);
-               }
-       }
-
-       return NULL;
-}
-
-
-/**
- * lgl_db_lookup_paper_from_id:
- * @id: paper id string
- *
- * Lookup paper definition from id string.
- *
- * Returns: pointer to a newly allocated #lglPaper structure.
- *
- */
-lglPaper *
-lgl_db_lookup_paper_from_id (const gchar *id)
-{
-       GList       *p;
-       lglPaper    *paper;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-       if (id == NULL)
-        {
-               /* If no id, return first paper as a default */
-               return lgl_paper_dup ((lglPaper *) model->papers->data);
-       }
-
-       for (p = model->papers; p != NULL; p = p->next)
-        {
-               paper = (lglPaper *) p->data;
-               if (ASCII_EQUAL (paper->id, id))
-                {
-                       return lgl_paper_dup (paper);
-               }
-       }
-
-       return NULL;
-}
-
-
-/**
- * lgl_db_lookup_paper_id_from_name:
- * @name: localized paper name stringp
- *
- * Lookup paper name string from localized paper name string.
- *
- * Returns: pointer to a newly allocated id string.
- *
- */
-gchar *
-lgl_db_lookup_paper_id_from_name (const gchar *name)
-{
-       lglPaper *paper = NULL;
-       gchar    *id = NULL;
-
-       if (name != NULL)
-       {
-               paper = lgl_db_lookup_paper_from_name (name);
-               if ( paper != NULL )
-               {
-                       id = g_strdup (paper->id);
-                       lgl_paper_free (paper);
-                       paper = NULL;
-               }
-       }
-
-       return id;
-}
-
-
-/**
- * lgl_db_lookup_paper_name_from_id:
- * @id: paper id string
- *
- * Lookup localized paper name string from paper id string.
- *
- * Returns: pointer to a newly allocated localized paper name string.
- *
- */
-gchar *
-lgl_db_lookup_paper_name_from_id (const gchar         *id)
-{
-       lglPaper *paper = NULL;
-       gchar    *name = NULL;
-
-       if (id != NULL)
-       {
-               paper = lgl_db_lookup_paper_from_id (id);
-               if ( paper != NULL )
-               {
-                       name = g_strdup (paper->name);
-                       lgl_paper_free (paper);
-                       paper = NULL;
-               }
-       }
-
-       return name;
-}
-
-
-/**
- * lgl_db_is_paper_id_known:
- * @id: paper id to test
- *
- * Determine if given paper id is known to libglabels.
- *
- * Returns: TRUE if id is known, otherwise FALSE.
- *
- */
-gboolean
-lgl_db_is_paper_id_known (const gchar *id)
-{
-       GList       *p;
-       lglPaper    *paper;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-       if (id == NULL)
-        {
-               return FALSE;
-       }
-
-       for (p = model->papers; p != NULL; p = p->next)
-        {
-               paper = (lglPaper *) p->data;
-               if (ASCII_EQUAL (paper->id, id))
-                {
-                       return TRUE;
-               }
-       }
-
-       return FALSE;
-}
-
-
-/**
- * lgl_db_is_paper_id_other:
- * @id: paper id to test
- *
- * Determine if given paper id is the special id "Other."
- *
- * Returns: TRUE if id is "Other", otherwise FALSE.
- *
- */
-gboolean
-lgl_db_is_paper_id_other (const gchar *id)
-{
-       if (id == NULL)
-        {
-               return FALSE;
-       }
-
-       return (ASCII_EQUAL (id, "Other"));
-}
-
-
-static GList *
-read_papers (void)
-{
-       gchar *data_dir;
-       GList *papers = NULL;
-
-       data_dir = SYSTEM_CONFIG_DIR;
-       papers = read_paper_files_from_dir (papers, data_dir);
-       g_free (data_dir);
-
-       data_dir = USER_CONFIG_DIR;
-       papers = read_paper_files_from_dir (papers, data_dir);
-       g_free (data_dir);
-
-       if (papers == NULL) {
-               g_critical (_("Unable to locate paper size definitions.  Libglabels may not be installed correctly!"));
-       }
-
-       return papers;
-}
-
-
-static GList *
-read_paper_files_from_dir (GList       *papers,
-                          const gchar *dirname)
-{
-       GDir        *dp;
-       const gchar *filename, *extension;
-       gchar       *full_filename = NULL;
-       GError      *gerror = NULL;
-       GList       *new_papers = NULL;
-
-       if (dirname == NULL) {
-               return papers;
-       }
-
-       if (!g_file_test (dirname, G_FILE_TEST_EXISTS)) {
-               return papers;
-       }
-
-       dp = g_dir_open (dirname, 0, &gerror);
-       if (gerror != NULL) {
-               g_message ("cannot open data directory: %s", gerror->message );
-               return papers;
-       }
-
-       while ((filename = g_dir_read_name (dp)) != NULL) {
-
-               extension = strrchr (filename, '.');
-
-               if (extension != NULL) {
-
-                       if ( ASCII_EQUAL (filename, "paper-sizes.xml") )
-                        {
-
-                               full_filename =
-                                   g_build_filename (dirname, filename, NULL);
-                               new_papers =
-                                   lgl_xml_paper_read_papers_from_file (full_filename);
-                               g_free (full_filename);
-
-                               papers = g_list_concat (papers, new_papers);
-                               new_papers = NULL;
-
-                       }
-
-               }
-
-       }
-
-       g_dir_close (dp);
-
-       return papers;
-}
-
-
-/**
- * lgl_db_print_known_papers:
- *
- * For debugging purposes: print a list of all paper definitions known to
- * libglabels.
- *
- */
-void
-lgl_db_print_known_papers (void)
-{
-       GList       *p;
-       lglPaper    *paper;
-
-       if (!model) {
-               lgl_db_init ();
-       }
-
-       g_print ("%s():\n", __FUNCTION__);
-       for (p = model->papers; p != NULL; p = p->next) {
-               paper = (lglPaper *) p->data;
-
-               g_print ("PAPER id=\"%s\", name=\"%s\", width=%gpts, height=%gpts\n",
-                        paper->id, paper->name, paper->width, paper->height);
-
-       }
-       g_print ("\n");
-
-}
-
-
-/*===========================================*/
-/* Category db functions.                    */
-/*===========================================*/
-
-/**
- * lgl_db_get_category_id_list:
- *
- * Get a list of all category ids known to libglabels.
- *
- * Returns: a list of category ids.
- *
- */
-GList *
-lgl_db_get_category_id_list (void)
-{
-       GList           *ids = NULL;
-       GList           *p;
-       lglCategory     *category;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-       for ( p=model->categories; p != NULL; p=p->next )
-        {
-               category = (lglCategory *)p->data;
-               ids = g_list_append (ids, g_strdup (category->id));
-       }
-
-       return ids;
-}
-
-
-/**
- * lgl_db_free_category_id_list:
- * @ids: List of id strings to be freed.
- *
- * Free up all storage associated with an id list obtained with
- * lgl_db_get_category_id_list().
- *
- */
-void
-lgl_db_free_category_id_list (GList *ids)
-{
-       GList *p;
-
-       for (p = ids; p != NULL; p = p->next)
-        {
-               g_free (p->data);
-               p->data = NULL;
-       }
-
-       g_list_free (ids);
-}
-
-
-/**
- * lgl_db_get_category_name_list:
- *
- * Get a list of all localized category names known to libglabels.
- *
- * Returns: a list of localized category names.
- *
- */
-GList *
-lgl_db_get_category_name_list (void)
-{
-       GList           *names = NULL;
-       GList           *p;
-       lglCategory     *category;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-       for ( p=model->categories; p != NULL; p=p->next )
-        {
-               category = (lglCategory *)p->data;
-               names = g_list_append (names, g_strdup (category->name));
-       }
-
-       return names;
-}
-
-
-/**
- * lgl_db_free_category_name_list:
- * @names: List of localized category name strings to be freed.
- *
- * Free up all storage associated with a name list obtained with
- * lgl_db_get_category_name_list().
- *
- */
-void
-lgl_db_free_category_name_list (GList *names)
-{
-       GList *p;
-
-       for (p = names; p != NULL; p = p->next)
-        {
-               g_free (p->data);
-               p->data = NULL;
-       }
-
-       g_list_free (names);
-}
-
-
-/**
- * lgl_db_lookup_category_from_name:
- * @name: localized category name string
- *
- * Lookup category definition from localized category name string.
- *
- * Returns: pointer to a newly allocated #lglCategory structure.
- *
- */
-lglCategory *
-lgl_db_lookup_category_from_name (const gchar *name)
-{
-       GList       *p;
-       lglCategory *category;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-       if (name == NULL)
-        {
-               /* If no name, return first category as a default */
-               return lgl_category_dup ((lglCategory *) model->categories->data);
-       }
-
-       for (p = model->categories; p != NULL; p = p->next)
-        {
-               category = (lglCategory *) p->data;
-               if (UTF8_EQUAL (category->name, name))
-                {
-                       return lgl_category_dup (category);
-               }
-       }
-
-       return NULL;
-}
-
-
-/**
- * lgl_db_lookup_category_from_id:
- * @id: category id string
- *
- * Lookup category definition from id string.
- *
- * Returns: pointer to a newly allocated #lglCategory structure.
- *
- */
-lglCategory *
-lgl_db_lookup_category_from_id (const gchar *id)
-{
-       GList       *p;
-       lglCategory *category;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-       if (id == NULL)
-        {
-               /* If no id, return first category as a default */
-               return lgl_category_dup ((lglCategory *) model->categories->data);
-       }
-
-       for (p = model->categories; p != NULL; p = p->next)
-        {
-               category = (lglCategory *) p->data;
-               if (ASCII_EQUAL (category->id, id))
-                {
-                       return lgl_category_dup (category);
-               }
-       }
-
-       return NULL;
-}
-
-
-/**
- * lgl_db_lookup_category_id_from_name:
- * @name: localized category name stringp
- *
- * Lookup category name string from localized category name string.
- *
- * Returns: pointer to a newly allocated id string.
- *
- */
-gchar *
-lgl_db_lookup_category_id_from_name (const gchar *name)
-{
-       lglCategory *category = NULL;
-       gchar       *id = NULL;
-
-       if (name != NULL)
-       {
-               category = lgl_db_lookup_category_from_name (name);
-               if ( category != NULL )
-               {
-                       id = g_strdup (category->id);
-                       lgl_category_free (category);
-                       category = NULL;
-               }
-       }
-
-       return id;
-}
-
-
-/**
- * lgl_db_lookup_category_name_from_id:
- * @id: category id string
- *
- * Lookup localized category name string from category id string.
- *
- * Returns: pointer to a newly allocated localized category name string.
- *
- */
-gchar *
-lgl_db_lookup_category_name_from_id (const gchar         *id)
-{
-       lglCategory *category = NULL;
-       gchar       *name = NULL;
-
-       if (id != NULL)
-       {
-               category = lgl_db_lookup_category_from_id (id);
-               if ( category != NULL )
-               {
-                       name = g_strdup (category->name);
-                       lgl_category_free (category);
-                       category = NULL;
-               }
-       }
-
-       return name;
-}
-
-
-/**
- * lgl_db_is_category_id_known:
- * @id: category id to test
- *
- * Determine if given category id is known to libglabels.
- *
- * Returns: TRUE if id is known, otherwise FALSE.
- *
- */
-gboolean
-lgl_db_is_category_id_known (const gchar *id)
-{
-       GList       *p;
-       lglCategory *category;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-       if (id == NULL)
-        {
-               return FALSE;
-       }
-
-       for (p = model->categories; p != NULL; p = p->next)
-        {
-               category = (lglCategory *) p->data;
-               if (ASCII_EQUAL (category->id, id))
-                {
-                       return TRUE;
-               }
-       }
-
-       return FALSE;
-}
-
-
-static GList *
-read_categories (void)
-{
-       gchar *data_dir;
-       GList *categories = NULL;
-
-       data_dir = SYSTEM_CONFIG_DIR;
-       categories = read_category_files_from_dir (categories, data_dir);
-       g_free (data_dir);
-
-       data_dir = USER_CONFIG_DIR;
-       categories = read_category_files_from_dir (categories, data_dir);
-       g_free (data_dir);
-
-       if (categories == NULL) {
-               g_critical (_("Unable to locate category definitions.  Libglabels may not be installed correctly!"));
-       }
-
-       return categories;
-}
-
-
-static GList *
-read_category_files_from_dir (GList       *categories,
-                              const gchar *dirname)
-{
-       GDir        *dp;
-       const gchar *filename, *extension;
-       gchar       *full_filename = NULL;
-       GError      *gerror = NULL;
-       GList       *new_categories = NULL;
-
-       if (dirname == NULL) {
-               return categories;
-       }
-
-       if (!g_file_test (dirname, G_FILE_TEST_EXISTS)) {
-               return categories;
-       }
-
-       dp = g_dir_open (dirname, 0, &gerror);
-       if (gerror != NULL) {
-               g_message ("cannot open data directory: %s", gerror->message );
-               return categories;
-       }
-
-       while ((filename = g_dir_read_name (dp)) != NULL) {
-
-               extension = strrchr (filename, '.');
-
-               if (extension != NULL) {
-
-                       if ( ASCII_EQUAL (filename, "categories.xml") )
-                        {
-
-                               full_filename =
-                                   g_build_filename (dirname, filename, NULL);
-                               new_categories =
-                                   lgl_xml_category_read_categories_from_file (full_filename);
-                               g_free (full_filename);
-
-                               categories = g_list_concat (categories, new_categories);
-                               new_categories = NULL;
-
-                       }
-
-               }
-
-       }
-
-       g_dir_close (dp);
-
-       return categories;
-}
-
-
-/**
- * lgl_db_print_known_categories:
- *
- * For debugging purposes: print a list of all category definitions known to
- * libglabels.
- *
- */
-void
-lgl_db_print_known_categories (void)
-{
-       GList       *p;
-       lglCategory *category;
-
-       if (!model) {
-               lgl_db_init ();
-       }
-
-       g_print ("%s():\n", __FUNCTION__);
-       for (p = model->categories; p != NULL; p = p->next) {
-               category = (lglCategory *) p->data;
-
-               g_print ("CATEGORY id=\"%s\", name=\"%s\"\n", category->id, category->name);
-
-       }
-       g_print ("\n");
-
-}
-
-
-/*===========================================*/
-/* Vendor db functions.                       */
-/*===========================================*/
-
-/**
- * lgl_db_get_vendor_name_list:
- *
- * Get a list of all localized vendor names known to libglabels.
- *
- * Returns: a list of localized vendor names.
- *
- */
-GList *
-lgl_db_get_vendor_name_list (void)
-{
-       GList           *names = NULL;
-       GList           *p;
-       lglVendor       *vendor;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-       for ( p=model->vendors; p != NULL; p=p->next )
-        {
-               vendor = (lglVendor *)p->data;
-               names = g_list_append (names, g_strdup (vendor->name));
-       }
-
-       return names;
-}
-
-
-/**
- * lgl_db_free_vendor_name_list:
- * @names: List of localized vendor name strings to be freed.
- *
- * Free up all storage associated with a name list obtained with
- * lgl_db_get_vendor_name_list().
- *
- */
-void
-lgl_db_free_vendor_name_list (GList *names)
-{
-       GList *p;
-
-       for (p = names; p != NULL; p = p->next)
-        {
-               g_free (p->data);
-               p->data = NULL;
-       }
-
-       g_list_free (names);
-}
-
-
-/**
- * lgl_db_lookup_vendor_from_name:
- * @name: localized vendor name string
- *
- * Lookup vendor definition from localized vendor name string.
- *
- * Returns: pointer to a newly allocated #lglVendor structure.
- *
- */
-lglVendor *
-lgl_db_lookup_vendor_from_name (const gchar *name)
-{
-       GList       *p;
-       lglVendor   *vendor;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-       if (name == NULL)
-        {
-               /* If no name, return first vendor as a default */
-               return lgl_vendor_dup ((lglVendor *) model->vendors->data);
-       }
-
-       for (p = model->vendors; p != NULL; p = p->next)
-        {
-               vendor = (lglVendor *) p->data;
-               if (UTF8_EQUAL (vendor->name, name))
-                {
-                       return lgl_vendor_dup (vendor);
-               }
-       }
-
-       return NULL;
-}
-
-
-/**
- * lgl_db_is_vendor_name_known:
- * @name: vendor name to test
- *
- * Determine if given vendor id is known to libglabels.
- *
- * Returns: TRUE if id is known, otherwise FALSE.
- *
- */
-gboolean
-lgl_db_is_vendor_name_known (const gchar *name)
-{
-       GList       *p;
-       lglVendor   *vendor;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-       if (name == NULL)
-        {
-               return FALSE;
-       }
-
-       for (p = model->vendors; p != NULL; p = p->next)
-        {
-               vendor = (lglVendor *) p->data;
-               if (UTF8_EQUAL (vendor->name, name))
-                {
-                       return TRUE;
-               }
-       }
-
-       return FALSE;
-}
-
-
-static GList *
-read_vendors (void)
-{
-       gchar *data_dir;
-       GList *vendors = NULL;
-
-       data_dir = SYSTEM_CONFIG_DIR;
-       vendors = read_vendor_files_from_dir (vendors, data_dir);
-       g_free (data_dir);
-
-       data_dir = USER_CONFIG_DIR;
-       vendors = read_vendor_files_from_dir (vendors, data_dir);
-       g_free (data_dir);
-
-       return vendors;
-}
-
-
-static GList *
-read_vendor_files_from_dir (GList      *vendors,
-                          const gchar *dirname)
-{
-       GDir        *dp;
-       const gchar *filename, *extension;
-       gchar       *full_filename = NULL;
-       GError      *gerror = NULL;
-       GList       *new_vendors = NULL;
-
-       if (dirname == NULL) {
-               return vendors;
-       }
-
-       if (!g_file_test (dirname, G_FILE_TEST_EXISTS)) {
-               return vendors;
-       }
-
-       dp = g_dir_open (dirname, 0, &gerror);
-       if (gerror != NULL) {
-               g_message ("cannot open data directory: %s", gerror->message );
-               return vendors;
-       }
-
-       while ((filename = g_dir_read_name (dp)) != NULL) {
-
-               extension = strrchr (filename, '.');
-
-               if (extension != NULL) {
-
-                       if ( ASCII_EQUAL (filename, "vendors.xml") )
-                        {
-
-                               full_filename =
-                                   g_build_filename (dirname, filename, NULL);
-                               new_vendors =
-                                   lgl_xml_vendor_read_vendors_from_file (full_filename);
-                               g_free (full_filename);
-
-                               vendors = g_list_concat (vendors, new_vendors);
-                               new_vendors = NULL;
-
-                       }
-
-               }
-
-       }
-
-       g_dir_close (dp);
-
-       return vendors;
-}
-
-
-/**
- * lgl_db_print_known_vendors:
- *
- * For debugging purposes: print a list of all vendor definitions known to
- * libglabels.
- *
- */
-void
-lgl_db_print_known_vendors (void)
-{
-       GList       *p;
-       lglVendor   *vendor;
-
-       if (!model) {
-               lgl_db_init ();
-       }
-
-       g_print ("%s():\n", __FUNCTION__);
-       for (p = model->vendors; p != NULL; p = p->next) {
-               vendor = (lglVendor *) p->data;
-
-               g_print ("VENDOR name=\"%s\", url=\"%s\"\n",
-                        vendor->name, vendor->url);
-
-       }
-       g_print ("\n");
-
-}
-
-
-/*===========================================*/
-/* Brand db functions.                       */
-/*===========================================*/
-
-/**
- * lgl_db_get_brand_list:
- * @paper_id: If non NULL, limit results to given page size.
- * @category_id: If non NULL, limit results to given template category.
- *
- * Get a list of all valid brands of templates in the template database.
- * Results can be filtered by page size and/or template category.  A list of valid page
- * sizes can be obtained using lgl_db_get_paper_id_list().  A list of valid template
- * categories can be obtained using lgl_db_get_category_id_list().
- *
- * Returns: a list of brands
- */
-GList *
-lgl_db_get_brand_list (const gchar *paper_id,
-                       const gchar *category_id)
-{
-       GList            *p_tmplt;
-       lglTemplate      *template;
-       GList            *brands = NULL;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-       for (p_tmplt = model->templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
-        {
-               template = (lglTemplate *) p_tmplt->data;
-               if (lgl_template_does_page_size_match (template, paper_id) &&
-                    lgl_template_does_category_match (template, category_id))
-                {
-
-                        if ( !g_list_find_custom (brands, template->brand,
-                                                  (GCompareFunc)lgl_str_utf8_casecmp) )
-                        {
-                                brands = g_list_insert_sorted (brands,
-                                                               g_strdup (template->brand),
-                                                               (GCompareFunc)lgl_str_utf8_casecmp);
-                        }
-               }
-       }
-
-       return brands;
-}
-
-
-/**
- * lgl_db_free_brand_list:
- * @brands: List of template brand strings to be freed.
- *
- * Free up all storage associated with a list of template names obtained with
- * lgl_db_get_brand_list().
- *
- */
-void
-lgl_db_free_brand_list (GList *brands)
-{
-       GList *p_brand;
-
-       for (p_brand = brands; p_brand != NULL; p_brand = p_brand->next)
-        {
-               g_free (p_brand->data);
-               p_brand->data = NULL;
-       }
-
-       g_list_free (brands);
-}
-
-
-/*===========================================*/
-/* Template db functions.                    */
-/*===========================================*/
-
-void
-_lgl_db_register_template_internal (const lglTemplate   *template)
-{
-        lglTemplate *template_copy;
-
-        if (!lgl_db_does_template_exist (template->brand, template->part))
-        {
-                template_copy = lgl_template_dup (template);
-                model->templates = g_list_append (model->templates, template_copy);
-                add_to_template_cache (template_copy);
-        }
-        else
-        {
-               g_message ("Duplicate template: %s %s.", template->brand, template->part);
-        }
-}
-
-
-/**
- * lgl_db_register_template:
- * @template:  Pointer to a template structure to add to database.
- *
- * Register a template.  This function adds a template to the template database.
- * The template will be stored in an individual XML file in the user template directory.
- *
- * Returns: Status of registration attempt (#lglDbRegStatus)
- */
-lglDbRegStatus
-lgl_db_register_template (const lglTemplate *template)
-{
-        lglTemplate *template_copy;
-        gchar       *dir, *filename, *abs_filename;
-        gint         bytes_written;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-        if (lgl_db_does_template_exist (template->brand, template->part))
-        {
-                return LGL_DB_REG_BRAND_PART_EXISTS;
-        }
-
-       if (lgl_db_is_paper_id_known (template->paper_id))
-        {
-               dir = USER_CONFIG_DIR;
-               g_mkdir_with_parents (dir, 0775); /* Try to make sure directory exists. */
-               filename = g_strdup_printf ("%s_%s.template", template->brand, template->part);
-               abs_filename = g_build_filename (dir, filename, NULL);
-               bytes_written = lgl_xml_template_write_template_to_file (template, abs_filename);
-               g_free (dir);
-               g_free (filename);
-               g_free (abs_filename);
-
-                if (bytes_written > 0)
-                {
-                        template_copy = lgl_template_dup (template);
-                        lgl_template_add_category (template_copy, "user-defined");
-                        model->templates = g_list_append (model->templates, template_copy);
-                        add_to_template_cache (template_copy);
-                        g_signal_emit (G_OBJECT (model), signals[CHANGED], 0);
-                        return LGL_DB_REG_OK;
-                }
-                else
-                {
-                        return LGL_DB_REG_FILE_WRITE_ERROR;
-                }
-       }
-        else
-        {
-               g_message ("Cannot register new template with unknown page size.");
-                return LGL_DB_REG_BAD_PAPER_ID;
-       }
-
-}
-
-
-/**
- * lgl_db_delete_template_by_name:
- * @name:  Name of template to be deleted.
- *
- * Delete a user defined template.  This function deletes a template from
- * the template database. The individual XML file in the user template
- * directory will also be removed.
- *
- * Returns: Status of registration attempt (#lglDbDeleteStatus)
- */
-lglDbDeleteStatus
-lgl_db_delete_template_by_name (const gchar *name)
-{
-        lglTemplate *template, *template1;
-        gchar       *dir, *filename, *abs_filename;
-        GList       *p;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-        if (!lgl_db_does_template_name_exist (name))
-        {
-                return LGL_DB_DELETE_DOES_NOT_EXIST;
-        }
-
-        template = lgl_db_lookup_template_from_name (name);
-        if ( lgl_template_does_category_match (template, "user-defined") )
-        {
-               dir = USER_CONFIG_DIR;
-               filename = g_strdup_printf ("%s_%s.template", template->brand, template->part);
-               abs_filename = g_build_filename (dir, filename, NULL);
-
-                if (!g_file_test (abs_filename, G_FILE_TEST_EXISTS))
-                {
-                        g_message ("File \"%s\" does not exist.  Cannot delete template.", abs_filename);
-                        return LGL_DB_DELETE_DOES_NOT_EXIST;
-                }
-
-                g_unlink (abs_filename);
-
-               g_free (dir);
-               g_free (filename);
-               g_free (abs_filename);
-
-                for ( p=model->templates; p != NULL; p=p->next )
-                {
-                        template1 = (lglTemplate *)p->data;
-
-                        if ( lgl_template_do_templates_match (template, template1) )
-                        {
-                                model->templates = g_list_delete_link (model->templates, p);
-                                g_hash_table_remove (model->template_cache, name);
-                                break;
-                        }
-                }
-
-                lgl_template_free (template);
-
-                g_signal_emit (G_OBJECT (model), signals[CHANGED], 0);
-                return LGL_DB_DELETE_OK;
-        }
-        else
-        {
-                return LGL_DB_DELETE_NOT_USER_DEFINED;
-        }
-
-}
-
-
-/**
- * lgl_db_delete_template_by_brand_part:
- * @brand:  Brand name or vendor of template to be deleted.
- * @part:   Part name or number of template to be deleted.
- *
- * Delete a user defined template.  This function deletes a template from
- * the template database. The individual XML file in the user template
- * directory will also be removed.
- *
- * Returns: Status of registration attempt (#lglDbDeleteStatus)
- */
-lglDbDeleteStatus
-lgl_db_delete_template_by_brand_part (const gchar  *brand,
-                                      const gchar  *part)
-{
-        gchar             *name;
-        lglDbDeleteStatus  status;
-
-        name = g_strdup_printf ("%s %s", brand, part);
-
-        status = lgl_db_delete_template_by_name (name);
-
-        g_free (name);
-
-        return status;
-}
-
-
-/**
- * lgl_db_does_template_exist:
- * @brand: Brand name.
- * @part:  Part name/number.
- *
- * This function tests whether a template with the given brand and part name/number exists.
- *
- * Returns:  TRUE if such a template exists in the database.
- */
-gboolean
-lgl_db_does_template_exist (const gchar *brand,
-                            const gchar *part)
-{
-       GList            *p_tmplt;
-       lglTemplate      *template;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-       if ((brand == NULL) || (part == NULL))
-        {
-               return FALSE;
-       }
-
-       for (p_tmplt = model->templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
-        {
-               template = (lglTemplate *) p_tmplt->data;
-
-                if ( UTF8_EQUAL (brand, template->brand) &&
-                     UTF8_EQUAL (part, template->part) )
-                {
-                        return TRUE;
-                }
-       }
-
-       return FALSE;
-}
-
-
-/**
- * lgl_db_does_template_name_exist:
- * @name: name string
- *
- * This function test whether a template with the given name exists.
- *
- * Returns: TRUE if such a template exists in the database.
- *
- */
-gboolean
-lgl_db_does_template_name_exist (const gchar *name)
-{
-       GList            *p_tmplt;
-        lglTemplate      *template;
-        gchar            *candidate_name;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-       if (name == NULL)
-        {
-               return FALSE;
-       }
-
-       for (p_tmplt = model->templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
-        {
-               template = (lglTemplate *) p_tmplt->data;
-                candidate_name = g_strdup_printf ("%s %s", template->brand, template->part);
-
-                if ( UTF8_EQUAL (candidate_name, name) )
-                {
-                        g_free (candidate_name);
-                        return TRUE;
-                }
-                g_free (candidate_name);
-       }
-
-       return FALSE;
-}
-
-
-/**
- * lgl_db_get_template_name_list_all:
- * @brand:     If non NULL, limit results to given brand
- * @paper_id: If non NULL, limit results to given page size.
- * @category_id: If non NULL, limit results to given template category.
- *
- * Get a list of all valid names of templates in the template database.
- * Results can be filtered by page size and/or template category.  A list of valid page
- * sizes can be obtained using lgl_db_get_paper_id_list().  A list of valid template
- * categories can be obtained using lgl_db_get_category_id_list().
- *
- * Returns: a list of template names.
- */
-GList *
-lgl_db_get_template_name_list_all (const gchar *brand,
-                                   const gchar *paper_id,
-                                   const gchar *category_id)
-{
-       GList            *p_tmplt;
-       lglTemplate      *template;
-        gchar            *name;
-       GList            *names = NULL;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-       for (p_tmplt = model->templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
-        {
-               template = (lglTemplate *) p_tmplt->data;
-               if (lgl_template_does_brand_match (template, brand) &&
-                    lgl_template_does_page_size_match (template, paper_id) &&
-                    lgl_template_does_category_match (template, category_id))
-                {
-                        name = g_strdup_printf ("%s %s", template->brand, template->part);
-                        names = g_list_insert_sorted (names, name, (GCompareFunc)lgl_str_part_name_cmp);
-               }
-       }
-
-       return names;
-}
-
-
-/**
- * lgl_db_get_similar_template_name_list:
- * @name:     Name of template under test.
- *
- * Get a list of all valid names of templates in the template database that
- * have the same size and layout characteristics as the given template.
- *
- * Returns: a list of template names.
- */
-GList *
-lgl_db_get_similar_template_name_list (const gchar  *name)
-{
-       GList            *p_tmplt;
-       lglTemplate      *template1;
-       lglTemplate      *template2;
-        gchar            *name2;
-       GList            *names = NULL;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-        if ( !name )
-        {
-                return NULL;
-        }
-
-        template1 = lgl_db_lookup_template_from_name (name);
-        if ( !template1 )
-        {
-                return NULL;
-        }
-
-       for (p_tmplt = model->templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
-        {
-               template2 = (lglTemplate *) p_tmplt->data;
-
-                if ( lgl_template_are_templates_identical (template1, template2) )
-                {
-
-                        name2 = g_strdup_printf ("%s %s", template2->brand, template2->part);
-                        if ( !UTF8_EQUAL (name2, name) )
-                        {
-                                names = g_list_insert_sorted (names, name2,
-                                                              (GCompareFunc)lgl_str_part_name_cmp);
-                        }
-
-               }
-       }
-
-       return names;
-}
-
-
-/**
- * lgl_db_free_template_name_list:
- * @names: List of template name strings to be freed.
- *
- * Free up all storage associated with a list of template names obtained with
- * lgl_db_get_template_name_list_all().
- *
- */
-void
-lgl_db_free_template_name_list (GList *names)
-{
-       GList *p_name;
-
-       for (p_name = names; p_name != NULL; p_name = p_name->next)
-        {
-               g_free (p_name->data);
-               p_name->data = NULL;
-       }
-
-       g_list_free (names);
-}
-
-
-/**
- * lgl_db_lookup_template_from_name:
- * @name: name string
- *
- * Lookup template in template database from name string.
- *
- * Returns: pointer to a newly allocated #lglTemplate structure.
- *
- */
-lglTemplate *
-lgl_db_lookup_template_from_name (const gchar *name)
-{
-       lglTemplate      *template;
-       lglTemplate      *new_template;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-       if (name == NULL)
-        {
-               /* If no name, return first template as a default */
-               return lgl_template_dup ((lglTemplate *) model->templates->data);
-       }
-
-        template = g_hash_table_lookup (model->template_cache, name);
-
-        if (template)
-        {
-                new_template = lgl_template_dup (template);
-                return new_template;
-        }
-
-       /* No matching template has been found so return the first template */
-       return lgl_template_dup ((lglTemplate *) model->templates->data);
-}
-
-
-/**
- * lgl_db_lookup_template_from_brand_part:
- * @brand: brand name string
- * @part:  part name string
- *
- * Lookup template in template database from brand and part strings.
- *
- * Returns: pointer to a newly allocated #lglTemplate structure.
- *
- */
-lglTemplate *
-lgl_db_lookup_template_from_brand_part(const gchar *brand,
-                                       const gchar *part)
-{
-        gchar            *name;
-       lglTemplate      *template;
-       lglTemplate      *new_template;
-
-       if (!model)
-        {
-               lgl_db_init ();
-       }
-
-       if ((brand == NULL) || (part == NULL))
-        {
-               /* If no name, return first template as a default */
-               return lgl_template_dup ((lglTemplate *) model->templates->data);
-       }
-
-        name = g_strdup_printf ("%s %s", brand, part);
-        template = g_hash_table_lookup (model->template_cache, name);
-
-        if (template)
-        {
-                new_template = lgl_template_dup (template);
-                return new_template;
-        }
-
-       /* No matching template has been found so return the first template */
-        g_free (name);
-       return lgl_template_dup ((lglTemplate *) model->templates->data);
-}
-
-
-static void
-add_to_template_cache (lglTemplate *template)
-{
-        gchar            *name;
-
-        name = g_strdup_printf ("%s %s", template->brand, template->part);
-
-        g_hash_table_insert (model->template_cache, name, template);
-}
-
-
-void
-read_templates (void)
-{
-       gchar       *data_dir;
-        GList       *p;
-        lglTemplate *template;
-
-        /*
-         * User defined templates.  Add to user-defined category.
-         */
-       data_dir = USER_CONFIG_DIR;
-       read_template_files_from_dir (data_dir);
-       g_free (data_dir);
-        for ( p=model->templates; p != NULL; p=p->next )
-        {
-                template = (lglTemplate *)p->data;
-                lgl_template_add_category (template, "user-defined");
-        }
-
-        /*
-         * Alternate user defined templates.  (Used for manually created templates).
-         */
-       data_dir = ALT_USER_CONFIG_DIR;
-       read_template_files_from_dir (data_dir);
-       g_free (data_dir);
-
-        /*
-         * System templates.
-         */
-       data_dir = SYSTEM_CONFIG_DIR;
-       read_template_files_from_dir (data_dir);
-       g_free (data_dir);
-
-       if (model->templates == NULL)
-        {
-               g_critical (_("Unable to locate any template files.  Libglabels may not be installed correctly!"));
-       }
-}
-
-
-void
-read_template_files_from_dir (const gchar *dirname)
-{
-       GDir        *dp;
-       const gchar *filename, *extension, *extension2;
-       gchar       *full_filename = NULL;
-       GError      *gerror = NULL;
-
-       if (dirname == NULL)
-               return;
-
-       if (!g_file_test (dirname, G_FILE_TEST_EXISTS))
-        {
-               return;
-       }
-
-       dp = g_dir_open (dirname, 0, &gerror);
-       if (gerror != NULL)
-        {
-               g_message ("cannot open data directory: %s", gerror->message );
-               return;
-       }
-
-       while ((filename = g_dir_read_name (dp)) != NULL)
-        {
-
-               extension = strrchr (filename, '.');
-               extension2 = strrchr (filename, '-');
-
-               if ( (extension && ASCII_EQUAL (extension, ".template")) ||
-                    (extension2 && ASCII_EQUAL (extension2, "-templates.xml")) )
-                {
-
-                       full_filename = g_build_filename (dirname, filename, NULL);
-                        lgl_xml_template_read_templates_from_file (full_filename);
-                       g_free (full_filename);
-               }
-
-       }
-
-       g_dir_close (dp);
-}
-
-
-static lglTemplate *
-template_full_page (const gchar *paper_id)
-{
-       lglPaper              *paper = NULL;
-       lglTemplate           *template = NULL;
-       lglTemplateFrame      *frame = NULL;
-        gchar                 *part;
-        gchar                 *desc;
-
-       g_return_val_if_fail (paper_id, NULL);
-
-       paper = lgl_db_lookup_paper_from_id (paper_id);
-       if ( paper == NULL )
-        {
-               return NULL;
-       }
-
-       part = g_strdup_printf ("%s-Full-Page", paper->id);
-       desc = g_strdup_printf (_("%s full page label"), paper->name);
-
-       template = lgl_template_new ("Generic", part, desc,
-                                     paper_id, paper->width, paper->height);
-
-
-       frame = lgl_template_frame_rect_new ("0",
-                                             paper->width,
-                                             paper->height,
-                                             0.0,
-                                             0.0,
-                                             0.0);
-       lgl_template_add_frame (template, frame);
-
-       lgl_template_frame_add_layout (frame, lgl_template_layout_new (1, 1, 0., 0., 0., 0.));
-
-       lgl_template_frame_add_markup (frame, lgl_template_markup_margin_new (9.0));
-
-       g_free (desc);
-       desc = NULL;
-       lgl_paper_free (paper);
-       paper = NULL;
-
-       return template;
-}
-
-
-/**
- * lgl_db_print_known_templates:
- *
- * Print all known templates (for debugging purposes).
- *
- */
-void
-lgl_db_print_known_templates (void)
-{
-       GList       *p;
-       lglTemplate *template;
-
-        if (!model)
-        {
-                lgl_db_init ();
-        }
-
-       g_print ("%s():\n", __FUNCTION__);
-       for (p=model->templates; p!=NULL; p=p->next)
-        {
-               template = (lglTemplate *)p->data;
-
-               g_print("TEMPLATE brand=\"%s\", part=\"%s\", description=\"%s\"\n",
-                       template->brand, template->part, template->description);
-
-       }
-       g_print ("\n");
-
-}
-
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/db.h b/libglabels/db.h
deleted file mode 100644 (file)
index bcba326..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- *  db.h
- *  Copyright (C) 2006-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __LGL_DB_H__
-#define __LGL_DB_H__
-
-#include <glib.h>
-
-#include "paper.h"
-#include "category.h"
-#include "vendor.h"
-#include "template.h"
-
-G_BEGIN_DECLS
-
-typedef enum
-{
-        LGL_DB_REG_OK                =  0,
-        LGL_DB_REG_BAD_PAPER_ID      = -1,
-        LGL_DB_REG_BRAND_PART_EXISTS = -2,
-        LGL_DB_REG_FILE_WRITE_ERROR  = -3
-} lglDbRegStatus;
-
-typedef enum
-{
-        LGL_DB_DELETE_OK                =  0,
-        LGL_DB_DELETE_DOES_NOT_EXIST    = -1,
-        LGL_DB_DELETE_NOT_USER_DEFINED  = -2,
-        LGL_DB_DELETE_FILE_ERROR        = -3
-} lglDbDeleteStatus;
-
-
-typedef void  (*lglDbNotifyFunc) (gpointer user_data);
-
-
-
-
-/*
- * Module initialization
- */
-void           lgl_db_init                           (void);
-
-
-
-/*
- * Notification
- */
-gulong         lgl_db_notify_add                     (lglDbNotifyFunc      func,
-                                                      gpointer             user_data);
-
-void           lgl_db_notify_remove                  (gulong               id);
-
-
-
-/*
- * Paper
- */
-GList         *lgl_db_get_paper_id_list              (void);
-
-void           lgl_db_free_paper_id_list             (GList               *ids);
-
-GList         *lgl_db_get_paper_name_list            (void);
-
-void           lgl_db_free_paper_name_list           (GList               *names);
-
-lglPaper      *lgl_db_lookup_paper_from_name         (const gchar         *name);
-
-lglPaper      *lgl_db_lookup_paper_from_id           (const gchar         *id);
-
-gchar         *lgl_db_lookup_paper_id_from_name      (const gchar         *name);
-
-gchar         *lgl_db_lookup_paper_name_from_id      (const gchar         *id);
-
-gboolean       lgl_db_is_paper_id_known              (const gchar         *id);
-
-gboolean       lgl_db_is_paper_id_other              (const gchar         *id);
-
-
-
-/*
- * Template categories
- */
-GList         *lgl_db_get_category_id_list           (void);
-
-void           lgl_db_free_category_id_list          (GList              *ids);
-
-GList         *lgl_db_get_category_name_list         (void);
-
-void           lgl_db_free_category_name_list        (GList               *names);
-
-lglCategory   *lgl_db_lookup_category_from_name      (const gchar         *name);
-
-lglCategory   *lgl_db_lookup_category_from_id        (const gchar         *id);
-
-gchar         *lgl_db_lookup_category_id_from_name   (const gchar         *name);
-
-gchar         *lgl_db_lookup_category_name_from_id   (const gchar         *id);
-
-gboolean       lgl_db_is_category_id_known           (const gchar         *id);
-
-
-/*
- * Vendor
- */
-GList         *lgl_db_get_vendor_name_list           (void);
-
-void           lgl_db_free_vendor_name_list          (GList               *names);
-
-lglVendor     *lgl_db_lookup_vendor_from_name        (const gchar         *name);
-
-gboolean       lgl_db_is_vendor_name_known           (const gchar         *name);
-
-
-/*
- * Template brands
- */
-GList         *lgl_db_get_brand_list                 (const gchar         *paper_id,
-                                                      const gchar         *category_id);
-
-void           lgl_db_free_brand_list                (GList               *brands);
-
-
-/*
- * Templates
- */
-lglDbRegStatus lgl_db_register_template              (const lglTemplate   *template);
-
-lglDbDeleteStatus lgl_db_delete_template_by_name        (const gchar         *name);
-
-lglDbDeleteStatus lgl_db_delete_template_by_brand_part  (const gchar         *brand,
-                                                         const gchar         *part);
-
-gboolean       lgl_db_does_template_exist            (const gchar         *brand,
-                                                      const gchar         *part);
-
-gboolean       lgl_db_does_template_name_exist       (const gchar         *name);
-
-GList         *lgl_db_get_template_name_list_all     (const gchar         *brand,
-                                                      const gchar         *paper_id,
-                                                      const gchar         *category_id);
-
-GList         *lgl_db_get_similar_template_name_list (const gchar         *name);
-
-void           lgl_db_free_template_name_list        (GList               *names);
-
-lglTemplate   *lgl_db_lookup_template_from_name      (const gchar         *name);
-
-lglTemplate   *lgl_db_lookup_template_from_brand_part(const gchar         *brand,
-                                                      const gchar         *part);
-
-
-/*
- * Debugging functions
- */
-void           lgl_db_print_known_papers             (void);
-
-void           lgl_db_print_known_categories         (void);
-
-void           lgl_db_print_known_templates          (void);
-
-void           lgl_db_print_aliases                  (const lglTemplate    *template);
-
-void           lgl_db_print_known_vendors            (void);
-
-
-
-G_END_DECLS
-
-#endif /* __LGL_DB_H__ */
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/lgl-category.c b/libglabels/lgl-category.c
new file mode 100644 (file)
index 0000000..a733535
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ *  lgl-category.c
+ *  Copyright (C) 2006-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "lgl-category.h"
+
+#include <glib/gi18n.h>
+#include <glib.h>
+#include <string.h>
+
+#include "libglabels-private.h"
+
+
+/*===========================================*/
+/* Private types                             */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Private globals                           */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Local function prototypes                 */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Functions.                                */
+/*===========================================*/
+
+/**
+ * lgl_category_new:
+ * @id:     Id of category definition. (E.g. label, card, etc.)  Should be
+ *          unique.
+ * @name:   Localized name of category.
+ *
+ * Allocates and constructs a new #lglCategory structure.
+ *
+ * Returns: a pointer to a newly allocated #lglCategory structure.
+ *
+ */
+lglCategory *
+lgl_category_new (gchar             *id,
+                  gchar             *name)
+{
+       lglCategory *category;
+
+       category         = g_new0 (lglCategory,1);
+       category->id     = g_strdup (id);
+       category->name   = g_strdup (name);
+
+       return category;
+}
+
+
+/**
+ * lgl_category_dup:
+ * @orig:  #lglCategory structure to be duplicated.
+ *
+ * Duplicates an existing #lglCategory structure.
+ *
+ * Returns: a pointer to a newly allocated #lglCategory structure.
+ *
+ */
+lglCategory *lgl_category_dup (const lglCategory *orig)
+{
+       lglCategory       *category;
+
+       g_return_val_if_fail (orig, NULL);
+
+       category = g_new0 (lglCategory,1);
+
+       category->id     = g_strdup (orig->id);
+       category->name   = g_strdup (orig->name);
+
+       return category;
+}
+
+
+/**
+ * lgl_category_free:
+ * @category:  pointer to #lglCategory structure to be freed.
+ *
+ * Free all memory associated with an existing #lglCategory structure.
+ *
+ */
+void lgl_category_free (lglCategory *category)
+{
+
+       if ( category != NULL ) {
+
+               g_free (category->id);
+               category->id = NULL;
+
+               g_free (category->name);
+               category->name = NULL;
+
+               g_free (category);
+       }
+
+}
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-category.h b/libglabels/lgl-category.h
new file mode 100644 (file)
index 0000000..8ac3536
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *  lgl-category.h
+ *  Copyright (C) 2006-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LGL_CATEGORY_H__
+#define __LGL_CATEGORY_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+/*
+ *   Template class
+ */
+typedef struct _lglCategory lglCategory;
+
+struct _lglCategory {
+       gchar               *id;     /* Unique ID of category */
+       gchar               *name;   /* Localized name of category */
+};
+
+
+/*
+ * Category construction
+ */
+lglCategory      *lgl_category_new                 (gchar             *id,
+                                                    gchar             *name);
+
+lglCategory      *lgl_category_dup                 (const lglCategory *orig);
+void              lgl_category_free                (lglCategory       *category);
+
+
+G_END_DECLS
+
+#endif /* __LGL_CATEGORY_H__ */
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-db.c b/libglabels/lgl-db.c
new file mode 100644 (file)
index 0000000..fed3aee
--- /dev/null
@@ -0,0 +1,2103 @@
+/*
+ *  lgl-db.c
+ *  Copyright (C) 2003-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "lgl-db.h"
+
+#include <glib/gi18n.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <glib-object.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "libglabels-private.h"
+
+#include "lgl-xml-paper.h"
+#include "lgl-xml-category.h"
+#include "lgl-xml-vendor.h"
+#include "lgl-xml-template.h"
+
+/*===========================================*/
+/* Private macros and constants.             */
+/*===========================================*/
+
+/* Data system and user data directories.  (must free w/ g_free()) */
+#define SYSTEM_CONFIG_DIR     g_build_filename (LIBGLABELS_CONFIG_DIR, "templates", NULL)
+#define USER_CONFIG_DIR       g_build_filename (g_get_user_config_dir (), "libglabels", "templates" , NULL)
+#define ALT_USER_CONFIG_DIR   g_build_filename (g_get_home_dir (), ".glabels", NULL)
+
+
+/*===========================================*/
+/* Private types                             */
+/*===========================================*/
+
+#define TYPE_LGL_DB_MODEL              (lgl_db_model_get_type ())
+#define LGL_DB_MODEL(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_LGL_DB_MODEL, lglDbModel))
+#define LGL_DB_MODEL_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_LGL_DB_MODEL, lglDbModelClass))
+#define IS_LGL_DB_MODEL(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_LGL_DB_MODEL))
+#define IS_LGL_DB_MODEL_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_LGL_DB_MODEL))
+#define LGL_DB_MODEL_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), TYPE_LGL_DB_MODEL, lglDbModelClass))
+
+
+typedef struct _lglDbModel          lglDbModel;
+typedef struct _lglDbModelClass     lglDbModelClass;
+
+
+struct _lglDbModel {
+        GObject     parent;
+
+        GList      *papers;
+        GList      *categories;
+        GList      *vendors;
+        GList      *templates;
+
+        GHashTable *template_cache;
+};
+
+
+struct _lglDbModelClass {
+        GObjectClass  parent_class;
+
+        /*
+         * Signals
+         */
+        void (*changed)     (lglDbModel *this,
+                             gpointer    user_data);
+
+};
+
+
+enum {
+        CHANGED,
+        LAST_SIGNAL
+};
+
+
+/*===========================================*/
+/* Private globals                           */
+/*===========================================*/
+
+static guint signals[LAST_SIGNAL] = {0};
+
+static lglDbModel *model = NULL;
+
+
+/*===========================================*/
+/* Local function prototypes                 */
+/*===========================================*/
+
+static void   lgl_db_model_finalize        (GObject     *object);
+
+static void   add_to_template_cache        (lglTemplate *template);
+
+static GList *read_papers                  (void);
+static GList *read_paper_files_from_dir    (GList       *papers,
+                                           const gchar *dirname);
+
+static GList *read_categories              (void);
+static GList *read_category_files_from_dir (GList       *categories,
+                                            const gchar *dirname);
+
+static GList *read_vendors                 (void);
+static GList *read_vendor_files_from_dir   (GList       *vendors,
+                                           const gchar *dirname);
+
+static void   read_templates               (void);
+static void   read_template_files_from_dir (const gchar *dirname);
+
+static lglTemplate *template_full_page     (const gchar *page_size);
+
+
+/*****************************************************************************/
+/* Object infrastructure.                                                    */
+/*****************************************************************************/
+G_DEFINE_TYPE (lglDbModel, lgl_db_model, G_TYPE_OBJECT);
+
+
+/*****************************************************************************/
+/* Class Init Function.                                                      */
+/*****************************************************************************/
+static void
+lgl_db_model_class_init (lglDbModelClass *class)
+{
+        GObjectClass  *gobject_class = (GObjectClass *) class;
+
+        lgl_db_model_parent_class = g_type_class_peek_parent (class);
+
+        gobject_class->finalize = lgl_db_model_finalize;
+
+        signals[CHANGED] =
+                g_signal_new ("changed",
+                              G_OBJECT_CLASS_TYPE (gobject_class),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (lglDbModelClass, changed),
+                              NULL, NULL,
+                              g_cclosure_marshal_VOID__VOID,
+                              G_TYPE_NONE,
+                              0);
+}
+
+
+/*****************************************************************************/
+/* Object Instance Init Function.                                            */
+/*****************************************************************************/
+static void
+lgl_db_model_init (lglDbModel *this)
+{
+        this->template_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)lgl_template_free);
+}
+
+
+/*****************************************************************************/
+/* Finalize Method.                                                          */
+/*****************************************************************************/
+static void
+lgl_db_model_finalize (GObject *object)
+{
+        lglDbModel    *this;
+        GList         *p;
+
+        g_return_if_fail (object && IS_LGL_DB_MODEL (object));
+        this = LGL_DB_MODEL (object);
+
+        g_hash_table_unref (this->template_cache);
+
+       for (p = this->papers; p != NULL; p = p->next)
+        {
+               g_free (p->data);
+               p->data = NULL;
+       }
+       g_list_free (this->papers);
+
+       for (p = this->categories; p != NULL; p = p->next)
+        {
+               g_free (p->data);
+               p->data = NULL;
+       }
+       g_list_free (this->categories);
+
+       for (p = this->vendors; p != NULL; p = p->next)
+        {
+               g_free (p->data);
+               p->data = NULL;
+       }
+       g_list_free (this->vendors);
+
+       for (p = this->templates; p != NULL; p = p->next)
+        {
+               lgl_template_free ((lglTemplate *)p->data);
+               p->data = NULL;
+       }
+       g_list_free (this->templates);
+
+        G_OBJECT_CLASS (lgl_db_model_parent_class)->finalize (object);
+}
+
+
+/*****************************************************************************/
+/** New Object Generator.                                                    */
+/*****************************************************************************/
+lglDbModel *
+lgl_db_model_new (void)
+{
+        lglDbModel *this;
+
+        this = g_object_new (TYPE_LGL_DB_MODEL, NULL);
+
+        return this;
+}
+
+
+/*===========================================*/
+/* Module initialization                     */
+/*===========================================*/
+
+/**
+ * lgl_db_init:
+ *
+ * Initialize all libglabels subsystems.  It is not necessary for an application to call
+ * lgl_db_init(), because libglabels will initialize on demand.  An application programmer may
+ * choose to call lgl_db_init() at startup to minimize the impact of the first libglabels call
+ * on GUI response time.
+ *
+ * This function initializes its paper definitions, category definitions, vendor definitions,
+ * and its template database. It will search both system and user template directories to locate
+ * this data.
+ */
+void
+lgl_db_init (void)
+{
+       lglPaper    *paper_other;
+        lglCategory *category_user_defined;
+        lglTemplate *template;
+        GList       *page_sizes;
+        GList       *p;
+
+        model = lgl_db_model_new ();
+
+        /*
+         * Paper definitions
+         */
+        model->papers = read_papers ();
+
+        /* Create and append an "Other" entry. */
+        /* Translators: "Other" here means other page size.  Meaning a page size
+         * other than the standard ones that libglabels knows about such as
+         * "letter", "A4", etc. */
+        paper_other = lgl_paper_new ("Other", _("Other"), 0.0, 0.0, NULL);
+        model->papers = g_list_append (model->papers, paper_other);
+
+        /*
+         * Categories
+         */
+        model->categories = read_categories ();
+
+        /* Create and append a "User defined" entry. */
+        category_user_defined = lgl_category_new ("user-defined", _("User defined"));
+        model->categories = g_list_append (model->categories, category_user_defined);
+
+        /*
+         * Vendors
+         */
+        model->vendors = read_vendors ();
+
+        /*
+         * Templates
+         */
+        read_templates ();
+
+        /* Create and append generic full page templates. */
+        page_sizes = lgl_db_get_paper_id_list ();
+        for ( p=page_sizes; p != NULL; p=p->next )
+        {
+                if ( !lgl_db_is_paper_id_other (p->data) )
+                {
+                        template = template_full_page (p->data);
+                        _lgl_db_register_template_internal (template);
+                        lgl_template_free (template);
+                }
+        }
+        lgl_db_free_paper_id_list (page_sizes);
+
+}
+
+
+/**
+ * lgl_db_notify_add:
+ * @func: Callback function to be called when database changes.
+ * @user_data: Passback user data to supply to callback function.
+ *
+ * Register a notification callback function to be called when the database changes.
+ *
+ * Returns: an ID for this notification registration.
+ */
+gulong
+lgl_db_notify_add (lglDbNotifyFunc func,
+                   gpointer        user_data)
+{
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+        return g_signal_connect_swapped (G_OBJECT (model), "changed", G_CALLBACK (func), user_data);
+}
+
+
+/**
+ * lgl_db_notify_remove:
+ * @id: ID of notification registration to cancel (see lgl_db_notify_add()).
+ *
+ * Cancel a previous registration a notification callback function.
+ */
+void
+lgl_db_notify_remove  (gulong id)
+{
+        g_signal_handler_disconnect (G_OBJECT (model), id);
+}
+
+
+/*===========================================*/
+/* Paper db functions.                       */
+/*===========================================*/
+
+/**
+ * lgl_db_get_paper_id_list:
+ *
+ * Get a list of all paper ids known to libglabels.
+ *
+ * Returns: a list of paper ids.
+ *
+ */
+GList *
+lgl_db_get_paper_id_list (void)
+{
+       GList           *ids = NULL;
+       GList           *p;
+       lglPaper        *paper;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+       for ( p=model->papers; p != NULL; p=p->next )
+        {
+               paper = (lglPaper *)p->data;
+               ids = g_list_append (ids, g_strdup (paper->id));
+       }
+
+       return ids;
+}
+
+
+/**
+ * lgl_db_free_paper_id_list:
+ * @ids: List of id strings to be freed.
+ *
+ * Free up all storage associated with an id list obtained with
+ * lgl_db_get_paper_id_list().
+ *
+ */
+void
+lgl_db_free_paper_id_list (GList *ids)
+{
+       GList *p;
+
+       for (p = ids; p != NULL; p = p->next)
+        {
+               g_free (p->data);
+               p->data = NULL;
+       }
+
+       g_list_free (ids);
+}
+
+
+/**
+ * lgl_db_get_paper_name_list:
+ *
+ * Get a list of all localized paper names known to libglabels.
+ *
+ * Returns: a list of localized paper names.
+ *
+ */
+GList *
+lgl_db_get_paper_name_list (void)
+{
+       GList           *names = NULL;
+       GList           *p;
+       lglPaper        *paper;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+       for ( p=model->papers; p != NULL; p=p->next )
+        {
+               paper = (lglPaper *)p->data;
+               names = g_list_append (names, g_strdup (paper->name));
+       }
+
+       return names;
+}
+
+
+/**
+ * lgl_db_free_paper_name_list:
+ * @names: List of localized paper name strings to be freed.
+ *
+ * Free up all storage associated with a name list obtained with
+ * lgl_db_get_paper_name_list().
+ *
+ */
+void
+lgl_db_free_paper_name_list (GList *names)
+{
+       GList *p;
+
+       for (p = names; p != NULL; p = p->next)
+        {
+               g_free (p->data);
+               p->data = NULL;
+       }
+
+       g_list_free (names);
+}
+
+
+/**
+ * lgl_db_lookup_paper_from_name:
+ * @name: localized paper name string
+ *
+ * Lookup paper definition from localized paper name string.
+ *
+ * Returns: pointer to a newly allocated #lglPaper structure.
+ *
+ */
+lglPaper *
+lgl_db_lookup_paper_from_name (const gchar *name)
+{
+       GList       *p;
+       lglPaper    *paper;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+       if (name == NULL)
+        {
+               /* If no name, return first paper as a default */
+               return lgl_paper_dup ((lglPaper *) model->papers->data);
+       }
+
+       for (p = model->papers; p != NULL; p = p->next)
+        {
+               paper = (lglPaper *) p->data;
+               if (UTF8_EQUAL (paper->name, name))
+                {
+                       return lgl_paper_dup (paper);
+               }
+       }
+
+       return NULL;
+}
+
+
+/**
+ * lgl_db_lookup_paper_from_id:
+ * @id: paper id string
+ *
+ * Lookup paper definition from id string.
+ *
+ * Returns: pointer to a newly allocated #lglPaper structure.
+ *
+ */
+lglPaper *
+lgl_db_lookup_paper_from_id (const gchar *id)
+{
+       GList       *p;
+       lglPaper    *paper;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+       if (id == NULL)
+        {
+               /* If no id, return first paper as a default */
+               return lgl_paper_dup ((lglPaper *) model->papers->data);
+       }
+
+       for (p = model->papers; p != NULL; p = p->next)
+        {
+               paper = (lglPaper *) p->data;
+               if (ASCII_EQUAL (paper->id, id))
+                {
+                       return lgl_paper_dup (paper);
+               }
+       }
+
+       return NULL;
+}
+
+
+/**
+ * lgl_db_lookup_paper_id_from_name:
+ * @name: localized paper name stringp
+ *
+ * Lookup paper name string from localized paper name string.
+ *
+ * Returns: pointer to a newly allocated id string.
+ *
+ */
+gchar *
+lgl_db_lookup_paper_id_from_name (const gchar *name)
+{
+       lglPaper *paper = NULL;
+       gchar    *id = NULL;
+
+       if (name != NULL)
+       {
+               paper = lgl_db_lookup_paper_from_name (name);
+               if ( paper != NULL )
+               {
+                       id = g_strdup (paper->id);
+                       lgl_paper_free (paper);
+                       paper = NULL;
+               }
+       }
+
+       return id;
+}
+
+
+/**
+ * lgl_db_lookup_paper_name_from_id:
+ * @id: paper id string
+ *
+ * Lookup localized paper name string from paper id string.
+ *
+ * Returns: pointer to a newly allocated localized paper name string.
+ *
+ */
+gchar *
+lgl_db_lookup_paper_name_from_id (const gchar         *id)
+{
+       lglPaper *paper = NULL;
+       gchar    *name = NULL;
+
+       if (id != NULL)
+       {
+               paper = lgl_db_lookup_paper_from_id (id);
+               if ( paper != NULL )
+               {
+                       name = g_strdup (paper->name);
+                       lgl_paper_free (paper);
+                       paper = NULL;
+               }
+       }
+
+       return name;
+}
+
+
+/**
+ * lgl_db_is_paper_id_known:
+ * @id: paper id to test
+ *
+ * Determine if given paper id is known to libglabels.
+ *
+ * Returns: TRUE if id is known, otherwise FALSE.
+ *
+ */
+gboolean
+lgl_db_is_paper_id_known (const gchar *id)
+{
+       GList       *p;
+       lglPaper    *paper;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+       if (id == NULL)
+        {
+               return FALSE;
+       }
+
+       for (p = model->papers; p != NULL; p = p->next)
+        {
+               paper = (lglPaper *) p->data;
+               if (ASCII_EQUAL (paper->id, id))
+                {
+                       return TRUE;
+               }
+       }
+
+       return FALSE;
+}
+
+
+/**
+ * lgl_db_is_paper_id_other:
+ * @id: paper id to test
+ *
+ * Determine if given paper id is the special id "Other."
+ *
+ * Returns: TRUE if id is "Other", otherwise FALSE.
+ *
+ */
+gboolean
+lgl_db_is_paper_id_other (const gchar *id)
+{
+       if (id == NULL)
+        {
+               return FALSE;
+       }
+
+       return (ASCII_EQUAL (id, "Other"));
+}
+
+
+static GList *
+read_papers (void)
+{
+       gchar *data_dir;
+       GList *papers = NULL;
+
+       data_dir = SYSTEM_CONFIG_DIR;
+       papers = read_paper_files_from_dir (papers, data_dir);
+       g_free (data_dir);
+
+       data_dir = USER_CONFIG_DIR;
+       papers = read_paper_files_from_dir (papers, data_dir);
+       g_free (data_dir);
+
+       if (papers == NULL) {
+               g_critical (_("Unable to locate paper size definitions.  Libglabels may not be installed correctly!"));
+       }
+
+       return papers;
+}
+
+
+static GList *
+read_paper_files_from_dir (GList       *papers,
+                          const gchar *dirname)
+{
+       GDir        *dp;
+       const gchar *filename, *extension;
+       gchar       *full_filename = NULL;
+       GError      *gerror = NULL;
+       GList       *new_papers = NULL;
+
+       if (dirname == NULL) {
+               return papers;
+       }
+
+       if (!g_file_test (dirname, G_FILE_TEST_EXISTS)) {
+               return papers;
+       }
+
+       dp = g_dir_open (dirname, 0, &gerror);
+       if (gerror != NULL) {
+               g_message ("cannot open data directory: %s", gerror->message );
+               return papers;
+       }
+
+       while ((filename = g_dir_read_name (dp)) != NULL) {
+
+               extension = strrchr (filename, '.');
+
+               if (extension != NULL) {
+
+                       if ( ASCII_EQUAL (filename, "paper-sizes.xml") )
+                        {
+
+                               full_filename =
+                                   g_build_filename (dirname, filename, NULL);
+                               new_papers =
+                                   lgl_xml_paper_read_papers_from_file (full_filename);
+                               g_free (full_filename);
+
+                               papers = g_list_concat (papers, new_papers);
+                               new_papers = NULL;
+
+                       }
+
+               }
+
+       }
+
+       g_dir_close (dp);
+
+       return papers;
+}
+
+
+/**
+ * lgl_db_print_known_papers:
+ *
+ * For debugging purposes: print a list of all paper definitions known to
+ * libglabels.
+ *
+ */
+void
+lgl_db_print_known_papers (void)
+{
+       GList       *p;
+       lglPaper    *paper;
+
+       if (!model) {
+               lgl_db_init ();
+       }
+
+       g_print ("%s():\n", __FUNCTION__);
+       for (p = model->papers; p != NULL; p = p->next) {
+               paper = (lglPaper *) p->data;
+
+               g_print ("PAPER id=\"%s\", name=\"%s\", width=%gpts, height=%gpts\n",
+                        paper->id, paper->name, paper->width, paper->height);
+
+       }
+       g_print ("\n");
+
+}
+
+
+/*===========================================*/
+/* Category db functions.                    */
+/*===========================================*/
+
+/**
+ * lgl_db_get_category_id_list:
+ *
+ * Get a list of all category ids known to libglabels.
+ *
+ * Returns: a list of category ids.
+ *
+ */
+GList *
+lgl_db_get_category_id_list (void)
+{
+       GList           *ids = NULL;
+       GList           *p;
+       lglCategory     *category;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+       for ( p=model->categories; p != NULL; p=p->next )
+        {
+               category = (lglCategory *)p->data;
+               ids = g_list_append (ids, g_strdup (category->id));
+       }
+
+       return ids;
+}
+
+
+/**
+ * lgl_db_free_category_id_list:
+ * @ids: List of id strings to be freed.
+ *
+ * Free up all storage associated with an id list obtained with
+ * lgl_db_get_category_id_list().
+ *
+ */
+void
+lgl_db_free_category_id_list (GList *ids)
+{
+       GList *p;
+
+       for (p = ids; p != NULL; p = p->next)
+        {
+               g_free (p->data);
+               p->data = NULL;
+       }
+
+       g_list_free (ids);
+}
+
+
+/**
+ * lgl_db_get_category_name_list:
+ *
+ * Get a list of all localized category names known to libglabels.
+ *
+ * Returns: a list of localized category names.
+ *
+ */
+GList *
+lgl_db_get_category_name_list (void)
+{
+       GList           *names = NULL;
+       GList           *p;
+       lglCategory     *category;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+       for ( p=model->categories; p != NULL; p=p->next )
+        {
+               category = (lglCategory *)p->data;
+               names = g_list_append (names, g_strdup (category->name));
+       }
+
+       return names;
+}
+
+
+/**
+ * lgl_db_free_category_name_list:
+ * @names: List of localized category name strings to be freed.
+ *
+ * Free up all storage associated with a name list obtained with
+ * lgl_db_get_category_name_list().
+ *
+ */
+void
+lgl_db_free_category_name_list (GList *names)
+{
+       GList *p;
+
+       for (p = names; p != NULL; p = p->next)
+        {
+               g_free (p->data);
+               p->data = NULL;
+       }
+
+       g_list_free (names);
+}
+
+
+/**
+ * lgl_db_lookup_category_from_name:
+ * @name: localized category name string
+ *
+ * Lookup category definition from localized category name string.
+ *
+ * Returns: pointer to a newly allocated #lglCategory structure.
+ *
+ */
+lglCategory *
+lgl_db_lookup_category_from_name (const gchar *name)
+{
+       GList       *p;
+       lglCategory *category;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+       if (name == NULL)
+        {
+               /* If no name, return first category as a default */
+               return lgl_category_dup ((lglCategory *) model->categories->data);
+       }
+
+       for (p = model->categories; p != NULL; p = p->next)
+        {
+               category = (lglCategory *) p->data;
+               if (UTF8_EQUAL (category->name, name))
+                {
+                       return lgl_category_dup (category);
+               }
+       }
+
+       return NULL;
+}
+
+
+/**
+ * lgl_db_lookup_category_from_id:
+ * @id: category id string
+ *
+ * Lookup category definition from id string.
+ *
+ * Returns: pointer to a newly allocated #lglCategory structure.
+ *
+ */
+lglCategory *
+lgl_db_lookup_category_from_id (const gchar *id)
+{
+       GList       *p;
+       lglCategory *category;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+       if (id == NULL)
+        {
+               /* If no id, return first category as a default */
+               return lgl_category_dup ((lglCategory *) model->categories->data);
+       }
+
+       for (p = model->categories; p != NULL; p = p->next)
+        {
+               category = (lglCategory *) p->data;
+               if (ASCII_EQUAL (category->id, id))
+                {
+                       return lgl_category_dup (category);
+               }
+       }
+
+       return NULL;
+}
+
+
+/**
+ * lgl_db_lookup_category_id_from_name:
+ * @name: localized category name stringp
+ *
+ * Lookup category name string from localized category name string.
+ *
+ * Returns: pointer to a newly allocated id string.
+ *
+ */
+gchar *
+lgl_db_lookup_category_id_from_name (const gchar *name)
+{
+       lglCategory *category = NULL;
+       gchar       *id = NULL;
+
+       if (name != NULL)
+       {
+               category = lgl_db_lookup_category_from_name (name);
+               if ( category != NULL )
+               {
+                       id = g_strdup (category->id);
+                       lgl_category_free (category);
+                       category = NULL;
+               }
+       }
+
+       return id;
+}
+
+
+/**
+ * lgl_db_lookup_category_name_from_id:
+ * @id: category id string
+ *
+ * Lookup localized category name string from category id string.
+ *
+ * Returns: pointer to a newly allocated localized category name string.
+ *
+ */
+gchar *
+lgl_db_lookup_category_name_from_id (const gchar         *id)
+{
+       lglCategory *category = NULL;
+       gchar       *name = NULL;
+
+       if (id != NULL)
+       {
+               category = lgl_db_lookup_category_from_id (id);
+               if ( category != NULL )
+               {
+                       name = g_strdup (category->name);
+                       lgl_category_free (category);
+                       category = NULL;
+               }
+       }
+
+       return name;
+}
+
+
+/**
+ * lgl_db_is_category_id_known:
+ * @id: category id to test
+ *
+ * Determine if given category id is known to libglabels.
+ *
+ * Returns: TRUE if id is known, otherwise FALSE.
+ *
+ */
+gboolean
+lgl_db_is_category_id_known (const gchar *id)
+{
+       GList       *p;
+       lglCategory *category;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+       if (id == NULL)
+        {
+               return FALSE;
+       }
+
+       for (p = model->categories; p != NULL; p = p->next)
+        {
+               category = (lglCategory *) p->data;
+               if (ASCII_EQUAL (category->id, id))
+                {
+                       return TRUE;
+               }
+       }
+
+       return FALSE;
+}
+
+
+static GList *
+read_categories (void)
+{
+       gchar *data_dir;
+       GList *categories = NULL;
+
+       data_dir = SYSTEM_CONFIG_DIR;
+       categories = read_category_files_from_dir (categories, data_dir);
+       g_free (data_dir);
+
+       data_dir = USER_CONFIG_DIR;
+       categories = read_category_files_from_dir (categories, data_dir);
+       g_free (data_dir);
+
+       if (categories == NULL) {
+               g_critical (_("Unable to locate category definitions.  Libglabels may not be installed correctly!"));
+       }
+
+       return categories;
+}
+
+
+static GList *
+read_category_files_from_dir (GList       *categories,
+                              const gchar *dirname)
+{
+       GDir        *dp;
+       const gchar *filename, *extension;
+       gchar       *full_filename = NULL;
+       GError      *gerror = NULL;
+       GList       *new_categories = NULL;
+
+       if (dirname == NULL) {
+               return categories;
+       }
+
+       if (!g_file_test (dirname, G_FILE_TEST_EXISTS)) {
+               return categories;
+       }
+
+       dp = g_dir_open (dirname, 0, &gerror);
+       if (gerror != NULL) {
+               g_message ("cannot open data directory: %s", gerror->message );
+               return categories;
+       }
+
+       while ((filename = g_dir_read_name (dp)) != NULL) {
+
+               extension = strrchr (filename, '.');
+
+               if (extension != NULL) {
+
+                       if ( ASCII_EQUAL (filename, "categories.xml") )
+                        {
+
+                               full_filename =
+                                   g_build_filename (dirname, filename, NULL);
+                               new_categories =
+                                   lgl_xml_category_read_categories_from_file (full_filename);
+                               g_free (full_filename);
+
+                               categories = g_list_concat (categories, new_categories);
+                               new_categories = NULL;
+
+                       }
+
+               }
+
+       }
+
+       g_dir_close (dp);
+
+       return categories;
+}
+
+
+/**
+ * lgl_db_print_known_categories:
+ *
+ * For debugging purposes: print a list of all category definitions known to
+ * libglabels.
+ *
+ */
+void
+lgl_db_print_known_categories (void)
+{
+       GList       *p;
+       lglCategory *category;
+
+       if (!model) {
+               lgl_db_init ();
+       }
+
+       g_print ("%s():\n", __FUNCTION__);
+       for (p = model->categories; p != NULL; p = p->next) {
+               category = (lglCategory *) p->data;
+
+               g_print ("CATEGORY id=\"%s\", name=\"%s\"\n", category->id, category->name);
+
+       }
+       g_print ("\n");
+
+}
+
+
+/*===========================================*/
+/* Vendor db functions.                       */
+/*===========================================*/
+
+/**
+ * lgl_db_get_vendor_name_list:
+ *
+ * Get a list of all localized vendor names known to libglabels.
+ *
+ * Returns: a list of localized vendor names.
+ *
+ */
+GList *
+lgl_db_get_vendor_name_list (void)
+{
+       GList           *names = NULL;
+       GList           *p;
+       lglVendor       *vendor;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+       for ( p=model->vendors; p != NULL; p=p->next )
+        {
+               vendor = (lglVendor *)p->data;
+               names = g_list_append (names, g_strdup (vendor->name));
+       }
+
+       return names;
+}
+
+
+/**
+ * lgl_db_free_vendor_name_list:
+ * @names: List of localized vendor name strings to be freed.
+ *
+ * Free up all storage associated with a name list obtained with
+ * lgl_db_get_vendor_name_list().
+ *
+ */
+void
+lgl_db_free_vendor_name_list (GList *names)
+{
+       GList *p;
+
+       for (p = names; p != NULL; p = p->next)
+        {
+               g_free (p->data);
+               p->data = NULL;
+       }
+
+       g_list_free (names);
+}
+
+
+/**
+ * lgl_db_lookup_vendor_from_name:
+ * @name: localized vendor name string
+ *
+ * Lookup vendor definition from localized vendor name string.
+ *
+ * Returns: pointer to a newly allocated #lglVendor structure.
+ *
+ */
+lglVendor *
+lgl_db_lookup_vendor_from_name (const gchar *name)
+{
+       GList       *p;
+       lglVendor   *vendor;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+       if (name == NULL)
+        {
+               /* If no name, return first vendor as a default */
+               return lgl_vendor_dup ((lglVendor *) model->vendors->data);
+       }
+
+       for (p = model->vendors; p != NULL; p = p->next)
+        {
+               vendor = (lglVendor *) p->data;
+               if (UTF8_EQUAL (vendor->name, name))
+                {
+                       return lgl_vendor_dup (vendor);
+               }
+       }
+
+       return NULL;
+}
+
+
+/**
+ * lgl_db_is_vendor_name_known:
+ * @name: vendor name to test
+ *
+ * Determine if given vendor id is known to libglabels.
+ *
+ * Returns: TRUE if id is known, otherwise FALSE.
+ *
+ */
+gboolean
+lgl_db_is_vendor_name_known (const gchar *name)
+{
+       GList       *p;
+       lglVendor   *vendor;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+       if (name == NULL)
+        {
+               return FALSE;
+       }
+
+       for (p = model->vendors; p != NULL; p = p->next)
+        {
+               vendor = (lglVendor *) p->data;
+               if (UTF8_EQUAL (vendor->name, name))
+                {
+                       return TRUE;
+               }
+       }
+
+       return FALSE;
+}
+
+
+static GList *
+read_vendors (void)
+{
+       gchar *data_dir;
+       GList *vendors = NULL;
+
+       data_dir = SYSTEM_CONFIG_DIR;
+       vendors = read_vendor_files_from_dir (vendors, data_dir);
+       g_free (data_dir);
+
+       data_dir = USER_CONFIG_DIR;
+       vendors = read_vendor_files_from_dir (vendors, data_dir);
+       g_free (data_dir);
+
+       return vendors;
+}
+
+
+static GList *
+read_vendor_files_from_dir (GList      *vendors,
+                          const gchar *dirname)
+{
+       GDir        *dp;
+       const gchar *filename, *extension;
+       gchar       *full_filename = NULL;
+       GError      *gerror = NULL;
+       GList       *new_vendors = NULL;
+
+       if (dirname == NULL) {
+               return vendors;
+       }
+
+       if (!g_file_test (dirname, G_FILE_TEST_EXISTS)) {
+               return vendors;
+       }
+
+       dp = g_dir_open (dirname, 0, &gerror);
+       if (gerror != NULL) {
+               g_message ("cannot open data directory: %s", gerror->message );
+               return vendors;
+       }
+
+       while ((filename = g_dir_read_name (dp)) != NULL) {
+
+               extension = strrchr (filename, '.');
+
+               if (extension != NULL) {
+
+                       if ( ASCII_EQUAL (filename, "vendors.xml") )
+                        {
+
+                               full_filename =
+                                   g_build_filename (dirname, filename, NULL);
+                               new_vendors =
+                                   lgl_xml_vendor_read_vendors_from_file (full_filename);
+                               g_free (full_filename);
+
+                               vendors = g_list_concat (vendors, new_vendors);
+                               new_vendors = NULL;
+
+                       }
+
+               }
+
+       }
+
+       g_dir_close (dp);
+
+       return vendors;
+}
+
+
+/**
+ * lgl_db_print_known_vendors:
+ *
+ * For debugging purposes: print a list of all vendor definitions known to
+ * libglabels.
+ *
+ */
+void
+lgl_db_print_known_vendors (void)
+{
+       GList       *p;
+       lglVendor   *vendor;
+
+       if (!model) {
+               lgl_db_init ();
+       }
+
+       g_print ("%s():\n", __FUNCTION__);
+       for (p = model->vendors; p != NULL; p = p->next) {
+               vendor = (lglVendor *) p->data;
+
+               g_print ("VENDOR name=\"%s\", url=\"%s\"\n",
+                        vendor->name, vendor->url);
+
+       }
+       g_print ("\n");
+
+}
+
+
+/*===========================================*/
+/* Brand db functions.                       */
+/*===========================================*/
+
+/**
+ * lgl_db_get_brand_list:
+ * @paper_id: If non NULL, limit results to given page size.
+ * @category_id: If non NULL, limit results to given template category.
+ *
+ * Get a list of all valid brands of templates in the template database.
+ * Results can be filtered by page size and/or template category.  A list of valid page
+ * sizes can be obtained using lgl_db_get_paper_id_list().  A list of valid template
+ * categories can be obtained using lgl_db_get_category_id_list().
+ *
+ * Returns: a list of brands
+ */
+GList *
+lgl_db_get_brand_list (const gchar *paper_id,
+                       const gchar *category_id)
+{
+       GList            *p_tmplt;
+       lglTemplate      *template;
+       GList            *brands = NULL;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+       for (p_tmplt = model->templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
+        {
+               template = (lglTemplate *) p_tmplt->data;
+               if (lgl_template_does_page_size_match (template, paper_id) &&
+                    lgl_template_does_category_match (template, category_id))
+                {
+
+                        if ( !g_list_find_custom (brands, template->brand,
+                                                  (GCompareFunc)lgl_str_utf8_casecmp) )
+                        {
+                                brands = g_list_insert_sorted (brands,
+                                                               g_strdup (template->brand),
+                                                               (GCompareFunc)lgl_str_utf8_casecmp);
+                        }
+               }
+       }
+
+       return brands;
+}
+
+
+/**
+ * lgl_db_free_brand_list:
+ * @brands: List of template brand strings to be freed.
+ *
+ * Free up all storage associated with a list of template names obtained with
+ * lgl_db_get_brand_list().
+ *
+ */
+void
+lgl_db_free_brand_list (GList *brands)
+{
+       GList *p_brand;
+
+       for (p_brand = brands; p_brand != NULL; p_brand = p_brand->next)
+        {
+               g_free (p_brand->data);
+               p_brand->data = NULL;
+       }
+
+       g_list_free (brands);
+}
+
+
+/*===========================================*/
+/* Template db functions.                    */
+/*===========================================*/
+
+void
+_lgl_db_register_template_internal (const lglTemplate   *template)
+{
+        lglTemplate *template_copy;
+
+        if (!lgl_db_does_template_exist (template->brand, template->part))
+        {
+                template_copy = lgl_template_dup (template);
+                model->templates = g_list_append (model->templates, template_copy);
+                add_to_template_cache (template_copy);
+        }
+        else
+        {
+               g_message ("Duplicate template: %s %s.", template->brand, template->part);
+        }
+}
+
+
+/**
+ * lgl_db_register_template:
+ * @template:  Pointer to a template structure to add to database.
+ *
+ * Register a template.  This function adds a template to the template database.
+ * The template will be stored in an individual XML file in the user template directory.
+ *
+ * Returns: Status of registration attempt (#lglDbRegStatus)
+ */
+lglDbRegStatus
+lgl_db_register_template (const lglTemplate *template)
+{
+        lglTemplate *template_copy;
+        gchar       *dir, *filename, *abs_filename;
+        gint         bytes_written;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+        if (lgl_db_does_template_exist (template->brand, template->part))
+        {
+                return LGL_DB_REG_BRAND_PART_EXISTS;
+        }
+
+       if (lgl_db_is_paper_id_known (template->paper_id))
+        {
+               dir = USER_CONFIG_DIR;
+               g_mkdir_with_parents (dir, 0775); /* Try to make sure directory exists. */
+               filename = g_strdup_printf ("%s_%s.template", template->brand, template->part);
+               abs_filename = g_build_filename (dir, filename, NULL);
+               bytes_written = lgl_xml_template_write_template_to_file (template, abs_filename);
+               g_free (dir);
+               g_free (filename);
+               g_free (abs_filename);
+
+                if (bytes_written > 0)
+                {
+                        template_copy = lgl_template_dup (template);
+                        lgl_template_add_category (template_copy, "user-defined");
+                        model->templates = g_list_append (model->templates, template_copy);
+                        add_to_template_cache (template_copy);
+                        g_signal_emit (G_OBJECT (model), signals[CHANGED], 0);
+                        return LGL_DB_REG_OK;
+                }
+                else
+                {
+                        return LGL_DB_REG_FILE_WRITE_ERROR;
+                }
+       }
+        else
+        {
+               g_message ("Cannot register new template with unknown page size.");
+                return LGL_DB_REG_BAD_PAPER_ID;
+       }
+
+}
+
+
+/**
+ * lgl_db_delete_template_by_name:
+ * @name:  Name of template to be deleted.
+ *
+ * Delete a user defined template.  This function deletes a template from
+ * the template database. The individual XML file in the user template
+ * directory will also be removed.
+ *
+ * Returns: Status of registration attempt (#lglDbDeleteStatus)
+ */
+lglDbDeleteStatus
+lgl_db_delete_template_by_name (const gchar *name)
+{
+        lglTemplate *template, *template1;
+        gchar       *dir, *filename, *abs_filename;
+        GList       *p;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+        if (!lgl_db_does_template_name_exist (name))
+        {
+                return LGL_DB_DELETE_DOES_NOT_EXIST;
+        }
+
+        template = lgl_db_lookup_template_from_name (name);
+        if ( lgl_template_does_category_match (template, "user-defined") )
+        {
+               dir = USER_CONFIG_DIR;
+               filename = g_strdup_printf ("%s_%s.template", template->brand, template->part);
+               abs_filename = g_build_filename (dir, filename, NULL);
+
+                if (!g_file_test (abs_filename, G_FILE_TEST_EXISTS))
+                {
+                        g_message ("File \"%s\" does not exist.  Cannot delete template.", abs_filename);
+                        return LGL_DB_DELETE_DOES_NOT_EXIST;
+                }
+
+                g_unlink (abs_filename);
+
+               g_free (dir);
+               g_free (filename);
+               g_free (abs_filename);
+
+                for ( p=model->templates; p != NULL; p=p->next )
+                {
+                        template1 = (lglTemplate *)p->data;
+
+                        if ( lgl_template_do_templates_match (template, template1) )
+                        {
+                                model->templates = g_list_delete_link (model->templates, p);
+                                g_hash_table_remove (model->template_cache, name);
+                                break;
+                        }
+                }
+
+                lgl_template_free (template);
+
+                g_signal_emit (G_OBJECT (model), signals[CHANGED], 0);
+                return LGL_DB_DELETE_OK;
+        }
+        else
+        {
+                return LGL_DB_DELETE_NOT_USER_DEFINED;
+        }
+
+}
+
+
+/**
+ * lgl_db_delete_template_by_brand_part:
+ * @brand:  Brand name or vendor of template to be deleted.
+ * @part:   Part name or number of template to be deleted.
+ *
+ * Delete a user defined template.  This function deletes a template from
+ * the template database. The individual XML file in the user template
+ * directory will also be removed.
+ *
+ * Returns: Status of registration attempt (#lglDbDeleteStatus)
+ */
+lglDbDeleteStatus
+lgl_db_delete_template_by_brand_part (const gchar  *brand,
+                                      const gchar  *part)
+{
+        gchar             *name;
+        lglDbDeleteStatus  status;
+
+        name = g_strdup_printf ("%s %s", brand, part);
+
+        status = lgl_db_delete_template_by_name (name);
+
+        g_free (name);
+
+        return status;
+}
+
+
+/**
+ * lgl_db_does_template_exist:
+ * @brand: Brand name.
+ * @part:  Part name/number.
+ *
+ * This function tests whether a template with the given brand and part name/number exists.
+ *
+ * Returns:  TRUE if such a template exists in the database.
+ */
+gboolean
+lgl_db_does_template_exist (const gchar *brand,
+                            const gchar *part)
+{
+       GList            *p_tmplt;
+       lglTemplate      *template;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+       if ((brand == NULL) || (part == NULL))
+        {
+               return FALSE;
+       }
+
+       for (p_tmplt = model->templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
+        {
+               template = (lglTemplate *) p_tmplt->data;
+
+                if ( UTF8_EQUAL (brand, template->brand) &&
+                     UTF8_EQUAL (part, template->part) )
+                {
+                        return TRUE;
+                }
+       }
+
+       return FALSE;
+}
+
+
+/**
+ * lgl_db_does_template_name_exist:
+ * @name: name string
+ *
+ * This function test whether a template with the given name exists.
+ *
+ * Returns: TRUE if such a template exists in the database.
+ *
+ */
+gboolean
+lgl_db_does_template_name_exist (const gchar *name)
+{
+       GList            *p_tmplt;
+        lglTemplate      *template;
+        gchar            *candidate_name;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+       if (name == NULL)
+        {
+               return FALSE;
+       }
+
+       for (p_tmplt = model->templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
+        {
+               template = (lglTemplate *) p_tmplt->data;
+                candidate_name = g_strdup_printf ("%s %s", template->brand, template->part);
+
+                if ( UTF8_EQUAL (candidate_name, name) )
+                {
+                        g_free (candidate_name);
+                        return TRUE;
+                }
+                g_free (candidate_name);
+       }
+
+       return FALSE;
+}
+
+
+/**
+ * lgl_db_get_template_name_list_all:
+ * @brand:     If non NULL, limit results to given brand
+ * @paper_id: If non NULL, limit results to given page size.
+ * @category_id: If non NULL, limit results to given template category.
+ *
+ * Get a list of all valid names of templates in the template database.
+ * Results can be filtered by page size and/or template category.  A list of valid page
+ * sizes can be obtained using lgl_db_get_paper_id_list().  A list of valid template
+ * categories can be obtained using lgl_db_get_category_id_list().
+ *
+ * Returns: a list of template names.
+ */
+GList *
+lgl_db_get_template_name_list_all (const gchar *brand,
+                                   const gchar *paper_id,
+                                   const gchar *category_id)
+{
+       GList            *p_tmplt;
+       lglTemplate      *template;
+        gchar            *name;
+       GList            *names = NULL;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+       for (p_tmplt = model->templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
+        {
+               template = (lglTemplate *) p_tmplt->data;
+               if (lgl_template_does_brand_match (template, brand) &&
+                    lgl_template_does_page_size_match (template, paper_id) &&
+                    lgl_template_does_category_match (template, category_id))
+                {
+                        name = g_strdup_printf ("%s %s", template->brand, template->part);
+                        names = g_list_insert_sorted (names, name, (GCompareFunc)lgl_str_part_name_cmp);
+               }
+       }
+
+       return names;
+}
+
+
+/**
+ * lgl_db_get_similar_template_name_list:
+ * @name:     Name of template under test.
+ *
+ * Get a list of all valid names of templates in the template database that
+ * have the same size and layout characteristics as the given template.
+ *
+ * Returns: a list of template names.
+ */
+GList *
+lgl_db_get_similar_template_name_list (const gchar  *name)
+{
+       GList            *p_tmplt;
+       lglTemplate      *template1;
+       lglTemplate      *template2;
+        gchar            *name2;
+       GList            *names = NULL;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+        if ( !name )
+        {
+                return NULL;
+        }
+
+        template1 = lgl_db_lookup_template_from_name (name);
+        if ( !template1 )
+        {
+                return NULL;
+        }
+
+       for (p_tmplt = model->templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
+        {
+               template2 = (lglTemplate *) p_tmplt->data;
+
+                if ( lgl_template_are_templates_identical (template1, template2) )
+                {
+
+                        name2 = g_strdup_printf ("%s %s", template2->brand, template2->part);
+                        if ( !UTF8_EQUAL (name2, name) )
+                        {
+                                names = g_list_insert_sorted (names, name2,
+                                                              (GCompareFunc)lgl_str_part_name_cmp);
+                        }
+
+               }
+       }
+
+       return names;
+}
+
+
+/**
+ * lgl_db_free_template_name_list:
+ * @names: List of template name strings to be freed.
+ *
+ * Free up all storage associated with a list of template names obtained with
+ * lgl_db_get_template_name_list_all().
+ *
+ */
+void
+lgl_db_free_template_name_list (GList *names)
+{
+       GList *p_name;
+
+       for (p_name = names; p_name != NULL; p_name = p_name->next)
+        {
+               g_free (p_name->data);
+               p_name->data = NULL;
+       }
+
+       g_list_free (names);
+}
+
+
+/**
+ * lgl_db_lookup_template_from_name:
+ * @name: name string
+ *
+ * Lookup template in template database from name string.
+ *
+ * Returns: pointer to a newly allocated #lglTemplate structure.
+ *
+ */
+lglTemplate *
+lgl_db_lookup_template_from_name (const gchar *name)
+{
+       lglTemplate      *template;
+       lglTemplate      *new_template;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+       if (name == NULL)
+        {
+               /* If no name, return first template as a default */
+               return lgl_template_dup ((lglTemplate *) model->templates->data);
+       }
+
+        template = g_hash_table_lookup (model->template_cache, name);
+
+        if (template)
+        {
+                new_template = lgl_template_dup (template);
+                return new_template;
+        }
+
+       /* No matching template has been found so return the first template */
+       return lgl_template_dup ((lglTemplate *) model->templates->data);
+}
+
+
+/**
+ * lgl_db_lookup_template_from_brand_part:
+ * @brand: brand name string
+ * @part:  part name string
+ *
+ * Lookup template in template database from brand and part strings.
+ *
+ * Returns: pointer to a newly allocated #lglTemplate structure.
+ *
+ */
+lglTemplate *
+lgl_db_lookup_template_from_brand_part(const gchar *brand,
+                                       const gchar *part)
+{
+        gchar            *name;
+       lglTemplate      *template;
+       lglTemplate      *new_template;
+
+       if (!model)
+        {
+               lgl_db_init ();
+       }
+
+       if ((brand == NULL) || (part == NULL))
+        {
+               /* If no name, return first template as a default */
+               return lgl_template_dup ((lglTemplate *) model->templates->data);
+       }
+
+        name = g_strdup_printf ("%s %s", brand, part);
+        template = g_hash_table_lookup (model->template_cache, name);
+
+        if (template)
+        {
+                new_template = lgl_template_dup (template);
+                return new_template;
+        }
+
+       /* No matching template has been found so return the first template */
+        g_free (name);
+       return lgl_template_dup ((lglTemplate *) model->templates->data);
+}
+
+
+static void
+add_to_template_cache (lglTemplate *template)
+{
+        gchar            *name;
+
+        name = g_strdup_printf ("%s %s", template->brand, template->part);
+
+        g_hash_table_insert (model->template_cache, name, template);
+}
+
+
+void
+read_templates (void)
+{
+       gchar       *data_dir;
+        GList       *p;
+        lglTemplate *template;
+
+        /*
+         * User defined templates.  Add to user-defined category.
+         */
+       data_dir = USER_CONFIG_DIR;
+       read_template_files_from_dir (data_dir);
+       g_free (data_dir);
+        for ( p=model->templates; p != NULL; p=p->next )
+        {
+                template = (lglTemplate *)p->data;
+                lgl_template_add_category (template, "user-defined");
+        }
+
+        /*
+         * Alternate user defined templates.  (Used for manually created templates).
+         */
+       data_dir = ALT_USER_CONFIG_DIR;
+       read_template_files_from_dir (data_dir);
+       g_free (data_dir);
+
+        /*
+         * System templates.
+         */
+       data_dir = SYSTEM_CONFIG_DIR;
+       read_template_files_from_dir (data_dir);
+       g_free (data_dir);
+
+       if (model->templates == NULL)
+        {
+               g_critical (_("Unable to locate any template files.  Libglabels may not be installed correctly!"));
+       }
+}
+
+
+void
+read_template_files_from_dir (const gchar *dirname)
+{
+       GDir        *dp;
+       const gchar *filename, *extension, *extension2;
+       gchar       *full_filename = NULL;
+       GError      *gerror = NULL;
+
+       if (dirname == NULL)
+               return;
+
+       if (!g_file_test (dirname, G_FILE_TEST_EXISTS))
+        {
+               return;
+       }
+
+       dp = g_dir_open (dirname, 0, &gerror);
+       if (gerror != NULL)
+        {
+               g_message ("cannot open data directory: %s", gerror->message );
+               return;
+       }
+
+       while ((filename = g_dir_read_name (dp)) != NULL)
+        {
+
+               extension = strrchr (filename, '.');
+               extension2 = strrchr (filename, '-');
+
+               if ( (extension && ASCII_EQUAL (extension, ".template")) ||
+                    (extension2 && ASCII_EQUAL (extension2, "-templates.xml")) )
+                {
+
+                       full_filename = g_build_filename (dirname, filename, NULL);
+                        lgl_xml_template_read_templates_from_file (full_filename);
+                       g_free (full_filename);
+               }
+
+       }
+
+       g_dir_close (dp);
+}
+
+
+static lglTemplate *
+template_full_page (const gchar *paper_id)
+{
+       lglPaper              *paper = NULL;
+       lglTemplate           *template = NULL;
+       lglTemplateFrame      *frame = NULL;
+        gchar                 *part;
+        gchar                 *desc;
+
+       g_return_val_if_fail (paper_id, NULL);
+
+       paper = lgl_db_lookup_paper_from_id (paper_id);
+       if ( paper == NULL )
+        {
+               return NULL;
+       }
+
+       part = g_strdup_printf ("%s-Full-Page", paper->id);
+       desc = g_strdup_printf (_("%s full page label"), paper->name);
+
+       template = lgl_template_new ("Generic", part, desc,
+                                     paper_id, paper->width, paper->height);
+
+
+       frame = lgl_template_frame_rect_new ("0",
+                                             paper->width,
+                                             paper->height,
+                                             0.0,
+                                             0.0,
+                                             0.0);
+       lgl_template_add_frame (template, frame);
+
+       lgl_template_frame_add_layout (frame, lgl_template_layout_new (1, 1, 0., 0., 0., 0.));
+
+       lgl_template_frame_add_markup (frame, lgl_template_markup_margin_new (9.0));
+
+       g_free (desc);
+       desc = NULL;
+       lgl_paper_free (paper);
+       paper = NULL;
+
+       return template;
+}
+
+
+/**
+ * lgl_db_print_known_templates:
+ *
+ * Print all known templates (for debugging purposes).
+ *
+ */
+void
+lgl_db_print_known_templates (void)
+{
+       GList       *p;
+       lglTemplate *template;
+
+        if (!model)
+        {
+                lgl_db_init ();
+        }
+
+       g_print ("%s():\n", __FUNCTION__);
+       for (p=model->templates; p!=NULL; p=p->next)
+        {
+               template = (lglTemplate *)p->data;
+
+               g_print("TEMPLATE brand=\"%s\", part=\"%s\", description=\"%s\"\n",
+                       template->brand, template->part, template->description);
+
+       }
+       g_print ("\n");
+
+}
+
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-db.h b/libglabels/lgl-db.h
new file mode 100644 (file)
index 0000000..a505e62
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ *  lgl-db.h
+ *  Copyright (C) 2006-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LGL_DB_H__
+#define __LGL_DB_H__
+
+#include <glib.h>
+
+#include "lgl-paper.h"
+#include "lgl-category.h"
+#include "lgl-vendor.h"
+#include "lgl-template.h"
+
+G_BEGIN_DECLS
+
+typedef enum
+{
+        LGL_DB_REG_OK                =  0,
+        LGL_DB_REG_BAD_PAPER_ID      = -1,
+        LGL_DB_REG_BRAND_PART_EXISTS = -2,
+        LGL_DB_REG_FILE_WRITE_ERROR  = -3
+} lglDbRegStatus;
+
+typedef enum
+{
+        LGL_DB_DELETE_OK                =  0,
+        LGL_DB_DELETE_DOES_NOT_EXIST    = -1,
+        LGL_DB_DELETE_NOT_USER_DEFINED  = -2,
+        LGL_DB_DELETE_FILE_ERROR        = -3
+} lglDbDeleteStatus;
+
+
+typedef void  (*lglDbNotifyFunc) (gpointer user_data);
+
+
+
+
+/*
+ * Module initialization
+ */
+void           lgl_db_init                           (void);
+
+
+
+/*
+ * Notification
+ */
+gulong         lgl_db_notify_add                     (lglDbNotifyFunc      func,
+                                                      gpointer             user_data);
+
+void           lgl_db_notify_remove                  (gulong               id);
+
+
+
+/*
+ * Paper
+ */
+GList         *lgl_db_get_paper_id_list              (void);
+
+void           lgl_db_free_paper_id_list             (GList               *ids);
+
+GList         *lgl_db_get_paper_name_list            (void);
+
+void           lgl_db_free_paper_name_list           (GList               *names);
+
+lglPaper      *lgl_db_lookup_paper_from_name         (const gchar         *name);
+
+lglPaper      *lgl_db_lookup_paper_from_id           (const gchar         *id);
+
+gchar         *lgl_db_lookup_paper_id_from_name      (const gchar         *name);
+
+gchar         *lgl_db_lookup_paper_name_from_id      (const gchar         *id);
+
+gboolean       lgl_db_is_paper_id_known              (const gchar         *id);
+
+gboolean       lgl_db_is_paper_id_other              (const gchar         *id);
+
+
+
+/*
+ * Template categories
+ */
+GList         *lgl_db_get_category_id_list           (void);
+
+void           lgl_db_free_category_id_list          (GList              *ids);
+
+GList         *lgl_db_get_category_name_list         (void);
+
+void           lgl_db_free_category_name_list        (GList               *names);
+
+lglCategory   *lgl_db_lookup_category_from_name      (const gchar         *name);
+
+lglCategory   *lgl_db_lookup_category_from_id        (const gchar         *id);
+
+gchar         *lgl_db_lookup_category_id_from_name   (const gchar         *name);
+
+gchar         *lgl_db_lookup_category_name_from_id   (const gchar         *id);
+
+gboolean       lgl_db_is_category_id_known           (const gchar         *id);
+
+
+/*
+ * Vendor
+ */
+GList         *lgl_db_get_vendor_name_list           (void);
+
+void           lgl_db_free_vendor_name_list          (GList               *names);
+
+lglVendor     *lgl_db_lookup_vendor_from_name        (const gchar         *name);
+
+gboolean       lgl_db_is_vendor_name_known           (const gchar         *name);
+
+
+/*
+ * Template brands
+ */
+GList         *lgl_db_get_brand_list                 (const gchar         *paper_id,
+                                                      const gchar         *category_id);
+
+void           lgl_db_free_brand_list                (GList               *brands);
+
+
+/*
+ * Templates
+ */
+lglDbRegStatus lgl_db_register_template              (const lglTemplate   *template);
+
+lglDbDeleteStatus lgl_db_delete_template_by_name        (const gchar         *name);
+
+lglDbDeleteStatus lgl_db_delete_template_by_brand_part  (const gchar         *brand,
+                                                         const gchar         *part);
+
+gboolean       lgl_db_does_template_exist            (const gchar         *brand,
+                                                      const gchar         *part);
+
+gboolean       lgl_db_does_template_name_exist       (const gchar         *name);
+
+GList         *lgl_db_get_template_name_list_all     (const gchar         *brand,
+                                                      const gchar         *paper_id,
+                                                      const gchar         *category_id);
+
+GList         *lgl_db_get_similar_template_name_list (const gchar         *name);
+
+void           lgl_db_free_template_name_list        (GList               *names);
+
+lglTemplate   *lgl_db_lookup_template_from_name      (const gchar         *name);
+
+lglTemplate   *lgl_db_lookup_template_from_brand_part(const gchar         *brand,
+                                                      const gchar         *part);
+
+
+/*
+ * Debugging functions
+ */
+void           lgl_db_print_known_papers             (void);
+
+void           lgl_db_print_known_categories         (void);
+
+void           lgl_db_print_known_templates          (void);
+
+void           lgl_db_print_aliases                  (const lglTemplate    *template);
+
+void           lgl_db_print_known_vendors            (void);
+
+
+
+G_END_DECLS
+
+#endif /* __LGL_DB_H__ */
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-paper.c b/libglabels/lgl-paper.c
new file mode 100644 (file)
index 0000000..43cca91
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ *  lgl-paper.c
+ *  Copyright (C) 2003-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "lgl-paper.h"
+
+#include <glib/gi18n.h>
+#include <glib.h>
+#include <string.h>
+
+#include "libglabels-private.h"
+
+/*===========================================*/
+/* Private types                             */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Private globals                           */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Local function prototypes                 */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Functions.                                */
+/*===========================================*/
+
+/**
+ * lgl_paper_new:
+ * @id:       Id of paper definition. (E.g. US-Letter, A4, etc.)  Should be
+ *            unique.
+ * @name:     Localized name of paper.
+ * @width:    Width of paper in points.
+ * @height:   Height of paper in points.
+ * @pwg_size: PWG 5101.1-2002 size name.
+ *
+ * Allocates and constructs a new #lglPaper structure.
+ *
+ * Returns: a pointer to a newly allocated #lglPaper structure.
+ *
+ */
+lglPaper *
+lgl_paper_new (gchar             *id,
+              gchar             *name,
+              gdouble            width,
+              gdouble            height,
+              gchar             *pwg_size)
+{
+       lglPaper *paper;
+
+       paper           = g_new0 (lglPaper,1);
+
+       paper->id       = g_strdup (id);
+       paper->name     = g_strdup (name);
+       paper->width    = width;
+       paper->height   = height;
+       paper->pwg_size = g_strdup (pwg_size);
+
+       return paper;
+}
+
+
+/**
+ * lgl_paper_dup:
+ * @orig:  #lglPaper structure to be duplicated.
+ *
+ * Duplicates an existing #lglPaper structure.
+ *
+ * Returns: a pointer to a newly allocated #lglPaper structure.
+ *
+ */
+lglPaper *lgl_paper_dup (const lglPaper *orig)
+{
+       lglPaper       *paper;
+
+       g_return_val_if_fail (orig, NULL);
+
+       paper = g_new0 (lglPaper,1);
+
+       paper->id       = g_strdup (orig->id);
+       paper->name     = g_strdup (orig->name);
+       paper->width    = orig->width;
+       paper->height   = orig->height;
+       paper->pwg_size = g_strdup (orig->pwg_size);
+
+       return paper;
+}
+
+
+/**
+ * lgl_paper_free:
+ * @paper:  pointer to #lglPaper structure to be freed.
+ *
+ * Free all memory associated with an existing #lglPaper structure.
+ *
+ */
+void lgl_paper_free (lglPaper *paper)
+{
+
+       if ( paper != NULL ) {
+
+               g_free (paper->id);
+               paper->id = NULL;
+
+               g_free (paper->name);
+               paper->name = NULL;
+
+               g_free (paper->pwg_size);
+               paper->pwg_size = NULL;
+
+               g_free (paper);
+       }
+
+}
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-paper.h b/libglabels/lgl-paper.h
new file mode 100644 (file)
index 0000000..ecb5b8e
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ *  lgl-paper.h
+ *  Copyright (C) 2003-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LGL_PAPER_H__
+#define __LGL_PAPER_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+
+/*
+ *   lglPaper structure
+ */
+typedef struct _lglPaper lglPaper;
+
+struct _lglPaper {
+       gchar               *id;       /* Unique ID of paper definition */
+       gchar               *name;     /* Localized name of paper */
+       gdouble              width;    /* Width (in points) */
+       gdouble              height;   /* Height (in points) */
+       gchar               *pwg_size; /* PWG 5101.1-2002 size name */
+};
+
+
+/*
+ * Paper construction
+ */
+lglPaper            *lgl_paper_new                 (gchar           *id,
+                                                   gchar           *name,
+                                                   gdouble          width,
+                                                   gdouble          height,
+                                                   gchar           *pwg_size);
+
+lglPaper             *lgl_paper_dup                (const lglPaper   *orig);
+
+void                 lgl_paper_free                (lglPaper         *paper);
+
+
+G_END_DECLS
+
+#endif /* __LGL_PAPER_H__ */
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-str.c b/libglabels/lgl-str.c
new file mode 100644 (file)
index 0000000..4618fad
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+ *  lgl-str.c
+ *  Copyright (C) 2007-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "lgl-str.h"
+
+#include <string.h>
+#include <math.h>
+
+#define FRAC_EPSILON 0.00005
+
+
+/*===========================================*/
+/* Private types                             */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Private globals                           */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Local function prototypes                 */
+/*===========================================*/
+
+static gchar *span_digits (gchar **p);
+static gchar *span_non_digits (gchar **p);
+
+/*===========================================*/
+/* Functions.                                */
+/*===========================================*/
+
+/**
+ * lgl_str_utf8_casecmp:
+ * @s1: string to compare with s2.
+ * @s2: string to compare with s1.
+ *
+ * Compare two UTF-8 strings, ignoring the case of characters.
+ *
+ * This function should be used only on strings that are known to be encoded
+ * in UTF-8 or a compatible UTF-8 subset.
+ *
+ * Returns: 0 if the strings match, a negative value if s1 < s2,
+ *          or a positive value if s1 > s2.
+ *
+ */
+gint
+lgl_str_utf8_casecmp (const gchar *s1,
+                      const gchar *s2)
+{
+        gchar *folded_s1;
+        gchar *folded_s2;
+        gint   result;
+
+        folded_s1 = g_utf8_casefold (s1, -1);
+        folded_s2 = g_utf8_casefold (s2, -1);
+
+        result = g_utf8_collate (folded_s1, folded_s2);
+
+        g_free (folded_s1);
+        g_free (folded_s2);
+
+        return result;
+}
+
+
+/**
+ * lgl_str_part_name_cmp:
+ * @s1: string to compare with s2.
+ * @s2: string to compare with s1.
+ *
+ * Compare two UTF-8 strings representing part names or numbers.  This function
+ * uses a natural sort order:
+ *
+ *  - Ignores case.
+ *
+ *  - Strings are divided into chunks (numeric and non-numeric)
+ *
+ *  - Non-numeric chunks are compared character by character
+ *
+ *  - Numerical chunks are compared numerically, so that "20" precedes "100".
+ *
+ *  - Comparison of chunks is performed left to right until the first difference
+ *    is encountered or all chunks evaluate as equal.
+ *
+ * This function should be used only on strings that are known to be encoded
+ * in UTF-8 or a compatible UTF-8 subset.
+ *
+ * Numeric chunks are converted to 64 bit unsigned integers for comparison,
+ * so the behaviour may be unpredictable for numeric chunks that exceed
+ * 18446744073709551615.
+ *
+ * Returns: 0 if the strings match, a negative value if s1 < s2,
+ *          or a positive value if s1 > s2.
+ *
+ */
+gint
+lgl_str_part_name_cmp (const gchar *s1,
+                       const gchar *s2)
+{
+        gchar *folded_s1, *p1, *chunk1;
+        gchar *folded_s2, *p2, *chunk2;
+        gboolean isnum1, isnum2;
+        guint64 n1, n2;
+        gboolean done;
+        gint   result;
+
+       if ( s1 == s2 ) return 0;
+       if (s1 == NULL) return -1;
+       if (s2 == NULL) return 1;
+
+        folded_s1 = g_utf8_casefold (s1, -1);
+        folded_s2 = g_utf8_casefold (s2, -1);
+
+        result = 0;
+        done = FALSE;
+        p1 = folded_s1;
+        p2 = folded_s2;
+        while ( (result == 0) && !done )
+        {
+
+                if ( g_ascii_isdigit (*p1) )
+                {
+                        chunk1 = span_digits (&p1);
+                        isnum1 = TRUE;
+                }
+                else
+                {
+                        chunk1 = span_non_digits (&p1);
+                        isnum1 = FALSE;
+                }
+                
+                if ( g_ascii_isdigit (*p2) )
+                {
+                        chunk2 = span_digits (&p2);
+                        isnum2 = TRUE;
+                }
+                else
+                {
+                        chunk2 = span_non_digits (&p2);
+                        isnum2 = FALSE;
+                }
+
+                if ( (strlen(chunk1) == 0) && (strlen(chunk2) == 0) )
+                {
+                        /* Case 1: Both are empty. */
+                        done = TRUE;
+                }
+                else if ( isnum1 && isnum2 )
+                {
+                        /* Case 2: They both contain numbers */
+                        n1 = g_ascii_strtoull (chunk1, NULL, 10);
+                        n2 = g_ascii_strtoull (chunk2, NULL, 10);
+
+                        if ( n1 < n2 ) result = -1;
+                        if ( n1 > n2 ) result =  1;
+                }
+                else
+                {
+                        /* Case 3: One or both do not contain numbers */
+                        result = g_utf8_collate (chunk1, chunk2);
+                }
+
+                g_free (chunk1);
+                g_free (chunk2);
+        }
+
+        g_free (folded_s1);
+        g_free (folded_s2);
+
+        return result;
+}
+
+
+static gchar *
+span_digits (gchar **p)
+{
+        gchar *chunk = g_new0 (gchar, strlen (*p) + 1);
+        gint i;
+
+        for ( i = 0; **p && g_ascii_isdigit (**p); i++, *p = g_utf8_next_char(*p) )
+        {
+                chunk[i] = **p;
+        }
+
+        return chunk;
+}
+
+
+static gchar *
+span_non_digits (gchar **p)
+{
+        gchar *chunk = g_new0 (gchar, strlen (*p) + 1);
+        gint i;
+
+        for ( i = 0; **p && !g_ascii_isdigit (**p); i++, *p = g_utf8_next_char(*p) )
+        {
+                chunk[i] = **p;
+        }
+
+        return chunk;
+}
+
+
+/**
+ * lgl_str_format_fraction:
+ * @x: Floating point number to convert to fractional notation
+ *
+ * Create fractional representation of number, if possible.  Uses UTF-8 superscripts and
+ * subscripts for numerator and denominator values respecively.
+ *
+ * Returns: UTF-8 string containing fractional representation of x.
+ */
+gchar *
+lgl_str_format_fraction (gdouble x)
+{
+       static gdouble denom[]        = {  1.,  2., 3.,  4.,  8.,  16.,  32.,  0. };
+        static gchar  *denom_string[] = { "1", "₂", "₃", "₄", "₈", "₁₆", "₃₂", NULL };
+        static gchar  *num_string[]   = {  "⁰",  "¹",  "²",  "³",  "⁴",  "⁵",  "⁶",  "⁷",  "⁸",  "⁹",
+                                          "¹⁰", "¹¹", "¹²", "¹³", "¹⁴", "¹⁵", "¹⁶", "¹⁷", "¹⁸", "¹⁹",
+                                          "²⁰", "²¹", "²²", "²³", "²⁴", "²⁵", "²⁶", "²⁷", "²⁸", "²⁹",
+                                          "³⁰", "³¹" };
+       gint i;
+       gdouble product, remainder;
+       gint n, d;
+
+       for ( i=0; denom[i] != 0.0; i++ ) {
+               product = x * denom[i];
+               remainder = fabs(product - ((gint)(product+0.5)));
+               if ( remainder < FRAC_EPSILON ) break;
+       }
+
+       if ( denom[i] == 0.0 ) {
+               /* None of our denominators work. */
+               return g_strdup_printf ("%.5g", x);
+       }
+       if ( denom[i] == 1.0 ) {
+               /* Simple integer. */
+               return g_strdup_printf ("%.0f", x);
+       }
+       n = (gint)( x * denom[i] + 0.5 );
+       d = (gint)denom[i];
+       if ( n > d ) {
+               return g_strdup_printf ("%d%s/%s", (n/d), num_string[n%d], denom_string[i]);
+       } else {
+               return g_strdup_printf ("%s/%s", num_string[n%d], denom_string[i]);
+       }
+}
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-str.h b/libglabels/lgl-str.h
new file mode 100644 (file)
index 0000000..3c096b0
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ *  lgl-str.h
+ *  Copyright (C) 2007-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LGL_STR_H__
+#define __LGL_STR_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+gint   lgl_str_utf8_casecmp    (const gchar *s1,
+                                const gchar *s2);
+
+gint   lgl_str_part_name_cmp   (const gchar *s1,
+                                const gchar *s2);
+
+gchar *lgl_str_format_fraction (gdouble      x);
+
+G_END_DECLS
+
+
+#endif /* __LGL_STR_H__ */
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-template.c b/libglabels/lgl-template.c
new file mode 100644 (file)
index 0000000..11763dc
--- /dev/null
@@ -0,0 +1,1397 @@
+/*
+ *  lgl-template.c
+ *  Copyright (C) 2001-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "lgl-template.h"
+
+#include <glib/gi18n.h>
+#include <glib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <math.h>
+
+#include "libglabels-private.h"
+
+#include "lgl-db.h"
+#include "lgl-paper.h"
+
+/*===========================================*/
+/* Private macros and constants.             */
+/*===========================================*/
+
+/* Allowed error when comparing dimensions. (0.5pts ~= .007in ~= .2mm) */
+#define EPSILON 0.5
+
+/*===========================================*/
+/* Private types                             */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Private globals                           */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Local function prototypes                 */
+/*===========================================*/
+
+static gint         compare_origins              (gconstpointer           a,
+                                                  gconstpointer           b,
+                                                  gpointer                user_data);
+
+/*===========================================*/
+/* Functions.                                */
+/*===========================================*/
+
+/**
+ * lgl_template_new:
+ *   @brand:        Template brand
+ *   @part:         Template part name/number
+ *   @description:  Template descriptions
+ *   @paper_id:     Page size id
+ *   @page_width:   Page width in points, set to zero unless paper_id="Other"
+ *   @page_height:  Page height in points, set to zero unless paper_id="Other"
+ *
+ * Create a new template structure, with the given top-level attributes.  The
+ * created template will have no initial categories, or frames associated with
+ * it.  See lgl_template_add_category() and lgl_template_add_frame() to add
+ * these.
+ *
+ * Returns: pointer to a newly allocated #lglTemplate structure.
+ *
+ */
+lglTemplate *
+lgl_template_new (const gchar         *brand,
+                  const gchar         *part,
+                  const gchar         *description,
+                  const gchar         *paper_id,
+                  gdouble              page_width,
+                  gdouble              page_height)
+{
+       lglTemplate      *template;
+
+       template = g_new0 (lglTemplate,1);
+
+       template->brand       = g_strdup (brand);
+       template->part        = g_strdup (part);
+       template->description = g_strdup (description);
+       template->paper_id    = g_strdup (paper_id);
+       template->page_width  = page_width;
+       template->page_height = page_height;
+
+       return template;
+}
+
+
+/**
+ * lgl_template_new_from_equiv:
+ *   @brand:        Template brand
+ *   @part:         Template part name/number
+ *   @equiv_part:   Name of equivalent part to base template on
+ *
+ * Create a new template structure based on an existing template.  The
+ * created template will be a duplicate of the original template, except with
+ * the new part name/number.
+ *
+ * Returns: pointer to a newly allocated #lglTemplate structure.
+ *
+ */
+lglTemplate *
+lgl_template_new_from_equiv (const gchar          *brand,
+                             const gchar          *part,
+                             const gchar          *equiv_part)
+{
+        lglTemplate      *template = NULL;
+
+        if ( lgl_db_does_template_exist (brand, equiv_part) )
+        {
+                template = lgl_db_lookup_template_from_brand_part (brand, equiv_part);
+
+                g_free (template->part);
+                g_free (template->equiv_part);
+
+                template->part       = g_strdup (part);
+                template->equiv_part = g_strdup (equiv_part);
+        }
+        else
+        {
+                g_message ("Equivalent part (\"%s\") for \"%s\", not previously defined.",
+                           equiv_part, part);
+        }
+
+        return template;
+}
+
+
+/**
+ * lgl_template_get_name:
+ *   @template:  Pointer to template structure to test
+ *
+ * This function returns the name of the given template.  The name is the concetenation
+ * of the brand and part name/number.
+ *
+ * Returns:  A pointer to a newly allocated name string.  Should be freed with g_free().
+ *
+ */
+gchar *
+lgl_template_get_name (const lglTemplate  *template)
+{
+       g_return_val_if_fail (template, NULL);
+
+        return g_strdup_printf ("%s %s", template->brand, template->part);
+}
+
+
+/**
+ * lgl_template_do_templates_match:
+ *   @template1:  Pointer to 1st template structure to test
+ *   @template2:  Pointer to 2nd template structure to test
+ *
+ * This function tests if the given templates match.  This is a simple test that only tests
+ * the brand and part name/number. It does not test if they are actually identical.
+ *
+ * Returns:  TRUE if the two templates match.
+ *
+ */
+gboolean
+lgl_template_do_templates_match (const lglTemplate  *template1,
+                                 const lglTemplate  *template2)
+{
+       g_return_val_if_fail (template1, FALSE);
+       g_return_val_if_fail (template2, FALSE);
+
+        return (UTF8_EQUAL (template1->brand, template2->brand) &&
+                UTF8_EQUAL (template1->part, template2->part));
+}
+
+
+/**
+ * lgl_template_does_brand_match:
+ *   @template:  Pointer to template structure to test
+ *   @brand:     Brand string
+ *
+ * This function tests if the brand of the template matches the given brand.
+ *
+ * Returns:  TRUE if the template matches the given brand.
+ *
+ */
+gboolean
+lgl_template_does_brand_match (const lglTemplate  *template,
+                               const gchar        *brand)
+{
+       g_return_val_if_fail (template, FALSE);
+
+        /* NULL matches everything. */
+        if (brand == NULL)
+        {
+                return TRUE;
+        }
+
+        return UTF8_EQUAL (template->brand, brand);
+}
+
+
+/**
+ * lgl_template_does_page_size_match:
+ *   @template:  Pointer to template structure to test
+ *   @paper_id:  Page size ID string
+ *
+ * This function tests if the page size of the template matches the given ID.
+ *
+ * Returns:  TRUE if the template matches the given page size ID.
+ *
+ */
+gboolean
+lgl_template_does_page_size_match (const lglTemplate  *template,
+                                   const gchar        *paper_id)
+{
+       g_return_val_if_fail (template, FALSE);
+
+        /* NULL matches everything. */
+        if (paper_id == NULL)
+        {
+                return TRUE;
+        }
+
+        return ASCII_EQUAL(paper_id, template->paper_id);
+}
+
+
+/**
+ * lgl_template_does_category_match:
+ *   @template:     Pointer to template structure to test
+ *   @category_id:  Category ID string
+ *
+ * This function tests if the given template belongs to the given category ID.
+ *
+ * Returns:  TRUE if the template matches the given category ID.
+ *
+ */
+gboolean
+lgl_template_does_category_match  (const lglTemplate  *template,
+                                   const gchar        *category_id)
+{
+        GList *p;
+
+       g_return_val_if_fail (template, FALSE);
+
+        /* NULL matches everything. */
+        if (category_id == NULL)
+        {
+                return TRUE;
+        }
+
+        for ( p=template->category_ids; p != NULL; p=p->next )
+        {
+                if (ASCII_EQUAL(category_id, p->data))
+                {
+                        return TRUE;
+                }
+        }
+
+        return FALSE;
+}
+
+
+/**
+ * lgl_template_are_templates_identical:
+ *   @template1:  Pointer to 1st template structure to test
+ *   @template2:  Pointer to 2nd template structure to test
+ *
+ * This function tests if the given templates have identical size and layout properties.
+ *
+ * Returns:  TRUE if the two templates are identical.
+ *
+ */
+gboolean
+lgl_template_are_templates_identical (const lglTemplate   *template1,
+                                      const lglTemplate   *template2)
+{
+        lglTemplateFrame  *frame1;
+        lglTemplateFrame  *frame2;
+        GList             *p1;
+        GList             *p2;
+        lglTemplateLayout *layout1;
+        lglTemplateLayout *layout2;
+        gboolean           match_found;
+
+
+        if (!UTF8_EQUAL (template1->paper_id, template2->paper_id) ||
+            (template1->page_width  != template2->page_width)      ||
+            (template1->page_height != template2->page_height))
+        {
+                return FALSE;
+        }
+
+        frame1 = (lglTemplateFrame *)template1->frames->data;
+        frame2 = (lglTemplateFrame *)template2->frames->data;
+
+        if ( frame1->shape != frame2->shape )
+        {
+                return FALSE;
+        }
+
+        switch ( frame1->shape )
+        {
+
+        case LGL_TEMPLATE_FRAME_SHAPE_RECT:
+                if ( (fabs(frame1->rect.w - frame2->rect.w) > EPSILON) ||
+                     (fabs(frame1->rect.h - frame2->rect.h) > EPSILON) )
+                {
+                        return FALSE;
+                }
+                break;
+
+        case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
+                if ( (fabs(frame1->ellipse.w - frame2->ellipse.w) > EPSILON) ||
+                     (fabs(frame1->ellipse.h - frame2->ellipse.h) > EPSILON) )
+                {
+                        return FALSE;
+                }
+                break;
+
+        case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
+                if ( fabs(frame1->round.r - frame2->round.r) > EPSILON )
+                {
+                        return FALSE;
+                }
+                break;
+
+        case LGL_TEMPLATE_FRAME_SHAPE_CD:
+                if ( (fabs(frame1->cd.r1 - frame2->cd.r1) > EPSILON) ||
+                     (fabs(frame1->cd.r2 - frame2->cd.r2) > EPSILON) )
+                {
+                        return FALSE;
+                }
+        }
+
+        for ( p1 = frame1->all.layouts; p1; p1 = p1->next )
+        {
+                layout1 = (lglTemplateLayout *)p1->data;
+
+                match_found = FALSE;
+                for ( p2 = frame2->all.layouts; p2 && !match_found; p2 = p2->next )
+                {
+                        layout2 = (lglTemplateLayout *)p2->data;
+
+                        if ( (layout1->nx == layout2->nx) &&
+                             (layout1->ny == layout2->ny) &&
+                             (fabs(layout1->x0 - layout2->x0) < EPSILON) &&
+                             (fabs(layout1->y0 - layout2->y0) < EPSILON) &&
+                             (fabs(layout1->dx - layout2->dx) < EPSILON) &&
+                             (fabs(layout1->dy - layout2->dy) < EPSILON) )
+                        {
+                                match_found = TRUE;
+                        }
+
+                }
+                if ( !match_found )
+                {
+                        return FALSE;
+                }
+        }
+
+        return TRUE;
+}
+
+
+/**
+ * lgl_template_add_frame:
+ *   @template:  Pointer to template structure
+ *   @frame:     Pointer to frame structure
+ *
+ * This function adds the given frame structure to the template.  Once added,
+ * the frame structure belongs to the given template; do not attempt to free
+ * it.
+ *
+ * Note: Currently glabels only supports a single frame per template.
+ *
+ */
+void
+lgl_template_add_frame (lglTemplate      *template,
+                        lglTemplateFrame *frame)
+{
+       g_return_if_fail (template);
+       g_return_if_fail (frame);
+
+       template->frames = g_list_append (template->frames, frame);
+}
+
+/**
+ * lgl_template_add_category:
+ *   @template:     Pointer to template structure
+ *   @category_id:  Category ID string
+ *
+ * This function adds the given category ID to a templates category list.
+ *
+ */
+void
+lgl_template_add_category (lglTemplate         *template,
+                           const gchar         *category_id)
+{
+       g_return_if_fail (template);
+       g_return_if_fail (category_id);
+
+       template->category_ids = g_list_append (template->category_ids,
+                                                g_strdup (category_id));
+}
+
+/**
+ * lgl_template_frame_rect_new:
+ *   @id:      ID of frame.  (This should currently always be "0").
+ *   @w:       width of frame in points.
+ *   @h:       height of frame in points.
+ *   @r:       radius of rounded corners in points.  (Should be 0 for square corners.)
+ *   @x_waste: Amount of overprint to allow in the horizontal direction.
+ *   @y_waste: Amount of overprint to allow in the vertical direction.
+ *
+ * This function creates a new template frame for a rectangular label or card.
+ *
+ * Returns: Pointer to newly allocated #lglTemplateFrame structure.
+ *
+ */
+lglTemplateFrame *
+lgl_template_frame_rect_new  (const gchar         *id,
+                              gdouble              w,
+                              gdouble              h,
+                              gdouble              r,
+                              gdouble              x_waste,
+                              gdouble              y_waste)
+{
+       lglTemplateFrame *frame;
+
+       frame = g_new0 (lglTemplateFrame, 1);
+
+       frame->shape = LGL_TEMPLATE_FRAME_SHAPE_RECT;
+       frame->rect.id = g_strdup (id);
+
+       frame->rect.w = w;
+       frame->rect.h = h;
+       frame->rect.r = r;
+       frame->rect.x_waste = x_waste;
+       frame->rect.y_waste = y_waste;
+
+       return frame;
+}
+
+
+/**
+ * lgl_template_frame_ellipse_new:
+ *   @id:      ID of frame.  (This should currently always be "0").
+ *   @w:       width of frame in points.
+ *   @h:       height of frame in points.
+ *   @waste:   Amount of overprint to allow in points.
+ *
+ * This function creates a new template frame for an elliptical label or card.
+ *
+ * Returns: Pointer to newly allocated #lglTemplateFrame structure.
+ *
+ */
+lglTemplateFrame *
+lgl_template_frame_ellipse_new  (const gchar         *id,
+                                 gdouble              w,
+                                 gdouble              h,
+                                 gdouble              waste)
+{
+       lglTemplateFrame *frame;
+
+       frame = g_new0 (lglTemplateFrame, 1);
+
+       frame->shape = LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE;
+       frame->ellipse.id = g_strdup (id);
+
+       frame->ellipse.w = w;
+       frame->ellipse.h = h;
+       frame->ellipse.waste = waste;
+
+       return frame;
+}
+
+
+/**
+ * lgl_template_frame_round_new:
+ *   @id:      ID of frame.  (This should currently always be "0").
+ *   @r:       radius of label in points.
+ *   @waste:   Amount of overprint to allow.
+ *
+ * This function creates a new template frame for a round label.
+ *
+ * Returns: Pointer to newly allocated #lglTemplateFrame structure.
+ *
+ */
+lglTemplateFrame *
+lgl_template_frame_round_new (const gchar         *id,
+                              gdouble              r,
+                              gdouble              waste)
+{
+       lglTemplateFrame *frame;
+
+       frame = g_new0 (lglTemplateFrame, 1);
+
+       frame->shape = LGL_TEMPLATE_FRAME_SHAPE_ROUND;
+       frame->round.id = g_strdup (id);
+
+       frame->round.r = r;
+       frame->round.waste = waste;
+
+       return frame;
+}
+
+                                                                               
+/**
+ * lgl_template_frame_cd_new:
+ *   @id:      ID of frame.  (This should currently always be "0").
+ *   @r1:      outer radius of label in points.
+ *   @r2:      radius of center hole in points.
+ *   @w:       clip width of frame in points for business card CDs.  Should be 0 for no clipping.
+ *   @h:       clip height of frame in points for business card CDs.  Should be 0 for no clipping.
+ *   @waste:   Amount of overprint to allow.
+ *
+ * This function creates a new template frame for a CD/DVD label.
+ *
+ * Returns: Pointer to newly allocated #lglTemplateFrame structure.
+ *
+ */
+lglTemplateFrame *
+lgl_template_frame_cd_new (const gchar         *id,
+                           gdouble              r1,
+                           gdouble              r2,
+                           gdouble              w,
+                           gdouble              h,
+                           gdouble              waste)
+{
+       lglTemplateFrame *frame;
+
+       frame = g_new0 (lglTemplateFrame, 1);
+
+       frame->shape = LGL_TEMPLATE_FRAME_SHAPE_CD;
+       frame->cd.id = g_strdup (id);
+
+       frame->cd.r1 = r1;
+       frame->cd.r2 = r2;
+       frame->cd.w  = w;
+       frame->cd.h  = h;
+       frame->cd.waste = waste;
+
+       return frame;
+}
+
+
+/**
+ * lgl_template_frame_get_size:
+ * @frame: #lglTemplateFrame structure to query
+ * @w: pointer to location to receive width of frame
+ * @h: pointer to location to receive height of frame
+ *
+ * Get size (width and height) of given #lglTemplateFrame in points.
+ *
+ */
+void
+lgl_template_frame_get_size (const lglTemplateFrame *frame,
+                             gdouble                *w,
+                             gdouble                *h)
+{
+       g_return_if_fail (frame);
+
+       switch (frame->shape) {
+       case LGL_TEMPLATE_FRAME_SHAPE_RECT:
+               *w = frame->rect.w;
+               *h = frame->rect.h;
+               break;
+       case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
+               *w = frame->ellipse.w;
+               *h = frame->ellipse.h;
+               break;
+       case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
+               *w = 2.0 * frame->round.r;
+               *h = 2.0 * frame->round.r;
+               break;
+       case LGL_TEMPLATE_FRAME_SHAPE_CD:
+               if (frame->cd.w == 0.0) {
+                       *w = 2.0 * frame->cd.r1;
+               } else {
+                       *w = frame->cd.w;
+               }
+               if (frame->cd.h == 0.0) {
+                       *h = 2.0 * frame->cd.r1;
+               } else {
+                       *h = frame->cd.h;
+               }
+               break;
+       default:
+               *w = 0.0;
+               *h = 0.0;
+               break;
+       }
+}
+
+
+/**
+ * lgl_template_frame_get_n_labels:
+ * @frame: #lglTemplateFrame structure to query
+ *
+ * Get total number of labels per sheet corresponding to the given frame.
+ *
+ * Returns: number of labels per sheet.
+ *
+ */
+gint
+lgl_template_frame_get_n_labels (const lglTemplateFrame *frame)
+{
+       gint               n_labels = 0;
+       GList             *p;
+       lglTemplateLayout *layout;
+
+       g_return_val_if_fail (frame, 0);
+
+       for ( p=frame->all.layouts; p != NULL; p=p->next ) {
+               layout = (lglTemplateLayout *)p->data;
+
+               n_labels += layout->nx * layout->ny;
+       }
+
+       return n_labels;
+}
+
+
+/**
+ * lgl_template_frame_get_layout_description
+ * @frame: #lglTemplateFrame structure to query
+ *
+ * Get a description of the label layout including number of labels per sheet.
+ *
+ * Returns: a newly allocation description string.
+ *
+ */
+gchar *
+lgl_template_frame_get_layout_description (const lglTemplateFrame *frame)
+{
+        gint                    n_labels;
+        gchar                  *string;
+        lglTemplateLayout      *layout;
+
+        n_labels = lgl_template_frame_get_n_labels (frame);
+
+        if ( frame->all.layouts && (frame->all.layouts->next == NULL) )
+        {
+                layout = (lglTemplateLayout *)frame->all.layouts->data;
+                /*
+                 * Translators: 1st %d = number of labels across a page,
+                 *              2nd %d = number of labels down a page,
+                 *              3rd %d = total number of labels on a page (sheet).
+                 */
+                string = g_strdup_printf (_("%d × %d (%d per sheet)"), layout->nx, layout->ny, n_labels);
+        }
+        else
+        {
+                /* Translators: %d is the total number of labels on a page (sheet). */
+                string = g_strdup_printf (_("%d per sheet"), n_labels);
+        }
+
+        return string;
+}
+
+
+/**
+ * lgl_template_frame_get_size_description
+ * @frame: #lglTemplateFrame structure to query
+ * @units: #lglUnits
+ *
+ * Get a description of the label size.
+ *
+ * Returns: a newly allocation description string.
+ *
+ */
+gchar *
+lgl_template_frame_get_size_description (const lglTemplateFrame *frame,
+                                         lglUnits                units)
+{
+        const gchar               *units_string;
+        gdouble                    units_per_point;
+        gchar                     *string = NULL;
+
+        units_string    = lgl_units_get_name (units);
+        units_per_point = lgl_units_get_units_per_point (units);
+
+        switch (frame->shape) {
+        case LGL_TEMPLATE_FRAME_SHAPE_RECT:
+                if ( units == LGL_UNITS_INCH ) {
+                        gchar *xstr, *ystr;
+
+                        xstr = lgl_str_format_fraction (frame->rect.w*units_per_point);
+                        ystr = lgl_str_format_fraction (frame->rect.h*units_per_point);
+                        string = g_strdup_printf ("%s × %s %s",
+                                                  xstr, ystr, units_string);
+                        g_free (xstr);
+                        g_free (ystr);
+                } else {
+                        string = g_strdup_printf ("%.5g × %.5g %s",
+                                                  frame->rect.w*units_per_point,
+                                                  frame->rect.h*units_per_point,
+                                                  units_string);
+                }
+                break;
+        case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
+                if ( units == LGL_UNITS_INCH ) {
+                        gchar *xstr, *ystr;
+
+                        xstr = lgl_str_format_fraction (frame->ellipse.w*units_per_point);
+                        ystr = lgl_str_format_fraction (frame->ellipse.h*units_per_point);
+                        string = g_strdup_printf ("%s × %s %s",
+                                                  xstr, ystr, units_string);
+                        g_free (xstr);
+                        g_free (ystr);
+                } else {
+                        string = g_strdup_printf ("%.5g × %.5g %s",
+                                                  frame->ellipse.w*units_per_point,
+                                                  frame->ellipse.h*units_per_point,
+                                                  units_string);
+                }
+                break;
+        case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
+                if ( units == LGL_UNITS_INCH ) {
+                        gchar *dstr;
+
+                        dstr = lgl_str_format_fraction (2.0*frame->round.r*units_per_point);
+                        string = g_strdup_printf ("%s %s %s",
+                                                  dstr, units_string,
+                                                  _("diameter"));
+                        g_free (dstr);
+                } else {
+                        string = g_strdup_printf ("%.5g %s %s",
+                                                  2.0*frame->round.r*units_per_point,
+                                                  units_string,
+                                                  _("diameter"));
+                }
+                break;
+        case LGL_TEMPLATE_FRAME_SHAPE_CD:
+                if ( units == LGL_UNITS_INCH ) {
+                        gchar *dstr;
+
+                        dstr = lgl_str_format_fraction (2.0*frame->cd.r1*units_per_point);
+                        string = g_strdup_printf ("%s %s %s",
+                                                  dstr, units_string,
+                                                  _("diameter"));
+                        g_free (dstr);
+                } else {
+                        string = g_strdup_printf ("%.5g %s %s",
+                                                  2.0*frame->cd.r1*units_per_point,
+                                                  units_string,
+                                                  _("diameter"));
+                }
+                break;
+        default:
+                break;
+        }
+
+        return string;
+}
+
+
+/**
+ * lgl_template_frame_get_origins:
+ * @frame: #lglTemplateFrame structure to query
+ *
+ * Get an array of label origins for the given frame.  These origins represent the
+ * upper left hand corner of each label on a page corresponding to the given frame.
+ * The origins will be ordered geometrically left to right and then top to bottom.
+ * The array should be freed using g_free().
+ *
+ * Returns: A newly allocated array of #lglTemplateOrigin structures.
+ *
+ */
+lglTemplateOrigin *
+lgl_template_frame_get_origins (const lglTemplateFrame *frame)
+{
+       gint               i_label, n_labels, ix, iy;
+       lglTemplateOrigin *origins;
+       GList             *p;
+       lglTemplateLayout *layout;
+
+       g_return_val_if_fail (frame, NULL);
+
+       n_labels = lgl_template_frame_get_n_labels (frame);
+       origins = g_new0 (lglTemplateOrigin, n_labels);
+
+       i_label = 0;
+       for ( p=frame->all.layouts; p != NULL; p=p->next ) {
+               layout = (lglTemplateLayout *)p->data;
+
+               for (iy = 0; iy < layout->ny; iy++) {
+                       for (ix = 0; ix < layout->nx; ix++, i_label++) {
+                               origins[i_label].x = ix*layout->dx + layout->x0;
+                               origins[i_label].y = iy*layout->dy + layout->y0;
+                       }
+               }
+       }
+
+       g_qsort_with_data (origins, n_labels, sizeof(lglTemplateOrigin),
+                          compare_origins, NULL);
+
+       return origins;
+}
+
+
+/**
+ * lgl_template_frame_add_layout:
+ *   @frame:  Pointer to template frame to add layout to.
+ *   @layout: Pointer to layout structure to add to frame.
+ *
+ * This function adds a layout structure to the given template frame.
+ *
+ */
+void
+lgl_template_frame_add_layout (lglTemplateFrame   *frame,
+                               lglTemplateLayout  *layout)
+{
+       g_return_if_fail (frame);
+       g_return_if_fail (layout);
+
+       frame->all.layouts = g_list_append (frame->all.layouts, layout);
+}
+
+/**
+ * lgl_template_frame_add_markup:
+ *   @frame:  Pointer to template frame to add markup to.
+ *   @markup: Pointer to markup structure to add to frame.
+ *
+ * This function adds a markup structure to the given template frame.
+ *
+ */
+void
+lgl_template_frame_add_markup (lglTemplateFrame   *frame,
+                               lglTemplateMarkup  *markup)
+{
+       g_return_if_fail (frame);
+       g_return_if_fail (markup);
+
+       frame->all.markups = g_list_append (frame->all.markups, markup);
+}
+
+/**
+ * lgl_template_layout_new:
+ *   @nx:  Number of labels across.
+ *   @ny:  Number of labels down.
+ *   @x0:  X coordinate of the top-left corner of the top-left label in the layout in points.
+ *   @y0:  Y coordinate of the top-left corner of the top-left label in the layout in points.
+ *   @dx:  Horizontal pitch in points.  This is the distance from left-edge to left-edge.
+ *   @dy:  Vertical pitch in points.  This is the distance from top-edge to top-edge.
+ *
+ * This function creates a new layout structure with the given parameters.
+ *
+ * Returns: a newly allocated #lglTemplateLayout structure.
+ *
+ */
+lglTemplateLayout *
+lgl_template_layout_new (gint    nx,
+                         gint    ny,
+                         gdouble x0,
+                         gdouble y0,
+                         gdouble dx,
+                         gdouble dy)
+{
+       lglTemplateLayout *layout;
+
+       layout = g_new0 (lglTemplateLayout, 1);
+
+       layout->nx = nx;
+       layout->ny = ny;
+       layout->x0 = x0;
+       layout->y0 = y0;
+       layout->dx = dx;
+       layout->dy = dy;
+
+       return layout;
+}
+
+
+/**
+ * lgl_template_markup_margin_new:
+ *   @size: margin size in points.
+ *
+ * This function creates a new margin markup structure.
+ *
+ * Returns: a newly allocated #lglTemplateMarkup structure.
+ *
+ */
+lglTemplateMarkup *
+lgl_template_markup_margin_new (gdouble size)
+{
+       lglTemplateMarkup *markup;
+
+       markup = g_new0 (lglTemplateMarkup, 1);
+
+       markup->type        = LGL_TEMPLATE_MARKUP_MARGIN;
+       markup->margin.size = size;
+
+       return markup;
+}
+
+
+/**
+ * lgl_template_markup_line_new:
+ *   @x1: x coordinate of first endpoint.
+ *   @y1: y coordinate of first endpoint.
+ *   @x2: x coordinate of second endpoint.
+ *   @y2: y coordinate of second endpoint.
+ *
+ * This function creates a new line markup structure.
+ *
+ * Returns: a newly allocated #lglTemplateMarkup structure.
+ *
+ */
+lglTemplateMarkup *
+lgl_template_markup_line_new (gdouble x1,
+                              gdouble y1,
+                              gdouble x2,
+                              gdouble y2)
+{
+       lglTemplateMarkup *markup;
+
+       markup = g_new0 (lglTemplateMarkup, 1);
+
+       markup->type        = LGL_TEMPLATE_MARKUP_LINE;
+       markup->line.x1     = x1;
+       markup->line.y1     = y1;
+       markup->line.x2     = x2;
+       markup->line.y2     = y2;
+
+       return markup;
+}
+
+
+/**
+ * lgl_template_markup_circle_new:
+ *   @x0: x coordinate of center of circle.
+ *   @y0: y coordinate of center of circle.
+ *   @r:  radius of circle.
+ *
+ * This function creates a new circle markup structure.
+ *
+ * Returns: a newly allocated #lglTemplateMarkup structure.
+ *
+ */
+lglTemplateMarkup *
+lgl_template_markup_circle_new (gdouble x0,
+                                gdouble y0,
+                                gdouble r)
+{
+       lglTemplateMarkup *markup;
+
+       markup = g_new0 (lglTemplateMarkup, 1);
+
+       markup->type        = LGL_TEMPLATE_MARKUP_CIRCLE;
+       markup->circle.x0   = x0;
+       markup->circle.y0   = y0;
+       markup->circle.r    = r;
+
+       return markup;
+}
+
+
+/**
+ * lgl_template_markup_rect_new:
+ *   @x1: x coordinate of top-left corner of rectangle.
+ *   @y1: y coordinate of top-left corner of rectangle.
+ *   @w:  width of rectangle.
+ *   @h:  height of rectangle.
+ *   @r:  radius of rounded corner.
+ *
+ * This function creates a new rectangle markup structure.
+ *
+ * Returns: a newly allocated #lglTemplateMarkup structure.
+ *
+ */
+lglTemplateMarkup *
+lgl_template_markup_rect_new (gdouble x1,
+                              gdouble y1,
+                              gdouble w,
+                              gdouble h,
+                              gdouble r)
+{
+       lglTemplateMarkup *markup;
+
+       markup = g_new0 (lglTemplateMarkup, 1);
+
+       markup->type        = LGL_TEMPLATE_MARKUP_RECT;
+       markup->rect.x1     = x1;
+       markup->rect.y1     = y1;
+       markup->rect.w      = w;
+       markup->rect.h      = h;
+       markup->rect.r      = r;
+
+       return markup;
+}
+
+
+/**
+ * lgl_template_markup_ellipse_new:
+ *   @x1: x coordinate of top-left corner of ellipse.
+ *   @y1: y coordinate of top-left corner of ellipse.
+ *   @w:  width of ellipse.
+ *   @h:  height of ellipse.
+ *
+ * This function creates a new ellipse markup structure.
+ *
+ * Returns: a newly allocated #lglTemplateMarkup structure.
+ *
+ */
+lglTemplateMarkup *
+lgl_template_markup_ellipse_new (gdouble x1,
+                                 gdouble y1,
+                                 gdouble w,
+                                 gdouble h)
+{
+       lglTemplateMarkup *markup;
+
+       markup = g_new0 (lglTemplateMarkup, 1);
+
+       markup->type        = LGL_TEMPLATE_MARKUP_ELLIPSE;
+       markup->ellipse.x1     = x1;
+       markup->ellipse.y1     = y1;
+       markup->ellipse.w      = w;
+       markup->ellipse.h      = h;
+
+       return markup;
+}
+
+
+/**
+ * lgl_template_dup:
+ *   @orig_template: Template to duplicate.
+ *
+ * This function duplicates a template structure.
+ *
+ * Returns:  a newly allocated #lglTemplate structure.
+ *
+ */
+lglTemplate *
+lgl_template_dup (const lglTemplate *orig_template)
+{
+       lglTemplate         *template;
+       GList               *p;
+       lglTemplateFrame    *frame;
+
+       g_return_val_if_fail (orig_template, NULL);
+
+       template = lgl_template_new (orig_template->brand,
+                                     orig_template->part,
+                                     orig_template->description,
+                                     orig_template->paper_id,
+                                     orig_template->page_width,
+                                     orig_template->page_height);
+
+        template->equiv_part  = g_strdup (orig_template->equiv_part);
+        template->product_url = g_strdup (orig_template->product_url);
+
+
+       for ( p=orig_template->category_ids; p != NULL; p=p->next )
+        {
+                lgl_template_add_category (template, p->data);
+       }
+
+       for ( p=orig_template->frames; p != NULL; p=p->next )
+        {
+               frame = (lglTemplateFrame *)p->data;
+
+               lgl_template_add_frame (template, lgl_template_frame_dup (frame));
+       }
+
+       return template;
+}
+
+
+/**
+ * lgl_template_free:
+ *   @template: Template to free.
+ *
+ * This function frees all memory associated with given template structure.
+ *
+ */
+void
+lgl_template_free (lglTemplate *template)
+{
+       GList            *p;
+       lglTemplateFrame *frame;
+
+       if ( template != NULL ) {
+
+               g_free (template->brand);
+               template->brand = NULL;
+
+               g_free (template->part);
+               template->part = NULL;
+
+               g_free (template->description);
+               template->description = NULL;
+
+               g_free (template->paper_id);
+               template->paper_id = NULL;
+
+               for ( p=template->category_ids; p != NULL; p=p->next ) {
+
+                       g_free (p->data);
+                       p->data = NULL;
+
+               }
+               g_list_free (template->category_ids);
+               template->category_ids = NULL;
+
+               for ( p=template->frames; p != NULL; p=p->next ) {
+
+                       frame = (lglTemplateFrame *)p->data;
+
+                       lgl_template_frame_free (frame);
+                       p->data = NULL;
+               }
+               g_list_free (template->frames);
+               template->frames = NULL;
+
+               g_free (template);
+
+       }
+
+}
+
+
+/**
+ * lgl_template_frame_dup:
+ *   @orig_frame: Frame to duplicate.
+ *
+ * This function duplicates a template frame structure.
+ *
+ * Returns:  a newly allocated #lglTemplateFrame structure.
+ *
+ */
+lglTemplateFrame *
+lgl_template_frame_dup (const lglTemplateFrame *orig_frame)
+{
+       lglTemplateFrame    *frame;
+       GList               *p;
+       lglTemplateLayout   *layout;
+       lglTemplateMarkup   *markup;
+
+       g_return_val_if_fail (orig_frame, NULL);
+
+       switch (orig_frame->shape) {
+
+       case LGL_TEMPLATE_FRAME_SHAPE_RECT:
+               frame =
+                       lgl_template_frame_rect_new (orig_frame->all.id,
+                                                     orig_frame->rect.w,
+                                                     orig_frame->rect.h,
+                                                     orig_frame->rect.r,
+                                                     orig_frame->rect.x_waste,
+                                                     orig_frame->rect.y_waste);
+               break;
+
+       case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
+               frame =
+                       lgl_template_frame_ellipse_new (orig_frame->all.id,
+                                                        orig_frame->ellipse.w,
+                                                        orig_frame->ellipse.h,
+                                                        orig_frame->ellipse.waste);
+               break;
+
+       case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
+               frame =
+                       lgl_template_frame_round_new (orig_frame->all.id,
+                                                      orig_frame->round.r,
+                                                      orig_frame->round.waste);
+               break;
+
+       case LGL_TEMPLATE_FRAME_SHAPE_CD:
+               frame =
+                       lgl_template_frame_cd_new (orig_frame->all.id,
+                                                   orig_frame->cd.r1,
+                                                   orig_frame->cd.r2,
+                                                   orig_frame->cd.w,
+                                                   orig_frame->cd.h,
+                                                   orig_frame->cd.waste);
+               break;
+
+       default:
+               return NULL;
+               break;
+       }
+
+       for ( p=orig_frame->all.layouts; p != NULL; p=p->next ) {
+
+               layout = (lglTemplateLayout *)p->data;
+
+               lgl_template_frame_add_layout (frame, lgl_template_layout_dup (layout));
+       }
+
+       for ( p=orig_frame->all.markups; p != NULL; p=p->next ) {
+
+               markup = (lglTemplateMarkup *)p->data;
+
+               lgl_template_frame_add_markup (frame, lgl_template_markup_dup (markup));
+       }
+
+       return frame;
+}
+
+
+/**
+ * lgl_template_frame_free:
+ *   @frame: Frame to free.
+ *
+ * This function frees all memory associated with given template frame structure.
+ *
+ */
+void
+lgl_template_frame_free (lglTemplateFrame *frame)
+{
+       GList                *p;
+       lglTemplateLayout    *layout;
+       lglTemplateMarkup    *markup;
+
+       if ( frame != NULL ) {
+
+               g_free (frame->all.id);
+               frame->all.id = NULL;
+
+               for ( p=frame->all.layouts; p != NULL; p=p->next ) {
+
+                       layout = (lglTemplateLayout *)p->data;
+
+                       lgl_template_layout_free (layout);
+                       p->data = NULL;
+               }
+               g_list_free (frame->all.layouts);
+               frame->all.layouts = NULL;
+
+               for ( p=frame->all.markups; p != NULL; p=p->next ) {
+
+                       markup = (lglTemplateMarkup *)p->data;
+
+                       lgl_template_markup_free (markup);
+                       p->data = NULL;
+               }
+               g_list_free (frame->all.markups);
+               frame->all.markups = NULL;
+
+               g_free (frame);
+
+       }
+
+}
+
+
+/**
+ * lgl_template_layout_dup:
+ *   @orig_layout: Layout to duplicate.
+ *
+ * This function duplicates a template layout structure.
+ *
+ * Returns:  a newly allocated #lglTemplateLayout structure.
+ *
+ */
+lglTemplateLayout *
+lgl_template_layout_dup (const lglTemplateLayout *orig_layout)
+{
+       lglTemplateLayout *layout;
+
+       g_return_val_if_fail (orig_layout, NULL);
+
+       layout = g_new0 (lglTemplateLayout, 1);
+
+       /* copy contents */
+       *layout = *orig_layout;
+
+       return layout;
+}
+
+
+/**
+ * lgl_template_layout_free:
+ *   @layout: Layout to free.
+ *
+ * This function frees all memory associated with given template layout structure.
+ *
+ */
+void
+lgl_template_layout_free (lglTemplateLayout *layout)
+{
+       g_free (layout);
+}
+
+
+/**
+ * lgl_template_markup_dup:
+ *   @orig_markup: Markup to duplicate.
+ *
+ * This function duplicates a template markup structure.
+ *
+ * Returns:  a newly allocated #lglTemplateMarkup structure.
+ *
+ */
+lglTemplateMarkup *
+lgl_template_markup_dup (const lglTemplateMarkup *orig_markup)
+{
+       lglTemplateMarkup *markup;
+
+       g_return_val_if_fail (orig_markup, NULL);
+
+       markup = g_new0 (lglTemplateMarkup, 1);
+
+       *markup = *orig_markup;
+
+       return markup;
+}
+
+
+/**
+ * lgl_template_markup_free:
+ *   @markup: Markup to free.
+ *
+ * This function frees all memory associated with given template markup structure.
+ *
+ */
+void
+lgl_template_markup_free (lglTemplateMarkup *markup)
+{
+       g_free (markup);
+}
+
+
+static gint
+compare_origins (gconstpointer a,
+                gconstpointer b,
+                gpointer      user_data)
+{
+       const lglTemplateOrigin *a_origin = a, *b_origin = b;
+
+       if ( a_origin->y < b_origin->y ) {
+               return -1;
+       } else if ( a_origin->y > b_origin->y ) {
+               return +1;
+       } else {
+               if ( a_origin->x < b_origin->x ) {
+                       return -1;
+               } else if ( a_origin->x > b_origin->x ) {
+                       return +1;
+               } else {
+                       return 0; /* hopefully 2 labels won't have the same origin */
+               }
+       }
+}
+
+
+/**
+ * lgl_template_print:
+ *   @template: template
+ *
+ * Print template details (for debugging purposes).
+ *
+ */
+void
+lgl_template_print (const lglTemplate *template)
+{
+        g_print ("---- %s( TEMPLATE=%p ) ----\n", __FUNCTION__, template);
+
+        g_print("brand=\"%s\", part=\"%s\", description=\"%s\"\n",
+                template->brand, template->part, template->description);
+
+        g_print("paper_id=\"%s\", page_width=%g, page_height=%g\n",
+                template->paper_id, template->page_width, template->page_height);
+
+        g_print ("\n");
+
+}
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-template.h b/libglabels/lgl-template.h
new file mode 100644 (file)
index 0000000..c1439ab
--- /dev/null
@@ -0,0 +1,424 @@
+/*
+ *  lgl-template.h
+ *  Copyright (C) 2001-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LGL_TEMPLATE_H__
+#define __LGL_TEMPLATE_H__
+
+#include <glib.h>
+#include "lgl-units.h"
+
+G_BEGIN_DECLS
+
+typedef struct _lglTemplate                lglTemplate;
+
+typedef union  _lglTemplateFrame           lglTemplateFrame;
+typedef struct _lglTemplateFrameAll        lglTemplateFrameAll;
+typedef struct _lglTemplateFrameRect       lglTemplateFrameRect;
+typedef struct _lglTemplateFrameEllipse    lglTemplateFrameEllipse;
+typedef struct _lglTemplateFrameRound      lglTemplateFrameRound;
+typedef struct _lglTemplateFrameCD         lglTemplateFrameCD;
+
+typedef struct _lglTemplateLayout          lglTemplateLayout;
+
+typedef union  _lglTemplateMarkup          lglTemplateMarkup;
+typedef struct _lglTemplateMarkupMargin    lglTemplateMarkupMargin;
+typedef struct _lglTemplateMarkupLine      lglTemplateMarkupLine;
+typedef struct _lglTemplateMarkupCircle    lglTemplateMarkupCircle;
+typedef struct _lglTemplateMarkupRect      lglTemplateMarkupRect;
+typedef struct _lglTemplateMarkupEllipse   lglTemplateMarkupEllipse;
+
+typedef struct _lglTemplateOrigin          lglTemplateOrigin;
+
+/*
+ *   Top-level Template Structure
+ */
+struct _lglTemplate {
+
+       gchar               *brand;
+        gchar               *part;
+        gchar               *equiv_part;
+
+       gchar               *description;
+       gchar               *paper_id;
+       gdouble              page_width;
+       gdouble              page_height;
+
+        /* Meta information. */
+        gchar               *product_url;   /* URL to manufacturer's product website. */
+       GList               *category_ids;  /* List of (gchar *) category ids. */
+
+       /* List of (lglTemplateFrame *) label frame structures.
+        * Currently glabels only supports a single label frame per
+        * template. */
+       GList               *frames;
+
+};
+
+
+/*
+ *   Possible Frame Shapes
+ */
+typedef enum {
+       LGL_TEMPLATE_FRAME_SHAPE_RECT,
+       LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE,
+       LGL_TEMPLATE_FRAME_SHAPE_ROUND,
+       LGL_TEMPLATE_FRAME_SHAPE_CD,
+} lglTemplateFrameShape;
+
+
+/*
+ *   Frame Structure
+ */
+struct _lglTemplateFrameAll {
+
+        /* Begin Common Fields */
+       lglTemplateFrameShape shape;
+
+       gchar                *id;       /* Id, currently always "0" */
+       GList                *layouts;  /* List of lglTemplateLayouts */
+       GList                *markups;  /* List of lglTemplateMarkups */
+        /* End Common Fields */
+};
+
+struct _lglTemplateFrameRect {
+
+        /* Begin Common Fields */
+       lglTemplateFrameShape shape;    /* Always LGL_TEMPLATE_FRAME_SHAPE_RECT. */
+
+       gchar                *id;       /* Id, currently always "0" */
+       GList                *layouts;  /* List of lglTemplateLayouts */
+       GList                *markups;  /* List of lglTemplateMarkups */
+        /* End Common Fields */
+
+        gdouble               w;        /* Width */
+        gdouble               h;        /* Height */
+        gdouble               r;        /* Corner radius */
+        gdouble               x_waste;  /* Amount of horiz overprint allowed. */
+        gdouble               y_waste;  /* Amount of vert overprint allowed. */
+};
+
+struct _lglTemplateFrameEllipse {
+
+        /* Begin Common Fields */
+       lglTemplateFrameShape shape;    /* Always LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE. */
+
+       gchar                *id;       /* Id, currently always "0" */
+       GList                *layouts;  /* List of lglTemplateLayouts */
+       GList                *markups;  /* List of lglTemplateMarkups */
+        /* End Common Fields */
+
+        gdouble               w;        /* Width */
+        gdouble               h;        /* Height */
+        gdouble               waste;    /* Amount of overprint allowed. */
+};
+
+struct _lglTemplateFrameRound {
+
+        /* Begin Common Fields */
+       lglTemplateFrameShape shape;    /* Always LGL_TEMPLATE_FRAME_SHAPE_ROUND. */
+
+       gchar                *id;       /* Id, currently always "0" */
+       GList                *layouts;  /* List of lglTemplateLayouts */
+       GList                *markups;  /* List of lglTemplateMarkups */
+        /* End Common Fields */
+
+        gdouble               r;      /* Radius */
+        gdouble               waste;  /* Amount of overprint allowed. */
+};
+
+struct _lglTemplateFrameCD {
+
+        /* Begin Common Fields */
+       lglTemplateFrameShape shape;    /* Always LGL_TEMPLATE_FRAME_SHAPE_CD. */
+
+       gchar                *id;       /* Id, currently always "0" */
+       GList                *layouts;  /* List of lglTemplateLayouts */
+       GList                *markups;  /* List of lglTemplateMarkups */
+        /* End Common Fields */
+
+        gdouble               r1;     /* Outer radius */
+        gdouble               r2;     /* Inner radius (hole) */
+        gdouble               w;      /* Clip width, business card CDs */
+        gdouble               h;      /* Clip height, business card CDs */
+        gdouble               waste;  /* Amount of overprint allowed. */
+};
+
+union _lglTemplateFrame{
+
+       lglTemplateFrameShape   shape;
+
+       lglTemplateFrameAll     all;
+       lglTemplateFrameRect    rect;
+       lglTemplateFrameEllipse ellipse;
+       lglTemplateFrameRound   round;
+       lglTemplateFrameCD      cd;
+};
+
+
+/*
+ *   Label Layout Structure
+ */
+struct _lglTemplateLayout {
+
+       gint                  nx;  /* Number of labels across */
+       gint                  ny;  /* Number of labels up and down */
+
+       gdouble               x0;  /* Left of grid from left edge of paper */
+       gdouble               y0;  /* Top of grid from top edge of paper */
+
+       gdouble               dx;  /* Horizontal pitch of grid */
+       gdouble               dy;  /* Vertical pitch of grid */
+
+};
+
+
+/*
+ * Possible Markup Types
+ */
+typedef enum {
+       LGL_TEMPLATE_MARKUP_MARGIN,
+       LGL_TEMPLATE_MARKUP_LINE,
+       LGL_TEMPLATE_MARKUP_CIRCLE,
+       LGL_TEMPLATE_MARKUP_RECT,
+       LGL_TEMPLATE_MARKUP_ELLIPSE,
+} lglTemplateMarkupType;
+
+
+/*
+ *   Label Markup Structure (Helpful lines drawn in glabels to help locate objects)
+ */
+struct _lglTemplateMarkupMargin {
+
+       lglTemplateMarkupType  type;  /* Always LGL_TEMPLATE_MARKUP_MARGIN */
+
+        gdouble                size;  /* Margin size */
+};
+
+struct _lglTemplateMarkupLine {
+
+       lglTemplateMarkupType  type;   /* Always LGL_TEMPLATE_MARKUP_LINE */
+
+        gdouble                x1, y1; /* 1st endpoint */
+        gdouble                x2, y2; /* 2nd endpoint */
+};
+
+struct _lglTemplateMarkupCircle {
+
+       lglTemplateMarkupType  type;   /* Always LGL_TEMPLATE_MARKUP_CIRCLE */
+
+        gdouble                x0, y0; /* Center of circle */
+        gdouble                r;      /* Radius of circle */
+};
+
+struct _lglTemplateMarkupRect {
+
+       lglTemplateMarkupType  type;   /* Always LGL_TEMPLATE_MARKUP_RECT */
+
+        gdouble                x1, y1; /* Upper left corner */
+        gdouble                w, h;   /* Width and height. */
+        gdouble                r;      /* Radius of corners. */
+};
+
+struct _lglTemplateMarkupEllipse {
+
+       lglTemplateMarkupType  type;   /* Always LGL_TEMPLATE_MARKUP_ELLIPSE */
+
+        gdouble                x1, y1; /* Upper left corner */
+        gdouble                w, h;   /* Width and height. */
+};
+
+union _lglTemplateMarkup {
+
+       lglTemplateMarkupType    type;
+
+       lglTemplateMarkupMargin  margin;
+       lglTemplateMarkupLine    line;
+       lglTemplateMarkupCircle  circle;
+       lglTemplateMarkupRect    rect;
+       lglTemplateMarkupEllipse ellipse;
+};
+
+
+/*
+ *  Origin coordinates
+ */
+struct _lglTemplateOrigin {
+
+       gdouble               x, y; /* Label origin relative to upper 
+                                    * upper left hand corner of paper */
+
+};
+
+
+
+/* 
+ * Template query functions
+ */
+gchar                     *lgl_template_get_name                (const lglTemplate   *template);
+
+gboolean                   lgl_template_do_templates_match      (const lglTemplate   *template1,
+                                                                 const lglTemplate   *template2);
+
+gboolean                   lgl_template_does_brand_match        (const lglTemplate   *template,
+                                                                 const gchar         *brand);
+
+gboolean                   lgl_template_does_page_size_match    (const lglTemplate   *template,
+                                                                 const gchar         *paper_id);
+
+gboolean                   lgl_template_does_category_match     (const lglTemplate   *template,
+                                                                 const gchar         *category_id);
+
+gboolean                   lgl_template_are_templates_identical (const lglTemplate   *template1,
+                                                                 const lglTemplate   *template2);
+
+
+
+
+/*
+ * Frame query functions
+ */
+void                 lgl_template_frame_get_size       (const lglTemplateFrame    *frame,
+                                                        gdouble                   *w,
+                                                        gdouble                   *h);
+
+gint                 lgl_template_frame_get_n_labels   (const lglTemplateFrame    *frame);
+
+lglTemplateOrigin   *lgl_template_frame_get_origins    (const lglTemplateFrame    *frame);
+
+gchar               *lgl_template_frame_get_layout_description (const lglTemplateFrame *frame);
+
+gchar               *lgl_template_frame_get_size_description   (const lglTemplateFrame *frame,
+                                                                lglUnits                units);
+
+
+
+
+/*
+ * Template Construction
+ */
+lglTemplate         *lgl_template_new                  (const gchar          *brand,
+                                                        const gchar          *part,
+                                                        const gchar          *description,
+                                                        const gchar          *paper_id,
+                                                        gdouble               page_width,
+                                                        gdouble               page_height);
+
+lglTemplate         *lgl_template_new_from_equiv       (const gchar          *brand,
+                                                        const gchar          *part,
+                                                        const gchar          *equiv_part);
+
+void                 lgl_template_add_category         (lglTemplate          *template,
+                                                        const gchar          *category_id);
+
+void                 lgl_template_add_frame            (lglTemplate          *template,
+                                                        lglTemplateFrame     *frame);
+
+lglTemplateFrame    *lgl_template_frame_rect_new       (const gchar          *id,
+                                                        gdouble               w,
+                                                        gdouble               h,
+                                                        gdouble               r,
+                                                        gdouble               x_waste,
+                                                        gdouble               y_waste);
+
+lglTemplateFrame    *lgl_template_frame_ellipse_new    (const gchar          *id,
+                                                        gdouble               w,
+                                                        gdouble               h,
+                                                        gdouble               waste);
+
+lglTemplateFrame    *lgl_template_frame_round_new      (const gchar          *id,
+                                                        gdouble               r,
+                                                        gdouble               waste);
+
+lglTemplateFrame    *lgl_template_frame_cd_new         (const gchar          *id,
+                                                        gdouble               r1,
+                                                        gdouble               r2,
+                                                        gdouble               w,
+                                                        gdouble               h,
+                                                        gdouble               waste);
+
+void                 lgl_template_frame_add_layout     (lglTemplateFrame     *frame,
+                                                        lglTemplateLayout    *layout);
+
+void                 lgl_template_frame_add_markup     (lglTemplateFrame     *frame,
+                                                        lglTemplateMarkup    *markup);
+
+lglTemplateLayout   *lgl_template_layout_new           (gint                  nx,
+                                                        gint                  ny,
+                                                        gdouble               x0,
+                                                        gdouble               y0,
+                                                        gdouble               dx,
+                                                        gdouble               dy);
+
+lglTemplateMarkup   *lgl_template_markup_margin_new    (gdouble               size);
+
+lglTemplateMarkup   *lgl_template_markup_line_new      (gdouble               x1,
+                                                        gdouble               y1,
+                                                        gdouble               x2,
+                                                        gdouble               y2);
+
+lglTemplateMarkup   *lgl_template_markup_circle_new    (gdouble               x0,
+                                                        gdouble               y0,
+                                                        gdouble               r);
+
+lglTemplateMarkup   *lgl_template_markup_rect_new      (gdouble               x1,
+                                                        gdouble               y1,
+                                                        gdouble               w,
+                                                        gdouble               h,
+                                                        gdouble               r);
+
+lglTemplateMarkup   *lgl_template_markup_ellipse_new   (gdouble               x1,
+                                                        gdouble               y1,
+                                                        gdouble               w,
+                                                        gdouble               h);
+
+lglTemplate         *lgl_template_dup                  (const lglTemplate    *orig_template);
+
+void                 lgl_template_free                 (lglTemplate          *template);
+
+lglTemplateFrame    *lgl_template_frame_dup            (const lglTemplateFrame     *orig_frame);
+void                 lgl_template_frame_free           (lglTemplateFrame           *frame);
+
+lglTemplateLayout   *lgl_template_layout_dup           (const lglTemplateLayout    *orig_layout);
+void                 lgl_template_layout_free          (lglTemplateLayout          *layout);
+
+lglTemplateMarkup   *lgl_template_markup_dup           (const lglTemplateMarkup    *orig_markup);
+void                 lgl_template_markup_free          (lglTemplateMarkup          *markup);
+
+
+/*
+ * Debugging functions.
+ */
+void                 lgl_template_print                (const lglTemplate          *template);
+
+
+G_END_DECLS
+
+#endif /* __LGL_TEMPLATE_H__ */
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-units.c b/libglabels/lgl-units.c
new file mode 100644 (file)
index 0000000..73d243d
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ *  lgl-units.c
+ *  Copyright (C) 2003-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "lgl-units.h"
+
+#include <glib/gi18n.h>
+#include <glib.h>
+#include <string.h>
+
+#include "libglabels-private.h"
+
+
+/*========================================================*/
+/* Private macros and constants.                          */
+/*========================================================*/
+
+#define POINTS_PER_POINT    1.0 /* internal units are points. */
+#define POINTS_PER_INCH    72.0
+#define POINTS_PER_MM       2.83464566929
+#define POINTS_PER_CM       (10.0*POINTS_PER_MM)
+#define POINTS_PER_PICA     (1.0/12.0)
+
+
+/*========================================================*/
+/* Private types.                                         */
+/*========================================================*/
+
+typedef struct {
+       gchar       *id;
+       gchar       *name;
+       gdouble      points_per_unit;
+} UnitTableEntry;
+
+
+/*========================================================*/
+/* Private globals.                                       */
+/*========================================================*/
+
+static UnitTableEntry unit_table[] = {
+
+       /* The ids are identical to the absolute length units supported in
+          the CSS2 Specification (Section 4.3.2) */
+
+       /* This table must be sorted exactly as the enumerations in lglUnits */
+
+       /* [LGL_UNITS_POINT] */   {"pt", N_("points"), POINTS_PER_POINT},
+       /* [LGL_UNITS_INCH]  */   {"in", N_("inches"), POINTS_PER_INCH},
+       /* [LGL_UNITS_MM]    */   {"mm", N_("mm"),     POINTS_PER_MM},
+       /* [LGL_UNITS_CM]    */   {"cm", N_("cm"),     POINTS_PER_CM},
+       /* [LGL_UNITS_PICA]  */   {"pc", N_("picas"),  POINTS_PER_PICA},
+
+};
+
+
+
+/**
+ * lgl_units_get_id:
+ * @units:       Units (#lglUnits)
+ *
+ * Return a unique ID string for the given units.  This ID is how units
+ * are encoded in libglabels XML files and will remain constant across
+ * all locales.  IDs are identical to the absolute length units supported
+ * in the CSS2 Specification (Section 4.3.2). 
+ *
+ * Returns: ID string.
+ *
+ */
+const gchar *
+lgl_units_get_id (lglUnits     units)
+{
+        if ( (units >= LGL_UNITS_FIRST) && (units <= LGL_UNITS_LAST) )
+        {
+                return unit_table[units].id;
+        }
+        else
+        {
+                /* Default to "pt", if invalid. */
+                return unit_table[LGL_UNITS_POINT].id;
+        }
+}
+
+
+/**
+ * lgl_units_from_id:
+ * @id:       ID string
+ *
+ * Return the unique #lglUnits for the given ID string.
+ * This ID is how units are encoded in libglabels XML files and will remain
+ * constant across all locales.  IDs are identical to the absolute length
+ * units supported in the CSS2 Specification (Section 4.3.2). 
+ *
+ * Returns: units (#lglUnits).
+ *
+ */
+lglUnits
+lgl_units_from_id (const gchar *id)
+{
+        lglUnits units;
+
+        /* An empty or missing id defaults to points. */
+        if ( (id == NULL) || (strlen (id) == 0) )
+        {
+                return LGL_UNITS_POINT;
+        }
+
+        for ( units = LGL_UNITS_FIRST; units <= LGL_UNITS_LAST; units++) {
+                if (g_ascii_strcasecmp (id, unit_table[units].id) == 0) {
+                        return units;
+                }
+        }
+
+        /* Try name as a fallback. (Will catch some legacy preferences.) */
+        for ( units = LGL_UNITS_FIRST; units <= LGL_UNITS_LAST; units++) {
+                if (g_ascii_strcasecmp (id, unit_table[units].name) == 0) {
+                        return units;
+                }
+        }
+
+        /* For compatibility with old preferences. */
+        if (g_ascii_strcasecmp (id, "Millimeters") == 0) {
+                return LGL_UNITS_MM;
+        }
+
+        return LGL_UNITS_INVALID;
+}
+
+
+/**
+ * lgl_units_get_name:
+ * @units:       Units (#lglUnits)
+ *
+ * Return a unique name string for the given units.  This name is human
+ * readable and will be translated to the current locale.
+ *
+ * Returns: name string.
+ *
+ */
+const gchar *
+lgl_units_get_name (lglUnits     units)
+{
+        if ( (units >= LGL_UNITS_FIRST) && (units <= LGL_UNITS_LAST) )
+        {
+                return gettext ((char *)unit_table[units].name);
+        }
+        else
+        {
+                /* Default to "points", if invalid. */
+                return gettext ((char *)unit_table[LGL_UNITS_POINT].name);
+        }
+}
+
+
+/**
+ * lgl_units_from_name:
+ * @name:       NAME string
+ *
+ * Return the unique #lglUnits for the given name string.  This name is
+ * human readable and is expected to be translated to the current locale.
+ *
+ * Returns: units (#lglUnits).
+ *
+ */
+lglUnits
+lgl_units_from_name (const gchar *name)
+{
+        lglUnits units;
+
+        for ( units = LGL_UNITS_FIRST; units <= LGL_UNITS_LAST; units++) {
+                if (g_ascii_strcasecmp (name, gettext ((char *)unit_table[units].name) ) == 0) {
+                        return units;
+                }
+        }
+
+        return LGL_UNITS_INVALID;
+}
+
+
+/**
+ * lgl_units_get_points_per_unit:
+ * @units:       Units (#lglUnits)
+ *
+ * Return a scale factor for the given units in points/unit.
+ *
+ * Returns: scale factor.
+ *
+ */
+gdouble
+lgl_units_get_points_per_unit (lglUnits     units)
+{
+        if ( (units >= LGL_UNITS_FIRST) && (units <= LGL_UNITS_LAST) )
+        {
+                return unit_table[units].points_per_unit;
+        }
+        else
+        {
+                /* Default to "points", if invalid. */
+                return 1.0;
+        }
+}
+
+
+/**
+ * lgl_units_get_units_per_point:
+ * @units:       Units (#lglUnits)
+ *
+ * Return a scale factor for the given units in units/point.
+ *
+ * Returns: scale factor.
+ *
+ */
+gdouble
+lgl_units_get_units_per_point (lglUnits     units)
+{
+        if ( (units >= LGL_UNITS_FIRST) && (units <= LGL_UNITS_LAST) )
+        {
+                return 1.0 / unit_table[units].points_per_unit;
+        }
+        else
+        {
+                /* Default to "points", if invalid. */
+                return 1.0;
+        }
+}
+
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-units.h b/libglabels/lgl-units.h
new file mode 100644 (file)
index 0000000..b22be07
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ *  lgl-units.h
+ *  Copyright (C) 2003-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LGL_UNITS_H__
+#define __LGL_UNITS_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+
+/*
+ * Units of distance
+ */
+typedef enum {
+       LGL_UNITS_POINT, /* encoded as "pt" */
+       LGL_UNITS_INCH,  /* encoded as "in" */
+       LGL_UNITS_MM,    /* encoded as "mm" */
+       LGL_UNITS_CM,    /* encoded as "cm" */
+       LGL_UNITS_PICA,  /* encoded as "pc" */
+
+       LGL_UNITS_FIRST = LGL_UNITS_POINT,
+       LGL_UNITS_LAST  = LGL_UNITS_PICA,
+
+        LGL_UNITS_INVALID = -1,
+} lglUnits;
+
+
+const gchar *lgl_units_get_id               (lglUnits     units);
+lglUnits     lgl_units_from_id              (const gchar *id);
+
+const gchar *lgl_units_get_name             (lglUnits     units);
+lglUnits     lgl_units_from_name            (const gchar *name);
+
+gdouble      lgl_units_get_points_per_unit  (lglUnits     units);
+gdouble      lgl_units_get_units_per_point  (lglUnits     units);
+
+
+G_END_DECLS
+
+
+#endif /* __LGL_UNITS_H__ */
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-vendor.c b/libglabels/lgl-vendor.c
new file mode 100644 (file)
index 0000000..425c1b5
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ *  lgl-vendor.c
+ *  Copyright (C) 2003-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "lgl-vendor.h"
+
+#include <glib/gi18n.h>
+#include <glib.h>
+#include <string.h>
+
+#include "libglabels-private.h"
+
+/*===========================================*/
+/* Private types                             */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Private globals                           */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Local function prototypes                 */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Functions.                                */
+/*===========================================*/
+
+/**
+ * lgl_vendor_new:
+ * @name:     Localized name of vendor.
+ *
+ * Allocates and constructs a new #lglVendor structure.
+ *
+ * Returns: a pointer to a newly allocated #lglVendor structure.
+ *
+ */
+lglVendor *
+lgl_vendor_new (gchar             *name)
+{
+       lglVendor *vendor;
+
+       vendor           = g_new0 (lglVendor,1);
+
+       vendor->name     = g_strdup (name);
+
+       return vendor;
+}
+
+
+/**
+ * lgl_vendor_dup:
+ * @orig:  #lglVendor structure to be duplicated.
+ *
+ * Duplicates an existing #lglVendor structure.
+ *
+ * Returns: a pointer to a newly allocated #lglVendor structure.
+ *
+ */
+lglVendor *lgl_vendor_dup (const lglVendor *orig)
+{
+       lglVendor       *vendor;
+
+       g_return_val_if_fail (orig, NULL);
+
+       vendor = g_new0 (lglVendor,1);
+
+       vendor->name  = g_strdup (orig->name);
+       vendor->url   = g_strdup (orig->url);
+
+       return vendor;
+}
+
+
+/**
+ * lgl_vendor_free:
+ * @vendor:  pointer to #lglVendor structure to be freed.
+ *
+ * Free all memory associated with an existing #lglVendor structure.
+ *
+ */
+void lgl_vendor_free (lglVendor *vendor)
+{
+
+       if ( vendor != NULL ) {
+
+               g_free (vendor->name);
+               vendor->name = NULL;
+
+               g_free (vendor->url);
+               vendor->url = NULL;
+
+               g_free (vendor);
+       }
+
+}
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-vendor.h b/libglabels/lgl-vendor.h
new file mode 100644 (file)
index 0000000..fc0be29
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *  lgl-vendor.h
+ *  Copyright (C) 2003-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LGL_VENDOR_H__
+#define __LGL_VENDOR_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+
+/*
+ *   lglVendor structure
+ */
+typedef struct _lglVendor lglVendor;
+
+struct _lglVendor {
+       gchar               *name;           /* Vendor name */
+       gchar               *url;            /* Vendor URL */
+};
+
+
+/*
+ * Vendor construction
+ */
+lglVendor           *lgl_vendor_new                (gchar           *name);
+
+lglVendor           *lgl_vendor_dup                (const lglVendor *orig);
+
+void                 lgl_vendor_free               (lglVendor       *vendor);
+
+
+G_END_DECLS
+
+#endif /* __LGL_VENDOR_H__ */
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-xml-category.c b/libglabels/lgl-xml-category.c
new file mode 100644 (file)
index 0000000..91822ee
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ *  lgl-xml-category.c
+ *  Copyright (C) 2006-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "lgl-xml-category.h"
+
+#include <glib/gi18n.h>
+#include <glib.h>
+#include <string.h>
+#include <libintl.h>
+
+#include "libglabels-private.h"
+
+#include "lgl-xml.h"
+
+/*===========================================*/
+/* Private types                             */
+/*===========================================*/
+
+/*===========================================*/
+/* Private globals                           */
+/*===========================================*/
+
+/*===========================================*/
+/* Local function prototypes                 */
+/*===========================================*/
+
+
+/**
+ * lgl_xml_category_read_categories_from_file:
+ * @utf8_filename:       Filename of categories file (name encoded as UTF-8)
+ *
+ * Read category definitions from a file.
+ *
+ * Returns: a list of #lglCategory structures.
+ *
+ */
+GList *
+lgl_xml_category_read_categories_from_file (gchar *utf8_filename)
+{
+       gchar      *filename;
+       GList      *categories;
+       xmlDocPtr   categories_doc;
+
+       LIBXML_TEST_VERSION;
+
+       filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
+       if (!filename) {
+               g_message ("Utf8 filename conversion error");
+               return NULL;
+       }
+
+       categories_doc = xmlParseFile (filename);
+       if (!categories_doc) {
+               g_message ("\"%s\" is not a glabels category file (not XML)",
+                          filename);
+               return NULL;
+       }
+
+       categories = lgl_xml_category_parse_categories_doc (categories_doc);
+
+       g_free (filename);
+       xmlFreeDoc (categories_doc);
+
+       return categories;
+}
+
+
+/**
+ * lgl_xml_category_parse_categories_doc:
+ * @categories_doc:  libxml #xmlDocPtr tree, representing a categories
+ * definition file.
+ *
+ * Read category definitions from a libxml #xmlDocPtr tree.
+ *
+ * Returns: a list of #lglCategory structures.
+ *
+ */
+GList *
+lgl_xml_category_parse_categories_doc (xmlDocPtr  categories_doc)
+{
+       GList       *categories = NULL;
+       xmlNodePtr   root, node;
+       lglCategory *category;
+
+       LIBXML_TEST_VERSION;
+
+       root = xmlDocGetRootElement (categories_doc);
+       if (!root || !root->name) {
+               g_message ("\"%s\" is not a glabels category file (no root node)",
+                          categories_doc->name);
+               xmlFreeDoc (categories_doc);
+               return categories;
+       }
+       if (!lgl_xml_is_node (root, "Glabels-categories")) {
+               g_message ("\"%s\" is not a glabels category file (wrong root node)",
+                          categories_doc->name);
+               xmlFreeDoc (categories_doc);
+               return categories;
+       }
+
+       for (node = root->xmlChildrenNode; node != NULL; node = node->next) {
+
+               if (lgl_xml_is_node (node, "Category")) {
+                       category = lgl_xml_category_parse_category_node (node);
+                       categories = g_list_append (categories, category);
+               } else {
+                       if ( !xmlNodeIsText(node) ) {
+                               if (!lgl_xml_is_node (node, "comment")) {
+                                       g_message ("bad node =  \"%s\"",node->name);
+                               }
+                       }
+               }
+       }
+
+       return categories;
+}
+
+
+/**
+ * lgl_xml_category_parse_category_node:
+ * @category_node:  libxml #xmlNodePtr category node from a #xmlDocPtr tree.
+ *
+ * Read a single category definition from a libxml #xmlNodePtr node.
+ *
+ * Returns: a pointer to a newly created #lglCategory structure.
+ *
+ */
+lglCategory *
+lgl_xml_category_parse_category_node (xmlNodePtr category_node)
+{
+       lglCategory           *category;
+       gchar                 *id, *name;
+
+       LIBXML_TEST_VERSION;
+
+       id   = lgl_xml_get_prop_string (category_node, "id", NULL);
+       name = lgl_xml_get_prop_i18n_string (category_node, "name", NULL);
+
+       category = lgl_category_new (id, name);
+
+       g_free (id);
+       g_free (name);
+
+       return category;
+}
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-xml-category.h b/libglabels/lgl-xml-category.h
new file mode 100644 (file)
index 0000000..1f535e9
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *  lgl-xml-category.h
+ *  Copyright (C) 2006-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LGL_XML_CATEGORY_H__
+#define __LGL_XML_CATEGORY_H__
+
+#include <glib.h>
+#include <libxml/tree.h>
+
+#include "lgl-category.h"
+
+G_BEGIN_DECLS
+
+GList       *lgl_xml_category_read_categories_from_file (gchar        *utf8_filename);
+
+GList       *lgl_xml_category_parse_categories_doc      (xmlDocPtr     categories_doc);
+
+lglCategory *lgl_xml_category_parse_category_node       (xmlNodePtr    category_node);
+
+
+G_END_DECLS
+
+#endif /* __LGL_XML_CATEGORY_H__ */
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-xml-paper.c b/libglabels/lgl-xml-paper.c
new file mode 100644 (file)
index 0000000..549f9e8
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ *  lgl-xml-paper.c
+ *  Copyright (C) 2003-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "lgl-xml-paper.h"
+
+#include <glib/gi18n.h>
+#include <glib.h>
+#include <string.h>
+#include <libintl.h>
+
+#include "libglabels-private.h"
+
+#include "lgl-xml.h"
+
+/*===========================================*/
+/* Private types                             */
+/*===========================================*/
+
+/*===========================================*/
+/* Private globals                           */
+/*===========================================*/
+
+/*===========================================*/
+/* Local function prototypes                 */
+/*===========================================*/
+
+
+/**
+ * lgl_xml_paper_read_papers_from_file:
+ * @utf8_filename:       Filename of papers file (name encoded as UTF-8)
+ *
+ * Read paper definitions from a file.
+ *
+ * Returns: a list of #lglPaper structures.
+ *
+ */
+GList *
+lgl_xml_paper_read_papers_from_file (gchar *utf8_filename)
+{
+       gchar      *filename;
+       GList      *papers;
+       xmlDocPtr   papers_doc;
+
+       LIBXML_TEST_VERSION;
+
+       filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
+       if (!filename) {
+               g_message ("Utf8 filename conversion error");
+               return NULL;
+       }
+
+       papers_doc = xmlParseFile (filename);
+       if (!papers_doc) {
+               g_message ("\"%s\" is not a glabels paper file (not XML)",
+                          filename);
+               return NULL;
+       }
+
+       papers = lgl_xml_paper_parse_papers_doc (papers_doc);
+
+       g_free (filename);
+       xmlFreeDoc (papers_doc);
+
+       return papers;
+}
+
+
+/**
+ * lgl_xml_paper_parse_papers_doc:
+ * @papers_doc:  libxml #xmlDocPtr tree, representing a papers definition file.
+ *
+ * Read paper definitions from a libxml #xmlDocPtr tree.
+ *
+ * Returns: a list of #lglPaper structures.
+ *
+ */
+GList *
+lgl_xml_paper_parse_papers_doc (xmlDocPtr  papers_doc)
+{
+       GList      *papers = NULL;
+       xmlNodePtr  root, node;
+       lglPaper   *paper;
+
+       LIBXML_TEST_VERSION;
+
+       root = xmlDocGetRootElement (papers_doc);
+       if (!root || !root->name) {
+               g_message ("\"%s\" is not a glabels paper file (no root node)",
+                          papers_doc->name);
+               xmlFreeDoc (papers_doc);
+               return papers;
+       }
+       if (!lgl_xml_is_node (root, "Glabels-paper-sizes")) {
+               g_message ("\"%s\" is not a glabels paper file (wrong root node)",
+                          papers_doc->name);
+               xmlFreeDoc (papers_doc);
+               return papers;
+       }
+
+       for (node = root->xmlChildrenNode; node != NULL; node = node->next) {
+
+               if (lgl_xml_is_node (node, "Paper-size")) {
+                       paper = lgl_xml_paper_parse_paper_node (node);
+                       papers = g_list_append (papers, paper);
+               } else {
+                       if ( !xmlNodeIsText(node) ) {
+                               if (!lgl_xml_is_node (node, "comment")) {
+                                       g_message ("bad node =  \"%s\"",node->name);
+                               }
+                       }
+               }
+       }
+
+       return papers;
+}
+
+
+/**
+ * lgl_xml_paper_parse_paper_node:
+ * @paper_node:  libxml #xmlNodePtr paper node from a #xmlDocPtr tree.
+ *
+ * Read a single paper definition from a libxml #xmlNodePtr node.
+ *
+ * Returns: a pointer to a newly created #lglPaper structure.
+ *
+ */
+lglPaper *
+lgl_xml_paper_parse_paper_node (xmlNodePtr paper_node)
+{
+       lglPaper              *paper;
+       gchar                 *id, *name, *pwg_size;
+       gdouble                width, height;
+
+       LIBXML_TEST_VERSION;
+
+       id   = lgl_xml_get_prop_string (paper_node, "id", NULL);
+
+       name = lgl_xml_get_prop_i18n_string (paper_node, "name", NULL);
+
+       width  = lgl_xml_get_prop_length (paper_node, "width", 0);
+       height = lgl_xml_get_prop_length (paper_node, "height", 0);
+
+       pwg_size = lgl_xml_get_prop_string (paper_node, "pwg_size", NULL);
+
+       paper = lgl_paper_new (id, name, width, height, pwg_size);
+
+       g_free (id);
+       g_free (name);
+       g_free (pwg_size);
+
+       return paper;
+}
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-xml-paper.h b/libglabels/lgl-xml-paper.h
new file mode 100644 (file)
index 0000000..e4704c6
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *  lgl-xml-paper.h
+ *  Copyright (C) 2003-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LGL_XML_PAPER_H__
+#define __LGL_XML_PAPER_H__
+
+#include <glib.h>
+#include <libxml/tree.h>
+
+#include "lgl-paper.h"
+
+G_BEGIN_DECLS
+
+GList       *lgl_xml_paper_read_papers_from_file (gchar        *utf8_filename);
+
+GList       *lgl_xml_paper_parse_papers_doc      (xmlDocPtr     papers_doc);
+
+lglPaper    *lgl_xml_paper_parse_paper_node      (xmlNodePtr    paper_node);
+
+
+G_END_DECLS
+
+#endif /* __LGL_XML_PAPER_H__ */
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-xml-template.c b/libglabels/lgl-xml-template.c
new file mode 100644 (file)
index 0000000..95a2a65
--- /dev/null
@@ -0,0 +1,1105 @@
+/*
+ *  lgl-xml-template.c
+ *  Copyright (C) 2001-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "lgl-xml-template.h"
+
+#include <glib/gi18n.h>
+#include <glib.h>
+#include <string.h>
+#include <libintl.h>
+
+#include "libglabels-private.h"
+
+#include "lgl-db.h"
+#include "lgl-xml.h"
+
+/*===========================================*/
+/* Private types                             */
+/*===========================================*/
+
+/*===========================================*/
+/* Private globals                           */
+/*===========================================*/
+
+/*===========================================*/
+/* Local function prototypes                 */
+/*===========================================*/
+static void  xml_parse_meta_node            (xmlNodePtr              label_node,
+                                            lglTemplate            *template);
+static void  xml_parse_label_rectangle_node (xmlNodePtr              label_node,
+                                            lglTemplate            *template);
+static void  xml_parse_label_ellipse_node   (xmlNodePtr              label_node,
+                                            lglTemplate            *template);
+static void  xml_parse_label_round_node     (xmlNodePtr              label_node,
+                                            lglTemplate            *template);
+static void  xml_parse_label_cd_node        (xmlNodePtr              label_node,
+                                            lglTemplate            *template);
+static void  xml_parse_layout_node          (xmlNodePtr              layout_node,
+                                            lglTemplateFrame       *frame);
+static void  xml_parse_markup_margin_node   (xmlNodePtr              markup_node,
+                                            lglTemplateFrame       *frame);
+static void  xml_parse_markup_line_node     (xmlNodePtr              markup_node,
+                                            lglTemplateFrame       *frame);
+static void  xml_parse_markup_circle_node   (xmlNodePtr              markup_node,
+                                            lglTemplateFrame       *frame);
+static void  xml_parse_markup_rect_node     (xmlNodePtr              markup_node,
+                                            lglTemplateFrame       *frame);
+static void  xml_parse_markup_ellipse_node  (xmlNodePtr              markup_node,
+                                            lglTemplateFrame       *frame);
+static void  xml_parse_alias_node           (xmlNodePtr              alias_node,
+                                            lglTemplate            *template);
+
+static void  xml_create_meta_node           (const gchar                  *attr,
+                                             const gchar                  *value,
+                                            xmlNodePtr                    root,
+                                            const xmlNsPtr                ns);
+static void  xml_create_label_node          (const lglTemplateFrame       *frame,
+                                            xmlNodePtr                    root,
+                                            const xmlNsPtr                ns);
+static void  xml_create_layout_node         (const lglTemplateLayout      *layout,
+                                            xmlNodePtr                    root,
+                                            const xmlNsPtr                ns);
+static void  xml_create_markup_margin_node  (const lglTemplateMarkup      *margin,
+                                            xmlNodePtr                    root,
+                                            const xmlNsPtr                ns);
+static void  xml_create_markup_line_node    (const lglTemplateMarkup      *line,
+                                            xmlNodePtr                    root,
+                                            const xmlNsPtr                ns);
+static void  xml_create_markup_circle_node  (const lglTemplateMarkup      *circle,
+                                            xmlNodePtr                    root,
+                                            const xmlNsPtr                ns);
+static void  xml_create_markup_rect_node    (const lglTemplateMarkup      *circle,
+                                            xmlNodePtr                    root,
+                                            const xmlNsPtr                ns);
+static void  xml_create_markup_ellipse_node (const lglTemplateMarkup      *circle,
+                                            xmlNodePtr                    root,
+                                            const xmlNsPtr                ns);
+
+
+/**
+ * lgl_xml_template_read_templates_from_file:
+ * @utf8_filename:       Filename of papers file (name encoded as UTF-8)
+ *
+ * Read glabels templates from template file.
+ *
+ */
+void
+lgl_xml_template_read_templates_from_file (const gchar *utf8_filename)
+{
+       gchar      *filename;
+       xmlDocPtr   templates_doc;
+
+       LIBXML_TEST_VERSION;
+
+       filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
+       if (!filename) {
+               g_message ("Utf8 filename conversion error");
+               return;
+       }
+
+       templates_doc = xmlParseFile (filename);
+       if (!templates_doc) {
+               g_message ("\"%s\" is not a glabels template file (not XML)",
+                     filename);
+               return;
+       }
+
+       lgl_xml_template_parse_templates_doc (templates_doc);
+
+       g_free (filename);
+       xmlFreeDoc (templates_doc);
+}
+
+
+/**
+ * lgl_xml_template_parse_templates_doc:
+ * @templates_doc:  libxml #xmlDocPtr tree, representing template file.
+ *
+ * Read glabels templates from a libxml #xmlDocPtr tree.
+ *
+ */
+void
+lgl_xml_template_parse_templates_doc (const xmlDocPtr templates_doc)
+{
+       
+       xmlNodePtr   root, node;
+       lglTemplate *template;
+
+       LIBXML_TEST_VERSION;
+
+       root = xmlDocGetRootElement (templates_doc);
+       if (!root || !root->name)
+        {
+               g_message ("\"%s\" is not a glabels template file (no root node)",
+                          templates_doc->URL);
+               return;
+       }
+       if (!lgl_xml_is_node (root, "Glabels-templates"))
+        {
+               g_message ("\"%s\" is not a glabels template file (wrong root node)",
+                     templates_doc->URL);
+               return;
+       }
+
+       for (node = root->xmlChildrenNode; node != NULL; node = node->next)
+        {
+
+               if (lgl_xml_is_node (node, "Template"))
+                {
+                       template = lgl_xml_template_parse_template_node (node);
+                        if (template)
+                        {
+                                _lgl_db_register_template_internal (template);
+                                lgl_template_free (template);
+                        }
+               }
+                else
+                {
+                       if ( !xmlNodeIsText(node) )
+                        {
+                               if (!lgl_xml_is_node (node,"comment"))
+                                {
+                                       g_message ("bad node =  \"%s\"",node->name);
+                               }
+                       }
+               }
+       }
+}
+
+
+/**
+ * lgl_xml_template_parse_template_node:
+ * @template_node:  libxml #xmlNodePtr template node from a #xmlDocPtr tree.
+ *
+ * Read a single glabels template from a libxml #xmlNodePtr node.
+ *
+ * Returns: a pointer to a newly created #lglTemplate structure.
+ *
+ */
+lglTemplate *
+lgl_xml_template_parse_template_node (const xmlNodePtr template_node)
+{
+       gchar                 *brand;
+        gchar                 *part;
+       gchar                 *name;
+        gchar                 *equiv_part;
+       gchar                 *description;
+       gchar                 *paper_id;
+       gdouble                page_width, page_height;
+       lglPaper              *paper = NULL;
+       lglTemplate           *template;
+       xmlNodePtr             node;
+        gchar                **v;
+        lglTemplateFrame      *frame;
+
+
+       brand = lgl_xml_get_prop_string (template_node, "brand", NULL);
+       part  = lgl_xml_get_prop_string (template_node, "part", NULL);
+        if (!brand || !part)
+        {
+                name = lgl_xml_get_prop_string (template_node, "name", NULL);
+                if (name)
+                {
+                        v = g_strsplit (name, " ", 2);
+                        brand = g_strdup (v[0]);
+                        part  = g_strchug (g_strdup (v[1]));
+                        g_free (name);
+                        g_strfreev (v);
+                        
+                }
+                else
+                {
+                       g_message ("Missing name or brand/part attributes.");
+                }
+        }
+
+
+        equiv_part = lgl_xml_get_prop_string (template_node, "equiv", NULL);
+
+
+       description = lgl_xml_get_prop_i18n_string (template_node, "description", NULL);
+       paper_id = lgl_xml_get_prop_string (template_node, "size", NULL);
+
+       if (lgl_db_is_paper_id_other (paper_id)) {
+
+               page_width = lgl_xml_get_prop_length (template_node, "width", 0);
+               page_height = lgl_xml_get_prop_length (template_node, "height", 0);
+
+       } else {
+               paper = lgl_db_lookup_paper_from_id (paper_id);
+               if (paper == NULL) {
+                       /* This should always be an id, but just in case a name
+                          slips by! */
+                       g_message ("Unknown page size id \"%s\", trying as name",
+                                  paper_id);
+                       paper = lgl_db_lookup_paper_from_name (paper_id);
+                       g_free (paper_id);
+                       paper_id = g_strdup (paper->id);
+               }
+               if (paper != NULL) {
+                       page_width  = paper->width;
+                       page_height = paper->height;
+               } else {
+                       page_width  = 612;
+                       page_height = 792;
+                       g_message ("Unknown page size id or name \"%s\"",
+                                  paper_id);
+               }
+               lgl_paper_free (paper);
+               paper = NULL;
+       }
+
+
+        if (!equiv_part)
+        {
+                template = lgl_template_new (brand, part, description,
+                                             paper_id, page_width, page_height);
+        }
+        else
+        {
+                template = lgl_template_new_from_equiv (brand, part, equiv_part);
+
+                if (!template)
+                {
+                       g_message ("Forward references not supported.");
+                        return NULL;
+                }
+        }
+
+
+       for (node = template_node->xmlChildrenNode; node != NULL;
+            node = node->next) {
+               if (lgl_xml_is_node (node, "Meta")) {
+                       xml_parse_meta_node (node, template);
+               } else if (lgl_xml_is_node (node, "Label-rectangle")) {
+                       xml_parse_label_rectangle_node (node, template);
+               } else if (lgl_xml_is_node (node, "Label-ellipse")) {
+                       xml_parse_label_ellipse_node (node, template);
+               } else if (lgl_xml_is_node (node, "Label-round")) {
+                       xml_parse_label_round_node (node, template);
+               } else if (lgl_xml_is_node (node, "Label-cd")) {
+                       xml_parse_label_cd_node (node, template);
+               } else if (lgl_xml_is_node (node, "Alias")) {
+                       xml_parse_alias_node (node, template);
+               } else {
+                       if (!xmlNodeIsText (node)) {
+                               if (!lgl_xml_is_node (node,"comment")) {
+                                       g_message ("bad node =  \"%s\"",node->name);
+                               }
+                       }
+               }
+       }
+
+       g_free (brand);
+       g_free (part);
+       g_free (equiv_part);
+       g_free (description);
+       g_free (paper_id);
+
+        /*
+         * Create a default full-page frame, if a known frame type was not found.
+         */
+        if ( template->frames == NULL )
+        {
+                g_message ("%s %s: missing valid frame node", template->brand, template->part);
+                frame = lgl_template_frame_rect_new ("0", page_width, page_height, 0, 0, 0);
+                lgl_template_frame_add_layout (frame, lgl_template_layout_new (1, 1, 0, 0, 0, 0));
+                lgl_template_add_frame (template, frame);
+        }
+
+        /*
+         * Create a default 1x1 layout, if layout is missing.
+         */
+        frame = (lglTemplateFrame *)template->frames->data;
+        if ( frame->all.layouts == NULL )
+        {
+                g_message ("%s %s: missing layout node", template->brand, template->part);
+                lgl_template_frame_add_layout (frame, lgl_template_layout_new (1, 1, 0, 0, 0, 0));
+        }
+
+       return template;
+}
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Parse XML Template->Meta Node.                                 */
+/*--------------------------------------------------------------------------*/
+static void
+xml_parse_meta_node (xmlNodePtr   meta_node,
+                    lglTemplate *template)
+{
+        gchar               *product_url;
+       gchar               *category;
+
+        product_url = lgl_xml_get_prop_string (meta_node, "product_url", NULL);
+        if ( product_url != NULL )
+        {
+                g_free (template->product_url);
+                template->product_url = product_url;
+        }
+
+       category = lgl_xml_get_prop_string (meta_node, "category", NULL);
+       if ( category != NULL )
+       {
+               lgl_template_add_category (template, category);
+               g_free (category);
+       }
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Parse XML Template->Label-rectangle Node.                      */
+/*--------------------------------------------------------------------------*/
+static void
+xml_parse_label_rectangle_node (xmlNodePtr   label_node,
+                               lglTemplate *template)
+{
+       gchar               *id;
+       gchar               *tmp;
+       gdouble              x_waste, y_waste;
+       gdouble              w, h, r;
+       lglTemplateFrame    *frame;
+       xmlNodePtr           node;
+
+       id      = lgl_xml_get_prop_string (label_node, "id", NULL);
+
+       if ((tmp = lgl_xml_get_prop_string (label_node, "waste", NULL))) {
+               /* Handle single "waste" property. */
+               x_waste = y_waste = lgl_xml_get_prop_length (label_node, "waste", 0);
+               g_free (tmp);
+       } else {
+               x_waste = lgl_xml_get_prop_length (label_node, "x_waste", 0);
+               y_waste = lgl_xml_get_prop_length (label_node, "y_waste", 0);
+       }
+
+       w       = lgl_xml_get_prop_length (label_node, "width", 0);
+       h       = lgl_xml_get_prop_length (label_node, "height", 0);
+       r       = lgl_xml_get_prop_length (label_node, "round", 0);
+
+       frame = lgl_template_frame_rect_new ((gchar *)id, w, h, r, x_waste, y_waste);
+       lgl_template_add_frame (template, frame);
+
+       for (node = label_node->xmlChildrenNode; node != NULL;
+            node = node->next) {
+               if (lgl_xml_is_node (node, "Layout")) {
+                       xml_parse_layout_node (node, frame);
+               } else if (lgl_xml_is_node (node, "Markup-margin")) {
+                       xml_parse_markup_margin_node (node, frame);
+               } else if (lgl_xml_is_node (node, "Markup-line")) {
+                       xml_parse_markup_line_node (node, frame);
+               } else if (lgl_xml_is_node (node, "Markup-circle")) {
+                       xml_parse_markup_circle_node (node, frame);
+               } else if (lgl_xml_is_node (node, "Markup-rect")) {
+                       xml_parse_markup_rect_node (node, frame);
+               } else if (lgl_xml_is_node (node, "Markup-ellipse")) {
+                       xml_parse_markup_ellipse_node (node, frame);
+               } else if (!xmlNodeIsText (node)) {
+                       if (!lgl_xml_is_node (node, "comment")) {
+                               g_message ("bad node =  \"%s\"",node->name);
+                       }
+               }
+       }
+
+       g_free (id);
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Parse XML Template->Label-ellipse Node.                        */
+/*--------------------------------------------------------------------------*/
+static void
+xml_parse_label_ellipse_node (xmlNodePtr   label_node,
+                              lglTemplate *template)
+{
+       gchar               *id;
+       gdouble              waste;
+       gdouble              w, h;
+       lglTemplateFrame    *frame;
+       xmlNodePtr           node;
+
+       id      = lgl_xml_get_prop_string (label_node, "id", NULL);
+
+       w       = lgl_xml_get_prop_length (label_node, "width", 0);
+       h       = lgl_xml_get_prop_length (label_node, "height", 0);
+        waste   = lgl_xml_get_prop_length (label_node, "waste", 0);
+
+       frame = lgl_template_frame_ellipse_new ((gchar *)id, w, h, waste);
+       lgl_template_add_frame (template, frame);
+
+       for (node = label_node->xmlChildrenNode; node != NULL;
+            node = node->next) {
+               if (lgl_xml_is_node (node, "Layout")) {
+                       xml_parse_layout_node (node, frame);
+               } else if (lgl_xml_is_node (node, "Markup-margin")) {
+                       xml_parse_markup_margin_node (node, frame);
+               } else if (lgl_xml_is_node (node, "Markup-line")) {
+                       xml_parse_markup_line_node (node, frame);
+               } else if (lgl_xml_is_node (node, "Markup-circle")) {
+                       xml_parse_markup_circle_node (node, frame);
+               } else if (lgl_xml_is_node (node, "Markup-rect")) {
+                       xml_parse_markup_rect_node (node, frame);
+               } else if (lgl_xml_is_node (node, "Markup-ellipse")) {
+                       xml_parse_markup_ellipse_node (node, frame);
+               } else if (!xmlNodeIsText (node)) {
+                       if (!lgl_xml_is_node (node, "comment")) {
+                               g_message ("bad node =  \"%s\"",node->name);
+                       }
+               }
+       }
+
+       g_free (id);
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Parse XML Template->Label-round Node.                          */
+/*--------------------------------------------------------------------------*/
+static void
+xml_parse_label_round_node (xmlNodePtr   label_node,
+                           lglTemplate *template)
+{
+       gchar               *id;
+       gdouble              waste;
+       gdouble              r;
+       lglTemplateFrame    *frame;
+       xmlNodePtr           node;
+
+       id    = lgl_xml_get_prop_string (label_node, "id", NULL);
+       waste = lgl_xml_get_prop_length (label_node, "waste", 0);
+       r     = lgl_xml_get_prop_length (label_node, "radius", 0);
+
+       frame = lgl_template_frame_round_new ((gchar *)id, r, waste);
+       lgl_template_add_frame (template, frame);
+
+       for (node = label_node->xmlChildrenNode; node != NULL;
+            node = node->next) {
+               if (lgl_xml_is_node (node, "Layout")) {
+                       xml_parse_layout_node (node, frame);
+               } else if (lgl_xml_is_node (node, "Markup-margin")) {
+                       xml_parse_markup_margin_node (node, frame);
+               } else if (lgl_xml_is_node (node, "Markup-line")) {
+                       xml_parse_markup_line_node (node, frame);
+               } else if (lgl_xml_is_node (node, "Markup-circle")) {
+                       xml_parse_markup_circle_node (node, frame);
+               } else if (lgl_xml_is_node (node, "Markup-rect")) {
+                       xml_parse_markup_rect_node (node, frame);
+               } else if (lgl_xml_is_node (node, "Markup-ellipse")) {
+                       xml_parse_markup_ellipse_node (node, frame);
+               } else if (!xmlNodeIsText (node)) {
+                       if (!lgl_xml_is_node (node, "comment")) {
+                               g_message ("bad node =  \"%s\"",node->name);
+                       }
+               }
+       }
+
+       g_free (id);
+}
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Parse XML Template->Label-cd Node.                             */
+/*--------------------------------------------------------------------------*/
+static void
+xml_parse_label_cd_node (xmlNodePtr   label_node,
+                        lglTemplate *template)
+{
+       gchar               *id;
+       gdouble              waste;
+       gdouble              r1, r2, w, h;
+       lglTemplateFrame    *frame;
+       xmlNodePtr           node;
+
+       id    = lgl_xml_get_prop_string (label_node, "id", NULL);
+       waste = lgl_xml_get_prop_length (label_node, "waste", 0);
+       r1    = lgl_xml_get_prop_length (label_node, "radius", 0);
+       r2    = lgl_xml_get_prop_length (label_node, "hole", 0);
+       w     = lgl_xml_get_prop_length (label_node, "width", 0);
+       h     = lgl_xml_get_prop_length (label_node, "height", 0);
+
+       frame = lgl_template_frame_cd_new ((gchar *)id, r1, r2, w, h, waste);
+       lgl_template_add_frame (template, frame);
+
+       for (node = label_node->xmlChildrenNode; node != NULL;
+            node = node->next) {
+               if (lgl_xml_is_node (node, "Layout")) {
+                       xml_parse_layout_node (node, frame);
+               } else if (lgl_xml_is_node (node, "Markup-margin")) {
+                       xml_parse_markup_margin_node (node, frame);
+               } else if (lgl_xml_is_node (node, "Markup-line")) {
+                       xml_parse_markup_line_node (node, frame);
+               } else if (lgl_xml_is_node (node, "Markup-circle")) {
+                       xml_parse_markup_circle_node (node, frame);
+               } else if (lgl_xml_is_node (node, "Markup-rect")) {
+                       xml_parse_markup_rect_node (node, frame);
+               } else if (lgl_xml_is_node (node, "Markup-ellipse")) {
+                       xml_parse_markup_ellipse_node (node, frame);
+               } else if (!xmlNodeIsText (node)) {
+                       if (!lgl_xml_is_node (node, "comment")) {
+                               g_message ("bad node =  \"%s\"",node->name);
+                       }
+               }
+       }
+
+       g_free (id);
+}
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Parse XML Template->Label->Layout Node.                        */
+/*--------------------------------------------------------------------------*/
+static void
+xml_parse_layout_node (xmlNodePtr          layout_node,
+                      lglTemplateFrame   *frame)
+{
+       gint        nx, ny;
+       gdouble     x0, y0, dx, dy;
+       xmlNodePtr  node;
+
+       nx = lgl_xml_get_prop_int (layout_node, "nx", 1);
+       ny = lgl_xml_get_prop_int (layout_node, "ny", 1);
+
+       x0 = lgl_xml_get_prop_length (layout_node, "x0", 0);
+       y0 = lgl_xml_get_prop_length (layout_node, "y0", 0);
+
+       dx = lgl_xml_get_prop_length (layout_node, "dx", 0);
+       dy = lgl_xml_get_prop_length (layout_node, "dy", 0);
+
+       lgl_template_frame_add_layout (frame, lgl_template_layout_new (nx, ny, x0, y0, dx, dy));
+
+       for (node = layout_node->xmlChildrenNode; node != NULL;
+            node = node->next) {
+               if (!xmlNodeIsText (node)) {
+                       if (!lgl_xml_is_node (node, "comment")) {
+                               g_message ("bad node =  \"%s\"",node->name);
+                       }
+               }
+       }
+
+}
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Parse XML Template->Label->Markup-margin Node.                 */
+/*--------------------------------------------------------------------------*/
+static void
+xml_parse_markup_margin_node (xmlNodePtr          markup_node,
+                             lglTemplateFrame   *frame)
+{
+       gdouble     size;
+       xmlNodePtr  node;
+
+       size = lgl_xml_get_prop_length (markup_node, "size", 0);
+
+       lgl_template_frame_add_markup (frame, lgl_template_markup_margin_new (size));
+
+       for (node = markup_node->xmlChildrenNode; node != NULL;
+            node = node->next) {
+               if (!xmlNodeIsText (node)) {
+                       if (!lgl_xml_is_node (node, "comment")) {
+                               g_message ("bad node =  \"%s\"",node->name);
+                       }
+               }
+       }
+
+}
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Parse XML Template->Label->Markup-line Node.                   */
+/*--------------------------------------------------------------------------*/
+static void
+xml_parse_markup_line_node (xmlNodePtr          markup_node,
+                           lglTemplateFrame   *frame)
+{
+       gdouble     x1, y1, x2, y2;
+       xmlNodePtr  node;
+
+       x1 = lgl_xml_get_prop_length (markup_node, "x1", 0);
+       y1 = lgl_xml_get_prop_length (markup_node, "y1", 0);
+       x2 = lgl_xml_get_prop_length (markup_node, "x2", 0);
+       y2 = lgl_xml_get_prop_length (markup_node, "y2", 0);
+
+       lgl_template_frame_add_markup (frame, lgl_template_markup_line_new (x1, y1, x2, y2));
+
+       for (node = markup_node->xmlChildrenNode; node != NULL;
+            node = node->next) {
+               if (!xmlNodeIsText (node)) {
+                       if (!lgl_xml_is_node (node, "comment")) {
+                               g_message ("bad node =  \"%s\"",node->name);
+                       }
+               }
+       }
+
+}
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Parse XML Template->Label->Markup-circle Node.                 */
+/*--------------------------------------------------------------------------*/
+static void
+xml_parse_markup_circle_node (xmlNodePtr          markup_node,
+                             lglTemplateFrame   *frame)
+{
+       gdouble     x0, y0, r;
+       xmlNodePtr  node;
+
+       x0 = lgl_xml_get_prop_length (markup_node, "x0", 0);
+       y0 = lgl_xml_get_prop_length (markup_node, "y0", 0);
+       r  = lgl_xml_get_prop_length (markup_node, "radius", 0);
+
+       lgl_template_frame_add_markup (frame, lgl_template_markup_circle_new (x0, y0, r));
+
+       for (node = markup_node->xmlChildrenNode; node != NULL;
+            node = node->next) {
+               if (!xmlNodeIsText (node)) {
+                       if (!lgl_xml_is_node (node, "comment")) {
+                               g_message ("bad node =  \"%s\"",node->name);
+                       }
+               }
+       }
+
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Parse XML Template->Label->Markup-rect Node.                   */
+/*--------------------------------------------------------------------------*/
+static void
+xml_parse_markup_rect_node (xmlNodePtr          markup_node,
+                           lglTemplateFrame   *frame)
+{
+       gdouble     x1, y1, w, h, r;
+       xmlNodePtr  node;
+
+       x1 = lgl_xml_get_prop_length (markup_node, "x1", 0);
+       y1 = lgl_xml_get_prop_length (markup_node, "y1", 0);
+       w  = lgl_xml_get_prop_length (markup_node, "w", 0);
+       h  = lgl_xml_get_prop_length (markup_node, "h", 0);
+       r  = lgl_xml_get_prop_length (markup_node, "r", 0);
+
+       lgl_template_frame_add_markup (frame, lgl_template_markup_rect_new (x1, y1, w, h, r));
+
+       for (node = markup_node->xmlChildrenNode; node != NULL;
+            node = node->next) {
+               if (!xmlNodeIsText (node)) {
+                       if (!lgl_xml_is_node (node, "comment")) {
+                               g_message ("bad node =  \"%s\"",node->name);
+                       }
+               }
+       }
+
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Parse XML Template->Label->Markup-ellipse Node.                */
+/*--------------------------------------------------------------------------*/
+static void
+xml_parse_markup_ellipse_node (xmlNodePtr          markup_node,
+                               lglTemplateFrame   *frame)
+{
+       gdouble     x1, y1, w, h;
+       xmlNodePtr  node;
+
+       x1 = lgl_xml_get_prop_length (markup_node, "x1", 0);
+       y1 = lgl_xml_get_prop_length (markup_node, "y1", 0);
+       w  = lgl_xml_get_prop_length (markup_node, "w", 0);
+       h  = lgl_xml_get_prop_length (markup_node, "h", 0);
+
+       lgl_template_frame_add_markup (frame, lgl_template_markup_ellipse_new (x1, y1, w, h));
+
+       for (node = markup_node->xmlChildrenNode; node != NULL;
+            node = node->next) {
+               if (!xmlNodeIsText (node)) {
+                       if (!lgl_xml_is_node (node, "comment")) {
+                               g_message ("bad node =  \"%s\"",node->name);
+                       }
+               }
+       }
+
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Parse deprecated XML Template->Alias Node.                     */
+/*--------------------------------------------------------------------------*/
+static void
+xml_parse_alias_node (xmlNodePtr   alias_node,
+                     lglTemplate *template)
+{
+        g_message ("Skipping deprecated \"Alias\" node.");
+}
+
+
+/**
+ * lgl_xml_template_write_templates_to_file:
+ * @templates:      List of #lglTemplate structures
+ * @utf8_filename:  Filename of templates file (name encoded as UTF-8)
+ *
+ * Write a list of #lglTemplate structures to a glabels XML template file.
+ *
+ * Returns: the number of bytes written or -1 in case of failure
+ *
+ */
+gint
+lgl_xml_template_write_templates_to_file (GList       *templates,
+                                          const gchar *utf8_filename)
+{
+       xmlDocPtr    doc;
+       xmlNsPtr     ns;
+       gint         bytes_written;
+       GList       *p;
+       lglTemplate *template;
+       gchar       *filename;
+
+       doc = xmlNewDoc ((xmlChar *)"1.0");
+       doc->xmlRootNode = xmlNewDocNode (doc, NULL, (xmlChar *)"Glabels-templates", NULL);
+
+       ns = xmlNewNs (doc->xmlRootNode, (xmlChar *)LGL_XML_NAME_SPACE, NULL);
+       xmlSetNs (doc->xmlRootNode, ns);
+
+       for (p=templates; p!=NULL; p=p->next) {
+               template = (lglTemplate *)p->data;
+               lgl_xml_template_create_template_node (template, doc->xmlRootNode, ns);
+       }
+
+       filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
+       if (!filename)
+        {
+               g_message ("Utf8 conversion error.");
+                return -1;
+        }
+       else
+        {
+               xmlSetDocCompressMode (doc, 0);
+               bytes_written = xmlSaveFormatFile (filename, doc, TRUE);
+               xmlFreeDoc (doc);
+               g_free (filename);
+                return bytes_written;
+       }
+
+}
+
+
+/**
+ * lgl_xml_template_write_template_to_file:
+ * @template:       #lglTemplate structure to be written
+ * @utf8_filename:  Filename of templates file (name encoded as UTF-8)
+ *
+ * Write a single #lglTemplate structures to a glabels XML template file.
+ *
+ * Returns: the number of bytes written or -1 in case of failure
+ *
+ */
+gint
+lgl_xml_template_write_template_to_file (const lglTemplate  *template,
+                                         const gchar        *utf8_filename)
+{
+       GList     *templates = NULL;
+       gint       bytes_written;
+
+       templates = g_list_append (templates, (gpointer)template);
+
+       bytes_written = lgl_xml_template_write_templates_to_file (templates, utf8_filename);
+
+       g_list_free (templates);
+
+        return bytes_written;
+}
+
+
+/**
+ * lgl_xml_template_create_template_node:
+ * @template:       #lglTemplate structure to be written
+ * @root:           parent node to receive new child node
+ * @ns:             a libxml #xmlNsPtr
+ *
+ * Add a single #lglTemplate child node to given #xmlNodePtr.
+ *
+ */
+void
+lgl_xml_template_create_template_node (const lglTemplate *template,
+                                       xmlNodePtr         root,
+                                       const xmlNsPtr     ns)
+{
+       xmlNodePtr          node;
+       GList              *p;
+       lglTemplateFrame   *frame;
+
+       node = xmlNewChild (root, ns, (xmlChar *)"Template", NULL);
+
+       lgl_xml_set_prop_string (node, "brand", template->brand);
+       lgl_xml_set_prop_string (node, "part", template->part);
+
+       lgl_xml_set_prop_string (node, "size", template->paper_id);
+       if (xmlStrEqual ((xmlChar *)template->paper_id, (xmlChar *)"Other"))
+        {
+
+               lgl_xml_set_prop_length (node, "width", template->page_width);
+               lgl_xml_set_prop_length (node, "height", template->page_height);
+
+       }
+
+       lgl_xml_set_prop_string (node, "description", template->description);
+
+        xml_create_meta_node ("product_url", template->product_url, node, ns );
+       for ( p=template->category_ids; p != NULL; p=p->next )
+        {
+                xml_create_meta_node ( "category", p->data, node, ns );
+       }
+       for ( p=template->frames; p != NULL; p=p->next )
+        {
+               frame = (lglTemplateFrame *)p->data;
+               xml_create_label_node (frame, node, ns);
+       }
+
+}
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Add XML Template->Meta Node with category.                     */
+/*--------------------------------------------------------------------------*/
+static void
+xml_create_meta_node (const gchar      *attr,
+                      const gchar      *value,
+                      xmlNodePtr        root,
+                      const xmlNsPtr    ns)
+{
+       xmlNodePtr node;
+
+        if ( value != NULL )
+        {
+                node = xmlNewChild (root, ns, (xmlChar *)"Meta", NULL);
+                lgl_xml_set_prop_string (node, attr, value);
+        }
+
+}
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Add XML Template->Label Node.                                  */
+/*--------------------------------------------------------------------------*/
+static void
+xml_create_label_node (const lglTemplateFrame  *frame,
+                      xmlNodePtr               root,
+                      const xmlNsPtr           ns)
+{
+       xmlNodePtr        node;
+       GList            *p;
+       lglTemplateMarkup *markup;
+       lglTemplateLayout *layout;
+
+       switch (frame->shape) {
+
+       case LGL_TEMPLATE_FRAME_SHAPE_RECT:
+               node = xmlNewChild(root, ns, (xmlChar *)"Label-rectangle", NULL);
+               lgl_xml_set_prop_string (node, "id",      frame->all.id);
+               lgl_xml_set_prop_length (node, "width",   frame->rect.w);
+               lgl_xml_set_prop_length (node, "height",  frame->rect.h);
+               lgl_xml_set_prop_length (node, "round",   frame->rect.r);
+               lgl_xml_set_prop_length (node, "x_waste", frame->rect.x_waste);
+               lgl_xml_set_prop_length (node, "y_waste", frame->rect.y_waste);
+               break;
+
+       case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
+               node = xmlNewChild(root, ns, (xmlChar *)"Label-ellipse", NULL);
+               lgl_xml_set_prop_string (node, "id",     frame->all.id);
+               lgl_xml_set_prop_length (node, "width",  frame->ellipse.w);
+               lgl_xml_set_prop_length (node, "height", frame->ellipse.h);
+               lgl_xml_set_prop_length (node, "waste",  frame->ellipse.waste);
+               break;
+
+       case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
+               node = xmlNewChild(root, ns, (xmlChar *)"Label-round", NULL);
+               lgl_xml_set_prop_string (node, "id",      frame->all.id);
+               lgl_xml_set_prop_length (node, "radius",  frame->round.r);
+               lgl_xml_set_prop_length (node, "waste",   frame->round.waste);
+               break;
+
+       case LGL_TEMPLATE_FRAME_SHAPE_CD:
+               node = xmlNewChild(root, ns, (xmlChar *)"Label-cd", NULL);
+               lgl_xml_set_prop_string (node, "id",     frame->all.id);
+               lgl_xml_set_prop_length (node, "radius", frame->cd.r1);
+               lgl_xml_set_prop_length (node, "hole",   frame->cd.r2);
+               if (frame->cd.w != 0.0) {
+                       lgl_xml_set_prop_length (node, "width",  frame->cd.w);
+               }
+               if (frame->cd.h != 0.0) {
+                       lgl_xml_set_prop_length (node, "height", frame->cd.h);
+               }
+               lgl_xml_set_prop_length (node, "waste",  frame->cd.waste);
+               break;
+
+       default:
+               g_message ("Unknown label style");
+               return;
+               break;
+
+       }
+
+       for ( p=frame->all.markups; p != NULL; p=p->next ) {
+               markup = (lglTemplateMarkup *)p->data;
+               switch (markup->type) {
+               case LGL_TEMPLATE_MARKUP_MARGIN:
+                       xml_create_markup_margin_node (markup, node, ns);
+                       break;
+               case LGL_TEMPLATE_MARKUP_LINE:
+                       xml_create_markup_line_node (markup, node, ns);
+                       break;
+               case LGL_TEMPLATE_MARKUP_CIRCLE:
+                       xml_create_markup_circle_node (markup, node, ns);
+                       break;
+               case LGL_TEMPLATE_MARKUP_RECT:
+                       xml_create_markup_rect_node (markup, node, ns);
+                       break;
+               case LGL_TEMPLATE_MARKUP_ELLIPSE:
+                       xml_create_markup_ellipse_node (markup, node, ns);
+                       break;
+               default:
+                       g_message ("Unknown markup type");
+                       break;
+               }
+       }
+
+       for ( p=frame->all.layouts; p != NULL; p=p->next ) {
+               layout = (lglTemplateLayout *)p->data;
+               xml_create_layout_node (layout, node, ns);
+       }
+
+}
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Add XML Template->Label->Layout Node.                          */
+/*--------------------------------------------------------------------------*/
+static void
+xml_create_layout_node (const lglTemplateLayout *layout,
+                       xmlNodePtr               root,
+                       const xmlNsPtr           ns)
+{
+       xmlNodePtr  node;
+
+       node = xmlNewChild(root, ns, (xmlChar *)"Layout", NULL);
+       lgl_xml_set_prop_int (node, "nx", layout->nx);
+       lgl_xml_set_prop_int (node, "ny", layout->ny);
+       lgl_xml_set_prop_length (node, "x0", layout->x0);
+       lgl_xml_set_prop_length (node, "y0", layout->y0);
+       lgl_xml_set_prop_length (node, "dx", layout->dx);
+       lgl_xml_set_prop_length (node, "dy", layout->dy);
+
+}
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Add XML Template->Label->Markup-margin Node.                   */
+/*--------------------------------------------------------------------------*/
+static void
+xml_create_markup_margin_node (const lglTemplateMarkup  *markup,
+                              xmlNodePtr                root,
+                              const xmlNsPtr            ns)
+{
+       xmlNodePtr  node;
+
+       node = xmlNewChild(root, ns, (xmlChar *)"Markup-margin", NULL);
+
+       lgl_xml_set_prop_length (node, "size", markup->margin.size);
+
+}
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Add XML Template->Label->Markup-line Node.                     */
+/*--------------------------------------------------------------------------*/
+static void
+xml_create_markup_line_node (const lglTemplateMarkup *markup,
+                            xmlNodePtr               root,
+                            const xmlNsPtr           ns)
+{
+       xmlNodePtr  node;
+
+       node = xmlNewChild(root, ns, (xmlChar *)"Markup-line", NULL);
+
+       lgl_xml_set_prop_length (node, "x1", markup->line.x1);
+       lgl_xml_set_prop_length (node, "y1", markup->line.y1);
+       lgl_xml_set_prop_length (node, "x2", markup->line.x2);
+       lgl_xml_set_prop_length (node, "y2", markup->line.y2);
+
+}
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Add XML Template->Label->Markup-circle Node.                   */
+/*--------------------------------------------------------------------------*/
+static void
+xml_create_markup_circle_node (const lglTemplateMarkup *markup,
+                              xmlNodePtr               root,
+                              const xmlNsPtr           ns)
+{
+       xmlNodePtr  node;
+
+       node = xmlNewChild(root, ns, (xmlChar *)"Markup-circle", NULL);
+
+       lgl_xml_set_prop_length (node, "x0",     markup->circle.x0);
+       lgl_xml_set_prop_length (node, "y0",     markup->circle.y0);
+       lgl_xml_set_prop_length (node, "radius", markup->circle.r);
+
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Add XML Template->Label->Markup-rect Node.                     */
+/*--------------------------------------------------------------------------*/
+static void
+xml_create_markup_rect_node (const lglTemplateMarkup *markup,
+                            xmlNodePtr               root,
+                            const xmlNsPtr           ns)
+{
+       xmlNodePtr  node;
+
+       node = xmlNewChild(root, ns, (xmlChar *)"Markup-rect", NULL);
+
+       lgl_xml_set_prop_length (node, "x1", markup->rect.x1);
+       lgl_xml_set_prop_length (node, "y1", markup->rect.y1);
+       lgl_xml_set_prop_length (node, "w",  markup->rect.w);
+       lgl_xml_set_prop_length (node, "h",  markup->rect.h);
+       lgl_xml_set_prop_length (node, "r",  markup->rect.r);
+
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Add XML Template->Label->Markup-ellipse Node.                  */
+/*--------------------------------------------------------------------------*/
+static void
+xml_create_markup_ellipse_node (const lglTemplateMarkup *markup,
+                                xmlNodePtr               root,
+                                const xmlNsPtr           ns)
+{
+       xmlNodePtr  node;
+
+       node = xmlNewChild(root, ns, (xmlChar *)"Markup-ellipse", NULL);
+
+       lgl_xml_set_prop_length (node, "x1", markup->ellipse.x1);
+       lgl_xml_set_prop_length (node, "y1", markup->ellipse.y1);
+       lgl_xml_set_prop_length (node, "w",  markup->ellipse.w);
+       lgl_xml_set_prop_length (node, "h",  markup->ellipse.h);
+
+}
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-xml-template.h b/libglabels/lgl-xml-template.h
new file mode 100644 (file)
index 0000000..99b52d3
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *  lgl-xml-template.h
+ *  Copyright (C) 2001-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LGL_XML_TEMPLATE_H__
+#define __LGL_XML_TEMPLATE_H__
+
+#include <glib.h>
+#include <libxml/tree.h>
+
+#include "lgl-template.h"
+
+G_BEGIN_DECLS
+
+void         lgl_xml_template_read_templates_from_file (const gchar       *utf8_filename);
+
+void         lgl_xml_template_parse_templates_doc      (const xmlDocPtr    templates_doc);
+
+lglTemplate *lgl_xml_template_parse_template_node      (const xmlNodePtr   template_node);
+
+
+gint         lgl_xml_template_write_templates_to_file  (GList             *templates,
+                                                       const gchar       *utf8_filename);
+
+gint         lgl_xml_template_write_template_to_file   (const lglTemplate *template,
+                                                       const gchar       *utf8_filename);
+
+void         lgl_xml_template_create_template_node     (const lglTemplate *template,
+                                                       xmlNodePtr         root,
+                                                       const xmlNsPtr     ns);
+
+G_END_DECLS
+
+#endif /* __LGL_XML_TEMPLATE_H__ */
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-xml-vendor.c b/libglabels/lgl-xml-vendor.c
new file mode 100644 (file)
index 0000000..cc44bc8
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ *  lgl-xml-vendor.c
+ *  Copyright (C) 2003-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "lgl-xml-vendor.h"
+
+#include <glib/gi18n.h>
+#include <glib.h>
+#include <string.h>
+#include <libintl.h>
+
+#include "libglabels-private.h"
+
+#include "lgl-xml.h"
+
+/*===========================================*/
+/* Private types                             */
+/*===========================================*/
+
+/*===========================================*/
+/* Private globals                           */
+/*===========================================*/
+
+/*===========================================*/
+/* Local function prototypes                 */
+/*===========================================*/
+
+
+/**
+ * lgl_xml_vendor_read_vendors_from_file:
+ * @utf8_filename:       Filename of vendors file (name encoded as UTF-8)
+ *
+ * Read vendor definitions from a file.
+ *
+ * Returns: a list of #lglVendor structures.
+ *
+ */
+GList *
+lgl_xml_vendor_read_vendors_from_file (gchar *utf8_filename)
+{
+       gchar      *filename;
+       GList      *vendors;
+       xmlDocPtr   vendors_doc;
+
+       LIBXML_TEST_VERSION;
+
+       filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
+       if (!filename) {
+               g_message ("Utf8 filename conversion error");
+               return NULL;
+       }
+
+       vendors_doc = xmlParseFile (filename);
+       if (!vendors_doc) {
+               g_message ("\"%s\" is not a glabels vendor file (not XML)",
+                          filename);
+               return NULL;
+       }
+
+       vendors = lgl_xml_vendor_parse_vendors_doc (vendors_doc);
+
+       g_free (filename);
+       xmlFreeDoc (vendors_doc);
+
+       return vendors;
+}
+
+
+/**
+ * lgl_xml_vendor_parse_vendors_doc:
+ * @vendors_doc:  libxml #xmlDocPtr tree, representing a vendors definition file.
+ *
+ * Read vendor definitions from a libxml #xmlDocPtr tree.
+ *
+ * Returns: a list of #lglVendor structures.
+ *
+ */
+GList *
+lgl_xml_vendor_parse_vendors_doc (xmlDocPtr  vendors_doc)
+{
+       GList       *vendors = NULL;
+       xmlNodePtr   root, node;
+       lglVendor   *vendor;
+
+       LIBXML_TEST_VERSION;
+
+       root = xmlDocGetRootElement (vendors_doc);
+       if (!root || !root->name) {
+               g_message ("\"%s\" is not a glabels vendor file (no root node)",
+                          vendors_doc->name);
+               xmlFreeDoc (vendors_doc);
+               return vendors;
+       }
+       if (!lgl_xml_is_node (root, "Glabels-vendors")) {
+               g_message ("\"%s\" is not a glabels vendor file (wrong root node)",
+                          vendors_doc->name);
+               xmlFreeDoc (vendors_doc);
+               return vendors;
+       }
+
+       for (node = root->xmlChildrenNode; node != NULL; node = node->next) {
+
+               if (lgl_xml_is_node (node, "Vendor")) {
+                       vendor = lgl_xml_vendor_parse_vendor_node (node);
+                       vendors = g_list_append (vendors, vendor);
+               } else {
+                       if ( !xmlNodeIsText(node) ) {
+                               if (!lgl_xml_is_node (node, "comment")) {
+                                       g_message ("bad node =  \"%s\"",node->name);
+                               }
+                       }
+               }
+       }
+
+       return vendors;
+}
+
+
+/**
+ * lgl_xml_vendor_parse_vendor_node:
+ * @vendor_node:  libxml #xmlNodePtr vendor node from a #xmlDocPtr tree.
+ *
+ * Read a single vendor definition from a libxml #xmlNodePtr node.
+ *
+ * Returns: a pointer to a newly created #lglVendor structure.
+ *
+ */
+lglVendor *
+lgl_xml_vendor_parse_vendor_node (xmlNodePtr vendor_node)
+{
+       lglVendor             *vendor;
+       gchar                 *name;
+
+       LIBXML_TEST_VERSION;
+
+       name = lgl_xml_get_prop_i18n_string (vendor_node, "name", NULL);
+
+       vendor = lgl_vendor_new (name);
+
+        vendor->url = lgl_xml_get_prop_i18n_string (vendor_node, "url", NULL);
+
+       g_free (name);
+
+       return vendor;
+}
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-xml-vendor.h b/libglabels/lgl-xml-vendor.h
new file mode 100644 (file)
index 0000000..0aac3b7
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *  lgl-xml-vendor.h
+ *  Copyright (C) 2003-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LGL_XML_VENDOR_H__
+#define __LGL_XML_VENDOR_H__
+
+#include <glib.h>
+#include <libxml/tree.h>
+
+#include "lgl-vendor.h"
+
+G_BEGIN_DECLS
+
+GList       *lgl_xml_vendor_read_vendors_from_file (gchar        *utf8_filename);
+
+GList       *lgl_xml_vendor_parse_vendors_doc      (xmlDocPtr     vendors_doc);
+
+lglVendor   *lgl_xml_vendor_parse_vendor_node      (xmlNodePtr    vendor_node);
+
+
+G_END_DECLS
+
+#endif /* __LGL_XML_VENDOR_H__ */
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-xml.c b/libglabels/lgl-xml.c
new file mode 100644 (file)
index 0000000..8a09019
--- /dev/null
@@ -0,0 +1,514 @@
+/*
+ *  lgl-xml.c
+ *  Copyright (C) 2003-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "lgl-xml.h"
+
+#include <glib/gi18n.h>
+#include <glib.h>
+#include <string.h>
+
+#include "libglabels-private.h"
+
+
+/*========================================================*/
+/* Private macros and constants.                          */
+/*========================================================*/
+
+/*========================================================*/
+/* Private types.                                         */
+/*========================================================*/
+
+/*========================================================*/
+/* Private globals.                                       */
+/*========================================================*/
+
+static lglUnits  default_units        = LGL_UNITS_POINT;
+
+
+/****************************************************************************/
+
+/**
+ * lgl_xml_get_prop_string:
+ * @node:        the libxml2 #xmlNodePtr of the node
+ * @property:    the property name
+ * @default_val: a default value to return if property not found
+ *
+ * Return value of property as a string.
+ *
+ * Returns: the property as a pointer to a gchar string.  This string should
+ *          be freed with g_free().
+ *
+ */
+gchar *
+lgl_xml_get_prop_string (xmlNodePtr   node,
+                        const gchar *property,
+                        const gchar *default_val)
+{
+       gchar   *val;
+       xmlChar *string;
+
+       string = xmlGetProp (node, (xmlChar *)property);
+       if ( string != NULL ) {
+               val = g_strdup ((gchar *)string);
+               xmlFree (string);
+               return val;
+       }
+
+       if (default_val) {
+               return g_strdup (default_val);
+       }
+
+       return NULL;
+}
+
+
+/**
+ * lgl_xml_get_prop_i18n_string:
+ * @node:        the libxml2 #xmlNodePtr of the node
+ * @property:    the property name
+ * @default_val: a default value to return if property not found
+ *
+ * Return value of a translatable property as a string.
+ *
+ * Returns: the property as a pointer to a gchar string.  This string should
+ *          be freed with g_free().
+ *
+ */
+gchar *
+lgl_xml_get_prop_i18n_string (xmlNodePtr   node,
+                             const gchar *property,
+                             const gchar *default_val)
+{
+       gchar   *_property;
+       gchar   *val;
+       xmlChar *string;
+
+       _property = g_strdup_printf ("_%s", property);
+       string = xmlGetProp (node, (xmlChar *)_property);
+       g_free (_property);
+
+       if ( string != NULL ) {
+
+               val = g_strdup (gettext ((char *)string));
+               xmlFree (string);
+               return val;
+
+       }
+
+       string = xmlGetProp (node, (xmlChar *)property);
+       if ( string != NULL ) {
+               val = g_strdup ((gchar *)string);
+               xmlFree (string);
+               return val;
+       }
+
+       if (default_val) {
+               return g_strdup (default_val);
+       }
+
+       return NULL;
+}
+
+
+/**
+ * lgl_xml_get_prop_double:
+ * @node:        the libxml2 #xmlNodePtr of the node
+ * @property:    the property name
+ * @default_val: a default value to return if property not found
+ *
+ * Return value of property as a double.
+ *
+ * Returns: the property as a double.
+ *
+ */
+gdouble
+lgl_xml_get_prop_double (xmlNodePtr   node,
+                        const gchar *property,
+                        gdouble      default_val)
+{
+       gdouble  val;
+       xmlChar *string;
+
+       string = xmlGetProp (node, (xmlChar *)property);
+       if ( string != NULL ) {
+               val = g_strtod ((gchar *)string, NULL);
+               xmlFree (string);
+               return val;
+       }
+
+       return default_val;
+}
+
+
+/**
+ * lgl_xml_get_prop_boolean:
+ * @node:        the libxml2 #xmlNodePtr of the node
+ * @property:    the property name
+ * @default_val: a default value to return if property not found
+ *
+ * Return value of property as a boolean.
+ *
+ * Returns: the property as a boolean.
+ *
+ */
+gboolean
+lgl_xml_get_prop_boolean (xmlNodePtr   node,
+                        const gchar *property,
+                        gboolean     default_val)
+{
+       gboolean  val;
+       xmlChar  *string;
+
+       string = xmlGetProp (node, (xmlChar *)property);
+       if ( string != NULL ) {
+               val = !((xmlStrcasecmp (string, (xmlChar *)"false") == 0) ||
+                       xmlStrEqual (string, (xmlChar *)"0"));;
+               xmlFree (string);
+               return val;
+       }
+
+       return default_val;
+}
+
+
+/**
+ * lgl_xml_get_prop_int:
+ * @node:        the libxml2 #xmlNodePtr of the node
+ * @property:    the property name
+ * @default_val: a default value to return if property not found
+ *
+ * Return value of property as an integer.
+ *
+ * Returns: the property as an integer.
+ *
+ */
+gint
+lgl_xml_get_prop_int (xmlNodePtr   node,
+                     const gchar *property,
+                     gint         default_val)
+{
+       gint     val;
+       xmlChar *string;
+
+       string = xmlGetProp (node, (xmlChar *)property);
+       if ( string != NULL ) {
+               val = strtol ((char *)string, NULL, 0);
+               xmlFree (string);
+               return val;
+       }
+
+       return default_val;
+}
+
+
+/**
+ * lgl_xml_get_prop_uint:
+ * @node:        the libxml2 #xmlNodePtr of the node
+ * @property:    the property name
+ * @default_val: a default value to return if property not found
+ *
+ * Return value of property (usually formatted in hex) as an unsigned integer.
+ *
+ * Returns: the property as an unsigned integer.
+ *
+ */
+guint
+lgl_xml_get_prop_uint (xmlNodePtr   node,
+                      const gchar *property,
+                      guint        default_val)
+{
+       guint    val;
+       xmlChar *string;
+
+       string = xmlGetProp (node, (xmlChar *)property);
+       if ( string != NULL ) {
+               val = strtoul ((char *)string, NULL, 0);
+               xmlFree (string);
+               return val;
+       }
+
+       return default_val;
+}
+
+
+/**
+ * lgl_xml_get_prop_length:
+ * @node:        the libxml2 #xmlNodePtr of the node
+ * @property:    the property name
+ * @default_val: a default value to return if property not found
+ *
+ * Return value of a length property as a double, converting to internal
+ * units (points).  The property is expected to be formatted as a number
+ * followed by a units string.  If there is no units string, the length
+ * is assumed to be in points.  Valid units strings are "pt" for points,
+ * "in" for inches, "mm" for millimeters, "cm" for centimeters, and
+ * "pc" for picas.
+ *
+ * Returns: the length in points.
+ *
+ */
+gdouble
+lgl_xml_get_prop_length (xmlNodePtr   node,
+                        const gchar *property,
+                        gdouble      default_val)
+{
+       gdouble  val;
+       xmlChar *string;
+       xmlChar *unit_id;
+        lglUnits units;
+
+       string = xmlGetProp (node, (xmlChar *)property);
+       if ( string != NULL ) {
+
+               val = g_strtod ((gchar *)string, (gchar **)&unit_id);
+
+               if (unit_id != string) {
+                       unit_id = (xmlChar *)g_strchug ((gchar *)unit_id);
+                        units = lgl_units_from_id ((gchar *)unit_id);
+                        if (units != LGL_UNITS_INVALID)
+                        {
+                                val *= lgl_units_get_points_per_unit (units);
+                        }
+                        else
+                        {
+                                g_message ("Line %ld, Node \"%s\", Property \"%s\": Unknown unit \"%s\", assuming points",
+                                           xmlGetLineNo (node), node->name, property, unit_id);
+                        }
+               }
+               else {
+                       val = 0.0;
+               }
+
+               xmlFree (string);
+               return val;
+       }
+
+       return default_val;
+}
+
+
+/**
+ * lgl_xml_set_prop_string:
+ * @node:        the libxml2 #xmlNodePtr of the node
+ * @property:    the property name
+ * @val:         the value to set
+ *
+ * Set a property from a string.
+ *
+ */
+void
+lgl_xml_set_prop_string (xmlNodePtr    node,
+                        const gchar  *property,
+                        const gchar  *val)
+{
+       if (val != NULL) {
+               xmlSetProp (node, (xmlChar *)property, (xmlChar *)val);
+       }
+}
+
+
+/**
+ * lgl_xml_set_prop_double:
+ * @node:        the libxml2 #xmlNodePtr of the node
+ * @property:    the property name
+ * @val:         the value to set
+ *
+ * Set a property from a double.
+ *
+ */
+void
+lgl_xml_set_prop_double (xmlNodePtr    node,
+                        const gchar  *property,
+                        gdouble       val)
+{
+       gchar  *string, buffer[G_ASCII_DTOSTR_BUF_SIZE];
+
+       /* Guarantee "C" locale by use of g_ascii_formatd */
+       string = g_ascii_formatd (buffer, G_ASCII_DTOSTR_BUF_SIZE, "%g", val);
+
+       xmlSetProp (node, (xmlChar *)property, (xmlChar *)string);
+}
+
+
+/**
+ * lgl_xml_set_prop_boolean:
+ * @node:        the libxml2 #xmlNodePtr of the node
+ * @property:    the property name
+ * @val:         the value to set
+ *
+ * Set a property from a boolean.
+ *
+ */
+void
+lgl_xml_set_prop_boolean (xmlNodePtr    node,
+                         const gchar  *property,
+                         gboolean      val)
+{
+       xmlSetProp (node, (xmlChar *)property, (xmlChar *)(val ? "True" : "False"));
+}
+
+/**
+ * lgl_xml_set_prop_int:
+ * @node:        the libxml2 #xmlNodePtr of the node
+ * @property:    the property name
+ * @val:         the value to set
+ *
+ * Set a property from an integer.
+ *
+ */
+void
+lgl_xml_set_prop_int (xmlNodePtr    node,
+                     const gchar  *property,
+                     gint          val)
+{
+       gchar  *string;
+
+       string = g_strdup_printf ("%d", val);
+       xmlSetProp (node, (xmlChar *)property, (xmlChar *)string);
+       g_free (string);
+}
+
+/**
+ * lgl_xml_set_prop_uint_hex:
+ * @node:        the libxml2 #xmlNodePtr of the node
+ * @property:    the property name
+ * @val:         the value to set
+ *
+ * Set a property from an unsigned integer and format in hex.
+ *
+ */
+void
+lgl_xml_set_prop_uint_hex (xmlNodePtr    node,
+                          const gchar  *property,
+                          guint         val)
+{
+       gchar  *string;
+
+       string = g_strdup_printf ("0x%08x", val);
+       xmlSetProp (node, (xmlChar *)property, (xmlChar *)string);
+       g_free (string);
+}
+
+/**
+ * lgl_xml_set_prop_length:
+ * @node:        the libxml2 #xmlNodePtr of the node
+ * @property:    the property name
+ * @val:         the length to set in internal units (points)
+ *
+ * Set a property from a length, performing any necessary conversion.
+ * Length properties are formatted as a number followed by a units string.
+ * The units of the formatted property is determined by the most recent call to
+ * lgl_xml_set_default_units().
+ *
+ */
+void
+lgl_xml_set_prop_length (xmlNodePtr    node,
+                        const gchar  *property,
+                        gdouble       val)
+{
+       gchar  *string, buffer[G_ASCII_DTOSTR_BUF_SIZE];
+       gchar  *string_unit;
+
+       /* Convert to default units */
+       val *= lgl_units_get_units_per_point (default_units);
+
+       /* Guarantee "C" locale by use of g_ascii_formatd */
+       string = g_ascii_formatd (buffer, G_ASCII_DTOSTR_BUF_SIZE, "%g", val);
+
+       string_unit = g_strdup_printf ("%s%s", string, lgl_units_get_id (default_units));
+       xmlSetProp (node, (xmlChar *)property, (xmlChar *)string_unit);
+        g_free (string_unit);
+}
+
+/**
+ * lgl_xml_is_node
+ * @node:        the libxml2 #xmlNodePtr of the node
+ * @name    :    the node name
+ *
+ * Test if a node name matches given name.
+ *
+ * Returns: TRUE if the name of the node matches.  Otherwise FALSE.
+ *
+ */
+gboolean
+lgl_xml_is_node (xmlNodePtr   node,
+                const gchar *name)
+{
+       return xmlStrEqual (node->name, (xmlChar *)name);
+}
+
+
+/**
+ * lgl_xml_get_node_content
+ * @node:        the libxml2 #xmlNodePtr of the node
+ *
+ * Get the content of a node.
+ *
+ * Returns: the property as a pointer to a gchar string.  This string should
+ *          be freed with g_free().
+ */
+gchar *
+lgl_xml_get_node_content (xmlNodePtr   node)
+{
+       xmlChar *xml_content;
+       gchar   *g_content;
+
+       xml_content = xmlNodeGetContent (node);
+
+       if (xml_content != NULL) {
+
+               g_content = g_strdup ((gchar *)xml_content);
+               xmlFree (xml_content);
+               return g_content;
+
+       }
+
+       return NULL;
+}
+
+
+/**
+ * lgl_xml_set_default_units:
+ * @units:       default units selection (#lglUnits)
+ *
+ * Set the default units when formatting lengths.  See
+ * lgl_xml_set_prop_length().
+ *
+ */
+void
+lgl_xml_set_default_units (lglUnits   units)
+{
+       g_return_if_fail ((units >= LGL_UNITS_FIRST) && (units <= LGL_UNITS_LAST));
+
+       default_units = units;
+}
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/libglabels/lgl-xml.h b/libglabels/lgl-xml.h
new file mode 100644 (file)
index 0000000..8bae243
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ *  lgl-xml.h
+ *  Copyright (C) 2003-2010  Jim Evins <evins@snaught.com>.
+ *
+ *  This file is part of libglabels.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LGL_XML_H__
+#define __LGL_XML_H__
+
+#include <glib.h>
+#include <libxml/tree.h>
+
+#include "lgl-units.h"
+
+#define LGL_XML_NAME_SPACE "http://glabels.org/xmlns/2.3/"
+
+G_BEGIN_DECLS
+
+/*
+ * Get property functions
+ */
+gchar *  lgl_xml_get_prop_string   (xmlNodePtr    node,
+                                   const gchar  *property,
+                                   const gchar  *default_val);
+
+gchar *  lgl_xml_get_prop_i18n_string (xmlNodePtr    node,
+                                      const gchar  *property,
+                                      const gchar  *default_val);
+
+gdouble  lgl_xml_get_prop_double   (xmlNodePtr    node,
+                                   const gchar  *property,
+                                   gdouble       default_val);
+
+gboolean lgl_xml_get_prop_boolean  (xmlNodePtr    node,
+                                   const gchar  *property,
+                                   gboolean      default_val);
+
+gint     lgl_xml_get_prop_int      (xmlNodePtr    node,
+                                   const gchar  *property,
+                                   gint          default_val);
+
+guint    lgl_xml_get_prop_uint     (xmlNodePtr    node,
+                                   const gchar  *property,
+                                   guint         default_val);
+
+gdouble  lgl_xml_get_prop_length   (xmlNodePtr    node,
+                                   const gchar  *property,
+                                   gdouble       default_val);
+
+
+/*
+ * Set property functions
+ */
+void     lgl_xml_set_prop_string   (xmlNodePtr    node,
+                                   const gchar  *property,
+                                   const gchar  *val);
+
+void     lgl_xml_set_prop_double   (xmlNodePtr    node,
+                                   const gchar  *property,
+                                   gdouble       val);
+
+void     lgl_xml_set_prop_boolean  (xmlNodePtr    node,
+                                   const gchar  *property,
+                                   gboolean      val);
+
+void     lgl_xml_set_prop_int      (xmlNodePtr    node,
+                                   const gchar  *property,
+                                   gint          val);
+
+void     lgl_xml_set_prop_uint_hex (xmlNodePtr    node,
+                                   const gchar  *property,
+                                   guint         val);
+
+void     lgl_xml_set_prop_length   (xmlNodePtr    node,
+                                   const gchar  *property,
+                                   gdouble       val);
+
+/*
+ * Other node functions
+ */
+gboolean lgl_xml_is_node           (xmlNodePtr    node,
+                                   const gchar  *name);
+
+gchar *  lgl_xml_get_node_content  (xmlNodePtr    node);
+
+/*
+ * Misc functions
+ */
+void     lgl_xml_set_default_units (lglUnits      units);
+
+G_END_DECLS
+
+
+#endif /* __LGL_XML_H__ */
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
index 726c80391e50cf802710ad830cdcd7e10e72f58d..43ea4cd4443232223a1a135b27ced17e3367e07a 100644 (file)
@@ -23,8 +23,8 @@
 
 #include <glib.h>
 
-#include "str.h"
-#include "template.h"
+#include "lgl-str.h"
+#include "lgl-template.h"
 
 #undef  G_LOG_DOMAIN
 #define G_LOG_DOMAIN "LibGlabels"
index 6d456700b133ff7256a93bb9590e5f38d6624c67..222670ca8a8c1d277fe88289318ce4f7b0b5c7ca 100644 (file)
 #ifndef __LIBGLABELS_H__
 #define __LIBGLABELS_H__
 
-#include <libglabels/db.h>
-#include <libglabels/paper.h>
-#include <libglabels/category.h>
-#include <libglabels/template.h>
-#include <libglabels/units.h>
-#include <libglabels/str.h>
-#include <libglabels/xml-paper.h>
-#include <libglabels/xml-category.h>
-#include <libglabels/xml-template.h>
-#include <libglabels/xml.h>
+#include <libglabels/lgl-db.h>
+#include <libglabels/lgl-paper.h>
+#include <libglabels/lgl-category.h>
+#include <libglabels/lgl-template.h>
+#include <libglabels/lgl-units.h>
+#include <libglabels/lgl-str.h>
+#include <libglabels/lgl-xml-paper.h>
+#include <libglabels/lgl-xml-category.h>
+#include <libglabels/lgl-xml-template.h>
+#include <libglabels/lgl-xml.h>
 
 #endif /* __LIBGLABELS_H__ */
 
diff --git a/libglabels/paper.c b/libglabels/paper.c
deleted file mode 100644 (file)
index d0b80fb..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- *  paper.c
- *  Copyright (C) 2003-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-
-#include "paper.h"
-
-#include <glib/gi18n.h>
-#include <glib.h>
-#include <string.h>
-
-#include "libglabels-private.h"
-
-/*===========================================*/
-/* Private types                             */
-/*===========================================*/
-
-
-/*===========================================*/
-/* Private globals                           */
-/*===========================================*/
-
-
-/*===========================================*/
-/* Local function prototypes                 */
-/*===========================================*/
-
-
-/*===========================================*/
-/* Functions.                                */
-/*===========================================*/
-
-/**
- * lgl_paper_new:
- * @id:       Id of paper definition. (E.g. US-Letter, A4, etc.)  Should be
- *            unique.
- * @name:     Localized name of paper.
- * @width:    Width of paper in points.
- * @height:   Height of paper in points.
- * @pwg_size: PWG 5101.1-2002 size name.
- *
- * Allocates and constructs a new #lglPaper structure.
- *
- * Returns: a pointer to a newly allocated #lglPaper structure.
- *
- */
-lglPaper *
-lgl_paper_new (gchar             *id,
-              gchar             *name,
-              gdouble            width,
-              gdouble            height,
-              gchar             *pwg_size)
-{
-       lglPaper *paper;
-
-       paper           = g_new0 (lglPaper,1);
-
-       paper->id       = g_strdup (id);
-       paper->name     = g_strdup (name);
-       paper->width    = width;
-       paper->height   = height;
-       paper->pwg_size = g_strdup (pwg_size);
-
-       return paper;
-}
-
-
-/**
- * lgl_paper_dup:
- * @orig:  #lglPaper structure to be duplicated.
- *
- * Duplicates an existing #lglPaper structure.
- *
- * Returns: a pointer to a newly allocated #lglPaper structure.
- *
- */
-lglPaper *lgl_paper_dup (const lglPaper *orig)
-{
-       lglPaper       *paper;
-
-       g_return_val_if_fail (orig, NULL);
-
-       paper = g_new0 (lglPaper,1);
-
-       paper->id       = g_strdup (orig->id);
-       paper->name     = g_strdup (orig->name);
-       paper->width    = orig->width;
-       paper->height   = orig->height;
-       paper->pwg_size = g_strdup (orig->pwg_size);
-
-       return paper;
-}
-
-
-/**
- * lgl_paper_free:
- * @paper:  pointer to #lglPaper structure to be freed.
- *
- * Free all memory associated with an existing #lglPaper structure.
- *
- */
-void lgl_paper_free (lglPaper *paper)
-{
-
-       if ( paper != NULL ) {
-
-               g_free (paper->id);
-               paper->id = NULL;
-
-               g_free (paper->name);
-               paper->name = NULL;
-
-               g_free (paper->pwg_size);
-               paper->pwg_size = NULL;
-
-               g_free (paper);
-       }
-
-}
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/paper.h b/libglabels/paper.h
deleted file mode 100644 (file)
index 46a7a64..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- *  paper.h
- *  Copyright (C) 2003-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __LGL_PAPER_H__
-#define __LGL_PAPER_H__
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-
-/*
- *   lglPaper structure
- */
-typedef struct _lglPaper lglPaper;
-
-struct _lglPaper {
-       gchar               *id;       /* Unique ID of paper definition */
-       gchar               *name;     /* Localized name of paper */
-       gdouble              width;    /* Width (in points) */
-       gdouble              height;   /* Height (in points) */
-       gchar               *pwg_size; /* PWG 5101.1-2002 size name */
-};
-
-
-/*
- * Paper construction
- */
-lglPaper            *lgl_paper_new                 (gchar           *id,
-                                                   gchar           *name,
-                                                   gdouble          width,
-                                                   gdouble          height,
-                                                   gchar           *pwg_size);
-
-lglPaper             *lgl_paper_dup                (const lglPaper   *orig);
-
-void                 lgl_paper_free                (lglPaper         *paper);
-
-
-G_END_DECLS
-
-#endif /* __LGL_PAPER_H__ */
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/str.c b/libglabels/str.c
deleted file mode 100644 (file)
index a9364c7..0000000
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- *  str.c
- *  Copyright (C) 2007-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-
-#include "str.h"
-
-#include <string.h>
-#include <math.h>
-
-#define FRAC_EPSILON 0.00005
-
-
-/*===========================================*/
-/* Private types                             */
-/*===========================================*/
-
-
-/*===========================================*/
-/* Private globals                           */
-/*===========================================*/
-
-
-/*===========================================*/
-/* Local function prototypes                 */
-/*===========================================*/
-
-static gchar *span_digits (gchar **p);
-static gchar *span_non_digits (gchar **p);
-
-/*===========================================*/
-/* Functions.                                */
-/*===========================================*/
-
-/**
- * lgl_str_utf8_casecmp:
- * @s1: string to compare with s2.
- * @s2: string to compare with s1.
- *
- * Compare two UTF-8 strings, ignoring the case of characters.
- *
- * This function should be used only on strings that are known to be encoded
- * in UTF-8 or a compatible UTF-8 subset.
- *
- * Returns: 0 if the strings match, a negative value if s1 < s2,
- *          or a positive value if s1 > s2.
- *
- */
-gint
-lgl_str_utf8_casecmp (const gchar *s1,
-                      const gchar *s2)
-{
-        gchar *folded_s1;
-        gchar *folded_s2;
-        gint   result;
-
-        folded_s1 = g_utf8_casefold (s1, -1);
-        folded_s2 = g_utf8_casefold (s2, -1);
-
-        result = g_utf8_collate (folded_s1, folded_s2);
-
-        g_free (folded_s1);
-        g_free (folded_s2);
-
-        return result;
-}
-
-
-/**
- * lgl_str_part_name_cmp:
- * @s1: string to compare with s2.
- * @s2: string to compare with s1.
- *
- * Compare two UTF-8 strings representing part names or numbers.  This function
- * uses a natural sort order:
- *
- *  - Ignores case.
- *
- *  - Strings are divided into chunks (numeric and non-numeric)
- *
- *  - Non-numeric chunks are compared character by character
- *
- *  - Numerical chunks are compared numerically, so that "20" precedes "100".
- *
- *  - Comparison of chunks is performed left to right until the first difference
- *    is encountered or all chunks evaluate as equal.
- *
- * This function should be used only on strings that are known to be encoded
- * in UTF-8 or a compatible UTF-8 subset.
- *
- * Numeric chunks are converted to 64 bit unsigned integers for comparison,
- * so the behaviour may be unpredictable for numeric chunks that exceed
- * 18446744073709551615.
- *
- * Returns: 0 if the strings match, a negative value if s1 < s2,
- *          or a positive value if s1 > s2.
- *
- */
-gint
-lgl_str_part_name_cmp (const gchar *s1,
-                       const gchar *s2)
-{
-        gchar *folded_s1, *p1, *chunk1;
-        gchar *folded_s2, *p2, *chunk2;
-        gboolean isnum1, isnum2;
-        guint64 n1, n2;
-        gboolean done;
-        gint   result;
-
-       if ( s1 == s2 ) return 0;
-       if (s1 == NULL) return -1;
-       if (s2 == NULL) return 1;
-
-        folded_s1 = g_utf8_casefold (s1, -1);
-        folded_s2 = g_utf8_casefold (s2, -1);
-
-        result = 0;
-        done = FALSE;
-        p1 = folded_s1;
-        p2 = folded_s2;
-        while ( (result == 0) && !done )
-        {
-
-                if ( g_ascii_isdigit (*p1) )
-                {
-                        chunk1 = span_digits (&p1);
-                        isnum1 = TRUE;
-                }
-                else
-                {
-                        chunk1 = span_non_digits (&p1);
-                        isnum1 = FALSE;
-                }
-                
-                if ( g_ascii_isdigit (*p2) )
-                {
-                        chunk2 = span_digits (&p2);
-                        isnum2 = TRUE;
-                }
-                else
-                {
-                        chunk2 = span_non_digits (&p2);
-                        isnum2 = FALSE;
-                }
-
-                if ( (strlen(chunk1) == 0) && (strlen(chunk2) == 0) )
-                {
-                        /* Case 1: Both are empty. */
-                        done = TRUE;
-                }
-                else if ( isnum1 && isnum2 )
-                {
-                        /* Case 2: They both contain numbers */
-                        n1 = g_ascii_strtoull (chunk1, NULL, 10);
-                        n2 = g_ascii_strtoull (chunk2, NULL, 10);
-
-                        if ( n1 < n2 ) result = -1;
-                        if ( n1 > n2 ) result =  1;
-                }
-                else
-                {
-                        /* Case 3: One or both do not contain numbers */
-                        result = g_utf8_collate (chunk1, chunk2);
-                }
-
-                g_free (chunk1);
-                g_free (chunk2);
-        }
-
-        g_free (folded_s1);
-        g_free (folded_s2);
-
-        return result;
-}
-
-
-static gchar *
-span_digits (gchar **p)
-{
-        gchar *chunk = g_new0 (gchar, strlen (*p) + 1);
-        gint i;
-
-        for ( i = 0; **p && g_ascii_isdigit (**p); i++, *p = g_utf8_next_char(*p) )
-        {
-                chunk[i] = **p;
-        }
-
-        return chunk;
-}
-
-
-static gchar *
-span_non_digits (gchar **p)
-{
-        gchar *chunk = g_new0 (gchar, strlen (*p) + 1);
-        gint i;
-
-        for ( i = 0; **p && !g_ascii_isdigit (**p); i++, *p = g_utf8_next_char(*p) )
-        {
-                chunk[i] = **p;
-        }
-
-        return chunk;
-}
-
-
-/**
- * lgl_str_format_fraction:
- * @x: Floating point number to convert to fractional notation
- *
- * Create fractional representation of number, if possible.  Uses UTF-8 superscripts and
- * subscripts for numerator and denominator values respecively.
- *
- * Returns: UTF-8 string containing fractional representation of x.
- */
-gchar *
-lgl_str_format_fraction (gdouble x)
-{
-       static gdouble denom[]        = {  1.,  2., 3.,  4.,  8.,  16.,  32.,  0. };
-        static gchar  *denom_string[] = { "1", "₂", "₃", "₄", "₈", "₁₆", "₃₂", NULL };
-        static gchar  *num_string[]   = {  "⁰",  "¹",  "²",  "³",  "⁴",  "⁵",  "⁶",  "⁷",  "⁸",  "⁹",
-                                          "¹⁰", "¹¹", "¹²", "¹³", "¹⁴", "¹⁵", "¹⁶", "¹⁷", "¹⁸", "¹⁹",
-                                          "²⁰", "²¹", "²²", "²³", "²⁴", "²⁵", "²⁶", "²⁷", "²⁸", "²⁹",
-                                          "³⁰", "³¹" };
-       gint i;
-       gdouble product, remainder;
-       gint n, d;
-
-       for ( i=0; denom[i] != 0.0; i++ ) {
-               product = x * denom[i];
-               remainder = fabs(product - ((gint)(product+0.5)));
-               if ( remainder < FRAC_EPSILON ) break;
-       }
-
-       if ( denom[i] == 0.0 ) {
-               /* None of our denominators work. */
-               return g_strdup_printf ("%.5g", x);
-       }
-       if ( denom[i] == 1.0 ) {
-               /* Simple integer. */
-               return g_strdup_printf ("%.0f", x);
-       }
-       n = (gint)( x * denom[i] + 0.5 );
-       d = (gint)denom[i];
-       if ( n > d ) {
-               return g_strdup_printf ("%d%s/%s", (n/d), num_string[n%d], denom_string[i]);
-       } else {
-               return g_strdup_printf ("%s/%s", num_string[n%d], denom_string[i]);
-       }
-}
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/str.h b/libglabels/str.h
deleted file mode 100644 (file)
index b22f13b..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *  str.h
- *  Copyright (C) 2007-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __LGL_STR_H__
-#define __LGL_STR_H__
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-gint   lgl_str_utf8_casecmp    (const gchar *s1,
-                                const gchar *s2);
-
-gint   lgl_str_part_name_cmp   (const gchar *s1,
-                                const gchar *s2);
-
-gchar *lgl_str_format_fraction (gdouble      x);
-
-G_END_DECLS
-
-
-#endif /* __LGL_STR_H__ */
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/template.c b/libglabels/template.c
deleted file mode 100644 (file)
index b28a6c2..0000000
+++ /dev/null
@@ -1,1397 +0,0 @@
-/*
- *  template.c
- *  Copyright (C) 2001-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-
-#include "template.h"
-
-#include <glib/gi18n.h>
-#include <glib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <math.h>
-
-#include "libglabels-private.h"
-
-#include "db.h"
-#include "paper.h"
-
-/*===========================================*/
-/* Private macros and constants.             */
-/*===========================================*/
-
-/* Allowed error when comparing dimensions. (0.5pts ~= .007in ~= .2mm) */
-#define EPSILON 0.5
-
-/*===========================================*/
-/* Private types                             */
-/*===========================================*/
-
-
-/*===========================================*/
-/* Private globals                           */
-/*===========================================*/
-
-
-/*===========================================*/
-/* Local function prototypes                 */
-/*===========================================*/
-
-static gint         compare_origins              (gconstpointer           a,
-                                                  gconstpointer           b,
-                                                  gpointer                user_data);
-
-/*===========================================*/
-/* Functions.                                */
-/*===========================================*/
-
-/**
- * lgl_template_new:
- *   @brand:        Template brand
- *   @part:         Template part name/number
- *   @description:  Template descriptions
- *   @paper_id:     Page size id
- *   @page_width:   Page width in points, set to zero unless paper_id="Other"
- *   @page_height:  Page height in points, set to zero unless paper_id="Other"
- *
- * Create a new template structure, with the given top-level attributes.  The
- * created template will have no initial categories, or frames associated with
- * it.  See lgl_template_add_category() and lgl_template_add_frame() to add
- * these.
- *
- * Returns: pointer to a newly allocated #lglTemplate structure.
- *
- */
-lglTemplate *
-lgl_template_new (const gchar         *brand,
-                  const gchar         *part,
-                  const gchar         *description,
-                  const gchar         *paper_id,
-                  gdouble              page_width,
-                  gdouble              page_height)
-{
-       lglTemplate      *template;
-
-       template = g_new0 (lglTemplate,1);
-
-       template->brand       = g_strdup (brand);
-       template->part        = g_strdup (part);
-       template->description = g_strdup (description);
-       template->paper_id    = g_strdup (paper_id);
-       template->page_width  = page_width;
-       template->page_height = page_height;
-
-       return template;
-}
-
-
-/**
- * lgl_template_new_from_equiv:
- *   @brand:        Template brand
- *   @part:         Template part name/number
- *   @equiv_part:   Name of equivalent part to base template on
- *
- * Create a new template structure based on an existing template.  The
- * created template will be a duplicate of the original template, except with
- * the new part name/number.
- *
- * Returns: pointer to a newly allocated #lglTemplate structure.
- *
- */
-lglTemplate *
-lgl_template_new_from_equiv (const gchar          *brand,
-                             const gchar          *part,
-                             const gchar          *equiv_part)
-{
-        lglTemplate      *template = NULL;
-
-        if ( lgl_db_does_template_exist (brand, equiv_part) )
-        {
-                template = lgl_db_lookup_template_from_brand_part (brand, equiv_part);
-
-                g_free (template->part);
-                g_free (template->equiv_part);
-
-                template->part       = g_strdup (part);
-                template->equiv_part = g_strdup (equiv_part);
-        }
-        else
-        {
-                g_message ("Equivalent part (\"%s\") for \"%s\", not previously defined.",
-                           equiv_part, part);
-        }
-
-        return template;
-}
-
-
-/**
- * lgl_template_get_name:
- *   @template:  Pointer to template structure to test
- *
- * This function returns the name of the given template.  The name is the concetenation
- * of the brand and part name/number.
- *
- * Returns:  A pointer to a newly allocated name string.  Should be freed with g_free().
- *
- */
-gchar *
-lgl_template_get_name (const lglTemplate  *template)
-{
-       g_return_val_if_fail (template, NULL);
-
-        return g_strdup_printf ("%s %s", template->brand, template->part);
-}
-
-
-/**
- * lgl_template_do_templates_match:
- *   @template1:  Pointer to 1st template structure to test
- *   @template2:  Pointer to 2nd template structure to test
- *
- * This function tests if the given templates match.  This is a simple test that only tests
- * the brand and part name/number. It does not test if they are actually identical.
- *
- * Returns:  TRUE if the two templates match.
- *
- */
-gboolean
-lgl_template_do_templates_match (const lglTemplate  *template1,
-                                 const lglTemplate  *template2)
-{
-       g_return_val_if_fail (template1, FALSE);
-       g_return_val_if_fail (template2, FALSE);
-
-        return (UTF8_EQUAL (template1->brand, template2->brand) &&
-                UTF8_EQUAL (template1->part, template2->part));
-}
-
-
-/**
- * lgl_template_does_brand_match:
- *   @template:  Pointer to template structure to test
- *   @brand:     Brand string
- *
- * This function tests if the brand of the template matches the given brand.
- *
- * Returns:  TRUE if the template matches the given brand.
- *
- */
-gboolean
-lgl_template_does_brand_match (const lglTemplate  *template,
-                               const gchar        *brand)
-{
-       g_return_val_if_fail (template, FALSE);
-
-        /* NULL matches everything. */
-        if (brand == NULL)
-        {
-                return TRUE;
-        }
-
-        return UTF8_EQUAL (template->brand, brand);
-}
-
-
-/**
- * lgl_template_does_page_size_match:
- *   @template:  Pointer to template structure to test
- *   @paper_id:  Page size ID string
- *
- * This function tests if the page size of the template matches the given ID.
- *
- * Returns:  TRUE if the template matches the given page size ID.
- *
- */
-gboolean
-lgl_template_does_page_size_match (const lglTemplate  *template,
-                                   const gchar        *paper_id)
-{
-       g_return_val_if_fail (template, FALSE);
-
-        /* NULL matches everything. */
-        if (paper_id == NULL)
-        {
-                return TRUE;
-        }
-
-        return ASCII_EQUAL(paper_id, template->paper_id);
-}
-
-
-/**
- * lgl_template_does_category_match:
- *   @template:     Pointer to template structure to test
- *   @category_id:  Category ID string
- *
- * This function tests if the given template belongs to the given category ID.
- *
- * Returns:  TRUE if the template matches the given category ID.
- *
- */
-gboolean
-lgl_template_does_category_match  (const lglTemplate  *template,
-                                   const gchar        *category_id)
-{
-        GList *p;
-
-       g_return_val_if_fail (template, FALSE);
-
-        /* NULL matches everything. */
-        if (category_id == NULL)
-        {
-                return TRUE;
-        }
-
-        for ( p=template->category_ids; p != NULL; p=p->next )
-        {
-                if (ASCII_EQUAL(category_id, p->data))
-                {
-                        return TRUE;
-                }
-        }
-
-        return FALSE;
-}
-
-
-/**
- * lgl_template_are_templates_identical:
- *   @template1:  Pointer to 1st template structure to test
- *   @template2:  Pointer to 2nd template structure to test
- *
- * This function tests if the given templates have identical size and layout properties.
- *
- * Returns:  TRUE if the two templates are identical.
- *
- */
-gboolean
-lgl_template_are_templates_identical (const lglTemplate   *template1,
-                                      const lglTemplate   *template2)
-{
-        lglTemplateFrame  *frame1;
-        lglTemplateFrame  *frame2;
-        GList             *p1;
-        GList             *p2;
-        lglTemplateLayout *layout1;
-        lglTemplateLayout *layout2;
-        gboolean           match_found;
-
-
-        if (!UTF8_EQUAL (template1->paper_id, template2->paper_id) ||
-            (template1->page_width  != template2->page_width)      ||
-            (template1->page_height != template2->page_height))
-        {
-                return FALSE;
-        }
-
-        frame1 = (lglTemplateFrame *)template1->frames->data;
-        frame2 = (lglTemplateFrame *)template2->frames->data;
-
-        if ( frame1->shape != frame2->shape )
-        {
-                return FALSE;
-        }
-
-        switch ( frame1->shape )
-        {
-
-        case LGL_TEMPLATE_FRAME_SHAPE_RECT:
-                if ( (fabs(frame1->rect.w - frame2->rect.w) > EPSILON) ||
-                     (fabs(frame1->rect.h - frame2->rect.h) > EPSILON) )
-                {
-                        return FALSE;
-                }
-                break;
-
-        case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
-                if ( (fabs(frame1->ellipse.w - frame2->ellipse.w) > EPSILON) ||
-                     (fabs(frame1->ellipse.h - frame2->ellipse.h) > EPSILON) )
-                {
-                        return FALSE;
-                }
-                break;
-
-        case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
-                if ( fabs(frame1->round.r - frame2->round.r) > EPSILON )
-                {
-                        return FALSE;
-                }
-                break;
-
-        case LGL_TEMPLATE_FRAME_SHAPE_CD:
-                if ( (fabs(frame1->cd.r1 - frame2->cd.r1) > EPSILON) ||
-                     (fabs(frame1->cd.r2 - frame2->cd.r2) > EPSILON) )
-                {
-                        return FALSE;
-                }
-        }
-
-        for ( p1 = frame1->all.layouts; p1; p1 = p1->next )
-        {
-                layout1 = (lglTemplateLayout *)p1->data;
-
-                match_found = FALSE;
-                for ( p2 = frame2->all.layouts; p2 && !match_found; p2 = p2->next )
-                {
-                        layout2 = (lglTemplateLayout *)p2->data;
-
-                        if ( (layout1->nx == layout2->nx) &&
-                             (layout1->ny == layout2->ny) &&
-                             (fabs(layout1->x0 - layout2->x0) < EPSILON) &&
-                             (fabs(layout1->y0 - layout2->y0) < EPSILON) &&
-                             (fabs(layout1->dx - layout2->dx) < EPSILON) &&
-                             (fabs(layout1->dy - layout2->dy) < EPSILON) )
-                        {
-                                match_found = TRUE;
-                        }
-
-                }
-                if ( !match_found )
-                {
-                        return FALSE;
-                }
-        }
-
-        return TRUE;
-}
-
-
-/**
- * lgl_template_add_frame:
- *   @template:  Pointer to template structure
- *   @frame:     Pointer to frame structure
- *
- * This function adds the given frame structure to the template.  Once added,
- * the frame structure belongs to the given template; do not attempt to free
- * it.
- *
- * Note: Currently glabels only supports a single frame per template.
- *
- */
-void
-lgl_template_add_frame (lglTemplate      *template,
-                        lglTemplateFrame *frame)
-{
-       g_return_if_fail (template);
-       g_return_if_fail (frame);
-
-       template->frames = g_list_append (template->frames, frame);
-}
-
-/**
- * lgl_template_add_category:
- *   @template:     Pointer to template structure
- *   @category_id:  Category ID string
- *
- * This function adds the given category ID to a templates category list.
- *
- */
-void
-lgl_template_add_category (lglTemplate         *template,
-                           const gchar         *category_id)
-{
-       g_return_if_fail (template);
-       g_return_if_fail (category_id);
-
-       template->category_ids = g_list_append (template->category_ids,
-                                                g_strdup (category_id));
-}
-
-/**
- * lgl_template_frame_rect_new:
- *   @id:      ID of frame.  (This should currently always be "0").
- *   @w:       width of frame in points.
- *   @h:       height of frame in points.
- *   @r:       radius of rounded corners in points.  (Should be 0 for square corners.)
- *   @x_waste: Amount of overprint to allow in the horizontal direction.
- *   @y_waste: Amount of overprint to allow in the vertical direction.
- *
- * This function creates a new template frame for a rectangular label or card.
- *
- * Returns: Pointer to newly allocated #lglTemplateFrame structure.
- *
- */
-lglTemplateFrame *
-lgl_template_frame_rect_new  (const gchar         *id,
-                              gdouble              w,
-                              gdouble              h,
-                              gdouble              r,
-                              gdouble              x_waste,
-                              gdouble              y_waste)
-{
-       lglTemplateFrame *frame;
-
-       frame = g_new0 (lglTemplateFrame, 1);
-
-       frame->shape = LGL_TEMPLATE_FRAME_SHAPE_RECT;
-       frame->rect.id = g_strdup (id);
-
-       frame->rect.w = w;
-       frame->rect.h = h;
-       frame->rect.r = r;
-       frame->rect.x_waste = x_waste;
-       frame->rect.y_waste = y_waste;
-
-       return frame;
-}
-
-
-/**
- * lgl_template_frame_ellipse_new:
- *   @id:      ID of frame.  (This should currently always be "0").
- *   @w:       width of frame in points.
- *   @h:       height of frame in points.
- *   @waste:   Amount of overprint to allow in points.
- *
- * This function creates a new template frame for an elliptical label or card.
- *
- * Returns: Pointer to newly allocated #lglTemplateFrame structure.
- *
- */
-lglTemplateFrame *
-lgl_template_frame_ellipse_new  (const gchar         *id,
-                                 gdouble              w,
-                                 gdouble              h,
-                                 gdouble              waste)
-{
-       lglTemplateFrame *frame;
-
-       frame = g_new0 (lglTemplateFrame, 1);
-
-       frame->shape = LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE;
-       frame->ellipse.id = g_strdup (id);
-
-       frame->ellipse.w = w;
-       frame->ellipse.h = h;
-       frame->ellipse.waste = waste;
-
-       return frame;
-}
-
-
-/**
- * lgl_template_frame_round_new:
- *   @id:      ID of frame.  (This should currently always be "0").
- *   @r:       radius of label in points.
- *   @waste:   Amount of overprint to allow.
- *
- * This function creates a new template frame for a round label.
- *
- * Returns: Pointer to newly allocated #lglTemplateFrame structure.
- *
- */
-lglTemplateFrame *
-lgl_template_frame_round_new (const gchar         *id,
-                              gdouble              r,
-                              gdouble              waste)
-{
-       lglTemplateFrame *frame;
-
-       frame = g_new0 (lglTemplateFrame, 1);
-
-       frame->shape = LGL_TEMPLATE_FRAME_SHAPE_ROUND;
-       frame->round.id = g_strdup (id);
-
-       frame->round.r = r;
-       frame->round.waste = waste;
-
-       return frame;
-}
-
-                                                                               
-/**
- * lgl_template_frame_cd_new:
- *   @id:      ID of frame.  (This should currently always be "0").
- *   @r1:      outer radius of label in points.
- *   @r2:      radius of center hole in points.
- *   @w:       clip width of frame in points for business card CDs.  Should be 0 for no clipping.
- *   @h:       clip height of frame in points for business card CDs.  Should be 0 for no clipping.
- *   @waste:   Amount of overprint to allow.
- *
- * This function creates a new template frame for a CD/DVD label.
- *
- * Returns: Pointer to newly allocated #lglTemplateFrame structure.
- *
- */
-lglTemplateFrame *
-lgl_template_frame_cd_new (const gchar         *id,
-                           gdouble              r1,
-                           gdouble              r2,
-                           gdouble              w,
-                           gdouble              h,
-                           gdouble              waste)
-{
-       lglTemplateFrame *frame;
-
-       frame = g_new0 (lglTemplateFrame, 1);
-
-       frame->shape = LGL_TEMPLATE_FRAME_SHAPE_CD;
-       frame->cd.id = g_strdup (id);
-
-       frame->cd.r1 = r1;
-       frame->cd.r2 = r2;
-       frame->cd.w  = w;
-       frame->cd.h  = h;
-       frame->cd.waste = waste;
-
-       return frame;
-}
-
-
-/**
- * lgl_template_frame_get_size:
- * @frame: #lglTemplateFrame structure to query
- * @w: pointer to location to receive width of frame
- * @h: pointer to location to receive height of frame
- *
- * Get size (width and height) of given #lglTemplateFrame in points.
- *
- */
-void
-lgl_template_frame_get_size (const lglTemplateFrame *frame,
-                             gdouble                *w,
-                             gdouble                *h)
-{
-       g_return_if_fail (frame);
-
-       switch (frame->shape) {
-       case LGL_TEMPLATE_FRAME_SHAPE_RECT:
-               *w = frame->rect.w;
-               *h = frame->rect.h;
-               break;
-       case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
-               *w = frame->ellipse.w;
-               *h = frame->ellipse.h;
-               break;
-       case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
-               *w = 2.0 * frame->round.r;
-               *h = 2.0 * frame->round.r;
-               break;
-       case LGL_TEMPLATE_FRAME_SHAPE_CD:
-               if (frame->cd.w == 0.0) {
-                       *w = 2.0 * frame->cd.r1;
-               } else {
-                       *w = frame->cd.w;
-               }
-               if (frame->cd.h == 0.0) {
-                       *h = 2.0 * frame->cd.r1;
-               } else {
-                       *h = frame->cd.h;
-               }
-               break;
-       default:
-               *w = 0.0;
-               *h = 0.0;
-               break;
-       }
-}
-
-
-/**
- * lgl_template_frame_get_n_labels:
- * @frame: #lglTemplateFrame structure to query
- *
- * Get total number of labels per sheet corresponding to the given frame.
- *
- * Returns: number of labels per sheet.
- *
- */
-gint
-lgl_template_frame_get_n_labels (const lglTemplateFrame *frame)
-{
-       gint               n_labels = 0;
-       GList             *p;
-       lglTemplateLayout *layout;
-
-       g_return_val_if_fail (frame, 0);
-
-       for ( p=frame->all.layouts; p != NULL; p=p->next ) {
-               layout = (lglTemplateLayout *)p->data;
-
-               n_labels += layout->nx * layout->ny;
-       }
-
-       return n_labels;
-}
-
-
-/**
- * lgl_template_frame_get_layout_description
- * @frame: #lglTemplateFrame structure to query
- *
- * Get a description of the label layout including number of labels per sheet.
- *
- * Returns: a newly allocation description string.
- *
- */
-gchar *
-lgl_template_frame_get_layout_description (const lglTemplateFrame *frame)
-{
-        gint                    n_labels;
-        gchar                  *string;
-        lglTemplateLayout      *layout;
-
-        n_labels = lgl_template_frame_get_n_labels (frame);
-
-        if ( frame->all.layouts && (frame->all.layouts->next == NULL) )
-        {
-                layout = (lglTemplateLayout *)frame->all.layouts->data;
-                /*
-                 * Translators: 1st %d = number of labels across a page,
-                 *              2nd %d = number of labels down a page,
-                 *              3rd %d = total number of labels on a page (sheet).
-                 */
-                string = g_strdup_printf (_("%d × %d (%d per sheet)"), layout->nx, layout->ny, n_labels);
-        }
-        else
-        {
-                /* Translators: %d is the total number of labels on a page (sheet). */
-                string = g_strdup_printf (_("%d per sheet"), n_labels);
-        }
-
-        return string;
-}
-
-
-/**
- * lgl_template_frame_get_size_description
- * @frame: #lglTemplateFrame structure to query
- * @units: #lglUnits
- *
- * Get a description of the label size.
- *
- * Returns: a newly allocation description string.
- *
- */
-gchar *
-lgl_template_frame_get_size_description (const lglTemplateFrame *frame,
-                                         lglUnits                units)
-{
-        const gchar               *units_string;
-        gdouble                    units_per_point;
-        gchar                     *string = NULL;
-
-        units_string    = lgl_units_get_name (units);
-        units_per_point = lgl_units_get_units_per_point (units);
-
-        switch (frame->shape) {
-        case LGL_TEMPLATE_FRAME_SHAPE_RECT:
-                if ( units == LGL_UNITS_INCH ) {
-                        gchar *xstr, *ystr;
-
-                        xstr = lgl_str_format_fraction (frame->rect.w*units_per_point);
-                        ystr = lgl_str_format_fraction (frame->rect.h*units_per_point);
-                        string = g_strdup_printf ("%s × %s %s",
-                                                  xstr, ystr, units_string);
-                        g_free (xstr);
-                        g_free (ystr);
-                } else {
-                        string = g_strdup_printf ("%.5g × %.5g %s",
-                                                  frame->rect.w*units_per_point,
-                                                  frame->rect.h*units_per_point,
-                                                  units_string);
-                }
-                break;
-        case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
-                if ( units == LGL_UNITS_INCH ) {
-                        gchar *xstr, *ystr;
-
-                        xstr = lgl_str_format_fraction (frame->ellipse.w*units_per_point);
-                        ystr = lgl_str_format_fraction (frame->ellipse.h*units_per_point);
-                        string = g_strdup_printf ("%s × %s %s",
-                                                  xstr, ystr, units_string);
-                        g_free (xstr);
-                        g_free (ystr);
-                } else {
-                        string = g_strdup_printf ("%.5g × %.5g %s",
-                                                  frame->ellipse.w*units_per_point,
-                                                  frame->ellipse.h*units_per_point,
-                                                  units_string);
-                }
-                break;
-        case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
-                if ( units == LGL_UNITS_INCH ) {
-                        gchar *dstr;
-
-                        dstr = lgl_str_format_fraction (2.0*frame->round.r*units_per_point);
-                        string = g_strdup_printf ("%s %s %s",
-                                                  dstr, units_string,
-                                                  _("diameter"));
-                        g_free (dstr);
-                } else {
-                        string = g_strdup_printf ("%.5g %s %s",
-                                                  2.0*frame->round.r*units_per_point,
-                                                  units_string,
-                                                  _("diameter"));
-                }
-                break;
-        case LGL_TEMPLATE_FRAME_SHAPE_CD:
-                if ( units == LGL_UNITS_INCH ) {
-                        gchar *dstr;
-
-                        dstr = lgl_str_format_fraction (2.0*frame->cd.r1*units_per_point);
-                        string = g_strdup_printf ("%s %s %s",
-                                                  dstr, units_string,
-                                                  _("diameter"));
-                        g_free (dstr);
-                } else {
-                        string = g_strdup_printf ("%.5g %s %s",
-                                                  2.0*frame->cd.r1*units_per_point,
-                                                  units_string,
-                                                  _("diameter"));
-                }
-                break;
-        default:
-                break;
-        }
-
-        return string;
-}
-
-
-/**
- * lgl_template_frame_get_origins:
- * @frame: #lglTemplateFrame structure to query
- *
- * Get an array of label origins for the given frame.  These origins represent the
- * upper left hand corner of each label on a page corresponding to the given frame.
- * The origins will be ordered geometrically left to right and then top to bottom.
- * The array should be freed using g_free().
- *
- * Returns: A newly allocated array of #lglTemplateOrigin structures.
- *
- */
-lglTemplateOrigin *
-lgl_template_frame_get_origins (const lglTemplateFrame *frame)
-{
-       gint               i_label, n_labels, ix, iy;
-       lglTemplateOrigin *origins;
-       GList             *p;
-       lglTemplateLayout *layout;
-
-       g_return_val_if_fail (frame, NULL);
-
-       n_labels = lgl_template_frame_get_n_labels (frame);
-       origins = g_new0 (lglTemplateOrigin, n_labels);
-
-       i_label = 0;
-       for ( p=frame->all.layouts; p != NULL; p=p->next ) {
-               layout = (lglTemplateLayout *)p->data;
-
-               for (iy = 0; iy < layout->ny; iy++) {
-                       for (ix = 0; ix < layout->nx; ix++, i_label++) {
-                               origins[i_label].x = ix*layout->dx + layout->x0;
-                               origins[i_label].y = iy*layout->dy + layout->y0;
-                       }
-               }
-       }
-
-       g_qsort_with_data (origins, n_labels, sizeof(lglTemplateOrigin),
-                          compare_origins, NULL);
-
-       return origins;
-}
-
-
-/**
- * lgl_template_frame_add_layout:
- *   @frame:  Pointer to template frame to add layout to.
- *   @layout: Pointer to layout structure to add to frame.
- *
- * This function adds a layout structure to the given template frame.
- *
- */
-void
-lgl_template_frame_add_layout (lglTemplateFrame   *frame,
-                               lglTemplateLayout  *layout)
-{
-       g_return_if_fail (frame);
-       g_return_if_fail (layout);
-
-       frame->all.layouts = g_list_append (frame->all.layouts, layout);
-}
-
-/**
- * lgl_template_frame_add_markup:
- *   @frame:  Pointer to template frame to add markup to.
- *   @markup: Pointer to markup structure to add to frame.
- *
- * This function adds a markup structure to the given template frame.
- *
- */
-void
-lgl_template_frame_add_markup (lglTemplateFrame   *frame,
-                               lglTemplateMarkup  *markup)
-{
-       g_return_if_fail (frame);
-       g_return_if_fail (markup);
-
-       frame->all.markups = g_list_append (frame->all.markups, markup);
-}
-
-/**
- * lgl_template_layout_new:
- *   @nx:  Number of labels across.
- *   @ny:  Number of labels down.
- *   @x0:  X coordinate of the top-left corner of the top-left label in the layout in points.
- *   @y0:  Y coordinate of the top-left corner of the top-left label in the layout in points.
- *   @dx:  Horizontal pitch in points.  This is the distance from left-edge to left-edge.
- *   @dy:  Vertical pitch in points.  This is the distance from top-edge to top-edge.
- *
- * This function creates a new layout structure with the given parameters.
- *
- * Returns: a newly allocated #lglTemplateLayout structure.
- *
- */
-lglTemplateLayout *
-lgl_template_layout_new (gint    nx,
-                         gint    ny,
-                         gdouble x0,
-                         gdouble y0,
-                         gdouble dx,
-                         gdouble dy)
-{
-       lglTemplateLayout *layout;
-
-       layout = g_new0 (lglTemplateLayout, 1);
-
-       layout->nx = nx;
-       layout->ny = ny;
-       layout->x0 = x0;
-       layout->y0 = y0;
-       layout->dx = dx;
-       layout->dy = dy;
-
-       return layout;
-}
-
-
-/**
- * lgl_template_markup_margin_new:
- *   @size: margin size in points.
- *
- * This function creates a new margin markup structure.
- *
- * Returns: a newly allocated #lglTemplateMarkup structure.
- *
- */
-lglTemplateMarkup *
-lgl_template_markup_margin_new (gdouble size)
-{
-       lglTemplateMarkup *markup;
-
-       markup = g_new0 (lglTemplateMarkup, 1);
-
-       markup->type        = LGL_TEMPLATE_MARKUP_MARGIN;
-       markup->margin.size = size;
-
-       return markup;
-}
-
-
-/**
- * lgl_template_markup_line_new:
- *   @x1: x coordinate of first endpoint.
- *   @y1: y coordinate of first endpoint.
- *   @x2: x coordinate of second endpoint.
- *   @y2: y coordinate of second endpoint.
- *
- * This function creates a new line markup structure.
- *
- * Returns: a newly allocated #lglTemplateMarkup structure.
- *
- */
-lglTemplateMarkup *
-lgl_template_markup_line_new (gdouble x1,
-                              gdouble y1,
-                              gdouble x2,
-                              gdouble y2)
-{
-       lglTemplateMarkup *markup;
-
-       markup = g_new0 (lglTemplateMarkup, 1);
-
-       markup->type        = LGL_TEMPLATE_MARKUP_LINE;
-       markup->line.x1     = x1;
-       markup->line.y1     = y1;
-       markup->line.x2     = x2;
-       markup->line.y2     = y2;
-
-       return markup;
-}
-
-
-/**
- * lgl_template_markup_circle_new:
- *   @x0: x coordinate of center of circle.
- *   @y0: y coordinate of center of circle.
- *   @r:  radius of circle.
- *
- * This function creates a new circle markup structure.
- *
- * Returns: a newly allocated #lglTemplateMarkup structure.
- *
- */
-lglTemplateMarkup *
-lgl_template_markup_circle_new (gdouble x0,
-                                gdouble y0,
-                                gdouble r)
-{
-       lglTemplateMarkup *markup;
-
-       markup = g_new0 (lglTemplateMarkup, 1);
-
-       markup->type        = LGL_TEMPLATE_MARKUP_CIRCLE;
-       markup->circle.x0   = x0;
-       markup->circle.y0   = y0;
-       markup->circle.r    = r;
-
-       return markup;
-}
-
-
-/**
- * lgl_template_markup_rect_new:
- *   @x1: x coordinate of top-left corner of rectangle.
- *   @y1: y coordinate of top-left corner of rectangle.
- *   @w:  width of rectangle.
- *   @h:  height of rectangle.
- *   @r:  radius of rounded corner.
- *
- * This function creates a new rectangle markup structure.
- *
- * Returns: a newly allocated #lglTemplateMarkup structure.
- *
- */
-lglTemplateMarkup *
-lgl_template_markup_rect_new (gdouble x1,
-                              gdouble y1,
-                              gdouble w,
-                              gdouble h,
-                              gdouble r)
-{
-       lglTemplateMarkup *markup;
-
-       markup = g_new0 (lglTemplateMarkup, 1);
-
-       markup->type        = LGL_TEMPLATE_MARKUP_RECT;
-       markup->rect.x1     = x1;
-       markup->rect.y1     = y1;
-       markup->rect.w      = w;
-       markup->rect.h      = h;
-       markup->rect.r      = r;
-
-       return markup;
-}
-
-
-/**
- * lgl_template_markup_ellipse_new:
- *   @x1: x coordinate of top-left corner of ellipse.
- *   @y1: y coordinate of top-left corner of ellipse.
- *   @w:  width of ellipse.
- *   @h:  height of ellipse.
- *
- * This function creates a new ellipse markup structure.
- *
- * Returns: a newly allocated #lglTemplateMarkup structure.
- *
- */
-lglTemplateMarkup *
-lgl_template_markup_ellipse_new (gdouble x1,
-                                 gdouble y1,
-                                 gdouble w,
-                                 gdouble h)
-{
-       lglTemplateMarkup *markup;
-
-       markup = g_new0 (lglTemplateMarkup, 1);
-
-       markup->type        = LGL_TEMPLATE_MARKUP_ELLIPSE;
-       markup->ellipse.x1     = x1;
-       markup->ellipse.y1     = y1;
-       markup->ellipse.w      = w;
-       markup->ellipse.h      = h;
-
-       return markup;
-}
-
-
-/**
- * lgl_template_dup:
- *   @orig_template: Template to duplicate.
- *
- * This function duplicates a template structure.
- *
- * Returns:  a newly allocated #lglTemplate structure.
- *
- */
-lglTemplate *
-lgl_template_dup (const lglTemplate *orig_template)
-{
-       lglTemplate         *template;
-       GList               *p;
-       lglTemplateFrame    *frame;
-
-       g_return_val_if_fail (orig_template, NULL);
-
-       template = lgl_template_new (orig_template->brand,
-                                     orig_template->part,
-                                     orig_template->description,
-                                     orig_template->paper_id,
-                                     orig_template->page_width,
-                                     orig_template->page_height);
-
-        template->equiv_part  = g_strdup (orig_template->equiv_part);
-        template->product_url = g_strdup (orig_template->product_url);
-
-
-       for ( p=orig_template->category_ids; p != NULL; p=p->next )
-        {
-                lgl_template_add_category (template, p->data);
-       }
-
-       for ( p=orig_template->frames; p != NULL; p=p->next )
-        {
-               frame = (lglTemplateFrame *)p->data;
-
-               lgl_template_add_frame (template, lgl_template_frame_dup (frame));
-       }
-
-       return template;
-}
-
-
-/**
- * lgl_template_free:
- *   @template: Template to free.
- *
- * This function frees all memory associated with given template structure.
- *
- */
-void
-lgl_template_free (lglTemplate *template)
-{
-       GList            *p;
-       lglTemplateFrame *frame;
-
-       if ( template != NULL ) {
-
-               g_free (template->brand);
-               template->brand = NULL;
-
-               g_free (template->part);
-               template->part = NULL;
-
-               g_free (template->description);
-               template->description = NULL;
-
-               g_free (template->paper_id);
-               template->paper_id = NULL;
-
-               for ( p=template->category_ids; p != NULL; p=p->next ) {
-
-                       g_free (p->data);
-                       p->data = NULL;
-
-               }
-               g_list_free (template->category_ids);
-               template->category_ids = NULL;
-
-               for ( p=template->frames; p != NULL; p=p->next ) {
-
-                       frame = (lglTemplateFrame *)p->data;
-
-                       lgl_template_frame_free (frame);
-                       p->data = NULL;
-               }
-               g_list_free (template->frames);
-               template->frames = NULL;
-
-               g_free (template);
-
-       }
-
-}
-
-
-/**
- * lgl_template_frame_dup:
- *   @orig_frame: Frame to duplicate.
- *
- * This function duplicates a template frame structure.
- *
- * Returns:  a newly allocated #lglTemplateFrame structure.
- *
- */
-lglTemplateFrame *
-lgl_template_frame_dup (const lglTemplateFrame *orig_frame)
-{
-       lglTemplateFrame    *frame;
-       GList               *p;
-       lglTemplateLayout   *layout;
-       lglTemplateMarkup   *markup;
-
-       g_return_val_if_fail (orig_frame, NULL);
-
-       switch (orig_frame->shape) {
-
-       case LGL_TEMPLATE_FRAME_SHAPE_RECT:
-               frame =
-                       lgl_template_frame_rect_new (orig_frame->all.id,
-                                                     orig_frame->rect.w,
-                                                     orig_frame->rect.h,
-                                                     orig_frame->rect.r,
-                                                     orig_frame->rect.x_waste,
-                                                     orig_frame->rect.y_waste);
-               break;
-
-       case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
-               frame =
-                       lgl_template_frame_ellipse_new (orig_frame->all.id,
-                                                        orig_frame->ellipse.w,
-                                                        orig_frame->ellipse.h,
-                                                        orig_frame->ellipse.waste);
-               break;
-
-       case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
-               frame =
-                       lgl_template_frame_round_new (orig_frame->all.id,
-                                                      orig_frame->round.r,
-                                                      orig_frame->round.waste);
-               break;
-
-       case LGL_TEMPLATE_FRAME_SHAPE_CD:
-               frame =
-                       lgl_template_frame_cd_new (orig_frame->all.id,
-                                                   orig_frame->cd.r1,
-                                                   orig_frame->cd.r2,
-                                                   orig_frame->cd.w,
-                                                   orig_frame->cd.h,
-                                                   orig_frame->cd.waste);
-               break;
-
-       default:
-               return NULL;
-               break;
-       }
-
-       for ( p=orig_frame->all.layouts; p != NULL; p=p->next ) {
-
-               layout = (lglTemplateLayout *)p->data;
-
-               lgl_template_frame_add_layout (frame, lgl_template_layout_dup (layout));
-       }
-
-       for ( p=orig_frame->all.markups; p != NULL; p=p->next ) {
-
-               markup = (lglTemplateMarkup *)p->data;
-
-               lgl_template_frame_add_markup (frame, lgl_template_markup_dup (markup));
-       }
-
-       return frame;
-}
-
-
-/**
- * lgl_template_frame_free:
- *   @frame: Frame to free.
- *
- * This function frees all memory associated with given template frame structure.
- *
- */
-void
-lgl_template_frame_free (lglTemplateFrame *frame)
-{
-       GList                *p;
-       lglTemplateLayout    *layout;
-       lglTemplateMarkup    *markup;
-
-       if ( frame != NULL ) {
-
-               g_free (frame->all.id);
-               frame->all.id = NULL;
-
-               for ( p=frame->all.layouts; p != NULL; p=p->next ) {
-
-                       layout = (lglTemplateLayout *)p->data;
-
-                       lgl_template_layout_free (layout);
-                       p->data = NULL;
-               }
-               g_list_free (frame->all.layouts);
-               frame->all.layouts = NULL;
-
-               for ( p=frame->all.markups; p != NULL; p=p->next ) {
-
-                       markup = (lglTemplateMarkup *)p->data;
-
-                       lgl_template_markup_free (markup);
-                       p->data = NULL;
-               }
-               g_list_free (frame->all.markups);
-               frame->all.markups = NULL;
-
-               g_free (frame);
-
-       }
-
-}
-
-
-/**
- * lgl_template_layout_dup:
- *   @orig_layout: Layout to duplicate.
- *
- * This function duplicates a template layout structure.
- *
- * Returns:  a newly allocated #lglTemplateLayout structure.
- *
- */
-lglTemplateLayout *
-lgl_template_layout_dup (const lglTemplateLayout *orig_layout)
-{
-       lglTemplateLayout *layout;
-
-       g_return_val_if_fail (orig_layout, NULL);
-
-       layout = g_new0 (lglTemplateLayout, 1);
-
-       /* copy contents */
-       *layout = *orig_layout;
-
-       return layout;
-}
-
-
-/**
- * lgl_template_layout_free:
- *   @layout: Layout to free.
- *
- * This function frees all memory associated with given template layout structure.
- *
- */
-void
-lgl_template_layout_free (lglTemplateLayout *layout)
-{
-       g_free (layout);
-}
-
-
-/**
- * lgl_template_markup_dup:
- *   @orig_markup: Markup to duplicate.
- *
- * This function duplicates a template markup structure.
- *
- * Returns:  a newly allocated #lglTemplateMarkup structure.
- *
- */
-lglTemplateMarkup *
-lgl_template_markup_dup (const lglTemplateMarkup *orig_markup)
-{
-       lglTemplateMarkup *markup;
-
-       g_return_val_if_fail (orig_markup, NULL);
-
-       markup = g_new0 (lglTemplateMarkup, 1);
-
-       *markup = *orig_markup;
-
-       return markup;
-}
-
-
-/**
- * lgl_template_markup_free:
- *   @markup: Markup to free.
- *
- * This function frees all memory associated with given template markup structure.
- *
- */
-void
-lgl_template_markup_free (lglTemplateMarkup *markup)
-{
-       g_free (markup);
-}
-
-
-static gint
-compare_origins (gconstpointer a,
-                gconstpointer b,
-                gpointer      user_data)
-{
-       const lglTemplateOrigin *a_origin = a, *b_origin = b;
-
-       if ( a_origin->y < b_origin->y ) {
-               return -1;
-       } else if ( a_origin->y > b_origin->y ) {
-               return +1;
-       } else {
-               if ( a_origin->x < b_origin->x ) {
-                       return -1;
-               } else if ( a_origin->x > b_origin->x ) {
-                       return +1;
-               } else {
-                       return 0; /* hopefully 2 labels won't have the same origin */
-               }
-       }
-}
-
-
-/**
- * lgl_template_print:
- *   @template: template
- *
- * Print template details (for debugging purposes).
- *
- */
-void
-lgl_template_print (const lglTemplate *template)
-{
-        g_print ("---- %s( TEMPLATE=%p ) ----\n", __FUNCTION__, template);
-
-        g_print("brand=\"%s\", part=\"%s\", description=\"%s\"\n",
-                template->brand, template->part, template->description);
-
-        g_print("paper_id=\"%s\", page_width=%g, page_height=%g\n",
-                template->paper_id, template->page_width, template->page_height);
-
-        g_print ("\n");
-
-}
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/template.h b/libglabels/template.h
deleted file mode 100644 (file)
index 74e50cf..0000000
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- *  template.h
- *  Copyright (C) 2001-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __LGL_TEMPLATE_H__
-#define __LGL_TEMPLATE_H__
-
-#include <glib.h>
-#include "units.h"
-
-G_BEGIN_DECLS
-
-typedef struct _lglTemplate                lglTemplate;
-
-typedef union  _lglTemplateFrame           lglTemplateFrame;
-typedef struct _lglTemplateFrameAll        lglTemplateFrameAll;
-typedef struct _lglTemplateFrameRect       lglTemplateFrameRect;
-typedef struct _lglTemplateFrameEllipse    lglTemplateFrameEllipse;
-typedef struct _lglTemplateFrameRound      lglTemplateFrameRound;
-typedef struct _lglTemplateFrameCD         lglTemplateFrameCD;
-
-typedef struct _lglTemplateLayout          lglTemplateLayout;
-
-typedef union  _lglTemplateMarkup          lglTemplateMarkup;
-typedef struct _lglTemplateMarkupMargin    lglTemplateMarkupMargin;
-typedef struct _lglTemplateMarkupLine      lglTemplateMarkupLine;
-typedef struct _lglTemplateMarkupCircle    lglTemplateMarkupCircle;
-typedef struct _lglTemplateMarkupRect      lglTemplateMarkupRect;
-typedef struct _lglTemplateMarkupEllipse   lglTemplateMarkupEllipse;
-
-typedef struct _lglTemplateOrigin          lglTemplateOrigin;
-
-/*
- *   Top-level Template Structure
- */
-struct _lglTemplate {
-
-       gchar               *brand;
-        gchar               *part;
-        gchar               *equiv_part;
-
-       gchar               *description;
-       gchar               *paper_id;
-       gdouble              page_width;
-       gdouble              page_height;
-
-        /* Meta information. */
-        gchar               *product_url;   /* URL to manufacturer's product website. */
-       GList               *category_ids;  /* List of (gchar *) category ids. */
-
-       /* List of (lglTemplateFrame *) label frame structures.
-        * Currently glabels only supports a single label frame per
-        * template. */
-       GList               *frames;
-
-};
-
-
-/*
- *   Possible Frame Shapes
- */
-typedef enum {
-       LGL_TEMPLATE_FRAME_SHAPE_RECT,
-       LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE,
-       LGL_TEMPLATE_FRAME_SHAPE_ROUND,
-       LGL_TEMPLATE_FRAME_SHAPE_CD,
-} lglTemplateFrameShape;
-
-
-/*
- *   Frame Structure
- */
-struct _lglTemplateFrameAll {
-
-        /* Begin Common Fields */
-       lglTemplateFrameShape shape;
-
-       gchar                *id;       /* Id, currently always "0" */
-       GList                *layouts;  /* List of lglTemplateLayouts */
-       GList                *markups;  /* List of lglTemplateMarkups */
-        /* End Common Fields */
-};
-
-struct _lglTemplateFrameRect {
-
-        /* Begin Common Fields */
-       lglTemplateFrameShape shape;    /* Always LGL_TEMPLATE_FRAME_SHAPE_RECT. */
-
-       gchar                *id;       /* Id, currently always "0" */
-       GList                *layouts;  /* List of lglTemplateLayouts */
-       GList                *markups;  /* List of lglTemplateMarkups */
-        /* End Common Fields */
-
-        gdouble               w;        /* Width */
-        gdouble               h;        /* Height */
-        gdouble               r;        /* Corner radius */
-        gdouble               x_waste;  /* Amount of horiz overprint allowed. */
-        gdouble               y_waste;  /* Amount of vert overprint allowed. */
-};
-
-struct _lglTemplateFrameEllipse {
-
-        /* Begin Common Fields */
-       lglTemplateFrameShape shape;    /* Always LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE. */
-
-       gchar                *id;       /* Id, currently always "0" */
-       GList                *layouts;  /* List of lglTemplateLayouts */
-       GList                *markups;  /* List of lglTemplateMarkups */
-        /* End Common Fields */
-
-        gdouble               w;        /* Width */
-        gdouble               h;        /* Height */
-        gdouble               waste;    /* Amount of overprint allowed. */
-};
-
-struct _lglTemplateFrameRound {
-
-        /* Begin Common Fields */
-       lglTemplateFrameShape shape;    /* Always LGL_TEMPLATE_FRAME_SHAPE_ROUND. */
-
-       gchar                *id;       /* Id, currently always "0" */
-       GList                *layouts;  /* List of lglTemplateLayouts */
-       GList                *markups;  /* List of lglTemplateMarkups */
-        /* End Common Fields */
-
-        gdouble               r;      /* Radius */
-        gdouble               waste;  /* Amount of overprint allowed. */
-};
-
-struct _lglTemplateFrameCD {
-
-        /* Begin Common Fields */
-       lglTemplateFrameShape shape;    /* Always LGL_TEMPLATE_FRAME_SHAPE_CD. */
-
-       gchar                *id;       /* Id, currently always "0" */
-       GList                *layouts;  /* List of lglTemplateLayouts */
-       GList                *markups;  /* List of lglTemplateMarkups */
-        /* End Common Fields */
-
-        gdouble               r1;     /* Outer radius */
-        gdouble               r2;     /* Inner radius (hole) */
-        gdouble               w;      /* Clip width, business card CDs */
-        gdouble               h;      /* Clip height, business card CDs */
-        gdouble               waste;  /* Amount of overprint allowed. */
-};
-
-union _lglTemplateFrame{
-
-       lglTemplateFrameShape   shape;
-
-       lglTemplateFrameAll     all;
-       lglTemplateFrameRect    rect;
-       lglTemplateFrameEllipse ellipse;
-       lglTemplateFrameRound   round;
-       lglTemplateFrameCD      cd;
-};
-
-
-/*
- *   Label Layout Structure
- */
-struct _lglTemplateLayout {
-
-       gint                  nx;  /* Number of labels across */
-       gint                  ny;  /* Number of labels up and down */
-
-       gdouble               x0;  /* Left of grid from left edge of paper */
-       gdouble               y0;  /* Top of grid from top edge of paper */
-
-       gdouble               dx;  /* Horizontal pitch of grid */
-       gdouble               dy;  /* Vertical pitch of grid */
-
-};
-
-
-/*
- * Possible Markup Types
- */
-typedef enum {
-       LGL_TEMPLATE_MARKUP_MARGIN,
-       LGL_TEMPLATE_MARKUP_LINE,
-       LGL_TEMPLATE_MARKUP_CIRCLE,
-       LGL_TEMPLATE_MARKUP_RECT,
-       LGL_TEMPLATE_MARKUP_ELLIPSE,
-} lglTemplateMarkupType;
-
-
-/*
- *   Label Markup Structure (Helpful lines drawn in glabels to help locate objects)
- */
-struct _lglTemplateMarkupMargin {
-
-       lglTemplateMarkupType  type;  /* Always LGL_TEMPLATE_MARKUP_MARGIN */
-
-        gdouble                size;  /* Margin size */
-};
-
-struct _lglTemplateMarkupLine {
-
-       lglTemplateMarkupType  type;   /* Always LGL_TEMPLATE_MARKUP_LINE */
-
-        gdouble                x1, y1; /* 1st endpoint */
-        gdouble                x2, y2; /* 2nd endpoint */
-};
-
-struct _lglTemplateMarkupCircle {
-
-       lglTemplateMarkupType  type;   /* Always LGL_TEMPLATE_MARKUP_CIRCLE */
-
-        gdouble                x0, y0; /* Center of circle */
-        gdouble                r;      /* Radius of circle */
-};
-
-struct _lglTemplateMarkupRect {
-
-       lglTemplateMarkupType  type;   /* Always LGL_TEMPLATE_MARKUP_RECT */
-
-        gdouble                x1, y1; /* Upper left corner */
-        gdouble                w, h;   /* Width and height. */
-        gdouble                r;      /* Radius of corners. */
-};
-
-struct _lglTemplateMarkupEllipse {
-
-       lglTemplateMarkupType  type;   /* Always LGL_TEMPLATE_MARKUP_ELLIPSE */
-
-        gdouble                x1, y1; /* Upper left corner */
-        gdouble                w, h;   /* Width and height. */
-};
-
-union _lglTemplateMarkup {
-
-       lglTemplateMarkupType    type;
-
-       lglTemplateMarkupMargin  margin;
-       lglTemplateMarkupLine    line;
-       lglTemplateMarkupCircle  circle;
-       lglTemplateMarkupRect    rect;
-       lglTemplateMarkupEllipse ellipse;
-};
-
-
-/*
- *  Origin coordinates
- */
-struct _lglTemplateOrigin {
-
-       gdouble               x, y; /* Label origin relative to upper 
-                                    * upper left hand corner of paper */
-
-};
-
-
-
-/* 
- * Template query functions
- */
-gchar                     *lgl_template_get_name                (const lglTemplate   *template);
-
-gboolean                   lgl_template_do_templates_match      (const lglTemplate   *template1,
-                                                                 const lglTemplate   *template2);
-
-gboolean                   lgl_template_does_brand_match        (const lglTemplate   *template,
-                                                                 const gchar         *brand);
-
-gboolean                   lgl_template_does_page_size_match    (const lglTemplate   *template,
-                                                                 const gchar         *paper_id);
-
-gboolean                   lgl_template_does_category_match     (const lglTemplate   *template,
-                                                                 const gchar         *category_id);
-
-gboolean                   lgl_template_are_templates_identical (const lglTemplate   *template1,
-                                                                 const lglTemplate   *template2);
-
-
-
-
-/*
- * Frame query functions
- */
-void                 lgl_template_frame_get_size       (const lglTemplateFrame    *frame,
-                                                        gdouble                   *w,
-                                                        gdouble                   *h);
-
-gint                 lgl_template_frame_get_n_labels   (const lglTemplateFrame    *frame);
-
-lglTemplateOrigin   *lgl_template_frame_get_origins    (const lglTemplateFrame    *frame);
-
-gchar               *lgl_template_frame_get_layout_description (const lglTemplateFrame *frame);
-
-gchar               *lgl_template_frame_get_size_description   (const lglTemplateFrame *frame,
-                                                                lglUnits                units);
-
-
-
-
-/*
- * Template Construction
- */
-lglTemplate         *lgl_template_new                  (const gchar          *brand,
-                                                        const gchar          *part,
-                                                        const gchar          *description,
-                                                        const gchar          *paper_id,
-                                                        gdouble               page_width,
-                                                        gdouble               page_height);
-
-lglTemplate         *lgl_template_new_from_equiv       (const gchar          *brand,
-                                                        const gchar          *part,
-                                                        const gchar          *equiv_part);
-
-void                 lgl_template_add_category         (lglTemplate          *template,
-                                                        const gchar          *category_id);
-
-void                 lgl_template_add_frame            (lglTemplate          *template,
-                                                        lglTemplateFrame     *frame);
-
-lglTemplateFrame    *lgl_template_frame_rect_new       (const gchar          *id,
-                                                        gdouble               w,
-                                                        gdouble               h,
-                                                        gdouble               r,
-                                                        gdouble               x_waste,
-                                                        gdouble               y_waste);
-
-lglTemplateFrame    *lgl_template_frame_ellipse_new    (const gchar          *id,
-                                                        gdouble               w,
-                                                        gdouble               h,
-                                                        gdouble               waste);
-
-lglTemplateFrame    *lgl_template_frame_round_new      (const gchar          *id,
-                                                        gdouble               r,
-                                                        gdouble               waste);
-
-lglTemplateFrame    *lgl_template_frame_cd_new         (const gchar          *id,
-                                                        gdouble               r1,
-                                                        gdouble               r2,
-                                                        gdouble               w,
-                                                        gdouble               h,
-                                                        gdouble               waste);
-
-void                 lgl_template_frame_add_layout     (lglTemplateFrame     *frame,
-                                                        lglTemplateLayout    *layout);
-
-void                 lgl_template_frame_add_markup     (lglTemplateFrame     *frame,
-                                                        lglTemplateMarkup    *markup);
-
-lglTemplateLayout   *lgl_template_layout_new           (gint                  nx,
-                                                        gint                  ny,
-                                                        gdouble               x0,
-                                                        gdouble               y0,
-                                                        gdouble               dx,
-                                                        gdouble               dy);
-
-lglTemplateMarkup   *lgl_template_markup_margin_new    (gdouble               size);
-
-lglTemplateMarkup   *lgl_template_markup_line_new      (gdouble               x1,
-                                                        gdouble               y1,
-                                                        gdouble               x2,
-                                                        gdouble               y2);
-
-lglTemplateMarkup   *lgl_template_markup_circle_new    (gdouble               x0,
-                                                        gdouble               y0,
-                                                        gdouble               r);
-
-lglTemplateMarkup   *lgl_template_markup_rect_new      (gdouble               x1,
-                                                        gdouble               y1,
-                                                        gdouble               w,
-                                                        gdouble               h,
-                                                        gdouble               r);
-
-lglTemplateMarkup   *lgl_template_markup_ellipse_new   (gdouble               x1,
-                                                        gdouble               y1,
-                                                        gdouble               w,
-                                                        gdouble               h);
-
-lglTemplate         *lgl_template_dup                  (const lglTemplate    *orig_template);
-
-void                 lgl_template_free                 (lglTemplate          *template);
-
-lglTemplateFrame    *lgl_template_frame_dup            (const lglTemplateFrame     *orig_frame);
-void                 lgl_template_frame_free           (lglTemplateFrame           *frame);
-
-lglTemplateLayout   *lgl_template_layout_dup           (const lglTemplateLayout    *orig_layout);
-void                 lgl_template_layout_free          (lglTemplateLayout          *layout);
-
-lglTemplateMarkup   *lgl_template_markup_dup           (const lglTemplateMarkup    *orig_markup);
-void                 lgl_template_markup_free          (lglTemplateMarkup          *markup);
-
-
-/*
- * Debugging functions.
- */
-void                 lgl_template_print                (const lglTemplate          *template);
-
-
-G_END_DECLS
-
-#endif /* __LGL_TEMPLATE_H__ */
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/units.c b/libglabels/units.c
deleted file mode 100644 (file)
index e585962..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- *  units.c
- *  Copyright (C) 2003-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-
-#include "units.h"
-
-#include <glib/gi18n.h>
-#include <glib.h>
-#include <string.h>
-
-#include "libglabels-private.h"
-
-
-/*========================================================*/
-/* Private macros and constants.                          */
-/*========================================================*/
-
-#define POINTS_PER_POINT    1.0 /* internal units are points. */
-#define POINTS_PER_INCH    72.0
-#define POINTS_PER_MM       2.83464566929
-#define POINTS_PER_CM       (10.0*POINTS_PER_MM)
-#define POINTS_PER_PICA     (1.0/12.0)
-
-
-/*========================================================*/
-/* Private types.                                         */
-/*========================================================*/
-
-typedef struct {
-       gchar       *id;
-       gchar       *name;
-       gdouble      points_per_unit;
-} UnitTableEntry;
-
-
-/*========================================================*/
-/* Private globals.                                       */
-/*========================================================*/
-
-static UnitTableEntry unit_table[] = {
-
-       /* The ids are identical to the absolute length units supported in
-          the CSS2 Specification (Section 4.3.2) */
-
-       /* This table must be sorted exactly as the enumerations in lglUnits */
-
-       /* [LGL_UNITS_POINT] */   {"pt", N_("points"), POINTS_PER_POINT},
-       /* [LGL_UNITS_INCH]  */   {"in", N_("inches"), POINTS_PER_INCH},
-       /* [LGL_UNITS_MM]    */   {"mm", N_("mm"),     POINTS_PER_MM},
-       /* [LGL_UNITS_CM]    */   {"cm", N_("cm"),     POINTS_PER_CM},
-       /* [LGL_UNITS_PICA]  */   {"pc", N_("picas"),  POINTS_PER_PICA},
-
-};
-
-
-
-/**
- * lgl_units_get_id:
- * @units:       Units (#lglUnits)
- *
- * Return a unique ID string for the given units.  This ID is how units
- * are encoded in libglabels XML files and will remain constant across
- * all locales.  IDs are identical to the absolute length units supported
- * in the CSS2 Specification (Section 4.3.2). 
- *
- * Returns: ID string.
- *
- */
-const gchar *
-lgl_units_get_id (lglUnits     units)
-{
-        if ( (units >= LGL_UNITS_FIRST) && (units <= LGL_UNITS_LAST) )
-        {
-                return unit_table[units].id;
-        }
-        else
-        {
-                /* Default to "pt", if invalid. */
-                return unit_table[LGL_UNITS_POINT].id;
-        }
-}
-
-
-/**
- * lgl_units_from_id:
- * @id:       ID string
- *
- * Return the unique #lglUnits for the given ID string.
- * This ID is how units are encoded in libglabels XML files and will remain
- * constant across all locales.  IDs are identical to the absolute length
- * units supported in the CSS2 Specification (Section 4.3.2). 
- *
- * Returns: units (#lglUnits).
- *
- */
-lglUnits
-lgl_units_from_id (const gchar *id)
-{
-        lglUnits units;
-
-        /* An empty or missing id defaults to points. */
-        if ( (id == NULL) || (strlen (id) == 0) )
-        {
-                return LGL_UNITS_POINT;
-        }
-
-        for ( units = LGL_UNITS_FIRST; units <= LGL_UNITS_LAST; units++) {
-                if (g_ascii_strcasecmp (id, unit_table[units].id) == 0) {
-                        return units;
-                }
-        }
-
-        /* Try name as a fallback. (Will catch some legacy preferences.) */
-        for ( units = LGL_UNITS_FIRST; units <= LGL_UNITS_LAST; units++) {
-                if (g_ascii_strcasecmp (id, unit_table[units].name) == 0) {
-                        return units;
-                }
-        }
-
-        /* For compatibility with old preferences. */
-        if (g_ascii_strcasecmp (id, "Millimeters") == 0) {
-                return LGL_UNITS_MM;
-        }
-
-        return LGL_UNITS_INVALID;
-}
-
-
-/**
- * lgl_units_get_name:
- * @units:       Units (#lglUnits)
- *
- * Return a unique name string for the given units.  This name is human
- * readable and will be translated to the current locale.
- *
- * Returns: name string.
- *
- */
-const gchar *
-lgl_units_get_name (lglUnits     units)
-{
-        if ( (units >= LGL_UNITS_FIRST) && (units <= LGL_UNITS_LAST) )
-        {
-                return gettext ((char *)unit_table[units].name);
-        }
-        else
-        {
-                /* Default to "points", if invalid. */
-                return gettext ((char *)unit_table[LGL_UNITS_POINT].name);
-        }
-}
-
-
-/**
- * lgl_units_from_name:
- * @name:       NAME string
- *
- * Return the unique #lglUnits for the given name string.  This name is
- * human readable and is expected to be translated to the current locale.
- *
- * Returns: units (#lglUnits).
- *
- */
-lglUnits
-lgl_units_from_name (const gchar *name)
-{
-        lglUnits units;
-
-        for ( units = LGL_UNITS_FIRST; units <= LGL_UNITS_LAST; units++) {
-                if (g_ascii_strcasecmp (name, gettext ((char *)unit_table[units].name) ) == 0) {
-                        return units;
-                }
-        }
-
-        return LGL_UNITS_INVALID;
-}
-
-
-/**
- * lgl_units_get_points_per_unit:
- * @units:       Units (#lglUnits)
- *
- * Return a scale factor for the given units in points/unit.
- *
- * Returns: scale factor.
- *
- */
-gdouble
-lgl_units_get_points_per_unit (lglUnits     units)
-{
-        if ( (units >= LGL_UNITS_FIRST) && (units <= LGL_UNITS_LAST) )
-        {
-                return unit_table[units].points_per_unit;
-        }
-        else
-        {
-                /* Default to "points", if invalid. */
-                return 1.0;
-        }
-}
-
-
-/**
- * lgl_units_get_units_per_point:
- * @units:       Units (#lglUnits)
- *
- * Return a scale factor for the given units in units/point.
- *
- * Returns: scale factor.
- *
- */
-gdouble
-lgl_units_get_units_per_point (lglUnits     units)
-{
-        if ( (units >= LGL_UNITS_FIRST) && (units <= LGL_UNITS_LAST) )
-        {
-                return 1.0 / unit_table[units].points_per_unit;
-        }
-        else
-        {
-                /* Default to "points", if invalid. */
-                return 1.0;
-        }
-}
-
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/units.h b/libglabels/units.h
deleted file mode 100644 (file)
index ac3bb0c..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- *  units.h
- *  Copyright (C) 2003-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __LGL_UNITS_H__
-#define __LGL_UNITS_H__
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-
-/*
- * Units of distance
- */
-typedef enum {
-       LGL_UNITS_POINT, /* encoded as "pt" */
-       LGL_UNITS_INCH,  /* encoded as "in" */
-       LGL_UNITS_MM,    /* encoded as "mm" */
-       LGL_UNITS_CM,    /* encoded as "cm" */
-       LGL_UNITS_PICA,  /* encoded as "pc" */
-
-       LGL_UNITS_FIRST = LGL_UNITS_POINT,
-       LGL_UNITS_LAST  = LGL_UNITS_PICA,
-
-        LGL_UNITS_INVALID = -1,
-} lglUnits;
-
-
-const gchar *lgl_units_get_id               (lglUnits     units);
-lglUnits     lgl_units_from_id              (const gchar *id);
-
-const gchar *lgl_units_get_name             (lglUnits     units);
-lglUnits     lgl_units_from_name            (const gchar *name);
-
-gdouble      lgl_units_get_points_per_unit  (lglUnits     units);
-gdouble      lgl_units_get_units_per_point  (lglUnits     units);
-
-
-G_END_DECLS
-
-
-#endif /* __LGL_UNITS_H__ */
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/vendor.c b/libglabels/vendor.c
deleted file mode 100644 (file)
index e7f950b..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- *  vendor.c
- *  Copyright (C) 2003-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-
-#include "vendor.h"
-
-#include <glib/gi18n.h>
-#include <glib.h>
-#include <string.h>
-
-#include "libglabels-private.h"
-
-/*===========================================*/
-/* Private types                             */
-/*===========================================*/
-
-
-/*===========================================*/
-/* Private globals                           */
-/*===========================================*/
-
-
-/*===========================================*/
-/* Local function prototypes                 */
-/*===========================================*/
-
-
-/*===========================================*/
-/* Functions.                                */
-/*===========================================*/
-
-/**
- * lgl_vendor_new:
- * @name:     Localized name of vendor.
- *
- * Allocates and constructs a new #lglVendor structure.
- *
- * Returns: a pointer to a newly allocated #lglVendor structure.
- *
- */
-lglVendor *
-lgl_vendor_new (gchar             *name)
-{
-       lglVendor *vendor;
-
-       vendor           = g_new0 (lglVendor,1);
-
-       vendor->name     = g_strdup (name);
-
-       return vendor;
-}
-
-
-/**
- * lgl_vendor_dup:
- * @orig:  #lglVendor structure to be duplicated.
- *
- * Duplicates an existing #lglVendor structure.
- *
- * Returns: a pointer to a newly allocated #lglVendor structure.
- *
- */
-lglVendor *lgl_vendor_dup (const lglVendor *orig)
-{
-       lglVendor       *vendor;
-
-       g_return_val_if_fail (orig, NULL);
-
-       vendor = g_new0 (lglVendor,1);
-
-       vendor->name  = g_strdup (orig->name);
-       vendor->url   = g_strdup (orig->url);
-
-       return vendor;
-}
-
-
-/**
- * lgl_vendor_free:
- * @vendor:  pointer to #lglVendor structure to be freed.
- *
- * Free all memory associated with an existing #lglVendor structure.
- *
- */
-void lgl_vendor_free (lglVendor *vendor)
-{
-
-       if ( vendor != NULL ) {
-
-               g_free (vendor->name);
-               vendor->name = NULL;
-
-               g_free (vendor->url);
-               vendor->url = NULL;
-
-               g_free (vendor);
-       }
-
-}
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/vendor.h b/libglabels/vendor.h
deleted file mode 100644 (file)
index 68b9ff5..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *  vendor.h
- *  Copyright (C) 2003-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __LGL_VENDOR_H__
-#define __LGL_VENDOR_H__
-
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-
-/*
- *   lglVendor structure
- */
-typedef struct _lglVendor lglVendor;
-
-struct _lglVendor {
-       gchar               *name;           /* Vendor name */
-       gchar               *url;            /* Vendor URL */
-};
-
-
-/*
- * Vendor construction
- */
-lglVendor           *lgl_vendor_new                (gchar           *name);
-
-lglVendor           *lgl_vendor_dup                (const lglVendor *orig);
-
-void                 lgl_vendor_free               (lglVendor       *vendor);
-
-
-G_END_DECLS
-
-#endif /* __LGL_VENDOR_H__ */
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/xml-category.c b/libglabels/xml-category.c
deleted file mode 100644 (file)
index 4925eba..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- *  xml-category.c
- *  Copyright (C) 2006-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-
-#include "xml-category.h"
-
-#include <glib/gi18n.h>
-#include <glib.h>
-#include <string.h>
-#include <libintl.h>
-
-#include "libglabels-private.h"
-
-#include "xml.h"
-
-/*===========================================*/
-/* Private types                             */
-/*===========================================*/
-
-/*===========================================*/
-/* Private globals                           */
-/*===========================================*/
-
-/*===========================================*/
-/* Local function prototypes                 */
-/*===========================================*/
-
-
-/**
- * lgl_xml_category_read_categories_from_file:
- * @utf8_filename:       Filename of categories file (name encoded as UTF-8)
- *
- * Read category definitions from a file.
- *
- * Returns: a list of #lglCategory structures.
- *
- */
-GList *
-lgl_xml_category_read_categories_from_file (gchar *utf8_filename)
-{
-       gchar      *filename;
-       GList      *categories;
-       xmlDocPtr   categories_doc;
-
-       LIBXML_TEST_VERSION;
-
-       filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
-       if (!filename) {
-               g_message ("Utf8 filename conversion error");
-               return NULL;
-       }
-
-       categories_doc = xmlParseFile (filename);
-       if (!categories_doc) {
-               g_message ("\"%s\" is not a glabels category file (not XML)",
-                          filename);
-               return NULL;
-       }
-
-       categories = lgl_xml_category_parse_categories_doc (categories_doc);
-
-       g_free (filename);
-       xmlFreeDoc (categories_doc);
-
-       return categories;
-}
-
-
-/**
- * lgl_xml_category_parse_categories_doc:
- * @categories_doc:  libxml #xmlDocPtr tree, representing a categories
- * definition file.
- *
- * Read category definitions from a libxml #xmlDocPtr tree.
- *
- * Returns: a list of #lglCategory structures.
- *
- */
-GList *
-lgl_xml_category_parse_categories_doc (xmlDocPtr  categories_doc)
-{
-       GList       *categories = NULL;
-       xmlNodePtr   root, node;
-       lglCategory *category;
-
-       LIBXML_TEST_VERSION;
-
-       root = xmlDocGetRootElement (categories_doc);
-       if (!root || !root->name) {
-               g_message ("\"%s\" is not a glabels category file (no root node)",
-                          categories_doc->name);
-               xmlFreeDoc (categories_doc);
-               return categories;
-       }
-       if (!lgl_xml_is_node (root, "Glabels-categories")) {
-               g_message ("\"%s\" is not a glabels category file (wrong root node)",
-                          categories_doc->name);
-               xmlFreeDoc (categories_doc);
-               return categories;
-       }
-
-       for (node = root->xmlChildrenNode; node != NULL; node = node->next) {
-
-               if (lgl_xml_is_node (node, "Category")) {
-                       category = lgl_xml_category_parse_category_node (node);
-                       categories = g_list_append (categories, category);
-               } else {
-                       if ( !xmlNodeIsText(node) ) {
-                               if (!lgl_xml_is_node (node, "comment")) {
-                                       g_message ("bad node =  \"%s\"",node->name);
-                               }
-                       }
-               }
-       }
-
-       return categories;
-}
-
-
-/**
- * lgl_xml_category_parse_category_node:
- * @category_node:  libxml #xmlNodePtr category node from a #xmlDocPtr tree.
- *
- * Read a single category definition from a libxml #xmlNodePtr node.
- *
- * Returns: a pointer to a newly created #lglCategory structure.
- *
- */
-lglCategory *
-lgl_xml_category_parse_category_node (xmlNodePtr category_node)
-{
-       lglCategory           *category;
-       gchar                 *id, *name;
-
-       LIBXML_TEST_VERSION;
-
-       id   = lgl_xml_get_prop_string (category_node, "id", NULL);
-       name = lgl_xml_get_prop_i18n_string (category_node, "name", NULL);
-
-       category = lgl_category_new (id, name);
-
-       g_free (id);
-       g_free (name);
-
-       return category;
-}
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/xml-category.h b/libglabels/xml-category.h
deleted file mode 100644 (file)
index acfc5a5..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *  xml-category.h
- *  Copyright (C) 2006-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __LGL_XML_CATEGORY_H__
-#define __LGL_XML_CATEGORY_H__
-
-#include <glib.h>
-#include <libxml/tree.h>
-
-#include "category.h"
-
-G_BEGIN_DECLS
-
-GList       *lgl_xml_category_read_categories_from_file (gchar        *utf8_filename);
-
-GList       *lgl_xml_category_parse_categories_doc      (xmlDocPtr     categories_doc);
-
-lglCategory *lgl_xml_category_parse_category_node       (xmlNodePtr    category_node);
-
-
-G_END_DECLS
-
-#endif /* __LGL_XML_CATEGORY_H__ */
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/xml-paper.c b/libglabels/xml-paper.c
deleted file mode 100644 (file)
index 00263e7..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- *  xml-paper.c
- *  Copyright (C) 2003-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-
-#include "xml-paper.h"
-
-#include <glib/gi18n.h>
-#include <glib.h>
-#include <string.h>
-#include <libintl.h>
-
-#include "libglabels-private.h"
-
-#include "xml.h"
-
-/*===========================================*/
-/* Private types                             */
-/*===========================================*/
-
-/*===========================================*/
-/* Private globals                           */
-/*===========================================*/
-
-/*===========================================*/
-/* Local function prototypes                 */
-/*===========================================*/
-
-
-/**
- * lgl_xml_paper_read_papers_from_file:
- * @utf8_filename:       Filename of papers file (name encoded as UTF-8)
- *
- * Read paper definitions from a file.
- *
- * Returns: a list of #lglPaper structures.
- *
- */
-GList *
-lgl_xml_paper_read_papers_from_file (gchar *utf8_filename)
-{
-       gchar      *filename;
-       GList      *papers;
-       xmlDocPtr   papers_doc;
-
-       LIBXML_TEST_VERSION;
-
-       filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
-       if (!filename) {
-               g_message ("Utf8 filename conversion error");
-               return NULL;
-       }
-
-       papers_doc = xmlParseFile (filename);
-       if (!papers_doc) {
-               g_message ("\"%s\" is not a glabels paper file (not XML)",
-                          filename);
-               return NULL;
-       }
-
-       papers = lgl_xml_paper_parse_papers_doc (papers_doc);
-
-       g_free (filename);
-       xmlFreeDoc (papers_doc);
-
-       return papers;
-}
-
-
-/**
- * lgl_xml_paper_parse_papers_doc:
- * @papers_doc:  libxml #xmlDocPtr tree, representing a papers definition file.
- *
- * Read paper definitions from a libxml #xmlDocPtr tree.
- *
- * Returns: a list of #lglPaper structures.
- *
- */
-GList *
-lgl_xml_paper_parse_papers_doc (xmlDocPtr  papers_doc)
-{
-       GList      *papers = NULL;
-       xmlNodePtr  root, node;
-       lglPaper   *paper;
-
-       LIBXML_TEST_VERSION;
-
-       root = xmlDocGetRootElement (papers_doc);
-       if (!root || !root->name) {
-               g_message ("\"%s\" is not a glabels paper file (no root node)",
-                          papers_doc->name);
-               xmlFreeDoc (papers_doc);
-               return papers;
-       }
-       if (!lgl_xml_is_node (root, "Glabels-paper-sizes")) {
-               g_message ("\"%s\" is not a glabels paper file (wrong root node)",
-                          papers_doc->name);
-               xmlFreeDoc (papers_doc);
-               return papers;
-       }
-
-       for (node = root->xmlChildrenNode; node != NULL; node = node->next) {
-
-               if (lgl_xml_is_node (node, "Paper-size")) {
-                       paper = lgl_xml_paper_parse_paper_node (node);
-                       papers = g_list_append (papers, paper);
-               } else {
-                       if ( !xmlNodeIsText(node) ) {
-                               if (!lgl_xml_is_node (node, "comment")) {
-                                       g_message ("bad node =  \"%s\"",node->name);
-                               }
-                       }
-               }
-       }
-
-       return papers;
-}
-
-
-/**
- * lgl_xml_paper_parse_paper_node:
- * @paper_node:  libxml #xmlNodePtr paper node from a #xmlDocPtr tree.
- *
- * Read a single paper definition from a libxml #xmlNodePtr node.
- *
- * Returns: a pointer to a newly created #lglPaper structure.
- *
- */
-lglPaper *
-lgl_xml_paper_parse_paper_node (xmlNodePtr paper_node)
-{
-       lglPaper              *paper;
-       gchar                 *id, *name, *pwg_size;
-       gdouble                width, height;
-
-       LIBXML_TEST_VERSION;
-
-       id   = lgl_xml_get_prop_string (paper_node, "id", NULL);
-
-       name = lgl_xml_get_prop_i18n_string (paper_node, "name", NULL);
-
-       width  = lgl_xml_get_prop_length (paper_node, "width", 0);
-       height = lgl_xml_get_prop_length (paper_node, "height", 0);
-
-       pwg_size = lgl_xml_get_prop_string (paper_node, "pwg_size", NULL);
-
-       paper = lgl_paper_new (id, name, width, height, pwg_size);
-
-       g_free (id);
-       g_free (name);
-       g_free (pwg_size);
-
-       return paper;
-}
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/xml-paper.h b/libglabels/xml-paper.h
deleted file mode 100644 (file)
index 71c3087..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *  xml-paper.h
- *  Copyright (C) 2003-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __LGL_XML_PAPER_H__
-#define __LGL_XML_PAPER_H__
-
-#include <glib.h>
-#include <libxml/tree.h>
-
-#include "paper.h"
-
-G_BEGIN_DECLS
-
-GList       *lgl_xml_paper_read_papers_from_file (gchar        *utf8_filename);
-
-GList       *lgl_xml_paper_parse_papers_doc      (xmlDocPtr     papers_doc);
-
-lglPaper    *lgl_xml_paper_parse_paper_node      (xmlNodePtr    paper_node);
-
-
-G_END_DECLS
-
-#endif /* __LGL_XML_PAPER_H__ */
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/xml-template.c b/libglabels/xml-template.c
deleted file mode 100644 (file)
index 8e9f5b3..0000000
+++ /dev/null
@@ -1,1105 +0,0 @@
-/*
- *  xml-template.c
- *  Copyright (C) 2001-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-
-#include "xml-template.h"
-
-#include <glib/gi18n.h>
-#include <glib.h>
-#include <string.h>
-#include <libintl.h>
-
-#include "libglabels-private.h"
-
-#include "db.h"
-#include "xml.h"
-
-/*===========================================*/
-/* Private types                             */
-/*===========================================*/
-
-/*===========================================*/
-/* Private globals                           */
-/*===========================================*/
-
-/*===========================================*/
-/* Local function prototypes                 */
-/*===========================================*/
-static void  xml_parse_meta_node            (xmlNodePtr              label_node,
-                                            lglTemplate            *template);
-static void  xml_parse_label_rectangle_node (xmlNodePtr              label_node,
-                                            lglTemplate            *template);
-static void  xml_parse_label_ellipse_node   (xmlNodePtr              label_node,
-                                            lglTemplate            *template);
-static void  xml_parse_label_round_node     (xmlNodePtr              label_node,
-                                            lglTemplate            *template);
-static void  xml_parse_label_cd_node        (xmlNodePtr              label_node,
-                                            lglTemplate            *template);
-static void  xml_parse_layout_node          (xmlNodePtr              layout_node,
-                                            lglTemplateFrame       *frame);
-static void  xml_parse_markup_margin_node   (xmlNodePtr              markup_node,
-                                            lglTemplateFrame       *frame);
-static void  xml_parse_markup_line_node     (xmlNodePtr              markup_node,
-                                            lglTemplateFrame       *frame);
-static void  xml_parse_markup_circle_node   (xmlNodePtr              markup_node,
-                                            lglTemplateFrame       *frame);
-static void  xml_parse_markup_rect_node     (xmlNodePtr              markup_node,
-                                            lglTemplateFrame       *frame);
-static void  xml_parse_markup_ellipse_node  (xmlNodePtr              markup_node,
-                                            lglTemplateFrame       *frame);
-static void  xml_parse_alias_node           (xmlNodePtr              alias_node,
-                                            lglTemplate            *template);
-
-static void  xml_create_meta_node           (const gchar                  *attr,
-                                             const gchar                  *value,
-                                            xmlNodePtr                    root,
-                                            const xmlNsPtr                ns);
-static void  xml_create_label_node          (const lglTemplateFrame       *frame,
-                                            xmlNodePtr                    root,
-                                            const xmlNsPtr                ns);
-static void  xml_create_layout_node         (const lglTemplateLayout      *layout,
-                                            xmlNodePtr                    root,
-                                            const xmlNsPtr                ns);
-static void  xml_create_markup_margin_node  (const lglTemplateMarkup      *margin,
-                                            xmlNodePtr                    root,
-                                            const xmlNsPtr                ns);
-static void  xml_create_markup_line_node    (const lglTemplateMarkup      *line,
-                                            xmlNodePtr                    root,
-                                            const xmlNsPtr                ns);
-static void  xml_create_markup_circle_node  (const lglTemplateMarkup      *circle,
-                                            xmlNodePtr                    root,
-                                            const xmlNsPtr                ns);
-static void  xml_create_markup_rect_node    (const lglTemplateMarkup      *circle,
-                                            xmlNodePtr                    root,
-                                            const xmlNsPtr                ns);
-static void  xml_create_markup_ellipse_node (const lglTemplateMarkup      *circle,
-                                            xmlNodePtr                    root,
-                                            const xmlNsPtr                ns);
-
-
-/**
- * lgl_xml_template_read_templates_from_file:
- * @utf8_filename:       Filename of papers file (name encoded as UTF-8)
- *
- * Read glabels templates from template file.
- *
- */
-void
-lgl_xml_template_read_templates_from_file (const gchar *utf8_filename)
-{
-       gchar      *filename;
-       xmlDocPtr   templates_doc;
-
-       LIBXML_TEST_VERSION;
-
-       filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
-       if (!filename) {
-               g_message ("Utf8 filename conversion error");
-               return;
-       }
-
-       templates_doc = xmlParseFile (filename);
-       if (!templates_doc) {
-               g_message ("\"%s\" is not a glabels template file (not XML)",
-                     filename);
-               return;
-       }
-
-       lgl_xml_template_parse_templates_doc (templates_doc);
-
-       g_free (filename);
-       xmlFreeDoc (templates_doc);
-}
-
-
-/**
- * lgl_xml_template_parse_templates_doc:
- * @templates_doc:  libxml #xmlDocPtr tree, representing template file.
- *
- * Read glabels templates from a libxml #xmlDocPtr tree.
- *
- */
-void
-lgl_xml_template_parse_templates_doc (const xmlDocPtr templates_doc)
-{
-       
-       xmlNodePtr   root, node;
-       lglTemplate *template;
-
-       LIBXML_TEST_VERSION;
-
-       root = xmlDocGetRootElement (templates_doc);
-       if (!root || !root->name)
-        {
-               g_message ("\"%s\" is not a glabels template file (no root node)",
-                          templates_doc->URL);
-               return;
-       }
-       if (!lgl_xml_is_node (root, "Glabels-templates"))
-        {
-               g_message ("\"%s\" is not a glabels template file (wrong root node)",
-                     templates_doc->URL);
-               return;
-       }
-
-       for (node = root->xmlChildrenNode; node != NULL; node = node->next)
-        {
-
-               if (lgl_xml_is_node (node, "Template"))
-                {
-                       template = lgl_xml_template_parse_template_node (node);
-                        if (template)
-                        {
-                                _lgl_db_register_template_internal (template);
-                                lgl_template_free (template);
-                        }
-               }
-                else
-                {
-                       if ( !xmlNodeIsText(node) )
-                        {
-                               if (!lgl_xml_is_node (node,"comment"))
-                                {
-                                       g_message ("bad node =  \"%s\"",node->name);
-                               }
-                       }
-               }
-       }
-}
-
-
-/**
- * lgl_xml_template_parse_template_node:
- * @template_node:  libxml #xmlNodePtr template node from a #xmlDocPtr tree.
- *
- * Read a single glabels template from a libxml #xmlNodePtr node.
- *
- * Returns: a pointer to a newly created #lglTemplate structure.
- *
- */
-lglTemplate *
-lgl_xml_template_parse_template_node (const xmlNodePtr template_node)
-{
-       gchar                 *brand;
-        gchar                 *part;
-       gchar                 *name;
-        gchar                 *equiv_part;
-       gchar                 *description;
-       gchar                 *paper_id;
-       gdouble                page_width, page_height;
-       lglPaper              *paper = NULL;
-       lglTemplate           *template;
-       xmlNodePtr             node;
-        gchar                **v;
-        lglTemplateFrame      *frame;
-
-
-       brand = lgl_xml_get_prop_string (template_node, "brand", NULL);
-       part  = lgl_xml_get_prop_string (template_node, "part", NULL);
-        if (!brand || !part)
-        {
-                name = lgl_xml_get_prop_string (template_node, "name", NULL);
-                if (name)
-                {
-                        v = g_strsplit (name, " ", 2);
-                        brand = g_strdup (v[0]);
-                        part  = g_strchug (g_strdup (v[1]));
-                        g_free (name);
-                        g_strfreev (v);
-                        
-                }
-                else
-                {
-                       g_message ("Missing name or brand/part attributes.");
-                }
-        }
-
-
-        equiv_part = lgl_xml_get_prop_string (template_node, "equiv", NULL);
-
-
-       description = lgl_xml_get_prop_i18n_string (template_node, "description", NULL);
-       paper_id = lgl_xml_get_prop_string (template_node, "size", NULL);
-
-       if (lgl_db_is_paper_id_other (paper_id)) {
-
-               page_width = lgl_xml_get_prop_length (template_node, "width", 0);
-               page_height = lgl_xml_get_prop_length (template_node, "height", 0);
-
-       } else {
-               paper = lgl_db_lookup_paper_from_id (paper_id);
-               if (paper == NULL) {
-                       /* This should always be an id, but just in case a name
-                          slips by! */
-                       g_message ("Unknown page size id \"%s\", trying as name",
-                                  paper_id);
-                       paper = lgl_db_lookup_paper_from_name (paper_id);
-                       g_free (paper_id);
-                       paper_id = g_strdup (paper->id);
-               }
-               if (paper != NULL) {
-                       page_width  = paper->width;
-                       page_height = paper->height;
-               } else {
-                       page_width  = 612;
-                       page_height = 792;
-                       g_message ("Unknown page size id or name \"%s\"",
-                                  paper_id);
-               }
-               lgl_paper_free (paper);
-               paper = NULL;
-       }
-
-
-        if (!equiv_part)
-        {
-                template = lgl_template_new (brand, part, description,
-                                             paper_id, page_width, page_height);
-        }
-        else
-        {
-                template = lgl_template_new_from_equiv (brand, part, equiv_part);
-
-                if (!template)
-                {
-                       g_message ("Forward references not supported.");
-                        return NULL;
-                }
-        }
-
-
-       for (node = template_node->xmlChildrenNode; node != NULL;
-            node = node->next) {
-               if (lgl_xml_is_node (node, "Meta")) {
-                       xml_parse_meta_node (node, template);
-               } else if (lgl_xml_is_node (node, "Label-rectangle")) {
-                       xml_parse_label_rectangle_node (node, template);
-               } else if (lgl_xml_is_node (node, "Label-ellipse")) {
-                       xml_parse_label_ellipse_node (node, template);
-               } else if (lgl_xml_is_node (node, "Label-round")) {
-                       xml_parse_label_round_node (node, template);
-               } else if (lgl_xml_is_node (node, "Label-cd")) {
-                       xml_parse_label_cd_node (node, template);
-               } else if (lgl_xml_is_node (node, "Alias")) {
-                       xml_parse_alias_node (node, template);
-               } else {
-                       if (!xmlNodeIsText (node)) {
-                               if (!lgl_xml_is_node (node,"comment")) {
-                                       g_message ("bad node =  \"%s\"",node->name);
-                               }
-                       }
-               }
-       }
-
-       g_free (brand);
-       g_free (part);
-       g_free (equiv_part);
-       g_free (description);
-       g_free (paper_id);
-
-        /*
-         * Create a default full-page frame, if a known frame type was not found.
-         */
-        if ( template->frames == NULL )
-        {
-                g_message ("%s %s: missing valid frame node", template->brand, template->part);
-                frame = lgl_template_frame_rect_new ("0", page_width, page_height, 0, 0, 0);
-                lgl_template_frame_add_layout (frame, lgl_template_layout_new (1, 1, 0, 0, 0, 0));
-                lgl_template_add_frame (template, frame);
-        }
-
-        /*
-         * Create a default 1x1 layout, if layout is missing.
-         */
-        frame = (lglTemplateFrame *)template->frames->data;
-        if ( frame->all.layouts == NULL )
-        {
-                g_message ("%s %s: missing layout node", template->brand, template->part);
-                lgl_template_frame_add_layout (frame, lgl_template_layout_new (1, 1, 0, 0, 0, 0));
-        }
-
-       return template;
-}
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Parse XML Template->Meta Node.                                 */
-/*--------------------------------------------------------------------------*/
-static void
-xml_parse_meta_node (xmlNodePtr   meta_node,
-                    lglTemplate *template)
-{
-        gchar               *product_url;
-       gchar               *category;
-
-        product_url = lgl_xml_get_prop_string (meta_node, "product_url", NULL);
-        if ( product_url != NULL )
-        {
-                g_free (template->product_url);
-                template->product_url = product_url;
-        }
-
-       category = lgl_xml_get_prop_string (meta_node, "category", NULL);
-       if ( category != NULL )
-       {
-               lgl_template_add_category (template, category);
-               g_free (category);
-       }
-}
-
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Parse XML Template->Label-rectangle Node.                      */
-/*--------------------------------------------------------------------------*/
-static void
-xml_parse_label_rectangle_node (xmlNodePtr   label_node,
-                               lglTemplate *template)
-{
-       gchar               *id;
-       gchar               *tmp;
-       gdouble              x_waste, y_waste;
-       gdouble              w, h, r;
-       lglTemplateFrame    *frame;
-       xmlNodePtr           node;
-
-       id      = lgl_xml_get_prop_string (label_node, "id", NULL);
-
-       if ((tmp = lgl_xml_get_prop_string (label_node, "waste", NULL))) {
-               /* Handle single "waste" property. */
-               x_waste = y_waste = lgl_xml_get_prop_length (label_node, "waste", 0);
-               g_free (tmp);
-       } else {
-               x_waste = lgl_xml_get_prop_length (label_node, "x_waste", 0);
-               y_waste = lgl_xml_get_prop_length (label_node, "y_waste", 0);
-       }
-
-       w       = lgl_xml_get_prop_length (label_node, "width", 0);
-       h       = lgl_xml_get_prop_length (label_node, "height", 0);
-       r       = lgl_xml_get_prop_length (label_node, "round", 0);
-
-       frame = lgl_template_frame_rect_new ((gchar *)id, w, h, r, x_waste, y_waste);
-       lgl_template_add_frame (template, frame);
-
-       for (node = label_node->xmlChildrenNode; node != NULL;
-            node = node->next) {
-               if (lgl_xml_is_node (node, "Layout")) {
-                       xml_parse_layout_node (node, frame);
-               } else if (lgl_xml_is_node (node, "Markup-margin")) {
-                       xml_parse_markup_margin_node (node, frame);
-               } else if (lgl_xml_is_node (node, "Markup-line")) {
-                       xml_parse_markup_line_node (node, frame);
-               } else if (lgl_xml_is_node (node, "Markup-circle")) {
-                       xml_parse_markup_circle_node (node, frame);
-               } else if (lgl_xml_is_node (node, "Markup-rect")) {
-                       xml_parse_markup_rect_node (node, frame);
-               } else if (lgl_xml_is_node (node, "Markup-ellipse")) {
-                       xml_parse_markup_ellipse_node (node, frame);
-               } else if (!xmlNodeIsText (node)) {
-                       if (!lgl_xml_is_node (node, "comment")) {
-                               g_message ("bad node =  \"%s\"",node->name);
-                       }
-               }
-       }
-
-       g_free (id);
-}
-
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Parse XML Template->Label-ellipse Node.                        */
-/*--------------------------------------------------------------------------*/
-static void
-xml_parse_label_ellipse_node (xmlNodePtr   label_node,
-                              lglTemplate *template)
-{
-       gchar               *id;
-       gdouble              waste;
-       gdouble              w, h;
-       lglTemplateFrame    *frame;
-       xmlNodePtr           node;
-
-       id      = lgl_xml_get_prop_string (label_node, "id", NULL);
-
-       w       = lgl_xml_get_prop_length (label_node, "width", 0);
-       h       = lgl_xml_get_prop_length (label_node, "height", 0);
-        waste   = lgl_xml_get_prop_length (label_node, "waste", 0);
-
-       frame = lgl_template_frame_ellipse_new ((gchar *)id, w, h, waste);
-       lgl_template_add_frame (template, frame);
-
-       for (node = label_node->xmlChildrenNode; node != NULL;
-            node = node->next) {
-               if (lgl_xml_is_node (node, "Layout")) {
-                       xml_parse_layout_node (node, frame);
-               } else if (lgl_xml_is_node (node, "Markup-margin")) {
-                       xml_parse_markup_margin_node (node, frame);
-               } else if (lgl_xml_is_node (node, "Markup-line")) {
-                       xml_parse_markup_line_node (node, frame);
-               } else if (lgl_xml_is_node (node, "Markup-circle")) {
-                       xml_parse_markup_circle_node (node, frame);
-               } else if (lgl_xml_is_node (node, "Markup-rect")) {
-                       xml_parse_markup_rect_node (node, frame);
-               } else if (lgl_xml_is_node (node, "Markup-ellipse")) {
-                       xml_parse_markup_ellipse_node (node, frame);
-               } else if (!xmlNodeIsText (node)) {
-                       if (!lgl_xml_is_node (node, "comment")) {
-                               g_message ("bad node =  \"%s\"",node->name);
-                       }
-               }
-       }
-
-       g_free (id);
-}
-
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Parse XML Template->Label-round Node.                          */
-/*--------------------------------------------------------------------------*/
-static void
-xml_parse_label_round_node (xmlNodePtr   label_node,
-                           lglTemplate *template)
-{
-       gchar               *id;
-       gdouble              waste;
-       gdouble              r;
-       lglTemplateFrame    *frame;
-       xmlNodePtr           node;
-
-       id    = lgl_xml_get_prop_string (label_node, "id", NULL);
-       waste = lgl_xml_get_prop_length (label_node, "waste", 0);
-       r     = lgl_xml_get_prop_length (label_node, "radius", 0);
-
-       frame = lgl_template_frame_round_new ((gchar *)id, r, waste);
-       lgl_template_add_frame (template, frame);
-
-       for (node = label_node->xmlChildrenNode; node != NULL;
-            node = node->next) {
-               if (lgl_xml_is_node (node, "Layout")) {
-                       xml_parse_layout_node (node, frame);
-               } else if (lgl_xml_is_node (node, "Markup-margin")) {
-                       xml_parse_markup_margin_node (node, frame);
-               } else if (lgl_xml_is_node (node, "Markup-line")) {
-                       xml_parse_markup_line_node (node, frame);
-               } else if (lgl_xml_is_node (node, "Markup-circle")) {
-                       xml_parse_markup_circle_node (node, frame);
-               } else if (lgl_xml_is_node (node, "Markup-rect")) {
-                       xml_parse_markup_rect_node (node, frame);
-               } else if (lgl_xml_is_node (node, "Markup-ellipse")) {
-                       xml_parse_markup_ellipse_node (node, frame);
-               } else if (!xmlNodeIsText (node)) {
-                       if (!lgl_xml_is_node (node, "comment")) {
-                               g_message ("bad node =  \"%s\"",node->name);
-                       }
-               }
-       }
-
-       g_free (id);
-}
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Parse XML Template->Label-cd Node.                             */
-/*--------------------------------------------------------------------------*/
-static void
-xml_parse_label_cd_node (xmlNodePtr   label_node,
-                        lglTemplate *template)
-{
-       gchar               *id;
-       gdouble              waste;
-       gdouble              r1, r2, w, h;
-       lglTemplateFrame    *frame;
-       xmlNodePtr           node;
-
-       id    = lgl_xml_get_prop_string (label_node, "id", NULL);
-       waste = lgl_xml_get_prop_length (label_node, "waste", 0);
-       r1    = lgl_xml_get_prop_length (label_node, "radius", 0);
-       r2    = lgl_xml_get_prop_length (label_node, "hole", 0);
-       w     = lgl_xml_get_prop_length (label_node, "width", 0);
-       h     = lgl_xml_get_prop_length (label_node, "height", 0);
-
-       frame = lgl_template_frame_cd_new ((gchar *)id, r1, r2, w, h, waste);
-       lgl_template_add_frame (template, frame);
-
-       for (node = label_node->xmlChildrenNode; node != NULL;
-            node = node->next) {
-               if (lgl_xml_is_node (node, "Layout")) {
-                       xml_parse_layout_node (node, frame);
-               } else if (lgl_xml_is_node (node, "Markup-margin")) {
-                       xml_parse_markup_margin_node (node, frame);
-               } else if (lgl_xml_is_node (node, "Markup-line")) {
-                       xml_parse_markup_line_node (node, frame);
-               } else if (lgl_xml_is_node (node, "Markup-circle")) {
-                       xml_parse_markup_circle_node (node, frame);
-               } else if (lgl_xml_is_node (node, "Markup-rect")) {
-                       xml_parse_markup_rect_node (node, frame);
-               } else if (lgl_xml_is_node (node, "Markup-ellipse")) {
-                       xml_parse_markup_ellipse_node (node, frame);
-               } else if (!xmlNodeIsText (node)) {
-                       if (!lgl_xml_is_node (node, "comment")) {
-                               g_message ("bad node =  \"%s\"",node->name);
-                       }
-               }
-       }
-
-       g_free (id);
-}
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Parse XML Template->Label->Layout Node.                        */
-/*--------------------------------------------------------------------------*/
-static void
-xml_parse_layout_node (xmlNodePtr          layout_node,
-                      lglTemplateFrame   *frame)
-{
-       gint        nx, ny;
-       gdouble     x0, y0, dx, dy;
-       xmlNodePtr  node;
-
-       nx = lgl_xml_get_prop_int (layout_node, "nx", 1);
-       ny = lgl_xml_get_prop_int (layout_node, "ny", 1);
-
-       x0 = lgl_xml_get_prop_length (layout_node, "x0", 0);
-       y0 = lgl_xml_get_prop_length (layout_node, "y0", 0);
-
-       dx = lgl_xml_get_prop_length (layout_node, "dx", 0);
-       dy = lgl_xml_get_prop_length (layout_node, "dy", 0);
-
-       lgl_template_frame_add_layout (frame, lgl_template_layout_new (nx, ny, x0, y0, dx, dy));
-
-       for (node = layout_node->xmlChildrenNode; node != NULL;
-            node = node->next) {
-               if (!xmlNodeIsText (node)) {
-                       if (!lgl_xml_is_node (node, "comment")) {
-                               g_message ("bad node =  \"%s\"",node->name);
-                       }
-               }
-       }
-
-}
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Parse XML Template->Label->Markup-margin Node.                 */
-/*--------------------------------------------------------------------------*/
-static void
-xml_parse_markup_margin_node (xmlNodePtr          markup_node,
-                             lglTemplateFrame   *frame)
-{
-       gdouble     size;
-       xmlNodePtr  node;
-
-       size = lgl_xml_get_prop_length (markup_node, "size", 0);
-
-       lgl_template_frame_add_markup (frame, lgl_template_markup_margin_new (size));
-
-       for (node = markup_node->xmlChildrenNode; node != NULL;
-            node = node->next) {
-               if (!xmlNodeIsText (node)) {
-                       if (!lgl_xml_is_node (node, "comment")) {
-                               g_message ("bad node =  \"%s\"",node->name);
-                       }
-               }
-       }
-
-}
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Parse XML Template->Label->Markup-line Node.                   */
-/*--------------------------------------------------------------------------*/
-static void
-xml_parse_markup_line_node (xmlNodePtr          markup_node,
-                           lglTemplateFrame   *frame)
-{
-       gdouble     x1, y1, x2, y2;
-       xmlNodePtr  node;
-
-       x1 = lgl_xml_get_prop_length (markup_node, "x1", 0);
-       y1 = lgl_xml_get_prop_length (markup_node, "y1", 0);
-       x2 = lgl_xml_get_prop_length (markup_node, "x2", 0);
-       y2 = lgl_xml_get_prop_length (markup_node, "y2", 0);
-
-       lgl_template_frame_add_markup (frame, lgl_template_markup_line_new (x1, y1, x2, y2));
-
-       for (node = markup_node->xmlChildrenNode; node != NULL;
-            node = node->next) {
-               if (!xmlNodeIsText (node)) {
-                       if (!lgl_xml_is_node (node, "comment")) {
-                               g_message ("bad node =  \"%s\"",node->name);
-                       }
-               }
-       }
-
-}
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Parse XML Template->Label->Markup-circle Node.                 */
-/*--------------------------------------------------------------------------*/
-static void
-xml_parse_markup_circle_node (xmlNodePtr          markup_node,
-                             lglTemplateFrame   *frame)
-{
-       gdouble     x0, y0, r;
-       xmlNodePtr  node;
-
-       x0 = lgl_xml_get_prop_length (markup_node, "x0", 0);
-       y0 = lgl_xml_get_prop_length (markup_node, "y0", 0);
-       r  = lgl_xml_get_prop_length (markup_node, "radius", 0);
-
-       lgl_template_frame_add_markup (frame, lgl_template_markup_circle_new (x0, y0, r));
-
-       for (node = markup_node->xmlChildrenNode; node != NULL;
-            node = node->next) {
-               if (!xmlNodeIsText (node)) {
-                       if (!lgl_xml_is_node (node, "comment")) {
-                               g_message ("bad node =  \"%s\"",node->name);
-                       }
-               }
-       }
-
-}
-
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Parse XML Template->Label->Markup-rect Node.                   */
-/*--------------------------------------------------------------------------*/
-static void
-xml_parse_markup_rect_node (xmlNodePtr          markup_node,
-                           lglTemplateFrame   *frame)
-{
-       gdouble     x1, y1, w, h, r;
-       xmlNodePtr  node;
-
-       x1 = lgl_xml_get_prop_length (markup_node, "x1", 0);
-       y1 = lgl_xml_get_prop_length (markup_node, "y1", 0);
-       w  = lgl_xml_get_prop_length (markup_node, "w", 0);
-       h  = lgl_xml_get_prop_length (markup_node, "h", 0);
-       r  = lgl_xml_get_prop_length (markup_node, "r", 0);
-
-       lgl_template_frame_add_markup (frame, lgl_template_markup_rect_new (x1, y1, w, h, r));
-
-       for (node = markup_node->xmlChildrenNode; node != NULL;
-            node = node->next) {
-               if (!xmlNodeIsText (node)) {
-                       if (!lgl_xml_is_node (node, "comment")) {
-                               g_message ("bad node =  \"%s\"",node->name);
-                       }
-               }
-       }
-
-}
-
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Parse XML Template->Label->Markup-ellipse Node.                */
-/*--------------------------------------------------------------------------*/
-static void
-xml_parse_markup_ellipse_node (xmlNodePtr          markup_node,
-                               lglTemplateFrame   *frame)
-{
-       gdouble     x1, y1, w, h;
-       xmlNodePtr  node;
-
-       x1 = lgl_xml_get_prop_length (markup_node, "x1", 0);
-       y1 = lgl_xml_get_prop_length (markup_node, "y1", 0);
-       w  = lgl_xml_get_prop_length (markup_node, "w", 0);
-       h  = lgl_xml_get_prop_length (markup_node, "h", 0);
-
-       lgl_template_frame_add_markup (frame, lgl_template_markup_ellipse_new (x1, y1, w, h));
-
-       for (node = markup_node->xmlChildrenNode; node != NULL;
-            node = node->next) {
-               if (!xmlNodeIsText (node)) {
-                       if (!lgl_xml_is_node (node, "comment")) {
-                               g_message ("bad node =  \"%s\"",node->name);
-                       }
-               }
-       }
-
-}
-
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Parse deprecated XML Template->Alias Node.                     */
-/*--------------------------------------------------------------------------*/
-static void
-xml_parse_alias_node (xmlNodePtr   alias_node,
-                     lglTemplate *template)
-{
-        g_message ("Skipping deprecated \"Alias\" node.");
-}
-
-
-/**
- * lgl_xml_template_write_templates_to_file:
- * @templates:      List of #lglTemplate structures
- * @utf8_filename:  Filename of templates file (name encoded as UTF-8)
- *
- * Write a list of #lglTemplate structures to a glabels XML template file.
- *
- * Returns: the number of bytes written or -1 in case of failure
- *
- */
-gint
-lgl_xml_template_write_templates_to_file (GList       *templates,
-                                          const gchar *utf8_filename)
-{
-       xmlDocPtr    doc;
-       xmlNsPtr     ns;
-       gint         bytes_written;
-       GList       *p;
-       lglTemplate *template;
-       gchar       *filename;
-
-       doc = xmlNewDoc ((xmlChar *)"1.0");
-       doc->xmlRootNode = xmlNewDocNode (doc, NULL, (xmlChar *)"Glabels-templates", NULL);
-
-       ns = xmlNewNs (doc->xmlRootNode, (xmlChar *)LGL_XML_NAME_SPACE, NULL);
-       xmlSetNs (doc->xmlRootNode, ns);
-
-       for (p=templates; p!=NULL; p=p->next) {
-               template = (lglTemplate *)p->data;
-               lgl_xml_template_create_template_node (template, doc->xmlRootNode, ns);
-       }
-
-       filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
-       if (!filename)
-        {
-               g_message ("Utf8 conversion error.");
-                return -1;
-        }
-       else
-        {
-               xmlSetDocCompressMode (doc, 0);
-               bytes_written = xmlSaveFormatFile (filename, doc, TRUE);
-               xmlFreeDoc (doc);
-               g_free (filename);
-                return bytes_written;
-       }
-
-}
-
-
-/**
- * lgl_xml_template_write_template_to_file:
- * @template:       #lglTemplate structure to be written
- * @utf8_filename:  Filename of templates file (name encoded as UTF-8)
- *
- * Write a single #lglTemplate structures to a glabels XML template file.
- *
- * Returns: the number of bytes written or -1 in case of failure
- *
- */
-gint
-lgl_xml_template_write_template_to_file (const lglTemplate  *template,
-                                         const gchar        *utf8_filename)
-{
-       GList     *templates = NULL;
-       gint       bytes_written;
-
-       templates = g_list_append (templates, (gpointer)template);
-
-       bytes_written = lgl_xml_template_write_templates_to_file (templates, utf8_filename);
-
-       g_list_free (templates);
-
-        return bytes_written;
-}
-
-
-/**
- * lgl_xml_template_create_template_node:
- * @template:       #lglTemplate structure to be written
- * @root:           parent node to receive new child node
- * @ns:             a libxml #xmlNsPtr
- *
- * Add a single #lglTemplate child node to given #xmlNodePtr.
- *
- */
-void
-lgl_xml_template_create_template_node (const lglTemplate *template,
-                                       xmlNodePtr         root,
-                                       const xmlNsPtr     ns)
-{
-       xmlNodePtr          node;
-       GList              *p;
-       lglTemplateFrame   *frame;
-
-       node = xmlNewChild (root, ns, (xmlChar *)"Template", NULL);
-
-       lgl_xml_set_prop_string (node, "brand", template->brand);
-       lgl_xml_set_prop_string (node, "part", template->part);
-
-       lgl_xml_set_prop_string (node, "size", template->paper_id);
-       if (xmlStrEqual ((xmlChar *)template->paper_id, (xmlChar *)"Other"))
-        {
-
-               lgl_xml_set_prop_length (node, "width", template->page_width);
-               lgl_xml_set_prop_length (node, "height", template->page_height);
-
-       }
-
-       lgl_xml_set_prop_string (node, "description", template->description);
-
-        xml_create_meta_node ("product_url", template->product_url, node, ns );
-       for ( p=template->category_ids; p != NULL; p=p->next )
-        {
-                xml_create_meta_node ( "category", p->data, node, ns );
-       }
-       for ( p=template->frames; p != NULL; p=p->next )
-        {
-               frame = (lglTemplateFrame *)p->data;
-               xml_create_label_node (frame, node, ns);
-       }
-
-}
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Add XML Template->Meta Node with category.                     */
-/*--------------------------------------------------------------------------*/
-static void
-xml_create_meta_node (const gchar      *attr,
-                      const gchar      *value,
-                      xmlNodePtr        root,
-                      const xmlNsPtr    ns)
-{
-       xmlNodePtr node;
-
-        if ( value != NULL )
-        {
-                node = xmlNewChild (root, ns, (xmlChar *)"Meta", NULL);
-                lgl_xml_set_prop_string (node, attr, value);
-        }
-
-}
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Add XML Template->Label Node.                                  */
-/*--------------------------------------------------------------------------*/
-static void
-xml_create_label_node (const lglTemplateFrame  *frame,
-                      xmlNodePtr               root,
-                      const xmlNsPtr           ns)
-{
-       xmlNodePtr        node;
-       GList            *p;
-       lglTemplateMarkup *markup;
-       lglTemplateLayout *layout;
-
-       switch (frame->shape) {
-
-       case LGL_TEMPLATE_FRAME_SHAPE_RECT:
-               node = xmlNewChild(root, ns, (xmlChar *)"Label-rectangle", NULL);
-               lgl_xml_set_prop_string (node, "id",      frame->all.id);
-               lgl_xml_set_prop_length (node, "width",   frame->rect.w);
-               lgl_xml_set_prop_length (node, "height",  frame->rect.h);
-               lgl_xml_set_prop_length (node, "round",   frame->rect.r);
-               lgl_xml_set_prop_length (node, "x_waste", frame->rect.x_waste);
-               lgl_xml_set_prop_length (node, "y_waste", frame->rect.y_waste);
-               break;
-
-       case LGL_TEMPLATE_FRAME_SHAPE_ELLIPSE:
-               node = xmlNewChild(root, ns, (xmlChar *)"Label-ellipse", NULL);
-               lgl_xml_set_prop_string (node, "id",     frame->all.id);
-               lgl_xml_set_prop_length (node, "width",  frame->ellipse.w);
-               lgl_xml_set_prop_length (node, "height", frame->ellipse.h);
-               lgl_xml_set_prop_length (node, "waste",  frame->ellipse.waste);
-               break;
-
-       case LGL_TEMPLATE_FRAME_SHAPE_ROUND:
-               node = xmlNewChild(root, ns, (xmlChar *)"Label-round", NULL);
-               lgl_xml_set_prop_string (node, "id",      frame->all.id);
-               lgl_xml_set_prop_length (node, "radius",  frame->round.r);
-               lgl_xml_set_prop_length (node, "waste",   frame->round.waste);
-               break;
-
-       case LGL_TEMPLATE_FRAME_SHAPE_CD:
-               node = xmlNewChild(root, ns, (xmlChar *)"Label-cd", NULL);
-               lgl_xml_set_prop_string (node, "id",     frame->all.id);
-               lgl_xml_set_prop_length (node, "radius", frame->cd.r1);
-               lgl_xml_set_prop_length (node, "hole",   frame->cd.r2);
-               if (frame->cd.w != 0.0) {
-                       lgl_xml_set_prop_length (node, "width",  frame->cd.w);
-               }
-               if (frame->cd.h != 0.0) {
-                       lgl_xml_set_prop_length (node, "height", frame->cd.h);
-               }
-               lgl_xml_set_prop_length (node, "waste",  frame->cd.waste);
-               break;
-
-       default:
-               g_message ("Unknown label style");
-               return;
-               break;
-
-       }
-
-       for ( p=frame->all.markups; p != NULL; p=p->next ) {
-               markup = (lglTemplateMarkup *)p->data;
-               switch (markup->type) {
-               case LGL_TEMPLATE_MARKUP_MARGIN:
-                       xml_create_markup_margin_node (markup, node, ns);
-                       break;
-               case LGL_TEMPLATE_MARKUP_LINE:
-                       xml_create_markup_line_node (markup, node, ns);
-                       break;
-               case LGL_TEMPLATE_MARKUP_CIRCLE:
-                       xml_create_markup_circle_node (markup, node, ns);
-                       break;
-               case LGL_TEMPLATE_MARKUP_RECT:
-                       xml_create_markup_rect_node (markup, node, ns);
-                       break;
-               case LGL_TEMPLATE_MARKUP_ELLIPSE:
-                       xml_create_markup_ellipse_node (markup, node, ns);
-                       break;
-               default:
-                       g_message ("Unknown markup type");
-                       break;
-               }
-       }
-
-       for ( p=frame->all.layouts; p != NULL; p=p->next ) {
-               layout = (lglTemplateLayout *)p->data;
-               xml_create_layout_node (layout, node, ns);
-       }
-
-}
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Add XML Template->Label->Layout Node.                          */
-/*--------------------------------------------------------------------------*/
-static void
-xml_create_layout_node (const lglTemplateLayout *layout,
-                       xmlNodePtr               root,
-                       const xmlNsPtr           ns)
-{
-       xmlNodePtr  node;
-
-       node = xmlNewChild(root, ns, (xmlChar *)"Layout", NULL);
-       lgl_xml_set_prop_int (node, "nx", layout->nx);
-       lgl_xml_set_prop_int (node, "ny", layout->ny);
-       lgl_xml_set_prop_length (node, "x0", layout->x0);
-       lgl_xml_set_prop_length (node, "y0", layout->y0);
-       lgl_xml_set_prop_length (node, "dx", layout->dx);
-       lgl_xml_set_prop_length (node, "dy", layout->dy);
-
-}
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Add XML Template->Label->Markup-margin Node.                   */
-/*--------------------------------------------------------------------------*/
-static void
-xml_create_markup_margin_node (const lglTemplateMarkup  *markup,
-                              xmlNodePtr                root,
-                              const xmlNsPtr            ns)
-{
-       xmlNodePtr  node;
-
-       node = xmlNewChild(root, ns, (xmlChar *)"Markup-margin", NULL);
-
-       lgl_xml_set_prop_length (node, "size", markup->margin.size);
-
-}
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Add XML Template->Label->Markup-line Node.                     */
-/*--------------------------------------------------------------------------*/
-static void
-xml_create_markup_line_node (const lglTemplateMarkup *markup,
-                            xmlNodePtr               root,
-                            const xmlNsPtr           ns)
-{
-       xmlNodePtr  node;
-
-       node = xmlNewChild(root, ns, (xmlChar *)"Markup-line", NULL);
-
-       lgl_xml_set_prop_length (node, "x1", markup->line.x1);
-       lgl_xml_set_prop_length (node, "y1", markup->line.y1);
-       lgl_xml_set_prop_length (node, "x2", markup->line.x2);
-       lgl_xml_set_prop_length (node, "y2", markup->line.y2);
-
-}
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Add XML Template->Label->Markup-circle Node.                   */
-/*--------------------------------------------------------------------------*/
-static void
-xml_create_markup_circle_node (const lglTemplateMarkup *markup,
-                              xmlNodePtr               root,
-                              const xmlNsPtr           ns)
-{
-       xmlNodePtr  node;
-
-       node = xmlNewChild(root, ns, (xmlChar *)"Markup-circle", NULL);
-
-       lgl_xml_set_prop_length (node, "x0",     markup->circle.x0);
-       lgl_xml_set_prop_length (node, "y0",     markup->circle.y0);
-       lgl_xml_set_prop_length (node, "radius", markup->circle.r);
-
-}
-
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Add XML Template->Label->Markup-rect Node.                     */
-/*--------------------------------------------------------------------------*/
-static void
-xml_create_markup_rect_node (const lglTemplateMarkup *markup,
-                            xmlNodePtr               root,
-                            const xmlNsPtr           ns)
-{
-       xmlNodePtr  node;
-
-       node = xmlNewChild(root, ns, (xmlChar *)"Markup-rect", NULL);
-
-       lgl_xml_set_prop_length (node, "x1", markup->rect.x1);
-       lgl_xml_set_prop_length (node, "y1", markup->rect.y1);
-       lgl_xml_set_prop_length (node, "w",  markup->rect.w);
-       lgl_xml_set_prop_length (node, "h",  markup->rect.h);
-       lgl_xml_set_prop_length (node, "r",  markup->rect.r);
-
-}
-
-
-/*--------------------------------------------------------------------------*/
-/* PRIVATE.  Add XML Template->Label->Markup-ellipse Node.                  */
-/*--------------------------------------------------------------------------*/
-static void
-xml_create_markup_ellipse_node (const lglTemplateMarkup *markup,
-                                xmlNodePtr               root,
-                                const xmlNsPtr           ns)
-{
-       xmlNodePtr  node;
-
-       node = xmlNewChild(root, ns, (xmlChar *)"Markup-ellipse", NULL);
-
-       lgl_xml_set_prop_length (node, "x1", markup->ellipse.x1);
-       lgl_xml_set_prop_length (node, "y1", markup->ellipse.y1);
-       lgl_xml_set_prop_length (node, "w",  markup->ellipse.w);
-       lgl_xml_set_prop_length (node, "h",  markup->ellipse.h);
-
-}
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/xml-template.h b/libglabels/xml-template.h
deleted file mode 100644 (file)
index 3c32349..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *  xml-template.h
- *  Copyright (C) 2001-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __LGL_XML_TEMPLATE_H__
-#define __LGL_XML_TEMPLATE_H__
-
-#include <glib.h>
-#include <libxml/tree.h>
-
-#include "template.h"
-
-G_BEGIN_DECLS
-
-void         lgl_xml_template_read_templates_from_file (const gchar       *utf8_filename);
-
-void         lgl_xml_template_parse_templates_doc      (const xmlDocPtr    templates_doc);
-
-lglTemplate *lgl_xml_template_parse_template_node      (const xmlNodePtr   template_node);
-
-
-gint         lgl_xml_template_write_templates_to_file  (GList             *templates,
-                                                       const gchar       *utf8_filename);
-
-gint         lgl_xml_template_write_template_to_file   (const lglTemplate *template,
-                                                       const gchar       *utf8_filename);
-
-void         lgl_xml_template_create_template_node     (const lglTemplate *template,
-                                                       xmlNodePtr         root,
-                                                       const xmlNsPtr     ns);
-
-G_END_DECLS
-
-#endif /* __LGL_XML_TEMPLATE_H__ */
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/xml-vendor.c b/libglabels/xml-vendor.c
deleted file mode 100644 (file)
index c6ba991..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- *  xml-vendor.c
- *  Copyright (C) 2003-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-
-#include "xml-vendor.h"
-
-#include <glib/gi18n.h>
-#include <glib.h>
-#include <string.h>
-#include <libintl.h>
-
-#include "libglabels-private.h"
-
-#include "xml.h"
-
-/*===========================================*/
-/* Private types                             */
-/*===========================================*/
-
-/*===========================================*/
-/* Private globals                           */
-/*===========================================*/
-
-/*===========================================*/
-/* Local function prototypes                 */
-/*===========================================*/
-
-
-/**
- * lgl_xml_vendor_read_vendors_from_file:
- * @utf8_filename:       Filename of vendors file (name encoded as UTF-8)
- *
- * Read vendor definitions from a file.
- *
- * Returns: a list of #lglVendor structures.
- *
- */
-GList *
-lgl_xml_vendor_read_vendors_from_file (gchar *utf8_filename)
-{
-       gchar      *filename;
-       GList      *vendors;
-       xmlDocPtr   vendors_doc;
-
-       LIBXML_TEST_VERSION;
-
-       filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL);
-       if (!filename) {
-               g_message ("Utf8 filename conversion error");
-               return NULL;
-       }
-
-       vendors_doc = xmlParseFile (filename);
-       if (!vendors_doc) {
-               g_message ("\"%s\" is not a glabels vendor file (not XML)",
-                          filename);
-               return NULL;
-       }
-
-       vendors = lgl_xml_vendor_parse_vendors_doc (vendors_doc);
-
-       g_free (filename);
-       xmlFreeDoc (vendors_doc);
-
-       return vendors;
-}
-
-
-/**
- * lgl_xml_vendor_parse_vendors_doc:
- * @vendors_doc:  libxml #xmlDocPtr tree, representing a vendors definition file.
- *
- * Read vendor definitions from a libxml #xmlDocPtr tree.
- *
- * Returns: a list of #lglVendor structures.
- *
- */
-GList *
-lgl_xml_vendor_parse_vendors_doc (xmlDocPtr  vendors_doc)
-{
-       GList       *vendors = NULL;
-       xmlNodePtr   root, node;
-       lglVendor   *vendor;
-
-       LIBXML_TEST_VERSION;
-
-       root = xmlDocGetRootElement (vendors_doc);
-       if (!root || !root->name) {
-               g_message ("\"%s\" is not a glabels vendor file (no root node)",
-                          vendors_doc->name);
-               xmlFreeDoc (vendors_doc);
-               return vendors;
-       }
-       if (!lgl_xml_is_node (root, "Glabels-vendors")) {
-               g_message ("\"%s\" is not a glabels vendor file (wrong root node)",
-                          vendors_doc->name);
-               xmlFreeDoc (vendors_doc);
-               return vendors;
-       }
-
-       for (node = root->xmlChildrenNode; node != NULL; node = node->next) {
-
-               if (lgl_xml_is_node (node, "Vendor")) {
-                       vendor = lgl_xml_vendor_parse_vendor_node (node);
-                       vendors = g_list_append (vendors, vendor);
-               } else {
-                       if ( !xmlNodeIsText(node) ) {
-                               if (!lgl_xml_is_node (node, "comment")) {
-                                       g_message ("bad node =  \"%s\"",node->name);
-                               }
-                       }
-               }
-       }
-
-       return vendors;
-}
-
-
-/**
- * lgl_xml_vendor_parse_vendor_node:
- * @vendor_node:  libxml #xmlNodePtr vendor node from a #xmlDocPtr tree.
- *
- * Read a single vendor definition from a libxml #xmlNodePtr node.
- *
- * Returns: a pointer to a newly created #lglVendor structure.
- *
- */
-lglVendor *
-lgl_xml_vendor_parse_vendor_node (xmlNodePtr vendor_node)
-{
-       lglVendor             *vendor;
-       gchar                 *name;
-
-       LIBXML_TEST_VERSION;
-
-       name = lgl_xml_get_prop_i18n_string (vendor_node, "name", NULL);
-
-       vendor = lgl_vendor_new (name);
-
-        vendor->url = lgl_xml_get_prop_i18n_string (vendor_node, "url", NULL);
-
-       g_free (name);
-
-       return vendor;
-}
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/xml-vendor.h b/libglabels/xml-vendor.h
deleted file mode 100644 (file)
index a565eb0..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *  xml-vendor.h
- *  Copyright (C) 2003-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __LGL_XML_VENDOR_H__
-#define __LGL_XML_VENDOR_H__
-
-#include <glib.h>
-#include <libxml/tree.h>
-
-#include "vendor.h"
-
-G_BEGIN_DECLS
-
-GList       *lgl_xml_vendor_read_vendors_from_file (gchar        *utf8_filename);
-
-GList       *lgl_xml_vendor_parse_vendors_doc      (xmlDocPtr     vendors_doc);
-
-lglVendor   *lgl_xml_vendor_parse_vendor_node      (xmlNodePtr    vendor_node);
-
-
-G_END_DECLS
-
-#endif /* __LGL_XML_VENDOR_H__ */
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/xml.c b/libglabels/xml.c
deleted file mode 100644 (file)
index 4bce17e..0000000
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- *  xml.c
- *  Copyright (C) 2003-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-
-#include "xml.h"
-
-#include <glib/gi18n.h>
-#include <glib.h>
-#include <string.h>
-
-#include "libglabels-private.h"
-
-
-/*========================================================*/
-/* Private macros and constants.                          */
-/*========================================================*/
-
-/*========================================================*/
-/* Private types.                                         */
-/*========================================================*/
-
-/*========================================================*/
-/* Private globals.                                       */
-/*========================================================*/
-
-static lglUnits  default_units        = LGL_UNITS_POINT;
-
-
-/****************************************************************************/
-
-/**
- * lgl_xml_get_prop_string:
- * @node:        the libxml2 #xmlNodePtr of the node
- * @property:    the property name
- * @default_val: a default value to return if property not found
- *
- * Return value of property as a string.
- *
- * Returns: the property as a pointer to a gchar string.  This string should
- *          be freed with g_free().
- *
- */
-gchar *
-lgl_xml_get_prop_string (xmlNodePtr   node,
-                        const gchar *property,
-                        const gchar *default_val)
-{
-       gchar   *val;
-       xmlChar *string;
-
-       string = xmlGetProp (node, (xmlChar *)property);
-       if ( string != NULL ) {
-               val = g_strdup ((gchar *)string);
-               xmlFree (string);
-               return val;
-       }
-
-       if (default_val) {
-               return g_strdup (default_val);
-       }
-
-       return NULL;
-}
-
-
-/**
- * lgl_xml_get_prop_i18n_string:
- * @node:        the libxml2 #xmlNodePtr of the node
- * @property:    the property name
- * @default_val: a default value to return if property not found
- *
- * Return value of a translatable property as a string.
- *
- * Returns: the property as a pointer to a gchar string.  This string should
- *          be freed with g_free().
- *
- */
-gchar *
-lgl_xml_get_prop_i18n_string (xmlNodePtr   node,
-                             const gchar *property,
-                             const gchar *default_val)
-{
-       gchar   *_property;
-       gchar   *val;
-       xmlChar *string;
-
-       _property = g_strdup_printf ("_%s", property);
-       string = xmlGetProp (node, (xmlChar *)_property);
-       g_free (_property);
-
-       if ( string != NULL ) {
-
-               val = g_strdup (gettext ((char *)string));
-               xmlFree (string);
-               return val;
-
-       }
-
-       string = xmlGetProp (node, (xmlChar *)property);
-       if ( string != NULL ) {
-               val = g_strdup ((gchar *)string);
-               xmlFree (string);
-               return val;
-       }
-
-       if (default_val) {
-               return g_strdup (default_val);
-       }
-
-       return NULL;
-}
-
-
-/**
- * lgl_xml_get_prop_double:
- * @node:        the libxml2 #xmlNodePtr of the node
- * @property:    the property name
- * @default_val: a default value to return if property not found
- *
- * Return value of property as a double.
- *
- * Returns: the property as a double.
- *
- */
-gdouble
-lgl_xml_get_prop_double (xmlNodePtr   node,
-                        const gchar *property,
-                        gdouble      default_val)
-{
-       gdouble  val;
-       xmlChar *string;
-
-       string = xmlGetProp (node, (xmlChar *)property);
-       if ( string != NULL ) {
-               val = g_strtod ((gchar *)string, NULL);
-               xmlFree (string);
-               return val;
-       }
-
-       return default_val;
-}
-
-
-/**
- * lgl_xml_get_prop_boolean:
- * @node:        the libxml2 #xmlNodePtr of the node
- * @property:    the property name
- * @default_val: a default value to return if property not found
- *
- * Return value of property as a boolean.
- *
- * Returns: the property as a boolean.
- *
- */
-gboolean
-lgl_xml_get_prop_boolean (xmlNodePtr   node,
-                        const gchar *property,
-                        gboolean     default_val)
-{
-       gboolean  val;
-       xmlChar  *string;
-
-       string = xmlGetProp (node, (xmlChar *)property);
-       if ( string != NULL ) {
-               val = !((xmlStrcasecmp (string, (xmlChar *)"false") == 0) ||
-                       xmlStrEqual (string, (xmlChar *)"0"));;
-               xmlFree (string);
-               return val;
-       }
-
-       return default_val;
-}
-
-
-/**
- * lgl_xml_get_prop_int:
- * @node:        the libxml2 #xmlNodePtr of the node
- * @property:    the property name
- * @default_val: a default value to return if property not found
- *
- * Return value of property as an integer.
- *
- * Returns: the property as an integer.
- *
- */
-gint
-lgl_xml_get_prop_int (xmlNodePtr   node,
-                     const gchar *property,
-                     gint         default_val)
-{
-       gint     val;
-       xmlChar *string;
-
-       string = xmlGetProp (node, (xmlChar *)property);
-       if ( string != NULL ) {
-               val = strtol ((char *)string, NULL, 0);
-               xmlFree (string);
-               return val;
-       }
-
-       return default_val;
-}
-
-
-/**
- * lgl_xml_get_prop_uint:
- * @node:        the libxml2 #xmlNodePtr of the node
- * @property:    the property name
- * @default_val: a default value to return if property not found
- *
- * Return value of property (usually formatted in hex) as an unsigned integer.
- *
- * Returns: the property as an unsigned integer.
- *
- */
-guint
-lgl_xml_get_prop_uint (xmlNodePtr   node,
-                      const gchar *property,
-                      guint        default_val)
-{
-       guint    val;
-       xmlChar *string;
-
-       string = xmlGetProp (node, (xmlChar *)property);
-       if ( string != NULL ) {
-               val = strtoul ((char *)string, NULL, 0);
-               xmlFree (string);
-               return val;
-       }
-
-       return default_val;
-}
-
-
-/**
- * lgl_xml_get_prop_length:
- * @node:        the libxml2 #xmlNodePtr of the node
- * @property:    the property name
- * @default_val: a default value to return if property not found
- *
- * Return value of a length property as a double, converting to internal
- * units (points).  The property is expected to be formatted as a number
- * followed by a units string.  If there is no units string, the length
- * is assumed to be in points.  Valid units strings are "pt" for points,
- * "in" for inches, "mm" for millimeters, "cm" for centimeters, and
- * "pc" for picas.
- *
- * Returns: the length in points.
- *
- */
-gdouble
-lgl_xml_get_prop_length (xmlNodePtr   node,
-                        const gchar *property,
-                        gdouble      default_val)
-{
-       gdouble  val;
-       xmlChar *string;
-       xmlChar *unit_id;
-        lglUnits units;
-
-       string = xmlGetProp (node, (xmlChar *)property);
-       if ( string != NULL ) {
-
-               val = g_strtod ((gchar *)string, (gchar **)&unit_id);
-
-               if (unit_id != string) {
-                       unit_id = (xmlChar *)g_strchug ((gchar *)unit_id);
-                        units = lgl_units_from_id ((gchar *)unit_id);
-                        if (units != LGL_UNITS_INVALID)
-                        {
-                                val *= lgl_units_get_points_per_unit (units);
-                        }
-                        else
-                        {
-                                g_message ("Line %ld, Node \"%s\", Property \"%s\": Unknown unit \"%s\", assuming points",
-                                           xmlGetLineNo (node), node->name, property, unit_id);
-                        }
-               }
-               else {
-                       val = 0.0;
-               }
-
-               xmlFree (string);
-               return val;
-       }
-
-       return default_val;
-}
-
-
-/**
- * lgl_xml_set_prop_string:
- * @node:        the libxml2 #xmlNodePtr of the node
- * @property:    the property name
- * @val:         the value to set
- *
- * Set a property from a string.
- *
- */
-void
-lgl_xml_set_prop_string (xmlNodePtr    node,
-                        const gchar  *property,
-                        const gchar  *val)
-{
-       if (val != NULL) {
-               xmlSetProp (node, (xmlChar *)property, (xmlChar *)val);
-       }
-}
-
-
-/**
- * lgl_xml_set_prop_double:
- * @node:        the libxml2 #xmlNodePtr of the node
- * @property:    the property name
- * @val:         the value to set
- *
- * Set a property from a double.
- *
- */
-void
-lgl_xml_set_prop_double (xmlNodePtr    node,
-                        const gchar  *property,
-                        gdouble       val)
-{
-       gchar  *string, buffer[G_ASCII_DTOSTR_BUF_SIZE];
-
-       /* Guarantee "C" locale by use of g_ascii_formatd */
-       string = g_ascii_formatd (buffer, G_ASCII_DTOSTR_BUF_SIZE, "%g", val);
-
-       xmlSetProp (node, (xmlChar *)property, (xmlChar *)string);
-}
-
-
-/**
- * lgl_xml_set_prop_boolean:
- * @node:        the libxml2 #xmlNodePtr of the node
- * @property:    the property name
- * @val:         the value to set
- *
- * Set a property from a boolean.
- *
- */
-void
-lgl_xml_set_prop_boolean (xmlNodePtr    node,
-                         const gchar  *property,
-                         gboolean      val)
-{
-       xmlSetProp (node, (xmlChar *)property, (xmlChar *)(val ? "True" : "False"));
-}
-
-/**
- * lgl_xml_set_prop_int:
- * @node:        the libxml2 #xmlNodePtr of the node
- * @property:    the property name
- * @val:         the value to set
- *
- * Set a property from an integer.
- *
- */
-void
-lgl_xml_set_prop_int (xmlNodePtr    node,
-                     const gchar  *property,
-                     gint          val)
-{
-       gchar  *string;
-
-       string = g_strdup_printf ("%d", val);
-       xmlSetProp (node, (xmlChar *)property, (xmlChar *)string);
-       g_free (string);
-}
-
-/**
- * lgl_xml_set_prop_uint_hex:
- * @node:        the libxml2 #xmlNodePtr of the node
- * @property:    the property name
- * @val:         the value to set
- *
- * Set a property from an unsigned integer and format in hex.
- *
- */
-void
-lgl_xml_set_prop_uint_hex (xmlNodePtr    node,
-                          const gchar  *property,
-                          guint         val)
-{
-       gchar  *string;
-
-       string = g_strdup_printf ("0x%08x", val);
-       xmlSetProp (node, (xmlChar *)property, (xmlChar *)string);
-       g_free (string);
-}
-
-/**
- * lgl_xml_set_prop_length:
- * @node:        the libxml2 #xmlNodePtr of the node
- * @property:    the property name
- * @val:         the length to set in internal units (points)
- *
- * Set a property from a length, performing any necessary conversion.
- * Length properties are formatted as a number followed by a units string.
- * The units of the formatted property is determined by the most recent call to
- * lgl_xml_set_default_units().
- *
- */
-void
-lgl_xml_set_prop_length (xmlNodePtr    node,
-                        const gchar  *property,
-                        gdouble       val)
-{
-       gchar  *string, buffer[G_ASCII_DTOSTR_BUF_SIZE];
-       gchar  *string_unit;
-
-       /* Convert to default units */
-       val *= lgl_units_get_units_per_point (default_units);
-
-       /* Guarantee "C" locale by use of g_ascii_formatd */
-       string = g_ascii_formatd (buffer, G_ASCII_DTOSTR_BUF_SIZE, "%g", val);
-
-       string_unit = g_strdup_printf ("%s%s", string, lgl_units_get_id (default_units));
-       xmlSetProp (node, (xmlChar *)property, (xmlChar *)string_unit);
-        g_free (string_unit);
-}
-
-/**
- * lgl_xml_is_node
- * @node:        the libxml2 #xmlNodePtr of the node
- * @name    :    the node name
- *
- * Test if a node name matches given name.
- *
- * Returns: TRUE if the name of the node matches.  Otherwise FALSE.
- *
- */
-gboolean
-lgl_xml_is_node (xmlNodePtr   node,
-                const gchar *name)
-{
-       return xmlStrEqual (node->name, (xmlChar *)name);
-}
-
-
-/**
- * lgl_xml_get_node_content
- * @node:        the libxml2 #xmlNodePtr of the node
- *
- * Get the content of a node.
- *
- * Returns: the property as a pointer to a gchar string.  This string should
- *          be freed with g_free().
- */
-gchar *
-lgl_xml_get_node_content (xmlNodePtr   node)
-{
-       xmlChar *xml_content;
-       gchar   *g_content;
-
-       xml_content = xmlNodeGetContent (node);
-
-       if (xml_content != NULL) {
-
-               g_content = g_strdup ((gchar *)xml_content);
-               xmlFree (xml_content);
-               return g_content;
-
-       }
-
-       return NULL;
-}
-
-
-/**
- * lgl_xml_set_default_units:
- * @units:       default units selection (#lglUnits)
- *
- * Set the default units when formatting lengths.  See
- * lgl_xml_set_prop_length().
- *
- */
-void
-lgl_xml_set_default_units (lglUnits   units)
-{
-       g_return_if_fail ((units >= LGL_UNITS_FIRST) && (units <= LGL_UNITS_LAST));
-
-       default_units = units;
-}
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
diff --git a/libglabels/xml.h b/libglabels/xml.h
deleted file mode 100644 (file)
index 8b5ba9d..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- *  xml.h
- *  Copyright (C) 2003-2009  Jim Evins <evins@snaught.com>.
- *
- *  This file is part of libglabels.
- *
- *  libglabels is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  libglabels is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public License
- *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __LGL_XML_H__
-#define __LGL_XML_H__
-
-#include <glib.h>
-#include <libxml/tree.h>
-
-#include "units.h"
-
-#define LGL_XML_NAME_SPACE "http://glabels.org/xmlns/2.3/"
-
-G_BEGIN_DECLS
-
-/*
- * Get property functions
- */
-gchar *  lgl_xml_get_prop_string   (xmlNodePtr    node,
-                                   const gchar  *property,
-                                   const gchar  *default_val);
-
-gchar *  lgl_xml_get_prop_i18n_string (xmlNodePtr    node,
-                                      const gchar  *property,
-                                      const gchar  *default_val);
-
-gdouble  lgl_xml_get_prop_double   (xmlNodePtr    node,
-                                   const gchar  *property,
-                                   gdouble       default_val);
-
-gboolean lgl_xml_get_prop_boolean  (xmlNodePtr    node,
-                                   const gchar  *property,
-                                   gboolean      default_val);
-
-gint     lgl_xml_get_prop_int      (xmlNodePtr    node,
-                                   const gchar  *property,
-                                   gint          default_val);
-
-guint    lgl_xml_get_prop_uint     (xmlNodePtr    node,
-                                   const gchar  *property,
-                                   guint         default_val);
-
-gdouble  lgl_xml_get_prop_length   (xmlNodePtr    node,
-                                   const gchar  *property,
-                                   gdouble       default_val);
-
-
-/*
- * Set property functions
- */
-void     lgl_xml_set_prop_string   (xmlNodePtr    node,
-                                   const gchar  *property,
-                                   const gchar  *val);
-
-void     lgl_xml_set_prop_double   (xmlNodePtr    node,
-                                   const gchar  *property,
-                                   gdouble       val);
-
-void     lgl_xml_set_prop_boolean  (xmlNodePtr    node,
-                                   const gchar  *property,
-                                   gboolean      val);
-
-void     lgl_xml_set_prop_int      (xmlNodePtr    node,
-                                   const gchar  *property,
-                                   gint          val);
-
-void     lgl_xml_set_prop_uint_hex (xmlNodePtr    node,
-                                   const gchar  *property,
-                                   guint         val);
-
-void     lgl_xml_set_prop_length   (xmlNodePtr    node,
-                                   const gchar  *property,
-                                   gdouble       val);
-
-/*
- * Other node functions
- */
-gboolean lgl_xml_is_node           (xmlNodePtr    node,
-                                   const gchar  *name);
-
-gchar *  lgl_xml_get_node_content  (xmlNodePtr    node);
-
-/*
- * Misc functions
- */
-void     lgl_xml_set_default_units (lglUnits      units);
-
-G_END_DECLS
-
-
-#endif /* __LGL_XML_H__ */
-
-
-
-/*
- * Local Variables:       -- emacs
- * mode: C                -- emacs
- * c-basic-offset: 8      -- emacs
- * tab-width: 8           -- emacs
- * indent-tabs-mode: nil  -- emacs
- * End:                   -- emacs
- */
index 5f1297bbd8e2215745f54a48792a9318622c0404..f71c35b414b776b4c48876eac6e41c1af9f4fee6 100644 (file)
@@ -185,27 +185,27 @@ src/xml-label-04.h
 src/xml-label.c
 src/xml-label.h
 
-libglabels/category.c
-libglabels/category.h
-libglabels/db.c
-libglabels/db.h
+libglabels/lgl-category.c
+libglabels/lgl-category.h
+libglabels/lgl-db.c
+libglabels/lgl-db.h
+libglabels/lgl-paper.c
+libglabels/lgl-paper.h
+libglabels/lgl-str.c
+libglabels/lgl-str.h
+libglabels/lgl-template.c
+libglabels/lgl-template.h
+libglabels/lgl-units.c
+libglabels/lgl-units.h
+libglabels/lgl-xml.c
+libglabels/lgl-xml.h
+libglabels/lgl-xml-category.c
+libglabels/lgl-xml-category.h
+libglabels/lgl-xml-paper.c
+libglabels/lgl-xml-paper.h
+libglabels/lgl-xml-template.c
+libglabels/lgl-xml-template.h
 libglabels/libglabels-private.h
-libglabels/paper.c
-libglabels/paper.h
-libglabels/str.c
-libglabels/str.h
-libglabels/template.c
-libglabels/template.h
-libglabels/units.c
-libglabels/units.h
-libglabels/xml.c
-libglabels/xml.h
-libglabels/xml-category.c
-libglabels/xml-category.h
-libglabels/xml-paper.c
-libglabels/xml-paper.h
-libglabels/xml-template.c
-libglabels/xml-template.h
 
 [type: gettext/glade]data/ui/merge-properties-dialog.ui
 [type: gettext/glade]data/ui/media-select.ui