From: Jim Evins Date: Sun, 19 Dec 2010 04:11:04 +0000 (-0500) Subject: Renamed libglabels source files to have "lgl-" prefix. X-Git-Tag: glabels-2_3_1~28 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=5c6f4d559896d7290d8877651d60010eefc1c6bb;p=glabels Renamed libglabels source files to have "lgl-" prefix. Improve odds that source files (headers in particular) remain unique. --- diff --git a/docs/libglabels/libglabels-3.0-sections.txt b/docs/libglabels/libglabels-3.0-sections.txt index 5323ab0f..7efab0c5 100644 --- a/docs/libglabels/libglabels-3.0-sections.txt +++ b/docs/libglabels/libglabels-3.0-sections.txt @@ -1,6 +1,6 @@
db -libglabels/db.h +libglabels/lgl-db.h lglDbRegStatus lglDbDeleteStatus @@ -58,7 +58,7 @@ lgl_db_print_known_vendors
template -libglabels/template.h +libglabels/lgl-template.h lglTemplate lglTemplateFrameShape @@ -127,7 +127,7 @@ lgl_template_print
paper -libglabels/paper.h +libglabels/lgl-paper.h lglPaper lgl_paper_new lgl_paper_dup @@ -136,7 +136,7 @@ lgl_paper_free
category -libglabels/category.h +libglabels/lgl-category.h lglCategory lgl_category_new lgl_category_dup @@ -145,7 +145,7 @@ lgl_category_free
vendor -libglabels/vendor.h +libglabels/lgl-vendor.h lglVendor lgl_vendor_new lgl_vendor_dup @@ -154,7 +154,7 @@ lgl_vendor_free
xml-paper -libglabels/xml-paper.h +libglabels/lgl-xml-paper.h 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
xml-category -libglabels/xml-category.h +libglabels/lgl-xml-category.h 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
xml-template -libglabels/xml-templates.h +libglabels/lgl-xml-templates.h 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
xml-vendor -libglabels/xml-vendor.h +libglabels/lgl-xml-vendor.h 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
xml -libglabels/xml.h +libglabels/lgl-xml.h LGL_XML_NAME_SPACE lgl_xml_get_prop_string @@ -215,7 +215,7 @@ lgl_xml_set_default_units
units -libglabels/units.h +libglabels/lgl-units.h lglUnits lgl_units_get_id lgl_units_from_id @@ -227,7 +227,7 @@ lgl_units_get_units_per_point
str -libglabels/str.h +libglabels/lgl-str.h lgl_str_utf8_casecmp lgl_str_part_name_cmp lgl_str_format_fraction diff --git a/libglabels/Makefile.am b/libglabels/Makefile.am index 4d43f5c0..f9013460 100644 --- a/libglabels/Makefile.am +++ b/libglabels/Makefile.am @@ -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 index f7f4052c..00000000 --- a/libglabels/category.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * category.c - * Copyright (C) 2006-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 "category.h" - -#include -#include -#include - -#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 index b62b9065..00000000 --- a/libglabels/category.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * category.h - * Copyright (C) 2006-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_CATEGORY_H__ -#define __LGL_CATEGORY_H__ - -#include - -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 index daf914c4..00000000 --- a/libglabels/db.c +++ /dev/null @@ -1,2103 +0,0 @@ -/* - * db.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 "db.h" - -#include -#include -#include -#include -#include -#include -#include - -#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 index bcba326b..00000000 --- a/libglabels/db.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * db.h - * Copyright (C) 2006-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_DB_H__ -#define __LGL_DB_H__ - -#include - -#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 index 00000000..a7335354 --- /dev/null +++ b/libglabels/lgl-category.c @@ -0,0 +1,132 @@ +/* + * lgl-category.c + * Copyright (C) 2006-2010 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 "lgl-category.h" + +#include +#include +#include + +#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 index 00000000..8ac35362 --- /dev/null +++ b/libglabels/lgl-category.h @@ -0,0 +1,62 @@ +/* + * lgl-category.h + * Copyright (C) 2006-2010 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_CATEGORY_H__ +#define __LGL_CATEGORY_H__ + +#include + +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 index 00000000..fed3aeec --- /dev/null +++ b/libglabels/lgl-db.c @@ -0,0 +1,2103 @@ +/* + * lgl-db.c + * Copyright (C) 2003-2010 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 "lgl-db.h" + +#include +#include +#include +#include +#include +#include +#include + +#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 index 00000000..a505e62a --- /dev/null +++ b/libglabels/lgl-db.h @@ -0,0 +1,197 @@ +/* + * lgl-db.h + * Copyright (C) 2006-2010 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_DB_H__ +#define __LGL_DB_H__ + +#include + +#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 index 00000000..43cca91c --- /dev/null +++ b/libglabels/lgl-paper.c @@ -0,0 +1,147 @@ +/* + * lgl-paper.c + * Copyright (C) 2003-2010 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 "lgl-paper.h" + +#include +#include +#include + +#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 index 00000000..ecb5b8ee --- /dev/null +++ b/libglabels/lgl-paper.h @@ -0,0 +1,70 @@ +/* + * lgl-paper.h + * Copyright (C) 2003-2010 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_PAPER_H__ +#define __LGL_PAPER_H__ + +#include + +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 index 00000000..4618fadf --- /dev/null +++ b/libglabels/lgl-str.c @@ -0,0 +1,278 @@ +/* + * lgl-str.c + * Copyright (C) 2007-2010 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 "lgl-str.h" + +#include +#include + +#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 index 00000000..3c096b01 --- /dev/null +++ b/libglabels/lgl-str.h @@ -0,0 +1,50 @@ +/* + * lgl-str.h + * Copyright (C) 2007-2010 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_STR_H__ +#define __LGL_STR_H__ + +#include + +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 index 00000000..11763dcf --- /dev/null +++ b/libglabels/lgl-template.c @@ -0,0 +1,1397 @@ +/* + * lgl-template.c + * Copyright (C) 2001-2010 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 "lgl-template.h" + +#include +#include +#include +#include +#include +#include + +#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 index 00000000..c1439ab2 --- /dev/null +++ b/libglabels/lgl-template.h @@ -0,0 +1,424 @@ +/* + * lgl-template.h + * Copyright (C) 2001-2010 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_TEMPLATE_H__ +#define __LGL_TEMPLATE_H__ + +#include +#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 index 00000000..73d243d0 --- /dev/null +++ b/libglabels/lgl-units.c @@ -0,0 +1,254 @@ +/* + * lgl-units.c + * Copyright (C) 2003-2010 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 "lgl-units.h" + +#include +#include +#include + +#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 index 00000000..b22be074 --- /dev/null +++ b/libglabels/lgl-units.h @@ -0,0 +1,70 @@ +/* + * lgl-units.h + * Copyright (C) 2003-2010 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_UNITS_H__ +#define __LGL_UNITS_H__ + +#include + +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 index 00000000..425c1b53 --- /dev/null +++ b/libglabels/lgl-vendor.c @@ -0,0 +1,128 @@ +/* + * lgl-vendor.c + * Copyright (C) 2003-2010 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 "lgl-vendor.h" + +#include +#include +#include + +#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 index 00000000..fc0be293 --- /dev/null +++ b/libglabels/lgl-vendor.h @@ -0,0 +1,63 @@ +/* + * lgl-vendor.h + * Copyright (C) 2003-2010 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/lgl-xml-category.c b/libglabels/lgl-xml-category.c new file mode 100644 index 00000000..91822eec --- /dev/null +++ b/libglabels/lgl-xml-category.c @@ -0,0 +1,175 @@ +/* + * lgl-xml-category.c + * Copyright (C) 2006-2010 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 "lgl-xml-category.h" + +#include +#include +#include +#include + +#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 index 00000000..1f535e9b --- /dev/null +++ b/libglabels/lgl-xml-category.h @@ -0,0 +1,51 @@ +/* + * lgl-xml-category.h + * Copyright (C) 2006-2010 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_CATEGORY_H__ +#define __LGL_XML_CATEGORY_H__ + +#include +#include + +#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 index 00000000..549f9e8a --- /dev/null +++ b/libglabels/lgl-xml-paper.c @@ -0,0 +1,182 @@ +/* + * lgl-xml-paper.c + * Copyright (C) 2003-2010 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 "lgl-xml-paper.h" + +#include +#include +#include +#include + +#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 index 00000000..e4704c62 --- /dev/null +++ b/libglabels/lgl-xml-paper.h @@ -0,0 +1,51 @@ +/* + * lgl-xml-paper.h + * Copyright (C) 2003-2010 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_PAPER_H__ +#define __LGL_XML_PAPER_H__ + +#include +#include + +#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 index 00000000..95a2a659 --- /dev/null +++ b/libglabels/lgl-xml-template.c @@ -0,0 +1,1105 @@ +/* + * lgl-xml-template.c + * Copyright (C) 2001-2010 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 "lgl-xml-template.h" + +#include +#include +#include +#include + +#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 index 00000000..99b52d39 --- /dev/null +++ b/libglabels/lgl-xml-template.h @@ -0,0 +1,61 @@ +/* + * lgl-xml-template.h + * Copyright (C) 2001-2010 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_TEMPLATE_H__ +#define __LGL_XML_TEMPLATE_H__ + +#include +#include + +#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 index 00000000..cc44bc87 --- /dev/null +++ b/libglabels/lgl-xml-vendor.c @@ -0,0 +1,174 @@ +/* + * lgl-xml-vendor.c + * Copyright (C) 2003-2010 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 "lgl-xml-vendor.h" + +#include +#include +#include +#include + +#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 index 00000000..0aac3b71 --- /dev/null +++ b/libglabels/lgl-xml-vendor.h @@ -0,0 +1,51 @@ +/* + * lgl-xml-vendor.h + * Copyright (C) 2003-2010 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 "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 index 00000000..8a090198 --- /dev/null +++ b/libglabels/lgl-xml.c @@ -0,0 +1,514 @@ +/* + * lgl-xml.c + * Copyright (C) 2003-2010 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 "lgl-xml.h" + +#include +#include +#include + +#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 index 00000000..8bae2431 --- /dev/null +++ b/libglabels/lgl-xml.h @@ -0,0 +1,119 @@ +/* + * lgl-xml.h + * Copyright (C) 2003-2010 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_H__ +#define __LGL_XML_H__ + +#include +#include + +#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 + */ diff --git a/libglabels/libglabels-private.h b/libglabels/libglabels-private.h index 726c8039..43ea4cd4 100644 --- a/libglabels/libglabels-private.h +++ b/libglabels/libglabels-private.h @@ -23,8 +23,8 @@ #include -#include "str.h" -#include "template.h" +#include "lgl-str.h" +#include "lgl-template.h" #undef G_LOG_DOMAIN #define G_LOG_DOMAIN "LibGlabels" diff --git a/libglabels/libglabels.h b/libglabels/libglabels.h index 6d456700..222670ca 100644 --- a/libglabels/libglabels.h +++ b/libglabels/libglabels.h @@ -21,16 +21,16 @@ #ifndef __LIBGLABELS_H__ #define __LIBGLABELS_H__ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #endif /* __LIBGLABELS_H__ */ diff --git a/libglabels/paper.c b/libglabels/paper.c deleted file mode 100644 index d0b80fbb..00000000 --- a/libglabels/paper.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * paper.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 "paper.h" - -#include -#include -#include - -#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 index 46a7a64d..00000000 --- a/libglabels/paper.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * paper.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_PAPER_H__ -#define __LGL_PAPER_H__ - -#include - -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 index a9364c7d..00000000 --- a/libglabels/str.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * str.c - * Copyright (C) 2007-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 "str.h" - -#include -#include - -#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 index b22f13b5..00000000 --- a/libglabels/str.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * str.h - * Copyright (C) 2007-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_STR_H__ -#define __LGL_STR_H__ - -#include - -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 index b28a6c24..00000000 --- a/libglabels/template.c +++ /dev/null @@ -1,1397 +0,0 @@ -/* - * template.c - * Copyright (C) 2001-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 "template.h" - -#include -#include -#include -#include -#include -#include - -#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 index 74e50cf8..00000000 --- a/libglabels/template.h +++ /dev/null @@ -1,424 +0,0 @@ -/* - * template.h - * Copyright (C) 2001-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_TEMPLATE_H__ -#define __LGL_TEMPLATE_H__ - -#include -#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 index e585962b..00000000 --- a/libglabels/units.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * units.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 "units.h" - -#include -#include -#include - -#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 index ac3bb0c7..00000000 --- a/libglabels/units.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * units.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_UNITS_H__ -#define __LGL_UNITS_H__ - -#include - -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 index e7f950bd..00000000 --- a/libglabels/vendor.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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: - * @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 index 68b9ff58..00000000 --- a/libglabels/vendor.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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-category.c b/libglabels/xml-category.c deleted file mode 100644 index 4925eba3..00000000 --- a/libglabels/xml-category.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * xml-category.c - * Copyright (C) 2006-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-category.h" - -#include -#include -#include -#include - -#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 index acfc5a53..00000000 --- a/libglabels/xml-category.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * xml-category.h - * Copyright (C) 2006-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_CATEGORY_H__ -#define __LGL_XML_CATEGORY_H__ - -#include -#include - -#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 index 00263e71..00000000 --- a/libglabels/xml-paper.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * xml-paper.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-paper.h" - -#include -#include -#include -#include - -#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 index 71c30878..00000000 --- a/libglabels/xml-paper.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * xml-paper.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_PAPER_H__ -#define __LGL_XML_PAPER_H__ - -#include -#include - -#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 index 8e9f5b3d..00000000 --- a/libglabels/xml-template.c +++ /dev/null @@ -1,1105 +0,0 @@ -/* - * xml-template.c - * Copyright (C) 2001-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-template.h" - -#include -#include -#include -#include - -#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 index 3c323491..00000000 --- a/libglabels/xml-template.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * xml-template.h - * Copyright (C) 2001-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_TEMPLATE_H__ -#define __LGL_XML_TEMPLATE_H__ - -#include -#include - -#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 index c6ba9911..00000000 --- a/libglabels/xml-vendor.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * 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; - - 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 index a565eb09..00000000 --- a/libglabels/xml-vendor.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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/libglabels/xml.c b/libglabels/xml.c deleted file mode 100644 index 4bce17e2..00000000 --- a/libglabels/xml.c +++ /dev/null @@ -1,514 +0,0 @@ -/* - * xml.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.h" - -#include -#include -#include - -#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 index 8b5ba9dd..00000000 --- a/libglabels/xml.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * xml.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_H__ -#define __LGL_XML_H__ - -#include -#include - -#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 - */ diff --git a/po/POTFILES.in b/po/POTFILES.in index 5f1297bb..f71c35b4 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -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