[gnumeric] Conditional styles: switch storage method.



commit c88d94c5368ffaa0303d3d864152831e17b78186
Author: Morten Welinder <terra gnome org>
Date:   Tue May 22 14:46:07 2012 -0400

    Conditional styles: switch storage method.
    
    We need to store pointers to records, not records.  This will be needed
    for later changes that use dependents for expressions -- linked dependents
    don't like to be moved around.

 plugins/excel/ms-excel-write.c        |   18 ++---
 plugins/openoffice/openoffice-write.c |   23 +++---
 src/dialogs/dialog-cell-format-cond.c |   12 +--
 src/style-conditions.c                |  134 ++++++++++++++++++++++-----------
 src/style-conditions.h                |   13 +++-
 src/xml-sax-write.c                   |    6 +-
 6 files changed, 128 insertions(+), 78 deletions(-)
---
diff --git a/plugins/excel/ms-excel-write.c b/plugins/excel/ms-excel-write.c
index 8671b2b..c499650 100644
--- a/plugins/excel/ms-excel-write.c
+++ b/plugins/excel/ms-excel-write.c
@@ -940,10 +940,8 @@ cb_write_condition (GnmStyleConditions const *sc, CondDetails *cd,
 	guint8 buf[14], type, op;
 	guint32 flags = 0x38C3FF;	/* these are always true */
 	unsigned i, expr0_len, expr1_len, header_pos;
-	GArray const *details = gnm_style_conditions_details (sc);
+	GPtrArray const *details = gnm_style_conditions_details (sc);
 	unsigned det_len = details ? details->len : 0;
-	GnmStyleCond const *cond;
-	GnmStyle const *s;
 
 	/* The parent record */
 	ms_biff_put_var_next (bp, BIFF_CONDFMT);
@@ -962,8 +960,8 @@ cb_write_condition (GnmStyleConditions const *sc, CondDetails *cd,
 
 	/* The individual conditions */
 	for (i = 0 ; i < det_len ; i++) {
-		cond = &g_array_index (details, GnmStyleCond, i);
-		s = cond->overlay;
+		GnmStyleCond const *cond = g_ptr_array_index (details, i);
+		GnmStyle const *s = cond->overlay;
 
 		ms_biff_put_var_next (bp, BIFF_CF);
 		header_pos = bp->curpos;
@@ -1497,8 +1495,7 @@ excel_write_prep_conditions (ExcelWriteSheet *esheet)
 {
 	GnmStyleList *ptr = esheet->conditions;
 	GnmStyleRegion const *sr;
-	GnmStyleCond const *cond;
-	GArray const *conds;
+	GPtrArray const *conds;
 	unsigned i;
 
 	for (; ptr != NULL ; ptr = ptr->next) {
@@ -1509,7 +1506,7 @@ excel_write_prep_conditions (ExcelWriteSheet *esheet)
 		conds = gnm_style_conditions_details (
 			gnm_style_get_conditions (sr->style));
 		for (i = 0 ; i < (conds ? conds->len : 0) ; i++) {
-			cond = &g_array_index (conds, GnmStyleCond, i);
+			GnmStyleCond const *cond = g_ptr_array_index (conds, i);
 			if (cond->texpr[0] != NULL)
 				excel_write_prep_expr (esheet->ewb, cond->texpr[0]);
 			if (cond->texpr[1] != NULL)
@@ -1813,10 +1810,11 @@ put_colors (ExcelStyleVariant const *esv, gpointer dummy, XLExportBase *ewb)
 	}
 	if (gnm_style_is_element_set (st, MSTYLE_CONDITIONS) &&
 	    NULL != gnm_style_get_conditions (st)) {
-		GArray const *conds = gnm_style_conditions_details (
+		GPtrArray const *conds = gnm_style_conditions_details (
 			gnm_style_get_conditions (st));
 		for (i = 0 ; i < (conds ? conds->len : 0) ; i++) {
-			st = g_array_index (conds, GnmStyleCond, i).overlay;
+			GnmStyleCond const *cond = g_ptr_array_index (conds, i);
+			st = cond->overlay;
 			if (gnm_style_is_element_set (st, MSTYLE_FONT_COLOR))
 				put_color_gnm (ewb, gnm_style_get_font_color (st));
 			if (gnm_style_is_element_set (st, MSTYLE_COLOR_BACK))
diff --git a/plugins/openoffice/openoffice-write.c b/plugins/openoffice/openoffice-write.c
index 2c42811..a5822a4 100644
--- a/plugins/openoffice/openoffice-write.c
+++ b/plugins/openoffice/openoffice-write.c
@@ -1656,7 +1656,7 @@ static void
 odf_write_style (GnmOOExport *state, GnmStyle const *style, GnmRange *r, gboolean is_default)
 {
 	GnmStyleConditions const *sc;
-	GArray const *conds;
+	GPtrArray const *conds;
 	guint i;
 
 	if ((!is_default) && gnm_style_is_element_set (style, MSTYLE_FORMAT)) {
@@ -1671,9 +1671,12 @@ odf_write_style (GnmOOExport *state, GnmStyle const *style, GnmRange *r, gboolea
 
 	if (gnm_style_is_element_set (style, MSTYLE_CONDITIONS) &&
 	    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), r);
+	    NULL != (conds = gnm_style_conditions_details (sc))) {
+		for (i = 0 ; i < conds->len ; i++) {
+			GnmStyleCond const *cond = g_ptr_array_index (conds, i);
+			odf_save_style_map (state, cond, 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 */
@@ -1793,12 +1796,12 @@ odf_store_this_named_style (GnmStyle *style, char const *name, GnmRange *r, GnmO
 
 	if (gnm_style_is_element_set (style, MSTYLE_CONDITIONS) &&
 	    NULL != (sc = gnm_style_get_conditions (style))) {
-		GArray const *conds = gnm_style_conditions_details (sc);
+		GPtrArray 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);
+				GnmStyleCond const *cond =
+					g_ptr_array_index (conds, i);
 				odf_store_this_named_style (cond->overlay, NULL, r, state);
 			}
 		}
@@ -1819,12 +1822,12 @@ odf_save_this_style (G_GNUC_UNUSED gconstpointer dummy, GnmStyleRegion *sr, GnmO
 
 	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);
+		GPtrArray 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);
+				GnmStyleCond const *cond =
+					g_ptr_array_index (conds, i);
 				odf_store_this_named_style (cond->overlay, NULL, &sr->range, state);
 			}
 		}
diff --git a/src/dialogs/dialog-cell-format-cond.c b/src/dialogs/dialog-cell-format-cond.c
index 9cc4bfa..51f83f9 100644
--- a/src/dialogs/dialog-cell-format-cond.c
+++ b/src/dialogs/dialog-cell-format-cond.c
@@ -418,10 +418,10 @@ cb_c_fmt_dialog_copy_button (G_GNUC_UNUSED GtkWidget *btn, CFormatState *state)
 		GtkTreePath *path = gtk_tree_model_get_path
 			(GTK_TREE_MODEL (state->model), &iter);
 		gint *pind = gtk_tree_path_get_indices (path);
-		GArray const *conds = gnm_style_conditions_details (sc);
+		GPtrArray const *conds = gnm_style_conditions_details (sc);
 		if (pind && conds) {
 			gint ind = *pind;
-			GnmStyleCond *gsc = &g_array_index (conds, GnmStyleCond, ind);
+			GnmStyleCond *gsc = g_ptr_array_index (conds, ind);
 			GtkTreeIter iter;
 			GnmParsePos pp;
 			GnmStyle   *style;
@@ -809,7 +809,7 @@ c_fmt_dialog_conditions_page_load_cond_double_f (CFormatState *state,
 
 static void
 c_fmt_dialog_conditions_page_load_cond (CFormatState *state, GnmStyleCond const *cond,
-				      GtkTreeIter *iter)
+					GtkTreeIter *iter)
 {
 	GtkTreeIter iter1;
 
@@ -975,7 +975,7 @@ static void
 c_fmt_dialog_conditions_page_load_conditions (GnmStyle *style, char const *range, CFormatState *state)
 {
 	GnmStyleConditions const *sc;
-	GArray const *conds;
+	GPtrArray const *conds;
 	guint i;
 	GtkTreeIter iter1, *iter;
 
@@ -993,9 +993,7 @@ c_fmt_dialog_conditions_page_load_conditions (GnmStyle *style, char const *range
 		}
 		for (i = 0 ; i < conds->len ; i++)
 			c_fmt_dialog_conditions_page_load_cond
-				(state, &g_array_index (conds,
-							GnmStyleCond,
-							i), iter);
+				(state, g_ptr_array_index (conds, i), iter);
 	}
 
 }
diff --git a/src/style-conditions.c b/src/style-conditions.c
index f905b8d..07e9e7d 100644
--- a/src/style-conditions.c
+++ b/src/style-conditions.c
@@ -39,7 +39,7 @@
 typedef GObjectClass GnmStyleConditionsClass;
 struct _GnmStyleConditions {
 	GObject base;
-	GArray *conditions;
+	GPtrArray *conditions;
 };
 
 static GObjectClass *parent_class;
@@ -68,16 +68,58 @@ gnm_style_cond_is_valid (GnmStyleCond const *cond)
 	return TRUE;
 }
 
-static void
-cond_unref (GnmStyleCond const *cond)
+GnmStyleCond *
+gnm_style_cond_new (GnmStyleCondOp op, GnmStyle *overlay)
+{
+	GnmStyleCond *res = g_new0 (GnmStyleCond, 1);
+	res->op = op;
+	gnm_style_ref ((res->overlay = overlay));
+	return res;
+}
+
+GnmStyleCond *
+gnm_style_cond_dup (GnmStyleCond const *src)
 {
+	GnmStyleCond *dst;
+	unsigned ui;
+
+	g_return_val_if_fail (src != NULL, NULL);
+
+	dst = gnm_style_cond_new (src->op, src->overlay);
+	for (ui = 0; ui < 2; ui++)
+		gnm_style_cond_set_expr (dst, src->texpr[ui], ui);
+
+	return dst;
+}
+
+void
+gnm_style_cond_free (GnmStyleCond *cond)
+{
+	unsigned ui;
+
+	g_return_if_fail (cond != NULL);
+
 	/* Be very delicate, this is called for invalid conditions too */
 	if (cond->overlay)
 		gnm_style_unref (cond->overlay);
-	if (cond->texpr[0])
-		gnm_expr_top_unref (cond->texpr[0]);
-	if (cond->texpr[1])
-		gnm_expr_top_unref (cond->texpr[1]);
+	for (ui = 0; ui < 2; ui++)
+		if (cond->texpr[ui])
+			gnm_expr_top_unref (cond->texpr[ui]);
+
+	g_free (cond);
+}
+
+void
+gnm_style_cond_set_expr (GnmStyleCond *cond,
+			 GnmExprTop const *texpr,
+			 unsigned idx)
+{
+	g_return_if_fail (cond != NULL);
+	g_return_if_fail (idx < G_N_ELEMENTS (cond->texpr));
+
+	if (texpr) gnm_expr_top_ref (texpr);
+	if (cond->texpr[idx]) gnm_expr_top_unref (cond->texpr[idx]);
+	cond->texpr[idx] = texpr;
 }
 
 static void
@@ -85,15 +127,11 @@ gnm_style_conditions_finalize (GObject *obj)
 {
 	GnmStyleConditions *sc = (GnmStyleConditions *)obj;
 
-	if (sc->conditions != NULL) {
-		int i = sc->conditions->len;
-		while (i-- > 0)
-			cond_unref (&g_array_index (sc->conditions, GnmStyleCond, i));
-		g_array_free (sc->conditions, TRUE);
-		sc->conditions = NULL;
-	}
+	while (sc->conditions)
+		gnm_style_conditions_delete (sc, sc->conditions->len - 1);
 	G_OBJECT_CLASS (parent_class)->finalize (obj);
 }
+
 static void
 gnm_style_conditions_init (GnmStyleConditions *sc)
 {
@@ -126,26 +164,19 @@ gnm_style_conditions_new (void)
 GnmStyleConditions *
 gnm_style_conditions_dup  (GnmStyleConditions const *cond)
 {
-	GnmStyleConditions  *dup;
-	GArray const *ga;
+	GnmStyleConditions *dup;
+	GPtrArray const *ga;
 	if (cond == NULL)
 		return NULL;
 
-	dup =  gnm_style_conditions_new ();
+	dup = gnm_style_conditions_new ();
 	ga = gnm_style_conditions_details (cond);
 	if (ga != NULL) {
 		guint i;
-		GArray *ga_dup = g_array_sized_new (FALSE, FALSE, sizeof (GnmStyleCond),
-						    ga->len);
+		GPtrArray *ga_dup = g_ptr_array_sized_new (ga->len);
 		for (i = 0; i < ga->len; i++) {
-			GnmStyleCond gsc = g_array_index(ga, GnmStyleCond, i);
-
-			gnm_style_ref (gsc.overlay);
-			if (gsc.texpr[0])
-				gnm_expr_top_ref (gsc.texpr[0]);
-			if (gsc.texpr[1])
-				gnm_expr_top_ref (gsc.texpr[1]);
-			g_array_append_val (ga_dup, gsc);
+			GnmStyleCond *cond = g_ptr_array_index (ga, i);
+			g_ptr_array_add (ga_dup, gnm_style_cond_dup (cond));
 		}
 		dup->conditions = ga_dup;
 	}
@@ -159,7 +190,7 @@ gnm_style_conditions_dup  (GnmStyleConditions const *cond)
  *
  * Returns an array of GnmStyleCond which should not be modified.
  **/
-GArray const	*
+GPtrArray const *
 gnm_style_conditions_details (GnmStyleConditions const *sc)
 {
 	g_return_val_if_fail (sc != NULL, NULL);
@@ -177,22 +208,32 @@ gnm_style_conditions_details (GnmStyleConditions const *sc)
  **/
 void
 gnm_style_conditions_insert (GnmStyleConditions *sc,
-			     GnmStyleCond const *cond, int pos)
+			     GnmStyleCond const *cond_, int pos)
 {
-	g_return_if_fail (cond != NULL);
+	GnmStyleCond *cond;
+
+	g_return_if_fail (cond_ != NULL);
 
+	cond = g_memdup (cond_, sizeof (*cond_));
 	if (sc == NULL || !gnm_style_cond_is_valid (cond)) {
-		cond_unref (cond); /* be careful not to leak */
+		gnm_style_cond_free (cond); /* be careful not to leak */
 		return;
 	}
 
 	if (sc->conditions == NULL)
-		sc->conditions = g_array_new (FALSE, FALSE, sizeof (GnmStyleCond));
-
-	if (pos < 0)
-		g_array_append_val (sc->conditions, *cond);
-	else
-		g_array_insert_val (sc->conditions, pos, *cond);
+		sc->conditions = g_ptr_array_new ();
+
+	g_ptr_array_add (sc->conditions, cond);
+	if (pos >= 0) {
+		int i;
+
+		for (i = sc->conditions->len - 1;
+		     i > pos;
+		     i--)
+			g_ptr_array_index (sc->conditions, i) =
+				g_ptr_array_index (sc->conditions, i - 1);
+		g_ptr_array_index (sc->conditions, pos) = cond;
+	}
 }
 
 void
@@ -203,8 +244,12 @@ gnm_style_conditions_delete  (GnmStyleConditions *sc,
 	g_return_if_fail (sc->conditions != NULL);
 	g_return_if_fail (sc->conditions->len > pos);
 
-	cond_unref (&g_array_index (sc->conditions, GnmStyleCond, pos));
-	g_array_remove_index (sc->conditions, pos);
+	gnm_style_cond_free (g_ptr_array_index (sc->conditions, pos));
+	if (sc->conditions->len <= 1) {
+		g_ptr_array_free (sc->conditions, TRUE);
+		sc->conditions = NULL;
+	} else
+		g_ptr_array_remove_index (sc->conditions, pos);
 }
 
 
@@ -213,8 +258,6 @@ gnm_style_conditions_overlay (GnmStyleConditions const *sc,
 			      GnmStyle const *base)
 {
 	GPtrArray *res;
-	GnmStyle const *overlay;
-	GnmStyle *merge;
 	unsigned i;
 
 	g_return_val_if_fail (sc != NULL, NULL);
@@ -222,8 +265,10 @@ gnm_style_conditions_overlay (GnmStyleConditions const *sc,
 
 	res = g_ptr_array_sized_new (sc->conditions->len);
 	for (i = 0 ; i < sc->conditions->len; i++) {
-		overlay = g_array_index (sc->conditions, GnmStyleCond, i).overlay;
-		merge = gnm_style_new_merged (base, overlay);
+		GnmStyleCond const *cond =
+			g_ptr_array_index (sc->conditions, i);
+		GnmStyle const *overlay = cond->overlay;
+		GnmStyle *merge = gnm_style_new_merged (base, overlay);
 		/* We only draw a background colour is the pattern != 0 */
 		if (merge->pattern == 0 &&
 		     elem_is_set (overlay, MSTYLE_COLOR_BACK) &&
@@ -247,8 +292,7 @@ gnm_style_conditions_eval (GnmStyleConditions const *sc, GnmEvalPos const *ep)
 	unsigned i;
 	gboolean use_this = FALSE;
 	GnmValue *val = NULL;
-	GArray const *conds;
-	GnmStyleCond const *cond;
+	GPtrArray const *conds;
 	GnmParsePos pp;
 	GnmCell const *cell = sheet_cell_get (ep->sheet, ep->eval.col, ep->eval.row);
 	GnmValue const *cv = cell ? cell->value : NULL;
@@ -260,7 +304,7 @@ gnm_style_conditions_eval (GnmStyleConditions const *sc, GnmEvalPos const *ep)
 	conds = sc->conditions;
 	parse_pos_init_evalpos (&pp, ep);
 	for (i = 0 ; i < conds->len ; i++) {
-		cond = &g_array_index (conds, GnmStyleCond, i);
+		GnmStyleCond const *cond = g_ptr_array_index (conds, i);
 
 		if (cond->op == GNM_STYLE_COND_CONTAINS_ERR)
 			use_this = (cv != NULL) && VALUE_IS_ERROR (cv);
diff --git a/src/style-conditions.h b/src/style-conditions.h
index d6d533d6..aeb5c6e 100644
--- a/src/style-conditions.h
+++ b/src/style-conditions.h
@@ -42,9 +42,18 @@ typedef struct {
 	GnmStyleCondOp	  op;
 } GnmStyleCond;
 
+GnmStyleCond *gnm_style_cond_new (GnmStyleCondOp op,
+				  GnmStyle *overlay);
+void gnm_style_cond_free (GnmStyleCond *cond);
+GnmStyleCond *gnm_style_cond_dup (GnmStyleCond const *src);
+gboolean      gnm_style_cond_is_valid (GnmStyleCond const *cond);
+void          gnm_style_cond_set_expr (GnmStyleCond *cond,
+				       GnmExprTop const *texpr,
+				       unsigned idx);
+
 GnmStyleConditions *gnm_style_conditions_new  (void);
 GnmStyleConditions *gnm_style_conditions_dup  (GnmStyleConditions const *cond);
-GArray const *gnm_style_conditions_details (GnmStyleConditions const *sc);
+GPtrArray const *gnm_style_conditions_details (GnmStyleConditions const *sc);
 void	      gnm_style_conditions_insert  (GnmStyleConditions *sc,
 					    GnmStyleCond const *cond,
 					    int pos);
@@ -55,8 +64,6 @@ GPtrArray    *gnm_style_conditions_overlay (GnmStyleConditions const *sc,
 int	      gnm_style_conditions_eval    (GnmStyleConditions const *sc,
 					    GnmEvalPos const *pos);
 
-gboolean      gnm_style_cond_is_valid (GnmStyleCond const *cond);
-
 G_END_DECLS
 
 #endif /* _GNM_STYLE_CONDITIONS_H_ */
diff --git a/src/xml-sax-write.c b/src/xml-sax-write.c
index a0c6f44..0eff911 100644
--- a/src/xml-sax-write.c
+++ b/src/xml-sax-write.c
@@ -453,7 +453,6 @@ xml_write_style (GnmOutputXML *state, GnmStyle const *style)
 	GnmHLink   const *link;
 	GnmInputMsg const *im;
 	GnmStyleConditions const *sc;
-	GnmStyleCond const *cond;
 	GnmStyleBorderType t;
 	unsigned i;
 	gboolean started;
@@ -605,14 +604,15 @@ xml_write_style (GnmOutputXML *state, GnmStyle const *style)
 
 	if (gnm_style_is_element_set (style, MSTYLE_CONDITIONS) &&
 	    NULL != (sc = gnm_style_get_conditions (style))) {
-		GArray const *conds = gnm_style_conditions_details (sc);
+		GPtrArray const *conds = gnm_style_conditions_details (sc);
 		if (conds != NULL) {
 			char *tmp;
 			GnmParsePos pp;
 			parse_pos_init_sheet (&pp, (Sheet *)state->sheet);
 
 			for (i = 0 ; i < conds->len ; i++) {
-				cond = &g_array_index (conds, GnmStyleCond, i);
+				GnmStyleCond const *cond =
+					g_ptr_array_index (conds, i);
 				gsf_xml_out_start_element (state->output, GNM "Condition");
 				gsf_xml_out_add_int (state->output, "Operator", cond->op);
 				if (cond->texpr[0] != NULL &&



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