[gnumeric] make teh base-cell-address for conditional styles in ODF export really correct



commit ce87be189b0d21640fd0df2ebd9d06e67051086f
Author: Andreas J Guelzow <aguelzow pyrshep ca>
Date:   Mon May 21 18:42:26 2012 -0600

    make teh base-cell-address for conditional styles in ODF export really correct
    
    2012-05-21  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* openoffice-write.c (odf_determine_base): use a range that has this style,
    	add argument and change all callers
    	(odf_save_style_map): add range argument, change all callers
    	(odf_save_this_style_with_name): replace argument, change all callers
    	(odf_write_style): add range argument, change all callers
    	(odf_store_this_named_style): add range argument, change all callers
    	(odf_save_this_style): replace argument, change all callers
    	(odf_write_cell_styles): use sheet_style_range_foreach
    	(odf_write_office_styles): use new hash
    
    2012-05-21  Andreas J. Guelzow <aguelzow pyrshep ca>
    
    	* src/sheet-style.h (sheet_style_range_foreach): new
    	(gnm_style_region_new): new
    	(gnm_style_region_free): new
    	* src/sheet-style.c (sheet_style_range_foreach): new
    	(style_region_new): rename to gnm_style_region_new and publish
    	(style_region_free): rename to gnm_style_region_free and publish
    	(cb_hash_to_cb): new

 ChangeLog                             |   10 +++
 plugins/openoffice/ChangeLog          |   12 +++
 plugins/openoffice/openoffice-write.c |  123 ++++++++++++++++++--------------
 src/sheet-style.c                     |  106 +++++++++++++++++++++++-----
 src/sheet-style.h                     |    8 ++
 5 files changed, 187 insertions(+), 72 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index abafb52..a1a9e3b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2012-05-21  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* src/sheet-style.h (sheet_style_range_foreach): new
+	(gnm_style_region_new): new
+	(gnm_style_region_free): new
+	* src/sheet-style.c (sheet_style_range_foreach): new
+	(style_region_new): rename to gnm_style_region_new and publish
+	(style_region_free): rename to gnm_style_region_free and publish
+	(cb_hash_to_cb): new
+
 2012-05-17  Morten Welinder  <terra gnome org>
 
 	* src/validation.h: Grand rename into gnm_ namespace.
diff --git a/plugins/openoffice/ChangeLog b/plugins/openoffice/ChangeLog
index 22d0bc5..af19ae1 100644
--- a/plugins/openoffice/ChangeLog
+++ b/plugins/openoffice/ChangeLog
@@ -1,3 +1,15 @@
+2012-05-21  Andreas J. Guelzow <aguelzow pyrshep ca>
+
+	* openoffice-write.c (odf_determine_base): use a range that has this style,
+	add argument and change all callers
+	(odf_save_style_map): add range argument, change all callers
+	(odf_save_this_style_with_name): replace argument, change all callers
+	(odf_write_style): add range argument, change all callers
+	(odf_store_this_named_style): add range argument, change all callers
+	(odf_save_this_style): replace argument, change all callers
+	(odf_write_cell_styles): use sheet_style_range_foreach
+	(odf_write_office_styles): use new hash
+
 2012-05-20  Andreas J. Guelzow <aguelzow pyrshep ca>
 
 	* openoffice-write.c (odf_save_style_map_single_f): change arguments
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index 5094a29..35a0005 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -116,12 +116,13 @@ typedef struct {
 	GSList *col_styles;
 	GHashTable *cell_styles;
 	GHashTable *named_cell_styles;
+	GHashTable *named_cell_style_regions;
 	GHashTable *so_styles;
 	GHashTable *xl_styles;
 	GHashTable *xl_styles_neg;
 	GHashTable *xl_styles_zero;
 	GHashTable *xl_styles_conditional;
-	GnmStyle *default_style;
+	GnmStyleRegion *default_style_region;
 	ColRowInfo const *row_default;
 	ColRowInfo const *column_default;
 	GHashTable *graphs;
@@ -1491,24 +1492,16 @@ odf_strip_brackets (char *string)
 }
 
 static void
