/* * Copyright (C) 2012 - Juan Ferrer Toribio * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "vn-model.h" #include static void vn_model_buildable_init (GtkBuildableIface * iface); G_DEFINE_TYPE_WITH_CODE (VnModel, vn_model, DB_TYPE_MODEL, G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, vn_model_buildable_init) ); /* GtkBuildable custom tag implementation * * * * ... * */ typedef struct { GtkBuilder * builder; DbModel * model; GSList * fields; GSList * params; GSList * linked; } VnModelData; //+++++++++++++++++++++++++++++++++++++++++++++++++++ GtkBuildable static void vn_model_start_element (GMarkupParseContext * context, const gchar * element, const gchar ** names, const gchar ** values, gpointer data, GError ** err) { guint i; VnModelData * d = data; if (!g_strcmp0 (element, "link")) for (i = 0; names[i]; i++) if (!g_strcmp0 (names[i], "field")) d->fields = g_slist_prepend (d->fields, g_strdup (values[i])); else if (!g_strcmp0 (names[i], "param")) d->params = g_slist_prepend (d->params, g_strdup (values[i])); else if (!g_strcmp0 (names[i], "linked")) { gboolean b = values[i] && !g_strcmp0 (values[i], "True") ? TRUE : FALSE; d->linked = g_slist_prepend (d->linked, GINT_TO_POINTER (b)); } else if (!g_strcmp0 (element, "holder")) for (i = 0; names[i]; i++) if (!g_strcmp0 (names[i], "id")) d->fields = g_slist_prepend (d->fields, g_strdup (values[i])); else if (!g_strcmp0 (names[i], "param")) d->params = g_slist_prepend (d->params, g_strdup (values[i])); } static const GMarkupParser vn_model_parser = { vn_model_start_element }; static gboolean vn_model_buildable_custom_tag_start (GtkBuildable * buildable, GtkBuilder * builder, GObject * child, const gchar * tag, GMarkupParser * parser, gpointer * data) { if (child) return FALSE; if (!g_strcmp0 (tag, "links") || !g_strcmp0 (tag, "batch")) { VnModelData * data_ptr = g_slice_new (VnModelData); data_ptr->builder = builder; data_ptr->model = DB_MODEL (buildable); data_ptr->fields = NULL; data_ptr->params = NULL; data_ptr->linked = FALSE; *data = data_ptr; *parser = vn_model_parser; return TRUE; } else g_warning ("Unknown custom model tag: %s", tag); return FALSE; } static void vn_model_buildable_custom_finished (GtkBuildable * buildable, GtkBuilder * builder, GObject * child, const gchar * tagname, gpointer data) { GSList * f, * p, * l; VnModelData * d = data; g_return_if_fail (d->builder); if (!g_strcmp0 (tagname, "links")) { d->fields = g_slist_reverse (d->fields); d->params = g_slist_reverse (d->params); d->linked = g_slist_reverse (d->linked); for (f = d->fields, p = d->params, l = d->linked; f && p && l; f = f->next, p = p->next, l = l->next) { gchar * field = f->data; gboolean linked = GPOINTER_TO_INT (l->data); GvnParam * param = GVN_PARAM (gtk_builder_get_object (d->builder, p->data)); db_model_set_default_value_from_param (d->model, field, param, linked); g_free (f->data); g_free (p->data); } g_slist_free (d->fields); g_slist_free (d->params); g_slist_free (d->linked); g_slice_free (VnModelData, d); } else if (!g_strcmp0 (tagname, "batch")) { d->fields = g_slist_reverse (d->fields); d->params = g_slist_reverse (d->params); for (f = d->fields, p = d->params; f && p; f = f->next, p = p->next) { gchar * id = f->data; GvnParam * param = GVN_PARAM (gtk_builder_get_object (d->builder, p->data)); SqlBatch * batch = db_model_get_batch (d->model); if (!batch) { batch = sql_batch_new (); sql_batch_add_from_param (batch, id, param); db_model_set_batch (d->model, batch); } else sql_batch_add_from_param (batch, id, param); g_free (f->data); g_free (p->data); } g_slist_free (d->fields); g_slist_free (d->params); g_slice_free (VnModelData, d); } } static void vn_model_buildable_set_buildable_property (GtkBuildable * buildable, GtkBuilder * builder, const gchar * name, const GValue * value) { if (!g_strcmp0 (name, "sql")) { static gpointer old_object = NULL; if (old_object != buildable) g_object_set_property (G_OBJECT (buildable), name, value); old_object = buildable; } else g_object_set_property (G_OBJECT (buildable), name, value); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Class static void vn_model_class_init (VnModelClass * klass) { } static void vn_model_buildable_init (GtkBuildableIface * iface) { iface->custom_tag_start = vn_model_buildable_custom_tag_start; iface->set_buildable_property = vn_model_buildable_set_buildable_property; iface->custom_finished = vn_model_buildable_custom_finished; } static void vn_model_init (VnModel * obj) {}