Ejemplo n.º 1
0
void
exprTri1 (syn_ctx * ctx, char *name)
{
	char *buf = cell_name ("TRI");
	if (!name)
	{			//create definition
		if (!exists (ctx, buf))
		{
			o_p ("(cell %s (celltype GENERIC)\n", buf);
			i_i ();
			o_p ("(view netlist (viewtype NETLIST)\n");
			i_i ();
			o_p ("(interface\n");
			i_i ();
			o_p ("(port Q (direction OUTPUT))\n");	//output
			o_p ("(port A (direction INPUT))\n");	//input
			o_p ("(port ENA (direction INPUT))\n");	//ctrl
			i_d ();
			o_p (")\n");	//interface
			i_d ();	//builtin, no contents
			o_p (")\n");	//view
			i_d ();
			o_p (")\n");	//cell
			hash_put (ctx, buf);
		}
	}
	else
	{
		o_p ("(instance %s (viewref netlist (cellref %s (libraryref DESIGNS))))\n", name, buf);
	}
	free (buf);
}
Ejemplo n.º 2
0
static const char *
glpk_var_name (GnmSubSolver *ssol, GnmCell const *cell)
{
    if (ssol)
        return gnm_sub_solver_get_cell_name (ssol, cell);
    return cell_name (cell);
}
Ejemplo n.º 3
0
/**
 * dialog_init:
 * @state:
 *
 * Create the dialog (guru).
 *
 **/
