[goffice] Fixed warnings and add some theme editiong code.



commit 901260e1e28bad5204c8b06f165547224b3926f7
Author: Jean Brefort <jean brefort normalesup org>
Date:   Mon Nov 26 14:11:53 2012 +0100

    Fixed warnings and add some theme editiong code.

 ChangeLog                                 |   16 ++
 docs/reference/goffice-0.10-sections.txt  |   11 +-
 goffice/Makefile.am                       |    2 +
 goffice/app/go-plugin.c                   |    2 +-
 goffice/component/go-component.c          |    2 +-
 goffice/component/go-component.h          |    4 +-
 goffice/graph/gog-axis-color-map-prefs.ui |    1 +
 goffice/graph/gog-axis-color-map.c        |   25 ++-
 goffice/graph/gog-axis-color-map.h        |    1 +
 goffice/graph/gog-theme-editor.ui         |  330 +++++++++++++++++++++++++++++
 goffice/graph/gog-theme.c                 |  198 +++++++++++++++---
 goffice/graph/gog-theme.h                 |    5 +-
 goffice/graph/new-theme-prefs.ui          |  151 +++++++++++++
 goffice/gtk/goffice-gtk.c                 |    2 +-
 goffice/utils/go-file.h                   |   15 +-
 15 files changed, 717 insertions(+), 48 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 62d7c15..cc83343 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2012-11-26  Jean Brefort  <jean brefort normalesup org>
