From 2d0ad672af26c3bc863e0a56a65a6be89944ced8 Mon Sep 17 00:00:00 2001 From: Jim Evins Date: Sun, 6 Dec 2009 21:41:40 -0500 Subject: [PATCH] Libglabels mods to support reorganization of template database Added "equiv" attribute to "Template" tag. The "equiv" attribute works differently than the "Alias" tag: instead of defining a simple alias for the current template struct, it says to use the equivalent part as the prototype for this template. The template could override (or append) unique meta data for this part number. The "Alias" tag is still supported, but is deprecated. Added a "product_url" attribute to the "Meta" tag. Added a "vendor.xml" file which contains a database of vendors and their primary url. This file has only been populated with a few examples so far. A new DTD file has been created to describe the above changes. The "Avery 5160" family in "avery-us-templates.xml", has been organized in the new scheme as an example. --- libglabels/Makefile.am | 4 + libglabels/db.c | 383 ++++++++++++++++-- libglabels/db.h | 16 + libglabels/libglabels-private.h | 3 + libglabels/template.c | 56 +++ libglabels/template.h | 17 +- libglabels/vendor.c | 133 ++++++ libglabels/vendor.h | 63 +++ libglabels/xml-template.c | 82 ++-- libglabels/xml-template.h | 4 +- libglabels/xml-vendor.c | 176 ++++++++ libglabels/xml-vendor.h | 51 +++ templates/Makefile.am | 1 + templates/avery-us-templates.xml | 63 +-- .../{glabels-2.2.dtd => glabels-2.3.dtd} | 35 +- templates/vendors.xml | 42 ++ 16 files changed, 1016 insertions(+), 113 deletions(-) create mode 100644 libglabels/vendor.c create mode 100644 libglabels/vendor.h create mode 100644 libglabels/xml-vendor.c create mode 100644 libglabels/xml-vendor.h rename templates/{glabels-2.2.dtd => glabels-2.3.dtd} (91%) create mode 100644 templates/vendors.xml diff --git a/libglabels/Makefile.am b/libglabels/Makefile.am index 5e654aee..51812ddb 100644 --- a/libglabels/Makefile.am +++ b/libglabels/Makefile.am @@ -24,12 +24,16 @@ libglabels_la_SOURCES = \ 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 \ diff --git a/libglabels/db.c b/libglabels/db.c index 4a582e8d..b05f54d3 100644 --- a/libglabels/db.c +++ b/libglabels/db.c @@ -32,6 +32,7 @@ #include "xml-paper.h" #include "xml-category.h" +#include "xml-vendor.h" #include "xml-template.h" @@ -46,6 +47,7 @@ static GList *papers = NULL; static GList *categories = NULL; +static GList *vendors = NULL; static GList *templates = NULL; static GHashTable *template_cache = NULL; @@ -66,9 +68,12 @@ static GList *read_categories (void); static GList *read_category_files_from_dir (GList *categories, const gchar *dirname); -static GList *read_templates (void); -static GList *read_template_files_from_dir (GList *templates, - 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); @@ -85,8 +90,8 @@ static lglTemplate *template_full_page (const gchar *page_size); * 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, and its template - * database.. It will search both system and user template directories to locate + * 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 @@ -94,6 +99,7 @@ lgl_db_init (void) { lglPaper *paper_other; lglCategory *category_user_defined; + lglTemplate *template; GList *page_sizes; GList *p; @@ -123,13 +129,23 @@ lgl_db_init (void) categories = g_list_append (categories, category_user_defined); } + /* + * Vendors + */ + if (!vendors) + { + vendors = read_vendors (); + } + /* * Templates */ if (!templates) { - templates = read_templates (); + init_template_cache (); + + read_templates (); /* Create and append generic full page templates. */ page_sizes = lgl_db_get_paper_id_list (); @@ -137,13 +153,12 @@ lgl_db_init (void) { if ( !lgl_db_is_paper_id_other (p->data) ) { - templates = g_list_append (templates, - template_full_page (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); - - init_template_cache (); } } @@ -507,8 +522,7 @@ read_paper_files_from_dir (GList *papers, if (extension != NULL) { - if ( ASCII_EQUAL (extension, ".paper") || - ASCII_EQUAL (filename, "paper-sizes.xml") ) + if ( ASCII_EQUAL (filename, "paper-sizes.xml") ) { full_filename = @@ -900,8 +914,7 @@ read_category_files_from_dir (GList *categories, if (extension != NULL) { - if ( ASCII_EQUAL (extension, ".category") || - ASCII_EQUAL (filename, "categories.xml") ) + if ( ASCII_EQUAL (filename, "categories.xml") ) { full_filename = @@ -954,6 +967,242 @@ lgl_db_print_known_categories (void) } +/*===========================================*/ +/* 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 (!papers) + { + lgl_db_init (); + } + + for ( p=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 (!papers) + { + lgl_db_init (); + } + + if (name == NULL) + { + /* If no name, return first vendor as a default */ + return lgl_vendor_dup ((lglVendor *) vendors->data); + } + + for (p = 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 (!papers) + { + lgl_db_init (); + } + + if (name == NULL) + { + return FALSE; + } + + for (p = 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 = LGL_SYSTEM_DATA_DIR; + vendors = read_vendor_files_from_dir (vendors, data_dir); + g_free (data_dir); + + data_dir = LGL_USER_DATA_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, "vendor-sizes.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 (!papers) { + lgl_db_init (); + } + + g_print ("%s():\n", __FUNCTION__); + for (p = 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. */ /*===========================================*/ @@ -1037,6 +1286,17 @@ lgl_db_free_brand_list (GList *brands) /* Template db functions. */ /*===========================================*/ +void +_lgl_db_register_template_internal (const lglTemplate *template) +{ + lglTemplate *template_copy; + + template_copy = lgl_template_dup (template); + templates = g_list_append (templates, template_copy); + add_to_template_cache (template_copy); +} + + /** * lgl_db_register_template: * @template: Pointer to a template structure to add to database. @@ -1376,28 +1636,74 @@ lgl_db_lookup_template_from_name (const gchar *name) } -static void -init_template_cache (void) +/** + * 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) { - GList *p_tmplt, *p_alias; + gchar *name; + GList *p_alias; lglTemplate *template; lglTemplateAlias *alias; - gchar *name; + gchar *candidate_name; + lglTemplate *new_template; - template_cache = g_hash_table_new (g_str_hash, g_str_equal); + if (!templates) + { + lgl_db_init (); + } - for ( p_tmplt=templates; p_tmplt != NULL; p_tmplt=p_tmplt->next ) + if ((brand == NULL) || (part == NULL)) { - template = (lglTemplate *) p_tmplt->data; + /* If no name, return first template as a default */ + return lgl_template_dup ((lglTemplate *) templates->data); + } + + name = g_strdup_printf ("%s %s", brand, part); + template = g_hash_table_lookup (template_cache, name); - for ( p_alias=template->aliases; p_alias != NULL; p_alias=p_alias->next ) + if (template) + { + for (p_alias = template->aliases; p_alias != NULL; p_alias = p_alias->next) { alias = (lglTemplateAlias *)p_alias->data; - name = g_strdup_printf ("%s %s", alias->brand, alias->part); + candidate_name = g_strdup_printf ("%s %s", alias->brand, alias->part); + + if ( UTF8_EQUAL (candidate_name, name) ) + { + g_free (candidate_name); + new_template = lgl_template_dup (template); + g_free (new_template->brand); + new_template->brand = g_strdup (alias->brand); + g_free (new_template->part); + new_template->part = g_strdup (alias->part); + g_free (name); + return new_template; + } - g_hash_table_insert (template_cache, name, template); + g_free (candidate_name); } } + + /* No matching template has been found so return the first template */ + g_free (name); + return lgl_template_dup ((lglTemplate *) templates->data); +} + + +static void +init_template_cache (void) +{ + template_cache = g_hash_table_new (g_str_hash, g_str_equal); } @@ -1418,11 +1724,10 @@ add_to_template_cache (lglTemplate *template) } -static GList * +void read_templates (void) { gchar *data_dir; - GList *templates = NULL; GList *p; lglTemplate *template; @@ -1430,7 +1735,7 @@ read_templates (void) * User defined templates. Add to user-defined category. */ data_dir = LGL_USER_DATA_DIR; - templates = read_template_files_from_dir (templates, data_dir); + read_template_files_from_dir (data_dir); g_free (data_dir); for ( p=templates; p != NULL; p=p->next ) { @@ -1442,41 +1747,37 @@ read_templates (void) * System templates. */ data_dir = LGL_SYSTEM_DATA_DIR; - templates = read_template_files_from_dir (templates, data_dir); + read_template_files_from_dir (data_dir); g_free (data_dir); if (templates == NULL) { g_critical (_("Unable to locate any template files. Libglabels may not be installed correctly!")); } - - return templates; } -static GList * -read_template_files_from_dir (GList *templates, - const gchar *dirname) +void +read_template_files_from_dir (const gchar *dirname) { GDir *dp; const gchar *filename, *extension, *extension2; gchar *full_filename = NULL; GError *gerror = NULL; - GList *new_templates = NULL; if (dirname == NULL) - return templates; + return; if (!g_file_test (dirname, G_FILE_TEST_EXISTS)) { - return templates; + return; } dp = g_dir_open (dirname, 0, &gerror); if (gerror != NULL) { g_message ("cannot open data directory: %s", gerror->message ); - return templates; + return; } while ((filename = g_dir_read_name (dp)) != NULL) @@ -1490,19 +1791,13 @@ read_template_files_from_dir (GList *templates, { full_filename = g_build_filename (dirname, filename, NULL); - new_templates = - lgl_xml_template_read_templates_from_file (full_filename); + lgl_xml_template_read_templates_from_file (full_filename); g_free (full_filename); - - templates = g_list_concat (templates, new_templates); - new_templates = NULL; } } g_dir_close (dp); - - return templates; } diff --git a/libglabels/db.h b/libglabels/db.h index 465929fb..3fd9f3a8 100644 --- a/libglabels/db.h +++ b/libglabels/db.h @@ -25,6 +25,7 @@ #include "paper.h" #include "category.h" +#include "vendor.h" #include "template.h" G_BEGIN_DECLS @@ -90,6 +91,18 @@ 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 */ @@ -121,6 +134,9 @@ 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 diff --git a/libglabels/libglabels-private.h b/libglabels/libglabels-private.h index fa205ee8..b5f6c21d 100644 --- a/libglabels/libglabels-private.h +++ b/libglabels/libglabels-private.h @@ -24,6 +24,7 @@ #include #include "str.h" +#include "template.h" /* Data system and user data directories. (must free w/ g_free()) */ #define LGL_SYSTEM_DATA_DIR g_build_filename (LIBGLABELS_TEMPLATE_DIR, NULL) @@ -35,6 +36,8 @@ #define UTF8_EQUAL(s1,s2) (!lgl_str_utf8_casecmp (s1, s2)) #define ASCII_EQUAL(s1,s2) (!g_ascii_strcasecmp (s1, s2)) +void _lgl_db_register_template_internal (const lglTemplate *template); + #endif /* __LIBGLABELS_PRIVATE_H__ */ diff --git a/libglabels/template.c b/libglabels/template.c index 5675c401..34252031 100644 --- a/libglabels/template.c +++ b/libglabels/template.c @@ -30,6 +30,7 @@ #include "libglabels-private.h" +#include "db.h" #include "paper.h" /*===========================================*/ @@ -100,6 +101,58 @@ lgl_template_new (const gchar *brand, } +/** + * 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; + GList *p_alias; + lglTemplateAlias *alias; + + template = lgl_db_lookup_template_from_brand_part (brand, equiv_part); + if (template) + { + g_free (template->part); + g_free (template->equiv_part); + + template->part = g_strdup (part); + template->equiv_part = g_strdup (equiv_part); + + for ( p_alias = template->aliases; p_alias != NULL; p_alias = p_alias->next ) + { + alias = (lglTemplateAlias *)p_alias->data; + lgl_template_alias_free (alias); + } + g_list_free (template->aliases); + template->aliases = NULL; + + alias = lgl_template_alias_new (brand, part); + lgl_template_add_alias (template, alias); + } + 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 @@ -762,6 +815,9 @@ lgl_template_dup (const lglTemplate *orig_template) 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->aliases; p != NULL; p=p->next ) { alias = (lglTemplateAlias *)p->data; diff --git a/libglabels/template.h b/libglabels/template.h index f8e5383c..5793ea6c 100644 --- a/libglabels/template.h +++ b/libglabels/template.h @@ -52,22 +52,25 @@ struct _lglTemplate { gchar *brand; gchar *part; + gchar *equiv_part; + gchar *description; gchar *paper_id; gdouble page_width; gdouble page_height; - /* List of (lglTemplateAlias *) aliase structures. */ - GList *aliases; - - /* List of (gchar *) category ids. */ - GList *category_ids; + /* 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; + /* Deprecated: List of (lglTemplateAlias *) alias structures. */ + GList *aliases; + }; @@ -290,6 +293,10 @@ lglTemplate *lgl_template_new (const gchar *br 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_alias (lglTemplate *template, lglTemplateAlias *alias); diff --git a/libglabels/vendor.c b/libglabels/vendor.c new file mode 100644 index 00000000..9ee29bfb --- /dev/null +++ b/libglabels/vendor.c @@ -0,0 +1,133 @@ +/* + * vendor.c + * Copyright (C) 2003-2009 Jim Evins . + * + * 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 . + */ + +#include + +#include "vendor.h" + +#include +#include +#include + +#include "libglabels-private.h" + +/*===========================================*/ +/* Private types */ +/*===========================================*/ + + +/*===========================================*/ +/* Private globals */ +/*===========================================*/ + + +/*===========================================*/ +/* Local function prototypes */ +/*===========================================*/ + + +/*===========================================*/ +/* Functions. */ +/*===========================================*/ + +/** + * lgl_vendor_new: + * @id: Id of vendor definition. (E.g. US-Letter, A4, etc.) Should be + * unique. + * @name: Localized name of vendor. + * @width: Width of vendor in points. + * @height: Height of vendor in points. + * @pwg_size: PWG 5101.1-2002 size name. + * + * 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 new file mode 100644 index 00000000..68b9ff58 --- /dev/null +++ b/libglabels/vendor.h @@ -0,0 +1,63 @@ +/* + * vendor.h + * Copyright (C) 2003-2009 Jim Evins . + * + * 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 . + */ + +#ifndef __LGL_VENDOR_H__ +#define __LGL_VENDOR_H__ + +#include + +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-template.c b/libglabels/xml-template.c index 9a880c3c..c33cc583 100644 --- a/libglabels/xml-template.c +++ b/libglabels/xml-template.c @@ -64,7 +64,8 @@ static void xml_parse_markup_rect_node (xmlNodePtr markup_node static void xml_parse_alias_node (xmlNodePtr alias_node, lglTemplate *template); -static void xml_create_meta_node (const gchar *category, +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, @@ -99,7 +100,7 @@ static void xml_create_alias_node (const lglTemplateAlias *alias * Returns: a list of #lglTemplate structures. * */ -GList * +void lgl_xml_template_read_templates_from_file (const gchar *utf8_filename) { gchar *filename; @@ -111,22 +112,20 @@ lgl_xml_template_read_templates_from_file (const gchar *utf8_filename) filename = g_filename_from_utf8 (utf8_filename, -1, NULL, NULL, NULL); if (!filename) { g_message ("Utf8 filename conversion error"); - return NULL; + return; } templates_doc = xmlParseFile (filename); if (!templates_doc) { g_message ("\"%s\" is not a glabels template file (not XML)", filename); - return templates; + return; } - templates = lgl_xml_template_parse_templates_doc (templates_doc); + lgl_xml_template_parse_templates_doc (templates_doc); g_free (filename); xmlFreeDoc (templates_doc); - - return templates; } @@ -139,11 +138,10 @@ lgl_xml_template_read_templates_from_file (const gchar *utf8_filename) * Returns: a list of #lglTemplate structures. * */ -GList * +void lgl_xml_template_parse_templates_doc (const xmlDocPtr templates_doc) { - GList *templates = NULL; xmlNodePtr root, node; lglTemplate *template; @@ -153,19 +151,20 @@ lgl_xml_template_parse_templates_doc (const xmlDocPtr templates_doc) if (!root || !root->name) { g_message ("\"%s\" is not a glabels template file (no root node)", templates_doc->URL); - return templates; + 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 templates; + 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); - templates = g_list_append (templates, template); + _lgl_db_register_template_internal (template); + lgl_template_free (template); } else { if ( !xmlNodeIsText(node) ) { if (!lgl_xml_is_node (node,"comment")) { @@ -174,8 +173,6 @@ lgl_xml_template_parse_templates_doc (const xmlDocPtr templates_doc) } } } - - return templates; } @@ -194,10 +191,11 @@ 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; + lglPaper *paper = NULL; lglTemplate *template; xmlNodePtr node; gchar **v; @@ -222,6 +220,10 @@ lgl_xml_template_parse_template_node (const xmlNodePtr template_node) } } + + 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); @@ -254,8 +256,23 @@ lgl_xml_template_parse_template_node (const xmlNodePtr template_node) paper = NULL; } - template = lgl_template_new (brand, part, description, - paper_id, page_width, page_height); + + 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) { @@ -280,6 +297,7 @@ lgl_xml_template_parse_template_node (const xmlNodePtr template_node) g_free (brand); g_free (part); + g_free (equiv_part); g_free (description); g_free (paper_id); @@ -293,11 +311,18 @@ static void xml_parse_meta_node (xmlNodePtr meta_node, lglTemplate *template) { + gchar *product_url; gchar *category; - category = lgl_xml_get_prop_string (meta_node, "category", NULL); + 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; + } - if (category != NULL) + category = lgl_xml_get_prop_string (meta_node, "category", NULL); + if ( category != NULL ) { lgl_template_add_category (template, category); g_free (category); @@ -746,9 +771,10 @@ lgl_xml_template_create_template_node (const lglTemplate *template, xml_create_alias_node ( alias, node, ns ); } } + 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 ( p->data, node, ns ); + xml_create_meta_node ( "category", p->data, node, ns ); } for ( p=template->frames; p != NULL; p=p->next ) { @@ -759,17 +785,21 @@ lgl_xml_template_create_template_node (const lglTemplate *template, } /*--------------------------------------------------------------------------*/ -/* PRIVATE. Add XML Template->Meta Node. */ +/* PRIVATE. Add XML Template->Meta Node with category. */ /*--------------------------------------------------------------------------*/ static void -xml_create_meta_node (const gchar *category, - xmlNodePtr root, - const xmlNsPtr ns) +xml_create_meta_node (const gchar *attr, + const gchar *value, + xmlNodePtr root, + const xmlNsPtr ns) { xmlNodePtr node; - node = xmlNewChild (root, ns, (xmlChar *)"Meta", NULL); - lgl_xml_set_prop_string (node, "category", category); + if ( value != NULL ) + { + node = xmlNewChild (root, ns, (xmlChar *)"Meta", NULL); + lgl_xml_set_prop_string (node, attr, value); + } } diff --git a/libglabels/xml-template.h b/libglabels/xml-template.h index 205faa7a..3c323491 100644 --- a/libglabels/xml-template.h +++ b/libglabels/xml-template.h @@ -28,9 +28,9 @@ G_BEGIN_DECLS -GList *lgl_xml_template_read_templates_from_file (const gchar *utf8_filename); +void lgl_xml_template_read_templates_from_file (const gchar *utf8_filename); -GList *lgl_xml_template_parse_templates_doc (const xmlDocPtr templates_doc); +void lgl_xml_template_parse_templates_doc (const xmlDocPtr templates_doc); lglTemplate *lgl_xml_template_parse_template_node (const xmlNodePtr template_node); diff --git a/libglabels/xml-vendor.c b/libglabels/xml-vendor.c new file mode 100644 index 00000000..153f935f --- /dev/null +++ b/libglabels/xml-vendor.c @@ -0,0 +1,176 @@ +/* + * xml-vendor.c + * Copyright (C) 2003-2009 Jim Evins . + * + * 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 . + */ + +#include + +#include "xml-vendor.h" + +#include +#include +#include +#include + +#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; + gchar *url; + + + 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 new file mode 100644 index 00000000..a565eb09 --- /dev/null +++ b/libglabels/xml-vendor.h @@ -0,0 +1,51 @@ +/* + * xml-vendor.h + * Copyright (C) 2003-2009 Jim Evins . + * + * 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 . + */ + +#ifndef __LGL_XML_VENDOR_H__ +#define __LGL_XML_VENDOR_H__ + +#include +#include + +#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/templates/Makefile.am b/templates/Makefile.am index e740e61b..cf2cd1e2 100644 --- a/templates/Makefile.am +++ b/templates/Makefile.am @@ -10,6 +10,7 @@ templatesdir = $(datadir)/glabels/templates templates_DATA = \ paper-sizes.xml \ categories.xml \ + vendors.xml \ avery-us-templates.xml \ avery-iso-templates.xml \ avery-other-templates.xml \ diff --git a/templates/avery-us-templates.xml b/templates/avery-us-templates.xml index 6626ed0f..a1861aa7 100644 --- a/templates/avery-us-templates.xml +++ b/templates/avery-us-templates.xml @@ -40,7 +40,7 @@ - + +