[gnumeric] ods: make ods export more deterministic.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] ods: make ods export more deterministic.
- Date: Tue, 20 May 2014 23:22:16 +0000 (UTC)
commit 6a6ebdc1ed9d9657f76bb62ad81c3cf8e684f108
Author: Morten Welinder <terra gnome org>
Date: Tue May 20 19:20:30 2014 -0400
ods: make ods export more deterministic.
1. Avoid using pointers for naming items in ods.
2. Avoid some dependence on hash order.
ChangeLog | 6 +
NEWS | 1 +
plugins/openoffice/ChangeLog | 2 +-
plugins/openoffice/openoffice-write.c | 189 ++++++++++++++++++++++++---------
4 files changed, 145 insertions(+), 53 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 4a4c23a..4885f23 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2014-05-20 Morten Welinder <terra gnome org>
+ * plugins/openoffice/openoffice-write.c
+ (openoffice_file_save_real): Write graphs and images in order of
+ name, not random hash order.
+ (oo_item_name): New function for naming various styles and objects
+ consistently.
+
* src/gutils.c (gnm_hash_table_foreach_ordered): New function.
* src/gnm-so-filled.c (gnm_so_filled_write_xml_sax): Don't write
diff --git a/NEWS b/NEWS
index f28aede..faf34bd 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,7 @@ Morten:
* Make installtion work without scrollkeeper.
* Improve import/export testing. [#730397]
* Speed up certain large ranges of conditional formatting.
+ * Work towards making ods export deterministic.
--------------------------------------------------------------------------
Gnumeric 1.12.15
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index 7107832..08b05bc 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -775,7 +775,7 @@
2013-06-13 Andreas J. Guelzow <aguelzow pyrshep ca>
* openoffice-read.c (unset_gvalue): deleted
- (openoffice_file_open): use teh correct GDestroyNotify
+ (openoffice_file_open): use the correct GDestroyNotify
2013-06-13 Andreas J. Guelzow <aguelzow pyrshep ca>
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index 86b3093..3c7e53d 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -124,6 +124,7 @@ typedef struct {
GHashTable *named_cell_style_regions;
GHashTable *so_styles;
GHashTable *xl_styles;
+ GHashTable *style_names[10];
GnmStyleRegion *default_style_region;
ColRowInfo const *row_default;
ColRowInfo const *column_default;
@@ -231,22 +232,72 @@ odf_update_progress (GnmOOExport *state, float delta)
/*****************************************************************************/
+typedef enum {
+ OO_ITEM_TABLE_STYLE,
+ OO_ITEM_TABLE_MASTER_PAGE_STYLE,
+ OO_ITEM_PAGE_LAYOUT,
+ OO_ITEM_UNSTYLED_GRAPH_OBJECT,
+ OO_ITEM_GRAPH_STYLE,
+ OO_ITEM_SHEET_OBJECT,
+ OO_ITEM_SHEET_OBJECT_LINE,
+ OO_ITEM_MSTYLE,
+ OO_ITEM_VALIDATION,
+ OO_ITEM_INPUT_MSG
+} OONamedItemType;
+
+
static char *
-table_style_name (Sheet const *sheet)
+oo_item_name (GnmOOExport *state, OONamedItemType typ, gconstpointer ptr)
+{
+ static const char * const
+ prefixes[G_N_ELEMENTS (state->style_names)] = {
+ "ta",
+ "ta-mp"
+ "pl",
+ "GOG-",
+ "GOG",
+ "so-g",
+ "so-g-l",
+ "ACE",
+ "VAL",
+ "VAL-IM"
+ };
+ char *name;
+
+ g_return_val_if_fail ((size_t)typ <= G_N_ELEMENTS (prefixes), NULL);
+
+ name = g_hash_table_lookup (state->style_names[typ], ptr);
+ if (name) {
+ if (!g_str_has_prefix (name, prefixes[typ]))
+ g_warning ("Style name confusion.");
+ } else {
+ name = g_strdup_printf
+ ("%s-%u", prefixes[typ],
+ g_hash_table_size (state->style_names[typ]));
+ g_hash_table_replace (state->style_names[typ],
+ (gpointer)ptr,
+ name);
+ }
+ return g_strdup (name);
+}
+
+
+static char *
+table_style_name (GnmOOExport *state, Sheet const *sheet)
{
- return g_strdup_printf ("ta-%p", sheet);
+ return oo_item_name (state, OO_ITEM_TABLE_STYLE, sheet);
}
static char *
-table_master_page_style_name (Sheet const *sheet)
+table_master_page_style_name (GnmOOExport *state, Sheet const *sheet)
{
- return g_strdup_printf ("ta-mp-%p", sheet);
+ return oo_item_name (state, OO_ITEM_TABLE_MASTER_PAGE_STYLE, sheet);
}
static char *
-page_layout_name (PrintInformation *pi)
+page_layout_name (GnmOOExport *state, PrintInformation *pi)
{
- return g_strdup_printf ("pl-%p", pi);
+ return oo_item_name (state, OO_ITEM_PAGE_LAYOUT, pi);
}
@@ -666,8 +717,8 @@ odf_start_style (GsfXMLOut *xml, char const *name, char const *family)
static void
odf_write_table_style (GnmOOExport *state, Sheet const *sheet)
{
- char *name = table_style_name (sheet);
- char *mp_name = table_master_page_style_name (sheet);
+ char *name = table_style_name (state, sheet);
+ char *mp_name = table_master_page_style_name (state, sheet);
odf_start_style (state->xml, name, "table");
gsf_xml_out_add_cstr_unchecked (state->xml, STYLE "master-page-name", mp_name);
@@ -707,25 +758,26 @@ odf_write_table_style (GnmOOExport *state, Sheet const *sheet)
}
static gchar*
-odf_get_gog_style_name (GOStyle const *style, GogObject const *obj)
+odf_get_gog_style_name (GnmOOExport *state,
+ GOStyle const *style, GogObject const *obj)
{
if (style == NULL)
- return g_strdup_printf ("GOG--%p", obj);
+ return oo_item_name (state, OO_ITEM_UNSTYLED_GRAPH_OBJECT, obj);
else
- return g_strdup_printf ("GOG-%p", style);
+ return oo_item_name (state, OO_ITEM_GRAPH_STYLE, style);
}
static gchar*
-odf_get_gog_style_name_from_obj (GogObject const *obj)
+odf_get_gog_style_name_from_obj (GnmOOExport *state, GogObject const *obj)
{
GOStyle *style = NULL;
if (gnm_object_has_readable_prop (obj, "style", G_TYPE_NONE, &style)) {
- char *name = odf_get_gog_style_name (style, obj);
+ char *name = odf_get_gog_style_name (state, style, obj);
g_object_unref (style);
return name;
} else
- return odf_get_gog_style_name (NULL, obj);
+ return odf_get_gog_style_name (state, NULL, obj);
}
static const char*
@@ -791,7 +843,7 @@ odf_get_arrow_marker_name (GnmOOExport *state, GOArrow *arrow)
static char *
odf_write_sheet_object_style (GnmOOExport *state, SheetObject *so)
{
- char *name = g_strdup_printf ("so-g-%p", so);
+ char *name = oo_item_name (state, OO_ITEM_SHEET_OBJECT, so);
GOStyle *style = NULL;
(void)gnm_object_has_readable_prop (so, "style", G_TYPE_NONE, &style);
@@ -813,7 +865,7 @@ odf_write_sheet_object_style (GnmOOExport *state, SheetObject *so)
static char *
odf_write_sheet_object_line_style (GnmOOExport *state, SheetObject *so)
{
- char *name = g_strdup_printf ("so-g-l-%p", so);
+ char *name = oo_item_name (state, OO_ITEM_SHEET_OBJECT_LINE, so);
GOStyle *style = NULL;
GOArrow *start = NULL, *end = NULL;
char const *start_arrow_name = NULL;
@@ -1759,7 +1811,7 @@ odf_save_this_style (G_GNUC_UNUSED gconstpointer dummy, GnmStyleRegion *sr, GnmO
if (NULL != g_hash_table_lookup (state->cell_styles, sr->style))
return;
- name = g_strdup_printf ("ACE-%p", sr->style);
+ name = oo_item_name (state, OO_ITEM_MSTYLE, sr->style);
g_hash_table_insert (state->cell_styles, sr->style, name);
if (gnm_style_is_element_set (sr->style, MSTYLE_CONDITIONS) &&
@@ -3140,12 +3192,12 @@ odf_write_empty_cell (GnmOOExport *state, int num, GnmStyle const *style, GSList
gsf_xml_out_add_cstr (state->xml,
TABLE "style-name", name);
if (val != NULL) {
- char *vname = g_strdup_printf ("VAL-%p", val);
+ char *vname = oo_item_name (state, OO_ITEM_VALIDATION, val);
gsf_xml_out_add_cstr (state->xml,
TABLE "content-validation-name", vname);
g_free (vname);
} else if (NULL != (im = gnm_style_get_input_msg (style))) {
- char *vname = g_strdup_printf ("VAL-%p", im);
+ char *vname = oo_item_name (state, OO_ITEM_INPUT_MSG, im);
gsf_xml_out_add_cstr (state->xml,
TABLE "content-validation-name", vname);
g_free (vname);
@@ -3250,7 +3302,7 @@ odf_write_cell (GnmOOExport *state, GnmCell *cell, GnmRange const *merge_range,
gsf_xml_out_add_cstr (state->xml,
TABLE "style-name", name);
if (val != NULL) {
- char *vname = g_strdup_printf ("VAL-%p", val);
+ char *vname = oo_item_name (state, OO_ITEM_VALIDATION, val);
gsf_xml_out_add_cstr (state->xml,
TABLE "content-validation-name", vname);
g_free (vname);
@@ -4437,7 +4489,9 @@ odf_print_spreadsheet_content_validations (GnmOOExport *state)
gsf_xml_out_start_element (state->xml,
TABLE "content-validation");
- name = g_strdup_printf ("VAL-%p", val ? (gpointer) val : (gpointer) msg);
+ name = val
+ ? oo_item_name (state, OO_ITEM_VALIDATION, val)
+ : oo_item_name (state, OO_ITEM_INPUT_MSG, msg);
gsf_xml_out_add_cstr (state->xml, TABLE "name", name);
g_free (name);
@@ -4744,7 +4798,7 @@ odf_write_content (GnmOOExport *state, GsfOutput *child)
gsf_xml_out_start_element (state->xml, TABLE "table");
gsf_xml_out_add_cstr (state->xml, TABLE "name", sheet->name_unquoted);
- style_name = table_style_name (sheet);
+ style_name = table_style_name (state, sheet);
gsf_xml_out_add_cstr (state->xml, TABLE "style-name", style_name);
g_free (style_name);
@@ -5188,7 +5242,7 @@ odf_write_office_styles (GnmOOExport *state)
{
gsf_xml_out_start_element (state->xml, OFFICE "styles");
- /* We need to make sure all teh data styles for the named styles are included */
+ /* We need to make sure all the data styles for the named styles are included */
g_hash_table_foreach (state->named_cell_style_regions, (GHFunc)
odf_store_data_style_for_style_with_name, state);
g_hash_table_foreach (state->xl_styles, (GHFunc) odf_write_xl_style, state);
@@ -5278,7 +5332,7 @@ odf_write_page_layout (GnmOOExport *state, PrintInformation *pi,
"both" ,
NULL };
- char *name = page_layout_name (pi);
+ char *name = page_layout_name (state, pi);
GtkPageSetup *gps = print_info_get_page_setup (pi);
int i;
GtkPageOrientation orient = gtk_page_setup_get_orientation (gps);
@@ -5389,8 +5443,8 @@ odf_write_master_styles (GnmOOExport *state)
for (i = 0; i < workbook_sheet_count (state->wb); i++) {
Sheet const *sheet = workbook_sheet_by_index (state->wb, i);
- char *mp_name = table_master_page_style_name (sheet);
- char *name = page_layout_name (sheet->print_info);
+ char *mp_name = table_master_page_style_name (state, sheet);
+ char *name = page_layout_name (state, sheet->print_info);
gsf_xml_out_start_element (state->xml, STYLE "master-page");
gsf_xml_out_add_cstr_unchecked (state->xml, STYLE "name", mp_name);
@@ -5956,6 +6010,14 @@ odf_write_image_manifest (SheetObject *image, char const *name, GnmOOExport *sta
}
+static int
+by_value_str (G_GNUC_UNUSED gpointer key_a, gpointer val_a,
+ G_GNUC_UNUSED gpointer key_b, gpointer val_b,
+ G_GNUC_UNUSED gpointer user)
+{
+ return strcmp (val_a, val_b);
+}
+
static void
odf_write_manifest (GnmOOExport *state, GsfOutput *child)
{
@@ -5976,8 +6038,16 @@ odf_write_manifest (GnmOOExport *state, GsfOutput *child)
odf_file_entry (xml, "text/xml", "settings.xml");
state->xml = xml;
- g_hash_table_foreach (state->graphs, (GHFunc) odf_write_graph_manifest, state);
- g_hash_table_foreach (state->images, (GHFunc) odf_write_image_manifest, state);
+ gnm_hash_table_foreach_ordered
+ (state->graphs,
+ (GHFunc) odf_write_graph_manifest,
+ by_value_str,
+ state);
+ gnm_hash_table_foreach_ordered
+ (state->images,
+ (GHFunc) odf_write_image_manifest,
+ by_value_str,
+ state);
for (l = state->fill_image_files; l != NULL; l = l->next)
odf_file_entry (xml, "image/png", l->data);
@@ -6045,7 +6115,8 @@ odf_write_drop_line (GnmOOExport *state, GogObject const *series, char const *dr
GSList *drops = gog_object_get_children
(series, role);
if (drops != NULL && drops->data != NULL) {
- char *style = odf_get_gog_style_name_from_obj (GOG_OBJECT (drops->data));
+ GogObject *obj = GOG_OBJECT (drops->data);
+ char *style = odf_get_gog_style_name_from_obj (state, obj);
gsf_xml_out_start_element (state->xml, GNMSTYLE "droplines");
gsf_xml_out_add_cstr (state->xml, CHART "style-name", style);
@@ -6169,7 +6240,7 @@ odf_write_regression_curve (GnmOOExport *state, GogObjectRole const *role, GogOb
gog_object_get_child_by_name (regression, "Equation"):
NULL;
str = odf_get_gog_style_name_from_obj
- (GOG_OBJECT (regression));
+ (state, GOG_OBJECT (regression));
gsf_xml_out_start_element
(state->xml,
(l == regressions) ? CHART "regression-curve"
@@ -6208,7 +6279,7 @@ odf_write_regression_curve (GnmOOExport *state, GogObjectRole const *role, GogOb
odf_write_plot_style_bool (state->xml, equation,
"show-r2", eq_r);
str = odf_get_gog_style_name_from_obj
- (GOG_OBJECT (equation));
+ (state, GOG_OBJECT (equation));
gsf_xml_out_add_cstr (state->xml, CHART "style-name", str);
odf_write_gog_position (state, equation);
odf_write_gog_position_pts (state, equation);
@@ -6236,7 +6307,7 @@ odf_write_standard_series (GnmOOExport *state, GSList const *series)
GSList *points;
GOData const *cat = gog_dataset_get_dim (GOG_DATASET (series->data),
GOG_MS_DIM_LABELS);
- char *str = odf_get_gog_style_name_from_obj (series->data);
+ char *str = odf_get_gog_style_name_from_obj (state, series->data);
gsf_xml_out_add_cstr (state->xml, CHART "style-name", str);
g_free (str);
@@ -6269,7 +6340,7 @@ odf_write_standard_series (GnmOOExport *state, GSList const *series)
for (l = points; l != NULL; l = l->next) {
char *style = odf_get_gog_style_name_from_obj
- (GOG_OBJECT (l->data));
+ (state, GOG_OBJECT (l->data));
g_object_get (G_OBJECT (l->data), "index", &index, NULL);
if (index > next_index) {
gsf_xml_out_start_element (state->xml,
@@ -6322,7 +6393,7 @@ odf_write_box_series (GnmOOExport *state, GSList const *series)
gsf_xml_out_add_cstr (state->xml, CHART "values-cell-range-address",
odf_strip_brackets (str));
g_free (str);
- str = odf_get_gog_style_name_from_obj (series->data);
+ str = odf_get_gog_style_name_from_obj (state, series->data);
gsf_xml_out_add_cstr (state->xml, CHART "style-name", str);
g_free (str);
odf_write_label_cell_address
@@ -6351,7 +6422,7 @@ odf_write_gantt_series (GnmOOExport *state, GSList const *series)
gsf_xml_out_add_cstr (state->xml, CHART "values-cell-range-address",
odf_strip_brackets (str));
g_free (str);
- str = odf_get_gog_style_name_from_obj (series->data);
+ str = odf_get_gog_style_name_from_obj (state, series->data);
gsf_xml_out_add_cstr (state->xml, CHART "style-name", str);
g_free (str);
if (NULL != cat) {
@@ -6377,7 +6448,7 @@ odf_write_gantt_series (GnmOOExport *state, GSList const *series)
gsf_xml_out_add_cstr (state->xml, CHART "values-cell-range-address",
odf_strip_brackets (str));
g_free (str);
- str = odf_get_gog_style_name_from_obj (series->data);
+ str = odf_get_gog_style_name_from_obj (state, series->data);
gsf_xml_out_add_cstr (state->xml, CHART "style-name", str);
g_free (str);
gsf_xml_out_end_element (state->xml); /* </chart:series> */
@@ -6405,7 +6476,7 @@ odf_write_bubble_series (GnmOOExport *state, GSList const *orig_series)
gsf_xml_out_add_cstr (state->xml, CHART "values-cell-range-address",
odf_strip_brackets (str));
g_free (str);
- str = odf_get_gog_style_name_from_obj (series->data);
+ str = odf_get_gog_style_name_from_obj (state, series->data);
gsf_xml_out_add_cstr (state->xml, CHART "style-name", str);
g_free (str);
for (j = 1; j >= 0; j--) {
@@ -6448,7 +6519,7 @@ odf_write_min_max_series (GnmOOExport *state, GSList const *orig_series)
gsf_xml_out_add_cstr (state->xml, CHART "values-cell-range-address",
odf_strip_brackets (str));
g_free (str);
- str = odf_get_gog_style_name_from_obj (series->data);
+ str = odf_get_gog_style_name_from_obj (state, series->data);
gsf_xml_out_add_cstr (state->xml, CHART "style-name", str);
g_free (str);
break;
@@ -6749,11 +6820,11 @@ odf_write_radar_axes_styles (G_GNUC_UNUSED GnmOOExport *state,
axis = gog_object_get_child_by_name (chart, "Radial-Axis");
if (axis != NULL)
- *y_style = odf_get_gog_style_name_from_obj (axis);
+ *y_style = odf_get_gog_style_name_from_obj (state, axis);
axis = gog_object_get_child_by_name (chart, "Circular-Axis");
if (axis != NULL)
- *x_style = odf_get_gog_style_name_from_obj (axis);
+ *x_style = odf_get_gog_style_name_from_obj (state, axis);
}
static void
@@ -6771,11 +6842,11 @@ odf_write_standard_axes_styles (G_GNUC_UNUSED GnmOOExport *state,
axis = gog_object_get_child_by_name (chart, x_role);
if (axis != NULL)
- *x_style = odf_get_gog_style_name_from_obj (axis);
+ *x_style = odf_get_gog_style_name_from_obj (state, axis);
axis = gog_object_get_child_by_name (chart, y_role);
if (axis != NULL)
- *y_style = odf_get_gog_style_name_from_obj (axis);
+ *y_style = odf_get_gog_style_name_from_obj (state, axis);
}
static void
@@ -6795,7 +6866,7 @@ odf_write_surface_axes_styles (GnmOOExport *state, GogObject const *chart,
axis = gog_object_get_child_by_name (chart, z_role);
if (axis != NULL)
- *z_style = odf_get_gog_style_name_from_obj (axis);
+ *z_style = odf_get_gog_style_name_from_obj (state, axis);
}
static void
@@ -6806,7 +6877,7 @@ odf_write_one_axis_grid (GnmOOExport *state, GogObject const *axis,
grid = gog_object_get_child_by_name (axis, role);
if (grid) {
- char *style = odf_get_gog_style_name_from_obj (GOG_OBJECT (grid));
+ char *style = odf_get_gog_style_name_from_obj (state, GOG_OBJECT (grid));
gsf_xml_out_start_element (state->xml, CHART "grid");
gsf_xml_out_add_cstr (state->xml, CHART "style-name", style);
@@ -6848,7 +6919,7 @@ odf_write_title (GnmOOExport *state, GogObject const *title,
odf_write_gog_position (state, title);
odf_write_gog_position_pts (state, title);
- name = odf_get_gog_style_name_from_obj (title);
+ name = odf_get_gog_style_name_from_obj (state, title);
if (name != NULL) {
gsf_xml_out_add_cstr (state->xml, CHART "style-name",
@@ -7310,7 +7381,7 @@ static void
odf_write_gog_style (GnmOOExport *state, GOStyle const *style,
GogObject const *obj)
{
- char *name = odf_get_gog_style_name (style, obj);
+ char *name = odf_get_gog_style_name (state, style, obj);
if (name != NULL) {
odf_start_style (state->xml, name, "chart");
@@ -7697,7 +7768,7 @@ odf_write_plot (GnmOOExport *state, SheetObject *so, GogObject const *graph,
if (legend != NULL) {
GogObjectPosition flags;
char *style_name = odf_get_gog_style_name_from_obj
- (legend);
+ (state, legend);
GSList *ltitles = gog_object_get_children
(legend, gog_object_find_role_by_name
(legend, "Title"));
@@ -7781,7 +7852,7 @@ odf_write_plot (GnmOOExport *state, SheetObject *so, GogObject const *graph,
gsf_xml_out_start_element (state->xml, CHART "plot-area");
- name = odf_get_gog_style_name_from_obj (plot);
+ name = odf_get_gog_style_name_from_obj (state, plot);
if (name != NULL) {
gsf_xml_out_add_cstr (state->xml, CHART "style-name", name);
g_free (name);
@@ -7826,7 +7897,7 @@ odf_write_plot (GnmOOExport *state, SheetObject *so, GogObject const *graph,
this_plot->odf_write_series (state, series);
if (wall != NULL) {
- char *name = odf_get_gog_style_name_from_obj (wall);
+ char *name = odf_get_gog_style_name_from_obj (state, wall);
gsf_xml_out_start_element (state->xml, CHART "wall");
odf_add_pt (state->xml, SVG "width", res_pts[2] - res_pts[0] - 2 * this_plot->pad);
@@ -8255,7 +8326,7 @@ openoffice_file_save_real (G_GNUC_UNUSED GOFileSaver const *fs, GOIOContext *io
GnmOOExport state;
GnmLocale *locale;
GError *err;
- unsigned i;
+ unsigned i, ui;
Sheet *sheet;
GsfOutput *pictures;
GsfOutput *manifest;
@@ -8291,6 +8362,10 @@ openoffice_file_save_real (G_GNUC_UNUSED GOFileSaver const *fs, GOIOContext *io
NULL, (GDestroyNotify) g_free);
state.xl_styles = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free, (GDestroyNotify) g_free);
+ for (ui = 0; ui < G_N_ELEMENTS (state.style_names); ui++)
+ state.style_names[ui] =
+ g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, (GDestroyNotify) g_free);
state.graph_dashes = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
NULL);
@@ -8372,8 +8447,16 @@ openoffice_file_save_real (G_GNUC_UNUSED GOFileSaver const *fs, GOIOContext *io
pictures = gsf_outfile_new_child_full (state.outfile, "Pictures", TRUE,
"compression-level", GSF_ZIP_DEFLATED,
NULL);
- g_hash_table_foreach (state.graphs, (GHFunc) odf_write_graphs, &state);
- g_hash_table_foreach (state.images, (GHFunc) odf_write_images, &state);
+ gnm_hash_table_foreach_ordered
+ (state.graphs,
+ (GHFunc) odf_write_graphs,
+ by_value_str,
+ &state);
+ gnm_hash_table_foreach_ordered
+ (state.images,
+ (GHFunc) odf_write_images,
+ by_value_str,
+ &state);
if (NULL != pictures) {
gsf_output_close (pictures);
g_object_unref (pictures);
@@ -8414,6 +8497,8 @@ openoffice_file_save_real (G_GNUC_UNUSED GOFileSaver const *fs, GOIOContext *io
g_hash_table_unref (state.cell_styles);
g_hash_table_unref (state.so_styles);
g_hash_table_unref (state.xl_styles);
+ for (ui = 0; ui < G_N_ELEMENTS (state.style_names); ui++)
+ g_hash_table_unref (state.style_names[ui]);
g_hash_table_unref (state.graph_dashes);
g_hash_table_unref (state.graph_hatches);
g_hash_table_unref (state.graph_gradients);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]