Exemple #1
0
static gboolean
cb_exercise_pango (gpointer data)
{
	static int state = 0;

	WorkbookControl *wbc = data;
	SheetView	*sv  = wb_control_cur_sheet_view (wbc);

	if (state == 0) {
		sv_selection_reset (sv);
		sv_selection_add_full(sv, 0, 0, 0, 0, 40, STEP_SIZE*TEST_STEPS);
		cmd_area_set_text (wbc, sv, "=rand()", FALSE);
	} else if (state < TEST_STEPS) {
		SHEET_VIEW_FOREACH_CONTROL(wb_control_cur_sheet_view (wbc),
			sc, sc_set_top_left (sc, 0, state*STEP_SIZE););
static void
dialog_goto_load_selection (GotoState *state)
{
	SheetView *sv = wb_control_cur_sheet_view 
		(WORKBOOK_CONTROL (state->wbcg));
	GnmRange const *first = selection_first_range (sv, NULL, NULL);

	if (first != NULL) {
		gint rows = range_height (first);
		gint cols = range_width (first);
		GnmConventionsOut out;
		GString *str = g_string_new (NULL);
		GnmParsePos pp;
		GnmRangeRef rr;
		
		out.accum = str;
		out.pp = parse_pos_init_sheet (&pp, sv->sheet);
		out.convs = sheet_get_conventions (sv->sheet);
		gnm_cellref_init (&rr.a, NULL, first->start.col, 
				  first->start.row, TRUE);
		gnm_cellref_init (&rr.b, NULL, first->start.col, 
				  first->start.row, TRUE);
		rangeref_as_string (&out, &rr);
		gtk_entry_set_text (state->goto_text, str->str);
		gtk_editable_select_region (GTK_EDITABLE (state->goto_text),
					    0, -1);
		g_string_free (str, TRUE);
		cb_dialog_goto_update_sensitivity (NULL, state);
		gtk_spin_button_set_value (state->spin_rows, rows);
		gtk_spin_button_set_value (state->spin_cols, cols);
	} else
		cb_dialog_goto_update_sensitivity (NULL, state);

}
/**
 * cmd_slicer_refresh:
 * @wbc: the workbook control.
 **/
gboolean
cmd_slicer_refresh (WorkbookControl *wbc)
{
	CmdSlicerRefresh *me;
	char *r_name;
	SheetView *sv = wb_control_cur_sheet_view (wbc);
	GnmSheetSlicer *slicer;

	slicer = gnm_sheet_slicers_at_pos (sv->sheet, &sv->edit_pos);
	if (NULL == slicer)
		return FALSE;

	me = g_object_new (CMD_SLICER_REFRESH_TYPE, NULL);
	me->cmd.sheet = sv_sheet (sv);
	me->cmd.size = 1;  /* Updated below.  */
	me->orig_content = NULL;
	me->slicer = slicer;

	r_name = undo_range_name (me->cmd.sheet,
		gnm_sheet_slicer_get_range (slicer));
	me->cmd.cmd_descriptor = g_strdup_printf (_("Refreshing DataSlicer in %s"), r_name);
	g_free (r_name);

	return gnm_command_push_undo (wbc, G_OBJECT (me));
}
static void
wb_create_name (WorkbookControl *wbc, char const *text, GnmParsePos *pp)
{
	GnmRange const *r;
	GnmCellRef a, b;
	GnmExpr const *target_range;

	r = selection_first_range (wb_control_cur_sheet_view (wbc),
		                   GO_CMD_CONTEXT (wbc), _("Define Name"));
	if (r != NULL) {
		a.sheet = b.sheet = wb_control_cur_sheet (wbc);
		a.col = r->start.col;
		a.row = r->start.row;
		b.col = r->end.col;
		b.row = r->end.row;
		a.col_relative = a.row_relative = b.col_relative = b.row_relative = FALSE;
		pp->sheet = NULL; /* make it a global name */
		if (gnm_cellref_equal (&a, &b))
			target_range = gnm_expr_new_cellref (&a);
		else
			target_range = gnm_expr_new_constant (
				value_new_cellrange_unsafe (&a, &b));
		cmd_define_name (wbc, text, pp, gnm_expr_top_new (target_range), NULL);
	}
}
Exemple #5
0
void
dialog_fill_series (WBCGtk *wbcg)
{
	FillSeriesState *state;
	WorkbookControl *wbc = WORKBOOK_CONTROL (wbcg);
	SheetView       *sv = wb_control_cur_sheet_view (wbc);

	g_return_if_fail (wbcg != NULL);

	/* Only pop up one copy per workbook */
	if (gnumeric_dialog_raise_if_exists (wbcg, FILL_SERIES_KEY)) {
		return;
	}

	state = g_new (FillSeriesState, 1);

	if (dialog_tool_init ((GenericToolState *)state, wbcg, sv_sheet (sv),
			      GNUMERIC_HELP_LINK_FILL_SERIES,
			      "fill-series.ui", "Fill_series",
			      _("Could not create the Fill Series dialog."),
			      FILL_SERIES_KEY,
			      G_CALLBACK (cb_fill_series_ok_clicked), NULL,
			      G_CALLBACK (cb_fill_series_update_sensitivity),
			      0))
		return;

	gnm_dao_set_put (GNM_DAO (state->base.gdao), FALSE, FALSE);
	dialog_fill_series_tool_init (state);
	gtk_widget_show (state->base.dialog);

	return;
}
/**
 * dialog_preload_selection:
 * @state:
 * @entry
 *
 *
 **/
static void
dialog_preload_selection (GoalSeekState *state, GnmExprEntry *entry)
{
	GnmRange const *sel;

	sel = selection_first_range
		(wb_control_cur_sheet_view
		 (WORKBOOK_CONTROL (state->wbcg)), NULL, NULL);
	if (sel)
		gnm_expr_entry_load_from_range (entry,
						state->sheet, sel);
}
Exemple #7
0
void
dialog_data_table (WBCGtk *wbcg)
{
	GnmDialogDataTable *state;
	GnmRange const	*r;
	GnmRange	 input_range;
	SheetView	*sv;
	Sheet		*sheet;

	g_return_if_fail (wbcg != NULL);

	if (wbc_gtk_get_guru (wbcg) ||
	    gnm_dialog_raise_if_exists (wbcg, DIALOG_DATA_TABLE_KEY))
		return;

	sv = wb_control_cur_sheet_view (GNM_WBC (wbcg));
	r = selection_first_range (sv, GO_CMD_CONTEXT (wbcg), _("Create Data Table"));
	if (NULL == r)
		return;
	if (range_width	(r) <= 1 || range_height (r) <= 1) {
		GError *msg = g_error_new (go_error_invalid(), 0,
			_("The selection must have more than 1 column and row to create a Data Table."));
		go_cmd_context_error (GO_CMD_CONTEXT (wbcg), msg);
		g_error_free (msg);
		return;
	}
	input_range = *r;
	input_range.start.col++;
	input_range.start.row++;
	sheet = sv_sheet (sv);
	if (sheet_range_splits_region (sheet, &input_range, NULL,
				       GO_CMD_CONTEXT (wbcg), _("Data Table")))
		return;
	if (cmd_cell_range_is_locked_effective
	    (sheet, &input_range, GNM_WBC (wbcg),
					   _("Data Table")))
		return;


	state = g_new0 (GnmDialogDataTable, 1);
	state->wbcg  = wbcg;
	state->sheet = sheet;
	state->input_range = input_range;
	if (data_table_init (state, wbcg)) {
		go_gtk_notice_dialog (wbcg_toplevel (wbcg), GTK_MESSAGE_ERROR,
			_("Could not create the Data Table definition dialog."));
		g_free (state);
	}
}
/*
 * This is called when something is entered in the location entry.
 * We either go there (if the text refers to a cell by address or
 * name), or we try to define a name for the selection.
 */
gboolean
wb_control_parse_and_jump (WorkbookControl *wbc, char const *text)
{
	Sheet *sheet = wb_control_cur_sheet (wbc);
	GnmParsePos pp;
	GnmEvalPos ep;
	GnmValue *target;
	GnmRangeRef range;
	SheetView *sv;

	if (text == NULL || *text == '\0')
		return FALSE;

	sv = wb_control_cur_sheet_view (wbc);
	parse_pos_init_editpos (&pp, sv);
	target = value_new_cellrange_parsepos_str (&pp, text,
						   GNM_EXPR_PARSE_DEFAULT);
	if (target == NULL) {
		/* Not an address; is it a name? */
		GnmParsePos pp;
		GnmNamedExpr *nexpr = expr_name_lookup (
			parse_pos_init_sheet (&pp, sheet), text);

		/* If no name, or just a placeholder exists create a name */
		if (nexpr == NULL || expr_name_is_placeholder (nexpr)) {
			wb_create_name (wbc, text, &pp);
			return FALSE;
		} else {
			target = gnm_expr_top_get_range (nexpr->texpr);
			if (target == NULL) {
				go_cmd_context_error_invalid (GO_CMD_CONTEXT (wbc),
					_("Address"), text);
				return FALSE;
			}
		}
	}

	eval_pos_init_editpos (&ep, sv);
	gnm_cellref_make_abs (&range.a, &target->v_range.cell.a, &ep);
	gnm_cellref_make_abs (&range.b, &target->v_range.cell.b, &ep);
	value_release (target);

	return wb_control_jump (wbc, sheet, &range);
}
/*
 * Main entry point for the Cell Sort dialog box
 */
void
dialog_cell_sort (WBCGtk *wbcg)
{
	SortFlowState *state;
	GtkBuilder *gui;

	g_return_if_fail (wbcg != NULL);

	if (gnumeric_dialog_raise_if_exists (wbcg, CELL_SORT_KEY))
		return;

	gui = gnm_gtk_builder_new ("cell-sort.ui", NULL, GO_CMD_CONTEXT (wbcg));
    if (gui == NULL)
            return;

	state = g_new (SortFlowState, 1);
	state->wbcg  = wbcg;
	state->wb    = wb_control_get_workbook (WORKBOOK_CONTROL (wbcg));
	state->sv    = wb_control_cur_sheet_view (WORKBOOK_CONTROL (wbcg));
	state->sheet = sv_sheet (state->sv);
	state->warning_dialog = NULL;
	state->sel = NULL;
	state->sort_items = 0;
	state->gui = gui;
        state->dialog = go_gtk_builder_get_widget (state->gui, "CellSort");

	state->image_ascending =
		gtk_widget_render_icon_pixbuf (state->dialog,
					GTK_STOCK_SORT_ASCENDING,
					GTK_ICON_SIZE_LARGE_TOOLBAR);
	state->image_descending =
		gtk_widget_render_icon_pixbuf (state->dialog,
					GTK_STOCK_SORT_DESCENDING,
					GTK_ICON_SIZE_LARGE_TOOLBAR);
	dialog_init (state);

	gnumeric_keyed_dialog (state->wbcg, GTK_WINDOW (state->dialog),
			       CELL_SORT_KEY);

	gtk_widget_show (state->dialog);
}
Exemple #10
0
static void
wbcg_edit_init_markup (WBCGtk *wbcg, PangoAttrList *markup)
{
	SheetView const *sv;
	char const *text;
	GnmStyle const *style;

	g_return_if_fail (wbcg->edit_line.full_content == NULL);

	wbcg->edit_line.markup = markup;

	sv = wb_control_cur_sheet_view (GNM_WBC (wbcg));
	style = sheet_style_get (sv->sheet, sv->edit_pos.col, sv->edit_pos.row);
	wbcg->edit_line.cell_attrs = gnm_style_generate_attrs_full (style);

	wbcg->edit_line.full_content = pango_attr_list_copy (wbcg->edit_line.cell_attrs);
	pango_attr_list_splice (wbcg->edit_line.full_content, markup, 0, 0);

	text = gtk_entry_get_text (wbcg_get_entry (wbcg));
	set_cur_fmt (wbcg, strlen (text) - 1);
}
Exemple #11
0
void
dialog_delete_cells (WBCGtk *wbcg)
{
	DeleteCellState *state;
	WorkbookControl *wbc = GNM_WBC (wbcg);
	SheetView	*sv  = wb_control_cur_sheet_view (wbc);
	Sheet *sheet = sv_sheet (sv);
	GnmRange const *sel;
	GtkBuilder *gui;
	GtkWidget   *w;
	int  cols, rows;

	g_return_if_fail (wbcg != NULL);

	if (!(sel = selection_first_range (sv, GO_CMD_CONTEXT (wbc), _("Delete"))))
		return;
	cols = sel->end.col - sel->start.col + 1;
	rows = sel->end.row - sel->start.row + 1;

	if (range_is_full (sel, sheet, FALSE)) {
		cmd_delete_cols (wbc, sheet, sel->start.col, cols);
		return;
	}
	if (range_is_full (sel, sheet, TRUE)) {
		cmd_delete_rows (wbc, sheet, sel->start.row, rows);
		return;
	}

	if (gnm_dialog_raise_if_exists (wbcg, DELETE_CELL_DIALOG_KEY))
		return;
	gui = gnm_gtk_builder_load ("res:ui/delete-cells.ui", NULL, GO_CMD_CONTEXT (wbcg));
	if (gui == NULL)
		return;

	state = g_new (DeleteCellState, 1);
	state->wbcg  = wbcg;
	state->sel   = sel;
	state->gui   = gui;
	state->sheet = sv_sheet (sv);

	state->dialog = go_gtk_builder_get_widget (state->gui, "Delete_cells");
	if (state->dialog == NULL) {
		go_gtk_notice_dialog (wbcg_toplevel (wbcg), GTK_MESSAGE_ERROR,
				 _("Could not create the Delete Cell dialog."));
		g_free (state);
		return ;
	}

	w = go_gtk_builder_get_widget (state->gui, "okbutton");
	g_signal_connect_swapped (G_OBJECT (w), "clicked",
		G_CALLBACK (cb_delete_cell_ok_clicked), state);
	w = go_gtk_builder_get_widget (state->gui, "cancelbutton");
	g_signal_connect (G_OBJECT (w), "clicked",
		G_CALLBACK (cb_delete_cell_cancel_clicked), state);

	gnm_dialog_setup_destroy_handlers (GTK_DIALOG (state->dialog),
					   state->wbcg,
					   GNM_DIALOG_DESTROY_CURRENT_SHEET_REMOVED);

	gnm_init_help_button (
		go_gtk_builder_get_widget (state->gui, "helpbutton"),
		GNUMERIC_HELP_LINK_DELETE_CELLS);

	gtk_toggle_button_set_active
		(GTK_TOGGLE_BUTTON (go_gtk_builder_get_widget
				    (state->gui, cols < rows
				     ? "radio_0" : "radio_1")),
		 TRUE);

	wbc_gtk_attach_guru (state->wbcg, state->dialog);
	g_object_set_data_full (G_OBJECT (state->dialog),
		"state", state, (GDestroyNotify) cb_delete_cell_destroy);

	gnm_keyed_dialog (wbcg, GTK_WINDOW (state->dialog),
			       DELETE_CELL_DIALOG_KEY);
	gtk_widget_show (state->dialog);
}
Exemple #12
0
/**
 * stf_text_to_columns:
 * @wbc: The control making the request
 * @cc:
 *
 * Main routine, handles importing a file including all dialog mumbo-jumbo
 **/
void
stf_text_to_columns (WorkbookControl *wbc, GOCmdContext *cc)
{
	DialogStfResult_t *dialogresult = NULL;
	SheetView	*sv;
	Sheet		*src_sheet, *target_sheet;
	GnmRange const	*src;
	GnmRange	 target;
	GsfOutput	*buf;
	guint8 const	*data;
	size_t data_len;

	sv    = wb_control_cur_sheet_view (wbc);
	src_sheet = sv_sheet (sv);
	src = selection_first_range (sv, cc, _("Text to Columns"));
	if (src == NULL)
		return;
	if (range_width	(src) > 1) {
		go_cmd_context_error (cc, g_error_new (go_error_invalid (), 0,
			_("Only one column of input data can be parsed at a time")));
		return;
	}

	/* FIXME : how to do this cleanly ? */
	if (!GNM_IS_WBC_GTK (wbc))
		return;

#warning Add UI for this
	target_sheet = src_sheet;
	target = *src;
	range_translate (&target, target_sheet, 1, 0);

	buf = gsf_output_memory_new ();
	sheet_foreach_cell_in_range (src_sheet,
		CELL_ITER_ALL,
		src->start.col, src->start.row,
		src->end.col, src->end.row,
		(CellIterFunc) &cb_get_content, buf);

	gsf_output_close (buf);
	data = gsf_output_memory_get_bytes (GSF_OUTPUT_MEMORY (buf));
	data_len = (size_t)gsf_output_size (buf);
	if (data_len == 0) {
		go_cmd_context_error_import (GO_CMD_CONTEXT (cc),
					     _("There is no data "
					       "to convert"));
	} else {
		dialogresult = stf_dialog (WBC_GTK (wbc),
					   NULL, FALSE, NULL, FALSE,
					   _("Text to Columns"),
					   data, data_len);
	}
	if (dialogresult != NULL) {
		GnmCellRegion *cr = stf_parse_region (dialogresult->parseoptions,
			dialogresult->text, NULL, target_sheet->workbook);
		if (cr != NULL) {
			stf_dialog_result_attach_formats_to_cr (dialogresult, cr);
			target.end.col = target.start.col + cr->cols - 1;
			target.end.row = target.start.row + cr->rows - 1;
		}
		if (cr == NULL ||
		    cmd_text_to_columns (wbc, src, src_sheet,
					 &target, target_sheet, cr))
			go_cmd_context_error_import (GO_CMD_CONTEXT (cc),
					     _("Error while trying to "
					       "parse data into sheet"));
		stf_dialog_result_free (dialogresult);
	}

	g_object_unref (buf);
}
Exemple #13
0
void
dialog_row_height (WBCGtk *wbcg, gboolean use_default)
{
	RowHeightState *state;

	g_return_if_fail (wbcg != NULL);

	if (gnm_dialog_raise_if_exists (wbcg, ROW_HEIGHT_DIALOG_KEY))
		return;

	state = g_new (RowHeightState, 1);
	state->wbcg  = wbcg;
	state->sv = wb_control_cur_sheet_view (GNM_WBC (wbcg));
	state->sheet = sv_sheet (state->sv);
	state->adjusting = FALSE;
	state->gui = gnm_gtk_builder_load ("row-height.ui", NULL, GO_CMD_CONTEXT (wbcg));
	g_return_if_fail (state->gui != NULL);

	state->dialog = go_gtk_builder_get_widget (state->gui, "dialog");

	state->description = GTK_WIDGET (go_gtk_builder_get_widget (state->gui, "description"));
	state->points = GTK_WIDGET (go_gtk_builder_get_widget (state->gui, "pts-label"));

	state->spin  = GTK_SPIN_BUTTON (go_gtk_builder_get_widget (state->gui, "spin"));
	gtk_adjustment_set_lower (gtk_spin_button_get_adjustment (state->spin),
				  GNM_ROW_MARGIN + GNM_ROW_MARGIN + 1);
	g_signal_connect (G_OBJECT (state->spin),
		"value-changed",
		G_CALLBACK (cb_dialog_row_height_value_changed), state);

	state->default_check  = GTK_WIDGET (go_gtk_builder_get_widget (state->gui, "default_check"));
	g_signal_connect (G_OBJECT (state->default_check),
		"clicked",
		G_CALLBACK (cb_dialog_row_height_default_check_toggled), state);

	state->ok_button = go_gtk_builder_get_widget (state->gui, "ok_button");
	g_signal_connect (G_OBJECT (state->ok_button),
		"clicked",
		G_CALLBACK (cb_dialog_row_height_ok_clicked), state);
	state->apply_button = go_gtk_builder_get_widget (state->gui, "apply_button");
	g_signal_connect (G_OBJECT (state->apply_button),
		"clicked",
		G_CALLBACK (cb_dialog_row_height_apply_clicked), state);

	state->cancel_button = go_gtk_builder_get_widget (state->gui, "cancel_button");
	g_signal_connect (G_OBJECT (state->cancel_button),
		"clicked",
		G_CALLBACK (cb_dialog_row_height_cancel_clicked), state);

	gnm_init_help_button (
		go_gtk_builder_get_widget (state->gui, "help_button"),
		GNUMERIC_HELP_LINK_ROW_HEIGHT);
	g_object_set_data_full (G_OBJECT (state->dialog),
		"state", state, (GDestroyNotify) cb_dialog_row_height_destroy);

	gnm_dialog_setup_destroy_handlers (GTK_DIALOG (state->dialog),
					   state->wbcg,
					   GNM_DIALOG_DESTROY_CURRENT_SHEET_REMOVED);

	dialog_row_height_set_mode (use_default, state);
	dialog_row_height_load_value (state);

	wbc_gtk_attach_guru (state->wbcg, state->dialog);
	gnm_keyed_dialog (wbcg, GTK_WINDOW (state->dialog),
			       ROW_HEIGHT_DIALOG_KEY);
	gtk_widget_show (state->dialog);
}
Exemple #14
0
void
dialog_search (WBCGtk *wbcg)
{
	GtkBuilder *gui;
	GtkDialog *dialog;
	DialogState *dd;
	GtkGrid *grid;

	g_return_if_fail (wbcg != NULL);

	/* Only one guru per workbook. */
	if (wbc_gtk_get_guru (wbcg))
		return;

	gui = gnm_gtk_builder_load ("search.ui", NULL, GO_CMD_CONTEXT (wbcg));
        if (gui == NULL)
                return;

	dialog = GTK_DIALOG (gtk_builder_get_object (gui, "search_dialog"));

	dd = g_new (DialogState, 1);
	dd->wbcg = wbcg;
	dd->gui = gui;
	dd->dialog = dialog;
	dd->matches = g_ptr_array_new ();

	dd->prev_button = go_gtk_builder_get_widget (gui, "prev_button");
	dd->next_button = go_gtk_builder_get_widget (gui, "next_button");

	dd->notebook = GTK_NOTEBOOK (gtk_builder_get_object (gui, "notebook"));
	dd->notebook_matches_page =
		gtk_notebook_page_num (dd->notebook,
				       go_gtk_builder_get_widget (gui, "matches_tab"));

	dd->rangetext = gnm_expr_entry_new (wbcg, TRUE);
	gnm_expr_entry_set_flags (dd->rangetext, 0, GNM_EE_MASK);
	grid = GTK_GRID (gtk_builder_get_object (gui, "normal-grid"));
	gtk_widget_set_hexpand (GTK_WIDGET (dd->rangetext), TRUE);
	gtk_grid_attach (grid, GTK_WIDGET (dd->rangetext), 1, 6, 1, 1);
	{
		char *selection_text =
			selection_to_string (
				wb_control_cur_sheet_view (WORKBOOK_CONTROL (wbcg)),
				TRUE);
		gnm_expr_entry_load_from_text  (dd->rangetext, selection_text);
		g_free (selection_text);
	}

	dd->gentry = GTK_ENTRY (gtk_entry_new ());
	gtk_widget_set_hexpand (GTK_WIDGET (dd->gentry), TRUE);
	gtk_grid_attach (grid, GTK_WIDGET (dd->gentry), 1, 0, 1, 1);
	gtk_widget_grab_focus (GTK_WIDGET (dd->gentry));
	gnumeric_editable_enters (GTK_WINDOW (dialog), GTK_WIDGET (dd->gentry));

	dd->matches_table = make_matches_table (dd);

	{
		GtkWidget *scrolled_window =
			gtk_scrolled_window_new (NULL, NULL);
		gtk_container_add (GTK_CONTAINER (scrolled_window),
				   GTK_WIDGET (dd->matches_table));
		gtk_box_pack_start (GTK_BOX (gtk_builder_get_object (gui, "matches_vbox")),
				    scrolled_window,
				    TRUE, TRUE, 0);
		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
						GTK_POLICY_NEVER,
						GTK_POLICY_ALWAYS);
	}

	/* Set sensitivity of buttons.  */
	cursor_change (dd->matches_table, dd);

#define SETW(w,f) gtk_toggle_button_set_active				\
	     (GTK_TOGGLE_BUTTON (gtk_builder_get_object (gui, w)),  f())
	SETW("search_expr", gnm_conf_get_searchreplace_change_cell_expressions);
	SETW("search_other", gnm_conf_get_searchreplace_change_cell_other);
	SETW("search_string", gnm_conf_get_searchreplace_change_cell_strings);
	SETW("search_comments", gnm_conf_get_searchreplace_change_comments);
	SETW("search_expr_results", gnm_conf_get_searchreplace_search_results);
	SETW("ignore_case", gnm_conf_get_searchreplace_ignore_case);
	SETW("match_words", gnm_conf_get_searchreplace_whole_words_only);
#undef SETW

	gtk_toggle_button_set_active
	  (GTK_TOGGLE_BUTTON
	   (gtk_builder_get_object
	    (gui,
	     search_type_group[gnm_conf_get_searchreplace_regex ()])), TRUE);
	gtk_toggle_button_set_active
	  (GTK_TOGGLE_BUTTON
	   (gtk_builder_get_object
	    (gui,
	     direction_group
	     [gnm_conf_get_searchreplace_columnmajor () ? 1 : 0])), TRUE);
	gtk_toggle_button_set_active
	  (GTK_TOGGLE_BUTTON
	   (gtk_builder_get_object
	    (gui,
	     scope_group[gnm_conf_get_searchreplace_scope ()])), TRUE);

	g_signal_connect (G_OBJECT (dd->matches_table), "cursor_changed",
		G_CALLBACK (cursor_change), dd);
	g_signal_connect (G_OBJECT (dd->matches_table), "select_cursor_row",
		G_CALLBACK (cb_next), dd);
	go_gtk_builder_signal_connect (gui, "search_button", "clicked",
		G_CALLBACK (search_clicked), dd);
	g_signal_connect (G_OBJECT (dd->prev_button), "clicked",
		G_CALLBACK (prev_clicked), dd);
	g_signal_connect (G_OBJECT (dd->next_button), "clicked",
		G_CALLBACK (next_clicked), dd);
	go_gtk_builder_signal_connect_swapped (gui, "close_button", "clicked",
		G_CALLBACK (gtk_widget_destroy), dd->dialog);
	g_signal_connect (G_OBJECT (gnm_expr_entry_get_entry (dd->rangetext)), "focus-in-event",
		G_CALLBACK (range_focused), dd);
	go_gtk_builder_signal_connect (gui, "scope_range", "toggled",
		G_CALLBACK (cb_focus_on_entry), dd->rangetext);

	wbc_gtk_attach_guru_with_unfocused_rs (wbcg, GTK_WIDGET (dialog), dd->rangetext);
	g_object_set_data_full (G_OBJECT (dialog),
		"state", dd, (GDestroyNotify) free_state);
	gnm_dialog_setup_destroy_handlers (dialog, wbcg,
		GNM_DIALOG_DESTROY_SHEET_REMOVED);
	gnumeric_init_help_button (
		go_gtk_builder_get_widget (gui, "help_button"),
		GNUMERIC_HELP_LINK_SEARCH);
	gnumeric_restore_window_geometry (GTK_WINDOW (dialog), SEARCH_KEY);

	go_gtk_nonmodal_dialog (wbcg_toplevel (wbcg), GTK_WINDOW (dialog));
	gtk_widget_show_all (GTK_WIDGET (dialog));
}
Exemple #15
0
void
dialog_data_slicer (WBCGtk *wbcg, gboolean create)
{
	static GtkTargetEntry row_targets[] = {
		{ (char *)"GTK_TREE_MODEL_ROW", GTK_TARGET_SAME_APP, 0 }
	};
	DialogDataSlicer *state;
	GtkBuilder *gui;
	GtkWidget *w;

	g_return_if_fail (wbcg != NULL);

	if (gnm_dialog_raise_if_exists (wbcg, DIALOG_KEY))
		return;

	gui = gnm_gtk_builder_load ("data-slicer.ui", NULL, GO_CMD_CONTEXT (wbcg));
	if (NULL == gui)
		return;

	state = g_new0 (DialogDataSlicer, 1);
	state->wbcg	= wbcg;
	state->sv	= wb_control_cur_sheet_view (GNM_WBC (wbcg));

	state->dialog	= go_gtk_builder_get_widget (gui, "dialog_data_slicer");
	state->notebook = go_gtk_builder_get_widget (gui, "notebook");
	state->slicer	= create ? NULL : sv_editpos_in_slicer (state->sv);
	state->cache	= NULL;
	state->source	= NULL;

	if (NULL == state->slicer) {
		state->slicer = g_object_new (GNM_SHEET_SLICER_TYPE, NULL);
	} else {
		g_object_ref (state->slicer);
		g_object_get (G_OBJECT (state->slicer), "cache", &state->cache, NULL);
		if (NULL != state->cache &&
		    NULL != (state->source = go_data_cache_get_source (state->cache)))
		    g_object_ref (state->source);
	}

	state->source_expr = gnm_expr_entry_new (state->wbcg, TRUE);
	gnm_expr_entry_set_flags (state->source_expr,
		GNM_EE_SINGLE_RANGE, GNM_EE_MASK);
	g_signal_connect_swapped (G_OBJECT (state->source_expr),
		"changed", G_CALLBACK (cb_source_expr_changed), state);
	w = go_gtk_builder_get_widget (gui, "source_vbox");
	gtk_box_pack_start (GTK_BOX (w), GTK_WIDGET (state->source_expr), FALSE, FALSE, 0);
	gtk_widget_show (GTK_WIDGET (state->source_expr));

	w = go_gtk_builder_get_widget (gui, "ok_button");
	g_signal_connect (G_OBJECT (w), "clicked",
		G_CALLBACK (cb_dialog_data_slicer_ok), state);
	w = go_gtk_builder_get_widget (gui, "cancel_button");
	g_signal_connect (G_OBJECT (w), "clicked",
		G_CALLBACK (cb_dialog_data_slicer_cancel), state);

	state->treeview = GTK_TREE_VIEW (go_gtk_builder_get_widget (gui, "field_tree"));
	gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (state->treeview), GDK_BUTTON1_MASK,
		row_targets, G_N_ELEMENTS (row_targets), GDK_ACTION_MOVE);
	gtk_tree_view_enable_model_drag_dest (GTK_TREE_VIEW (state->treeview),
		row_targets, G_N_ELEMENTS (row_targets), GDK_ACTION_MOVE);
	state->selection = gtk_tree_view_get_selection (state->treeview);
	gtk_tree_selection_set_mode (state->selection, GTK_SELECTION_SINGLE);
	g_signal_connect (state->selection, "changed",
		G_CALLBACK (cb_dialog_data_slicer_selection_changed), state);

	gtk_tree_view_append_column (state->treeview,
		gtk_tree_view_column_new_with_attributes ("",
			gtk_cell_renderer_text_new (), "text", FIELD_NAME, NULL));
	cb_dialog_data_slicer_create_model (state);

	g_signal_connect (state->treeview, "realize", G_CALLBACK (gtk_tree_view_expand_all), NULL);

	gtk_notebook_set_current_page (GTK_NOTEBOOK (state->notebook), create ? 0 : 1);

	/* a candidate for merging into attach guru */
	gnm_init_help_button (go_gtk_builder_get_widget (gui, "help_button"),
		GNUMERIC_HELP_LINK_DATA_SLICER);
	g_object_set_data_full (G_OBJECT (state->dialog),
		"state", state, (GDestroyNotify)cb_dialog_data_slicer_destroy);
	wbc_gtk_attach_guru (state->wbcg, state->dialog);
	gnm_keyed_dialog (wbcg, GTK_WINDOW (state->dialog), DIALOG_KEY);
	gtk_widget_show (state->dialog);
	g_object_unref (gui);
}
Exemple #16
0
/**
 * wbcg_edit_start:
 * @wbcg:       The workbook to be edited.
 * @blankp:   If true, erase current cell contents first.  If false, leave the
 *            contents alone.
 * @cursorp:  If true, create an editing cursor in the current sheet.  (If
 *            false, the text will be editing in the edit box above the sheet,
 *            but this is not handled by this function.)
 *
 * Initiate editing of a cell in the sheet.  Note that we have two modes of
 * editing:
 *  1) in-cell editing when you just start typing, and
 *  2) above sheet editing when you hit F2.
 *
 * Returns TRUE if we did indeed start editing.  Returns FALSE if the
 * cell-to-be-edited was locked.
 */