static gboolean
dialog_init (SolverState *state)
{
	GtkGrid *grid;
	GnmSolverParameters *param;
	GtkCellRenderer *renderer;
	GtkListStore *store;
	GtkTreeViewColumn *column;
	GSList *cl;
	GnmCell *target_cell;
	GnmValue const *input;
	int i;

	param = state->sheet->solver_parameters;

	state->gui = gnm_gtk_builder_load ("solver.ui", NULL, GO_CMD_CONTEXT (state->wbcg));
        if (state->gui == NULL)
                return TRUE;

	state->dialog = go_gtk_builder_get_widget (state->gui, "Solver");
        if (state->dialog == NULL)
                return TRUE;

	state->notebook = go_gtk_builder_get_widget (state->gui, "solver_notebook");

	/*  buttons  */
	state->solve_button  = go_gtk_builder_get_widget (state->gui, "solvebutton");
	g_signal_connect (G_OBJECT (state->solve_button), "clicked",
			  G_CALLBACK (cb_dialog_solve_clicked), state);

	state->close_button  = go_gtk_builder_get_widget (state->gui, "closebutton");
	g_signal_connect (G_OBJECT (state->close_button), "clicked",
			  G_CALLBACK (cb_dialog_close_clicked), state);

	state->help_button = go_gtk_builder_get_widget (state->gui, "helpbutton");
	gnm_init_help_button (state->help_button, GNUMERIC_HELP_LINK_SOLVER);

	state->add_button  = go_gtk_builder_get_widget (state->gui, "addbutton");
	gtk_button_set_alignment (GTK_BUTTON (state->add_button), 0.5, .5);
	g_signal_connect_swapped (G_OBJECT (state->add_button), "clicked",
		G_CALLBACK (cb_dialog_add_clicked), state);

	state->change_button = go_gtk_builder_get_widget (state->gui,
						     "changebutton");
	g_signal_connect (G_OBJECT (state->change_button), "clicked",
			  G_CALLBACK (cb_dialog_change_clicked), state);

	state->delete_button = go_gtk_builder_get_widget (state->gui,
						     "deletebutton");
	gtk_button_set_alignment (GTK_BUTTON (state->delete_button), 0.5, .5);
	g_signal_connect (G_OBJECT (state->delete_button), "clicked",
			  G_CALLBACK (cb_dialog_delete_clicked), state);

	state->stop_button = go_gtk_builder_get_widget (state->gui, "stopbutton");
	g_signal_connect_swapped (G_OBJECT (state->stop_button),
				  "clicked", G_CALLBACK (cb_stop_solver),
				  state);

	/* target_entry */
	grid = GTK_GRID (go_gtk_builder_get_widget (state->gui,
						 "parameter-grid"));
	state->target_entry = gnm_expr_entry_new (state->wbcg, TRUE);
	gnm_expr_entry_set_flags (state->target_entry,
		GNM_EE_SINGLE_RANGE |
		GNM_EE_FORCE_ABS_REF |
		GNM_EE_SHEET_OPTIONAL, GNM_EE_MASK);
	gtk_widget_set_hexpand (GTK_WIDGET (state->target_entry), TRUE);
	gtk_grid_attach (grid, GTK_WIDGET (state->target_entry), 1, 0, 2, 1);
	gnm_editable_enters (GTK_WINDOW (state->dialog),
				  GTK_WIDGET (state->target_entry));
	gtk_widget_show (GTK_WIDGET (state->target_entry));
	g_signal_connect_after (G_OBJECT (state->target_entry),	"changed",
			G_CALLBACK (dialog_set_main_button_sensitivity),
				state);

	/* change_cell_entry */
	state->change_cell_entry = gnm_expr_entry_new (state->wbcg, TRUE);
	gnm_expr_entry_set_flags (state->change_cell_entry,
		GNM_EE_SINGLE_RANGE |
		GNM_EE_FORCE_ABS_REF |
		GNM_EE_SHEET_OPTIONAL, GNM_EE_MASK);
	gtk_widget_set_hexpand (GTK_WIDGET (state->change_cell_entry), TRUE);
	gtk_grid_attach (grid,
	                 GTK_WIDGET (state->change_cell_entry), 1, 2, 2, 1);
	gnm_editable_enters (GTK_WINDOW (state->dialog),
				  GTK_WIDGET (state->change_cell_entry));
	gtk_widget_show (GTK_WIDGET (state->change_cell_entry));
	g_signal_connect_after (G_OBJECT (state->change_cell_entry), "changed",
		G_CALLBACK (dialog_set_main_button_sensitivity), state);

	/* Algorithm */
	state->algorithm_combo = GTK_COMBO_BOX
		(go_gtk_builder_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);
	fill_algorithm_combo (state, param->options.model_type);

	for (i = 0; model_type_group[i]; i++) {
		const char *bname = model_type_group[i];
		GtkWidget *w = go_gtk_builder_get_widget(state->gui, bname);
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w),
					      param->options.model_type ==
					      (GnmSolverModelType)i);
		g_signal_connect (G_OBJECT (w), "clicked",
				  G_CALLBACK (cb_dialog_model_type_clicked), state);
	}

	/* Options */
	state->max_iter_entry = go_gtk_builder_get_widget (state->gui,
						      "max_iter_entry");
	gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->max_iter_entry),
				   param->options.max_iter);

	state->max_time_entry = go_gtk_builder_get_widget (state->gui,
						      "max_time_entry");
	gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->max_time_entry),
				   param->options.max_time_sec);

	state->gradient_order_entry = go_gtk_builder_get_widget (state->gui,
								 "gradient_order_entry");
	gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->gradient_order_entry),
				   param->options.gradient_order);

	/* lhs_entry */
	grid = GTK_GRID (go_gtk_builder_get_widget (state->gui,
	                                            "constraints-grid"));
	state->lhs.entry = gnm_expr_entry_new (state->wbcg, TRUE);
	gnm_expr_entry_set_flags (state->lhs.entry,
		GNM_EE_SINGLE_RANGE |
		GNM_EE_FORCE_ABS_REF |
		GNM_EE_SHEET_OPTIONAL, GNM_EE_MASK);
	gtk_widget_set_hexpand (GTK_WIDGET (state->lhs.entry), TRUE);
	gtk_grid_attach (grid, GTK_WIDGET (state->lhs.entry), 0, 4, 1, 1);
	state->lhs.label = go_gtk_builder_get_widget (state->gui, "lhs_label");
	gtk_label_set_mnemonic_widget (GTK_LABEL (state->lhs.label),
		GTK_WIDGET (state->lhs.entry));
	gtk_widget_show (GTK_WIDGET (state->lhs.entry));
	g_signal_connect_after (G_OBJECT (state->lhs.entry),
		"changed",
		G_CALLBACK (dialog_set_sec_button_sensitivity), state);
	g_signal_connect_swapped (
		gnm_expr_entry_get_entry (GNM_EXPR_ENTRY (state->lhs.entry)),
		"activate", G_CALLBACK (cb_dialog_add_clicked), state);

	/* rhs_entry */
	state->rhs.entry = gnm_expr_entry_new (state->wbcg, TRUE);
	gnm_expr_entry_set_flags (state->rhs.entry,
				  GNM_EE_SINGLE_RANGE |
				  GNM_EE_FORCE_ABS_REF |
				  GNM_EE_SHEET_OPTIONAL |
				  GNM_EE_CONSTANT_ALLOWED,
				  GNM_EE_MASK);
	gtk_widget_set_hexpand (GTK_WIDGET (state->rhs.entry), TRUE);
	gtk_grid_attach (grid, GTK_WIDGET (state->rhs.entry), 2, 4, 1, 1);
	gtk_widget_show (GTK_WIDGET (state->rhs.entry));
	state->rhs.label = go_gtk_builder_get_widget (state->gui, "rhs_label");
	gtk_label_set_mnemonic_widget (
		GTK_LABEL (state->rhs.label), GTK_WIDGET (state->rhs.entry));
	g_signal_connect_after (G_OBJECT (state->rhs.entry),
		"changed",
		G_CALLBACK (dialog_set_sec_button_sensitivity), state);
	g_signal_connect_swapped (
		gnm_expr_entry_get_entry (GNM_EXPR_ENTRY (state->rhs.entry)),
		"activate", G_CALLBACK (cb_dialog_add_clicked), state);

	/* type_menu */
	state->type_combo = GTK_COMBO_BOX
		(go_gtk_builder_get_widget (state->gui, "type_menu"));
	gtk_combo_box_set_active (state->type_combo, 0);
	g_signal_connect (state->type_combo, "changed",
			  G_CALLBACK (dialog_set_sec_button_sensitivity),
			  state);

	/* constraint_list */
	state->constraint_list = GTK_TREE_VIEW (go_gtk_builder_get_widget
					    (state->gui, "constraint_list"));

	state->constr = NULL;
	g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (state->constraint_list)), "changed",
			  G_CALLBACK (constraint_select_click), state);
	gtk_tree_view_set_reorderable (state->constraint_list, TRUE);
	store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);
	gtk_tree_view_set_model (state->constraint_list, GTK_TREE_MODEL(store));
	renderer = gtk_cell_renderer_text_new ();
	column = gtk_tree_view_column_new_with_attributes (
			_("Subject to the Constraints:"),
			renderer, "text", 0, NULL);
	gtk_tree_view_column_set_expand (column, TRUE);
	gtk_tree_view_append_column (state->constraint_list, column);

	{
		GtkWidget *w = GTK_WIDGET (state->constraint_list);
		int width, height, vsep;
		PangoLayout *layout =
			gtk_widget_create_pango_layout (w, "Mg19");

		gtk_widget_style_get (w,
				      "vertical_separator", &vsep,
				      NULL);

		pango_layout_get_pixel_size (layout, &width, &height);
		gtk_widget_set_size_request (w,
					     -1,
					     (2 * height + vsep) * (4 + 1));
		g_object_unref (layout);
	}