-odf_determine_base (GnmOOExport *state, GnmExprTop const *texpr1, GnmExprTop const *texpr2, GnmParsePos *pp)
+odf_determine_base (GnmOOExport *state, GnmRange *r, GnmParsePos *pp)
 {
-	GnmRange r;
-
-	range_init_full_sheet (&r, state->sheet);
-
-	if (texpr1) 
-		gnm_expr_top_get_boundingbox (texpr1, state->sheet, &r);
-	if (texpr2)
-		gnm_expr_top_get_boundingbox (texpr2, state->sheet, &r);
-
-	/* We should be able to use the following, but it doesn't work in the 'common' situation. */
-	/* parse_pos_init (pp, (Workbook *) state->wb, state->sheet, r.start.col, r.start.row); */
-	parse_pos_init (pp, (Workbook *) state->wb, state->sheet, r.end.col + 1, r.end.row + 1);
+	if (r)
+		parse_pos_init (pp, (Workbook *) state->wb, state->sheet, r->start.col, r->start.row);
+	else
+		g_warning ("Unable to determine an appropriate base cell address.");
 }
 
 static void
-odf_save_style_map (GnmOOExport *state, GnmStyleCond const *cond)
+odf_save_style_map (GnmOOExport *state, GnmStyleCond const *cond, GnmRange *r)
 {
 	char const *name = odf_find_style (state, cond->overlay);
 	GString *str;
@@ -1523,42 +1516,42 @@ odf_save_style_map (GnmOOExport *state, GnmStyleCond const *cond)
 
 	switch (cond->op) {
 	case GNM_STYLE_COND_BETWEEN:
-		odf_determine_base (state, cond->texpr[0], cond->texpr[1], &pp);
+		odf_determine_base (state, r, &pp);
 		g_string_append (str, "of:cell-content-is-between");
 		odf_save_style_map_double_f (state, str, cond, &pp);
 		break;
 	case GNM_STYLE_COND_NOT_BETWEEN:
-		odf_determine_base (state, cond->texpr[0], cond->texpr[1], &pp);
+		odf_determine_base (state, r, &pp);
 		g_string_append (str, "of:cell-content-is-not-between");
 		odf_save_style_map_double_f (state, str, cond, &pp);
 		break;
 	case GNM_STYLE_COND_EQUAL:
-		odf_determine_base (state, cond->texpr[0], NULL, &pp);
+		odf_determine_base (state, r, &pp);
 		g_string_append (str, "of:cell-content()=");
 		odf_save_style_map_single_f (state, str, cond->texpr[0], &pp);
 		break;
 	case GNM_STYLE_COND_NOT_EQUAL:
-		odf_determine_base (state, cond->texpr[0], NULL, &pp);
+		odf_determine_base (state, r, &pp);
 		g_string_append (str, "of:cell-content()!=");
 		odf_save_style_map_single_f (state, str, cond->texpr[0], &pp);
 		break;
 	case GNM_STYLE_COND_GT:
-		odf_determine_base (state, cond->texpr[0], NULL, &pp);
+		odf_determine_base (state, r, &pp);
 		g_string_append (str, "of:cell-content()>");
 		odf_save_style_map_single_f (state, str, cond->texpr[0], &pp);
 		break;
 	case GNM_STYLE_COND_LT:
-		odf_determine_base (state, cond->texpr[0], NULL, &pp);
+		odf_determine_base (state, r, &pp);
 		g_string_append (str, "of:cell-content()<");
 		odf_save_style_map_single_f (state, str, cond->texpr[0], &pp);
 		break;
 	case GNM_STYLE_COND_GTE:
-		odf_determine_base (state, cond->texpr[0], NULL, &pp);
+		odf_determine_base (state, r, &pp);
 		g_string_append (str, "of:cell-content()>=");
 		odf_save_style_map_single_f (state, str, cond->texpr[0], &pp);
 		break;
 	case GNM_STYLE_COND_LTE:
-		odf_determine_base (state, cond->texpr[0], NULL, &pp);
+		odf_determine_base (state, r, &pp);
 		g_string_append (str, "of:cell-content()<=");
 		odf_save_style_map_single_f (state, str, cond->texpr[0], &pp);
 		break;
@@ -1569,21 +1562,21 @@ odf_save_style_map (GnmOOExport *state, GnmStyleCond const *cond)
 		g_string_append (str, "of:is-true-formula(NOT(ISERROR([.A1])))");
 		break;
 	case GNM_STYLE_COND_CONTAINS_STR:
-		odf_determine_base (state, cond->texpr[0], NULL, &pp);
+		odf_determine_base (state, r, &pp);
 		g_string_append (str, "of:is-true-formula(NOT(ISERROR(FIND(");
 		odf_save_style_map_single_f (state, str, cond->texpr[0], &pp);
 		g_string_append_printf (str, ";[.%s%s]))))", 
 					col_name (pp.eval.col), row_name (pp.eval.row));
 		break;
 	case GNM_STYLE_COND_NOT_CONTAINS_STR:
-		odf_determine_base (state, cond->texpr[0], NULL, &pp);
+		odf_determine_base (state, r, &pp);
 		g_string_append (str, "of:is-true-formula(ISERROR(FIND(");
 		odf_save_style_map_single_f (state, str, cond->texpr[0], &pp);
 		g_string_append_printf (str, ";[.%s%s])))", 
 					col_name (pp.eval.col), row_name (pp.eval.row));
 		break;
 	case GNM_STYLE_COND_BEGINS_WITH_STR:
-		odf_determine_base (state, cond->texpr[0], NULL, &pp);
+		odf_determine_base (state, r, &pp);
 
 		g_string_append (str, "of:is-true-formula(IFERROR(FIND(");
 		odf_save_style_map_single_f (state, str, cond->texpr[0], &pp);
@@ -1591,14 +1584,14 @@ odf_save_style_map (GnmOOExport *state, GnmStyleCond const *cond)
 					col_name (pp.eval.col), row_name (pp.eval.row));
 		break;
 	case GNM_STYLE_COND_NOT_BEGINS_WITH_STR:
-		odf_determine_base (state, cond->texpr[0], NULL, &pp);
+		odf_determine_base (state, r, &pp);
 		g_string_append (str, "of:is-true-formula(NOT(IFERROR(FIND(");
 		odf_save_style_map_single_f (state, str, cond->texpr[0], &pp);
 		g_string_append_printf (str, ";[.%s%s]);2)=1))", 
 					col_name (pp.eval.col), row_name (pp.eval.row));
 		break;
 	case GNM_STYLE_COND_ENDS_WITH_STR:
-		odf_determine_base (state, cond->texpr[0], NULL, &pp);
+		odf_determine_base (state, r, &pp);
 		g_string_append (str, "of:is-true-formula(EXACT(");
 		odf_save_style_map_single_f (state, str, cond->texpr[0], &pp);
 		g_string_append_printf (str, ";RIGHT([.%s%s];LEN(", 
@@ -1607,7 +1600,7 @@ odf_save_style_map (GnmOOExport *state, GnmStyleCond const *cond)
 		g_string_append (str, ")))");
 		break;
 	case GNM_STYLE_COND_NOT_ENDS_WITH_STR:
-		odf_determine_base (state, cond->texpr[0], NULL, &pp);
+		odf_determine_base (state, r, &pp);
 		g_string_append (str, "of:is-true-formula(NOT(EXACT(");
 		odf_save_style_map_single_f (state, str, cond->texpr[0], &pp);
 		g_string_append_printf (str, ";RIGHT([.%s%s];LEN(", 
@@ -1622,7 +1615,7 @@ odf_save_style_map (GnmOOExport *state, GnmStyleCond const *cond)
 		g_string_append (str, "of:is-true-formula(ISERROR(FIND(\" \";[.A1])))");
 		break;
 	case GNM_STYLE_COND_CUSTOM:
-		odf_determine_base (state, cond->texpr[0], NULL, &pp);
+		odf_determine_base (state, r, &pp);
 		g_string_append (str, "of:is-true-formula(");
 		odf_save_style_map_single_f (state, str, cond->texpr[0], &pp);
 		g_string_append (str, ")");
@@ -1655,7 +1648,7 @@ odf_save_style_map (GnmOOExport *state, GnmStyleCond const *cond)
 }
 
 static void
-odf_write_style (GnmOOExport *state, GnmStyle const *style, gboolean is_default)
+odf_write_style (GnmOOExport *state, GnmStyle const *style, GnmRange *r, gboolean is_default)
 {
 	GnmStyleConditions const *sc;
 	GArray const *conds;
@@ -1675,7 +1668,7 @@ odf_write_style (GnmOOExport *state, GnmStyle const *style, gboolean is_default)
 	    NULL != (sc = gnm_style_get_conditions (style)) &&
 	    NULL != (conds = gnm_style_conditions_details (sc)))
 		for (i = 0 ; i < conds->len ; i++)
-			odf_save_style_map (state, &g_array_index (conds, GnmStyleCond, i));
+			odf_save_style_map (state, &g_array_index (conds, GnmStyleCond, i), r);
 
 /* MSTYLE_VALIDATION validations need to be written at a different place and time in ODF  */
 /* MSTYLE_HLINK hyperlinks can not be attached to styles but need to be attached to the cell content */
@@ -1768,15 +1761,15 @@ odf_find_col_style (GnmOOExport *state, ColRowInfo const *ci, gboolean write)
 }
 
 static void
-odf_save_this_style_with_name (GnmStyle *style, char const *name, GnmOOExport *state)
+odf_save_this_style_with_name (GnmStyleRegion *sr, char const *name, GnmOOExport *state)
 {
 	odf_start_style (state->xml, name, "table-cell");
-	odf_write_style (state, style, FALSE);
+	odf_write_style (state, sr->style, &sr->range, FALSE);
 	gsf_xml_out_end_element (state->xml); /* </style:style */
 }
 
 static void
-odf_store_this_named_style (GnmStyle *style, char const *name, GnmOOExport *state)
+odf_store_this_named_style (GnmStyle *style, char const *name, GnmRange *r, GnmOOExport *state)
 {
 	char *real_name;
 	GnmStyleConditions const *sc;
@@ -1790,6 +1783,8 @@ odf_store_this_named_style (GnmStyle *style, char const *name, GnmOOExport *stat
 		real_name = g_strdup (name);
 
 	g_hash_table_insert (state->named_cell_styles, style, real_name);
+	g_hash_table_insert (state->named_cell_style_regions, gnm_style_region_new (r, style), 
+			     g_strdup (real_name));
 
 	if (gnm_style_is_element_set (style, MSTYLE_CONDITIONS) &&
 	    NULL != (sc = gnm_style_get_conditions (style))) {
@@ -1799,34 +1794,38 @@ odf_store_this_named_style (GnmStyle *style, char const *name, GnmOOExport *stat
 			for (i = 0 ; i < conds->len ; i++) {
 				GnmStyleCond const *cond;
 				cond = &g_array_index (conds, GnmStyleCond, i);
-				odf_store_this_named_style (cond->overlay, NULL, state);
+				odf_store_this_named_style (cond->overlay, NULL, r, state);
 			}
 		}
 	}
 }
 
 static void
-odf_save_this_style (GnmStyle *style, G_GNUC_UNUSED gconstpointer dummy, GnmOOExport *state)
+odf_save_this_style (G_GNUC_UNUSED gconstpointer dummy, GnmStyleRegion *sr, GnmOOExport *state)
 {
-	char *name = g_strdup_printf ("ACE-%p", style);
+	char *name;
 	GnmStyleConditions const *sc;
 
-	g_hash_table_insert (state->cell_styles, style, name);
+	if (NULL != g_hash_table_lookup (state->cell_styles, sr->style))
+		return;
 
-	if (gnm_style_is_element_set (style, MSTYLE_CONDITIONS) &&
-	    NULL != (sc = gnm_style_get_conditions (style))) {
+	name = g_strdup_printf ("ACE-%p", sr->style);
+	g_hash_table_insert (state->cell_styles, sr->style, name);
+
+	if (gnm_style_is_element_set (sr->style, MSTYLE_CONDITIONS) &&
+	    NULL != (sc = gnm_style_get_conditions (sr->style))) {
 		GArray const *conds = gnm_style_conditions_details (sc);
 		if (conds != NULL) {
 			guint i;
 			for (i = 0 ; i < conds->len ; i++) {
 				GnmStyleCond const *cond;
 				cond = &g_array_index (conds, GnmStyleCond, i);
-				odf_store_this_named_style (cond->overlay, NULL, state);
+				odf_store_this_named_style (cond->overlay, NULL, &sr->range, state);
 			}
 		}
 	}
 
-	odf_save_this_style_with_name (style, name, state);
+	odf_save_this_style_with_name (sr, name, state);
 }
 
 static void
@@ -1955,9 +1954,9 @@ odf_write_cell_styles (GnmOOExport *state)
 	int i;
 	for (i = 0; i < workbook_sheet_count (state->wb); i++) {
 		state->sheet = workbook_sheet_by_index (state->wb, i);
-		sheet_style_foreach (state->sheet,
-				     (GHFunc) odf_save_this_style,
-				     state);
+		sheet_style_range_foreach (state->sheet,
+					   (GHFunc) odf_save_this_style,
+					   state, FALSE);
 	}
 	state->sheet = NULL;
 }
@@ -3352,12 +3351,12 @@ odf_write_formatted_columns (GnmOOExport *state, Sheet const *sheet, GnmStyle **
 
 	gsf_xml_out_start_element (state->xml, TABLE "table-column");
 	number_cols_rep = 1;
-	last_col_style = filter_style (state->default_style, col_styles[0]);
+	last_col_style = filter_style (state->default_style_region->style, col_styles[0]);
 	last_ci = sheet_col_get (sheet, 0);
 	write_col_style (state, last_col_style, last_ci, sheet);
 
 	for (i = from+1; i < to; i++) {
-		GnmStyle *this_col_style = filter_style (state->default_style, col_styles[i]);
+		GnmStyle *this_col_style = filter_style (state->default_style_region->style, col_styles[i]);
 		ColRowInfo const *this_ci = sheet_col_get (sheet, i);
 
 		if ((this_col_style == last_col_style) && colrow_equal (last_ci, this_ci))
@@ -5131,14 +5130,15 @@ odf_write_office_styles (GnmOOExport *state)
 	g_hash_table_foreach (state->xl_styles_zero, (GHFunc) odf_write_this_xl_style_zero, state);
 	g_hash_table_foreach (state->xl_styles_conditional, (GHFunc) odf_write_this_conditional_xl_style, state);
 
-	g_hash_table_foreach (state->named_cell_styles, (GHFunc) odf_save_this_style_with_name, state);
+	g_hash_table_foreach (state->named_cell_style_regions, (GHFunc) odf_save_this_style_with_name, state);
 
 	g_hash_table_foreach (state->text_colours, (GHFunc) odf_write_text_colours, state);
 
-	if (state->default_style != NULL) {
+	if (state->default_style_region->style != NULL) {
 		gsf_xml_out_start_element (state->xml, STYLE "default-style");
 		gsf_xml_out_add_cstr_unchecked (state->xml, STYLE "family", "table-cell");
-		odf_write_style (state, state->default_style, TRUE);
+		odf_write_style (state, state->default_style_region->style, 
+				 &state->default_style_region->range, TRUE);
 		gsf_xml_out_end_element (state->xml); /* </style:default-style */
 	}
 	if (state->column_default != NULL) {
@@ -8013,6 +8013,7 @@ openoffice_file_save_real (G_GNUC_UNUSED  GOFileSaver const *fs, GOIOContext *io
 	Sheet *sheet;
 	GsfOutput  *pictures;
 	GsfOutput  *child;
+	GnmStyle *style;
 
 	locale  = gnm_push_C_locale ();
 
@@ -8033,6 +8034,9 @@ openoffice_file_save_real (G_GNUC_UNUSED  GOFileSaver const *fs, GOIOContext *io
 					       NULL, (GDestroyNotify) g_free);
 	state.named_cell_styles = g_hash_table_new_full (g_direct_hash, g_direct_equal,
 						   NULL, (GDestroyNotify) g_free);
+	state.named_cell_style_regions = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+								(GDestroyNotify) gnm_style_region_free, 
+								(GDestroyNotify) g_free);
 	state.cell_styles = g_hash_table_new_full (g_direct_hash, g_direct_equal,
 						   NULL, (GDestroyNotify) g_free);
 	state.so_styles = g_hash_table_new_full (g_direct_hash, g_direct_equal,
@@ -8090,9 +8094,18 @@ openoffice_file_save_real (G_GNUC_UNUSED  GOFileSaver const *fs, GOIOContext *io
 
 	state.column_default = &sheet->cols.default_style;
 	state.row_default = &sheet->rows.default_style;
-	if (NULL != (state.default_style = sheet_style_default (sheet)))
+	if (NULL != (style = sheet_style_default (sheet))) {
+		GnmRange r = {{0,0},{0,0}};
 		/* We need to make sure any referenced styles are added to the named hash */
-		odf_store_this_named_style (state.default_style, "Gnumeric-default", &state);
+		state.default_style_region = gnm_style_region_new (&r, style);
+		odf_store_this_named_style (state.default_style_region->style, "Gnumeric-default", 
+					    &state.default_style_region->range, 
+					    &state);
+		gnm_style_unref (style);
+	} else {
+		GnmRange r = {{0,0},{0,0}};
+		state.default_style_region = gnm_style_region_new (&r, NULL);
+	}
 
 	for (i = 0 ; i < G_N_ELEMENTS (streams); i++) {
 		child = gsf_outfile_new_child_full (state.outfile, streams[i].name, FALSE,
@@ -8146,6 +8159,7 @@ openoffice_file_save_real (G_GNUC_UNUSED  GOFileSaver const *fs, GOIOContext *io
 	g_hash_table_unref (state.images);
 	g_hash_table_unref (state.controls);
 	g_hash_table_unref (state.named_cell_styles);
+	g_hash_table_unref (state.named_cell_style_regions);
 	g_hash_table_unref (state.cell_styles);
 	g_hash_table_unref (state.so_styles);
 	g_hash_table_unref (state.xl_styles);
@@ -8160,7 +8174,8 @@ openoffice_file_save_real (G_GNUC_UNUSED  GOFileSaver const *fs, GOIOContext *io
 	g_hash_table_unref (state.text_colours);
 	g_slist_free (state.col_styles);
 	g_slist_free (state.row_styles);
-	gnm_style_unref (state.default_style);
+	if (state.default_style_region)
+		gnm_style_region_free (state.default_style_region);
 	go_format_unref (state.time_fmt);
 	go_format_unref (state.date_fmt);
 	go_format_unref (state.date_long_fmt);
diff --git a/src/sheet-style.c b/src/sheet-style.c
index e79ad42..91d0777 100644
--- a/src/sheet-style.c
+++ b/src/sheet-style.c
@@ -1,3 +1,4 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
  * sheet-style.c: storage mechanism for styles and eventually cells.
  *
@@ -258,7 +259,7 @@ rstyle_ctor (ReplacementStyle *res, GnmStyle *new_style, GnmStyle *pstyle, Sheet
 }
 
 static void
-cb_style_unlink (gpointer key, gpointer value, gpointer user_data)
+cb_style_unlink (gpointer key, gpointer value, G_GNUC_UNUSED gpointer user_data)
 {
 	gnm_style_unlink ((GnmStyle *)key);
 	gnm_style_unlink ((GnmStyle *)value);
@@ -713,7 +714,7 @@ sheet_style_resize (Sheet *sheet, int cols, int rows)
 }
 
 static void
-cb_unlink (void *key, void *value, void *user)
+cb_unlink (void *key, G_GNUC_UNUSED void *value, G_GNUC_UNUSED void *user)
 {
 	gnm_style_unlink (key);
 }
@@ -1774,8 +1775,9 @@ typedef struct {
 
 static void
 cb_find_conflicts (GnmStyle *style,
-		   int corner_col, int corner_row, int width, int height,
-		   GnmRange const *apply_to, FindConflicts *ptr)
+		   G_GNUC_UNUSED int corner_col, G_GNUC_UNUSED int corner_row, 
+		   G_GNUC_UNUSED int width, G_GNUC_UNUSED int height,
+		   G_GNUC_UNUSED GnmRange const *apply_to, FindConflicts *ptr)
 {
 	ptr->conflicts = gnm_style_find_conflicts (ptr->accum, style, ptr->conflicts);
 }
@@ -2130,7 +2132,8 @@ struct cb_is_default {
 
 static void
 cb_is_default (GnmStyle *style,
-	       int corner_col, int corner_row, int width, int height,
+	       int corner_col, G_GNUC_UNUSED int corner_row, 
+	       int width, G_GNUC_UNUSED int height,
 	       GnmRange const *apply_to, gpointer user_)
 {
 	struct cb_is_default *user = user_;
@@ -2237,8 +2240,8 @@ sheet_style_most_common (Sheet const *sheet, gboolean is_col)
 
 /****************************************************************************/
 
-static GnmStyleRegion *
-style_region_new (GnmRange const *range, GnmStyle *style)
+GnmStyleRegion *
+gnm_style_region_new (GnmRange const *range, GnmStyle *style)
 {
 	GnmStyleRegion *sr;
 
@@ -2250,8 +2253,8 @@ style_region_new (GnmRange const *range, GnmStyle *style)
 	return sr;
 }
 
-static void
-style_region_free (GnmStyleRegion *sr)
+void
+gnm_style_region_free (GnmStyleRegion *sr)
 {
 	g_return_if_fail (sr != NULL);
 
@@ -2319,14 +2322,14 @@ cb_style_list_add_node (GnmStyle *style,
 #ifdef DEBUG_STYLE_LIST
 		range_dump (&range, " <= Added\n");
 #endif
-		sr = style_region_new (&range, style);
+		sr = gnm_style_region_new (&range, style);
 	}
 
 	g_hash_table_insert (mi->cache, &sr->range.end, sr);
 }
 
 static gboolean
-cb_hash_merge_horiz (gpointer hash_key, gpointer value, gpointer user)
+cb_hash_merge_horiz (G_GNUC_UNUSED gpointer hash_key, gpointer value, gpointer user)
 {
 	StyleListMerge *mi = user;
 	GnmStyleRegion *sr = value, *srh;
@@ -2334,7 +2337,7 @@ cb_hash_merge_horiz (gpointer hash_key, gpointer value, gpointer user)
 
 	/* Already merged */
 	if (sr->range.start.col < 0) {
-		style_region_free (sr);
+		gnm_style_region_free (sr);
 		return TRUE;
 	}
 
@@ -2362,14 +2365,14 @@ cb_hash_merge_horiz (gpointer hash_key, gpointer value, gpointer user)
 }
 
 static gboolean
-cb_hash_to_list (gpointer key, gpointer	value, gpointer	user_data)
+cb_hash_to_list (G_GNUC_UNUSED gpointer key, gpointer	value, gpointer	user_data)
 {
 	GnmStyleList **res = user_data;
 	GnmStyleRegion *sr = value;
 
 	/* Already merged */
 	if (sr->range.start.col < 0) {
-		style_region_free (sr);
+		gnm_style_region_free (sr);
 		return TRUE;
 	}
 
@@ -2629,7 +2632,7 @@ style_list_free (GnmStyleList *list)
 	GnmStyleList *l;
 
 	for (l = list; l; l = l->next)
-		style_region_free (l->data);
+		gnm_style_region_free (l->data);
 	g_slist_free (list);
 }
 
@@ -2660,8 +2663,9 @@ style_list_get_style (GnmStyleList const *list, int col, int row)
 
 static void
 cb_find_link (GnmStyle *style,
-	      int corner_col, int corner_row, int width, int height,
-	      GnmRange const *apply_to, gpointer user)
+	      G_GNUC_UNUSED int corner_col, G_GNUC_UNUSED int corner_row, 
+	      G_GNUC_UNUSED int width, G_GNUC_UNUSED int height,
+	      G_GNUC_UNUSED GnmRange const *apply_to, gpointer user)
 {
 	GnmHLink **link = user;
 	if (*link == NULL)
@@ -2691,7 +2695,7 @@ sheet_style_region_contains_link (Sheet const *sheet, GnmRange const *r)
 }
 
 void
-sheet_style_foreach (Sheet const *sheet, GHFunc	func, gpointer user_data)
+sheet_style_foreach (Sheet const *sheet, GHFunc func, gpointer user_data)
 {
 	g_return_if_fail (IS_SHEET (sheet));
 	g_return_if_fail (sheet->style_data != NULL);
@@ -2699,6 +2703,72 @@ sheet_style_foreach (Sheet const *sheet, GHFunc	func, gpointer user_data)
 	sh_foreach (sheet->style_data->style_hash, func, user_data);
 }
 
+typedef struct {
+	gpointer user_data;
+	GHFunc func;
+} sheet_style_range_foreach_t;
+
+static gboolean
+cb_hash_to_cb (G_GNUC_UNUSED gpointer key, gpointer value, gpointer user_data)
+{
+	sheet_style_range_foreach_t *ud = user_data;
+	GnmStyleRegion *sr = value;
+
+	/* Already merged */
+	if (sr->range.start.col < 0) {
+		gnm_style_region_free (sr);
+		return TRUE;
+	}
+
+#ifdef DEBUG_STYLE_LIST
+	range_dump (&sr->range, "\n");
+#endif
+
+	ud->func (NULL, sr, ud->user_data);
+	gnm_style_region_free (sr);
+	return TRUE;
+
+}
+
+void
+sheet_style_range_foreach (Sheet const *sheet, GHFunc func, gpointer user_data, gboolean optimize)
+{
+	StyleListMerge mi;
+	GnmRange r;
+	sheet_style_range_foreach_t ud;
+
+	g_return_if_fail (IS_SHEET (sheet));
+
+	ud.user_data = user_data;
+	ud.func = func;
+	range_init_full_sheet (&r, sheet);
+
+	mi.style_equal = gnm_style_eq;
+	mi.cache = g_hash_table_new ((GHashFunc)&gnm_cellpos_hash,
+				     (GCompareFunc)&gnm_cellpos_equal);
+	mi.sheet = sheet;
+
+#ifdef DEBUG_STYLE_LIST
+	g_printerr ("====A====\n");
+#endif
+	foreach_tile (sheet->style_data->styles,
+		      sheet->tile_top_level, 0, 0, &r,
+		      cb_style_list_add_node, &mi);
+#ifdef DEBUG_STYLE_LIST
+	g_printerr ("====B====\n");
+#endif
+	if (optimize)
+		g_hash_table_foreach_remove (mi.cache, cb_hash_merge_horiz, &mi);
+#ifdef DEBUG_STYLE_LIST
+	g_printerr ("====C====\n");
+#endif
+	g_hash_table_foreach_remove (mi.cache, cb_hash_to_cb, &ud);
+#ifdef DEBUG_STYLE_LIST
+	g_printerr ("====D====\n");
+#endif
+	g_hash_table_destroy (mi.cache);
+}
+
 /* ------------------------------------------------------------------------- */
 
 static void
diff --git a/src/sheet-style.h b/src/sheet-style.h
index 2238765..5288045 100644
--- a/src/sheet-style.h
+++ b/src/sheet-style.h
@@ -56,6 +56,10 @@ GnmHLink *sheet_style_region_contains_link (Sheet const *sheet, GnmRange const *
 void	  sheet_style_foreach (Sheet const *sheet,
 			       GHFunc	    func,
 			       gpointer    user_data);
+void	  sheet_style_range_foreach (Sheet const *sheet,
+				     GHFunc	  func,
+				     gpointer     user_data,
+				     gboolean     optimize);
 
 GnmStyle **sheet_style_most_common (Sheet const *sheet, gboolean is_col);
 
@@ -85,6 +89,10 @@ GnmStyleList *sheet_style_collect_conditions	(Sheet const *s, GnmRange const *r)
 GnmStyleList *sheet_style_collect_hlinks	(Sheet const *s, GnmRange const *r);
 GnmStyleList *sheet_style_collect_validations	(Sheet const *s, GnmRange const *r);
 
+GnmStyleRegion *gnm_style_region_new (GnmRange const *range, GnmStyle *style);
+void gnm_style_region_free (GnmStyleRegion *sr);
+
+
 /* For internal use only */
 void	  sheet_style_unlink (Sheet *sheet, GnmStyle *st);
 



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