+
+	* goffice/Makefile.am: add two new .ui files.
+	* goffice/app/go-plugin.c: use GO_R_OK.
+	* goffice/component/go-component.c: constify an argument.
+	* goffice/component/go-component.h: ditto.
+	* goffice/graph/gog-axis-color-map-prefs.ui: add a title.
+	* goffice/graph/gog-axis-color-map.c: add gog_color_map_delete().
+	* goffice/graph/gog-axis-color-map.h: ditto.
+	* goffice/graph/gog-theme-editor.ui: theme editor user interface.
+	* goffice/graph/gog-theme.c: new code to edit themes.
+	* goffice/graph/gog-theme.h: ditto.
+	* goffice/graph/new-theme-prefs.ui: ditto.
+	* goffice/gtk/goffice-gtk.c: use GO_W_OK.
+	* goffice/utils/go-file.h: define GO_X_OK and friends.
+
 2012-11-25  Jean Brefort  <jean brefort normalesup org>
 
 	* goffice/gtk/go-locale-sel.c: fixed typos in locales list. [#688977]
diff --git a/docs/reference/goffice-0.10-sections.txt b/docs/reference/goffice-0.10-sections.txt
index 810ec51..35590f9 100644
--- a/docs/reference/goffice-0.10-sections.txt
+++ b/docs/reference/goffice-0.10-sections.txt
@@ -933,12 +933,12 @@ go_fourier_fftl
 <SECTION>
 <FILE>go-file</FILE>
 <TITLE>File utilities</TITLE>
-F_OK
+GO_F_OK
 GODotDot
 GOFilePermissions
-R_OK
-W_OK
-X_OK
+GO_R_OK
+GO_W_OK
+GO_X_OK
 go_basename_from_uri
 go_dirname_from_uri
 go_file_access
@@ -2748,6 +2748,7 @@ gog_axis_base_view_get_type
 GogAxisColorMap
 gog_axis_color_map_edit
 GogAxisColorMapHandler
+gog_axis_color_map_delete
 gog_axis_color_map_dup
 gog_axis_color_map_foreach
 gog_axis_color_map_from_colors
@@ -3405,8 +3406,10 @@ gog_styled_object_get_type
 <FILE>gog-theme</FILE>
 <TITLE>Theming</TITLE>
 GogTheme
+gog_theme_delete
 gog_theme_dup
 gog_theme_edit
+gog_theme_foreach
 gog_theme_fillin_style
 gog_theme_get_color_map
 gog_theme_get_description
diff --git a/goffice/Makefile.am b/goffice/Makefile.am
index 979773d..3e9b78a 100644
--- a/goffice/Makefile.am
+++ b/goffice/Makefile.am
@@ -567,6 +567,8 @@ embedded_stuff_compress = \
 	graph/gog-reg-eqn-prefs.ui		\
 	graph/gog-series-labels-prefs.ui	\
 	graph/gog-series-prefs.ui		\
+	graph/gog-theme-editor.ui		\
+	graph/new-theme-prefs.ui		\
 	gtk/go-3d-rotation-sel.ui		\
 	gtk/go-font-sel.ui			\
 	gtk/go-format-sel.ui			\
diff --git a/goffice/app/go-plugin.c b/goffice/app/go-plugin.c
index 32e488a..c9b1c6a 100644
--- a/goffice/app/go-plugin.c
+++ b/goffice/app/go-plugin.c
@@ -778,7 +778,7 @@ go_plugin_read (GOPlugin *plugin, gchar const *dir_name, GOErrorInfo **ret_error
 	doc = go_xml_parse_file (file_name);
 	if (doc == NULL || doc->xmlRootNode == NULL || strcmp (doc->xmlRootNode->name, "plugin") != 0) {
 		char *uri = go_filename_to_uri (file_name);
-		if (go_file_access (uri, R_OK) != 0) {
+		if (go_file_access (uri, GO_R_OK) != 0) {
 			*ret_error = go_error_info_new_printf (
 			             _("Can't read plugin info file (\"%s\")."),
 			             file_name);
diff --git a/goffice/component/go-component.c b/goffice/component/go-component.c
index 033ca88..4c8590e 100644
--- a/goffice/component/go-component.c
+++ b/goffice/component/go-component.c
@@ -851,7 +851,7 @@ go_component_get_snapshot (GOComponent *component, GOSnapshotType *type, size_t
 	return component->snapshot_data;
 }
 
-void go_component_set_font (GOComponent *component, PangoFontDescription *desc)
+void go_component_set_font (GOComponent *component, PangoFontDescription const *desc)
 {
 	GOComponentClass *klass = GO_COMPONENT_GET_CLASS (component);
 	if (klass->set_font)
diff --git a/goffice/component/go-component.h b/goffice/component/go-component.h
index c394fb8..0b10e4d 100644
--- a/goffice/component/go-component.h
+++ b/goffice/component/go-component.h
@@ -70,7 +70,7 @@ struct _GOComponentClass {
 	void (*set_size) (GOComponent *component);
 	void (*render) (GOComponent *component, cairo_t *cr,
 			    double width, double height);
-	void (*set_font) (GOComponent *component, PangoFontDescription *desc);
+	void (*set_font) (GOComponent *component, PangoFontDescription const *desc);
 	/*<private>*/
 	void (*reserved1) (void);
 	void (*reserved2) (void);
@@ -116,7 +116,7 @@ GOCmdContext *go_component_get_command_context (GOComponent *component);
 void go_component_set_default_command_context (GOCmdContext *cc);
 void go_component_render (GOComponent *component, cairo_t *cr, double width, double height);
 void go_component_get_size (GOComponent *component, double *width, double *height);
-void go_component_set_font (GOComponent *component, PangoFontDescription *desc);
+void go_component_set_font (GOComponent *component, PangoFontDescription const *desc);
 
 void go_component_write_xml_sax (GOComponent *component, GsfXMLOut *output);
 typedef void (*GOComponentSaxHandler)(GOComponent *component, gpointer user_data);
diff --git a/goffice/graph/gog-axis-color-map-prefs.ui b/goffice/graph/gog-axis-color-map-prefs.ui
index 1050506..bb70e2e 100644
--- a/goffice/graph/gog-axis-color-map-prefs.ui
+++ b/goffice/graph/gog-axis-color-map-prefs.ui
@@ -9,6 +9,7 @@
   <object class="GtkDialog" id="gog-axis-color-map-prefs">
     <property name="can_focus">False</property>
     <property name="border_width">5</property>
+    <property name="title" translatable="yes">Color map editor</property>
     <property name="type_hint">dialog</property>
     <child internal-child="vbox">
       <object class="GtkBox" id="dialog-vbox1">
diff --git a/goffice/graph/gog-axis-color-map.c b/goffice/graph/gog-axis-color-map.c
index 8e6eb95..11d7bb7 100644
--- a/goffice/graph/gog-axis-color-map.c
+++ b/goffice/graph/gog-axis-color-map.c
@@ -734,7 +734,7 @@ bin_changed_cb (GtkSpinButton *btn, struct color_map_edit_state *state)
 /**
  * gog_axis_color_map_edit:
  * @map: a #GogAxisColorMap or %NULL
- * @cc: a #GOCmdContext
+ * @cc: a #GOCmdContext or %NULL
  *
  * Opens a dialog to edit the color map. If @map is %NULL, creates a new one
  * unless the user cancels the edition.
@@ -880,7 +880,7 @@ color_map_load_from_uri (char const *uri)
 	if (!gsf_xml_in_doc_parse (xml, input, &state))
 		g_warning ("[GogAxisColorMap]: Could not parse %s", uri);
 	if (state.map != NULL) {
-		if (!go_file_access (uri, W_OK)) {
+		if (!go_file_access (uri, GO_W_OK)) {
 			state.map->uri = g_strdup (uri);
 			state.map->type = GO_RESOURCE_RW;
 		} else
@@ -961,6 +961,27 @@ gog_axis_color_map_get_from_id (char const *id)
 	return map;
 }
 
+/**
+ * gog_axis_color_map_delete:
+ * @map: a #GogAxisColorMap
+ *
+ * Destroys the color map and remove it from the user directory and from the
+ * database.
+ * Returns: %TRUE on success.
+ **/
+gboolean
+gog_axis_color_map_delete (GogAxisColorMap *map)
+{
+	GFile *file = g_file_new_for_uri (map->uri);
+	gboolean res;
+	if ((res = g_file_delete (file, NULL, NULL))) {
+		color_maps = g_slist_remove (color_maps, map);
+		g_object_unref (map);
+	}
+	g_object_unref (file);
+	return res;
+}
+
 void
 _gog_axis_color_maps_init (void)
 {
diff --git a/goffice/graph/gog-axis-color-map.h b/goffice/graph/gog-axis-color-map.h
index fd6c9cb..7161db0 100644
--- a/goffice/graph/gog-axis-color-map.h
+++ b/goffice/graph/gog-axis-color-map.h
@@ -53,6 +53,7 @@ GogAxisColorMap *gog_axis_color_map_edit (GogAxisColorMap *map, GOCmdContext *cc
 typedef void (*GogAxisColorMapHandler) (GogAxisColorMap const *map, gpointer user_data);
 void gog_axis_color_map_foreach (GogAxisColorMapHandler handler, gpointer user_data);
 GogAxisColorMap const *gog_axis_color_map_get_from_id (char const *id);
+gboolean gog_axis_color_map_delete (GogAxisColorMap *map);
 
 /* private */
 GogAxisColorMap const *_gog_axis_color_map_get_default (void);
diff --git a/goffice/graph/gog-theme-editor.ui b/goffice/graph/gog-theme-editor.ui
new file mode 100644
index 0000000..ebfb2f0
--- /dev/null
+++ b/goffice/graph/gog-theme-editor.ui
@@ -0,0 +1,330 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkDialog" id="gog-theme-editor">
+    <property name="can_focus">False</property>
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">Theme editor</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="dialog-vbox1">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area1">
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="close">
+                <property name="label">gtk-close</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="save">
+                <property name="label">gtk-save</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkGrid" id="theme-grid">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="vexpand">True</property>
+            <property name="row_spacing">6</property>
+            <property name="column_spacing">12</property>
+            <child>
+              <object class="GtkEntry" id="name">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="invisible_char">â</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">0</property>
+                <property name="width">2</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="name-lbl">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;Name&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">0</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkNotebook" id="classes-book">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="vexpand">True</property>
+                <property name="show_tabs">False</property>
+                <property name="show_border">False</property>
+                <child>
+                  <object class="GtkScrolledWindow" id="scrolledwindow1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="shadow_type">in</property>
+                    <child>
+                      <object class="GtkTreeView" id="styles-view">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="model">styles-list</property>
+                        <child internal-child="selection">
+                          <object class="GtkTreeSelection" id="styles-selection"/>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child type="tab">
+                  <placeholder/>
+                </child>
+                <child>
+                  <object class="GtkScrolledWindow" id="scrolledwindow2">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="shadow_type">in</property>
+                    <child>
+                      <object class="GtkTreeView" id="series-view">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="model">styles-list</property>
+                        <child internal-child="selection">
+                          <object class="GtkTreeSelection" id="series-selection"/>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child type="tab">
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child type="tab">
+                  <placeholder/>
+                </child>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">1</property>
+                <property name="width">2</property>
+                <property name="height">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkNotebook" id="styles-book">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="vexpand">True</property>
+                <property name="tab_pos">left</property>
+                <child>
+                  <placeholder/>
+                </child>
+                <child type="tab">
+                  <object class="GtkLabel" id="classes-lbl">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Classes</property>
+                  </object>
+                  <packing>
+                    <property name="tab_fill">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child type="tab">
+                  <object class="GtkLabel" id="series-lbl">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Series</property>
+                  </object>
+                  <packing>
+                    <property name="position">1</property>
+                    <property name="tab_fill">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child type="tab">
+                  <placeholder/>
+                </child>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">4</property>
+                <property name="width">4</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButtonBox" id="buttonbox1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="homogeneous">True</property>
+                <property name="layout_style">start</property>
+                <child>
+                  <object class="GtkButton" id="add">
+                    <property name="label">gtk-add</property>
+                    <property name="use_action_appearance">False</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="use_action_appearance">False</property>
+                    <property name="use_stock">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="delete">
+                    <property name="label">gtk-remove</property>
+                    <property name="use_action_appearance">False</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="use_action_appearance">False</property>
+                    <property name="use_stock">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">3</property>
+                <property name="width">2</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="snapshot">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="hexpand">True</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">&lt;b&gt;Snapshot&lt;/b&gt;</property>
+                <property name="use_markup">True</property>
+              </object>
+              <packing>
+                <property name="left_attach">2</property>
+                <property name="top_attach">1</property>
+                <property name="width">2</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkNotebook" id="snapshot-book">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="hexpand">True</property>
+                <property name="vexpand">True</property>
+                <property name="show_tabs">False</property>
+                <child>
+                  <placeholder/>
+                </child>
+                <child type="tab">
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child type="tab">
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child type="tab">
+                  <placeholder/>
+                </child>
+              </object>
+              <packing>
+                <property name="left_attach">2</property>
+                <property name="top_attach">2</property>
+                <property name="width">2</property>
+                <property name="height">2</property>
+              </packing>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="0">close</action-widget>
+      <action-widget response="1">save</action-widget>
+    </action-widgets>
+  </object>
+  <object class="GtkListStore" id="series-list">
+    <columns>
+      <!-- column-name Series -->
+      <column type="guint"/>
+    </columns>
+  </object>
+  <object class="GtkListStore" id="styles-list">
+    <columns>
+      <!-- column-name Class -->
+      <column type="gchararray"/>
+      <!-- column-name Role -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
+</interface>
diff --git a/goffice/graph/gog-theme.c b/goffice/graph/gog-theme.c
index 8cb631a..861baae 100644
--- a/goffice/graph/gog-theme.c
+++ b/goffice/graph/gog-theme.c
@@ -558,32 +558,54 @@ desc_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
 	state->lang = NULL;
 }
 
+enum { /* used in theme editor to display the right snapshot */
+	SNAPSHOT_GRAPH,
+	SNAPSHOT_TRENDLINE,
+	SNAPSHOT_SERIES,
+	SNAPSHOT_SERIESLABELS,
+	SNAPSHOT_SERIESLINES,
+#ifdef GOFFICE_WITH_LASEM
+	SNAPSHOT_EQUATION,
+#endif
+};
+
+typedef struct {
+	char const *klass_name;
+	char const *role_id;
+	char const *label;
+	GOStyleFlag flags;
+	unsigned snapshot;
+} GogThemeRoles;
+
+static GogThemeRoles roles[] = {
+	{"GogGraph", NULL, N_("Graph"), GO_STYLE_FILL | GO_STYLE_OUTLINE, SNAPSHOT_GRAPH},
+	{"GogGraph", "Title", N_("Graph title"), GO_STYLE_OUTLINE | GO_STYLE_FILL | GO_STYLE_FONT | GO_STYLE_TEXT_LAYOUT, SNAPSHOT_GRAPH},
+	{"GogChart", NULL, N_("Chart"), GO_STYLE_FILL | GO_STYLE_OUTLINE, SNAPSHOT_GRAPH},
+	{"GogChart", "Title", N_("Chart title"), GO_STYLE_OUTLINE | GO_STYLE_FILL | GO_STYLE_FONT | GO_STYLE_TEXT_LAYOUT, SNAPSHOT_GRAPH},
+	{"GogLegend", NULL, N_("Legend"), GO_STYLE_OUTLINE | GO_STYLE_FILL | GO_STYLE_FONT, SNAPSHOT_GRAPH},
+	{"GogAxis", NULL, N_("Axis"), GO_STYLE_LINE | GO_STYLE_FONT | GO_STYLE_TEXT_LAYOUT, SNAPSHOT_GRAPH},
+	{"GogAxisLine", NULL, N_("Axis line"), GO_STYLE_LINE | GO_STYLE_FONT, SNAPSHOT_GRAPH},
+	{"GogGrid", NULL, N_("Backplane"), GO_STYLE_FILL | GO_STYLE_OUTLINE, SNAPSHOT_GRAPH},
+	{"GogGrid", "MajorGrid", N_("Major grid"), GO_STYLE_LINE | GO_STYLE_FILL, SNAPSHOT_GRAPH},
+	{"GogGrid", "MinorGrid", N_("Minor grid"), GO_STYLE_LINE | GO_STYLE_FILL, SNAPSHOT_GRAPH},
+	{"GogLabel", NULL, N_("Label"), GO_STYLE_OUTLINE | GO_STYLE_FILL | GO_STYLE_FONT | GO_STYLE_TEXT_LAYOUT, SNAPSHOT_GRAPH},
+	{"GogTrendLine", NULL, N_("Trend line"), GO_STYLE_LINE, SNAPSHOT_TRENDLINE},
+	{"GogRegEqn", NULL, N_("Regression equation"), GO_STYLE_OUTLINE | GO_STYLE_FILL | GO_STYLE_FONT | GO_STYLE_TEXT_LAYOUT, SNAPSHOT_TRENDLINE},
+#ifdef GOFFICE_WITH_LASEM
+	{"GogEquation", NULL, N_("Equation"), GO_STYLE_OUTLINE | GO_STYLE_FILL | GO_STYLE_FONT | GO_STYLE_TEXT_LAYOUT, SNAPSHOT_EQUATION},
+#endif
+	{"GogSeriesLine", NULL, N_("Series lines"), GO_STYLE_LINE, SNAPSHOT_SERIESLINES},
+	{"GogSeries", NULL, N_("Series"), GO_STYLE_LINE | GO_STYLE_FILL | GO_STYLE_MARKER, SNAPSHOT_SERIES},
+	{"GogSeriesLabels", NULL, N_("Series labels"), GO_STYLE_OUTLINE | GO_STYLE_FILL | GO_STYLE_FONT | GO_STYLE_TEXT_LAYOUT, SNAPSHOT_SERIESLABELS},
+	{"GogDataLabel", NULL, N_("Data label"), GO_STYLE_OUTLINE | GO_STYLE_FILL | GO_STYLE_FONT | GO_STYLE_TEXT_LAYOUT, SNAPSHOT_SERIESLABELS}
+};
+
 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);
@@ -595,19 +617,18 @@ gog_theme_add_element (GogTheme *theme, GOStyle *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))
+	for (i = 0; i < G_N_ELEMENTS (roles); i++) {
+		if ((klass_name && roles[i].klass_name && strcmp (klass_name, roles[i].klass_name))
+		    || (klass_name != NULL && roles[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))
+		if ((role_id && roles[i].role_id && strcmp (role_id, roles[i].role_id))
+		    || (role_id == NULL && roles[i].role_id != NULL) ||
+		    (role_id != NULL && roles[i].role_id == NULL))
 			continue;
-		style->interesting_fields = ifields[i].fields;
+		style->interesting_fields = roles[i].flags;
 		break;
 	}
-	if (i == G_N_ELEMENTS (ifields))
+	if (i == G_N_ELEMENTS (roles))
 		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) {
@@ -1205,10 +1226,19 @@ build_predefined_themes (void)
 			(gpointer)"GogSeriesElement", (gpointer)"GogSeries");
 		g_hash_table_insert (global_class_aliases,
 			(gpointer)"GogSeriesLines", (gpointer)"GogSeries");
+		g_hash_table_insert (global_class_aliases,
+			(gpointer)"GogSeriesLabels", (gpointer)"GogLabel");
+		g_hash_table_insert (global_class_aliases,
+			(gpointer)"GogDataLabel", (gpointer)"GogLabel");
+#ifdef GOFFICE_WITH_LASEM
+		g_hash_table_insert (global_class_aliases,
+			(gpointer)"GogEquation", (gpointer)"GogLabel");
+#endif
 	}
 
 	/* An MS Excel-ish theme */
 	theme = gog_theme_new (N_("Default"), GO_RESOURCE_NATIVE);
+	theme->description = g_strdup (_("An MS Excel like theme"));
 	gog_theme_registry_add (theme, TRUE);
 
 	/* graph */
@@ -1379,6 +1409,7 @@ build_predefined_themes (void)
 
 /* Guppi */
 	theme = gog_theme_new (N_("Guppi"), GO_RESOURCE_NATIVE);
+	theme->description = g_strdup (_("Guppi theme"));
 	gog_theme_registry_add (theme, FALSE);
 
 	/* graph */
@@ -1561,7 +1592,7 @@ theme_load_from_uri (char const *uri)
 	if (!gsf_xml_in_doc_parse (xml, input, &state))
 		g_warning ("[GogTheme]: Could not parse %s", uri);
 	if (state.theme != NULL) {
-		if (!go_file_access (uri, W_OK)) {
+		if (!go_file_access (uri, GO_W_OK)) {
 			state.theme->uri = g_strdup (uri);
 			if (state.theme->id == NULL) {
 				state.theme->id = go_uuid ();
@@ -1664,10 +1695,45 @@ gog_theme_get_color_map (GogTheme const *theme, gboolean discrete)
 	return NULL;
 }
 
+/**
+ * gog_theme_delete:
+ * @theme: a #GogTheme
+ *
+ * Destroys the theme and remove it from the user directory and from the
+ * database.
+ * Returns: %TRUE on success.
+ **/
+gboolean
+gog_theme_delete (GogTheme *theme)
+{
+	GFile *file = g_file_new_for_uri (theme->uri);
+	gboolean res;
+	if ((res = g_file_delete (file, NULL, NULL))) {
+		themes = g_slist_remove (themes, theme);
+		g_object_unref (theme);
+	}
+	g_object_unref (file);
+	return res;
+}
+
 /*****************
  * Theme edition *
  *****************/
 
+/**
+ * gog_theme_foreach:
+ * @handler: (scope call): a #GFunc using a theme as first argument
+ * @user_data: data to pass to @handler
+ *
+ * Executes @handler to each theme installed on the system, including built-in
+ * themes.
+ **/
+void
+gog_theme_foreach (GFunc handler, gpointer user_data)
+{
+	g_slist_foreach (themes, handler, user_data);
+}
+
 static void
 gog_theme_set_name (GogTheme *theme, char const *name)
 {
@@ -1725,9 +1791,27 @@ gog_theme_dup (GogTheme *theme)
 	return new_theme;
 }
 
+#ifdef GOFFICE_WITH_GTK
+
+struct theme_edit_state {
+	GtkBuilder *gui;
+	GogTheme *theme;
+};
+
+static void
+create_toggled_cb (GtkListStore *list, char const *path) 
+{
+	GtkTreeIter iter;
+	gboolean set;
+	gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (list), &iter, path);
+	gtk_tree_model_get (GTK_TREE_MODEL (list), &iter, 1, &set, -1);
+	gtk_list_store_set (list, &iter, 1, !set, -1);
+}
+
 /**
  * gog_theme_edit:
  * @theme: the #GogTheme to edit or %NULL to create a new one.
+ * @cc: a #GOCmdContext or %NULL.
  *
  * Displays a dialog box to edit the theme. This can be done only for
  * locally installed themes that are writeable.
@@ -1735,7 +1819,59 @@ gog_theme_dup (GogTheme *theme)
  * been cancelled.
  **/
 GogTheme *
-gog_theme_edit (GogTheme *theme)
+gog_theme_edit (GogTheme *theme, GOCmdContext *cc)
 {
+	struct theme_edit_state state;
+	GtkWidget *w;
+
+	if (theme == NULL) {
+		/* display a dialog box to select used roles and series number */
+		GtkBuilder *gui = go_gtk_builder_load_internal ("res:go:graph/new-theme-prefs.ui", GETTEXT_PACKAGE, cc);
+		int response;
+		GtkWidget *w;
+		GtkListStore *l = GTK_LIST_STORE (gtk_builder_get_object (gui, "classes-list"));
+		GtkTreeView *tv = GTK_TREE_VIEW (gtk_builder_get_object (gui, "classes-tree"));
+		GtkCellRenderer *renderer;
+		GtkTreeViewColumn *column;
+		GtkTreeIter iter;
+		unsigned i;
+
+		renderer = gtk_cell_renderer_text_new ();
+		column = gtk_tree_view_column_new_with_attributes (_("Class"), renderer, "text", 0, NULL);
+		gtk_tree_view_append_column (tv, column);
+		renderer = gtk_cell_renderer_toggle_new ();
+		column = gtk_tree_view_column_new_with_attributes (_("Create"), renderer, "active", 1, NULL);
+		gtk_tree_view_append_column (tv, column);
+		for (i = 0; i < G_N_ELEMENTS (roles); i++) {
+			if (!strcmp (roles[i].klass_name, "Series"))
+				continue;
+			gtk_list_store_append (l, &iter);
+			gtk_list_store_set (l, &iter, 0, _(roles[i].label), 1, FALSE, 2, i, -1);
+		}
+		g_signal_connect_swapped (renderer, "toggled", G_CALLBACK (create_toggled_cb), l);
+
+		w = go_gtk_builder_get_widget (gui, "new-theme-prefs");
+		response = gtk_dialog_run (GTK_DIALOG (w));
+		gtk_widget_destroy (w);
+		g_object_unref (gui);
+		if (response == 1) {
+			theme = gog_theme_new (_("New theme"), FALSE);
+			theme->id = go_uuid ();
+			theme->type = GO_RESOURCE_RW;
+		} else
+			return NULL;
+	}
+
+	state.theme = theme;
+	state.gui = go_gtk_builder_load_internal ("res:go:graph/gog-theme-editor.ui", GETTEXT_PACKAGE, cc);
+
+	w = go_gtk_builder_get_widget (state.gui, "gog-theme-editor");
+	if (gtk_dialog_run (GTK_DIALOG (w))) {
+	}
+	gtk_widget_destroy (w);
+	g_object_unref (G_OBJECT (state.gui));
 	return NULL;
 }
+
+#endif
+
diff --git a/goffice/graph/gog-theme.h b/goffice/graph/gog-theme.h
index 6c9b0f8..2be4ac0 100644
--- a/goffice/graph/gog-theme.h
+++ b/goffice/graph/gog-theme.h
@@ -43,8 +43,11 @@ GogAxisColorMap const *gog_theme_get_color_map (GogTheme const *theme, gboolean
 GogTheme   *gog_theme_registry_lookup 		(char const *name);
 GSList	   *gog_theme_registry_get_theme_names	(void);
 void		gog_theme_save_to_home_dir (GogTheme *theme);
-GogTheme   *gog_theme_edit			(GogTheme *theme);
+GogTheme   *gog_theme_edit			(GogTheme *theme, GOCmdContext *cc);
 GogTheme   *gog_theme_dup			(GogTheme *theme);
+gboolean	gog_theme_delete		(GogTheme *theme);
+
+void gog_theme_foreach (GFunc handler, gpointer user_data);
 
 /* private */
 void _gog_themes_init	 (void);
diff --git a/goffice/graph/new-theme-prefs.ui b/goffice/graph/new-theme-prefs.ui
new file mode 100644
index 0000000..a6c9b17
--- /dev/null
+++ b/goffice/graph/new-theme-prefs.ui
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkListStore" id="classes-list">
+    <columns>
+      <!-- column-name Class -->
+      <column type="gchararray"/>
+      <!-- column-name Create -->
+      <column type="gboolean"/>
+      <!-- column-name index -->
+      <column type="guint"/>
+    </columns>
+  </object>
+  <object class="GtkAdjustment" id="series-adj">
+    <property name="upper">100</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+  <object class="GtkDialog" id="new-theme-prefs">
+    <property name="can_focus">False</property>
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">New theme</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="dialog-vbox1">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area1">
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="button2">
+                <property name="label">gtk-close</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="button1">
+                <property name="label">gtk-apply</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkGrid" id="grid1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="vexpand">True</property>
+            <property name="row_spacing">6</property>
+            <property name="column_spacing">12</property>
+            <child>
+              <object class="GtkScrolledWindow" id="scrolledwindow1">
+                <property name="height_request">300</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="hexpand">True</property>
+                <property name="vexpand">True</property>
+                <property name="hscrollbar_policy">never</property>
+                <property name="shadow_type">in</property>
+                <child>
+                  <object class="GtkTreeView" id="classes-tree">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="model">classes-list</property>
+                    <child internal-child="selection">
+                      <object class="GtkTreeSelection" id="classes-selection"/>
+                    </child>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">0</property>
+                <property name="width">2</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="series-lbl">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Series number</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">1</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkSpinButton" id="series">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="hexpand">True</property>
+                <property name="invisible_char">â</property>
+                <property name="adjustment">series-adj</property>
+                <property name="snap_to_ticks">True</property>
+              </object>
+              <packing>
+                <property name="left_attach">1</property>
+                <property name="top_attach">1</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="0">button2</action-widget>
+      <action-widget response="1">button1</action-widget>
+    </action-widgets>
+  </object>
+</interface>
diff --git a/goffice/gtk/goffice-gtk.c b/goffice/gtk/goffice-gtk.c
index a6305ba..966e655 100644
--- a/goffice/gtk/goffice-gtk.c
+++ b/goffice/gtk/goffice-gtk.c
@@ -1253,7 +1253,7 @@ go_gtk_url_is_writeable (GtkWindow *parent, char const *uri,
 		go_gtk_notice_dialog (parent, GTK_MESSAGE_ERROR,
 				      _("%s\nis a directory name"), uri);
 		result = FALSE;
-	} else if (go_file_access (uri, W_OK) != 0 && errno != ENOENT) {
+	} else if (go_file_access (uri, GO_W_OK) != 0 && errno != ENOENT) {
 		go_gtk_notice_dialog (parent, GTK_MESSAGE_ERROR,
 				      _("You do not have permission to save to\n%s"),
 				      uri);
diff --git a/goffice/utils/go-file.h b/goffice/utils/go-file.h
index d2f081e..25ffe09 100644
--- a/goffice/utils/go-file.h
+++ b/goffice/utils/go-file.h
@@ -49,11 +49,16 @@ typedef enum {
 	GO_DOTDOT_LEAVE         /* Leave alone.  */
 } GODotDot;
 
-#ifndef R_OK
-#  define F_OK 0
-#  define X_OK 1
-#  define W_OK 2
-#  define R_OK 4
+#ifdef R_OK
+#  define GO_F_OK F_OK
+#  define GO_X_OK X_OK
+#  define GO_W_OK W_OK
+#  define GO_R_OK R_OK
+#else
+#  define GO_F_OK 0
+#  define GO_X_OK 1
+#  define GO_W_OK 2
+#  define GO_R_OK 4
 #endif
 
 char *go_filename_simplify (const char *filename, GODotDot dotdot, gboolean make_absolute);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]