gboolean
wbcg_edit_start (WBCGtk *wbcg,
		 gboolean blankp, gboolean cursorp)
{
	/* We could save this, but the situation is rare, if confusing.  */
	static gboolean warn_on_text_format = TRUE;
	SheetView *sv;
	SheetControlGUI *scg;
	GnmCell *cell;
	char *text = NULL;
	int col, row;
	WorkbookView *wbv;
	int cursor_pos = -1;

	g_return_val_if_fail (GNM_IS_WBC_GTK (wbcg), FALSE);

	if (wbcg_is_editing (wbcg))
		return TRUE;

	/* Avoid recursion, and do not begin editing if a guru is up */
	if (wbcg->inside_editing || wbc_gtk_get_guru (wbcg) != NULL)
		return TRUE;
	wbcg->inside_editing = TRUE;

	wbv = wb_control_view (GNM_WBC (wbcg));
	sv = wb_control_cur_sheet_view (GNM_WBC (wbcg));
	scg = wbcg_cur_scg (wbcg);

	col = sv->edit_pos.col;
	row = sv->edit_pos.row;

	/* don't edit a locked cell */
	/* TODO : extend this to disable edits that cannot succeed
	 * like editing a single cell of an array.  I think we have enough
	 * information if we look at the selection.
	 */
	if (wb_view_is_protected (wbv, TRUE) &&
	    gnm_style_get_contents_locked (sheet_style_get (sv->sheet, col, row))) {
		char *pos =  g_strdup_printf ( _("%s!%s is locked"),
			sv->sheet->name_quoted, cell_coord_name (col, row));
		go_cmd_context_error_invalid (GO_CMD_CONTEXT (wbcg), pos,
			wb_view_is_protected (wbv, FALSE)
			 ? _("Unprotect the workbook to enable editing.")
			 : _("Unprotect the sheet to enable editing."));
		wbcg->inside_editing = FALSE;
		g_free (pos);
		return FALSE;
	}

	cell = sheet_cell_get (sv->sheet, col, row);
	if (cell &&
	    warn_on_text_format &&
	    go_format_is_text (gnm_cell_get_format (cell)) &&
	    (gnm_cell_has_expr (cell) || !VALUE_IS_STRING (cell->value))) {
		gint res; /* Using GtkResponseType would yield a warning on the switch */
		GtkWidget *check;
		GtkWidget *align;

		GtkWidget *d = gnm_message_dialog_create
			(wbcg_toplevel (wbcg),
			 GTK_DIALOG_DESTROY_WITH_PARENT,
			 GTK_MESSAGE_WARNING,
			 _("You are about to edit a cell with \"text\" format."),
			 _("The cell does not currently contain text, though, so if "
			   "you go on editing then the contents will be turned into "
			   "text."));
		gtk_dialog_add_button (GTK_DIALOG (d), GTK_STOCK_EDIT, GTK_RESPONSE_OK);
		go_gtk_dialog_add_button
			(GTK_DIALOG (d), _("Remove format"), GTK_STOCK_REMOVE,
			 GNM_RESPONSE_REMOVE);
		gtk_dialog_add_button (GTK_DIALOG (d), GNM_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
		gtk_dialog_set_default_response (GTK_DIALOG (d), GTK_RESPONSE_CANCEL);

		check = gtk_check_button_new_with_label (_("Show this dialog next time."));
		g_signal_connect (check, "toggled", G_CALLBACK (cb_warn_toggled), &warn_on_text_format);
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
		align = gtk_alignment_new (0.5, 0.5, 0, 0);
		gtk_container_add (GTK_CONTAINER (align), check);
		gtk_widget_show_all (align);
		gtk_box_pack_end (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (d))), align, TRUE, TRUE, 0);
		res = go_gtk_dialog_run (GTK_DIALOG (d), wbcg_toplevel (wbcg));

		switch (res) {
		case GNM_RESPONSE_REMOVE: {
			GnmStyle *style = gnm_style_new ();
			gnm_style_set_format (style, go_format_general ());
			if (!cmd_selection_format (GNM_WBC (wbcg),
						   style, NULL, NULL))
				break;
			/* Fall through.  */
		}
		default:
		case GTK_RESPONSE_CANCEL:
			wbcg->inside_editing = FALSE;
			return FALSE;
		case GTK_RESPONSE_OK:
			break;
		}
	}

	gnm_app_clipboard_unant ();

	if (blankp)
		gtk_entry_set_text (wbcg_get_entry (wbcg), "");
	else if (cell != NULL) {
		gboolean quoted = FALSE;

		text = gnm_cell_get_text_for_editing (cell, sv->sheet, &quoted, &cursor_pos);

		if (text)
			gtk_entry_set_text (wbcg_get_entry (wbcg), text);

		if (cell->value != NULL) {
			GOFormat const *fmt = VALUE_FMT (cell->value);
			if (fmt != NULL && go_format_is_markup (fmt)) {
				PangoAttrList *markup =
					pango_attr_list_copy ((PangoAttrList *)go_format_get_markup (fmt));
				if (quoted)
					go_pango_attr_list_open_hole (markup, 0, 1);
				wbcg_edit_init_markup (wbcg, markup);
			}
		}
	}

	gnm_expr_entry_set_scg (wbcg->edit_line.entry, scg);
	gnm_expr_entry_set_flags (wbcg->edit_line.entry,
		GNM_EE_SHEET_OPTIONAL | GNM_EE_FORMULA_ONLY,
		GNM_EE_SINGLE_RANGE | GNM_EE_SHEET_OPTIONAL | GNM_EE_FORMULA_ONLY | GNM_EE_FORCE_REL_REF | GNM_EE_FORCE_ABS_REF);
	scg_edit_start (scg);

	/* Redraw the cell contents in case there was a span */
	sheet_redraw_region (sv->sheet, col, row, col, row);

	if (cursorp && /* autocompletion code will not work in the edit line */
	    wbv->do_auto_completion &&
	    (text == NULL || g_unichar_isalpha (g_utf8_get_char (text)))) {
		wbcg->auto_complete = gnm_complete_sheet_new (
			sv->sheet, col, row,
			workbook_edit_complete_notify, wbcg);
		wbcg->auto_completing = TRUE;
		wbcg->auto_max_size = 0;
	} else
		wbcg->auto_complete = NULL;

	/* Give the focus to the edit line */
	if (!cursorp)
		gtk_window_set_focus (wbcg_toplevel (wbcg),
			(GtkWidget *) wbcg_get_entry (wbcg));

	wbcg->editing = TRUE;
	wbcg->editing_sheet = sv->sheet;
	wbcg->editing_cell = cell;

	/* If this assert fails, it means editing was not shut down
	 * properly before
	 */
	g_return_val_if_fail (wbcg->edit_line.signal_changed == 0, TRUE);
	wbcg->edit_line.signal_changed = g_signal_connect (
		G_OBJECT (wbcg_get_entry (wbcg)),
		"changed",
		G_CALLBACK (cb_entry_changed), wbcg);
	wbcg->edit_line.signal_insert = g_signal_connect (
		G_OBJECT (wbcg_get_entry (wbcg)),
		"insert-text",
		G_CALLBACK (cb_entry_insert_text), wbcg);
	wbcg->edit_line.signal_delete = g_signal_connect (
		G_OBJECT (wbcg_get_entry (wbcg)),
		"delete-text",
		G_CALLBACK (cb_entry_delete_text), wbcg);
	wbcg->edit_line.signal_cursor_pos = g_signal_connect_swapped (
		G_OBJECT (wbcg_get_entry (wbcg)),
		"notify::cursor-position",
		G_CALLBACK (cb_entry_cursor_pos), wbcg);
	wbcg->edit_line.signal_selection_bound = g_signal_connect_swapped (
		G_OBJECT (wbcg_get_entry (wbcg)),
		"notify::selection-bound",
		G_CALLBACK (cb_entry_cursor_pos), wbcg);

	g_free (text);
	wb_control_update_action_sensitivity (GNM_WBC (wbcg));

	wbcg->inside_editing = FALSE;

	gtk_editable_set_position (GTK_EDITABLE (wbcg_get_entry (wbcg)), cursor_pos);

	return TRUE;
}
Exemple #17
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;
}
Exemple #18
0
void
dialog_merge (WBCGtk *wbcg)
{
	MergeState *state;
	GtkBuilder *gui;
	GtkGrid *grid;
	GtkWidget *scrolled;
	GtkTreeViewColumn *column;
	GtkTreeSelection  *selection;
	GnmRange const *r;

	g_return_if_fail (wbcg != NULL);

	if (gnumeric_dialog_raise_if_exists (wbcg, MERGE_KEY))
		return;
	gui = gnm_gtk_builder_load ("merge.ui", NULL, GO_CMD_CONTEXT (wbcg));
        if (gui == NULL)
                return;

	state = g_new0 (MergeState, 1);
	state->gui = gui;
	state->wbcg = wbcg;
	state->sheet = wb_control_cur_sheet (WORKBOOK_CONTROL (state->wbcg));
	state->dialog     = go_gtk_builder_get_widget (gui, "Merge");
	state->warning_dialog = NULL;

	state->add_btn   = go_gtk_builder_get_widget (gui, "add_button");
	state->delete_btn   = go_gtk_builder_get_widget (gui, "remove_button");
	state->merge_btn  = go_gtk_builder_get_widget (gui, "merge_button");
	state->change_btn  = go_gtk_builder_get_widget (gui, "change_button");
	state->cancel_btn  = go_gtk_builder_get_widget (gui, "cancel_button");
	gtk_widget_set_size_request (state->delete_btn, 100, -1);

	gtk_button_set_alignment (GTK_BUTTON (state->add_btn),    0., .5);
	gtk_button_set_alignment (GTK_BUTTON (state->delete_btn), 0., .5);
	gtk_button_set_alignment (GTK_BUTTON (state->change_btn), 0., .5);

	grid = GTK_GRID (go_gtk_builder_get_widget (gui, "main-grid"));
	state->zone = gnm_expr_entry_new (wbcg, TRUE);
	gnm_expr_entry_set_flags (state->zone, GNM_EE_SINGLE_RANGE, GNM_EE_MASK);
	gnumeric_editable_enters (GTK_WINDOW (state->dialog),
				  GTK_WIDGET (state->zone));
	gtk_label_set_mnemonic_widget (GTK_LABEL (go_gtk_builder_get_widget (gui, "var1-label")),
				       GTK_WIDGET (state->zone));
	gtk_widget_set_hexpand (GTK_WIDGET (state->zone), TRUE);
	gtk_grid_attach (grid, GTK_WIDGET (state->zone), 1, 0, 2, 1);
	r = selection_first_range (
		wb_control_cur_sheet_view (WORKBOOK_CONTROL (wbcg)), NULL, NULL);
	if (r != NULL)
		gnm_expr_entry_load_from_range (state->zone,
			state->sheet, r);

	state->data = gnm_expr_entry_new (wbcg, TRUE);
	gnm_expr_entry_set_flags (state->data, GNM_EE_SINGLE_RANGE, GNM_EE_MASK);
	gtk_widget_set_hexpand (GTK_WIDGET (state->data), TRUE);
	gtk_grid_attach (grid, GTK_WIDGET (state->data), 0, 5, 1, 1);

	state->field = gnm_expr_entry_new (wbcg, TRUE);
	gnm_expr_entry_set_flags (state->field, GNM_EE_SINGLE_RANGE, GNM_EE_MASK);
	gtk_widget_set_hexpand (GTK_WIDGET (state->field), TRUE);
	gtk_grid_attach (grid, GTK_WIDGET (state->field), 1, 5, 1, 1);

	scrolled = go_gtk_builder_get_widget (state->gui, "scrolled");
	state->model = gtk_list_store_new (NUM_COLMNS, G_TYPE_STRING, G_TYPE_STRING);
	state->list = GTK_TREE_VIEW (gtk_tree_view_new_with_model
					   (GTK_TREE_MODEL (state->model)));
	selection = gtk_tree_view_get_selection (state->list);
	gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);

	column = gtk_tree_view_column_new_with_attributes (_("Input Data"),
							   gtk_cell_renderer_text_new (),
							   "text", DATA_RANGE,
							   NULL);
	gtk_tree_view_column_set_sort_column_id (column, DATA_RANGE);
	gtk_tree_view_column_set_min_width (column, 150);
	gtk_tree_view_append_column (state->list, column);
	column = gtk_tree_view_column_new_with_attributes (_("Merge Field"),
							   gtk_cell_renderer_text_new (),
							   "text", FIELD_LOCATION,
							   NULL);
	gtk_tree_view_column_set_sort_column_id (column, FIELD_LOCATION);
	gtk_tree_view_column_set_min_width (column, 100);
	gtk_tree_view_append_column (state->list, column);

	gtk_tree_view_set_headers_clickable (state->list, TRUE);
	gtk_container_add (GTK_CONTAINER (scrolled), GTK_WIDGET (state->list));

	cb_merge_update_buttons (NULL, state);
	g_signal_connect (selection,
		"changed",
		G_CALLBACK (cb_merge_selection_changed), state);

	g_signal_connect_after (G_OBJECT (state->zone),
		"changed",
		G_CALLBACK (cb_merge_update_buttons), state);
	g_signal_connect_after (G_OBJECT (state->data),
		"changed",
		G_CALLBACK (cb_merge_update_buttons), state);
	g_signal_connect_after (G_OBJECT (state->field),
		"changed",
		G_CALLBACK (cb_merge_update_buttons), state);

	g_signal_connect (G_OBJECT (state->add_btn),
		"clicked",
		G_CALLBACK (cb_merge_add_clicked), state);
	g_signal_connect (G_OBJECT (state->change_btn),
		"clicked",
		G_CALLBACK (cb_merge_change_clicked), state);
	g_signal_connect (G_OBJECT (state->delete_btn),
		"clicked",
		G_CALLBACK (cb_merge_delete_clicked), state);
	g_signal_connect (G_OBJECT (state->merge_btn),
		"clicked",
		G_CALLBACK (cb_merge_merge_clicked), state);
	g_signal_connect (G_OBJECT (state->cancel_btn),
		"clicked",
		G_CALLBACK (cb_merge_cancel_clicked), state);

	gnm_dialog_setup_destroy_handlers (GTK_DIALOG (state->dialog),
					   state->wbcg,
					   GNM_DIALOG_DESTROY_CURRENT_SHEET_REMOVED);

	gnumeric_init_help_button (
		go_gtk_builder_get_widget (state->gui, "help_button"),
		GNUMERIC_HELP_LINK_DATA_MERGE);

	gnumeric_keyed_dialog (state->wbcg, GTK_WINDOW (state->dialog),
			       MERGE_KEY);

	/* a candidate for merging into attach guru */
	g_object_set_data_full (G_OBJECT (state->dialog),
		"state", state, (GDestroyNotify) cb_merge_destroy);
	go_gtk_nonmodal_dialog (wbcg_toplevel (state->wbcg),
				   GTK_WINDOW (state->dialog));
	wbc_gtk_attach_guru (state->wbcg, GTK_WIDGET (state->dialog));
	gtk_widget_show_all (GTK_WIDGET (state->dialog));
}
Exemple #19
0
/**
 * wbcg_edit_finish:
 * @wbcg: #WBCGtk
 * @result: what should we do with the content
 * @showed_dialog: If non-NULL will indicate if a dialog was displayed.
 *
 * Return: TRUE if editing completed successfully, or we were no editing.
 **/
