Exemple #1
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);
	}
}
Exemple #2
0
void
dialog_so_list (WBCGtk *wbcg, GObject *so)
{
	GnmDialogSOList *state;

	g_return_if_fail (wbcg != NULL);

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

	state = g_new0 (GnmDialogSOList, 1);
	if (so_list_init (state, wbcg, GNM_SO (so))) {
		go_gtk_notice_dialog (wbcg_toplevel (wbcg), GTK_MESSAGE_ERROR,
			_("Could not create the List Property dialog."));
		g_free (state);
	}
}
Exemple #3
0
void
dialog_tabulate (WBCGtk *wbcg, Sheet *sheet)
{
	GtkBuilder *gui;
	GtkDialog *dialog;
	DialogState *dd;
	int i;

	g_return_if_fail (wbcg != NULL);

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

	if (gnm_dialog_raise_if_exists (wbcg, TABULATE_KEY))
		return;
	gui = gnm_gtk_builder_load ("tabulate.ui", NULL, GO_CMD_CONTEXT (wbcg));
        if (gui == NULL)
                return;

	dialog = GTK_DIALOG (go_gtk_builder_get_widget (gui, "tabulate_dialog"));

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

	dd->grid = GTK_GRID (go_gtk_builder_get_widget (gui, "main-grid"));
	/* we might get the 4 below from the positon of some of the widgets inside the grid */
	for (i = 1; i < 4; i++) {
		GnmExprEntry *ge = gnm_expr_entry_new (wbcg, TRUE);
		gnm_expr_entry_set_flags (ge,
			GNM_EE_SINGLE_RANGE | GNM_EE_SHEET_OPTIONAL,
			GNM_EE_MASK);

		gtk_grid_attach (dd->grid, GTK_WIDGET (ge), COL_CELL, i + 1, 1, 1);
		gtk_widget_set_margin_left (GTK_WIDGET (ge), 18);
		gtk_widget_show (GTK_WIDGET (ge));
	}

	dd->resultrangetext = gnm_expr_entry_new (wbcg, TRUE);
	gnm_expr_entry_set_flags (dd->resultrangetext,
		GNM_EE_SINGLE_RANGE | GNM_EE_SHEET_OPTIONAL,
		GNM_EE_MASK);
	gtk_grid_attach (dd->grid, GTK_WIDGET (dd->resultrangetext), 0, 6, 4, 1);
	gtk_widget_set_margin_left (GTK_WIDGET (dd->resultrangetext), 18);
	gtk_widget_show (GTK_WIDGET (dd->resultrangetext));

	g_signal_connect (G_OBJECT (go_gtk_builder_get_widget (gui, "ok_button")),
		"clicked",
		G_CALLBACK (tabulate_ok_clicked), dd);

	g_signal_connect (G_OBJECT (go_gtk_builder_get_widget (gui, "cancel_button")),
		"clicked",
		G_CALLBACK (cancel_clicked), dd);
/* FIXME: Add correct helpfile address */
	gnm_init_help_button (
		go_gtk_builder_get_widget (gui, "help_button"),
		GNUMERIC_HELP_LINK_TABULATE);
	g_object_set_data_full (G_OBJECT (dialog),
		"state", dd, (GDestroyNotify) cb_dialog_destroy);

	gnm_dialog_setup_destroy_handlers (dialog, wbcg,
					   GNM_DIALOG_DESTROY_SHEET_REMOVED);

	gtk_widget_show_all (gtk_dialog_get_content_area (dialog));
	wbc_gtk_attach_guru (wbcg, GTK_WIDGET (dialog));

	non_model_dialog (wbcg, dialog, TABULATE_KEY);
}
Exemple #4
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 #5
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 #6
0
static int
item_grid_button_pressed (GocItem *item, int button, double x_, double y_)
{
	GnmItemGrid *ig = GNM_ITEM_GRID (item);
	GocCanvas    *canvas = item->canvas;
	GnmPane *pane = GNM_PANE (canvas);
	SheetControlGUI *scg = ig->scg;
	WBCGtk *wbcg = scg_wbcg (scg);
	SheetControl	*sc = (SheetControl *)scg;
	SheetView	*sv = sc_view (sc);
	Sheet		*sheet = sv_sheet (sv);
	GnmCellPos	pos;
	gboolean edit_showed_dialog;
	gboolean already_selected;
	GdkEvent *event = goc_canvas_get_cur_event (item->canvas);
	gint64 x = x_ * canvas->pixels_per_unit, y = y_ * canvas->pixels_per_unit;

	gnm_pane_slide_stop (pane);

	pos.col = gnm_pane_find_col (pane, x, NULL);
	pos.row = gnm_pane_find_row (pane, y, NULL);

	/* GnmRange check first */
	if (pos.col >= gnm_sheet_get_max_cols (sheet))
		return TRUE;
	if (pos.row >= gnm_sheet_get_max_rows (sheet))
		return TRUE;

	/* A new object is ready to be realized and inserted */
	if (wbcg->new_object != NULL)
		return ig_obj_create_begin (ig, button, x, y);

	/* If we are not configuring an object then clicking on the sheet
	 * ends the edit.  */
	if (scg->selected_objects == NULL)
		wbcg_focus_cur_scg (wbcg);
	else if (wbc_gtk_get_guru (wbcg) == NULL)
		scg_mode_edit (scg);

	/* If we were already selecting a range of cells for a formula,
	 * reset the location to a new place, or extend the selection.
	 */
	if (button == 1 && scg->rangesel.active) {
		ig->selecting = GNM_ITEM_GRID_SELECTING_FORMULA_RANGE;
		if (event->button.state & GDK_SHIFT_MASK)
			scg_rangesel_extend_to (scg, pos.col, pos.row);
		else
			scg_rangesel_bound (scg, pos.col, pos.row, pos.col, pos.row);
		gnm_pane_slide_init (pane);
		gnm_simple_canvas_grab (item,
			GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
			NULL, gdk_event_get_time (event));
		return TRUE;
	}

	/* If the user is editing a formula (wbcg_rangesel_possible) then we
	 * enable the dynamic cell selection mode.
	 */
	if (button == 1 && wbcg_rangesel_possible (wbcg)) {
		scg_rangesel_start (scg, pos.col, pos.row, pos.col, pos.row);
		ig->selecting = GNM_ITEM_GRID_SELECTING_FORMULA_RANGE;
		gnm_pane_slide_init (pane);
		gnm_simple_canvas_grab (item,
			GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
			NULL, gdk_event_get_time (event));
		return TRUE;
	}

	/* While a guru is up ignore clicks */
	if (wbc_gtk_get_guru (wbcg) != NULL)
		return TRUE;

	/* This was a regular click on a cell on the spreadsheet.  Select it.
	 * but only if the entered expression is valid */
	if (!wbcg_edit_finish (wbcg, WBC_EDIT_ACCEPT, &edit_showed_dialog))
		return TRUE;

	if (button == 1 && !sheet_selection_is_allowed (sheet, &pos))
		return TRUE;

	/* Button == 1 is used to trigger hyperlinks (and possibly similar */
	/* special cases. Otherwise button == 2 should behave exactly like */
	/* button == 1. See bug #700792                                    */
	
	/* buttons 1 and 2 will always change the selection,  the other buttons will
	 * only effect things if the target is not already selected.  */
	already_selected = sv_is_pos_selected (sv, pos.col, pos.row);
	if (button == 1 || button == 2 || !already_selected) {
		if (!(event->button.state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK)))
			sv_selection_reset (sv);

		if ((event->button.button != 1 && event->button.button != 2) 
		    || !(event->button.state & GDK_SHIFT_MASK) ||
		    sv->selections == NULL) {
			sv_selection_add_pos (sv, pos.col, pos.row,
					      (already_selected && (event->button.state & GDK_CONTROL_MASK)) ?
					      GNM_SELECTION_MODE_REMOVE :
					      GNM_SELECTION_MODE_ADD);
			sv_make_cell_visible (sv, pos.col, pos.row, FALSE);
		} else sv_selection_extend_to (sv, pos.col, pos.row);
		sheet_update (sheet);
	}

	if (edit_showed_dialog)
		return TRUE;  /* we already ignored the button release */

	switch (button) {
	case 1:
	case 2: {
		guint32 double_click_time;

		/*
		 *  If the second click is on a different cell than the
		 *  first one this cannot be a double-click
		 */
		if (already_selected) {
			g_object_get (gtk_widget_get_settings (GTK_WIDGET (canvas)),
				      "gtk-double-click-time", &double_click_time,
				      NULL);

			if ((ig->last_click_time + double_click_time) > gdk_event_get_time (event) &&
			    wbcg_edit_start (wbcg, FALSE, FALSE)) {
				break;
			}
		}

		ig->last_click_time = gdk_event_get_time (event);
		ig->selecting = GNM_ITEM_GRID_SELECTING_CELL_RANGE;
		gnm_pane_slide_init (pane);
		gnm_simple_canvas_grab (item,
			GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
			NULL, gdk_event_get_time (event));
		break;
	}

	case 3: scg_context_menu (scg, event, FALSE, FALSE);
		break;
	default :
		break;
	}

	return TRUE;
}
Exemple #7
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));
}