[gnumeric] solver: fix menus in dialog to show what the factory db says.



commit f54534e389c1ff95ca5ad7d76f9b92dde3f758dd
Author: Morten Welinder <terra gnome org>
Date:   Wed Nov 11 21:08:28 2009 -0500

    solver: fix menus in dialog to show what the factory db says.

 src/dialogs/dialog-solver.c |  176 +++++++++++++++----------------------------
 src/gnumeric.h              |    2 +
 src/solver.h                |    2 +-
 src/tools/gnm-solver.h      |    2 -
 src/tools/solver/reports.c  |    8 +-
 src/tools/solver/solver.c   |    6 +-
 6 files changed, 71 insertions(+), 125 deletions(-)
---
diff --git a/src/dialogs/dialog-solver.c b/src/dialogs/dialog-solver.c
index a1ed74a..d158690 100644
--- a/src/dialogs/dialog-solver.c
+++ b/src/dialogs/dialog-solver.c
@@ -95,19 +95,6 @@ typedef struct {
 } SolverState;
 
 
-typedef struct {
-	char const *name;
-	SolverAlgorithmType alg;
-	SolverModelType type;
-} algorithm_def_t;
-
-static algorithm_def_t const algorithm_defs[] = {
-	{ N_("Simplex (LP Solve)"), LPSolve, SolverLPModel },
-	{ N_("Revised Simplex (GLPK 4.9)"), GLPKSimplex, SolverLPModel },
-	{ N_("< Not available >"), QPDummy, SolverQPModel },
-	{ NULL, 0, 0 }
-};
-
 static char const * const problem_type_group[] = {
 	"min_button",
 	"max_button",
@@ -122,9 +109,6 @@ static char const * const model_type_group[] = {
 	NULL
 };
 
-static GList *lp_alg_name_list = NULL;
-static GList *qp_alg_name_list = NULL;
-
 static void
 constraint_fill (SolverConstraint *c, SolverState *state)
 {
@@ -301,47 +285,65 @@ dialog_set_main_button_sensitivity (G_GNUC_UNUSED GtkWidget *dummy,
 	gtk_widget_set_sensitive (state->solve_button, ready);
 }
 
+static gboolean
+fill_algorithm_combo (SolverState *state, SolverModelType type)
+{
+	GtkListStore *store =
+		gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);
+	GSList *solvers, *l;
+
+	gtk_combo_box_set_model (state->algorithm_combo, GTK_TREE_MODEL (store));
+
+	l = NULL;
+	for (solvers = gnm_solver_db_get (); solvers; solvers = solvers->next) {
+		GnmSolverFactory *entry = solvers->data;
+		if (type != entry->type)
+			continue;
+		l = g_slist_prepend (l, entry);
+	}
+	solvers = l;
+
+	gtk_widget_set_sensitive (GTK_WIDGET (state->solve_button),
+				  solvers != NULL);
+	if (!solvers)
+		return FALSE;
+
+	for (l = solvers; l; l = l->next) {
+		GnmSolverFactory *factory = l->data;
+		GtkTreeIter iter;
+
+		gtk_list_store_append (store, &iter);
+		gtk_list_store_set (store, &iter,
+				    0, factory->name,
+				    1, factory,
+				    -1);
+	}
+	g_slist_free (solvers);
+
+	gtk_combo_box_set_active (state->algorithm_combo, 0);
+
+	return TRUE;
+}
+
 static void
 cb_dialog_model_type_clicked (G_GNUC_UNUSED GtkWidget *button,
 			      SolverState *state)
 {
 	SolverModelType type;
-	GtkListStore *store;
-	GtkTreeIter iter;
-	GList *l = NULL;
+	gboolean any;
 
 	type = gnumeric_glade_group_value (state->gui, model_type_group);
-	store = gtk_list_store_new (1, G_TYPE_STRING);
-	gtk_combo_box_set_model (state->algorithm_combo, GTK_TREE_MODEL (store));
-	switch (type) {
-	case SolverLPModel:
-		l = lp_alg_name_list;
-		gtk_widget_set_sensitive (GTK_WIDGET (state->solve_button),
-					  TRUE);
-		break;
-	case SolverQPModel:
-		l = qp_alg_name_list;
-		gtk_widget_set_sensitive (GTK_WIDGET (state->solve_button),
-					  FALSE);
-		go_gtk_notice_nonmodal_dialog ((GtkWindow *) state->dialog,
-					  &(state->warning_dialog),
-					  GTK_MESSAGE_INFO,
-					  _("Looking for a subject for your "
-					    "thesis? Maybe you would like to "
-					    "write a QP solver for "
-					    "Gnumeric?"));
-		break;
-	default:
-		break;
-	}
-	while (l) {
-		gtk_list_store_append (store, &iter);
-		gtk_list_store_set (store, &iter,
-					0, l->data,
-					-1);
-		l = l->next;
+	any = fill_algorithm_combo (state, type);
+
+	if (!any) {
+		go_gtk_notice_nonmodal_dialog
+			(GTK_WINDOW (state->dialog),
+			 &(state->warning_dialog),
+			 GTK_MESSAGE_INFO,
+			 _("Looking for a subject for your thesis? "
+			   "Maybe you would like to write a solver for "
+			   "Gnumeric?"));
 	}
-	gtk_combo_box_set_active (state->algorithm_combo ,0);
 }
 
 static void
@@ -607,18 +609,11 @@ run_solver (SolverState *state, SolverParameters *param)
 	GnmSolver *sol = NULL;
 	GnmValue const *vinput;
 	GtkWindow *top = GTK_WINDOW (gtk_widget_get_toplevel (state->dialog));
-	GSList *solvers;
 	GnmSolverResult *res = NULL;
 
-	for (solvers = gnm_solver_db_get (); solvers; solvers = solvers->next) {
-		GnmSolverFactory *entry = solvers->data;
-		if (param->problem_type != entry->type)
-			continue;
-		g_printerr ("Trying solver %s...\n", entry->id);
-		sol = gnm_solver_factory_create (entry, param);
-		if (sol)
-			break;
-	}
+	sol = param->options.algorithm
+		? gnm_solver_factory_create (param->options.algorithm, param)
+		: NULL;
 	if (!sol) {
 		go_gtk_notice_dialog (top, GTK_MESSAGE_ERROR,
 				      _("No suitable solver available."));
@@ -779,14 +774,13 @@ cb_dialog_solve_clicked (G_GNUC_UNUSED GtkWidget *button,
 	GnmSolverResult           *res;
 	GnmValue                   *target_range;
 	GnmValue                   *input_range;
-	gint                    i;
 	gboolean                answer, sensitivity, limits, performance;
 	gboolean                program, dual_program;
 	GError *err = NULL;
 	SolverParameters        *param;
 	GtkTreeIter iter;
-	gchar *name;
 	GnmCell *target_cell;
+	GnmSolverFactory *factory = NULL;
 
 	param = state->sheet->solver_parameters;
 
@@ -813,16 +807,8 @@ cb_dialog_solve_clicked (G_GNUC_UNUSED GtkWidget *button,
 
 	gtk_combo_box_get_active_iter (state->algorithm_combo, &iter);
 	gtk_tree_model_get (gtk_combo_box_get_model (state->algorithm_combo),
-			    &iter, 0, &name, -1);
-	for (i = 0; algorithm_defs[i].name; i++) {
-		if (param->options.model_type == algorithm_defs[i].type)
-			if (strcmp (algorithm_defs[i].name, name) == 0) {
-				param->options.algorithm =
-					algorithm_defs[i].alg;
-				break;
-			}
-	}
-	g_free (name);
+			    &iter, 1, &factory, -1);
+	param->options.algorithm = factory;
 
 	param->options.assume_non_negative = gtk_toggle_button_get_active
 		(GTK_TOGGLE_BUTTON (glade_xml_get_widget (state->gui,
@@ -924,36 +910,15 @@ dialog_init (SolverState *state)
 {
 	GtkTable                *table;
 	SolverParameters        *param;
-	int                     i;
 	GtkCellRenderer *renderer;
 	GtkListStore *store;
-	GtkTreeIter iter;
 	GtkTreeViewColumn *column;
-	GList *l = NULL;
 	GSList *cl;
 	GnmCell *target_cell;
 	GnmValue const *input;
 
 	param = state->sheet->solver_parameters;
 
-	if (lp_alg_name_list == NULL) {
-		for (i = 0; algorithm_defs[i].name; i++)
-			switch (algorithm_defs[i].type) {
-			case SolverLPModel:
-				lp_alg_name_list = g_list_append
-					(lp_alg_name_list,
-					 (gpointer) algorithm_defs[i].name);
-				break;
-			case SolverQPModel:
-				qp_alg_name_list = g_list_append
-					(qp_alg_name_list,
-					 (gpointer) algorithm_defs[i].name);
-				break;
-			default:
-				break;
-			}
-	}
-
 	state->gui = gnm_glade_xml_new (GO_CMD_CONTEXT (state->wbcg),
 		"solver.glade", NULL, NULL);
         if (state->gui == NULL)
@@ -1032,29 +997,10 @@ dialog_init (SolverState *state)
 		(glade_xml_get_widget (state->gui, "algorithm_combo"));
 	renderer = (GtkCellRenderer*) gtk_cell_renderer_text_new();
 	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (state->algorithm_combo), renderer, TRUE);
-    gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (state->algorithm_combo), renderer,
-                                        "text", 0,
-                                        NULL);
-	store = gtk_list_store_new (1, G_TYPE_STRING);
-	gtk_combo_box_set_model (state->algorithm_combo, GTK_TREE_MODEL (store));
-	switch (param->options.model_type) {
-	case SolverLPModel:
-		l = lp_alg_name_list;
-		break;
-	case SolverQPModel:
-		l = qp_alg_name_list;
-		break;
-	default:
-		break;
-	}
-	while (l) {
-		gtk_list_store_append (store, &iter);
-		gtk_list_store_set (store, &iter,
-				    0, l->data,
-				    -1);
-		l = l->next;
-	}
-	gtk_combo_box_set_active (state->algorithm_combo, 0);
+	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (state->algorithm_combo), renderer,
+					"text", 0,
+					NULL);
+	fill_algorithm_combo (state, param->options.model_type);
 
 	state->model_button =
 		glade_xml_get_widget(state->gui, "lp_model_button");
diff --git a/src/gnumeric.h b/src/gnumeric.h
index 818a54f..b8ac365 100644
--- a/src/gnumeric.h
+++ b/src/gnumeric.h
@@ -182,7 +182,9 @@ typedef struct _GnmInputMsg		GnmInputMsg;
 typedef struct _GnmSheetSlicer		GnmSheetSlicer;
 
 typedef struct _PrintInformation        PrintInformation;
+
 typedef struct _SolverParameters	SolverParameters;
+typedef struct GnmSolverFactory_        GnmSolverFactory;
 
 G_END_DECLS
 
diff --git a/src/solver.h b/src/solver.h
index 829f106..d8e2d0b 100644
--- a/src/solver.h
+++ b/src/solver.h
@@ -25,6 +25,7 @@ typedef enum {
 typedef struct {
 	int                 max_time_sec;
 	int                 max_iter;
+	GnmSolverFactory   *algorithm;
 	SolverModelType     model_type;
 	gboolean            assume_non_negative;
 	gboolean            assume_discrete;
@@ -38,7 +39,6 @@ typedef struct {
 	gboolean            dual_program_report;
 	gboolean            add_scenario;
 	gchar               *scenario_name;
-	SolverAlgorithmType algorithm;
 } SolverOptions;
 
 /* -------------------------------------------------------------------------- */
diff --git a/src/tools/gnm-solver.h b/src/tools/gnm-solver.h
index 44f2dee..62fd705 100644
--- a/src/tools/gnm-solver.h
+++ b/src/tools/gnm-solver.h
@@ -146,8 +146,6 @@ void gnm_sub_solver_flush (GnmSubSolver *subsol);
 #define GNM_SOLVER_FACTORY(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), GNM_SOLVER_FACTORY_TYPE, GnmSolverFactory))
 #define GNM_IS_SOLVER_FACTORY(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNM_SOLVER_FACTORY_TYPE))
 
-typedef struct GnmSolverFactory_ GnmSolverFactory;
-
 typedef GnmSolver * (*GnmSolverCreator) (GnmSolverFactory *,
 					 SolverParameters *);
 
diff --git a/src/tools/solver/reports.c b/src/tools/solver/reports.c
index 3fef10c..c04d34b 100644
--- a/src/tools/solver/reports.c
+++ b/src/tools/solver/reports.c
@@ -225,9 +225,9 @@ solver_prepare_reports (SolverProgram *program, SolverResults *res,
 	GnmCell const *target_cell;
 
 	if (res->param->options.model_type == SolverLPModel)
-	        alg = &lp_algorithm[param->options.algorithm];
+	        alg = &lp_algorithm[0 /* param->options.algorithm */];
 	else
-	        alg = &qp_algorithm[param->options.algorithm];
+	        alg = &qp_algorithm[0 /* param->options.algorithm */];
 
 	target_cell = gnm_solver_param_get_target_cell (res->param);
         get_input_variable_names (res, sheet);
@@ -245,9 +245,9 @@ solver_prepare_reports_success (SolverProgram *program, SolverResults *res,
 	const SolverLPAlgorithm *alg;
 
 	if (res->param->options.model_type == SolverLPModel)
-	        alg = &lp_algorithm[param->options.algorithm];
+	        alg = &lp_algorithm[0 /* param->options.algorithm */];
 	else
-	        alg = &qp_algorithm[param->options.algorithm];
+	        alg = &qp_algorithm[0 /* param->options.algorithm */];
 
 
 	/*
diff --git a/src/tools/solver/solver.c b/src/tools/solver/solver.c
index 54e3025..ef1a80f 100644
--- a/src/tools/solver/solver.c
+++ b/src/tools/solver/solver.c
@@ -79,7 +79,7 @@ gnm_solver_param_new (Sheet *sheet)
 	res->options.model_type          = SolverLPModel;
 	res->sheet                       = sheet;
 	res->options.assume_non_negative = TRUE;
-	res->options.algorithm           = GLPKSimplex;
+	res->options.algorithm           = NULL;
 	res->options.scenario_name       = g_strdup ("Optimal");
 	res->problem_type                = SolverMaximize;
 	res->constraints                 = NULL;
@@ -1255,10 +1255,10 @@ solver (WorkbookControl *wbc, Sheet *sheet, GError **err)
 
         switch (sheet->solver_parameters->options.model_type) {
 	case SolverLPModel:
-	        alg = &lp_algorithm [param->options.algorithm];
+	        alg = &lp_algorithm [0 /* param->options.algorithm */];
 		break;
 	case SolverQPModel:
-	        alg = &qp_algorithm [param->options.algorithm];
+	        alg = &qp_algorithm [0 /* param->options.algorithm */];
 		break;
 	case SolverNLPModel:
 	        return NULL;



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