/* Loading the old solver specs... from param  */

	for (cl = param->constraints; cl; cl = cl->next) {
		GnmSolverConstraint const *c = cl->data;
		GtkTreeIter iter;
		char *str;

		gtk_list_store_append (store, &iter);
		str = gnm_solver_constraint_as_str (c, state->sheet);
		gtk_list_store_set (store, &iter, 0, str, 1, c, -1);
		g_free (str);
	}
	g_object_unref (store);

	INIT_BOOL_ENTRY ("autoscale_button", options.automatic_scaling);
	INIT_BOOL_ENTRY ("non_neg_button", options.assume_non_negative);
	INIT_BOOL_ENTRY ("all_int_button", options.assume_discrete);
	INIT_BOOL_ENTRY ("program", options.program_report);
	INIT_BOOL_ENTRY ("sensitivity", options.sensitivity_report);

	input = gnm_solver_param_get_input (param);
	if (input != NULL)
		gnm_expr_entry_load_from_text (state->change_cell_entry,
					       value_peek_string (input));
	target_cell = gnm_solver_param_get_target_cell (param);
	if (target_cell)
		gnm_expr_entry_load_from_text (state->target_entry,
					       cell_name (target_cell));
	else {
		SheetView *sv = wb_control_cur_sheet_view
			(GNM_WBC (state->wbcg));
		if (sv) {
			GnmRange first = {sv->edit_pos, sv->edit_pos};
			gnm_expr_entry_load_from_range (state->target_entry,
							state->sheet, &first);
		}
	}

	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (
		go_gtk_builder_get_widget(state->gui, "max_button")),
			param->problem_type == GNM_SOLVER_MAXIMIZE);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (
		go_gtk_builder_get_widget(state->gui, "min_button")),
			param->problem_type == GNM_SOLVER_MINIMIZE);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (
		go_gtk_builder_get_widget(state->gui, "no_scenario")),
			! param->options.add_scenario);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (
		go_gtk_builder_get_widget(state->gui, "optimal_scenario")),
			param->options.add_scenario);

	state->scenario_name_entry = go_gtk_builder_get_widget
		(state->gui, "scenario_name_entry");
	gtk_entry_set_text (GTK_ENTRY (state->scenario_name_entry),
			    param->options.scenario_name);

	state->run.status_widget = go_gtk_builder_get_widget (state->gui, "solver_status_label");
	state->run.problem_status_widget = go_gtk_builder_get_widget (state->gui, "problem_status_label");
	state->run.objective_value_widget = go_gtk_builder_get_widget (state->gui, "objective_value_label");
	state->run.timer_widget = go_gtk_builder_get_widget (state->gui, "elapsed_time_label");
	state->run.spinner = go_gtk_builder_get_widget (state->gui, "run_spinner");


