[gnumeric] solver: ask user to locate binaries when our search fails.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] solver: ask user to locate binaries when our search fails.
- Date: Sun, 4 Jul 2010 03:13:39 +0000 (UTC)
commit 981b2a00b32d4677ffeac6c8a2f73975071bb134
Author: Morten Welinder <terra gnome org>
Date: Sat Jul 3 23:13:10 2010 -0400
solver: ask user to locate binaries when our search fails.
NEWS | 4 +
plugins/glpk/gnm-glpk.c | 44 ++++++-
plugins/lpsolve/gnm-lpsolve.c | 50 ++++++--
schemas/gnumeric-plugins.schemas.in | 23 ++++-
src/dialogs/ChangeLog | 65 +++++-----
src/dialogs/dialog-solver.c | 25 +++-
src/gnm-plugin.c | 5 +-
src/gnumeric-gconf.c | 235 +++++++++++++++++++++++------------
src/gnumeric-gconf.h | 10 ++
src/ssconvert.c | 5 +-
src/tools/ChangeLog | 14 ++-
src/tools/gnm-solver.c | 71 ++++++++++-
src/tools/gnm-solver.h | 11 ++-
13 files changed, 416 insertions(+), 146 deletions(-)
---
diff --git a/NEWS b/NEWS
index 3ea267d..a1277fb 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,10 @@ Andreas:
* Improve function syntax tooltips. [#623317]
* Add weekend specifier to WORKDAY and NETWORKDAYS. [#172458]
+Morten:
+ * Ask user to locate solver binaries when plain search fails.
+ [#619519]
+
--------------------------------------------------------------------------
Gnumeric 1.10.7
diff --git a/plugins/glpk/gnm-glpk.c b/plugins/glpk/gnm-glpk.c
index 0428188..23623b2 100644
--- a/plugins/glpk/gnm-glpk.c
+++ b/plugins/glpk/gnm-glpk.c
@@ -6,6 +6,7 @@
#include "value.h"
#include "ranges.h"
#include "gutils.h"
+#include "gnumeric-gconf.h"
#include <gsf/gsf-impl-utils.h>
#include <gsf/gsf-input-textline.h>
#include <gsf/gsf-input-stdio.h>
@@ -259,10 +260,15 @@ gnm_glpk_start (GnmSolver *sol, WorkbookControl *wbc, GError **err,
gchar *argv[7];
int argc = 0;
GnmSolverParameters *param = sol->params;
+ const char *binary;
g_return_val_if_fail (sol->status == GNM_SOLVER_STATUS_PREPARED, FALSE);
- argv[argc++] = (gchar *)SOLVER_PROGRAM;
+ binary = gnm_conf_get_plugin_glpk_glpsol_path ();
+ if (binary == NULL || *binary == 0)
+ binary = SOLVER_PROGRAM;
+
+ argv[argc++] = (gchar *)binary;
argv[argc++] = (gchar *)(param->options.automatic_scaling
? "--scale"
: "--noscale");
@@ -306,15 +312,39 @@ gnm_glpk_stop (GnmSolver *sol, GError *err, GnmGlpk *lp)
}
gboolean
-glpk_solver_factory_functional (GnmSolverFactory *factory);
+glpk_solver_factory_functional (GnmSolverFactory *factory,
+ WBCGtk *wbcg);
gboolean
-glpk_solver_factory_functional (GnmSolverFactory *factory)
+glpk_solver_factory_functional (GnmSolverFactory *factory,
+ WBCGtk *wbcg)
{
- char *full_path = g_find_program_in_path (SOLVER_PROGRAM);
- gboolean res= (full_path != NULL);
- g_free (full_path);
- return res;
+ const char *full_path = gnm_conf_get_plugin_glpk_glpsol_path ();
+ char *path;
+
+ if (full_path && *full_path)
+ return g_file_test (full_path, G_FILE_TEST_IS_EXECUTABLE);
+
+ path = g_find_program_in_path (SOLVER_PROGRAM);
+ if (path) {
+ g_free (path);
+ return TRUE;
+ }
+
+ if (!wbcg)
+ return FALSE;
+
+ path = gnm_sub_solver_locate_binary (SOLVER_PROGRAM,
+ "Gnu Linear Programming Kit",
+ SOLVER_URL,
+ wbcg);
+ if (path) {
+ gnm_conf_set_plugin_glpk_glpsol_path (path);
+ g_free (path);
+ return TRUE;
+ }
+
+ return FALSE;
}
diff --git a/plugins/lpsolve/gnm-lpsolve.c b/plugins/lpsolve/gnm-lpsolve.c
index 4d89630..4f73d78 100644
--- a/plugins/lpsolve/gnm-lpsolve.c
+++ b/plugins/lpsolve/gnm-lpsolve.c
@@ -5,11 +5,12 @@
#include "sheet.h"
#include "value.h"
#include "ranges.h"
+#include "gnumeric-gconf.h"
#include <gsf/gsf-impl-utils.h>
#include <glib/gi18n-lib.h>
#include <string.h>
-#define SOLVER_PROGRAM "lp_solve"
+#define SOLVER_PROGRAM "lp_solveXXX"
#define SOLVER_URL "http://sourceforge.net/projects/lpsolve/"
#define PRIVATE_KEY "::lpsolve::"
@@ -255,10 +256,15 @@ gnm_lpsolve_start (GnmSolver *sol, WorkbookControl *wbc, GError **err,
gchar *argv[5];
int argc = 0;
GnmSolverParameters *param = sol->params;
+ const char *binary;
g_return_val_if_fail (sol->status == GNM_SOLVER_STATUS_PREPARED, FALSE);
- argv[argc++] = (gchar *)SOLVER_PROGRAM;
+ binary = gnm_conf_get_plugin_lpsolve_lpsolve_path ();
+ if (binary == NULL || *binary == 0)
+ binary = SOLVER_PROGRAM;
+
+ argv[argc++] = (gchar *)binary;
argv[argc++] = (gchar *)"-i";
argv[argc++] = (gchar *)(param->options.automatic_scaling
? "-s1"
@@ -300,15 +306,39 @@ gnm_lpsolve_stop (GnmSolver *sol, GError *err, GnmLPSolve *lp)
}
gboolean
-lpsolve_solver_factory_functional (GnmSolverFactory *factory);
+lpsolve_solver_factory_functional (GnmSolverFactory *factory,
+ WBCGtk *wbcg);
gboolean
-lpsolve_solver_factory_functional (GnmSolverFactory *factory)
+lpsolve_solver_factory_functional (GnmSolverFactory *factory,
+ WBCGtk *wbcg)
{
- char *full_path = g_find_program_in_path (SOLVER_PROGRAM);
- gboolean res= (full_path != NULL);
- g_free (full_path);
- return res;
+ const char *full_path = gnm_conf_get_plugin_lpsolve_lpsolve_path ();
+ char *path;
+
+ if (full_path && *full_path)
+ return g_file_test (full_path, G_FILE_TEST_IS_EXECUTABLE);
+
+ path = g_find_program_in_path (SOLVER_PROGRAM);
+ if (path) {
+ g_free (path);
+ return TRUE;
+ }
+
+ if (!wbcg)
+ return FALSE;
+
+ path = gnm_sub_solver_locate_binary (SOLVER_PROGRAM,
+ "LP Solve",
+ SOLVER_URL,
+ wbcg);
+ if (path) {
+ gnm_conf_set_plugin_lpsolve_lpsolve_path (path);
+ g_free (path);
+ return TRUE;
+ }
+
+ return FALSE;
}
@@ -319,8 +349,8 @@ GnmSolver *
lpsolve_solver_factory (GnmSolverFactory *factory, GnmSolverParameters *params)
{
GnmSolver *res = g_object_new (GNM_SUB_SOLVER_TYPE,
- "params", params,
- NULL);
+ "params", params,
+ NULL);
GnmLPSolve *lp = g_new0 (GnmLPSolve, 1);
lp->parent = GNM_SUB_SOLVER (res);
diff --git a/schemas/gnumeric-plugins.schemas.in b/schemas/gnumeric-plugins.schemas.in
index 0e5adc2..bd93585 100644
--- a/schemas/gnumeric-plugins.schemas.in
+++ b/schemas/gnumeric-plugins.schemas.in
@@ -11,6 +11,27 @@
<long>This setting determines whether created LaTeX files use UTF-8 (unicode) or ISO-8859-1 (Latin1). To use the UTF-8 files, you must have the ucs LaTeX package installed.</long>
</locale>
</schema>
+ <schema>
+ <key>/schemas/apps/gnumeric/plugin/lpsolve/lpsolve-path</key>
+ <applyto>/apps/gnumeric/plugin/lpsolve/lpsolve-path</applyto>
+ <owner>Gnumeric</owner>
+ <type>string</type>
+ <default/>
+ <locale name="C">
+ <short>Full path of lp_solve program to use</short>
+ <long>This is the full path to the lp_solve binary that the lpsolve plugin should use.</long>
+ </locale>
+ </schema>
+ <schema>
+ <key>/schemas/apps/gnumeric/plugin/glpk/glpsol-path</key>
+ <applyto>/apps/gnumeric/plugin/glpk/glpsol-path</applyto>
+ <owner>Gnumeric</owner>
+ <type>string</type>
+ <default/>
+ <locale name="C">
+ <short>Full path of glpsol program to use</short>
+ <long>This is the full path to the glpsol binary that the lpsolve plugin should use.</long>
+ </locale>
+ </schema>
</schemalist>
</gconfschemafile>
-
diff --git a/src/dialogs/ChangeLog b/src/dialogs/ChangeLog
index 73899a9..91a1426 100644
--- a/src/dialogs/ChangeLog
+++ b/src/dialogs/ChangeLog
@@ -1,7 +1,12 @@
+2010-07-03 Morten Welinder <terra gnome org>
+
+ * dialog-solver.c (run_solver): Check that the solver is
+ functional. Fix error message.
+
2010-06-30 Andreas J. Guelzow <aguelzow pyrshep ca>
* dialog-search-replace.c (dialog_search_replace_save_in_prefs): new
- (apply_clicked): call dialog_search_replace_save_in_prefs if
+ (apply_clicked): call dialog_search_replace_save_in_prefs if
appropriate
(dialog_search_replace): set the current state according to the
preferences
@@ -18,7 +23,7 @@
2010-06-24 Andreas J. Guelzow <aguelzow pyrshep ca>
- * dialog-stf.h (FormatInfo_t): add new field
+ * dialog-stf.h (FormatInfo_t): add new field
* dialog-stf.c (stf_dialog): transfer autofit array
* dialog-stf-format-page.c (cb_col_check_clicked): set
sensitivity of autofit check
@@ -26,13 +31,13 @@
(format_page_update_preview): handle new field
(stf_dialog_format_page_cleanup): ditto
(stf_dialog_format_page_init): ditto
-
+
2010-06-22 Andreas J. Guelzow <aguelzow pyrshep ca>
* dialog-sheetobject-size.c (set_params): new
(cb_dialog_so_size_apply_clicked): use cmd_generic instead of
cmd_so_rename
-
+
2010-06-21 Andreas J. Guelzow <aguelzow pyrshep ca>
* dialog-solver.c (dialog_init): setup first entry
@@ -40,12 +45,12 @@
2010-06-21 Andreas J. Guelzow <aguelzow pyrshep ca>
* dialog-formula-guru.c (real_start_editing_cb): deleted
- (start_editing_cb): include real_start_editing_cb here
+ (start_editing_cb): include real_start_editing_cb here
(removes gtk 2.2 hack)
2010-06-17 Andreas J. Guelzow <aguelzow pyrshep ca>
- * dialog-formula-guru.c (cb_dialog_formula_guru_query_tooltip):
+ * dialog-formula-guru.c (cb_dialog_formula_guru_query_tooltip):
adjust tooltip
2010-06-17 Andreas J. Guelzow <aguelzow pyrshep ca>
@@ -60,11 +65,11 @@
(cb_dialog_formula_guru_destroy): unref tooltip widgets
(cb_dialog_formula_guru_query_tooltip): create our own tooltip
(dialog_formula_guru_init): initialize tooltip widgets
-
+
2010-06-16 Morten Welinder <terra gnome org>
* Release 1.10.6
-
+
2010-06-16 Andreas J. Guelzow <aguelzow pyrshep ca>
* dialog-formula-guru.c (dialog_formula_guru_adjust_children): use
@@ -78,10 +83,10 @@
2010-06-15 Andreas J. Guelzow <aguelzow pyrshep ca>
- * dialog-formula-guru.c (dialog_formula_guru_adjust_children): load
+ * dialog-formula-guru.c (dialog_formula_guru_adjust_children): load
tooltip
(dialog_formula_guru_init): set up tooltips
-
+
2010-06-15 Andreas J. Guelzow <aguelzow pyrshep ca>
* dialogs.h (dialog_formula_guru): change storage class of an arg
@@ -95,25 +100,25 @@
2010-06-10 Andreas J. Guelzow <aguelzow pyrshep ca>
- * dialog-function-select.c
+ * dialog-function-select.c
(dialog_function_select_get_description): rename to
dialog_function_select_get_description
(dialog_function_select_get_description): new
(dialog_function_select_load_tree): store the PangoAttrList
- (dialog_function_select_init): set up new attribute field in
+ (dialog_function_select_init): set up new attribute field in
the liststore
-
+
2010-06-09 Andreas J. Guelzow <aguelzow pyrshep ca>
- * dialog-function-select.c
- (dialog_function_select_erase_search_entry): only include for
+ * dialog-function-select.c
+ (dialog_function_select_erase_search_entry): only include for
newer gtk
-
+
2010-06-09 Andreas J. Guelzow <aguelzow pyrshep ca>
* dialog-function-select.c (dialog_function_select_init):
change the dialog title to reflect help mode
- (dialog_function_select): use a differnt key in help mode to
+ (dialog_function_select): use a differnt key in help mode to
avoid confusion
2010-06-09 Andreas J. Guelzow <aguelzow pyrshep ca>
@@ -122,7 +127,7 @@
* dialog-function-select.c (dialog_function_select_init):
show and hide the appropriate widgets depending on whether
we are in help mode
- (cb_dialog_function_select_ok_clicked): only called the
+ (cb_dialog_function_select_ok_clicked): only called the
formula guru if we aren't in help mode
(dialog_function_select): don't show the purposefully hidden
widgets
@@ -130,16 +135,16 @@
2010-06-09 Andreas J. Guelzow <aguelzow pyrshep ca>
* dialog-function-select.c (cb_unref): new
- (cb_dialog_function_select_search_all): handle "in use"
+ (cb_dialog_function_select_search_all): handle "in use"
selection
(dialog_function_select_search): set up "in use" selection
(cb_dialog_function_select_destroy): unref funcs
(dialog_function_select_load_cb): add "in use" item
(dialog_function_select_get_description): load stubs
- (dialog_function_select_load_tree): ref the funcs when
+ (dialog_function_select_load_tree): ref the funcs when
storing them in the model
(dialog_function_select_init): setup "in use" flag
-
+
2010-06-08 Andreas J. Guelzow <aguelzow pyrshep ca>
* dialog-function-select.c (dialog_function_select_search):
@@ -163,9 +168,9 @@
2010-06-07 Andreas J. Guelzow <aguelzow pyrshep ca>
- * dialog-define-names.c (cb_name_guru_name_edited): the
+ * dialog-define-names.c (cb_name_guru_name_edited): the
name becomes non-ediatable after it has been set.
-
+
2010-06-06 Andreas J. Guelzow <aguelzow pyrshep ca>
* regression.glade: add new checkbox and move the selectors for
@@ -186,7 +191,7 @@
* dialog-define-names.c (name_guru_parse_pos_init): new
(name_guru_check_expression): use name_guru_parse_pos_init
(cb_name_guru_name_edited): don't duplicate errorchecks already
- in cmd_define_name but make sure that we don't just redefine
+ in cmd_define_name but make sure that we don't just redefine
names
2010-06-04 Andreas J. Guelzow <aguelzow pyrshep ca>
@@ -198,13 +203,13 @@
2010-06-04 Andreas J. Guelzow <aguelzow pyrshep ca>
- * dialog-define-names.c (name_guru_delete): no need to
+ * dialog-define-names.c (name_guru_delete): no need to
check for in use if it wasn't saved.
(name_guru_find_place): new
(name_guru_move_record): use name_guru_find_place
(cb_name_guru_name_edited): we also need to set the GnmNamedExpr
if we possibly added a new name.
-
+
2010-06-04 Andreas J. Guelzow <aguelzow pyrshep ca>
* dialog-define-names.c (cb_name_guru_search): make searching
@@ -227,7 +232,7 @@
GtkTreeStore and GtkTreeView and adjust code throughout.
(name_guru_store_names): new type adjustment for every name
(cb_name_guru_content_edited): don't leak GnmExprTop
-
+
2010-06-03 Andreas J. Guelzow <aguelzow pyrshep ca>
* dialog-define-names.c (cb_name_guru_switch_scope): use
@@ -245,7 +250,7 @@
2010-06-03 Andreas J. Guelzow <aguelzow pyrshep ca>
* dialog-define-names.c (name_guru_paste): don't overwrite text
-
+
2010-06-03 Andreas J. Guelzow <aguelzow pyrshep ca>
* paste-names.glade: deleted
@@ -284,11 +289,11 @@
ditto
(dialog_sign_test_tool): ditto
* dialog-analysis-tools.c (tool_setup_update): new
-
+
2010-05-31 Andreas J. Guelzow <aguelzow pyrshep ca>
* dialogs.h (dialog_sign_test_two_tool): new
- * dialog-analysis-tool-sign-test.c
+ * dialog-analysis-tool-sign-test.c
(sign_test_tool_update_common_sensitivity_cb): new
(sign_test_tool_update_sensitivity_cb): split
(sign_test_two_tool_update_sensitivity_cb): new
diff --git a/src/dialogs/dialog-solver.c b/src/dialogs/dialog-solver.c
index 4502da3..7c4b778 100644
--- a/src/dialogs/dialog-solver.c
+++ b/src/dialogs/dialog-solver.c
@@ -628,12 +628,13 @@ run_solver (SolverState *state, GnmSolverParameters *param)
GnmSolverResult *res = NULL;
int y;
- sol = param->options.algorithm
- ? gnm_solver_factory_create (param->options.algorithm, param)
- : NULL;
+ sol = gnm_solver_factory_functional (param->options.algorithm,
+ state->wbcg)
+ ? gnm_solver_factory_create (param->options.algorithm, param)
+ : NULL;
if (!sol) {
go_gtk_notice_dialog (top, GTK_MESSAGE_ERROR,
- _("No suitable solver available."));
+ _("The chosen solver is not functional."));
goto fail;
}
@@ -1189,19 +1190,29 @@ dialog_solver (WBCGtk *wbcg, Sheet *sheet)
{
SolverState *state;
GnmSolverParameters *old_params = sheet->solver_parameters;
+ gboolean got_it;
+ int pass;
/* Only pop up one copy per workbook */
if (gnumeric_dialog_raise_if_exists (wbcg, SOLVER_KEY))
return;
- /* First time around, pick a functional algorithm. */
- if (!gnm_solver_factory_functional (old_params->options.algorithm)) {
+ /*
+ * First time around, pick a functional algorithm preferably one we
+ * can determine is functional without asking the user anything.
+ */
+ got_it = gnm_solver_factory_functional (old_params->options.algorithm,
+ NULL);
+ for (pass = 1; !got_it && pass <= 2; pass++) {
GSList *l;
+ WBCGtk *wbcg2 = pass == 2 ? wbcg : NULL;
+
for (l = gnm_solver_db_get (); l; l = l->next) {
GnmSolverFactory *factory = l->data;
if (old_params->options.model_type != factory->type)
continue;
- if (gnm_solver_factory_functional (factory)) {
+ if (gnm_solver_factory_functional (factory, wbcg2)) {
+ got_it = TRUE;
gnm_solver_param_set_algorithm (old_params,
factory);
break;
diff --git a/src/gnm-plugin.c b/src/gnm-plugin.c
index eb2ecd9..9d42ad1 100644
--- a/src/gnm-plugin.c
+++ b/src/gnm-plugin.c
@@ -513,7 +513,8 @@ cb_load_and_create (GnmSolverFactory *factory, GnmSolverParameters *param)
}
static gboolean
-cb_load_and_functional (GnmSolverFactory *factory)
+cb_load_and_functional (GnmSolverFactory *factory,
+ WBCGtk *wbcg)
{
PluginServiceSolver *ssol =
g_object_get_data (G_OBJECT (factory), "ssol");
@@ -529,7 +530,7 @@ cb_load_and_functional (GnmSolverFactory *factory)
}
functional = ssol->cbs.functional;
- return (functional == NULL || functional (factory));
+ return (functional == NULL || functional (factory, wbcg));
}
static void
diff --git a/src/gnumeric-gconf.c b/src/gnumeric-gconf.c
index 587071f..8d2eddb 100644
--- a/src/gnumeric-gconf.c
+++ b/src/gnumeric-gconf.c
@@ -1856,6 +1856,33 @@ gnm_conf_get_functionselector_recentfunctions_node (void)
return get_node (watch_functionselector_recentfunctions.key);
}
+static struct cb_watch_string watch_plugin_glpk_glpsol_path = {
+ 0, "plugin/glpk/glpk-path", "",
+};
+
+const char *
+gnm_conf_get_plugin_glpk_glpsol_path (void)
+{
+ if (!watch_plugin_glpk_glpsol_path.handler)
+ watch_string (&watch_plugin_glpk_glpsol_path);
+ return watch_plugin_glpk_glpsol_path.var;
+}
+
+void
+gnm_conf_set_plugin_glpk_glpsol_path (const char *x)
+{
+ g_return_if_fail (x != NULL);
+ if (!watch_plugin_glpk_glpsol_path.handler)
+ watch_string (&watch_plugin_glpk_glpsol_path);
+ set_string (&watch_plugin_glpk_glpsol_path, x);
+}
+
+GOConfNode *
+gnm_conf_get_plugin_glpk_glpsol_path_node (void)
+{
+ return get_node (watch_plugin_glpk_glpsol_path.key);
+}
+
static struct cb_watch_bool watch_plugin_latex_use_utf8 = {
0, "plugin/latex/use-utf8", FALSE,
};
@@ -1882,6 +1909,33 @@ gnm_conf_get_plugin_latex_use_utf8_node (void)
return get_node (watch_plugin_latex_use_utf8.key);
}
+static struct cb_watch_string watch_plugin_lpsolve_lpsolve_path = {
+ 0, "plugin/lpsolve/lpsolve-path", "",
+};
+
+const char *
+gnm_conf_get_plugin_lpsolve_lpsolve_path (void)
+{
+ if (!watch_plugin_lpsolve_lpsolve_path.handler)
+ watch_string (&watch_plugin_lpsolve_lpsolve_path);
+ return watch_plugin_lpsolve_lpsolve_path.var;
+}
+
+void
+gnm_conf_set_plugin_lpsolve_lpsolve_path (const char *x)
+{
+ g_return_if_fail (x != NULL);
+ if (!watch_plugin_lpsolve_lpsolve_path.handler)
+ watch_string (&watch_plugin_lpsolve_lpsolve_path);
+ set_string (&watch_plugin_lpsolve_lpsolve_path, x);
+}
+
+GOConfNode *
+gnm_conf_get_plugin_lpsolve_lpsolve_path_node (void)
+{
+ return get_node (watch_plugin_lpsolve_lpsolve_path.key);
+}
+
static struct cb_watch_bool watch_plugins_activate_new = {
0, "plugins/activate-new", TRUE,
};
@@ -2874,17 +2928,10 @@ gnm_conf_get_printsetup_scale_width_node (void)
return get_node (watch_printsetup_scale_width.key);
}
-
static struct cb_watch_bool watch_searchreplace_change_cell_expressions = {
0, "searchreplace/change-cell-expressions", TRUE,
};
-GOConfNode *
-gnm_conf_get_searchreplace_change_cell_expressions_node (void)
-{
- return get_node (watch_searchreplace_change_cell_expressions.key);
-}
-
gboolean
gnm_conf_get_searchreplace_change_cell_expressions (void)
{
@@ -2901,16 +2948,16 @@ gnm_conf_set_searchreplace_change_cell_expressions (gboolean x)
set_bool (&watch_searchreplace_change_cell_expressions, x);
}
-static struct cb_watch_bool watch_searchreplace_change_cell_other = {
- 0, "searchreplace/change-cell-other", TRUE,
-};
-
GOConfNode *
-gnm_conf_get_searchreplace_change_cell_other_node (void)
+gnm_conf_get_searchreplace_change_cell_expressions_node (void)
{
- return get_node (watch_searchreplace_change_cell_other.key);
+ return get_node (watch_searchreplace_change_cell_expressions.key);
}
+static struct cb_watch_bool watch_searchreplace_change_cell_other = {
+ 0, "searchreplace/change-cell-other", TRUE,
+};
+
gboolean
gnm_conf_get_searchreplace_change_cell_other (void)
{
@@ -2927,16 +2974,16 @@ gnm_conf_set_searchreplace_change_cell_other (gboolean x)
set_bool (&watch_searchreplace_change_cell_other, x);
}
-static struct cb_watch_bool watch_searchreplace_change_cell_strings = {
- 0, "searchreplace/change-cell-strings", TRUE,
-};
-
GOConfNode *
-gnm_conf_get_searchreplace_change_cell_strings_node (void)
+gnm_conf_get_searchreplace_change_cell_other_node (void)
{
- return get_node (watch_searchreplace_change_cell_strings.key);
+ return get_node (watch_searchreplace_change_cell_other.key);
}
+static struct cb_watch_bool watch_searchreplace_change_cell_strings = {
+ 0, "searchreplace/change-cell-strings", TRUE,
+};
+
gboolean
gnm_conf_get_searchreplace_change_cell_strings (void)
{
@@ -2953,16 +3000,16 @@ gnm_conf_set_searchreplace_change_cell_strings (gboolean x)
set_bool (&watch_searchreplace_change_cell_strings, x);
}
-static struct cb_watch_bool watch_searchreplace_change_comments = {
- 0, "searchreplace/change-comments", FALSE,
-};
-
GOConfNode *
-gnm_conf_get_searchreplace_change_comments_node (void)
+gnm_conf_get_searchreplace_change_cell_strings_node (void)
{
- return get_node (watch_searchreplace_change_comments.key);
+ return get_node (watch_searchreplace_change_cell_strings.key);
}
+static struct cb_watch_bool watch_searchreplace_change_comments = {
+ 0, "searchreplace/change-comments", FALSE,
+};
+
gboolean
gnm_conf_get_searchreplace_change_comments (void)
{
@@ -2979,16 +3026,16 @@ gnm_conf_set_searchreplace_change_comments (gboolean x)
set_bool (&watch_searchreplace_change_comments, x);
}
-static struct cb_watch_bool watch_searchreplace_columnmajor = {
- 0, "searchreplace/columnmajor", TRUE,
-};
-
GOConfNode *
-gnm_conf_get_searchreplace_columnmajor_node (void)
+gnm_conf_get_searchreplace_change_comments_node (void)
{
- return get_node (watch_searchreplace_columnmajor.key);
+ return get_node (watch_searchreplace_change_comments.key);
}
+static struct cb_watch_bool watch_searchreplace_columnmajor = {
+ 0, "searchreplace/columnmajor", TRUE,
+};
+
gboolean
gnm_conf_get_searchreplace_columnmajor (void)
{
@@ -3005,16 +3052,16 @@ gnm_conf_set_searchreplace_columnmajor (gboolean x)
set_bool (&watch_searchreplace_columnmajor, x);
}
-static struct cb_watch_int watch_searchreplace_error_behaviour = {
- 0, "searchreplace/error-behaviour", 0, 4, 0,
-};
-
GOConfNode *
-gnm_conf_get_searchreplace_error_behaviour_node (void)
+gnm_conf_get_searchreplace_columnmajor_node (void)
{
- return get_node (watch_searchreplace_error_behaviour.key);
+ return get_node (watch_searchreplace_columnmajor.key);
}
+static struct cb_watch_int watch_searchreplace_error_behaviour = {
+ 0, "searchreplace/error-behaviour", 0, 4, 0,
+};
+
int
gnm_conf_get_searchreplace_error_behaviour (void)
{
@@ -3031,16 +3078,16 @@ gnm_conf_set_searchreplace_error_behaviour (int x)
set_int (&watch_searchreplace_error_behaviour, x);
}
-static struct cb_watch_bool watch_searchreplace_ignore_case = {
- 0, "searchreplace/ignore-case", TRUE,
-};
-
GOConfNode *
-gnm_conf_get_searchreplace_ignore_case_node (void)
+gnm_conf_get_searchreplace_error_behaviour_node (void)
{
- return get_node (watch_searchreplace_ignore_case.key);
+ return get_node (watch_searchreplace_error_behaviour.key);
}
+static struct cb_watch_bool watch_searchreplace_ignore_case = {
+ 0, "searchreplace/ignore-case", TRUE,
+};
+
gboolean
gnm_conf_get_searchreplace_ignore_case (void)
{
@@ -3057,16 +3104,16 @@ gnm_conf_set_searchreplace_ignore_case (gboolean x)
set_bool (&watch_searchreplace_ignore_case, x);
}
-static struct cb_watch_bool watch_searchreplace_keep_strings = {
- 0, "searchreplace/keep-strings", TRUE,
-};
-
GOConfNode *
-gnm_conf_get_searchreplace_keep_strings_node (void)
+gnm_conf_get_searchreplace_ignore_case_node (void)
{
- return get_node (watch_searchreplace_keep_strings.key);
+ return get_node (watch_searchreplace_ignore_case.key);
}
+static struct cb_watch_bool watch_searchreplace_keep_strings = {
+ 0, "searchreplace/keep-strings", TRUE,
+};
+
gboolean
gnm_conf_get_searchreplace_keep_strings (void)
{
@@ -3083,16 +3130,16 @@ gnm_conf_set_searchreplace_keep_strings (gboolean x)
set_bool (&watch_searchreplace_keep_strings, x);
}
-static struct cb_watch_bool watch_searchreplace_preserve_case = {
- 0, "searchreplace/preserve-case", FALSE,
-};
-
GOConfNode *
-gnm_conf_get_searchreplace_preserve_case_node (void)
+gnm_conf_get_searchreplace_keep_strings_node (void)
{
- return get_node (watch_searchreplace_preserve_case.key);
+ return get_node (watch_searchreplace_keep_strings.key);
}
+static struct cb_watch_bool watch_searchreplace_preserve_case = {
+ 0, "searchreplace/preserve-case", FALSE,
+};
+
gboolean
gnm_conf_get_searchreplace_preserve_case (void)
{
@@ -3109,16 +3156,16 @@ gnm_conf_set_searchreplace_preserve_case (gboolean x)
set_bool (&watch_searchreplace_preserve_case, x);
}
-static struct cb_watch_bool watch_searchreplace_query = {
- 0, "searchreplace/query", FALSE,
-};
-
GOConfNode *
-gnm_conf_get_searchreplace_query_node (void)
+gnm_conf_get_searchreplace_preserve_case_node (void)
{
- return get_node (watch_searchreplace_query.key);
+ return get_node (watch_searchreplace_preserve_case.key);
}
+static struct cb_watch_bool watch_searchreplace_query = {
+ 0, "searchreplace/query", FALSE,
+};
+
gboolean
gnm_conf_get_searchreplace_query (void)
{
@@ -3135,16 +3182,16 @@ gnm_conf_set_searchreplace_query (gboolean x)
set_bool (&watch_searchreplace_query, x);
}
-static struct cb_watch_int watch_searchreplace_regex = {
- 0, "searchreplace/regex", 0, 2, 0,
-};
-
GOConfNode *
-gnm_conf_get_searchreplace_regex_node (void)
+gnm_conf_get_searchreplace_query_node (void)
{
- return get_node (watch_searchreplace_regex.key);
+ return get_node (watch_searchreplace_query.key);
}
+static struct cb_watch_int watch_searchreplace_regex = {
+ 0, "searchreplace/regex", 0, 2, 0,
+};
+
int
gnm_conf_get_searchreplace_regex (void)
{
@@ -3161,16 +3208,16 @@ gnm_conf_set_searchreplace_regex (int x)
set_int (&watch_searchreplace_regex, x);
}
-static struct cb_watch_int watch_searchreplace_scope = {
- 0, "searchreplace/scope", 0, 2, 0,
-};
-
GOConfNode *
-gnm_conf_get_searchreplace_scope_node (void)
+gnm_conf_get_searchreplace_regex_node (void)
{
- return get_node (watch_searchreplace_scope.key);
+ return get_node (watch_searchreplace_regex.key);
}
+static struct cb_watch_int watch_searchreplace_scope = {
+ 0, "searchreplace/scope", 0, 2, 0,
+};
+
int
gnm_conf_get_searchreplace_scope (void)
{
@@ -3187,16 +3234,16 @@ gnm_conf_set_searchreplace_scope (int x)
set_int (&watch_searchreplace_scope, x);
}
-static struct cb_watch_bool watch_searchreplace_whole_words_only = {
- 0, "searchreplace/whole-words-only", FALSE,
-};
-
GOConfNode *
-gnm_conf_get_searchreplace_whole_words_only_node (void)
+gnm_conf_get_searchreplace_scope_node (void)
{
- return get_node (watch_searchreplace_whole_words_only.key);
+ return get_node (watch_searchreplace_scope.key);
}
+static struct cb_watch_bool watch_searchreplace_whole_words_only = {
+ 0, "searchreplace/whole-words-only", FALSE,
+};
+
gboolean
gnm_conf_get_searchreplace_whole_words_only (void)
{
@@ -3213,6 +3260,12 @@ gnm_conf_set_searchreplace_whole_words_only (gboolean x)
set_bool (&watch_searchreplace_whole_words_only, x);
}
+GOConfNode *
+gnm_conf_get_searchreplace_whole_words_only_node (void)
+{
+ return get_node (watch_searchreplace_whole_words_only.key);
+}
+
static struct cb_watch_string watch_stf_export_separator = {
0, "stf/export/separator", ",",
};
@@ -3489,12 +3542,24 @@ gnm_conf_get_functionselector_dir_node (void)
}
GOConfNode *
+gnm_conf_get_plugin_glpk_dir_node (void)
+{
+ return get_node ("plugin/glpk");
+}
+
+GOConfNode *
gnm_conf_get_plugin_latex_dir_node (void)
{
return get_node ("plugin/latex");
}
GOConfNode *
+gnm_conf_get_plugin_lpsolve_dir_node (void)
+{
+ return get_node ("plugin/lpsolve");
+}
+
+GOConfNode *
gnm_conf_get_plugins_dir_node (void)
{
return get_node ("plugins");
@@ -3507,6 +3572,18 @@ gnm_conf_get_printsetup_dir_node (void)
}
GOConfNode *
+gnm_conf_get_searchreplace_dir_node (void)
+{
+ return get_node ("searchreplace");
+}
+
+GOConfNode *
+gnm_conf_get_stf_export_dir_node (void)
+{
+ return get_node ("stf/export");
+}
+
+GOConfNode *
gnm_conf_get_undo_dir_node (void)
{
return get_node ("undo");
diff --git a/src/gnumeric-gconf.h b/src/gnumeric-gconf.h
index 1ab6889..43d0c49 100644
--- a/src/gnumeric-gconf.h
+++ b/src/gnumeric-gconf.h
@@ -217,10 +217,18 @@ GOConfNode *gnm_conf_get_functionselector_recentfunctions_node (void);
GSList *gnm_conf_get_functionselector_recentfunctions (void);
void gnm_conf_set_functionselector_recentfunctions (GSList *);
+GOConfNode *gnm_conf_get_plugin_glpk_glpsol_path_node (void);
+const char *gnm_conf_get_plugin_glpk_glpsol_path (void);
+void gnm_conf_set_plugin_glpk_glpsol_path (const char *);
+
GOConfNode *gnm_conf_get_plugin_latex_use_utf8_node (void);
gboolean gnm_conf_get_plugin_latex_use_utf8 (void);
void gnm_conf_set_plugin_latex_use_utf8 (gboolean);
+GOConfNode *gnm_conf_get_plugin_lpsolve_lpsolve_path_node (void);
+const char *gnm_conf_get_plugin_lpsolve_lpsolve_path (void);
+void gnm_conf_set_plugin_lpsolve_lpsolve_path (const char *);
+
GOConfNode *gnm_conf_get_plugins_activate_new_node (void);
gboolean gnm_conf_get_plugins_activate_new (void);
void gnm_conf_set_plugins_activate_new (gboolean);
@@ -468,7 +476,9 @@ GOConfNode *gnm_conf_get_core_xml_dir_node (void);
GOConfNode *gnm_conf_get_cut_and_paste_dir_node (void);
GOConfNode *gnm_conf_get_dialogs_rs_dir_node (void);
GOConfNode *gnm_conf_get_functionselector_dir_node (void);
+GOConfNode *gnm_conf_get_plugin_glpk_dir_node (void);
GOConfNode *gnm_conf_get_plugin_latex_dir_node (void);
+GOConfNode *gnm_conf_get_plugin_lpsolve_dir_node (void);
GOConfNode *gnm_conf_get_plugins_dir_node (void);
GOConfNode *gnm_conf_get_printsetup_dir_node (void);
GOConfNode *gnm_conf_get_searchreplace_dir_node (void);
diff --git a/src/ssconvert.c b/src/ssconvert.c
index bc84784..3fa2846 100644
--- a/src/ssconvert.c
+++ b/src/ssconvert.c
@@ -432,13 +432,14 @@ run_solver (Sheet *sheet, WorkbookView *wbv)
wb_control_set_view (wbc, wbv, NULL);
/* Pick a functional algorithm. */
- if (!gnm_solver_factory_functional (params->options.algorithm)) {
+ if (!gnm_solver_factory_functional (params->options.algorithm,
+ NULL)) {
GSList *l;
for (l = gnm_solver_db_get (); l; l = l->next) {
GnmSolverFactory *factory = l->data;
if (params->options.model_type != factory->type)
continue;
- if (gnm_solver_factory_functional (factory)) {
+ if (gnm_solver_factory_functional (factory, NULL)) {
gnm_solver_param_set_algorithm (params,
factory);
break;
diff --git a/src/tools/ChangeLog b/src/tools/ChangeLog
index 4057c54..6752682 100644
--- a/src/tools/ChangeLog
+++ b/src/tools/ChangeLog
@@ -1,3 +1,9 @@
+2010-07-03 Morten Welinder <terra gnome org>
+
+ * gnm-solver.c (gnm_sub_solver_locate_binary): New function.
+ (gnm_solver_factory_functional): Take optional WBCGtk argument so
+ we can ask the user. All callers changed.
+
2010-06-28 Morten Welinder <terra gnome org>
* Release 1.10.7
@@ -21,9 +27,9 @@
* analysis-tools.h (analysis_tools_data_regression_t): new field
* analysis-tools.c (analysis_tool_regression_engine_run): use
analysis_tool_get_function
- (analysis_tool_regression_simple_engine_run): use
- analysis_tool_get_function and obey the new multiple-y setting.
-
+ (analysis_tool_regression_simple_engine_run): use
+ analysis_tool_get_function and obey the new multiple-y setting.
+
2010-06-02 Morten Welinder <terra gnome org>
* gnm-solver.c (gnm_solver_set_status, gnm_solver_elapsed):
@@ -45,7 +51,7 @@
* analysis-tools.h (analysis_tool_get_function): new
* analysis-tools.c (analysis_tool_get_function): new
* analysis-sign-test.h: minor formatting
- * analysis-sign-test.c
+ * analysis-sign-test.c
(analysis_tool_sign_test_two_engine_run): fix statistic
2010-05-30 Morten Welinder <terra gnome org>
diff --git a/src/tools/gnm-solver.c b/src/tools/gnm-solver.c
index 031254f..3c21be3 100644
--- a/src/tools/gnm-solver.c
+++ b/src/tools/gnm-solver.c
@@ -1526,6 +1526,72 @@ gnm_sub_solver_get_cell_name (GnmSubSolver *subsol,
return g_hash_table_lookup (subsol->name_from_cell, (gpointer)cell);
}
+char *
+gnm_sub_solver_locate_binary (const char *binary, const char *solver,
+ const char *url,
+ WBCGtk *wbcg)
+{
+ GtkWindow *parent;
+ GtkWidget *dialog;
+ char *path = NULL;
+ int res;
+ GtkFileChooser *fsel;
+ char *title;
+
+ parent = wbcg ? wbcg_toplevel (wbcg) : NULL;
+ dialog = gtk_message_dialog_new_with_markup
+ (parent,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_YES_NO,
+ "Gnumeric is unable to locate the program <i>%s</i> needed "
+ "for the <i>%s</i> solver. For more information see %s.\n\n"
+ "Would you like to locate it yourself?",
+ binary, solver, url);
+ title = g_strdup_printf ("Unable to locate %s", binary);
+ g_object_set (G_OBJECT (dialog),
+ "title", title,
+ NULL);
+ g_free (title);
+
+ res = go_gtk_dialog_run (GTK_DIALOG (dialog), parent);
+ switch (res) {
+ case GTK_RESPONSE_NO:
+ case GTK_RESPONSE_DELETE_EVENT:
+ default:
+ return NULL;
+ case GTK_RESPONSE_YES:
+ break;
+ }
+
+ title = g_strdup_printf ("Locate the %s program", binary);
+ fsel = GTK_FILE_CHOOSER
+ (g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG,
+ "action", GTK_FILE_CHOOSER_ACTION_OPEN,
+ "local-only", TRUE,
+ "title", title,
+ NULL));
+ g_free (title);
+ gtk_dialog_add_buttons (GTK_DIALOG (fsel),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_EXECUTE, GTK_RESPONSE_OK,
+ NULL);
+ g_object_ref (fsel);
+ if (go_gtk_file_sel_dialog (parent, GTK_WIDGET (fsel))) {
+ path = gtk_file_chooser_get_filename (fsel);
+ if (!g_file_test (path, G_FILE_TEST_IS_EXECUTABLE)) {
+ g_free (path);
+ path = NULL;
+ }
+ }
+
+ gtk_widget_destroy (GTK_WIDGET (fsel));
+ g_object_unref (fsel);
+
+ return path;
+}
+
+
void
gnm_sub_solver_flush (GnmSubSolver *subsol)
{
@@ -1619,13 +1685,14 @@ gnm_solver_factory_create (GnmSolverFactory *factory,
}
gboolean
-gnm_solver_factory_functional (GnmSolverFactory *factory)
+gnm_solver_factory_functional (GnmSolverFactory *factory,
+ WBCGtk *wbcg)
{
if (factory == NULL)
return FALSE;
return (factory->functional == NULL ||
- factory->functional (factory));
+ factory->functional (factory, wbcg));
}
static int
diff --git a/src/tools/gnm-solver.h b/src/tools/gnm-solver.h
index 179d1da..70a90e7 100644
--- a/src/tools/gnm-solver.h
+++ b/src/tools/gnm-solver.h
@@ -5,6 +5,7 @@
#include <glib-object.h>
#include <dependent.h>
#include <numbers.h>
+#include <wbc-gtk.h>
G_BEGIN_DECLS
@@ -292,6 +293,10 @@ GnmCell *gnm_sub_solver_find_cell (GnmSubSolver *subsol, const char *name);
const char *gnm_sub_solver_get_cell_name (GnmSubSolver *subsol,
GnmCell const *cell);
+char *gnm_sub_solver_locate_binary (const char *binary, const char *solver,
+ const char *url,
+ WBCGtk *wbcg);
+
/* ------------------------------------------------------------------------- */
#define GNM_SOLVER_FACTORY_TYPE (gnm_solver_factory_get_type ())
@@ -300,7 +305,8 @@ const char *gnm_sub_solver_get_cell_name (GnmSubSolver *subsol,
typedef GnmSolver * (*GnmSolverCreator) (GnmSolverFactory *,
GnmSolverParameters *);
-typedef gboolean (*GnmSolverFactoryFunctional) (GnmSolverFactory *);
+typedef gboolean (*GnmSolverFactoryFunctional) (GnmSolverFactory *,
+ WBCGtk *);
struct GnmSolverFactory_ {
GObject parent;
@@ -325,7 +331,8 @@ GnmSolverFactory *gnm_solver_factory_new (const char *id,
GnmSolverFactoryFunctional funct);
GnmSolver *gnm_solver_factory_create (GnmSolverFactory *factory,
GnmSolverParameters *param);
-gboolean gnm_solver_factory_functional (GnmSolverFactory *factory);
+gboolean gnm_solver_factory_functional (GnmSolverFactory *factory,
+ WBCGtk *wbcg);
GSList *gnm_solver_db_get (void);
void gnm_solver_db_register (GnmSolverFactory *factory);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]