[gnumeric] scenarios: starts making a sane api.



commit 189f913a9a20b1fb3c66421631b91cc1d1a7cd92
Author: Morten Welinder <terra gnome org>
Date:   Tue Nov 24 15:40:34 2009 -0500

    scenarios: starts making a sane api.

 src/sheet.c           |    2 +-
 src/tools/scenarios.c |  141 +++++++++++++++++++++++++++++++++++++++++-------
 src/tools/scenarios.h |   27 +++++++--
 3 files changed, 142 insertions(+), 28 deletions(-)
---
diff --git a/src/sheet.c b/src/sheet.c
index f269bb4..e595187 100644
--- a/src/sheet.c
+++ b/src/sheet.c
@@ -5822,7 +5822,7 @@ gnm_sheet_scenario_new (Sheet *sheet, const char *name)
 	} else
 		actual_name = g_strdup (name);
 
-	sc = gnm_scenario_new (actual_name, NULL, sheet);
+	sc = gnm_scenario_new (actual_name, sheet);
 
 	g_free (actual_name);
 
diff --git a/src/tools/scenarios.c b/src/tools/scenarios.c
index 5074a37..601da80 100644
--- a/src/tools/scenarios.c
+++ b/src/tools/scenarios.c
@@ -2,9 +2,6 @@
 /*
  * scenarios.c:
  *
- * Author:
- *        Jukka-Pekka Iivonen <jiivonen hutcs cs hut fi>
- *
  * (C) Copyright 2003 by Jukka-Pekka Iivonen <jiivonen hutcs cs hut fi>
  * (C) Copyright 2009 by Morten Welinder <terra gnome org>
  *
@@ -29,17 +26,14 @@
 #include <gsf/gsf-impl-utils.h>
 
 #include <sheet.h>
-#include <sheet-filter.h>
 #include <cell.h>
 #include <ranges.h>
 #include <value.h>
 #include <workbook.h>
-#include <workbook-control.h>
+#include <expr.h>
 
-#include "mathfunc.h"
 #include "scenarios.h"
 #include "dao.h"
-#include "style-color.h"
 #include "parse-util.h"
 #include <goffice/goffice.h>
 
@@ -47,6 +41,44 @@
 
 /* ------------------------------------------------------------------------- */
 
+GnmScenarioItem *
+gnm_scenario_item_new (Sheet *sheet)
+{
+	GnmScenarioItem *sci = g_new0 (GnmScenarioItem, 1);
+	dependent_managed_init (&sci->dep, sheet);
+	return sci;
+}
+
+void
+gnm_scenario_item_free (GnmScenarioItem *sci)
+{
+	gnm_scenario_item_set_range (sci, NULL);
+	gnm_scenario_item_set_value (sci, NULL);
+	g_free (sci);
+}
+
+void
+gnm_scenario_item_set_range (GnmScenarioItem *sci, const GnmSheetRange *sr)
+{
+	if (sr) {
+		GnmValue *v = value_new_cellrange_r (sr->sheet,
+						     &sr->range);
+		GnmExprTop const *texpr = gnm_expr_top_new_constant (v);
+		dependent_managed_set_expr (&sci->dep, texpr);
+		gnm_expr_top_unref (texpr);
+	} else
+		dependent_managed_set_expr (&sci->dep, NULL);
+}
+
+void
+gnm_scenario_item_set_value (GnmScenarioItem *sci, const GnmValue *v)
+{
+	value_release (sci->value);
+	sci->value = value_dup (v);
+}
+
+/* ------------------------------------------------------------------------- */
+
 typedef GnmValue * (*ScenarioValueCB) (int col, int row, GnmValue *v, gpointer data);
 
 static void
@@ -85,6 +117,8 @@ gnm_scenario_finalize (GObject *obj)
 	g_free (sc->name);
 	g_free (sc->comment);
 
+	go_slist_free_custom (sc->items, (GFreeFunc)gnm_scenario_item_free);
+
 	g_free (sc->cell_sel_str);
 
 	scenario_for_each_value (sc, cb_value_free, NULL);
@@ -94,28 +128,92 @@ gnm_scenario_finalize (GObject *obj)
 	gnm_scenario_parent_class->finalize (obj);
 }
 