gboolean
wbcg_edit_finish (WBCGtk *wbcg, WBCEditResult result,
		  gboolean *showed_dialog)
{
	Sheet *sheet;
	SheetView *sv;
	WorkbookControl *wbc;
	WorkbookView	*wbv;

	g_return_val_if_fail (GNM_IS_WBC_GTK (wbcg), FALSE);

	wbc = GNM_WBC (wbcg);
	wbv = wb_control_view (wbc);

	wbcg_focus_cur_scg (wbcg);

	gnm_expr_entry_close_tips (wbcg_get_entry_logical (wbcg));

	if (showed_dialog != NULL)
		*showed_dialog = FALSE;

	/* Remove the range selection cursor if it exists */
	if (NULL != wbcg->rangesel)
		scg_rangesel_stop (wbcg->rangesel, result == WBC_EDIT_REJECT);

	if (!wbcg_is_editing (wbcg)) {
		/* We may have a guru up even if we are not editing. remove it.
		 * Do NOT remove until later it if we are editing, it is possible
		 * that we may want to continue editing.
		 */
		if (wbcg->edit_line.guru != NULL) {
			GtkWidget *w = wbcg->edit_line.guru;
			wbc_gtk_detach_guru (wbcg);
			gtk_widget_destroy (w);
		}

		return TRUE;
	}

	g_return_val_if_fail (IS_SHEET (wbcg->editing_sheet), TRUE);

	sheet = wbcg->editing_sheet;
	sv = sheet_get_view (sheet, wbv);

	/* Save the results before changing focus */
	if (result != WBC_EDIT_REJECT) {
		ValidationStatus valid = GNM_VALIDATION_STATUS_VALID;
		char *free_txt = NULL;
		char const *txt;
		GnmStyle const *mstyle;
		char const *expr_txt = NULL;
		GOFormat const *fmt;
		GnmValue *value;
		GOUndo *u = NULL;
		GSList	*selection = selection_get_ranges (sv, FALSE);
		GnmParsePos    pp;
		GnmExprTop const *texpr = NULL;

		parse_pos_init_editpos (&pp, sv);

		/* Array only works on single range.  */
		if (result == WBC_EDIT_ACCEPT_ARRAY &&
		    (selection == NULL || selection->next != NULL))
			result = WBC_EDIT_ACCEPT_RANGE;

		/******* Check whether we would split a range ********/

		switch (result) {
		case (WBC_EDIT_ACCEPT_RANGE):
		case (WBC_EDIT_ACCEPT_ARRAY): {
			if (sheet_ranges_split_region (sheet, selection,
						       GO_CMD_CONTEXT (wbc), _("Set Text"))) {
				range_fragment_free (selection);
				if (showed_dialog != NULL)
					*showed_dialog = TRUE;
				return FALSE;
			}

			if (result == WBC_EDIT_ACCEPT_ARRAY &&
			    sheet_range_contains_merges_or_arrays
			    	(sheet, selection->data,
				 GO_CMD_CONTEXT (wbc), _("Set Text"),
				 TRUE, FALSE)) {
				range_fragment_free (selection);
				if (showed_dialog != NULL)
					*showed_dialog = TRUE;
				return FALSE;
			}

			break;
		}
		case (WBC_EDIT_ACCEPT_WO_AC):
		case (WBC_EDIT_ACCEPT): {
			GnmCell const *cell = sheet_cell_get
				(sheet, sv->edit_pos.col, sv->edit_pos.row);
			if (gnm_cell_is_nonsingleton_array (cell)) {
				gnm_cmd_context_error_splits_array (GO_CMD_CONTEXT (wbc),
								    _("Set Text"), NULL);
				if (showed_dialog != NULL)
					*showed_dialog = TRUE;
				range_fragment_free (selection);
				return FALSE;
			}
			break;
		}
		case (WBC_EDIT_REJECT):
		default:
			/* We should not be able to get here! */
			break;
		}


		/******* Check whether the range is locked ********/

		switch (result) {
		case (WBC_EDIT_ACCEPT_RANGE):
		case (WBC_EDIT_ACCEPT_ARRAY): {
			if (cmd_selection_is_locked_effective (sheet, selection, wbc,
							       _("Set Text"))) {
				range_fragment_free (selection);
				if (showed_dialog != NULL)
					*showed_dialog = TRUE;
				return FALSE;
			}
			break;
		}
		case (WBC_EDIT_ACCEPT_WO_AC):
		case (WBC_EDIT_ACCEPT): {
			GnmRange r;
			r.end = r.start = pp.eval;

			if (cmd_cell_range_is_locked_effective (sheet, &r, wbc,
							       _("Set Text"))) {
				range_fragment_free (selection);
				if (showed_dialog != NULL)
					*showed_dialog = TRUE;
				return FALSE;
			}
			break;
		}
		case (WBC_EDIT_REJECT):
		default:
			/* We should not be able to get here! */
			break;
		}
		/*****************************************************/

		txt = wbcg_edit_get_display_text (wbcg);
		mstyle = sheet_style_get (sheet, sv->edit_pos.col, sv->edit_pos.row);
		fmt = gnm_cell_get_format (sheet_cell_fetch (sheet, sv->edit_pos.col,
							     sv->edit_pos.row));

		value = format_match (txt, fmt,
				      workbook_date_conv (sheet->workbook));
		if (value == NULL)
			expr_txt = gnm_expr_char_start_p (txt);
		else
			value_release (value);

		/* NOTE : do not modify gnm_expr_char_start_p to exclude "-"
		 * it _can_ start an expression, which is required for rangesel
		 * it just isn't an expression. */
		if (expr_txt != NULL && *expr_txt != '\0' && strcmp (expr_txt, "-")) {
			GnmExprTop const *texpr_test = NULL;
			GnmParseError  perr;

			parse_error_init (&perr);
			texpr_test = gnm_expr_parse_str (expr_txt,
							 &pp, GNM_EXPR_PARSE_DEFAULT, NULL, &perr);
			/* Try adding a single extra closing paren to see if it helps */
			if (texpr_test == NULL && perr.err != NULL &&
			    perr.err->code == PERR_MISSING_PAREN_CLOSE) {
				GnmParseError tmp_err;
				char *tmp = g_strconcat (txt, ")", NULL);
				parse_error_init (&tmp_err);
				texpr_test = gnm_expr_parse_str (gnm_expr_char_start_p (tmp),
								 &pp, GNM_EXPR_PARSE_DEFAULT,
								 NULL, &tmp_err);
				parse_error_free (&tmp_err);

				if (texpr_test != NULL) {
					txt = free_txt = tmp;
					expr_txt = gnm_expr_char_start_p (txt);
				} else
					g_free (tmp);
			}

			if (texpr_test == NULL && perr.err != NULL) {
				ValidationStatus reedit;

				/* set focus _before_ selection.  gtk2 seems to
				 * screw with selection in gtk_entry_grab_focus
				 * (no longer required now that we clear
				 * gtk-entry-select-on-focus) */
				gtk_window_set_focus (wbcg_toplevel (wbcg),
						      (GtkWidget *) wbcg_get_entry (wbcg));

				if (perr.begin_char != 0 || perr.end_char != 0) {
					int offset = expr_txt - txt;
					gtk_editable_select_region (GTK_EDITABLE (wbcg_get_entry (wbcg)),
								    offset + perr.begin_char,
								    offset + perr.end_char);
				} else
					gtk_editable_set_position (
								   GTK_EDITABLE (wbcg_get_entry (wbcg)), -1);

				reedit = wb_control_validation_msg (GNM_WBC (wbcg),
								    GNM_VALIDATION_STYLE_PARSE_ERROR, NULL,
								    perr.err->message);
				if (showed_dialog != NULL)
					*showed_dialog = TRUE;

				parse_error_free (&perr);
				if (reedit == GNM_VALIDATION_STATUS_INVALID_EDIT) {
					range_fragment_free (selection);
					return FALSE;
				}
				/* restore focus to sheet , or we'll leave edit
				 * mode only to jump right back in the new
				 * cell because it looks like someone just
				 * focused on the edit line (eg hit F2) */
				wbcg_focus_cur_scg (wbcg);
			}
			if (texpr_test != NULL)
				gnm_expr_top_unref (texpr_test);
		}

		/* We only enter an array formula if the text is a formula */
		if (result == WBC_EDIT_ACCEPT_ARRAY && !expr_txt)
			result = WBC_EDIT_ACCEPT_RANGE;

		if (result == WBC_EDIT_ACCEPT_ARRAY) {
			GnmParsePos pp_array;
			GnmRange *r = selection->data;

			parse_pos_init (&pp_array, sheet->workbook, sheet, r->start.col, r->start.row);

			if ((texpr = gnm_expr_parse_str
			     (expr_txt, &pp_array, GNM_EXPR_PARSE_DEFAULT,
			      sheet_get_conventions (sheet), NULL)) == NULL)
				result = WBC_EDIT_ACCEPT_RANGE;
		}

		/* We need to save the information that we will temporarily overwrite */
		/* We then assign the information. No need to worry about formatting */
		/* Finally we can check the validation! */

		switch (result) {
		case (WBC_EDIT_ACCEPT_RANGE): {
			GSList	*l;

			for (l = selection; l != NULL; l = l->next) {
				GnmRange *r = l->data;
				u = go_undo_combine (u,  clipboard_copy_range_undo (sheet, r));
			}
			for (l = selection; l != NULL; l = l->next) {
				GnmRange *r = l->data;
				/* We do this separately since there may be overlap between ranges */
				sheet_range_set_text (&pp, r, txt);
				valid =	gnm_validation_eval_range (wbc, sheet, &sv->edit_pos, r,
							       showed_dialog);
				if (valid != GNM_VALIDATION_STATUS_VALID)
					break;
			}
			break;
		}
		case (WBC_EDIT_ACCEPT_ARRAY): {
			GnmRange *r = selection->data;

			u = go_undo_combine (u,  clipboard_copy_range_undo (sheet, r));
			if (texpr) {
				gnm_expr_top_ref (texpr);
				gnm_cell_set_array_formula (sheet,
							    r->start.col, r->start.row,
							    r->end.col, r->end.row,
							    texpr);
				sheet_region_queue_recalc (sheet, r);
			}
			valid =	gnm_validation_eval_range (wbc, sheet, &sv->edit_pos, r,
						       showed_dialog);
			break;
		}
		case (WBC_EDIT_ACCEPT_WO_AC):
		case (WBC_EDIT_ACCEPT): {
			GnmRange r;
			GnmCell *cell;

			range_init_cellpos (&r, &sv->edit_pos);
			u = clipboard_copy_range_undo (sheet, &r);

			cell = sheet_cell_fetch (sheet,
						 sv->edit_pos.col,
						 sv->edit_pos.row);
			sheet_cell_set_text (cell, txt, wbcg->edit_line.markup);
			valid = gnm_validation_eval (wbc, mstyle, sheet, &sv->edit_pos, showed_dialog);
			break;
		}
		case (WBC_EDIT_REJECT):
		default:
			/* We should not be able to get here! */
			break;
		}

		range_fragment_free (selection);

		/* We need to rebuild the original info first. */

		go_undo_undo (u);
		g_object_unref (u);

		/* Now we can respond to our validation information */

		if (valid != GNM_VALIDATION_STATUS_VALID) {
			result = WBC_EDIT_REJECT;
			if (valid == GNM_VALIDATION_STATUS_INVALID_EDIT) {
				gtk_window_set_focus (wbcg_toplevel (wbcg),
					(GtkWidget *) wbcg_get_entry (wbcg));
				g_free (free_txt);
				if (texpr != NULL)
					gnm_expr_top_unref (texpr);
				return FALSE;
			}
		} else {
			if (result == WBC_EDIT_ACCEPT_ARRAY) {
				cmd_area_set_array_expr (wbc, sv, texpr);

			} else {
				PangoAttrList *res_markup = wbcg->edit_line.markup
					? pango_attr_list_copy (wbcg->edit_line.markup)
					: NULL;
				if (result == WBC_EDIT_ACCEPT)
					cmd_set_text (wbc, sheet, &sv->edit_pos, txt, res_markup, TRUE);
				else if (result == WBC_EDIT_ACCEPT_WO_AC)
					cmd_set_text (wbc, sheet, &sv->edit_pos, txt, res_markup, FALSE);
				else
					cmd_area_set_text (wbc, sv, txt, res_markup);
				if (res_markup)
					pango_attr_list_unref (res_markup);
			}
		}
		if (texpr != NULL)
			gnm_expr_top_unref (texpr);
		g_free (free_txt);
	} else {
		if (sv == wb_control_cur_sheet_view (wbc)) {
			/* Redraw the cell contents in case there was a span */
			GnmRange tmp; tmp.start = tmp.end = sv->edit_pos;
			sheet_range_bounding_box (sv->sheet, &tmp);
			sv_redraw_range (wb_control_cur_sheet_view (wbc), &tmp);
		}

		/* Reload the entry widget with the original contents */
		wb_view_edit_line_set (wbv, wbc);
	}

	/* Stop editing */
	wbcg->editing = FALSE;
	wbcg->editing_sheet = NULL;
	wbcg->editing_cell = NULL;

	if (wbcg->edit_line.guru != NULL) {
		GtkWidget *w = wbcg->edit_line.guru;
		wbc_gtk_detach_guru (wbcg);
		gtk_widget_destroy (w);
	}

	if (wbcg->edit_line.signal_insert) {
		g_signal_handler_disconnect (wbcg_get_entry (wbcg),
					     wbcg->edit_line.signal_insert);
		wbcg->edit_line.signal_insert = 0;
	}
	if (wbcg->edit_line.signal_delete) {
		g_signal_handler_disconnect (wbcg_get_entry (wbcg),
					     wbcg->edit_line.signal_delete);
		wbcg->edit_line.signal_delete = 0;
	}
	if (wbcg->edit_line.signal_cursor_pos) {
		g_signal_handler_disconnect (wbcg_get_entry (wbcg),
					     wbcg->edit_line.signal_cursor_pos);
		wbcg->edit_line.signal_cursor_pos = 0;
	}
	if (wbcg->edit_line.signal_selection_bound) {
		g_signal_handler_disconnect (wbcg_get_entry (wbcg),
					     wbcg->edit_line.signal_selection_bound);
		wbcg->edit_line.signal_selection_bound = 0;
	}

	if (wbcg->edit_line.cell_attrs != NULL) {
		pango_attr_list_unref (wbcg->edit_line.cell_attrs);
		wbcg->edit_line.cell_attrs = NULL;
	}

	if (wbcg->edit_line.markup) {
		pango_attr_list_unref (wbcg->edit_line.markup);
		wbcg->edit_line.markup = NULL;
	}

	if (wbcg->edit_line.full_content != NULL) {
		pango_attr_list_unref (wbcg->edit_line.full_content);
		wbcg->edit_line.full_content = NULL;
	}

	if (wbcg->edit_line.cur_fmt) {
		pango_attr_list_unref (wbcg->edit_line.cur_fmt);
		wbcg->edit_line.cur_fmt = NULL;
	}

	/* set pos to 0, to ensure that if we start editing by clicking on the
	 * editline at the last position, we'll get the right style feedback */
	gtk_editable_set_position ((GtkEditable *) wbcg_get_entry (wbcg), 0);

	wb_control_update_action_sensitivity (wbc);

	if (!sheet->workbook->during_destruction) {
		/* restore focus to original sheet in case things were being selected
		 * on a different page.  Do no go through the view, rangesel is
		 * specific to the control.  */
		wb_control_sheet_focus (wbc, sheet);
		/* Only the edit sheet has an edit cursor */
		scg_edit_stop (wbcg_cur_scg (wbcg));
	}
	wbcg_auto_complete_destroy (wbcg);
	wb_control_style_feedback (wbc, NULL);	/* in case markup messed with things */

	return TRUE;
}
void
dialog_so_size (WBCGtk *wbcg, GObject *so)
{
	GtkBuilder *gui;
	SOSizeState *state;
	int width, height;

	g_return_if_fail (wbcg != NULL);

	if (gnumeric_dialog_raise_if_exists (wbcg, SO_SIZE_DIALOG_KEY))
		return;
	gui = gnm_gtk_builder_load ("sheetobject-size.ui", NULL, GO_CMD_CONTEXT (wbcg));
	if (gui == NULL)
		return;

	state = g_new (SOSizeState, 1);
	state->wbcg  = wbcg;
	state->sv = wb_control_cur_sheet_view (WORKBOOK_CONTROL (wbcg));
	state->sheet = sv_sheet (state->sv);
	state->scg = wbcg_get_nth_scg (wbcg, state->sheet->index_in_wb);
	state->gui    = gui;
	state->dialog = go_gtk_builder_get_widget (state->gui, "object-size");

	state->so = SHEET_OBJECT (so);
	g_object_ref (so);

	state->nameentry = GTK_ENTRY (go_gtk_builder_get_widget (state->gui, "name-entry"));
	state->old_anchor = NULL;
	state->old_name = NULL;
	g_object_get (so, "name", &state->old_name, NULL);
	if (state->old_name == NULL)
		state->old_name = g_strdup ("");
	gtk_entry_set_text (state->nameentry, state->old_name);
	state->so_name_changed = FALSE;
	g_signal_connect (G_OBJECT (state->nameentry),
			  "focus-out-event",
			  G_CALLBACK (cb_dialog_so_size_name_changed),
			  state);
	state->so_print_check_changed = FALSE;

	state->wpoints = GTK_WIDGET (go_gtk_builder_get_widget (state->gui, "w-pts-label"));
	state->wspin  = GTK_SPIN_BUTTON (go_gtk_builder_get_widget (state->gui, "w-spin"));
	state->hpoints = GTK_WIDGET (go_gtk_builder_get_widget (state->gui, "h-pts-label"));
	state->hspin  = GTK_SPIN_BUTTON (go_gtk_builder_get_widget (state->gui, "h-spin"));
	state->xpoints = GTK_WIDGET (go_gtk_builder_get_widget (state->gui, "x-pts-label"));
	state->xspin  = GTK_SPIN_BUTTON (go_gtk_builder_get_widget (state->gui, "x-spin"));
	state->ypoints = GTK_WIDGET (go_gtk_builder_get_widget (state->gui, "y-pts-label"));
	state->yspin  = GTK_SPIN_BUTTON (go_gtk_builder_get_widget (state->gui, "y-spin"));
	state->print_check = GTK_WIDGET (go_gtk_builder_get_widget (state->gui,
							       "print-check"));
	dialog_so_size_load (state);
	state->active_anchor = sheet_object_anchor_dup (sheet_object_get_anchor
							(state->so));
	width = state->coords[2] - state->coords[0];
	height = state->coords[3] - state->coords[1];

	gtk_spin_button_set_value (state->wspin, (width < 0) ? - width : width);
	gtk_spin_button_set_value (state->hspin, (height < 0) ? - height : height);
	gtk_spin_button_set_value (state->xspin, 0.);
	gtk_spin_button_set_value (state->yspin, 0.);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (state->print_check),
				      !(state->so->flags & SHEET_OBJECT_PRINT));
	g_signal_connect (G_OBJECT (state->wspin),
			  "value-changed",
			  G_CALLBACK (cb_dialog_so_size_value_changed_update_points),
			  state->wpoints);
	g_signal_connect (G_OBJECT (state->hspin),
			  "value-changed",
			  G_CALLBACK (cb_dialog_so_size_value_changed_update_points),
			  state->hpoints);
	g_signal_connect (G_OBJECT (state->xspin),
			  "value-changed",
			  G_CALLBACK (cb_dialog_so_size_value_changed_update_points),
			  state->xpoints);
	g_signal_connect (G_OBJECT (state->yspin),
			  "value-changed",
			  G_CALLBACK (cb_dialog_so_size_value_changed_update_points),
			  state->ypoints);
	g_signal_connect (G_OBJECT (state->print_check),
			  "toggled",
			  G_CALLBACK (cb_dialog_so_size_print_check_toggled),
			  state);

	cb_dialog_so_size_value_changed_update_points (state->wspin, GTK_LABEL (state->wpoints));
	cb_dialog_so_size_value_changed_update_points (state->hspin, GTK_LABEL (state->hpoints));
	cb_dialog_so_size_value_changed_update_points (state->xspin, GTK_LABEL (state->xpoints));
	cb_dialog_so_size_value_changed_update_points (state->yspin, GTK_LABEL (state->ypoints));


	g_signal_connect (G_OBJECT (state->wspin),
		"value-changed",
		G_CALLBACK (cb_dialog_so_size_value_changed), state);
	g_signal_connect (G_OBJECT (state->hspin),
		"value-changed",
		G_CALLBACK (cb_dialog_so_size_value_changed), state);
	g_signal_connect (G_OBJECT (state->xspin),
		"value-changed",
		G_CALLBACK (cb_dialog_so_size_value_changed), state);
	g_signal_connect (G_OBJECT (state->yspin),
		"value-changed",
		G_CALLBACK (cb_dialog_so_size_value_changed), state);

	state->ok_button = go_gtk_builder_get_widget (state->gui, "ok_button");
	g_signal_connect (G_OBJECT (state->ok_button),
		"clicked",
		G_CALLBACK (cb_dialog_so_size_ok_clicked), state);
	state->apply_button = go_gtk_builder_get_widget (state->gui, "apply_button");
	g_signal_connect (G_OBJECT (state->apply_button),
		"clicked",
		G_CALLBACK (cb_dialog_so_size_apply_clicked), state);

	state->cancel_button = go_gtk_builder_get_widget (state->gui, "cancel_button");
	g_signal_connect (G_OBJECT (state->cancel_button),
		"clicked",
		G_CALLBACK (cb_dialog_so_size_cancel_clicked), state);

	gnumeric_init_help_button (
		go_gtk_builder_get_widget (state->gui, "help_button"),
		GNUMERIC_HELP_LINK_SO_SIZE);

	gnm_dialog_setup_destroy_handlers (GTK_DIALOG (state->dialog),
					   state->wbcg,
					   GNM_DIALOG_DESTROY_CURRENT_SHEET_REMOVED);

	wbc_gtk_attach_guru (state->wbcg, state->dialog);
	g_object_set_data_full (G_OBJECT (state->dialog),
		"state", state, (GDestroyNotify) cb_dialog_so_size_destroy);

	gnumeric_keyed_dialog (wbcg, GTK_WINDOW (state->dialog),
			       SO_SIZE_DIALOG_KEY);
	dialog_so_size_button_sensitivity (state);
	gtk_widget_show (state->dialog);
}
Exemple #21
0
void
dialog_search (WBCGtk *wbcg)
{
	GtkBuilder *gui;
	GtkDialog *dialog;
	DialogState *dd;
	GtkTable *table;
	char *f;

	g_return_if_fail (wbcg != NULL);

#ifdef USE_GURU
	/* Only one guru per workbook. */
	if (wbc_gtk_get_guru (wbcg))
		return;
#endif

	f = g_build_filename (gnm_sys_data_dir (), "ui", "search.ui", NULL);
	gui = go_gtk_builder_new (f, NULL, GO_CMD_CONTEXT (wbcg));
	g_free (f);
        if (gui == NULL)
                return;

	dialog = GTK_DIALOG (gtk_builder_get_object (gui, "search_dialog"));

	dd = g_new (DialogState, 1);
	dd->wbcg = wbcg;
	dd->gui = gui;
	dd->dialog = dialog;
	dd->matches = g_ptr_array_new ();

	dd->prev_button = go_gtk_builder_get_widget (gui, "prev_button");
	dd->next_button = go_gtk_builder_get_widget (gui, "next_button");

	dd->notebook = GTK_NOTEBOOK (gtk_builder_get_object (gui, "notebook"));
	dd->notebook_matches_page =
		gtk_notebook_page_num (dd->notebook,
				       go_gtk_builder_get_widget (gui, "matches_tab"));

	dd->rangetext = gnm_expr_entry_new (wbcg, TRUE);
	gnm_expr_entry_set_flags (dd->rangetext, 0, GNM_EE_MASK);
	table = GTK_TABLE (gtk_builder_get_object (gui, "page1-table"));
	gtk_table_attach (table, GTK_WIDGET (dd->rangetext),
			  1, 2, 6, 7,
			  GTK_EXPAND | GTK_FILL, 0,
			  0, 0);
	{
		char *selection_text =
			selection_to_string (
				wb_control_cur_sheet_view (WORKBOOK_CONTROL (wbcg)),
				TRUE);
		gnm_expr_entry_load_from_text  (dd->rangetext, selection_text);
		g_free (selection_text);
	}

	dd->gentry = GTK_ENTRY (gtk_entry_new ());
	gtk_table_attach (table, GTK_WIDGET (dd->gentry),
			  1, 2, 0, 1,
			  GTK_EXPAND | GTK_FILL, 0,
			  0, 0);
	gtk_widget_grab_focus (GTK_WIDGET (dd->gentry));
	gnumeric_editable_enters (GTK_WINDOW (dialog), GTK_WIDGET (dd->gentry));

	dd->matches_table = make_matches_table (dd);

	{
		GtkWidget *scrolled_window =
			gtk_scrolled_window_new (NULL, NULL);
		gtk_container_add (GTK_CONTAINER (scrolled_window),
				   GTK_WIDGET (dd->matches_table));
		gtk_box_pack_start (GTK_BOX (gtk_builder_get_object (gui, "matches_vbox")),
				    scrolled_window,
				    TRUE, TRUE, 0);
		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
						GTK_POLICY_NEVER,
						GTK_POLICY_ALWAYS);
	}

	/* Set sensitivity of buttons.  */
	cursor_change (dd->matches_table, dd);

	g_signal_connect (G_OBJECT (dd->matches_table), "cursor_changed",
		G_CALLBACK (cursor_change), dd);
	g_signal_connect (G_OBJECT (dd->matches_table), "select_cursor_row",
		G_CALLBACK (cb_next), dd);
	go_gtk_builder_signal_connect (gui, "search_button", "clicked",
		G_CALLBACK (search_clicked), dd);
	g_signal_connect (G_OBJECT (dd->prev_button), "clicked",
		G_CALLBACK (prev_clicked), dd);
	g_signal_connect (G_OBJECT (dd->next_button), "clicked",
		G_CALLBACK (next_clicked), dd);
	go_gtk_builder_signal_connect_swapped (gui, "close_button", "clicked",
		G_CALLBACK (gtk_widget_destroy), dd->dialog);
	g_signal_connect (G_OBJECT (gnm_expr_entry_get_entry (dd->rangetext)), "focus-in-event",
		G_CALLBACK (range_focused), dd);
	go_gtk_builder_signal_connect (gui, "scope_range", "toggled",
		G_CALLBACK (cb_focus_on_entry), dd->rangetext);

#ifdef USE_GURU
	wbc_gtk_attach_guru_with_unfocused_rs (wbcg, GTK_WIDGET (dialog), dd->rangetext);
#endif
	g_object_set_data_full (G_OBJECT (dialog),
		"state", dd, (GDestroyNotify) free_state);
	gnm_dialog_setup_destroy_handlers (dialog, wbcg,
		GNM_DIALOG_DESTROY_SHEET_REMOVED);
	gnumeric_init_help_button (
		go_gtk_builder_get_widget (gui, "help_button"),
		GNUMERIC_HELP_LINK_SEARCH);
	gnumeric_restore_window_geometry (GTK_WINDOW (dialog), SEARCH_KEY);

	go_gtk_nonmodal_dialog (wbcg_toplevel (wbcg), GTK_WINDOW (dialog));
	gtk_widget_show_all (GTK_WIDGET (dialog));
}