<child type="tab">
<object class="GtkLabel" id="recent_tab_label">
<property name="visible">True</property>
- <property name="label" translatable="yes">Recent templates</property>
+ <property name="xpad">12</property>
+ <property name="label" translatable="yes">Recent</property>
</object>
<packing>
<property name="tab_fill">False</property>
<child type="tab">
<object class="GtkLabel" id="search_all_tabLlabel">
<property name="visible">True</property>
- <property name="label" translatable="yes">Search all templates</property>
+ <property name="xpad">12</property>
+ <property name="label" translatable="yes">Search all</property>
</object>
<packing>
<property name="position">1</property>
<property name="tab_fill">False</property>
</packing>
</child>
+ <child>
+ <object class="GtkVBox" id="custom_tab_vbox">
+ <property name="height_request">320</property>
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkVBox" id="custom_info_vbox">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow3">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="custom_treeview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <property name="spacing">9</property>
+ <child>
+ <object class="GtkButton" id="custom_add_button">
+ <property name="label">gtk-add</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="custom_edit_button">
+ <property name="label">gtk-edit</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="custom_delete_button">
+ <property name="label">gtk-delete</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">6</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="xpad">12</property>
+ <property name="label" translatable="yes">Custom</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_expand">True</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
</object>
<packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
</object>
+ <object class="GtkSizeGroup" id="custom_buttons_sizegroup">
+ <widgets>
+ <widget name="custom_add_button"/>
+ <widget name="custom_edit_button"/>
+ <widget name="custom_delete_button"/>
+ </widgets>
+ </object>
</interface>
<object class="GtkLabel" id="label19">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">Choose label or card product from hundreds of predefined templates. You may also
-define your own templates.</property>
+ <property name="label" translatable="yes">Choose label or card product from hundreds of predefined templates or define your own.</property>
</object>
<packing>
<property name="expand">False</property>
#include <glib/gi18n.h>
#include <glib.h>
+#include <glib-object.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
/* 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 GList *papers = NULL;
-static GList *categories = NULL;
-static GList *vendors = NULL;
-static GList *templates = NULL;
+static guint signals[LAST_SIGNAL] = {0};
-static GHashTable *template_cache = NULL;
+static lglDbModel *model = NULL;
/*===========================================*/
/* Local function prototypes */
/*===========================================*/
-static void init_template_cache (void);
+static void lgl_db_model_finalize (GObject *object);
+
static void add_to_template_cache (lglTemplate *template);
static GList *read_papers (void);
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 */
/*===========================================*/
GList *page_sizes;
GList *p;
+ model = lgl_db_model_new ();
+
/*
* Paper definitions
*/
- if (!papers)
- {
-
- papers = read_papers ();
+ model->papers = read_papers ();
- /* Create and append an "Other" entry. */
- paper_other = lgl_paper_new ("Other", _("Other"), 0.0, 0.0, NULL);
- papers = g_list_append (papers, paper_other);
-
- }
+ /* Create and append an "Other" entry. */
+ paper_other = lgl_paper_new ("Other", _("Other"), 0.0, 0.0, NULL);
+ model->papers = g_list_append (model->papers, paper_other);
/*
* Categories
*/
- if (!categories)
- {
- categories = read_categories ();
+ model->categories = read_categories ();
- /* Create and append a "User defined" entry. */
- category_user_defined = lgl_category_new ("user-defined", _("User defined"));
- categories = g_list_append (categories, category_user_defined);
- }
+ /* 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
*/
- if (!vendors)
- {
- vendors = read_vendors ();
- }
+ model->vendors = read_vendors ();
/*
* Templates
*/
- if (!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);
- init_template_cache ();
+}
- 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);
+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);
+}
+
+
+void
+lgl_db_notify_remove (gulong id)
+{
+ g_signal_handler_disconnect (G_OBJECT (model), id);
}
GList *p;
lglPaper *paper;
- if (!papers)
+ if (!model)
{
lgl_db_init ();
}
- for ( p=papers; p != NULL; p=p->next )
+ for ( p=model->papers; p != NULL; p=p->next )
{
paper = (lglPaper *)p->data;
ids = g_list_append (ids, g_strdup (paper->id));
GList *p;
lglPaper *paper;
- if (!papers)
+ if (!model)
{
lgl_db_init ();
}
- for ( p=papers; p != NULL; p=p->next )
+ for ( p=model->papers; p != NULL; p=p->next )
{
paper = (lglPaper *)p->data;
names = g_list_append (names, g_strdup (paper->name));
GList *p;
lglPaper *paper;
- if (!papers)
+ if (!model)
{
lgl_db_init ();
}
if (name == NULL)
{
/* If no name, return first paper as a default */
- return lgl_paper_dup ((lglPaper *) papers->data);
+ return lgl_paper_dup ((lglPaper *) model->papers->data);
}
- for (p = papers; p != NULL; p = p->next)
+ for (p = model->papers; p != NULL; p = p->next)
{
paper = (lglPaper *) p->data;
if (UTF8_EQUAL (paper->name, name))
GList *p;
lglPaper *paper;
- if (!papers)
+ if (!model)
{
lgl_db_init ();
}
if (id == NULL)
{
/* If no id, return first paper as a default */
- return lgl_paper_dup ((lglPaper *) papers->data);
+ return lgl_paper_dup ((lglPaper *) model->papers->data);
}
- for (p = papers; p != NULL; p = p->next)
+ for (p = model->papers; p != NULL; p = p->next)
{
paper = (lglPaper *) p->data;
if (ASCII_EQUAL (paper->id, id))
GList *p;
lglPaper *paper;
- if (!papers)
+ if (!model)
{
lgl_db_init ();
}
return FALSE;
}
- for (p = papers; p != NULL; p = p->next)
+ for (p = model->papers; p != NULL; p = p->next)
{
paper = (lglPaper *) p->data;
if (ASCII_EQUAL (paper->id, id))
GList *p;
lglPaper *paper;
- if (!papers) {
+ if (!model) {
lgl_db_init ();
}
g_print ("%s():\n", __FUNCTION__);
- for (p = papers; p != NULL; p = p->next) {
+ 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",
GList *p;
lglCategory *category;
- if (!categories)
+ if (!model)
{
lgl_db_init ();
}
- for ( p=categories; p != NULL; p=p->next )
+ for ( p=model->categories; p != NULL; p=p->next )
{
category = (lglCategory *)p->data;
ids = g_list_append (ids, g_strdup (category->id));
GList *p;
lglCategory *category;
- if (!categories)
+ if (!model)
{
lgl_db_init ();
}
- for ( p=categories; p != NULL; p=p->next )
+ for ( p=model->categories; p != NULL; p=p->next )
{
category = (lglCategory *)p->data;
names = g_list_append (names, g_strdup (category->name));
GList *p;
lglCategory *category;
- if (!categories)
+ if (!model)
{
lgl_db_init ();
}
if (name == NULL)
{
/* If no name, return first category as a default */
- return lgl_category_dup ((lglCategory *) categories->data);
+ return lgl_category_dup ((lglCategory *) model->categories->data);
}
- for (p = categories; p != NULL; p = p->next)
+ for (p = model->categories; p != NULL; p = p->next)
{
category = (lglCategory *) p->data;
if (UTF8_EQUAL (category->name, name))
GList *p;
lglCategory *category;
- if (!categories)
+ if (!model)
{
lgl_db_init ();
}
if (id == NULL)
{
/* If no id, return first category as a default */
- return lgl_category_dup ((lglCategory *) categories->data);
+ return lgl_category_dup ((lglCategory *) model->categories->data);
}
- for (p = categories; p != NULL; p = p->next)
+ for (p = model->categories; p != NULL; p = p->next)
{
category = (lglCategory *) p->data;
if (ASCII_EQUAL (category->id, id))
GList *p;
lglCategory *category;
- if (!categories)
+ if (!model)
{
lgl_db_init ();
}
return FALSE;
}
- for (p = categories; p != NULL; p = p->next)
+ for (p = model->categories; p != NULL; p = p->next)
{
category = (lglCategory *) p->data;
if (ASCII_EQUAL (category->id, id))
GList *p;
lglCategory *category;
- if (!categories) {
+ if (!model) {
lgl_db_init ();
}
g_print ("%s():\n", __FUNCTION__);
- for (p = categories; p != NULL; p = p->next) {
+ 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);
GList *p;
lglVendor *vendor;
- if (!papers)
+ if (!model)
{
lgl_db_init ();
}
- for ( p=vendors; p != NULL; p=p->next )
+ for ( p=model->vendors; p != NULL; p=p->next )
{
vendor = (lglVendor *)p->data;
names = g_list_append (names, g_strdup (vendor->name));
GList *p;
lglVendor *vendor;
- if (!papers)
+ if (!model)
{
lgl_db_init ();
}
if (name == NULL)
{
/* If no name, return first vendor as a default */
- return lgl_vendor_dup ((lglVendor *) vendors->data);
+ return lgl_vendor_dup ((lglVendor *) model->vendors->data);
}
- for (p = vendors; p != NULL; p = p->next)
+ for (p = model->vendors; p != NULL; p = p->next)
{
vendor = (lglVendor *) p->data;
if (UTF8_EQUAL (vendor->name, name))
GList *p;
lglVendor *vendor;
- if (!papers)
+ if (!model)
{
lgl_db_init ();
}
return FALSE;
}
- for (p = vendors; p != NULL; p = p->next)
+ for (p = model->vendors; p != NULL; p = p->next)
{
vendor = (lglVendor *) p->data;
if (UTF8_EQUAL (vendor->name, name))
GList *p;
lglVendor *vendor;
- if (!papers) {
+ if (!model) {
lgl_db_init ();
}
g_print ("%s():\n", __FUNCTION__);
- for (p = vendors; p != NULL; p = p->next) {
+ for (p = model->vendors; p != NULL; p = p->next) {
vendor = (lglVendor *) p->data;
g_print ("VENDOR name=\"%s\", url=\"%s\"\n",
lglTemplateAlias *alias;
GList *brands = NULL;
- if (!templates)
+ if (!model)
{
lgl_db_init ();
}
- for (p_tmplt = templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
+ 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) &&
lglTemplate *template_copy;
template_copy = lgl_template_dup (template);
- templates = g_list_append (templates, template_copy);
+ model->templates = g_list_append (model->templates, template_copy);
add_to_template_cache (template_copy);
}
gchar *dir, *filename, *abs_filename;
gint bytes_written;
- if (!templates)
+ if (!model)
{
lgl_db_init ();
}
{
template_copy = lgl_template_dup (template);
lgl_template_add_category (template_copy, "user-defined");
- templates = g_list_append (templates, template_copy);
+ 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
}
+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 = LGL_USER_DATA_DIR;
+ filename = g_strdup_printf ("%s_%s.template", template->brand, template->part);
+ abs_filename = g_build_filename (dir, filename, NULL);
+
+ 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_does_template_exist:
* @brand: Brand name.
lglTemplate *template;
lglTemplateAlias *alias;
- if (!templates)
+ if (!model)
{
lgl_db_init ();
}
return FALSE;
}
- for (p_tmplt = templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
+ for (p_tmplt = model->templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
{
template = (lglTemplate *) p_tmplt->data;
for (p_alias = template->aliases; p_alias != NULL; p_alias = p_alias->next)
lglTemplateAlias *alias;
gchar *candidate_name;
- if (!templates)
+ if (!model)
{
lgl_db_init ();
}
return FALSE;
}
- for (p_tmplt = templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
+ for (p_tmplt = model->templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
{
template = (lglTemplate *) p_tmplt->data;
for (p_alias = template->aliases; p_alias != NULL; p_alias = p_alias->next)
gchar *name;
GList *names = NULL;
- if (!templates)
+ if (!model)
{
lgl_db_init ();
}
- for (p_tmplt = templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
+ for (p_tmplt = model->templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
{
template = (lglTemplate *) p_tmplt->data;
gchar *name;
GList *names = NULL;
- if (!templates)
+ if (!model)
{
lgl_db_init ();
}
- for (p_tmplt = templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
+ 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) &&
gchar *name2;
GList *names = NULL;
- if (!templates)
+ if (!model)
{
lgl_db_init ();
}
}
}
- for (p_tmplt = templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
+ for (p_tmplt = model->templates; p_tmplt != NULL; p_tmplt = p_tmplt->next)
{
template2 = (lglTemplate *) p_tmplt->data;
gchar *candidate_name;
lglTemplate *new_template;
- if (!templates)
+ if (!model)
{
lgl_db_init ();
}
if (name == NULL)
{
/* If no name, return first template as a default */
- return lgl_template_dup ((lglTemplate *) templates->data);
+ return lgl_template_dup ((lglTemplate *) model->templates->data);
}
- template = g_hash_table_lookup (template_cache, name);
+ template = g_hash_table_lookup (model->template_cache, name);
if (template)
{
}
/* No matching template has been found so return the first template */
- return lgl_template_dup ((lglTemplate *) templates->data);
+ return lgl_template_dup ((lglTemplate *) model->templates->data);
}
gchar *candidate_name;
lglTemplate *new_template;
- if (!templates)
+ if (!model)
{
lgl_db_init ();
}
if ((brand == NULL) || (part == NULL))
{
/* If no name, return first template as a default */
- return lgl_template_dup ((lglTemplate *) templates->data);
+ return lgl_template_dup ((lglTemplate *) model->templates->data);
}
name = g_strdup_printf ("%s %s", brand, part);
- template = g_hash_table_lookup (template_cache, name);
+ template = g_hash_table_lookup (model->template_cache, name);
if (template)
{
/* No matching template has been found so return the first template */
g_free (name);
- return lgl_template_dup ((lglTemplate *) templates->data);
-}
-
-
-static void
-init_template_cache (void)
-{
- template_cache = g_hash_table_new (g_str_hash, g_str_equal);
+ return lgl_template_dup ((lglTemplate *) model->templates->data);
}
alias = (lglTemplateAlias *)p_alias->data;
name = g_strdup_printf ("%s %s", alias->brand, alias->part);
- g_hash_table_insert (template_cache, name, template);
+ g_hash_table_insert (model->template_cache, name, template);
}
}
data_dir = LGL_USER_DATA_DIR;
read_template_files_from_dir (data_dir);
g_free (data_dir);
- for ( p=templates; p != NULL; p=p->next )
+ for ( p=model->templates; p != NULL; p=p->next )
{
template = (lglTemplate *)p->data;
lgl_template_add_category (template, "user-defined");
read_template_files_from_dir (data_dir);
g_free (data_dir);
- if (templates == NULL)
+ if (model->templates == NULL)
{
g_critical (_("Unable to locate any template files. Libglabels may not be installed correctly!"));
}
GList *p;
lglTemplate *template;
+ if (!model)
+ {
+ lgl_db_init ();
+ }
+
g_print ("%s():\n", __FUNCTION__);
- for (p=templates; p!=NULL; p=p->next)
+ for (p=model->templates; p!=NULL; p=p->next)
{
template = (lglTemplate *)p->data;
GList *p;
lglTemplateAlias *alias;
+ if (!model)
+ {
+ lgl_db_init ();
+ }
+
g_print ("%s():\n", __FUNCTION__);
for (p=template->aliases; p!=NULL; p=p->next)
{
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
*/
*/
lglDbRegStatus lgl_db_register_template (const lglTemplate *template);
+lglDbDeleteStatus lgl_db_delete_template_by_name (const gchar *name);
+
gboolean lgl_db_does_template_exist (const gchar *brand,
const gchar *part);
-SUBDIRS= pixmaps stock-pixmaps
+SUBDIRS= ../libglabels pixmaps stock-pixmaps
bin_PROGRAMS = glabels-3 glabels-3-batch
#include "prefs.h"
#include "message-bar.h"
#include "template-history.h"
+#include "template-designer.h"
#include "str-util.h"
#include "combo-util.h"
#include "builder-util.h"
struct _glMediaSelectPrivate {
+ gulong db_notify_id;
+
GtkBuilder *builder;
GtkWidget *notebook;
GtkWidget *search_all_treeview;
GtkListStore *search_all_store;
+ gint custom_page_num;
+ GtkWidget *custom_tab_vbox;
+ GtkWidget *custom_info_vbox;
+ GtkWidget *custom_info_bar;
+ GtkWidget *custom_treeview;
+ GtkListStore *custom_store;
+ GtkWidget *custom_add_button;
+ GtkWidget *custom_edit_button;
+ GtkWidget *custom_delete_button;
+
/* Prevent recursion */
gboolean stop_signals;
};
/* Private globals */
/*===========================================*/
-static gint media_select_signals[LAST_SIGNAL] = { 0 };
+static gint signals[LAST_SIGNAL] = { 0 };
/*===========================================*/
static void gl_media_select_construct (glMediaSelect *this);
-static void filter_changed_cb (GtkComboBox *combo,
- gpointer user_data);
+static void filter_changed_cb (glMediaSelect *this);
static void selection_changed_cb (GtkTreeSelection *selection,
gpointer user_data);
+static void custom_add_clicked_cb (GtkButton *button,
+ gpointer user_data);
+
+static void custom_edit_clicked_cb (GtkButton *button,
+ gpointer user_data);
+
+static void custom_delete_clicked_cb (GtkButton *button,
+ gpointer user_data);
+
static void page_changed_cb (GtkNotebook *notebook,
GtkNotebookPage *page,
guint page_num,
gpointer user_data);
+static void db_changed_cb (glMediaSelect *this);
+
static void load_recent_list (glMediaSelect *this,
GtkListStore *store,
GtkTreeSelection *selection,
GList *list);
+static void load_custom_list (glMediaSelect *this,
+ GtkListStore *store,
+ GtkTreeSelection *selection,
+ GList *list);
+
static void load_search_all_list (glMediaSelect *this,
GtkListStore *store,
GtkTreeSelection *selection,
object_class->finalize = gl_media_select_finalize;
- media_select_signals[CHANGED] =
+ signals[CHANGED] =
g_signal_new ("changed",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
g_return_if_fail (object != NULL);
g_return_if_fail (GL_IS_MEDIA_SELECT (object));
+ if (this->priv->db_notify_id)
+ {
+ lgl_db_notify_remove (this->priv->db_notify_id);
+ }
+
if (this->priv->builder)
{
g_object_unref (this->priv->builder);
{
gchar *builder_filename;
GtkBuilder *builder;
- static gchar *object_ids[] = { "media_select_hbox", NULL };
+ static gchar *object_ids[] = { "media_select_hbox",
+ "custom_buttons_sizegroup",
+ NULL };
GError *error = NULL;
GtkWidget *hbox;
GList *recent_list = NULL;
GList *search_all_names = NULL;
const gchar *page_size_id;
gchar *page_size_name;
+ GList *custom_list = NULL;
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
GtkTreeSelection *recent_selection;
GtkTreeSelection *search_all_selection;
+ GtkTreeSelection *custom_selection;
gl_debug (DEBUG_MEDIA_SELECT, "START");
"category_combo", &this->priv->category_combo,
"search_all_info_vbox", &this->priv->search_all_info_vbox,
"search_all_treeview", &this->priv->search_all_treeview,
+ "custom_tab_vbox", &this->priv->custom_tab_vbox,
+ "custom_info_vbox", &this->priv->custom_info_vbox,
+ "custom_treeview", &this->priv->custom_treeview,
+ "custom_add_button", &this->priv->custom_add_button,
+ "custom_edit_button", &this->priv->custom_edit_button,
+ "custom_delete_button", &this->priv->custom_delete_button,
NULL);
gtk_container_add (GTK_CONTAINER (this), hbox);
this->priv->search_all_page_num =
gtk_notebook_page_num (GTK_NOTEBOOK (this->priv->notebook),
this->priv->search_all_tab_vbox);
+ this->priv->custom_page_num =
+ gtk_notebook_page_num (GTK_NOTEBOOK (this->priv->notebook),
+ this->priv->custom_tab_vbox);
gtk_widget_show_all (GTK_WIDGET (this));
load_search_all_list (this, this->priv->search_all_store, search_all_selection, search_all_names);
lgl_db_free_template_name_list (search_all_names);
+ /* Custom templates treeview */
+ this->priv->custom_store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (this->priv->custom_treeview),
+ GTK_TREE_MODEL (this->priv->custom_store));
+ renderer = gtk_cell_renderer_pixbuf_new ();
+ column = gtk_tree_view_column_new_with_attributes ("", renderer,
+ "pixbuf", PREVIEW_COLUMN,
+ "stock-id", PREVIEW_COLUMN_STOCK,
+ "stock-size", PREVIEW_COLUMN_STOCK_SIZE,
+ NULL);
+ gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (this->priv->custom_treeview), column);
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes ("", renderer,
+ "markup", DESCRIPTION_COLUMN,
+ NULL);
+ gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (this->priv->custom_treeview), column);
+ custom_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (this->priv->custom_treeview));
+ custom_list = lgl_db_get_template_name_list_all (NULL, NULL, "user-defined");
+ load_custom_list (this, this->priv->custom_store, custom_selection, custom_list);
+ lgl_db_free_template_name_list (custom_list);
+
+ page_size_id = gl_prefs_model_get_default_page_size (gl_prefs);
+ page_size_name = lgl_db_lookup_paper_name_from_id (page_size_id);
+
/* Connect signals to controls */
- g_signal_connect (G_OBJECT (this->priv->brand_combo), "changed",
- G_CALLBACK (filter_changed_cb),
- this);
- g_signal_connect (G_OBJECT (this->priv->page_size_combo), "changed",
- G_CALLBACK (filter_changed_cb),
- this);
- g_signal_connect (G_OBJECT (this->priv->category_combo), "changed",
- G_CALLBACK (filter_changed_cb),
- this);
+ g_signal_connect_swapped (G_OBJECT (this->priv->brand_combo), "changed",
+ G_CALLBACK (filter_changed_cb),
+ this);
+ g_signal_connect_swapped (G_OBJECT (this->priv->page_size_combo), "changed",
+ G_CALLBACK (filter_changed_cb),
+ this);
+ g_signal_connect_swapped (G_OBJECT (this->priv->category_combo), "changed",
+ G_CALLBACK (filter_changed_cb),
+ this);
g_signal_connect (G_OBJECT (recent_selection), "changed",
G_CALLBACK (selection_changed_cb),
this);
g_signal_connect (G_OBJECT (search_all_selection), "changed",
G_CALLBACK (selection_changed_cb),
this);
+ g_signal_connect (G_OBJECT (custom_selection), "changed",
+ G_CALLBACK (selection_changed_cb),
+ this);
+ g_signal_connect (G_OBJECT (this->priv->custom_add_button), "clicked",
+ G_CALLBACK (custom_add_clicked_cb),
+ this);
+ g_signal_connect (G_OBJECT (this->priv->custom_edit_button), "clicked",
+ G_CALLBACK (custom_edit_clicked_cb),
+ this);
+ g_signal_connect (G_OBJECT (this->priv->custom_delete_button), "clicked",
+ G_CALLBACK (custom_delete_clicked_cb),
+ this);
g_signal_connect (G_OBJECT (this->priv->notebook), "switch-page",
G_CALLBACK (page_changed_cb),
this);
}
gl_template_history_model_free_name_list (recent_list);
+ this->priv->db_notify_id = lgl_db_notify_add ((lglDbNotifyFunc)db_changed_cb, this);
+
gl_debug (DEBUG_MEDIA_SELECT, "END");
}
/* PRIVATE. modify widget due to change in selection */
/*--------------------------------------------------------------------------*/
static void
-filter_changed_cb (GtkComboBox *combo,
- gpointer user_data)
+filter_changed_cb (glMediaSelect *this)
{
- glMediaSelect *this = GL_MEDIA_SELECT (user_data);
gchar *brand;
gchar *page_size_name, *page_size_id;
gchar *category_name, *category_id;
g_free (category_id);
/* Emit our "changed" signal */
- g_signal_emit (G_OBJECT (user_data),
- media_select_signals[CHANGED], 0);
+ g_signal_emit (G_OBJECT (this), signals[CHANGED], 0);
}
g_free (brand);
g_free (page_size_name);
selection_changed_cb (GtkTreeSelection *selection,
gpointer user_data)
{
- glMediaSelect *this = GL_MEDIA_SELECT (user_data);
+ glMediaSelect *this = GL_MEDIA_SELECT (user_data);
+ GtkTreeSelection *custom_selection;
if (this->priv->stop_signals) return;
gl_debug (DEBUG_MEDIA_SELECT, "START");
+ custom_selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (this->priv->custom_treeview));
+ gtk_widget_set_sensitive (GTK_WIDGET (this->priv->custom_edit_button),
+ gtk_tree_selection_get_mode (custom_selection) != GTK_SELECTION_NONE );
+ gtk_widget_set_sensitive (GTK_WIDGET (this->priv->custom_delete_button),
+ gtk_tree_selection_get_mode (custom_selection) != GTK_SELECTION_NONE );
+
+ if (gtk_tree_selection_get_mode (selection) == GTK_SELECTION_NONE)
+
/* Emit our "changed" signal */
- g_signal_emit (G_OBJECT (user_data),
- media_select_signals[CHANGED], 0);
+ g_signal_emit (G_OBJECT (user_data), signals[CHANGED], 0);
gl_debug (DEBUG_MEDIA_SELECT, "END");
}
+/*--------------------------------------------------------------------------*/
+/* PRIVATE. Custom add button clicked callback. */
+/*--------------------------------------------------------------------------*/
+static void
+custom_add_clicked_cb (GtkButton *button,
+ gpointer user_data)
+{
+ glMediaSelect *this = GL_MEDIA_SELECT (user_data);
+ GtkWidget *window;
+ GtkWidget *dialog;
+
+ window = gtk_widget_get_toplevel (GTK_WIDGET (this));
+
+ dialog = gl_template_designer_new (GTK_WINDOW (window));
+
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+ gtk_widget_show (dialog);
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE. Custom edit button clicked callback. */
+/*--------------------------------------------------------------------------*/
+static void
+custom_edit_clicked_cb (GtkButton *button,
+ gpointer user_data)
+{
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE. Custom delete button clicked callback. */
+/*--------------------------------------------------------------------------*/
+static void
+custom_delete_clicked_cb (GtkButton *button,
+ gpointer user_data)
+{
+ glMediaSelect *this = GL_MEDIA_SELECT (user_data);
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ gchar *name;
+
+ this->priv->stop_signals = TRUE;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (this->priv->custom_treeview));
+
+ if (!gtk_tree_selection_get_mode (selection) == GTK_SELECTION_NONE)
+ {
+ gtk_tree_selection_get_selected (selection, &model, &iter);
+ gtk_tree_model_get (model, &iter, NAME_COLUMN, &name, -1);
+
+ lgl_db_delete_template_by_name (name);
+
+ g_free (name);
+ }
+
+ this->priv->stop_signals = FALSE;
+}
+
+
/*--------------------------------------------------------------------------*/
/* PRIVATE. modify widget due to change in selection */
/*--------------------------------------------------------------------------*/
this->priv->current_page_num = page_num;
/* Emit our "changed" signal */
- g_signal_emit (G_OBJECT (user_data),
- media_select_signals[CHANGED], 0);
+ g_signal_emit (G_OBJECT (user_data), signals[CHANGED], 0);
gl_debug (DEBUG_MEDIA_SELECT, "END");
}
+/*--------------------------------------------------------------------------*/
+/* PRIVATE. DB changed notification callback. */
+/*--------------------------------------------------------------------------*/
+static void
+db_changed_cb (glMediaSelect *this)
+{
+ gchar *brand;
+ gchar *page_size_name, *page_size_id;
+ gchar *category_name, *category_id;
+ GtkTreeSelection *selection;
+ GList *list;
+
+ this->priv->stop_signals = TRUE;
+
+ /* Update search all page. */
+ brand = gtk_combo_box_get_active_text (GTK_COMBO_BOX (this->priv->brand_combo));
+ page_size_name = gtk_combo_box_get_active_text (GTK_COMBO_BOX (this->priv->page_size_combo));
+ category_name = gtk_combo_box_get_active_text (GTK_COMBO_BOX (this->priv->category_combo));
+ if ( brand && strlen(brand) &&
+ page_size_name && strlen(page_size_name) &&
+ category_name && strlen(category_name) )
+ {
+ if (!g_utf8_collate (brand, _("Any")))
+ {
+ g_free (brand);
+ brand = NULL;
+ }
+ page_size_id = lgl_db_lookup_paper_id_from_name (page_size_name);
+ category_id = lgl_db_lookup_category_id_from_name (category_name);
+ list = lgl_db_get_template_name_list_all (brand, page_size_id, category_id);
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (this->priv->search_all_treeview));
+ load_search_all_list (this, this->priv->search_all_store, selection, list);
+ lgl_db_free_template_name_list (list);
+ g_free (page_size_id);
+ g_free (category_id);
+ }
+ g_free (brand);
+ g_free (page_size_name);
+ g_free (category_name);
+
+ /* Update custom page. */
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (this->priv->custom_treeview));
+ list = lgl_db_get_template_name_list_all (NULL, NULL, "user-defined");
+ load_custom_list (this, this->priv->custom_store, selection, list);
+ lgl_db_free_template_name_list (list);
+
+ this->priv->stop_signals = FALSE;
+
+ /* Emit our "changed" signal */
+ g_signal_emit (G_OBJECT (this), signals[CHANGED], 0);
+
+ filter_changed_cb (this);
+}
+
+
/****************************************************************************/
/* query selected label template name. */
/****************************************************************************/
{
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (this->priv->search_all_treeview));
}
+ else if (page_num == this->priv->custom_page_num)
+ {
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (this->priv->custom_treeview));
+ }
else
{
g_print ("notebook page = %d\n", page_num);
GTK_BUTTONS_NONE,
"%s", _("No recent templates found."));
gl_message_bar_format_secondary_text (GL_MESSAGE_BAR (this->priv->recent_info_bar),
- "%s", _("Try selecting a template from the \"Search all templates\" page."));
+ "%s", _("Try selecting a template in the \"Search all\" tab."));
gtk_box_pack_start (GTK_BOX (this->priv->recent_info_vbox),
this->priv->recent_info_bar,
}
+/*--------------------------------------------------------------------------*/
+/* PRIVATE. Load list store from template name list. */
+/*--------------------------------------------------------------------------*/
+static void
+load_custom_list (glMediaSelect *this,
+ GtkListStore *store,
+ GtkTreeSelection *selection,
+ GList *list)
+{
+ GList *p;
+ GtkTreeIter iter;
+ lglUnits units;
+ lglTemplate *template;
+ lglTemplateFrame *frame;
+ GdkPixbuf *pixbuf;
+ gchar *size;
+ gchar *layout;
+ gchar *description;
+
+ gl_debug (DEBUG_MEDIA_SELECT, "START");
+
+ gtk_list_store_clear (store);
+
+
+ if ( this->priv->custom_info_bar )
+ {
+ gtk_container_remove (GTK_CONTAINER (this->priv->custom_info_vbox),
+ this->priv->custom_info_bar);
+ this->priv->custom_info_bar = NULL;
+ }
+
+ if (list)
+ {
+
+ units = gl_prefs_model_get_units (gl_prefs);
+
+ for ( p=list; p!=NULL; p=p->next )
+ {
+
+ gl_debug (DEBUG_MEDIA_SELECT, "p->data = \"%s\"", p->data);
+
+ template = lgl_db_lookup_template_from_name (p->data);
+ frame = (lglTemplateFrame *)template->frames->data;
+ pixbuf = gl_mini_preview_pixbuf_cache_get_pixbuf (p->data);
+
+ size = lgl_template_frame_get_size_description (frame, units);
+ layout = lgl_template_frame_get_layout_description (frame);
+ description = g_strdup_printf ("<b>%s: %s</b>\n%s\n%s",
+ (gchar *)p->data,
+ template->description,
+ size,
+ layout);
+ g_free (size);
+ g_free (layout);
+
+ lgl_template_free (template);
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ NAME_COLUMN, p->data,
+ PREVIEW_COLUMN, pixbuf,
+ DESCRIPTION_COLUMN, description,
+ -1);
+
+ g_object_unref (G_OBJECT (pixbuf));
+ g_free (description);
+ }
+
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
+ gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
+ gtk_tree_selection_select_iter (selection, &iter);
+
+ gtk_widget_set_sensitive (GTK_WIDGET (this->priv->custom_edit_button), TRUE);
+ gtk_widget_set_sensitive (GTK_WIDGET (this->priv->custom_delete_button), TRUE);
+ }
+ else
+ {
+ this->priv->custom_info_bar = gl_message_bar_new (GTK_MESSAGE_INFO,
+ GTK_BUTTONS_NONE,
+ "%s", _("No custom templates found."));
+ gl_message_bar_format_secondary_text (GL_MESSAGE_BAR (this->priv->custom_info_bar),
+ "%s", _("You may create new templates or try searching for pre-defined templates in the \"Search all\" tab."));
+
+ gtk_box_pack_start (GTK_BOX (this->priv->custom_info_vbox),
+ this->priv->custom_info_bar,
+ FALSE, FALSE, 0);
+ gtk_widget_show_all (this->priv->custom_info_bar);
+
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_NONE);
+
+ gtk_widget_set_sensitive (GTK_WIDGET (this->priv->custom_edit_button), FALSE);
+ gtk_widget_set_sensitive (GTK_WIDGET (this->priv->custom_delete_button), FALSE);
+ }
+
+ gl_debug (DEBUG_MEDIA_SELECT, "END");
+}
+
+
/*
* Local Variables: -- emacs