/* Done */
	gnm_expr_entry_grab_focus (state->target_entry, FALSE);
	wbcg_set_entry (state->wbcg, state->target_entry);

	dialog_set_main_button_sensitivity (NULL, state);
	dialog_set_sec_button_sensitivity (NULL, state);

/* dialog */
	wbc_gtk_attach_guru (state->wbcg, state->dialog);

	g_signal_connect_swapped (G_OBJECT (state->dialog),
				  "destroy",
				  G_CALLBACK (cb_dialog_solver_destroy),
				  state);
	g_object_set_data_full (G_OBJECT (state->dialog),
				"state", state,
				(GDestroyNotify)unref_state);

	return FALSE;
}
Ejemplo n.º 4
0
void
tbl_bufif (syn_ctx * ctx, char *name, int width, Opdesc const *op)
{
	char *buf = cell_name ("%s_%d", op->name, width);
	assert (width > 0);
	if (!name)
	{			//create definition
		if (!exists (ctx, buf))
		{
			int i;
			char *inv1 = NULL;
			char **inv_en = NULL;
			char **tris = NULL;
			if (op->buf_pol)
			{
				exprInv (ctx, NULL, width);
			}
			if (!op->en_pol)
			{
				exprInv (ctx, NULL, 1);
			}
			exprTri1 (ctx, NULL);


			o_p ("(cell %s (celltype GENERIC)\n", buf);
			i_i ();
			o_p ("(view netlist (viewtype NETLIST)\n");
			i_i ();
			o_p ("(interface\n");
			i_i ();
			for (i = 0; i < width; i++)
				o_p ("(port A_%d (direction INPUT))\n", i);	//inputs
			for (i = 0; i < width; i++)
				o_p ("(port B_%d (direction INPUT))\n", i);	//the enable
			for (i = 0; i < width; i++)
				o_p ("(port Q_%d (direction OUTPUT))\n", i);	//outputs
			i_d ();
			o_p (")\n");	//interface
			o_p ("(contents\n");
			i_i ();
			if (op->buf_pol)
			{
				inv1 = l_n ();
				exprInv (ctx, inv1, width);
			}

			if (!op->en_pol)
			{
				inv_en = calloc (width, sizeof (char *));
				assert (inv_en);
				for (i = 0; i < width; i++)
				{
					inv_en[i] = l_n ();
					exprInv (ctx, inv_en[i], 1);
				}
			}

			tris = calloc (width, sizeof (char *));
			assert (tris);
			for (i = 0; i < width; i++)
			{
				tris[i] = l_n ();
				exprTri1 (ctx, tris[i]);
			}

			if (op->buf_pol)
			{
				for (i = 0; i < width; i++)
				{
					n_n ();
					o_p ("(portref A_%d)\n", i);
					o_p ("(portref A_%d (instanceref %s))\n", i, inv1);
					n_e ();
					n_n ();
					o_p ("(portref Q_%d (instanceref %s))\n", i, inv1);
					o_p ("(portref A (instanceref %s))\n",
					     tris[i]);
					n_e ();
				}
			}
			else
			{
				for (i = 0; i < width; i++)
				{
					n_n ();
					o_p ("(portref A_%d)\n", i);
					o_p ("(portref A (instanceref %s))\n",
					     tris[i]);
					n_e ();

				}
			}

			if (!op->en_pol)
			{
				for (i = 0; i < width; i++)
				{
					n_n ();
					o_p ("(portref B_%d)\n");
					o_p ("(portref A (instanceref %s))\n",
					     inv_en[i]);
					n_e ();
					n_n ();
					o_p ("(portref Q (instanceref %s))\n",
					     inv_en[i]);
					o_p ("(portref ENA (instanceref %s))\n", tris[i]);
					n_e ();
				}

			}
			else
			{
				for (i = 0; i < width; i++)
				{
					n_n ();
					o_p ("(portref B_%d)\n", i);
					o_p ("(portref ENA (instanceref %s))\n", tris[i]);
					n_e ();
				}
			}

			for (i = 0; i < width; i++)
			{
				n_n ();
				o_p ("(portref Q (instanceref %s))\n",
				     tris[i]);
				o_p ("(portref Q_%d)\n", i);
				n_e ();
			}

			i_d ();
			o_p (")\n");	//contents
			i_d ();
			o_p (")\n");	//view
			i_d ();
			o_p (")\n");	//cell
			hash_put (ctx, buf);
			for (i = 0; i < width; i++)
				free (tris[i]);
			free (tris);
			if (!op->en_pol)
			{
				for (i = 0; i < width; i++)
					free (inv_en[i]);
				free (inv_en);
			}
			if (op->buf_pol)
				free (inv1);
		}
	}
	else
	{
		o_p ("(instance %s (viewref netlist (cellref %s (libraryref DESIGNS))))\n", name, buf);
	}
	free (buf);
}
Ejemplo n.º 5
0
/**
 * gnm_validation_eval:
 * @wbc:
 * @mstyle:
 * @sheet:
 *
 * validation set in the GnmStyle if applicable.
 **/
