[goffice] Serialize custom graph themes.
- From: Jean BrÃfort <jbrefort src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [goffice] Serialize custom graph themes.
- Date: Tue, 6 Nov 2012 20:41:49 +0000 (UTC)
commit e1feef5dcc21b9b0a03e788504bf2579db3b2a13
Author: Jean Brefort <jean brefort normalesup org>
Date: Tue Nov 6 21:41:04 2012 +0100
Serialize custom graph themes.
ChangeLog | 31 ++
docs/reference/goffice-0.10-sections.txt | 4 +-
goffice/app/go-doc.c | 25 +-
goffice/graph/gog-axis-color-map.c | 16 +-
goffice/graph/gog-graph.c | 46 ++-
goffice/graph/gog-theme.c | 862 ++++++++++++++++++++++--------
goffice/graph/gog-theme.h | 3 +-
goffice/utils/go-style.c | 46 ++
goffice/utils/go-style.h | 1 +
goffice/utils/goffice-utils.c | 1 +
goffice/utils/goffice-utils.h | 1 +
11 files changed, 789 insertions(+), 247 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index e98eded..27aea3f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+2012-11-06 Jean Brefort <jean brefort normalesup org>
+
+ * goffice/app/go-doc.c (go_doc_write), (load_color_map),
+ (load_theme), (go_doc_read): serialize custom themes.
+ * goffice/graph/gog-axis-color-map.c (gog_axis_color_map_write),
+ (gog_axis_color_map_save), (gog_axis_color_map_persist_init),
+ (_gog_axis_color_maps_shutdown): cosmetic changes.
+ * goffice/graph/gog-graph.c (gog_graph_get_property),
+ (gog_graph_populate_editor), (gog_graph_sax_save),
+ (gog_graph_prep_sax), (gog_graph_persist_init), (theme_loaded_cb),
+ (gog_graph_set_theme): serialize custom themes.
+ * goffice/graph/gog-theme.c (gog_theme_set_property),
+ (gog_theme_get_property), (gog_theme_element_free),
+ (gog_theme_finalize), (gog_theme_class_init), (gog_theme_init),
+ (save_name_cb), (save_desc_cb), (save_elem_cb),
+ (save_series_style_cb), (gog_theme_build_uri),
+ (gog_theme_sax_save), (gog_theme_save), (theme_start),
+ (name_start), (name_end), (desc_end), (gog_theme_add_element),
+ (elem_start), (color_map_start), (theme_loaded), (parse_done_cb),
+ (gog_theme_prep_sax), (gog_theme_persist_init),
+ (gog_theme_find_element), (gog_theme_new), (gog_theme_get_id),
+ (gog_theme_get_description), (gog_theme_get_resource_type),
+ (gog_theme_registry_lookup), (build_predefined_themes),
+ (theme_load_from_uri), (_gog_themes_shutdown):
+ * goffice/graph/gog-theme.h: ditto.
+ * goffice/utils/go-style.c (go_style_force_auto),
+ (go_style_clear_auto): ditto.
+ * goffice/utils/go-style.h: ditto.
+ * goffice/utils/goffice-utils.c: ditto.
+ * goffice/utils/goffice-utils.h: ditto.
+
2012-11-05 Jean Brefort <jean brefort normalesup org>
* goffice/app/go-doc.c (go_doc_write), (load_color_map),
diff --git a/docs/reference/goffice-0.10-sections.txt b/docs/reference/goffice-0.10-sections.txt
index 062d7a9..8f49ddb 100644
--- a/docs/reference/goffice-0.10-sections.txt
+++ b/docs/reference/goffice-0.10-sections.txt
@@ -2073,6 +2073,7 @@ go_style_assign
go_style_dup
go_style_fill
go_style_force_auto
+go_style_clear_auto
go_style_get_editor
go_style_get_marker
go_style_is_auto
@@ -3407,8 +3408,9 @@ GogTheme
gog_theme_fillin_style
gog_theme_get_color_map
gog_theme_get_description
-gog_theme_get_local_name
+gog_theme_get_id
gog_theme_get_name
+gog_theme_get_resource_type
gog_theme_registry_get_theme_names
gog_theme_registry_lookup
<SUBSECTION Standard>
diff --git a/goffice/app/go-doc.c b/goffice/app/go-doc.c
index a8f30ab..6ff1d93 100644
--- a/goffice/app/go-doc.c
+++ b/goffice/app/go-doc.c
@@ -509,8 +509,11 @@ go_doc_write (GODoc *doc, GsfXMLOut *output)
doc->priv->resourcesbuf != NULL) {
gsf_xml_out_start_element (output, "GODoc");
g_hash_table_foreach (doc->priv->imagebuf, save_image_cb, output);
- for (ptr = doc->priv->resourcesbuf; ptr; ptr = ptr->next)
+ for (ptr = doc->priv->resourcesbuf; ptr; ptr = ptr->next) {
+ gsf_xml_out_start_element (output, G_OBJECT_TYPE_NAME (ptr->data));
go_persist_sax_save (GO_PERSIST (ptr->data), output);
+ gsf_xml_out_end_element (output);
+ }
g_slist_free (doc->priv->resourcesbuf);
doc->priv->resourcesbuf = NULL;
gsf_xml_out_end_element (output);
@@ -599,7 +602,21 @@ load_color_map (GsfXMLIn *xin, xmlChar const **attrs)
map = GOG_AXIS_COLOR_MAP (gog_axis_color_map_get_from_id ((char const *) attrs[1]));
break;
}
- go_persist_prep_sax (GO_PERSIST (map), xin, attrs);
+ if (map)
+ go_persist_prep_sax (GO_PERSIST (map), xin, attrs);
+}
+
+static void
+load_theme (GsfXMLIn *xin, xmlChar const **attrs)
+{
+ GogTheme *theme = NULL;
+ for (; attrs && *attrs; attrs +=2)
+ if (!strcmp ((char const *) *attrs, "id")) {
+ theme = GOG_THEME (gog_theme_registry_lookup ((char const *) attrs[1]));
+ break;
+ }
+ if (theme)
+ go_persist_prep_sax (GO_PERSIST (theme), xin, attrs);
}
void
@@ -617,6 +634,10 @@ go_doc_read (GODoc *doc, GsfXMLIn *xin, xmlChar const **attrs)
-1, "GogAxisColorMap",
GSF_XML_NO_CONTENT,
&load_color_map, NULL),
+ GSF_XML_IN_NODE (DOC, THEME,
+ -1, "GogTheme",
+ GSF_XML_NO_CONTENT,
+ &load_theme, NULL),
GSF_XML_IN_NODE_END
};
static GsfXMLInDoc *xmldoc = NULL;
diff --git a/goffice/graph/gog-axis-color-map.c b/goffice/graph/gog-axis-color-map.c
index b732c0c..6d15e0a 100644
--- a/goffice/graph/gog-axis-color-map.c
+++ b/goffice/graph/gog-axis-color-map.c
@@ -67,7 +67,7 @@ enum {
static void
gog_axis_color_map_set_property (GObject *gobject, guint param_id,
- GValue const *value, GParamSpec *pspec)
+ GValue const *value, GParamSpec *pspec)
{
GogAxisColorMap *map = GOG_AXIS_COLOR_MAP (gobject);
@@ -84,7 +84,7 @@ gog_axis_color_map_set_property (GObject *gobject, guint param_id,
static void
gog_axis_color_map_get_property (GObject *gobject, guint param_id,
- GValue *value, GParamSpec *pspec)
+ GValue *value, GParamSpec *pspec)
{
GogAxisColorMap *map = GOG_AXIS_COLOR_MAP (gobject);
@@ -98,6 +98,7 @@ gog_axis_color_map_get_property (GObject *gobject, guint param_id,
return; /* NOTE : RETURN */
}
}
+
static void
gog_axis_color_map_finalize (GObject *obj)
{
@@ -178,7 +179,6 @@ gog_axis_color_map_write (GOPersist const *gp, GsfXMLOut *output)
gog_axis_color_map_save (map);
return;
}
- gsf_xml_out_start_element (output, "GogAxisColorMap");
gsf_xml_out_add_cstr_unchecked (output, "id", map->id);
g_hash_table_foreach (map->names, (GHFunc) save_name_cb, output);
for (i = 0; i < map->size; i++) {
@@ -189,7 +189,6 @@ gog_axis_color_map_write (GOPersist const *gp, GsfXMLOut *output)
g_free (buf);
gsf_xml_out_end_element (output);
}
- gsf_xml_out_end_element (output);
}
struct _color_stop {
@@ -305,7 +304,9 @@ gog_axis_color_map_save (GogAxisColorMap const *map)
{
GsfOutput *output = gsf_output_gio_new_for_uri (map->uri, NULL);
GsfXMLOut *xml = gsf_xml_out_new (output);
+ gsf_xml_out_start_element (xml, "GogAxisColorMap");
gog_axis_color_map_write (GO_PERSIST (map), xml);
+ gsf_xml_out_end_element (xml);
g_object_unref (xml);
g_object_unref (output);
}
@@ -382,7 +383,7 @@ gog_axis_color_map_prep_sax (GOPersist *gp, GsfXMLIn *xin, xmlChar const **attrs
}
static void
-gog_axis_map_persist_init (GOPersistClass *iface)
+gog_axis_color_map_persist_init (GOPersistClass *iface)
{
iface->prep_sax = gog_axis_color_map_prep_sax;
iface->sax_save = gog_axis_color_map_write;
@@ -391,7 +392,7 @@ gog_axis_map_persist_init (GOPersistClass *iface)
GSF_CLASS_FULL (GogAxisColorMap, gog_axis_color_map,
NULL, NULL, gog_axis_color_map_class_init, NULL,
gog_axis_color_map_init, G_TYPE_OBJECT, 0,
- GSF_INTERFACE (gog_axis_map_persist_init, GO_TYPE_PERSIST))
+ GSF_INTERFACE (gog_axis_color_map_persist_init, GO_TYPE_PERSIST))
/**
* gog_axis_color_map_get_color:
@@ -995,5 +996,6 @@ _gog_axis_color_maps_shutdown (void)
{
g_object_unref (color_map);
g_slist_free_full (color_maps, g_object_unref);
- g_free (xml);
+ if (xml)
+ gsf_xml_in_doc_free (xml);
}
diff --git a/goffice/graph/gog-graph.c b/goffice/graph/gog-graph.c
index c723e67..97a2fe6 100644
--- a/goffice/graph/gog-graph.c
+++ b/goffice/graph/gog-graph.c
@@ -206,7 +206,7 @@ gog_graph_get_property (GObject *obj, guint param_id,
g_value_set_object (value, graph->theme);
break;
case GRAPH_PROP_THEME_NAME :
- g_value_set_string (value, gog_theme_get_name (graph->theme));
+ g_value_set_string (value, gog_theme_get_id (graph->theme));
break;
case GRAPH_PROP_WIDTH:
g_value_set_double (value, graph->width);
@@ -330,7 +330,7 @@ gog_graph_populate_editor (GogObject *gobj,
theme = gog_theme_registry_lookup (ptr->data);
gtk_list_store_append (model, &iter);
gtk_list_store_set (model, &iter,
- 0, gog_theme_get_local_name (theme),
+ 0, gog_theme_get_name (theme),
1, theme,
-1);
if (strcmp (ptr->data, graph_theme_name) == 0)
@@ -517,9 +517,31 @@ gog_graph_init (GogGraph *graph)
graph->data_refs = g_hash_table_new (g_direct_hash, g_direct_equal);
}
-GSF_CLASS (GogGraph, gog_graph,
- gog_graph_class_init, gog_graph_init,
- GOG_TYPE_OUTLINED_OBJECT)
+static void
+gog_graph_sax_save (GOPersist const *gp, GsfXMLOut *output)
+{
+ GogGraph *graph = GOG_GRAPH (gp);
+ if (gog_theme_get_resource_type (graph->theme) != GO_RESOURCE_NATIVE)
+ go_doc_save_resource (graph->doc, GO_PERSIST (graph->theme));
+}
+
+static void
+gog_graph_prep_sax (GOPersist *gp, GsfXMLIn *xin, xmlChar const **attrs)
+{
+ /* nothing to do */
+}
+
+static void
+gog_graph_persist_init (GOPersistClass *iface)
+{
+ iface->prep_sax = gog_graph_prep_sax;
+ iface->sax_save = gog_graph_sax_save;
+}
+
+GSF_CLASS_FULL (GogGraph, gog_graph,
+ NULL, NULL, gog_graph_class_init, NULL,
+ gog_graph_init, GOG_TYPE_OUTLINED_OBJECT, 0,
+ GSF_INTERFACE (gog_graph_persist_init, GO_TYPE_PERSIST))
/**
* gog_graph_validate_chart_layout:
@@ -669,6 +691,15 @@ apply_theme (GogObject *object, GogTheme const *theme, gboolean force_auto)
}
}
+static gboolean
+theme_loaded_cb (GogGraph *graph)
+{
+ if (gog_theme_get_name (graph->theme) == NULL)
+ return TRUE;
+ apply_theme (GOG_OBJECT (graph), graph->theme, FALSE);
+ return FALSE;
+}
+
void
gog_graph_set_theme (GogGraph *graph, GogTheme *theme)
{
@@ -677,7 +708,10 @@ gog_graph_set_theme (GogGraph *graph, GogTheme *theme)
graph->theme = theme;
- apply_theme (GOG_OBJECT (graph), graph->theme, FALSE);
+ if (gog_theme_get_name (theme) == NULL) /* the theme is not loaded yet */
+ g_timeout_add (10, (GSourceFunc) theme_loaded_cb, graph);
+ else
+ apply_theme (GOG_OBJECT (graph), graph->theme, FALSE);
}
/**
diff --git a/goffice/graph/gog-theme.c b/goffice/graph/gog-theme.c
index 72f7f0d..a26e6b5 100644
--- a/goffice/graph/gog-theme.c
+++ b/goffice/graph/gog-theme.c
@@ -24,6 +24,7 @@
#include <goffice/goffice-priv.h>
#include <goffice/graph/gog-theme.h>
#include <gsf/gsf-input-gio.h>
+#include <gsf/gsf-output-gio.h>
#include <gsf/gsf-impl-utils.h>
#include <glib/gi18n-lib.h>
@@ -36,8 +37,11 @@
* The library provides two hard coded themes, "Default", and "Guppi". Other themes
* are described in files, some of which might be distributed with the library.
*
- * A file defining a theme is an xml file with a <GogTheme> root node. The contents
- * must be: _name|name+, _description?|description*, GOStyle+.
+ * A file defining a theme is an xml file with a <GogTheme> root node.
+ * The root element needs to have an Id which should be unique. The uuid command
+ * provides such Ids.
+ *
+ * The contents must be: _name|name+, _description?|description*, GOStyle+.
*
* _name and name nodes:
*
@@ -79,8 +83,13 @@
* <tr><td> </td><td>MinorGrid</td><td>line, fill</td></tr>
* <tr><td>GogLabel</td><td></td><td>outline, fill, font, text_layout</td></tr>
* <tr><td>GogSeries</td><td></td><td>line, fill, marker</td><td>One is needed for each entry in the palette</td></tr>
- * <tr><td>GogTrendLine</td><td></td><td>line, fill</td></tr>
- * <tr><td>GogReqEqn</td><td></td><td>line, fill, font, text_layout</td></tr>
+ * <tr><td>GogTrendLine</td><td></td><td>line</td></tr>
+ * <tr><td>GogRegEqn</td><td></td><td>outline, fill, font, text_layout</td></tr>
+ * <tr><td>GogSeriesLabels</td><td></td><td>outline, fill, font, text_layout</td></tr>
+ * <tr><td>GogRegEqn</td><td></td><td>outline, fill, font, text_layout</td></tr>
+ * <tr><td>GogSeriesLabel</td><td></td><td>outline, fill, font, text_layout</td></tr>
+ * <tr><td>GogDataLabel</td><td></td><td>outline, fill, font, text_layout</td></tr>
+ * <tr><td>GogEquation</td><td></td><td>outline, fill, font, text_layout</td></tr>
* </table>
*
* The line and outline nodes are actually the same so using line in place of outline is
@@ -163,8 +172,8 @@ typedef void (*GogThemeStyleMap) (GOStyle *style, unsigned ind, GogTheme const *
typedef struct {
/* If role is non-null, klass_name specifies the container class,
* If role is null, klass_name specifies object type */
- char const *klass_name;
- char const *role_id;
+ char *klass_name;
+ char *role_id;
GOStyle *style;
GogThemeStyleMap map;
} GogThemeElement;
@@ -172,9 +181,13 @@ typedef struct {
struct _GogTheme {
GObject base;
+ char *id;
char *name;
- char *local_name;
char *description;
+ char *uri;
+ GoResourceType type;
+ GHashTable *names;
+ GHashTable *descs;
GHashTable *elem_hash_by_role;
GHashTable *elem_hash_by_class;
GHashTable *class_aliases;
@@ -194,10 +207,51 @@ static GSList *themes;
static GogTheme *default_theme = NULL;
static GHashTable *global_class_aliases = NULL;
+enum {
+ GOG_THEME_PROP_0,
+ GOG_THEME_PROP_TYPE
+};
+
+static void
+gog_theme_set_property (GObject *gobject, guint param_id,
+ GValue const *value, GParamSpec *pspec)
+{
+ GogTheme *theme = GOG_THEME (gobject);
+
+ switch (param_id) {
+ case GOG_THEME_PROP_TYPE:
+ theme->type = g_value_get_enum (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
+ return; /* NOTE : RETURN */
+ }
+}
+
+static void
+gog_theme_get_property (GObject *gobject, guint param_id,
+ GValue *value, GParamSpec *pspec)
+{
+ GogTheme *theme = GOG_THEME (gobject);
+
+ switch (param_id) {
+ case GOG_THEME_PROP_TYPE:
+ g_value_set_enum (value, theme->type);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec);
+ return; /* NOTE : RETURN */
+ }
+}
+
static void
gog_theme_element_free (GogThemeElement *elem)
{
g_object_unref (elem->style);
+ g_free (elem->klass_name);
+ g_free (elem->role_id);
g_free (elem);
}
@@ -226,9 +280,14 @@ gog_theme_finalize (GObject *obj)
themes = g_slist_remove (themes, theme);
+ g_free (theme->id);
g_free (theme->name);
- g_free (theme->local_name);
+ g_free (theme->uri);
g_free (theme->description);
+ if (theme->names)
+ g_hash_table_destroy (theme->names);
+ if (theme->descs)
+ g_hash_table_destroy (theme->descs);
if (theme->elem_hash_by_role)
g_hash_table_destroy (theme->elem_hash_by_role);
if (theme->elem_hash_by_class)
@@ -256,11 +315,21 @@ gog_theme_class_init (GogThemeClass *klass)
parent_klass = g_type_class_peek_parent (klass);
gobject_klass->finalize = gog_theme_finalize;
+ gobject_klass->set_property = gog_theme_set_property;
+ gobject_klass->get_property = gog_theme_get_property;
+ g_object_class_install_property (gobject_klass, GOG_THEME_PROP_TYPE,
+ g_param_spec_enum ("resource-type",
+ _("Resource type"),
+ _("The resource type for the theme"),
+ go_resource_type_get_type (), GO_RESOURCE_INVALID,
+ GSF_PARAM_STATIC | G_PARAM_READWRITE |G_PARAM_CONSTRUCT_ONLY));
}
static void
gog_theme_init (GogTheme *theme)
{
+ theme->names = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ theme->descs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
theme->elem_hash_by_role =
g_hash_table_new_full ((GHashFunc) gog_theme_element_hash,
(GCompareFunc) gog_theme_element_eq,
@@ -274,9 +343,436 @@ gog_theme_init (GogTheme *theme)
g_hash_table_new (g_str_hash, g_str_equal);
}
-GSF_CLASS (GogTheme, gog_theme,
- gog_theme_class_init, gog_theme_init,
- G_TYPE_OBJECT)
+/***************
+ * Output code *
+ ***************/
+
+static void
+save_name_cb (char const *lang, char const *name, GsfXMLOut *output)
+{
+ gsf_xml_out_start_element (output, "name");
+ if (strcmp (lang, "C"))
+ gsf_xml_out_add_cstr_unchecked (output, "xml:lang", lang);
+ gsf_xml_out_add_cstr_unchecked (output, NULL, name);
+ gsf_xml_out_end_element (output);
+}
+
+static void
+save_desc_cb (char const *lang, char const *name, GsfXMLOut *output)
+{
+ gsf_xml_out_start_element (output, "description");
+ if (strcmp (lang, "C"))
+ gsf_xml_out_add_cstr_unchecked (output, "xml:lang", lang);
+ gsf_xml_out_add_cstr_unchecked (output, NULL, name);
+ gsf_xml_out_end_element (output);
+}
+
+static void
+save_elem_cb (G_GNUC_UNUSED char const *key, GogThemeElement *elt, GsfXMLOut *output)
+{
+ if (elt->klass_name && !strcmp (elt->klass_name, "GogSeries"))
+ return;
+ gsf_xml_out_start_element (output, "GOStyle");
+ if (elt->klass_name)
+ gsf_xml_out_add_cstr_unchecked (output, "class", elt->klass_name);
+ if (elt->role_id)
+ gsf_xml_out_add_cstr_unchecked (output, "role", elt->role_id);
+ go_persist_sax_save (GO_PERSIST (elt->style), output);
+ gsf_xml_out_end_element (output);
+}
+
+static void
+save_series_style_cb (GOPersist *gp, GsfXMLOut *output)
+{
+ gsf_xml_out_start_element (output, "GOStyle");
+ gsf_xml_out_add_cstr_unchecked (output, "class", "GogSeries");
+ go_persist_sax_save (gp, output);
+ gsf_xml_out_end_element (output);
+}
+
+static void gog_theme_save (GogTheme const *theme);
+
+static void
+gog_theme_build_uri (GogTheme *theme)
+{
+ char *filename, *full_name;
+ filename = g_strconcat (theme->id, ".theme", NULL);
+ full_name = g_build_filename (g_get_home_dir (), ".goffice", "themes", filename, NULL);
+ theme->uri = go_filename_to_uri (full_name);
+ g_free (filename);
+ g_free (full_name);
+}
+
+static void
+gog_theme_sax_save (GOPersist const *gp, GsfXMLOut *output)
+{
+ GogTheme *theme;
+
+ g_return_if_fail (GOG_IS_THEME (gp));
+
+ theme = GOG_THEME (gp);
+ if (output == NULL) {
+ g_return_if_fail (theme->uri == NULL);
+ gog_theme_build_uri (theme);
+ theme->type = GO_RESOURCE_RW;
+ gog_theme_save (theme);
+ return;
+ }
+ gsf_xml_out_add_cstr_unchecked (output, "id", theme->id);
+ g_hash_table_foreach (theme->names, (GHFunc) save_name_cb, output);
+ g_hash_table_foreach (theme->descs, (GHFunc) save_desc_cb, output);
+ g_hash_table_foreach (theme->elem_hash_by_class, (GHFunc) save_elem_cb, output);
+ g_hash_table_foreach (theme->elem_hash_by_role, (GHFunc) save_elem_cb, output);
+ g_ptr_array_foreach (theme->palette, (GFunc) save_series_style_cb, output);
+ if (theme->cm && gog_axis_color_map_get_resource_type (theme->cm) == GO_RESOURCE_CHILD) {
+ gsf_xml_out_start_element (output, "GogAxisColorMap");
+ gsf_xml_out_add_cstr_unchecked (output, "type", (theme->cm == theme->dcm)? "both": "gradient");
+ go_persist_sax_save (GO_PERSIST (theme->cm), output);
+ gsf_xml_out_end_element (output);
+ }
+ if (theme->dcm && theme->dcm != theme->cm && gog_axis_color_map_get_resource_type (theme->dcm) == GO_RESOURCE_CHILD) {
+ gsf_xml_out_start_element (output, "GogAxisColorMap");
+ gsf_xml_out_add_cstr_unchecked (output, "type", "discrete");
+ go_persist_sax_save (GO_PERSIST (theme->dcm), output);
+ gsf_xml_out_end_element (output);
+ }
+}
+
+static void
+gog_theme_save (GogTheme const *theme)
+{
+ GsfOutput *output = gsf_output_gio_new_for_uri (theme->uri, NULL);
+ GsfXMLOut *xml = gsf_xml_out_new (output);
+ gsf_xml_out_start_element (xml, "GogTheme");
+ gog_theme_sax_save (GO_PERSIST (theme), xml);
+ gsf_xml_out_end_element (xml);
+ g_object_unref (xml);
+ g_object_unref (output);
+}
+
+/**************
+ * Input code *
+ **************/
+
+struct theme_load_state {
+ GogTheme *theme;
+ char *name, *desc, *lang;
+ unsigned name_lang_score;
+ unsigned desc_lang_score;
+ char const * const *langs;
+};
+
+static void
+theme_start (GsfXMLIn *xin, xmlChar const **attrs)
+{
+ struct theme_load_state *state = (struct theme_load_state *) xin->user_state;
+ if (state->theme == NULL) {
+ state->theme = g_object_new (GOG_TYPE_THEME, NULL);
+ for (; attrs && *attrs; attrs +=2)
+ if (!strcmp ((char const *) *attrs, "id")) {
+ state->theme->id = g_strdup ((char const *) attrs[1]);
+ break;
+ }
+ }
+}
+
+static void
+name_start (GsfXMLIn *xin, xmlChar const **attrs)
+{
+ struct theme_load_state *state = (struct theme_load_state *) xin->user_state;
+ unsigned i;
+ if (state->theme->name) /* the theme has already been loaded from elsewhere */
+ return;
+ for (i = 0; attrs != NULL && attrs[i] && attrs[i+1] ; i += 2)
+ if (0 == strcmp (attrs[i], "xml:lang"))
+ state->lang = g_strdup (attrs[i+1]);
+}
+
+static void
+name_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+{
+ struct theme_load_state *state = (struct theme_load_state *) xin->user_state;
+ char *name = NULL;
+ if (state->theme->name) /* the theme has already been loaded from elsewhere */
+ return;
+ if (xin->content->str == NULL)
+ return;
+ name = g_strdup (xin->content->str);
+ if (state->lang == NULL)
+ state->lang = g_strdup ("C");
+ if (state->name_lang_score > 0 && state->langs[0] != NULL) {
+ unsigned i;
+ for (i = 0; i < state->name_lang_score && state->langs[i] != NULL; i++) {
+ if (strcmp (state->langs[i], state->lang) == 0) {
+ g_free (state->name);
+ state->name = g_strdup (name);
+ state->name_lang_score = i;
+ }
+ }
+ }
+ g_hash_table_replace (state->theme->names, state->lang, name);
+ state->lang = NULL;
+}
+
+static void
+desc_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+{
+ struct theme_load_state *state = (struct theme_load_state *) xin->user_state;
+ char *desc = NULL;
+ if (state->theme->name) /* the theme has already been loaded from elsewhere */
+ return;
+ if (xin->content->str == NULL)
+ return;
+ desc = g_strdup (xin->content->str);
+ if (state->lang == NULL)
+ state->lang = g_strdup ("C");
+ if (state->desc_lang_score > 0 && state->langs[0] != NULL) {
+ unsigned i;
+ for (i = 0; i < state->desc_lang_score && state->langs[i] != NULL; i++) {
+ if (strcmp (state->langs[i], state->lang) == 0) {
+ g_free (state->desc);
+ state->desc = g_strdup (desc);
+ state->desc_lang_score = i;
+ }
+ }
+ }
+ g_hash_table_replace (state->theme->descs, state->lang, desc);
+ state->lang = NULL;
+}
+
+static void
+gog_theme_add_element (GogTheme *theme, GOStyle *style,
+ GogThemeStyleMap map,
+ char *klass_name, char *role_id)
+{
+ GogThemeElement *elem;
+ static struct {char const *klass_name; char const *role_id; unsigned fields;}
+ ifields[] = {
+ {"GogGraph", NULL, GO_STYLE_OUTLINE | GO_STYLE_FILL},
+ {"GogGraph", "Title", GO_STYLE_OUTLINE | GO_STYLE_FILL | GO_STYLE_FONT | GO_STYLE_TEXT_LAYOUT},
+ {"GogChart", NULL, GO_STYLE_OUTLINE | GO_STYLE_FILL},
+ {"GogChart", "Title", GO_STYLE_OUTLINE | GO_STYLE_FILL | GO_STYLE_FONT | GO_STYLE_TEXT_LAYOUT},
+ {"GogLegend", NULL, GO_STYLE_OUTLINE | GO_STYLE_FILL | GO_STYLE_FONT},
+ {"GogAxis", NULL, GO_STYLE_LINE | GO_STYLE_FONT | GO_STYLE_TEXT_LAYOUT},
+ {"GogAxisLine", NULL, GO_STYLE_LINE | GO_STYLE_FONT},
+ {"GogGrid", NULL, GO_STYLE_OUTLINE | GO_STYLE_FILL},
+ {NULL, "MajorGrid", GO_STYLE_LINE | GO_STYLE_FILL},
+ {NULL, "MinorGrid", GO_STYLE_LINE | GO_STYLE_FILL},
+ {"GogLabel", NULL, GO_STYLE_OUTLINE | GO_STYLE_FILL | GO_STYLE_FONT | GO_STYLE_TEXT_LAYOUT},
+ {"GogSeries", NULL, GO_STYLE_LINE | GO_STYLE_FILL | GO_STYLE_MARKER},
+ {"GogTrendLine", NULL, GO_STYLE_LINE},
+ {"GogRegEqn", NULL, GO_STYLE_OUTLINE | GO_STYLE_FILL | GO_STYLE_FONT | GO_STYLE_TEXT_LAYOUT},
+ {"GogSeriesLabels", NULL, GO_STYLE_OUTLINE | GO_STYLE_FILL | GO_STYLE_FONT | GO_STYLE_TEXT_LAYOUT},
+ {"GogDataLabel", NULL, GO_STYLE_OUTLINE | GO_STYLE_FILL | GO_STYLE_FONT | GO_STYLE_TEXT_LAYOUT},
+ {"GogEquation", NULL, GO_STYLE_OUTLINE | GO_STYLE_FILL | GO_STYLE_FONT | GO_STYLE_TEXT_LAYOUT}
+ };
+ unsigned i;
+
+ g_return_if_fail (theme != NULL);
+
+ elem = g_new0 (GogThemeElement, 1);
+ elem->klass_name = klass_name;
+ elem->role_id = role_id;
+ elem->style = style;
+ elem->map = map;
+
+ /* sets the needed insteresting_fields in style */
+ for (i = 0; i < G_N_ELEMENTS (ifields); i++) {
+ if ((klass_name && ifields[i].klass_name && strcmp (klass_name, ifields[i].klass_name))
+ || (klass_name == NULL && ifields[i].klass_name != NULL) ||
+ (klass_name != NULL && ifields[i].klass_name == NULL))
+ continue;
+ if ((role_id && ifields[i].role_id && strcmp (role_id, ifields[i].role_id))
+ || (role_id == NULL && ifields[i].role_id != NULL) ||
+ (role_id != NULL && ifields[i].role_id == NULL))
+ continue;
+ style->interesting_fields = ifields[i].fields;
+ break;
+ }
+ if (i == G_N_ELEMENTS (ifields))
+ g_warning ("[GogTheme]: unregistered style class=%s role=%s\n",klass_name, role_id);
+ /* Never put an element into both by_role_id & by_class_name */
+ if (role_id != NULL) {
+ if (g_hash_table_lookup (theme->elem_hash_by_role, (gpointer)elem) == NULL)
+ g_hash_table_insert (theme->elem_hash_by_role,
+ (gpointer)elem, elem);
+ else {
+ g_object_unref (style);
+ g_free (elem);
+ }
+ } else if (klass_name != NULL) {
+ if (g_hash_table_lookup (theme->elem_hash_by_class, (gpointer)klass_name) == NULL)
+ g_hash_table_insert (theme->elem_hash_by_class,
+ (gpointer)klass_name, elem);
+ else {
+ g_object_unref (style);
+ g_free (elem);
+ }
+
+ } else {
+ if (theme->default_style)
+ g_object_unref (theme->default_style);
+ theme->default_style = style;
+ g_free (elem);
+ }
+}
+
+static void
+elem_start (GsfXMLIn *xin, G_GNUC_UNUSED xmlChar const **attrs)
+{
+ struct theme_load_state *state = (struct theme_load_state *) xin->user_state;
+ char *role = NULL, *class_name = NULL;
+ GOStyle *style;
+ unsigned i;
+
+ if (state->theme == NULL)
+ return;
+ if (state->theme->name) /* the theme has already been loaded from elsewhere */
+ return;
+ for (i = 0; attrs != NULL && attrs[i] && attrs[i+1] ; i += 2)
+ if (0 == strcmp (attrs[i], "class"))
+ class_name = g_strdup (attrs[i+1]);
+ else if (0 == strcmp (attrs[i], "role"))
+ role = g_strdup (attrs[i+1]);
+ style = go_style_new ();
+ go_style_clear_auto (style);
+ go_persist_prep_sax (GO_PERSIST (style), xin, attrs);
+
+ if (class_name && !strcmp (class_name, "GogSeries")) {
+ if (state->theme->palette == NULL)
+ state->theme->palette = g_ptr_array_new ();
+ g_ptr_array_add (state->theme->palette, style);
+ g_free (class_name);
+ } else
+ gog_theme_add_element (state->theme, style, NULL, class_name, role);
+}
+
+static void
+color_map_start (GsfXMLIn *xin, G_GNUC_UNUSED xmlChar const **attrs)
+{
+ struct theme_load_state *state = (struct theme_load_state *) xin->user_state;
+ GogAxisColorMap *map;
+ if (state->theme == NULL)
+ return;
+ if (state->theme->name) /* the theme has already been loaded from elsewhere */
+ return;
+ map = g_object_new (GOG_TYPE_AXIS_COLOR_MAP, "resource-type", GO_RESOURCE_CHILD, NULL);
+ for (; attrs && *attrs; attrs += 2)
+ if (!strcmp ((char const *) *attrs, "type")) {
+ if (strcmp ((char const *) attrs[1], "discrete")) {
+ if (state->theme->cm != NULL) {
+ g_warning ("[GogTheme]: extra GogAxisColorMap found.");
+ g_object_unref (map);
+ return;
+ }
+ state->theme->cm = map;
+ if (strcmp ((char const *) attrs[1], "both"))
+ return;
+ g_object_ref (map);
+ }
+ if (state->theme->dcm != NULL) {
+ g_warning ("[GogTheme]: extra GogAxisColorMap found.");
+ g_object_unref (map);
+ return;
+ }
+ state->theme->dcm = map;
+ }
+}
+
+static GsfXMLInNode const theme_dtd[] = {
+ GSF_XML_IN_NODE (THEME, THEME, -1, "GogTheme", GSF_XML_NO_CONTENT, theme_start, NULL),
+ GSF_XML_IN_NODE (THEME, NAME, -1, "name", GSF_XML_CONTENT, name_start, name_end),
+ GSF_XML_IN_NODE (THEME, UNAME, -1, "_name", GSF_XML_CONTENT, name_start, name_end),
+ GSF_XML_IN_NODE (THEME, DESCRIPTION, -1, "description", GSF_XML_CONTENT, name_start, desc_end),
+ GSF_XML_IN_NODE (THEME, UDESCRIPTION, -1, "_description", GSF_XML_CONTENT, name_start, desc_end),
+ GSF_XML_IN_NODE (THEME, STYLE, -1, "GOStyle", GSF_XML_NO_CONTENT, elem_start, NULL),
+ GSF_XML_IN_NODE (THEME, COLORMAP, -1, "GogAxisColormap", GSF_XML_NO_CONTENT, color_map_start, NULL),
+ GSF_XML_IN_NODE_END
+};
+static GsfXMLInDoc *xml = NULL;
+
+static void map_area_series_solid_palette (GOStyle *, unsigned , GogTheme const *);
+static void map_area_series_solid_default (GOStyle *, unsigned , GogTheme const *);
+static void
+theme_loaded (struct theme_load_state *state)
+{
+ /* initialize a dummy GogSeries style */
+ GOStyle *style = go_style_new ();
+ go_style_clear_auto (style);
+ style->line.dash_type = GO_LINE_SOLID;
+ style->line.width = 0; /* hairline */
+ style->line.color = GO_COLOR_BLACK;
+ style->fill.type = GO_STYLE_FILL_NONE;
+ if (state->theme->palette && state->theme->palette->len > 0)
+ gog_theme_add_element (state->theme, style,
+ map_area_series_solid_palette, g_strdup ("GogSeries"), NULL);
+ else
+ gog_theme_add_element (state->theme, style,
+ map_area_series_solid_default, g_strdup ("GogSeries"), NULL);
+ if (state->theme->dcm == NULL) {
+ if (state->theme->palette) {
+ GOColor *colors = g_new (GOColor, state->theme->palette->len);
+ unsigned i;
+ for (i = 0; i < state->theme->palette->len; i++)
+ colors[i] = GO_STYLE (g_ptr_array_index (state->theme->palette, i))->fill.pattern.back;
+ state->theme->dcm = gog_axis_color_map_from_colors ("Default",
+ state->theme->palette->len,
+ colors,
+ GO_RESOURCE_GENERATED);
+ g_free (colors);
+ } else {
+ GogTheme *theme = gog_theme_registry_lookup ("Default");
+ state->theme->dcm = g_object_ref (theme->dcm);
+ }
+ }
+ state->theme->name = state->name;
+ state->theme->description = state->desc;
+}
+
+static void
+parse_done_cb (GsfXMLIn *xin, struct theme_load_state *state)
+{
+ if (state->theme->name == NULL)
+ theme_loaded (state);
+ else {
+ g_free (state->name);
+ g_free (state->desc);
+ }
+ g_free (state->lang);
+ g_free (state);
+}
+
+static void
+gog_theme_prep_sax (GOPersist *gp, GsfXMLIn *xin, xmlChar const **attrs)
+{
+ struct theme_load_state *state;
+
+ g_return_if_fail (GOG_IS_THEME (gp));
+
+ state = g_new (struct theme_load_state, 1);
+ state->theme = GOG_THEME (gp);
+ state->name = NULL;
+ state->desc = NULL;
+ state->lang = NULL;
+ state->langs = g_get_language_names ();
+ state->name_lang_score = G_MAXINT;
+ state->desc_lang_score = G_MAXINT;
+ if (!xml)
+ xml = gsf_xml_in_doc_new (theme_dtd, NULL);
+ gsf_xml_in_push_state (xin, xml, state, (GsfXMLInExtDtor) parse_done_cb, attrs);
+}
+
+static void
+gog_theme_persist_init (GOPersistClass *iface)
+{
+ iface->prep_sax = gog_theme_prep_sax;
+ iface->sax_save = gog_theme_sax_save;
+}
+
+GSF_CLASS_FULL (GogTheme, gog_theme,
+ NULL, NULL, gog_theme_class_init, NULL,
+ gog_theme_init, G_TYPE_OBJECT, 0,
+ GSF_INTERFACE (gog_theme_persist_init, GO_TYPE_PERSIST))
static GogThemeElement *
@@ -297,8 +793,8 @@ gog_theme_find_element (GogTheme const *theme, GogObject const *obj)
GogThemeElement key;
/* Search by specific role */
- key.role_id = obj->role->id;
- key.klass_name = G_OBJECT_TYPE_NAME (obj->parent);
+ key.role_id = (char *) obj->role->id;
+ key.klass_name = (char *) G_OBJECT_TYPE_NAME (obj->parent);
elem = g_hash_table_lookup (theme->elem_hash_by_role, &key);
}
@@ -306,7 +802,7 @@ gog_theme_find_element (GogTheme const *theme, GogObject const *obj)
GogThemeElement key;
/* Search by generic role */
- key.role_id = obj->role->id;
+ key.role_id = (char *) obj->role->id;
key.klass_name = NULL;
elem = g_hash_table_lookup (theme->elem_hash_by_role, &key);
}
@@ -385,10 +881,13 @@ gog_theme_fillin_style (GogTheme const *theme,
}
static GogTheme *
-gog_theme_new (char const *name)
+gog_theme_new (char const *name, GoResourceType type)
{
GogTheme *theme = g_object_new (GOG_TYPE_THEME, NULL);
- theme->name = g_strdup (name);
+ theme->name = g_strdup (_(name));
+ if (type == GO_RESOURCE_NATIVE)
+ theme->id = g_strdup (name);
+ theme->type = type;
return theme;
}
@@ -407,45 +906,18 @@ gog_theme_add_alias (GogTheme *theme, char const *from, char const *to)
}
#endif
-static void
-gog_theme_add_element (GogTheme *theme, GOStyle *style,
- GogThemeStyleMap map,
- char const *klass_name, char const *role_id)
+/**
+ * gog_theme_get_id:
+ * @theme: a #GogTheme
+ *
+ * Retrieves the theme Id.
+ * Returns: the GogTheme Id.
+ **/
+char const *
+gog_theme_get_id (GogTheme const *theme)
{
- GogThemeElement *elem;
-
- g_return_if_fail (theme != NULL);
-
- elem = g_new0 (GogThemeElement, 1);
- elem->klass_name = klass_name;
- elem->role_id = role_id;
- elem->style = style;
- elem->map = map;
-
- /* Never put an element into both by_role_id & by_class_name */
- if (role_id != NULL) {
- if (g_hash_table_lookup (theme->elem_hash_by_role, (gpointer)elem) == NULL)
- g_hash_table_insert (theme->elem_hash_by_role,
- (gpointer)elem, elem);
- else {
- g_object_unref (style);
- g_free (elem);
- }
- } else if (klass_name != NULL) {
- if (g_hash_table_lookup (theme->elem_hash_by_class, (gpointer)klass_name) == NULL)
- g_hash_table_insert (theme->elem_hash_by_class,
- (gpointer)klass_name, elem);
- else {
- g_object_unref (style);
- g_free (elem);
- }
-
- } else {
- if (theme->default_style)
- g_object_unref (theme->default_style);
- theme->default_style = style;
- g_free (elem);
- }
+ g_return_val_if_fail (GOG_IS_THEME (theme), "");
+ return theme->id;
}
/**
@@ -463,31 +935,31 @@ gog_theme_get_name (GogTheme const *theme)
}
/**
- * gog_theme_get_local_name:
+ * gog_theme_get_descrition:
* @theme: a #GogTheme
*
- * Returns: the localized GogTheme name.
+ * Returns: the localized GogTheme decription.
**/
char const *
-gog_theme_get_local_name (GogTheme const *theme)
+gog_theme_get_description (GogTheme const *theme)
{
g_return_val_if_fail (GOG_IS_THEME (theme), "");
- return (theme->local_name)? theme->local_name: _(theme->name);
+ return theme->description;
}
/**
- * gog_theme_get_descrition:
+ * gog_themep_get_resource_type:
* @theme: a #GogTheme
*
- * Returns: the localized GogTheme decription.
+ * Retrieves the resource type for @theme.
+ * Returns: the resource type.
**/
-
-char const *
-gog_theme_get_description (GogTheme const *theme)
+GoResourceType
+gog_theme_get_resource_type (GogTheme const *theme)
{
- g_return_val_if_fail (GOG_IS_THEME (theme), "");
- return theme->description;
+ g_return_val_if_fail (GOG_IS_THEME (theme), GO_RESOURCE_INVALID);
+ return theme->type;
}
/**************************************************************************/
@@ -647,17 +1119,30 @@ GogTheme *
gog_theme_registry_lookup (char const *name)
{
GSList *ptr;
- GogTheme *theme;
+ GogTheme *theme = default_theme;
if (name != NULL) {
for (ptr = themes ; ptr != NULL ; ptr = ptr->next) {
theme = ptr->data;
- if (!strcmp (theme->name, name))
+ if (!strcmp (theme->id, name))
return theme;
}
- g_warning ("No theme named '%s' found, using default", name);
+ if (strlen (name) != 36 || name[8] != '-' || name[13] != '-' || name[18] !='-' || name[23] != '-') {
+ /* name does not seem to be an uuid, migth be the theme name (needed for compatibility) */
+ char const *found_name;
+ for (ptr = themes ; ptr != NULL ; ptr = ptr->next) {
+ theme = ptr->data;
+ found_name = g_hash_table_lookup (theme->names, "C");
+ if (found_name && !strcmp (found_name, name))
+ return theme;
+ }
+ }
+ /* create an empty theme */
+ theme = g_object_new (GOG_TYPE_THEME, "resource-type", GO_RESOURCE_RW, NULL);
+ theme->id = g_strdup (name);
+ gog_theme_registry_add (theme, FALSE);
}
- return default_theme;
+ return theme;
}
/**
@@ -698,132 +1183,146 @@ build_predefined_themes (void)
}
/* An MS Excel-ish theme */
- theme = gog_theme_new (N_("Default"));
+ theme = gog_theme_new (N_("Default"), GO_RESOURCE_NATIVE);
gog_theme_registry_add (theme, TRUE);
/* graph */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_NONE;
style->line.width = 0;
style->line.color = GO_COLOR_BLACK;
style->fill.type = GO_STYLE_FILL_NONE;
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_WHITE);
- gog_theme_add_element (theme, style, NULL, "GogGraph", NULL);
+ gog_theme_add_element (theme, style, NULL, g_strdup ("GogGraph"), NULL);
/* chart */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_SOLID;
style->line.width = 0; /* hairline */
style->line.color = GO_COLOR_BLACK;
style->fill.type = GO_STYLE_FILL_PATTERN;
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_WHITE);
- gog_theme_add_element (theme, style, NULL, "GogChart", NULL);
+ gog_theme_add_element (theme, style, NULL, g_strdup ("GogChart"), NULL);
/* Legend */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_SOLID;
style->line.width = 0; /* hairline */
style->line.color = GO_COLOR_BLACK;
style->fill.type = GO_STYLE_FILL_PATTERN;
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_WHITE);
- gog_theme_add_element (theme, style, NULL, "GogLegend", NULL);
+ gog_theme_add_element (theme, style, NULL, g_strdup ("GogLegend"), NULL);
/* Axis */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.width = 0; /* hairline */
style->line.color = GO_COLOR_BLACK;
- gog_theme_add_element (theme, style, NULL, "GogAxis", NULL);
+ gog_theme_add_element (theme, style, NULL, g_strdup ("GogAxis"), NULL);
/* AxisLine */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.width = 0; /* hairline */
style->line.color = GO_COLOR_BLACK;
- gog_theme_add_element (theme, style, NULL, "GogAxisLine", NULL);
+ gog_theme_add_element (theme, style, NULL, g_strdup ("GogAxisLine"), NULL);
/* Grid */
style = go_style_new ();
+ go_style_clear_auto (style);
style->fill.type = GO_STYLE_FILL_PATTERN;
style->line.dash_type = GO_LINE_SOLID;
style->line.width = 1.;
style->line.color = 0X848284ff;
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_GREY (0xd0));
- gog_theme_add_element (theme, style, NULL, "GogGrid", NULL);
+ gog_theme_add_element (theme, style, NULL, g_strdup ("GogGrid"), NULL);
/* GridLine */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_SOLID;
style->line.width = 0.4;
style->line.color = GO_COLOR_BLACK;
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_FROM_RGBA (0xE0, 0xE0, 0xE0, 0xE0));
style->fill.type = GO_STYLE_FILL_NONE;
- gog_theme_add_element (theme, style, NULL, NULL, "MajorGrid");
+ gog_theme_add_element (theme, style, NULL, NULL, g_strdup ("MajorGrid"));
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_SOLID;
style->line.width = 0.2;
style->line.color = GO_COLOR_BLACK;
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_FROM_RGBA (0xE0, 0xE0, 0xE0, 0xE0));
style->fill.type = GO_STYLE_FILL_NONE;
- gog_theme_add_element (theme, style, NULL, NULL, "MinorGrid");
+ gog_theme_add_element (theme, style, NULL, NULL, g_strdup ("MinorGrid"));
/* Series */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_SOLID;
style->line.width = 0; /* hairline */
style->line.color = GO_COLOR_BLACK;
style->fill.type = GO_STYLE_FILL_PATTERN;
/* FIXME : not really true, will want to split area from line */
gog_theme_add_element (theme, style,
- map_area_series_solid_default, "GogSeries", NULL);
+ map_area_series_solid_default, g_strdup ("GogSeries"), NULL);
/* Chart titles */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_NONE;
style->line.width = 0.;
style->line.color = GO_COLOR_BLACK;
style->fill.type = GO_STYLE_FILL_NONE;
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_WHITE);
go_style_set_font_desc (style, pango_font_description_from_string ("Sans Bold 12"));
- gog_theme_add_element (theme, style, NULL, "GogChart", "Title");
+ gog_theme_add_element (theme, style, NULL, g_strdup ("GogChart"), g_strdup ("Title"));
/* labels */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_NONE;
style->line.width = 0.;
style->line.color = GO_COLOR_BLACK;
style->fill.type = GO_STYLE_FILL_NONE;
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_WHITE);
go_style_set_font_desc (style, pango_font_description_from_string ("Sans 10"));
- gog_theme_add_element (theme, style, NULL, "GogLabel", NULL);
+ gog_theme_add_element (theme, style, NULL, g_strdup ("GogLabel"), NULL);
/* regression curves */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_SOLID;
style->line.width = 1;
style->line.color = GO_COLOR_BLACK;
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_FROM_RGBA (0x00, 0x00, 0x00, 0x20));
style->fill.type = GO_STYLE_FILL_NONE;
gog_theme_add_element (theme, style,
- NULL, "GogTrendLine", NULL);
+ NULL, g_strdup ("GogTrendLine"), NULL);
/* regression equations */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_SOLID;
style->line.width = 0; /* hairline */
style->line.color = GO_COLOR_BLACK;
style->fill.type = GO_STYLE_FILL_PATTERN;
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_WHITE);
gog_theme_add_element (theme, style,
- NULL, "GogRegEqn", NULL);
+ NULL, g_strdup ("GogRegEqn"), NULL);
/* series labels */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_NONE;
style->line.width = 0; /* none */
style->line.color = GO_COLOR_BLACK;
style->fill.type = GO_STYLE_FILL_NONE;
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_WHITE);
go_style_set_font_desc (style, pango_font_description_from_string ("Sans 6"));
- gog_theme_add_element (theme, style, NULL, "GogSeriesLabels", NULL);
+ gog_theme_add_element (theme, style, NULL, g_strdup ("GogSeriesLabels"), NULL);
/* data label */
style = go_style_new ();
@@ -833,11 +1332,12 @@ build_predefined_themes (void)
style->fill.type = GO_STYLE_FILL_NONE;
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_WHITE);
go_style_set_font_desc (style, pango_font_description_from_string ("Sans 6"));
- gog_theme_add_element (theme, style, NULL, "GogDataLabel", NULL);
+ gog_theme_add_element (theme, style, NULL, g_strdup ("GogDataLabel"), NULL);
#ifdef GOFFICE_WITH_LASEM
/* Equations */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_NONE;
style->line.width = 0; /* hairline */
style->line.color = GO_COLOR_BLACK;
@@ -845,19 +1345,20 @@ build_predefined_themes (void)
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_WHITE);
go_style_set_font_desc (style, pango_font_description_from_string ("Sans 10"));
gog_theme_add_element (theme, style,
- NULL, "GogEquation", NULL);
+ NULL, g_strdup ("GogEquation"), NULL);
#endif
/* builds the default discrete color map */
theme->dcm = gog_axis_color_map_from_colors (N_("Theme"),
G_N_ELEMENTS (default_palette),
- default_palette, GO_RESOURCE_CHILD);
+ default_palette, GO_RESOURCE_GENERATED);
/* Guppi */
- theme = gog_theme_new (N_("Guppi"));
+ theme = gog_theme_new (N_("Guppi"), GO_RESOURCE_NATIVE);
gog_theme_registry_add (theme, FALSE);
/* graph */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_NONE;
style->line.width = 0;
style->line.color = GO_COLOR_BLACK;
@@ -865,67 +1366,75 @@ build_predefined_themes (void)
style->fill.gradient.dir = GO_GRADIENT_N_TO_S;
style->fill.pattern.fore = GO_COLOR_BLUE;
style->fill.pattern.back = GO_COLOR_BLACK;
- gog_theme_add_element (theme, style, NULL, "GogGraph", NULL);
+ gog_theme_add_element (theme, style, NULL, g_strdup ("GogGraph"), NULL);
/* chart */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_SOLID;
style->line.width = 0; /* hairline */
style->line.color = GO_COLOR_BLACK;
style->fill.type = GO_STYLE_FILL_PATTERN;
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_WHITE);
- gog_theme_add_element (theme, style, NULL, "GogChart", NULL);
+ gog_theme_add_element (theme, style, NULL, g_strdup ("GogChart"), NULL);
/* legend */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_SOLID;
style->line.width = 0; /* hairline */
style->line.color = GO_COLOR_BLACK;
style->fill.type = GO_STYLE_FILL_PATTERN;
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_WHITE);
- gog_theme_add_element (theme, style, NULL, "GogLegend", NULL);
+ gog_theme_add_element (theme, style, NULL, g_strdup ("GogLegend"), NULL);
/* Axis */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_SOLID;
style->line.width = 0.; /* hairline */
style->line.color = GO_COLOR_GREY (0x20);
- gog_theme_add_element (theme, style, NULL, "GogAxis", NULL);
+ gog_theme_add_element (theme, style, NULL, g_strdup ("GogAxis"), NULL);
/* AxisLine */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_SOLID;
style->line.width = 0.; /* hairline */
style->line.color = GO_COLOR_GREY (0x20);
- gog_theme_add_element (theme, style, NULL, "GogAxisLine", NULL);
+ gog_theme_add_element (theme, style, NULL, g_strdup ("GogAxisLine"), NULL);
/* Grid */
style = go_style_new ();
+ go_style_clear_auto (style);
style->fill.type = GO_STYLE_FILL_PATTERN;
style->line.dash_type = GO_LINE_NONE;
style->line.color = GO_COLOR_BLACK;
style->line.width = 0;
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_GREY (0xd0));
- gog_theme_add_element (theme, style, NULL, "GogGrid", NULL);
+ gog_theme_add_element (theme, style, NULL, g_strdup ("GogGrid"), NULL);
/* GridLine */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_SOLID;
style->line.width = 0.; /* hairline */
style->line.color = GO_COLOR_GREY (0x96);
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_FROM_RGBA (0xE0, 0xE0, 0xE0, 0xE0));
style->fill.type = GO_STYLE_FILL_NONE;
- gog_theme_add_element (theme, style, NULL, NULL, "MajorGrid");
+ gog_theme_add_element (theme, style, NULL, NULL, g_strdup ("MajorGrid"));
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_SOLID;
style->line.width = 0.; /* hairline */
style->line.color = GO_COLOR_GREY (0xC0);
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_FROM_RGBA (0xE0, 0xE0, 0xE0, 0xE0));
style->fill.type = GO_STYLE_FILL_NONE;
- gog_theme_add_element (theme, style, NULL, NULL, "MinorGrid");
+ gog_theme_add_element (theme, style, NULL, NULL, g_strdup ("MinorGrid"));
/* series */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_SOLID;
style->line.width = 0.; /* hairline */
style->line.color = GO_COLOR_BLACK;
@@ -933,60 +1442,66 @@ build_predefined_themes (void)
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_GREY (0x20));
/* FIXME : not really true, will want to split area from line */
gog_theme_add_element (theme, style,
- map_area_series_solid_guppi, "GogSeries", NULL);
+ map_area_series_solid_guppi, g_strdup ("GogSeries"), NULL);
/* labels */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_NONE;
style->line.width = 0; /* none */
style->line.color = GO_COLOR_BLACK;
style->fill.type = GO_STYLE_FILL_NONE;
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_WHITE);
- gog_theme_add_element (theme, style, NULL, "GogLabel", NULL);
+ gog_theme_add_element (theme, style, NULL, g_strdup ("GogLabel"), NULL);
/* trend lines */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_SOLID;
style->line.width = 1;
style->line.color = GO_COLOR_BLACK;
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_FROM_RGBA (0x00, 0x00, 0x00, 0x20));
style->fill.type = GO_STYLE_FILL_NONE;
gog_theme_add_element (theme, style,
- NULL, "GogTrendLine", NULL);
+ NULL, g_strdup ("GogTrendLine"), NULL);
/* regression equations */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_SOLID;
style->line.width = 0; /* hairline */
style->line.color = GO_COLOR_BLACK;
style->fill.type = GO_STYLE_FILL_PATTERN;
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_WHITE);
gog_theme_add_element (theme, style,
- NULL, "GogRegEqn", NULL);
+ NULL, g_strdup ("GogRegEqn"), NULL);
/* series labels */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_NONE;
style->line.width = 0; /* none */
style->line.color = GO_COLOR_BLACK;
style->fill.type = GO_STYLE_FILL_NONE;
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_WHITE);
go_style_set_font_desc (style, pango_font_description_from_string ("Sans 6"));
- gog_theme_add_element (theme, style, NULL, "GogSeriesLabels", NULL);
+ gog_theme_add_element (theme, style, NULL, g_strdup ("GogSeriesLabels"), NULL);
/* data label */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_NONE;
style->line.width = 0; /* none */
style->line.color = GO_COLOR_BLACK;
style->fill.type = GO_STYLE_FILL_NONE;
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_WHITE);
go_style_set_font_desc (style, pango_font_description_from_string ("Sans 6"));
- gog_theme_add_element (theme, style, NULL, "GogDataLabel", NULL);
+ gog_theme_add_element (theme, style, NULL, g_strdup ("GogDataLabel"), NULL);
#ifdef GOFFICE_WITH_LASEM
/* Equations */
style = go_style_new ();
+ go_style_clear_auto (style);
style->line.dash_type = GO_LINE_NONE;
style->line.width = 0; /* hairline */
style->line.color = GO_COLOR_BLACK;
@@ -994,128 +1509,18 @@ build_predefined_themes (void)
go_pattern_set_solid (&style->fill.pattern, GO_COLOR_WHITE);
go_style_set_font_desc (style, pango_font_description_from_string ("Sans 10"));
gog_theme_add_element (theme, style,
- NULL, "GogEquation", NULL);
+ NULL, g_strdup ("GogEquation"), NULL);
#endif
theme->dcm = gog_axis_color_map_from_colors (N_("Theme"),
G_N_ELEMENTS (guppi_palette),
- guppi_palette, GO_RESOURCE_CHILD);
-}
-
-struct theme_load_state {
- GogTheme *theme;
- char *desc, *lang, *local_name;
- unsigned name_lang_score;
- unsigned desc_lang_score;
- char const * const *langs;
-};
-
-static void
-name_start (GsfXMLIn *xin, xmlChar const **attrs)
-{
- struct theme_load_state *state = (struct theme_load_state *) xin->user_state;
- unsigned i;
- for (i = 0; attrs != NULL && attrs[i] && attrs[i+1] ; i += 2)
- if (0 == strcmp (attrs[i], "xml:lang"))
- state->lang = g_strdup (attrs[i+1]);
-}
-
-static void
-name_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
-{
- struct theme_load_state *state = (struct theme_load_state *) xin->user_state;
- char *name = NULL;
- if (xin->content->str == NULL)
- return;
- name = g_strdup (xin->content->str);
- if (state->lang == NULL) {
- GOStyle *style;
- state->theme = gog_theme_new (name);
- name = NULL;
- state->theme->palette = g_ptr_array_new ();
- /* initialize a dummy GogSeries style */
- style = go_style_new ();
- style->line.dash_type = GO_LINE_SOLID;
- style->line.width = 0; /* hairline */
- style->line.color = GO_COLOR_BLACK;
- style->fill.type = GO_STYLE_FILL_NONE;
- gog_theme_add_element (state->theme, style,
- map_area_series_solid_palette, "GogSeries", NULL);
- } else if (state->name_lang_score > 0 && state->langs[0] != NULL) {
- unsigned i;
- for (i = 0; i < state->name_lang_score && state->langs[i] != NULL; i++) {
- if (strcmp (state->langs[i], state->lang) == 0) {
- g_free (state->local_name);
- state->local_name = name;
- name = NULL;
- state->name_lang_score = i;
- }
- }
- }
- g_free (name);
- g_free (state->lang);
- state->lang = NULL;
-}
-
-static void
-desc_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
-{
- struct theme_load_state *state = (struct theme_load_state *) xin->user_state;
- if (state->lang == NULL) {
- if (state->desc == NULL)
- state->desc = g_strdup (xin->content->str);
- } else if (state->desc_lang_score > 0 && state->langs[0] != NULL) {
- unsigned i;
- for (i = 0; i < state->desc_lang_score && state->langs[i] != NULL; i++) {
- if (strcmp (state->langs[i], state->lang) == 0) {
- g_free (state->desc);
- state->desc = g_strdup (xin->content->str);
- state->desc_lang_score = i;
- }
- }
- }
- g_free (state->desc);
- state->desc = NULL;
-}
-
-static void
-elem_start (GsfXMLIn *xin, G_GNUC_UNUSED xmlChar const **attrs)
-{
- struct theme_load_state *state = (struct theme_load_state *) xin->user_state;
- char const *role = NULL, *class_name = NULL;
- GOStyle *style;
- unsigned i;
-
- if (state->theme == NULL)
- return;
- for (i = 0; attrs != NULL && attrs[i] && attrs[i+1] ; i += 2)
- if (0 == strcmp (attrs[i], "class"))
- class_name = g_strdup (attrs[i+1]);
- else if (0 == strcmp (attrs[i], "role"))
- role = g_strdup (attrs[i+1]);
- style = go_style_new ();
- go_persist_prep_sax (GO_PERSIST (style), xin, attrs);
-
- if (class_name && !strcmp (class_name, "GogSeries"))
- g_ptr_array_add (state->theme->palette, style);
- else
- gog_theme_add_element (state->theme, style, NULL, class_name, role);
+ guppi_palette, GO_RESOURCE_GENERATED);
}
static void
theme_load_from_uri (char const *uri)
{
- static GsfXMLInNode const theme_dtd[] = {
- GSF_XML_IN_NODE (THEME, THEME, -1, "GogTheme", GSF_XML_NO_CONTENT, NULL, NULL),
- GSF_XML_IN_NODE (THEME, NAME, -1, "name", GSF_XML_CONTENT, name_start, name_end),
- GSF_XML_IN_NODE (THEME, UNAME, -1, "_name", GSF_XML_CONTENT, name_start, name_end),
- GSF_XML_IN_NODE (THEME, DESCRIPTION, -1, "description", GSF_XML_CONTENT, name_start, desc_end),
- GSF_XML_IN_NODE (THEME, UDESCRIPTION, -1, "_description", GSF_XML_CONTENT, name_start, desc_end),
- GSF_XML_IN_NODE (THEME, STYLE, -1, "GOStyle", GSF_XML_NO_CONTENT, elem_start, NULL),
- GSF_XML_IN_NODE_END
- };
struct theme_load_state state;
- GsfXMLInDoc *xml;
GsfInput *input = go_file_open (uri, NULL);
if (input == NULL) {
@@ -1123,33 +1528,27 @@ theme_load_from_uri (char const *uri)
return;
}
state.theme = NULL;
- state.desc = state.lang = state.local_name = NULL;
+ state.desc = state.lang = state.name = NULL;
state.langs = g_get_language_names ();
state.name_lang_score = state.desc_lang_score = G_MAXINT;
- xml = gsf_xml_in_doc_new (theme_dtd, NULL);
+ if (!xml)
+ xml = gsf_xml_in_doc_new (theme_dtd, NULL);
if (!gsf_xml_in_doc_parse (xml, input, &state))
g_warning ("[GogTheme]: Could not parse %s", uri);
if (state.theme != NULL) {
- if (state.theme->dcm == NULL) {
- GOColor *colors = g_new (GOColor, state.theme->palette->len);
- unsigned i;
- for (i = 0; i < state.theme->palette->len; i++)
- colors[i] = GO_STYLE (g_ptr_array_index (state.theme->palette, i))->fill.pattern.back;
- state.theme->dcm = gog_axis_color_map_from_colors ("Default",
- state.theme->palette->len,
- colors,
- GO_RESOURCE_CHILD);
- g_free (colors);
+ state.theme->uri = g_strdup (uri);
+ if (state.theme->id == NULL) {
+ state.theme->id = go_uuid ();
+ gog_theme_save (state.theme);
}
- state.theme->local_name = state.local_name;
- state.theme->description = state.desc;
+ theme_loaded (&state);
gog_theme_registry_add (state.theme, FALSE);
+printf("theme is %p with id %s\n",state.theme,state.theme->id);
} else {
- g_free (state.local_name);
+ g_free (state.name);
g_free (state.desc);
}
g_free (state.lang);
- gsf_xml_in_doc_free (xml);
g_object_unref (input);
}
@@ -1202,8 +1601,11 @@ _gog_themes_shutdown (void)
g_slist_free_full (g_slist_copy (themes), g_object_unref);
g_slist_free (themes);
+ g_hash_table_destroy (global_class_aliases);
_gog_axis_color_maps_shutdown ();
themes = NULL;
+ if (xml)
+ gsf_xml_in_doc_free (xml);
}
/**
diff --git a/goffice/graph/gog-theme.h b/goffice/graph/gog-theme.h
index 8ae4a14..5d9e2c5 100644
--- a/goffice/graph/gog-theme.h
+++ b/goffice/graph/gog-theme.h
@@ -32,8 +32,9 @@ G_BEGIN_DECLS
GType gog_theme_get_type (void);
char const *gog_theme_get_name (GogTheme const *theme);
-char const *gog_theme_get_local_name (GogTheme const *theme);
+char const *gog_theme_get_id (GogTheme const *theme);
char const *gog_theme_get_description (GogTheme const *theme);
+GoResourceType gog_theme_get_resource_type (GogTheme const *theme);
void gog_theme_fillin_style (GogTheme const *theme, GOStyle *style,
GogObject const *obj, int ind,
GOStyleFlag relevant_fields);
diff --git a/goffice/utils/go-style.c b/goffice/utils/go-style.c
index 46573a6..fba85ed 100644
--- a/goffice/utils/go-style.c
+++ b/goffice/utils/go-style.c
@@ -1806,6 +1806,12 @@ go_style_is_fill_visible (const GOStyle *style)
return (style->fill.type != GO_STYLE_FILL_NONE);
}
+/**
+ * go_style_force_auto:
+ * @style: a #GOStyle
+ *
+ * Sets all auto fields in @style to %TRUE.
+ **/
void
go_style_force_auto (GOStyle *style)
{
@@ -1819,13 +1825,53 @@ go_style_force_auto (GOStyle *style)
style->marker.auto_fill_color =
style->line.auto_dash =
style->line.auto_color =
+ style->line.auto_fore =
+ style->line.auto_width =
style->fill.auto_type =
style->fill.auto_fore =
style->fill.auto_back =
+ style->fill.auto_pattern =
+ style->fill.gradient.auto_dir =
+ style->fill.gradient.auto_brightness =
style->font.auto_scale =
+ style->font.auto_font =
+ style->font.auto_color =
style->text_layout.auto_angle = TRUE;
}
+/**
+ * go_style_clear_auto:
+ * @style: a #GOStyle
+ *
+ * Sets all auto fields in @style to %FALSE.
+ **/
+void
+go_style_clear_auto (GOStyle *style)
+{
+ g_return_if_fail (GO_IS_STYLE (style));
+
+ if (style->marker.mark != NULL)
+ g_object_unref (G_OBJECT (style->marker.mark));
+ style->marker.mark = go_marker_new ();
+ style->marker.auto_shape =
+ style->marker.auto_outline_color =
+ style->marker.auto_fill_color =
+ style->line.auto_dash =
+ style->line.auto_color =
+ style->line.auto_fore =
+ style->line.auto_width =
+ style->fill.auto_type =
+ style->fill.auto_fore =
+ style->fill.auto_back =
+ style->fill.auto_pattern =
+ style->fill.gradient.auto_dir =
+ style->fill.gradient.auto_brightness =
+ style->font.auto_scale =
+ style->font.auto_font =
+ style->font.auto_color =
+ style->text_layout.auto_angle = FALSE;
+}
+
gboolean
go_style_is_auto (GOStyle *style)
{
diff --git a/goffice/utils/go-style.h b/goffice/utils/go-style.h
index 9cdb43c..7405477 100644
--- a/goffice/utils/go-style.h
+++ b/goffice/utils/go-style.h
@@ -146,6 +146,7 @@ gboolean go_style_is_line_visible (GOStyle const *style);
gboolean go_style_is_outline_visible (GOStyle const *style);
gboolean go_style_is_fill_visible (GOStyle const *style);
void go_style_force_auto (GOStyle *style);
+void go_style_clear_auto (GOStyle *style);
gboolean go_style_is_auto (GOStyle *style);
#ifdef GOFFICE_WITH_GTK
diff --git a/goffice/utils/goffice-utils.c b/goffice/utils/goffice-utils.c
index 4ecd594..8f1dfd1 100644
--- a/goffice/utils/goffice-utils.c
+++ b/goffice/utils/goffice-utils.c
@@ -110,6 +110,7 @@ go_uuid (void)
* @GO_RESOURCE_RO: read only on disk resource.
* @GO_RESOURCE_CHILD: child of another resource.
* @GO_RESOURCE_EXTERNAL: resource from a data file.
+ * @GO_RESOURCE_GENERATED: resource generated by the framework.
* @GO_RESOURCE_INVALID: invalid resource.
**/
GType
diff --git a/goffice/utils/goffice-utils.h b/goffice/utils/goffice-utils.h
index 86daba4..1467c22 100644
--- a/goffice/utils/goffice-utils.h
+++ b/goffice/utils/goffice-utils.h
@@ -134,6 +134,7 @@ typedef enum {
GO_RESOURCE_RW,
GO_RESOURCE_CHILD,
GO_RESOURCE_EXTERNAL,
+ GO_RESOURCE_GENERATED,
GO_RESOURCE_INVALID
} GoResourceType;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]