+static void
+gnm_scenario_class_init (GObjectClass *object_class)
+{
+	gnm_scenario_parent_class = g_type_class_peek_parent (object_class);
+
+	object_class->finalize = gnm_scenario_finalize;
+}
+
+GSF_CLASS (GnmScenario, gnm_scenario,
+	   &gnm_scenario_class_init, NULL, G_TYPE_OBJECT)
+
 GnmScenario *
-gnm_scenario_new (char const *name, char const *comment, Sheet *sheet)
+gnm_scenario_new (char const *name, Sheet *sheet)
 {
 	GnmScenario *sc = g_object_new (GNM_SCENARIO_TYPE, NULL);
 
 	sc->sheet = sheet;
 	sc->name = g_strdup (name);
-	sc->comment = g_strdup (comment);
 
 	return sc;
 }
 
-static void
-gnm_scenario_class_init (GObjectClass *object_class)
+void
+gnm_scenario_set_comment (GnmScenario *sc, const char *comment)
 {
-	gnm_scenario_parent_class = g_type_class_peek_parent (object_class);
+	char *s = g_strdup (comment);
+	g_free (sc->comment);
+	sc->comment = s;
+}
 
-	object_class->finalize = gnm_scenario_finalize;
+struct cb_save_cells {
+	GSList *items;
+	GnmScenario *sc;
+};
+
+static GnmValue *
+cb_save_cells (GnmCellIter const *iter, gpointer user)
+{
+	struct cb_save_cells *pdata = user;
+	GnmCell *cell = iter->cell;
+	GnmScenarioItem *sci = gnm_scenario_item_new (pdata->sc->sheet);
+	GnmSheetRange sr;
+
+	/* FIXME: Think about arrays.  */
+
+	sr.sheet = cell->base.sheet;
+	sr.range.start = sr.range.end = iter->pp.eval;
+	gnm_scenario_item_set_range (sci, &sr);
+	gnm_scenario_item_set_value (sci, cell->value);
+
+	pdata->items = g_slist_prepend (pdata->items, sci);
+
+	return NULL;
 }
 
-GSF_CLASS (GnmScenario, gnm_scenario,
-	   &gnm_scenario_class_init, NULL, G_TYPE_OBJECT)
+
+void
+gnm_scenario_add_area (GnmScenario *sc, const GnmSheetRange *sr,
+		       gboolean add_content)
+{
+	GnmScenarioItem *sci;
+	GnmSheetRange sr2;
+
+	g_return_if_fail (GNM_IS_SCENARIO (sc));
+	g_return_if_fail (sr != NULL);
+
+	sr2 = *sr;
+	if (!sr2.sheet)
+		sr2.sheet = sc->sheet;
+	sci = gnm_scenario_item_new (sc->sheet);
+	gnm_scenario_item_set_range (sci, &sr2);
+	sc->items = g_slist_prepend (sc->items, sci);
+
+	if (add_content) {
+		struct cb_save_cells data;
+		data.items = NULL;
+		data.sc = sc;
+		sheet_foreach_cell_in_range
+			(sr2.sheet, CELL_ITER_IGNORE_NONEXISTENT,
+			 sr2.range.start.col, sr2.range.start.row,
+			 sr2.range.end.col, sr2.range.end.row,
+			 cb_save_cells, &data);
+		sc->items = g_slist_concat (sc->items,
+					    g_slist_reverse (data.items));
+	}
+}
 
 /* ------------------------------------------------------------------------- */
 