ValidationStatus
gnm_validation_eval (WorkbookControl *wbc, GnmStyle const *mstyle,
		 Sheet *sheet, GnmCellPos const *pos, gboolean *showed_dialog)
{
	GnmValidation const *v;
	GnmCell *cell;
	GnmValue *val;
	gnm_float x;
	int nok, i;
	GnmEvalPos ep;

	if (showed_dialog) *showed_dialog = FALSE;

	v = gnm_style_get_validation (mstyle);
	if (v == NULL)
		return GNM_VALIDATION_STATUS_VALID;

	if (v->type == GNM_VALIDATION_TYPE_ANY)
		return GNM_VALIDATION_STATUS_VALID;

	cell = sheet_cell_get (sheet, pos->col, pos->row);
	if (cell != NULL)
		gnm_cell_eval (cell);

	if (gnm_cell_is_empty (cell)) {
		if (v->allow_blank)
			return GNM_VALIDATION_STATUS_VALID;
		BARF (g_strdup_printf (_("Cell %s is not permitted to be blank"),
				       cell_name (cell)));
	}

	val = cell->value;
	switch (val->type) {
	case VALUE_ERROR:
		if (typeinfo[v->type].errors_not_allowed)
			BARF (g_strdup_printf (_("Cell %s is not permitted to contain error values"),
					       cell_name (cell)));
		break;

	case VALUE_BOOLEAN:
		if (typeinfo[v->type].bool_always_ok)
			return GNM_VALIDATION_STATUS_VALID;
		break;

	case VALUE_STRING:
		if (typeinfo[v->type].strings_not_allowed)
			BARF (g_strdup_printf (_("Cell %s is not permitted to contain strings"),
					       cell_name (cell)));
		break;

	default:
		break;
	}

	eval_pos_init_cell (&ep, cell);

	switch (v->type) {
	case GNM_VALIDATION_TYPE_AS_INT:
		x = value_get_as_float (val);
		if (gnm_fake_floor (x) == gnm_fake_ceil (x))
			break;
		else
			BARF (g_strdup_printf (_("'%s' is not an integer"),
					       value_peek_string (val)));

	case GNM_VALIDATION_TYPE_AS_NUMBER:
		x = value_get_as_float (val);
		break;

	case GNM_VALIDATION_TYPE_AS_DATE: /* What the hell does this do?  */
		x = value_get_as_float (val);
		if (x < 0)
			BARF (g_strdup_printf (_("'%s' is not a valid date"),
					       value_peek_string (val)));
		break;


	case GNM_VALIDATION_TYPE_AS_TIME: /* What the hell does this do?  */
		x = value_get_as_float (val);
		break;

	case GNM_VALIDATION_TYPE_IN_LIST: {
		GnmExprTop const *texpr = v->deps[0].texpr;
		if (texpr) {
			GnmValue *list = gnm_expr_top_eval
				(texpr, &ep,
				 GNM_EXPR_EVAL_PERMIT_NON_SCALAR | GNM_EXPR_EVAL_PERMIT_EMPTY);
			GnmValue *res = value_area_foreach (list, &ep, CELL_ITER_IGNORE_BLANK,
				 (GnmValueIterFunc) cb_validate_custom, val);
			value_release (list);
			if (res == NULL) {
				GnmParsePos pp;
				char *expr_str = gnm_expr_top_as_string
					(texpr,
					 parse_pos_init_evalpos (&pp, &ep),
					 ep.sheet->convs);
				char *msg = g_strdup_printf (_("%s does not contain the new value."), expr_str);
				g_free (expr_str);
				BARF (msg);
			}
		}
		return GNM_VALIDATION_STATUS_VALID;
	}

	case GNM_VALIDATION_TYPE_TEXT_LENGTH:
		/* XL appears to use a very basic value->string mapping that
		 * ignores formatting.
		 * eg len (12/13/01) == len (37238) = 5
		 * This seems wrong for
		 */
		x = g_utf8_strlen (value_peek_string (val), -1);
		break;

	case GNM_VALIDATION_TYPE_CUSTOM: {
		gboolean valid;
		GnmExprTop const *texpr = v->deps[0].texpr;

		if (!texpr)
			return GNM_VALIDATION_STATUS_VALID;

		val = gnm_expr_top_eval (texpr, &ep, GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
		valid = value_get_as_bool (val, NULL);
		value_release (val);

		if (valid)
			return GNM_VALIDATION_STATUS_VALID;
		else {
			GnmParsePos pp;
			char *expr_str = gnm_expr_top_as_string
				(texpr,
				 parse_pos_init_evalpos (&pp, &ep),
				 ep.sheet->convs);
			char *msg = g_strdup_printf (_("%s is not true."), expr_str);
			g_free (expr_str);
			BARF (msg);
		}
	}

	default:
		g_assert_not_reached ();
		return GNM_VALIDATION_STATUS_VALID;
	}

	if (v->op == GNM_VALIDATION_OP_NONE)
		return GNM_VALIDATION_STATUS_VALID;

	nok = 0;
	for (i = 0; i < opinfo[v->op].nops; i++) {
		GnmExprTop const *texpr_i = v->deps[i].texpr;
		GnmExprTop const *texpr;
		GnmValue *cres;

		if (!texpr_i) {
			nok++;
			continue;
		}

		texpr = gnm_expr_top_new
			(gnm_expr_new_binary
			 (gnm_expr_new_constant (value_new_float (x)),
			  opinfo[v->op].ops[i],
			  gnm_expr_copy (texpr_i->expr)));
		cres = gnm_expr_top_eval
			(texpr, &ep, GNM_EXPR_EVAL_SCALAR_NON_EMPTY);
		if (value_get_as_bool (cres, NULL))
			nok++;
		value_release (cres);
		gnm_expr_top_unref (texpr);
	}

	if (nok < opinfo[v->op].ntrue)
		BARF (g_strdup_printf (_("%s is out of permitted range"),
				       value_peek_string (val)));

	return GNM_VALIDATION_STATUS_VALID;
}
Ejemplo n.º 6
0
/**
 * cb_dialog_apply_clicked:
 * @button:
 * @state:
 *
 * Close (destroy) the dialog
 **/
static void
cb_dialog_apply_clicked (G_GNUC_UNUSED GtkWidget *button,
			 GoalSeekState *state)
{
	char *status_str;
	GoalSeekStatus status;
	GnmValue *target;
	GnmRangeRef const *r;
	GOFormat *format;

	if (state->warning_dialog != NULL)
		gtk_widget_destroy (state->warning_dialog);

	/* set up source */
	target = gnm_expr_entry_parse_as_value (state->set_cell_entry,
						state->sheet);
	if (target == NULL) {
		go_gtk_notice_nonmodal_dialog (GTK_WINDOW(state->dialog),
					  &(state->warning_dialog),
					  GTK_MESSAGE_ERROR,
					  _("You should introduce a valid cell "
					    "name in 'Set Cell:'!"));
		gnm_expr_entry_grab_focus (state->set_cell_entry, TRUE);
		return;
	}
	r = &target->v_range.cell;
	state->set_cell = sheet_cell_get (r->a.sheet, r->a.col, r->a.row);
	value_release (target);
	if (state->set_cell == NULL || !gnm_cell_has_expr (state->set_cell)) {
		go_gtk_notice_nonmodal_dialog (GTK_WINDOW(state->dialog),
					  &(state->warning_dialog),
					  GTK_MESSAGE_ERROR,
					  _("The cell named in 'Set Cell:' "
					    "must contain a formula!"));
		gnm_expr_entry_grab_focus (state->set_cell_entry, TRUE);
		return;
	}

	/* set up source */
	target = gnm_expr_entry_parse_as_value (state->change_cell_entry,
						state->sheet);
	if (target == NULL) {
		go_gtk_notice_nonmodal_dialog (GTK_WINDOW(state->dialog),
					  &(state->warning_dialog),
					  GTK_MESSAGE_ERROR,
					  _("You should introduce a valid cell "
					    "name in 'By Changing Cell:'!"));
		gnm_expr_entry_grab_focus (state->change_cell_entry, TRUE);
		return;
	}

	r = &target->v_range.cell;
	state->change_cell = sheet_cell_fetch (r->a.sheet, r->a.col, r->a.row);
	value_release (target);
	if (gnm_cell_has_expr (state->change_cell)) {
		go_gtk_notice_nonmodal_dialog (GTK_WINDOW(state->dialog),
					  &(state->warning_dialog),
					  GTK_MESSAGE_ERROR,
					  _("The cell named in 'By changing cell' "
					    "must not contain a formula."));
		gnm_expr_entry_grab_focus (state->change_cell_entry, TRUE);
		return;
	}


	format = gnm_style_get_format (gnm_cell_get_style (state->set_cell));
	if (entry_to_float_with_format (GTK_ENTRY(state->to_value_entry),
					&state->target_value, TRUE, format)){
		go_gtk_notice_nonmodal_dialog (GTK_WINDOW(state->dialog),
					  &(state->warning_dialog),
					  GTK_MESSAGE_ERROR,
					  _("The value given in 'To Value:' "
					    "is not valid."));
		focus_on_entry (GTK_ENTRY(state->to_value_entry));
		return;
	}

	format = gnm_style_get_format (gnm_cell_get_style (state->change_cell));
	if (entry_to_float_with_format (GTK_ENTRY(state->at_least_entry),
					 &state->xmin, TRUE, format)) {
		state->xmin = -max_range_val;
		gtk_entry_set_text (GTK_ENTRY (state->at_least_entry), "");
	}

	if (entry_to_float_with_format (GTK_ENTRY(state->at_most_entry), &state->xmax,
					TRUE, format)) {
		state->xmax = +max_range_val;
		gtk_entry_set_text (GTK_ENTRY (state->at_most_entry), "");
	}

	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;
	}
	state->old_cell = state->change_cell;
	state->old_value = value_dup (state->change_cell->value);

	status = gnumeric_goal_seek (state);

	switch (status) {
	case GOAL_SEEK_OK: {
		const char *actual_str;
		const char *solution_str;
		GOFormat *format = go_format_general ();
		GnmValue *error_value = value_new_float (state->target_value -
						      value_get_as_float (state->set_cell->value));
		char *target_str = format_value (format, error_value, NULL, -1,
						 workbook_date_conv (state->wb));
		gtk_label_set_text (GTK_LABEL (state->target_value_label), target_str);
		g_free (target_str);
		value_release (error_value);

		status_str =
			g_strdup_printf (_("Goal seeking with cell %s found a solution."),
					 cell_name (state->set_cell));
		gtk_label_set_text (GTK_LABEL (state->result_label), status_str);
		g_free (status_str);

		/* FIXME?  Do a format?  */
		actual_str = state->set_cell->value
			? value_peek_string (state->set_cell->value)
			: "";
		gtk_label_set_text (GTK_LABEL (state->current_value_label), actual_str);

		solution_str = state->change_cell->value
			? value_peek_string (state->change_cell->value)
			: "";
		gtk_label_set_text (GTK_LABEL (state->solution_label), solution_str);

		break;
	}

	default:
		status_str =
			g_strdup_printf (_("Goal seeking with cell %s did not find a solution."),
					 cell_name (state->set_cell));
		gtk_label_set_text (GTK_LABEL (state->result_label), status_str);
		g_free (status_str);
		gtk_label_set_text (GTK_LABEL (state->current_value_label), "");
		gtk_label_set_text (GTK_LABEL (state->solution_label), "");
		gtk_label_set_text (GTK_LABEL (state->target_value_label), "");
		break;
	}
	state->cancelled = FALSE;

	gtk_widget_show (state->result_table);
	return;
}