[gnumeric] Calculation: improve inter-workbook calculations.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Calculation: improve inter-workbook calculations.
- Date: Mon, 30 Jul 2012 18:52:14 +0000 (UTC)
commit 82d8f0699aac95c4ddad25752f04648d0fd46a04
Author: Morten Welinder <terra gnome org>
Date: Mon Jul 30 14:49:11 2012 -0400
Calculation: improve inter-workbook calculations.
This introduces gnm_app_recalc -- about time, eh? -- that updates all
workbooks which are set for automatic recalculation by recalculating
dirty dependents and triggering the necessary redraw.
Since we already dirty across workbooks, this cause inter-workbook
calculations to start behaving sanely. I hope.
ChangeLog | 6 ++++++
NEWS | 1 +
plugins/glpk/glpk-write.c | 4 +++-
plugins/lpsolve/lpsolve-write.c | 4 +++-
plugins/mps/mps.c | 4 +---
plugins/nlsolve/gnm-nlsolve.c | 3 ++-
plugins/sample_datasource/sample_datasource.c | 4 ++--
src/application.c | 25 +++++++++++++++++++++++++
src/application.h | 1 +
src/commands.c | 16 +++-------------
src/dependent.c | 8 +++++++-
src/dialogs/dialog-goal-seek.c | 10 +++++++---
src/dialogs/dialog-solver.c | 3 ++-
src/ssconvert.c | 4 ++--
src/ssgrep.c | 4 ++--
src/sstest.c | 4 ++++
src/tools/tabulate.c | 3 ++-
17 files changed, 73 insertions(+), 31 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index f94392b..bbc3f11 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2012-07-30 Morten Welinder <terra gnome org>
+
+ * src/application.c (gnm_app_recalc): New function. (After almost
+ 15 years we get this?) Most calls to workbook_recalc redirected
+ to this.
+
2012-07-28 Morten Welinder <terra gnome org>
* src/dependent.h (GnmDependentClass): Add new "changed" method
diff --git a/NEWS b/NEWS
index cd9f800..7eb164d 100644
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,7 @@ Morten:
* Dependents code cleanups.
* Make cells regular dependents.
* Fix non-linear solver crash. [#680719]
+ * Improve inter-workbook recalculations.
--------------------------------------------------------------------------
Gnumeric 1.11.5
diff --git a/plugins/glpk/glpk-write.c b/plugins/glpk/glpk-write.c
index 4582373..aabf46d 100644
--- a/plugins/glpk/glpk-write.c
+++ b/plugins/glpk/glpk-write.c
@@ -22,6 +22,7 @@
#include <workbook-view.h>
#include <sheet.h>
#include <workbook.h>
+#include <application.h>
#include <value.h>
#include <cell.h>
#include <expr.h>
@@ -42,6 +43,7 @@ gnm_solver_get_lp_coeff (GnmCell *target, GnmCell *cell,
gnm_float x0, x1;
gboolean res = FALSE;
+ gnm_cell_eval (target);
if (!VALUE_IS_NUMBER (target->value))
goto fail;
x0 = value_get_as_float (target->value);
@@ -355,7 +357,7 @@ glpk_file_save (GOFileSaver const *fs, GOIOContext *io_context,
prg = glpk_create_program (sheet, io_context, ssol, &err);
gnm_pop_C_locale (locale);
- workbook_recalc (sheet->workbook);
+ gnm_app_recalc ();
if (!prg) {
go_cmd_context_error_import (GO_CMD_CONTEXT (io_context),
diff --git a/plugins/lpsolve/lpsolve-write.c b/plugins/lpsolve/lpsolve-write.c
index ef1c5b5..94c81db 100644
--- a/plugins/lpsolve/lpsolve-write.c
+++ b/plugins/lpsolve/lpsolve-write.c
@@ -20,6 +20,7 @@
#include <boot.h>
#include <numbers.h>
#include <workbook-view.h>
+#include <application.h>
#include <sheet.h>
#include <workbook.h>
#include <value.h>
@@ -42,6 +43,7 @@ gnm_solver_get_lp_coeff (GnmCell *target, GnmCell *cell,
gnm_float x0, x1;
gboolean res = FALSE;
+ gnm_cell_eval (target);
if (!VALUE_IS_NUMBER (target->value))
goto fail;
x0 = value_get_as_float (target->value);
@@ -338,7 +340,7 @@ lpsolve_file_save (GOFileSaver const *fs, GOIOContext *io_context,
prg = lpsolve_create_program (sheet, io_context, ssol, &err);
gnm_pop_C_locale (locale);
- workbook_recalc (sheet->workbook);
+ gnm_app_recalc ();
if (!prg) {
go_cmd_context_error_import (GO_CMD_CONTEXT (io_context),
diff --git a/plugins/mps/mps.c b/plugins/mps/mps.c
index 55d5ede..9a9d499 100644
--- a/plugins/mps/mps.c
+++ b/plugins/mps/mps.c
@@ -724,9 +724,7 @@ mps_file_open (GOFileOpener const *fo, GOIOContext *io_context,
(_("Error while reading MPS file.")));
} else {
mps_fill_sheet (&state);
-
- workbook_queue_all_recalc (state.wb);
- workbook_recalc (state.wb);
+ workbook_recalc_all (state.wb);
}
g_hash_table_destroy (state.row_hash);
diff --git a/plugins/nlsolve/gnm-nlsolve.c b/plugins/nlsolve/gnm-nlsolve.c
index ac061ed..6d9d5fe 100644
--- a/plugins/nlsolve/gnm-nlsolve.c
+++ b/plugins/nlsolve/gnm-nlsolve.c
@@ -7,6 +7,7 @@
#include "regression.h"
#include "rangefunc.h"
#include "workbook.h"
+#include "application.h"
#include <gsf/gsf-impl-utils.h>
#include <glib/gi18n-lib.h>
#include <string.h>
@@ -696,7 +697,7 @@ gnm_nlsolve_idle (gpointer data)
if (!call_again) {
set_vector (nl, nl->x0);
- workbook_recalc (sol->params->sheet->workbook);
+ gnm_app_recalc ();
rosenbrock_shutdown (nl);
}
diff --git a/plugins/sample_datasource/sample_datasource.c b/plugins/sample_datasource/sample_datasource.c
index 70927cc..32a20d3 100644
--- a/plugins/sample_datasource/sample_datasource.c
+++ b/plugins/sample_datasource/sample_datasource.c
@@ -25,6 +25,7 @@
#include "func.h"
#include "value.h"
#include "workbook.h"
+#include "application.h"
#include "sheet.h"
#include "gutils.h"
#include "gnm-i18n.h"
@@ -103,8 +104,7 @@ cb_watcher_queue_recalc (gpointer key, gpointer value, gpointer closure)
Sheet *sheet = w->dep->sheet;
dependent_queue_recalc (w->dep);
- if (sheet && workbook_get_recalcmode (sheet->workbook))
- workbook_recalc (sheet->workbook);
+ gnm_app_recalc ();
}
static gboolean
diff --git a/src/application.c b/src/application.c
index fab6875..b2ff9a2 100644
--- a/src/application.c
+++ b/src/application.c
@@ -946,6 +946,31 @@ _gnm_app_flag_windows_changed (void)
/**********************************************************************/
+/**
+ * gnm_app_recalc:
+ *
+ * Recalculate everything dirty in all workbooks that have automatic
+ * recalc turned on.
+ **/
+void
+gnm_app_recalc (void)
+{
+ GList *l;
+
+ g_return_if_fail (app != NULL);
+
+ gnm_app_recalc_start ();
+
+ for (l = app->workbook_list; l; l = l->next) {
+ Workbook *wb = l->data;
+
+ if (workbook_get_recalcmode (wb))
+ workbook_recalc (wb);
+ }
+
+ gnm_app_recalc_finish ();
+}
+
void
gnm_app_recalc_start (void)
{
diff --git a/src/application.h b/src/application.h
index e59b725..2b1abfe 100644
--- a/src/application.h
+++ b/src/application.h
@@ -24,6 +24,7 @@ Workbook *gnm_app_workbook_get_by_index (int i);
GSList *gnm_app_history_get_list (int max_elements);
void gnm_app_history_add (char const *filename, const char *mimetype);
+void gnm_app_recalc (void);
void gnm_app_recalc_start (void);
void gnm_app_recalc_finish (void);
void gnm_app_recalc_clear_caches (void);
diff --git a/src/commands.c b/src/commands.c
index 9e8a6d6..60f7625 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -109,7 +109,7 @@
* events. None of the internal utility routines should do so. Those are
* expensive events and should only be done once per command to avoid
* duplicating work. The lower levels can queue redraws if they must, and
- * flag state changes but the call to workbook_recalc and sheet_update is
+ * flag state changes but the call to gnm_app_recalc and sheet_update is
* by GnmCommand.
*
* FIXME: Filter the list of commands when a sheet is deleted.
@@ -339,12 +339,12 @@ undo_redo_menu_labels (Workbook *wb)
static void
update_after_action (Sheet *sheet, WorkbookControl *wbc)
{
+ gnm_app_recalc ();
+
if (sheet != NULL) {
g_return_if_fail (IS_SHEET (sheet));
sheet_mark_dirty (sheet);
- if (workbook_get_recalcmode (sheet->workbook))
- workbook_recalc (sheet->workbook);
sheet_update (sheet);
if (sheet->workbook == wb_control_get_workbook (wbc))
@@ -2620,16 +2620,10 @@ cmd_paste_cut_update (GnmExprRelocateInfo const *info,
/* Dirty and update both sheets */
sheet_mark_dirty (t);
- if (workbook_get_recalcmode (t->workbook))
- workbook_recalc (t->workbook);
sheet_update (t);
if (IS_SHEET (o) && o != t) {
sheet_mark_dirty (o);
- if (o->workbook != t->workbook) {
- if (workbook_get_recalcmode (o->workbook))
- workbook_recalc (o->workbook);
- }
sheet_update (o);
}
}
@@ -5255,7 +5249,6 @@ cmd_analysis_tool_undo (GnmCommand *cmd, WorkbookControl *wbc)
if (me->newSheetObjects == NULL)
me->newSheetObjects = dao_surrender_so (me->dao);
g_slist_foreach (me->newSheetObjects, (GFunc)sheet_object_clear_sheet, NULL);
- workbook_recalc (me->dao->sheet->workbook);
sheet_update (me->dao->sheet);
}
@@ -5343,7 +5336,6 @@ cmd_analysis_tool_redo (GnmCommand *cmd, WorkbookControl *wbc)
dao_autofit_columns (me->dao);
sheet_mark_dirty (me->dao->sheet);
- workbook_recalc (me->dao->sheet->workbook);
sheet_update (me->dao->sheet);
/* The concept of an undo if we create a new worksheet is extremely strange,
@@ -6639,7 +6631,6 @@ static gboolean
cmd_goal_seek_impl (GnmCell *cell, GnmValue *value)
{
sheet_cell_set_value (cell, value_dup(value));
- workbook_recalc (cell->base.sheet->workbook);
return FALSE;
}
@@ -7069,7 +7060,6 @@ cmd_so_set_value_redo (GnmCommand *cmd, G_GNUC_UNUSED WorkbookControl *wbc)
GnmCell *cell = sheet_cell_fetch (sheet, me->ref.col, me->ref.row);
sheet_cell_set_value (cell, value_dup (me->val));
- workbook_recalc (sheet->workbook);
sheet_update (sheet);
return FALSE;
diff --git a/src/dependent.c b/src/dependent.c
index 1155790..f23dd28 100644
--- a/src/dependent.c
+++ b/src/dependent.c
@@ -2713,13 +2713,19 @@ workbook_recalc (Workbook *wb)
* workbook_recalc_all :
* @wb :
*
- * Queues all dependents for recalc and marks them all as dirty.
+ * Queues all dependents for recalc and recalculates.
*/
void
workbook_recalc_all (Workbook *wb)
{
workbook_queue_all_recalc (wb);
+
+ /* Recalculate this workbook unconditionally. */
workbook_recalc (wb);
+
+ /* Recalculate other workbooks when needed. */
+ gnm_app_recalc ();
+
WORKBOOK_FOREACH_VIEW (wb, view,
sheet_update (wb_view_cur_sheet (view)););
}
diff --git a/src/dialogs/dialog-goal-seek.c b/src/dialogs/dialog-goal-seek.c
index 6306895..4670211 100644
--- a/src/dialogs/dialog-goal-seek.c
+++ b/src/dialogs/dialog-goal-seek.c
@@ -47,6 +47,7 @@
#include <mathfunc.h>
#include <widgets/gnumeric-expr-entry.h>
#include <selection.h>
+#include <application.h>
#include <gtk/gtk.h>
#include <math.h>
@@ -107,7 +108,7 @@ goal_seek_eval (gnm_float x, gnm_float *y, void *vevaldata)
gnm_cell_set_value (evaldata->xcell, v);
cell_queue_recalc (evaldata->xcell);
}
- workbook_recalc (evaldata->state->wb);
+ gnm_cell_eval (evaldata->ycell);
if (evaldata->ycell->value) {
*y = value_get_as_float (evaldata->ycell->value) - evaldata->ytarget;
@@ -286,9 +287,10 @@ cb_dialog_cancel_clicked (G_GNUC_UNUSED GtkWidget *button,
if ((state->old_cell != NULL) && (state->old_value != NULL)) {
sheet_cell_set_value (state->old_cell, state->old_value);
- workbook_recalc (state->wb);
state->old_value = NULL;
}
+
+ gnm_app_recalc ();
gtk_widget_destroy (state->dialog);
}
@@ -398,14 +400,16 @@ cb_dialog_apply_clicked (G_GNUC_UNUSED GtkWidget *button,
if ((state->old_cell != NULL) && (state->old_value != NULL)) {
sheet_cell_set_value (state->old_cell, state->old_value);
- workbook_recalc (state->wb);
state->old_value = NULL;
}
+ gnm_app_recalc ();
state->old_cell = state->change_cell;
state->old_value = value_dup (state->change_cell->value);
status = gnumeric_goal_seek (state);
+ gnm_app_recalc ();
+
switch (status) {
case GOAL_SEEK_OK: {
const char *actual_str;
diff --git a/src/dialogs/dialog-solver.c b/src/dialogs/dialog-solver.c
index a4e4ddf..f742808 100644
--- a/src/dialogs/dialog-solver.c
+++ b/src/dialogs/dialog-solver.c
@@ -44,6 +44,7 @@
#include <commands.h>
#include <clipboard.h>
#include <selection.h>
+#include <application.h>
#include <tools/gnm-solver.h>
#include <widgets/gnumeric-expr-entry.h>
@@ -924,7 +925,7 @@ cb_dialog_solve_clicked (G_GNUC_UNUSED GtkWidget *button,
res = run_solver (state, param);
- workbook_recalc (state->sheet->workbook);
+ gnm_app_recalc ();
if (res != NULL) {
if ((res->quality == GNM_SOLVER_RESULT_OPTIMAL ||
diff --git a/src/ssconvert.c b/src/ssconvert.c
index c026777..251a6f4 100644
--- a/src/ssconvert.c
+++ b/src/ssconvert.c
@@ -15,6 +15,7 @@
#include "gnumeric.h"
#include "position.h"
#include "parse-util.h"
+#include "application.h"
#include "workbook.h"
#include "workbook-priv.h"
#include "workbook-control.h"
@@ -637,8 +638,7 @@ convert (char const *inarg, char const *outarg, char const *mergeargs[],
if (ssconvert_recalc)
workbook_recalc_all (wb);
- else
- workbook_recalc (wb);
+ gnm_app_recalc ();
if (ssconvert_range)
setup_range (G_OBJECT (wb),
diff --git a/src/ssgrep.c b/src/ssgrep.c
index 6bd8af6..a0a468a 100644
--- a/src/ssgrep.c
+++ b/src/ssgrep.c
@@ -12,6 +12,7 @@
#include "command-context-stderr.h"
#include "workbook-view.h"
#include "workbook.h"
+#include "application.h"
#include "gutils.h"
#include "gnm-plugin.h"
#include "search.h"
@@ -289,8 +290,7 @@ ssgrep (const char *arg, char const *uri, GOIOContext *ioc, GHashTable *targets,
if (ssgrep_locus_results) {
if (ssgrep_recalc)
workbook_recalc_all (wb);
- else
- workbook_recalc (wb);
+ gnm_app_recalc ();
}
if (ssgrep_string_table) {
diff --git a/src/sstest.c b/src/sstest.c
index c9b4158..766cfd0 100644
--- a/src/sstest.c
+++ b/src/sstest.c
@@ -452,7 +452,9 @@ test_random_1 (int N, const char *expr,
define_cell (sheet, 1, 3, s);
g_free (s);
+ /* Force recalc of all dirty cells even in manual mode. */
workbook_recalc (sheet->workbook);
+
for (i = 0; i < N; i++)
res[i] = value_get_as_float (sheet_cell_get (sheet, 0, i)->value);
*mean = value_get_as_float (sheet_cell_get (sheet, 1, 0)->value);
@@ -513,7 +515,9 @@ test_random_normality (int N, const char *expr,
define_cell (sheet, 1, 5, s);
g_free (s);
+ /* Force recalc of all dirty cells even in manual mode. */
workbook_recalc (sheet->workbook);
+
for (i = 0; i < N; i++)
res[i] = value_get_as_float (sheet_cell_get (sheet, 0, i)->value);
*mean = value_get_as_float (sheet_cell_get (sheet, 1, 0)->value);
diff --git a/src/tools/tabulate.c b/src/tools/tabulate.c
index 244288c..15f03a3 100644
--- a/src/tools/tabulate.c
+++ b/src/tools/tabulate.c
@@ -264,7 +264,8 @@ do_tabulation (WorkbookControl *wbc,
gnm_cell_set_value (data->cells[i], old_values[i]);
cell_queue_recalc (data->cells[i]);
}
- workbook_recalc (wb);
+ gnm_cell_eval (data->target);
+ gnm_app_recalc (wb);
}
g_free (values);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]