@@ -169,7 +267,7 @@ scenario_add_new (gchar const *name,
 	GnmScenario *scenario = gnm_sheet_scenario_new (sheet, name);
 	gboolean    res = collect_values (sheet, scenario, (GnmValueRange *) changing_cells);
 
-	scenario->comment = g_strdup (comment);
+	gnm_scenario_set_comment (scenario, comment);
 	scenario->cell_sel_str = g_strdup (cell_sel_str);
 	sheet_redraw_all (sheet, TRUE);
 
@@ -203,7 +301,8 @@ gnm_scenario_dup (GnmScenario *src, Sheet *new_sheet)
 	GnmScenario *dst;
 	copy_cb_t  cb;
 
-	dst = gnm_scenario_new (src->name, src->comment, new_sheet);
+	dst = gnm_scenario_new (src->name, new_sheet);
+	gnm_scenario_set_comment (dst, src->comment);
 	dst->cell_sel_str = g_strdup (src->cell_sel_str);
 	dst->range = src->range;
 
@@ -247,20 +346,20 @@ scenario_show (GnmScenario             *s,
 		return NULL;
 
 	/* Store values for recovery. */
-	stored_values = gnm_sheet_scenario_new (s->sheet, "");
+	stored_values = gnm_sheet_scenario_new (dao->sheet, "");
 	stored_values->range = s->range;
 	rows = s->range.end.row - s->range.start.row + 1;
 	cols = s->range.end.col - s->range.start.col + 1;
 	stored_values->changing_cells = g_new (GnmValue *, rows * cols);
 
-	cb.sheet = s->sheet;
+	cb.sheet = dao->sheet;
 	scenario_for_each_value (stored_values, (ScenarioValueCB) collect_cb,
 				 &cb);
 
 	/* Show scenario and recalculate. */
 	scenario_for_each_value (s, (ScenarioValueCB) show_cb, dao);
-	workbook_recalc (s->sheet->workbook);
-	sheet_redraw_all (s->sheet, TRUE);
+	workbook_recalc (dao->sheet->workbook);
+	sheet_redraw_all (dao->sheet, TRUE);
 
 	return stored_values;
 }
diff --git a/src/tools/scenarios.h b/src/tools/scenarios.h
index be4b64a..cb31293 100644
--- a/src/tools/scenarios.h
+++ b/src/tools/scenarios.h
@@ -6,6 +6,20 @@
 
 /* ------------------------------------------------------------------------- */
 
+typedef struct {
+	GnmDependent dep;
+	GnmValue *value;
+} GnmScenarioItem;
+
+GnmScenarioItem *gnm_scenario_item_new (Sheet *sheet);
+void gnm_scenario_item_free (GnmScenarioItem *sci);
+void gnm_scenario_item_set_range (GnmScenarioItem *sci,
+				  const GnmSheetRange *sr);
+void gnm_scenario_item_set_value (GnmScenarioItem *sci,
+				  const GnmValue *v);
+
+/* ------------------------------------------------------------------------- */
+
 #define GNM_SCENARIO_TYPE        (gnm_scenario_get_type ())
 #define GNM_SCENARIO(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), GNM_SCENARIO_TYPE, GnmScenario))
 #define GNM_SCENARIO_CLASS(k)    (G_TYPE_CHECK_CLASS_CAST ((k), GNM_SCENARIO_TYPE, GnmScenarioClass))
@@ -18,6 +32,8 @@ struct GnmScenario_ {
         char *name;
         char *comment;
 
+	GSList *items;
+
         GnmValue **changing_cells;
         GnmRange  range;
 
@@ -30,23 +46,22 @@ typedef struct {
 
 GType gnm_scenario_get_type (void);
 
-GnmScenario *gnm_scenario_new (char const *name, char const *comment,
-			       Sheet *sheet);
+GnmScenario *gnm_scenario_new (char const *name, Sheet *sheet);
 
 GnmScenario *gnm_scenario_dup (GnmScenario *s, Sheet *new_sheet);
 
-/* ------------------------------------------------------------------------- */
+void gnm_scenario_set_comment (GnmScenario *sc, const char *comment);
 
+void gnm_scenario_add_area (GnmScenario *sc, const GnmSheetRange *sr,
+			    gboolean add_content);
 
+/* ------------------------------------------------------------------------- */
 
 typedef struct _scenario_cmd_t {
         GnmScenario *redo;
         GnmScenario *undo;
 } scenario_cmd_t;
 
-GnmScenario *scenario_by_name      (GList *scenarios, const gchar *name,
-				   gboolean *all_deleted);
-
 GnmScenario *scenario_show         (GnmScenario             *scenario,
 				    GnmScenario             *old_values,
 				    data_analysis_output_t *dao);



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