workbook-control-gui.c 125 KB
Newer Older
1 2
/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */

3 4 5
/*
 * workbook-control-gui.c: GUI specific routines for a workbook-control.
 *
Jody Goldberg's avatar
Jody Goldberg committed
6
 * Copyright (C) 2000 Jody Goldberg (jody@gnome.org)
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 */
23 24
#include <gnumeric-config.h>
#include "gnumeric.h"
25
#include "workbook-control-gui-priv.h"
26

27 28 29 30 31 32 33
#include "application.h"
#include "workbook-object-toolbar.h"
#include "workbook-format-toolbar.h"
#include "workbook-view.h"
#include "workbook-edit.h"
#include "workbook.h"
#include "sheet.h"
34
#include "sheet-merge.h"
35
#include "sheet-private.h"
36
#include "sheet-control-gui-priv.h"
37
#include "gnumeric-canvas.h"
Jody Goldberg's avatar
Jody Goldberg committed
38
#include "sheet-object.h"
39 40 41 42 43 44 45 46 47 48 49 50 51 52
#include "dialogs.h"
#include "commands.h"
#include "cmd-edit.h"
#include "workbook-cmd-format.h"
#include "selection.h"
#include "clipboard.h"
#include "print.h"
#include "gui-clipboard.h"
#include "workbook-edit.h"
#include "main.h"
#include "eval.h"
#include "position.h"
#include "parse-util.h"
#include "ranges.h"
Morten Welinder's avatar
Morten Welinder committed
53
#include "value.h"
Jody Goldberg's avatar
Jody Goldberg committed
54
#include "validation.h"
Jody Goldberg's avatar
Jody Goldberg committed
55 56
#include "history.h"
#include "str.h"
Jody Goldberg's avatar
Jody Goldberg committed
57
#include "cell.h"
58
#include "gui-file.h"
59
#include "search.h"
60
#include "error-info.h"
Jody Goldberg's avatar
fix.  
Jody Goldberg committed
61
#include "pixmaps/equal-sign.xpm"
62
#include "gui-util.h"
Jody Goldberg's avatar
fix.  
Jody Goldberg committed
63
#include "widgets/widget-editable-label.h"
64
#include "widgets/gnumeric-combo-text.h"
65

Jody Goldberg's avatar
update  
Jody Goldberg committed
66 67
#ifdef ENABLE_BONOBO
#include "sheet-object-container.h"
68
#ifdef ENABLE_EVOLUTION
Jody Goldberg's avatar
Jody Goldberg committed
69
#include <idl/Evolution-Composer.h>
70 71
#include <bonobo/bonobo-stream-memory.h>
#endif
Jody Goldberg's avatar
update  
Jody Goldberg committed
72
#endif
73

74
#include <gal/util/e-util.h>
Jody Goldberg's avatar
fix.  
Jody Goldberg committed
75
#include <gal/widgets/widget-color-combo.h>
76
#include <gal/widgets/gtk-combo-stack.h>
Jody Goldberg's avatar
fix.  
Jody Goldberg committed
77 78 79 80

#include <libgnome/gnome-i18n.h>
#include <libgnome/gnome-config.h>

81
#include <ctype.h>
82
#include <stdarg.h>
83
#include <stdio.h>
84
#include <errno.h>
85

86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
gboolean
wbcg_ui_update_begin (WorkbookControlGUI *wbcg)
{
	g_return_val_if_fail (IS_WORKBOOK_CONTROL_GUI (wbcg), FALSE);
	g_return_val_if_fail (!wbcg->updating_ui, FALSE);

	return (wbcg->updating_ui = TRUE);
}

void
wbcg_ui_update_end (WorkbookControlGUI *wbcg)
{
	g_return_if_fail (IS_WORKBOOK_CONTROL_GUI (wbcg));
	g_return_if_fail (wbcg->updating_ui);

	wbcg->updating_ui = FALSE;
}

104 105 106 107 108 109 110 111 112 113 114
static int
sheet_to_page_index (WorkbookControlGUI *wbcg, Sheet *sheet, SheetControlGUI **res)
{
	int i = 0;
	GtkWidget *w;

	if (res)
		*res = NULL;
	g_return_val_if_fail (IS_SHEET (sheet), -1);

	for ( ; NULL != (w = gtk_notebook_get_nth_page (wbcg->notebook, i)) ; i++) {
115 116 117
		GtkObject *obj = gtk_object_get_data (GTK_OBJECT (w),
						      SHEET_CONTROL_KEY);
		SheetControlGUI *scg = SHEET_CONTROL_GUI (obj);
118
		SheetControl *sc = (SheetControl *) scg;
Morten Welinder's avatar
Morten Welinder committed
119

120
		if (scg != NULL && sc->sheet == sheet) {
121
			if (res)
122
				*res = scg;
123 124 125 126 127 128
			return i;
		}
	}
	return -1;
}

Jody Goldberg's avatar
Jody Goldberg committed
129
GtkWindow *
Jody Goldberg's avatar
Jody Goldberg committed
130
wbcg_toplevel (WorkbookControlGUI *wbcg)
Jody Goldberg's avatar
Jody Goldberg committed
131
{
132 133
	g_return_val_if_fail (IS_WORKBOOK_CONTROL_GUI (wbcg), NULL);

Jody Goldberg's avatar
be safe  
Jody Goldberg committed
134
	return wbcg->toplevel;
Jody Goldberg's avatar
Jody Goldberg committed
135 136
}

137
/**
138
 * wbcg_focus_cur_scg :
139 140 141 142 143 144 145 146
 * @wbcg : The workbook control to operate on.
 *
 * A utility routine to safely ensure that the keyboard focus
 * is attached to the item-grid.  This is required when a user
 * edits a combo-box or and entry-line which grab focus.
 *
 * It is called for zoom, font name/size, and accept/cancel for the editline.
 */
147 148
Sheet *
wbcg_focus_cur_scg (WorkbookControlGUI *wbcg)
Jody Goldberg's avatar
Jody Goldberg committed
149
{
Jody Goldberg's avatar
Jody Goldberg committed
150
	GtkWidget *table;
151
	GtkObject *obj;
152
	SheetControlGUI *scg;
153
	Sheet *sheet;
Jody Goldberg's avatar
Jody Goldberg committed
154

Jody Goldberg's avatar
Jody Goldberg committed
155
	g_return_if_fail (IS_WORKBOOK_CONTROL_GUI (wbcg));
Jody Goldberg's avatar
Jody Goldberg committed
156

Jody Goldberg's avatar
Jody Goldberg committed
157 158 159
	table = gtk_notebook_get_nth_page (wbcg->notebook,
		gtk_notebook_get_current_page (wbcg->notebook));
	obj = gtk_object_get_data (GTK_OBJECT (table), SHEET_CONTROL_KEY);
160
	scg = SHEET_CONTROL_GUI (obj);
161

Jody Goldberg's avatar
Jody Goldberg committed
162
	g_return_if_fail (scg != NULL);
163

164
	scg_take_focus (scg);
165
	return sc_sheet (SHEET_CONTROL (scg));
166
}
Jody Goldberg's avatar
Jody Goldberg committed
167

168
SheetControlGUI *
Jody Goldberg's avatar
Jody Goldberg committed
169
wbcg_cur_scg (WorkbookControlGUI *wbcg)
170 171
{
	SheetControlGUI *scg;
Jody Goldberg's avatar
Jody Goldberg committed
172

173 174
	sheet_to_page_index (wbcg,
		wb_control_cur_sheet (WORKBOOK_CONTROL (wbcg)), &scg);
Jody Goldberg's avatar
Jody Goldberg committed
175

176
	return scg;
Jody Goldberg's avatar
Jody Goldberg committed
177 178
}

179 180 181 182 183 184 185 186
/****************************************************************************/
/* Autosave */
static gboolean
cb_autosave (gpointer *data)
{
	WorkbookView *wb_view;
        WorkbookControlGUI *wbcg = (WorkbookControlGUI *)data;

187
	g_return_val_if_fail (IS_WORKBOOK_CONTROL_GUI (wbcg), FALSE);
188 189 190 191 192 193 194 195 196

	wb_view = wb_control_view (WORKBOOK_CONTROL (wbcg));

	if (wb_view == NULL)
		return FALSE;

	if (wbcg->autosave && workbook_is_dirty (wb_view_workbook (wb_view))) {
	        if (wbcg->autosave_prompt && !dialog_autosave_prompt (wbcg))
			return TRUE;
197
		gui_file_save (wbcg, wb_view);
198 199 200 201
	}
	return TRUE;
}

202 203 204 205 206 207 208 209 210 211 212 213 214
/**
 * wbcg_rangesel_possible
 * @wbcg : the workbook control gui
 *
 * Returns true if the cursor keys should be used to select
 * a cell range (if the cursor is in a spot in the expression
 * where it makes sense to have a cell reference), false if not.
 */
gboolean
wbcg_rangesel_possible (WorkbookControlGUI const *wbcg)
{
	g_return_val_if_fail (IS_WORKBOOK_CONTROL_GUI (wbcg), FALSE);

215 216
	/* Already range selecting */
	if (wbcg->rangesel != NULL)
217 218
		return TRUE;

219
	/* Rangesel requires that we be editing somthing */
220
	if (!wbcg_is_editing (wbcg) && !wbcg_edit_entry_redirect_p (wbcg))
221 222
		return FALSE;

223
	return gnumeric_expr_entry_rangesel_meaningful (wbcg_get_entry_logical (wbcg));
224 225
}

Jody Goldberg's avatar
Jody Goldberg committed
226
gboolean
227
wbcg_is_editing (WorkbookControlGUI const *wbcg)
Jody Goldberg's avatar
Jody Goldberg committed
228 229 230 231 232
{
	g_return_val_if_fail (IS_WORKBOOK_CONTROL_GUI (wbcg), FALSE);
	return wbcg->editing;
}

233
void
234
wbcg_autosave_cancel (WorkbookControlGUI *wbcg)
235
{
Jody Goldberg's avatar
Jody Goldberg committed
236 237
	g_return_if_fail (IS_WORKBOOK_CONTROL_GUI (wbcg));

238 239 240 241 242 243 244
	if (wbcg->autosave_timer != 0) {
		gtk_timeout_remove (wbcg->autosave_timer);
		wbcg->autosave_timer = 0;
	}
}

void
245
wbcg_autosave_set (WorkbookControlGUI *wbcg, int minutes, gboolean prompt)
246
{
Jody Goldberg's avatar
Jody Goldberg committed
247 248
	g_return_if_fail (IS_WORKBOOK_CONTROL_GUI (wbcg));

249
	wbcg_autosave_cancel (wbcg);
250 251 252 253 254 255 256 257 258 259 260

	wbcg->autosave = (minutes != 0);
	wbcg->autosave_minutes = minutes;
	wbcg->autosave_prompt = prompt;

	if (wbcg->autosave)
		wbcg->autosave_timer = gtk_timeout_add (minutes * 60000,
			(GtkFunction) cb_autosave, wbcg);
}
/****************************************************************************/

Jody Goldberg's avatar
Jody Goldberg committed
261 262 263 264 265 266
static WorkbookControl *
wbcg_control_new (WorkbookControl *wbc, WorkbookView *wbv, Workbook *wb)
{
	return workbook_control_gui_new (wbv, wb);
}

Jody Goldberg's avatar
Jody Goldberg committed
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
static void
wbcg_init_state (WorkbookControl *wbc)
{
	WorkbookView	   *wbv = wb_control_view (wbc);
	WorkbookControlGUI *wbcg = WORKBOOK_CONTROL_GUI (wbc);
	ColorCombo *combo;

	/* Associate the combos with the view */
	combo = COLOR_COMBO (wbcg->back_color);
	color_palette_set_group (combo->palette,
		color_group_fetch ("back_color_group", wbv));
	combo = COLOR_COMBO (wbcg->fore_color);
	color_palette_set_group (combo->palette,
		color_group_fetch ("fore_color_group", wbv));
}

283 284 285 286 287 288 289 290 291 292 293
static void
wbcg_title_set (WorkbookControl *wbc, char const *title)
{
	WorkbookControlGUI *wbcg = (WorkbookControlGUI *)wbc;
	char *full_title;

	g_return_if_fail (wbcg != NULL);
	g_return_if_fail (title != NULL);

	full_title = g_strconcat (title, _(" : Gnumeric"), NULL);

Jody Goldberg's avatar
Jody Goldberg committed
294
 	gtk_window_set_title (wbcg_toplevel (wbcg), full_title);
295 296 297 298 299 300 301
	g_free (full_title);
}

static void
cb_prefs_update (gpointer key, gpointer value, gpointer user_data)
{
	Sheet *sheet = value;
302
	sheet_adjust_preferences (sheet, FALSE, FALSE);
303 304 305 306 307 308 309
}

static void
wbcg_prefs_update (WorkbookControl *wbc)
{
	WorkbookControlGUI *wbcg = (WorkbookControlGUI *)wbc;
	Workbook	*wb  = wb_control_workbook (wbc);
Jody Goldberg's avatar
Jody Goldberg committed
310
	WorkbookView	*wbv = wb_control_view (wbc);
311 312

	g_hash_table_foreach (wb->sheet_hash_private, cb_prefs_update, NULL);
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
313
	gtk_notebook_set_show_tabs (wbcg->notebook,
314 315 316 317
				    wbv->show_notebook_tabs);
}

static void
Jody Goldberg's avatar
Jody Goldberg committed
318
wbcg_format_feedback (WorkbookControl *wbc)
319
{
Jody Goldberg's avatar
Jody Goldberg committed
320
	workbook_feedback_set ((WorkbookControlGUI *)wbc);
321 322 323
}

static void
Jody Goldberg's avatar
Jody Goldberg committed
324
zoom_changed (WorkbookControlGUI *wbcg, Sheet* sheet)
325 326 327
{
	gchar buffer [25];

Jody Goldberg's avatar
delete.  
Jody Goldberg committed
328
	g_return_if_fail (IS_SHEET (sheet));
329 330 331
	g_return_if_fail (wbcg->zoom_entry != NULL);

	snprintf (buffer, sizeof (buffer), "%d%%",
332
		  (int) (sheet->last_zoom_factor_used * 100 + .5));
Jody Goldberg's avatar
delete.  
Jody Goldberg committed
333

334
	if (wbcg_ui_update_begin (wbcg)) {
335 336
		gnm_combo_text_set_text (GNM_COMBO_TEXT (wbcg->zoom_entry),
			buffer, GNM_COMBO_TEXT_CURRENT);
337 338
		wbcg_ui_update_end (wbcg);
	}
Jody Goldberg's avatar
delete.  
Jody Goldberg committed
339

Jody Goldberg's avatar
Jody Goldberg committed
340
	scg_object_update_bbox (wbcg_cur_scg (wbcg),
341
				NULL, NULL);
342 343 344 345 346 347 348
}

static void
wbcg_zoom_feedback (WorkbookControl *wbc)
{
	WorkbookControlGUI *wbcg = (WorkbookControlGUI *)wbc;
	Sheet *sheet = wb_control_cur_sheet (wbc);
Jody Goldberg's avatar
Jody Goldberg committed
349
	zoom_changed (wbcg, sheet);
350 351 352 353 354
}

static void
wbcg_edit_line_set (WorkbookControl *wbc, char const *text)
{
355 356
	GtkEntry *entry;

357
	entry = GTK_ENTRY (wbcg_get_entry ((WorkbookControlGUI*)wbc));
358 359 360
	gtk_entry_set_text (entry, text);
}

Jody Goldberg's avatar
Jody Goldberg committed
361 362 363 364 365 366 367
static void
wbcg_edit_selection_descr_set (WorkbookControl *wbc, char const *text)
{
	WorkbookControlGUI *wbcg = (WorkbookControlGUI *)wbc;
	gtk_entry_set_text (GTK_ENTRY (wbcg->selection_descriptor), text);
}

Jody Goldberg's avatar
be safe  
Jody Goldberg committed
368 369 370 371 372 373 374 375
/*
 * Signal handler for EditableLabel's text_changed signal.
 */
static gboolean
cb_sheet_label_changed (EditableLabel *el,
			const char *new_name, WorkbookControlGUI *wbcg)
{
	gboolean ans = !cmd_rename_sheet (WORKBOOK_CONTROL (wbcg),
Jody Goldberg's avatar
Jody Goldberg committed
376
		editable_label_get_text (el), new_name);
377
	wbcg_focus_cur_scg (wbcg);
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
378 379 380
	return ans;
}

Jody Goldberg's avatar
Jody Goldberg committed
381 382 383
static void
cb_sheet_label_edit_stopped (EditableLabel *el, WorkbookControlGUI *wbcg)
{
384
	wbcg_focus_cur_scg (wbcg);
Jody Goldberg's avatar
Jody Goldberg committed
385 386
}

Jody Goldberg's avatar
be safe  
Jody Goldberg committed
387
static void
388
sheet_action_add_sheet (GtkWidget *widget, SheetControlGUI *scg)
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
389
{
390 391 392
	SheetControl *sc = (SheetControl *) scg;

	workbook_sheet_add (wb_control_workbook (sc->wbc), sc->sheet, TRUE);
393
	wbcg_focus_cur_scg (scg->wbcg);
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
394
}
Jody Goldberg's avatar
Jody Goldberg committed
395

Jody Goldberg's avatar
be safe  
Jody Goldberg committed
396
static void
397
delete_sheet_if_possible (GtkWidget *ignored, SheetControlGUI *scg)
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
398
{
399 400
	SheetControl *sc = (SheetControl *) scg;
	Workbook *wb = wb_control_workbook (sc->wbc);
Jody Goldberg's avatar
Jody Goldberg committed
401
	GtkWidget *dialog;
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
402
	char *message;
Jody Goldberg's avatar
Jody Goldberg committed
403
	int response;
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
404

Jody Goldberg's avatar
Jody Goldberg committed
405
	/* If this is the last sheet left, ignore the request */
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
406 407 408
	if (workbook_sheet_count (wb) == 1)
		return;

Jody Goldberg's avatar
Jody Goldberg committed
409
	/* Don't prompt for things that are pristine */
410 411 412 413 414
	if (sc->sheet->pristine) {
		workbook_sheet_delete (sc->sheet);
		return;
	}

Jody Goldberg's avatar
be safe  
Jody Goldberg committed
415 416
	message = g_strdup_printf (
		_("Are you sure you want to remove the sheet called `%s'?"),
417
		sc->sheet->name_unquoted);
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
418

Jody Goldberg's avatar
Jody Goldberg committed
419 420 421 422 423
	dialog = gtk_message_dialog_new (wbcg_toplevel (scg->wbcg),
		GTK_DIALOG_DESTROY_WITH_PARENT,
		GTK_MESSAGE_QUESTION,
		GTK_BUTTONS_YES_NO,
		message);
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
424
	g_free (message);
Jody Goldberg's avatar
Jody Goldberg committed
425 426 427 428 429 430
	gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_NO);
	response = gtk_dialog_run (GTK_DIALOG (dialog));
	if (response == GTK_RESPONSE_YES) {
		workbook_sheet_delete (sc->sheet);
		workbook_recalc_all (wb);
	}
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
431 432
}

Jody Goldberg's avatar
update  
Jody Goldberg committed
433
static void
434
sheet_action_rename_sheet (GtkWidget *widget, SheetControlGUI *scg)
Jody Goldberg's avatar
update  
Jody Goldberg committed
435
{
436
	dialog_sheet_name (scg->wbcg);
Jody Goldberg's avatar
update  
Jody Goldberg committed
437 438 439
}

static void
440
sheet_action_clone_sheet (GtkWidget *widget, SheetControlGUI *scg)
Jody Goldberg's avatar
update  
Jody Goldberg committed
441
{
442 443
	SheetControl *sc = (SheetControl *) scg;
     	Sheet *new_sheet = sheet_duplicate (sc->sheet);
Morten Welinder's avatar
Morten Welinder committed
444

445
	workbook_sheet_attach (sc->sheet->workbook, new_sheet, sc->sheet);
Jody Goldberg's avatar
update  
Jody Goldberg committed
446
	sheet_set_dirty (new_sheet, TRUE);
447
	wbcg_focus_cur_scg (scg->wbcg);
Jody Goldberg's avatar
update  
Jody Goldberg committed
448 449 450
}

static void
451
sheet_action_reorder_sheet (GtkWidget *widget, SheetControlGUI *scg)
Jody Goldberg's avatar
update  
Jody Goldberg committed
452
{
453
	dialog_sheet_order (scg->wbcg);
Jody Goldberg's avatar
update  
Jody Goldberg committed
454 455
}

Jody Goldberg's avatar
be safe  
Jody Goldberg committed
456 457 458 459
/**
 * sheet_menu_label_run:
 */
static void
460
sheet_menu_label_run (SheetControlGUI *scg, GdkEventButton *event)
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
461 462
{
#define SHEET_CONTEXT_TEST_SIZE 1
463
	SheetControl *sc = (SheetControl *) scg;
Morten Welinder's avatar
Morten Welinder committed
464

Jody Goldberg's avatar
be safe  
Jody Goldberg committed
465 466
	struct {
		const char *text;
467
		void (*function) (GtkWidget *widget, SheetControlGUI *scg);
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
468 469 470
		int  flags;
	} const sheet_label_context_actions [] = {
		{ N_("Duplicate this sheet"), &sheet_action_clone_sheet, 0 },
471 472
		{ N_("Insert a new sheet"), &sheet_action_add_sheet, 0 },
		{ N_("Rename this sheet"), &sheet_action_rename_sheet, 0 },
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
473
		{ N_("Re-order sheets"), &sheet_action_reorder_sheet, SHEET_CONTEXT_TEST_SIZE },
474
		{ N_("Remove this sheet"), &delete_sheet_if_possible, SHEET_CONTEXT_TEST_SIZE },
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
475 476 477 478 479 480 481 482 483 484 485 486
		{ NULL, NULL }
	};

	GtkWidget *menu;
	GtkWidget *item;
	int i;

	menu = gtk_menu_new ();

	for (i = 0; sheet_label_context_actions [i].text != NULL; i++){
		int flags = sheet_label_context_actions [i].flags;

Jody Goldberg's avatar
update  
Jody Goldberg committed
487
		if (flags & SHEET_CONTEXT_TEST_SIZE &&
488
		    workbook_sheet_count (sc->sheet->workbook) < 2)
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
489
				continue;
Jody Goldberg's avatar
update  
Jody Goldberg committed
490

Jody Goldberg's avatar
be safe  
Jody Goldberg committed
491 492 493 494 495 496 497 498
		item = gtk_menu_item_new_with_label (
			_(sheet_label_context_actions [i].text));
		gtk_menu_append (GTK_MENU (menu), item);
		gtk_widget_show (item);

		gtk_signal_connect (
			GTK_OBJECT (item), "activate",
			GTK_SIGNAL_FUNC (sheet_label_context_actions [i].function),
499
			scg);
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
500 501 502 503 504 505 506 507 508 509 510
	}

	gnumeric_popup_menu (GTK_MENU (menu), event);
}

/**
 * cb_sheet_label_button_press:
 *
 * Invoked when the user has clicked on the EditableLabel widget.
 * This takes care of switching to the notebook that contains the label
 */
Jody Goldberg's avatar
Jody Goldberg committed
511
static gboolean
Jody Goldberg's avatar
update  
Jody Goldberg committed
512 513
cb_sheet_label_button_press (GtkWidget *widget, GdkEventButton *event,
			     GtkWidget *child)
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
514 515 516
{
	GtkWidget *notebook;
	gint page_number;
517 518 519 520 521
	GtkObject *obj = gtk_object_get_data (GTK_OBJECT (child),
					      SHEET_CONTROL_KEY);
	SheetControlGUI *scg = SHEET_CONTROL_GUI (obj);

	g_return_val_if_fail (scg != NULL, FALSE);
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
522 523 524 525 526 527 528

	if (event->type != GDK_BUTTON_PRESS)
		return FALSE;

	notebook = child->parent;
	page_number = gtk_notebook_page_num (GTK_NOTEBOOK (notebook), child);

529
	if (event->button == 1 || NULL != scg->wbcg->rangesel) {
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
530 531 532 533 534
		gtk_notebook_set_page (GTK_NOTEBOOK (notebook), page_number);
		return TRUE;
	}

	if (event->button == 3) {
535 536 537

		sheet_menu_label_run (SHEET_CONTROL_GUI (obj), event);
		scg_take_focus (SHEET_CONTROL_GUI (obj));
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
538 539 540 541 542 543
		return TRUE;
	}

	return FALSE;
}

Jody Goldberg's avatar
update  
Jody Goldberg committed
544
static void workbook_setup_sheets (WorkbookControlGUI *wbcg);
545
static void wbcg_menu_state_sheet_count (WorkbookControl *wbc);
Jody Goldberg's avatar
update  
Jody Goldberg committed
546

Jody Goldberg's avatar
be safe  
Jody Goldberg committed
547 548 549 550
/**
 * wbcg_sheet_add:
 * @sheet: a sheet
 *
551
 * Creates a new SheetControlGUI for the sheet and adds it to the workbook-control-gui.
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
552 553 554 555 556
 */
static void
wbcg_sheet_add (WorkbookControl *wbc, Sheet *sheet)
{
	WorkbookControlGUI *wbcg = (WorkbookControlGUI *)wbc;
557
	SheetControlGUI *scg;
558
	SheetControl *sc;
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
559
	GtkWidget *sheet_label;
Jody Goldberg's avatar
Jody Goldberg committed
560
	GList     *ptr;
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
561 562

	g_return_if_fail (wbcg != NULL);
Jody Goldberg's avatar
update  
Jody Goldberg committed
563 564 565

	if (wbcg->notebook == NULL)
		workbook_setup_sheets (wbcg);
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
566

567
	scg = sheet_control_gui_new (sheet);
568 569
	sc = (SheetControl *) scg;
	sc->wbc = wbc;
570
	scg->wbcg = wbcg;
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
571 572 573 574 575

	/*
	 * NB. this is so we can use editable_label_set_text since
	 * gtk_notebook_set_tab_label kills our widget & replaces with a label.
	 */
Jody Goldberg's avatar
Jody Goldberg committed
576
	sheet_label = editable_label_new (sheet->name_unquoted, sheet->tab_color);
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
577 578 579 580 581 582 583 584
	gtk_signal_connect_after (
		GTK_OBJECT (sheet_label), "text_changed",
		GTK_SIGNAL_FUNC (cb_sheet_label_changed), wbcg);
	gtk_signal_connect (
		GTK_OBJECT (sheet_label), "editing_stopped",
		GTK_SIGNAL_FUNC (cb_sheet_label_edit_stopped), wbcg);
	gtk_signal_connect (
		GTK_OBJECT (sheet_label), "button_press_event",
585
		GTK_SIGNAL_FUNC (cb_sheet_label_button_press), scg->table);
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
586 587

	gtk_widget_show (sheet_label);
588
	gtk_widget_show_all (GTK_WIDGET (scg->table));
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
589

590 591
	if (wbcg_ui_update_begin (wbcg)) {
		gtk_notebook_insert_page (wbcg->notebook,
592
			GTK_WIDGET (scg->table), sheet_label,
593 594 595
			workbook_sheet_index_get (wb_control_workbook (wbc), sheet));
		wbcg_ui_update_end (wbcg);
	}
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
596

597
	wbcg_menu_state_sheet_count (wbc);
Jody Goldberg's avatar
Jody Goldberg committed
598 599 600

	/* create views for the sheet objects */
	for (ptr = sheet->sheet_objects; ptr != NULL ; ptr = ptr->next)
601
		sheet_object_new_view (ptr->data, scg);
602 603
	scg_adjust_preferences (sc);
	scg_set_zoom_factor (sc);
604
	scg_take_focus (scg);
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
605 606 607 608 609 610
}

static void
wbcg_sheet_remove (WorkbookControl *wbc, Sheet *sheet)
{
	WorkbookControlGUI *wbcg = (WorkbookControlGUI *)wbc;
611
	SheetControlGUI *scg;
Jody Goldberg's avatar
update  
Jody Goldberg committed
612 613 614 615 616 617
	int i;

	/* During destruction we may have already removed the notebook */
	if (wbcg->notebook == NULL)
		return;

618
	i = sheet_to_page_index (wbcg, sheet, &scg);
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
619

Jody Goldberg's avatar
Jody Goldberg committed
620
	g_return_if_fail (i >= 0);
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
621

Jody Goldberg's avatar
Jody Goldberg committed
622
	gtk_notebook_remove_page (wbcg->notebook, i);
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
623

624
	wbcg_menu_state_sheet_count (wbc);
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
625 626
}

Jody Goldberg's avatar
Jody Goldberg committed
627 628 629 630 631
static void
wbcg_sheet_rename (WorkbookControl *wbc, Sheet *sheet)
{
	WorkbookControlGUI *wbcg = (WorkbookControlGUI *)wbc;
	GtkWidget *label;
632 633
	SheetControlGUI *scg;
	int i = sheet_to_page_index (wbcg, sheet, &scg);
Jody Goldberg's avatar
Jody Goldberg committed
634 635 636

	g_return_if_fail (i >= 0);

637
	label = gtk_notebook_get_tab_label (wbcg->notebook, GTK_WIDGET (scg->table));
Jody Goldberg's avatar
Jody Goldberg committed
638
	editable_label_set_text (EDITABLE_LABEL (label), sheet->name_unquoted);
Jody Goldberg's avatar
Jody Goldberg committed
639
	editable_label_set_color (EDITABLE_LABEL (label), sheet->tab_color);
Jody Goldberg's avatar
Jody Goldberg committed
640
}
Jody Goldberg's avatar
be safe  
Jody Goldberg committed
641

Jody Goldberg's avatar
Jody Goldberg committed
642
static void
Jody Goldberg's avatar
Jody Goldberg committed
643
wbcg_sheet_focus (WorkbookControl *wbc, Sheet *sheet)
Jody Goldberg's avatar
Jody Goldberg committed
644 645
{
	WorkbookControlGUI *wbcg = (WorkbookControlGUI *)wbc;
646 647
	SheetControlGUI *scg;
	int i = sheet_to_page_index (wbcg, sheet, &scg);
Jody Goldberg's avatar
Jody Goldberg committed
648 649 650 651 652 653 654 655 656

	/* A sheet added in another view may not yet have a view */
	if (i >= 0) {
		gtk_notebook_set_page (wbcg->notebook, i);
		zoom_changed (wbcg, sheet);
	}
}

static void
Jody Goldberg's avatar
Jody Goldberg committed
657
wbcg_sheet_move (WorkbookControl *wbc, Sheet *sheet, int new_pos)
Jody Goldberg's avatar
Jody Goldberg committed
658
{
Jody Goldberg's avatar
Jody Goldberg committed
659
	WorkbookControlGUI *wbcg = (WorkbookControlGUI *)wbc;
660
	SheetControlGUI *scg;
Jody Goldberg's avatar
Jody Goldberg committed
661 662 663 664

	g_return_if_fail (IS_SHEET (sheet));

	/* No need for sanity checking, the workbook did that */
665
        if (sheet_to_page_index (wbcg, sheet, &scg) >= 0)
Jody Goldberg's avatar
Jody Goldberg committed
666
		gtk_notebook_reorder_child (wbcg->notebook,
667
			GTK_WIDGET (scg->table), new_pos);
Jody Goldberg's avatar
Jody Goldberg committed
668 669
}

Jody Goldberg's avatar
update  
Jody Goldberg committed
670 671 672 673 674 675
static void
wbcg_sheet_remove_all (WorkbookControl *wbc)
{
	WorkbookControlGUI *wbcg = (WorkbookControlGUI *)wbc;

	if (wbcg->notebook != NULL) {
676 677
		GtkWidget *tmp = GTK_WIDGET (wbcg->notebook);

678
		/* Be sure we are no longer editing */
679
		wbcg_edit_finish (wbcg, FALSE);
680

681 682 683
		/* Clear notebook to disable updates as focus changes for pages
		 * during destruction
		 */
Jody Goldberg's avatar
update  
Jody Goldberg committed
684
		wbcg->notebook = NULL;
685
		gtk_container_remove (GTK_CONTAINER (wbcg->table), tmp);
Jody Goldberg's avatar
update  
Jody Goldberg committed
686 687 688
	}
}

Jody Goldberg's avatar
Jody Goldberg committed
689 690 691 692 693 694 695 696
static void
wbcg_history_setup (WorkbookControlGUI *wbcg)
{
	GList *hl = application_history_get_list ();
	if (hl)
		history_menu_setup (wbcg, hl);
}

697 698
static gboolean
cb_change_zoom (GtkWidget *caller, char *new_zoom, WorkbookControlGUI *wbcg)
Jody Goldberg's avatar
Jody Goldberg committed
699 700 701
{
	Sheet *sheet = wb_control_cur_sheet (WORKBOOK_CONTROL (wbcg));
	int factor;
702
	char *end;
Jody Goldberg's avatar
Jody Goldberg committed
703

Jody Goldberg's avatar
delete.  
Jody Goldberg committed
704
	if (sheet == NULL || wbcg->updating_ui)
705
		return TRUE;
Jody Goldberg's avatar
Jody Goldberg committed
706

707 708 709 710 711 712 713 714 715 716 717
	errno = 0; /* strtod sets errno, but does not clear it.  */
	factor = strtol (new_zoom, &end, 10);
	if (new_zoom != end && errno != ERANGE && factor == (gnum_float)factor)
		/* The GSList of sheet passed to cmd_zoom will be freed by cmd_zoom,
		 * and the sheet will fore an updat eof the zoom combo to keep the
		 * display consistent
		 */
		cmd_zoom (WORKBOOK_CONTROL (wbcg), g_slist_append (NULL, sheet),
			  (double) factor / 100);
	else
		zoom_changed (wbcg, sheet);
Jody Goldberg's avatar
Jody Goldberg committed
718

719
	wbcg_focus_cur_scg (wbcg);
720

721 722
	/* because we are updating it there is no need to apply it now */
	return FALSE;
Jody Goldberg's avatar
Jody Goldberg committed
723 724 725
}

static void
Jody Goldberg's avatar
Jody Goldberg committed
726
wbcg_auto_expr_value (WorkbookControl *wbc)
Jody Goldberg's avatar
Jody Goldberg committed
727
{
728
	WorkbookControlGUI *wbcg = WORKBOOK_CONTROL_GUI (wbc);
Jody Goldberg's avatar
Jody Goldberg committed
729
	WorkbookView *wbv = wb_control_view (wbc);
Jody Goldberg's avatar
Jody Goldberg committed
730

Jody Goldberg's avatar
Jody Goldberg committed
731 732 733
	g_return_if_fail (wbcg != NULL);
	g_return_if_fail (wbv != NULL);
	g_return_if_fail (wbv->auto_expr_value_as_string != NULL);
Jody Goldberg's avatar
Jody Goldberg committed
734

735
	if (wbcg_ui_update_begin (wbcg)) {
736 737 738
		gtk_label_set_text(
			 GTK_LABEL (GTK_BIN (wbcg->auto_expr_label)->child),
			 wbv->auto_expr_value_as_string);
739 740
		wbcg_ui_update_end (wbcg);
	}
Jody Goldberg's avatar
Jody Goldberg committed
741 742
}

743 744 745 746 747 748 749 750 751 752 753 754 755
static GtkComboStack *
ur_stack (WorkbookControl *wbc, gboolean is_undo)
{
	WorkbookControlGUI *wbcg = (WorkbookControlGUI *)wbc;
	return GTK_COMBO_STACK (is_undo ? wbcg->undo_combo : wbcg->redo_combo);
}

static void
wbcg_undo_redo_clear (WorkbookControl *wbc, gboolean is_undo)
{
	gtk_combo_stack_clear (ur_stack (wbc, is_undo));
}

756 757 758 759 760 761
static void
wbcg_undo_redo_truncate (WorkbookControl *wbc, int n, gboolean is_undo)
{
	gtk_combo_stack_truncate (ur_stack (wbc, is_undo), n);
}

762 763 764 765 766 767 768 769 770 771 772 773
static void
wbcg_undo_redo_pop (WorkbookControl *wbc, gboolean is_undo)
{
	gtk_combo_stack_remove_top (ur_stack (wbc, is_undo), 1);
}

static void
wbcg_undo_redo_push (WorkbookControl *wbc, char const *text, gboolean is_undo)
{
	gtk_combo_stack_push_item (ur_stack (wbc, is_undo), text);
}

Almer S. Tigelaar's avatar
Almer S. Tigelaar committed
774
#ifndef ENABLE_BONOBO
775 776
static void
change_menu_state (GtkWidget *menu_item, gboolean state)
Almer S. Tigelaar's avatar
Almer S. Tigelaar committed
777 778 779
{
	g_return_if_fail (menu_item != NULL);

780
	gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), state);
Jody Goldberg's avatar
enable.  
Jody Goldberg committed
781
}
782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801

static void
change_menu_sensitivity (GtkWidget *menu_item, gboolean sensitive)
{
	g_return_if_fail (menu_item != NULL);

	gtk_widget_set_sensitive (menu_item, sensitive);
}

static void
change_menu_label (GtkWidget *menu_item, char const *prefix, char const *suffix)
{
	gchar    *text;
	GtkBin   *bin = GTK_BIN (menu_item);
	GtkLabel *label = GTK_LABEL (bin->child);
	gboolean  sensitive = TRUE;

	g_return_if_fail (label != NULL);

	if (prefix == NULL) {
802
		gtk_label_parse_uline (label, suffix);
803 804 805 806 807 808 809 810 811 812
		return;
	}

	if (suffix == NULL) {
		suffix = _("Nothing");
		sensitive = FALSE;
	}

	text = g_strdup_printf ("%s : %s", prefix, suffix);

813
	gtk_label_parse_uline (label, text);
814 815 816
	gtk_widget_set_sensitive (menu_item, sensitive);
	g_free (text);
}
Almer S. Tigelaar's avatar
Almer S. Tigelaar committed
817
#else
818 819
static void
change_menu_state (WorkbookControlGUI const *wbcg,
Jody Goldberg's avatar
enable.  
Jody Goldberg committed
820 821
		  char const *verb_path, gboolean state)
{
Almer S. Tigelaar's avatar
Almer S. Tigelaar committed
822 823
	CORBA_Environment  ev;

Jody Goldberg's avatar
enable.  
Jody Goldberg committed
824
	g_return_if_fail (IS_WORKBOOK_CONTROL_GUI (wbcg));
Almer S. Tigelaar's avatar
Almer S. Tigelaar committed
825 826 827

	CORBA_exception_init (&ev);
	bonobo_ui_component_set_prop (wbcg->uic, verb_path,
Jody Goldberg's avatar
delete.  
Jody Goldberg committed
828
				      "state", state ? "1" : "0", &ev);
Morten Welinder's avatar
Morten Welinder committed
829
	CORBA_exception_free (&ev);
Almer S. Tigelaar's avatar
Almer S. Tigelaar committed
830
}
Jody Goldberg's avatar
enable.  
Jody Goldberg committed
831

Almer S. Tigelaar's avatar
Almer S. Tigelaar committed
832
static void
Jody Goldberg's avatar
enable.  
Jody Goldberg committed
833 834 835
change_menu_sensitivity (WorkbookControlGUI const *wbcg,
			 char const *verb_path, gboolean sensitive)
{
836 837
	CORBA_Environment  ev;

Jody Goldberg's avatar
enable.  
Jody Goldberg committed
838
	g_return_if_fail (IS_WORKBOOK_CONTROL_GUI (wbcg));
839 840 841 842

	CORBA_exception_init (&ev);
	bonobo_ui_component_set_prop (wbcg->uic, verb_path,
				      "sensitive", sensitive ? "1" : "0", &ev);
Morten Welinder's avatar
Morten Welinder committed
843
	CORBA_exception_free (&ev);
Almer S. Tigelaar's avatar
Almer S. Tigelaar committed
844
}
845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860

static void
change_menu_label (WorkbookControlGUI const *wbcg,
		   char const *verb_path,
		   char const *prefix,
		   char const *suffix)
{
	gboolean  sensitive = TRUE;
	gchar    *text;
	CORBA_Environment  ev;

	g_return_if_fail (IS_WORKBOOK_CONTROL_GUI (wbcg));

	CORBA_exception_init (&ev);

	if (prefix == NULL) {
861
		bonobo_ui_component_set_prop (wbcg->uic, verb_path, "label",
862 863 864 865 866 867 868 869 870
					      suffix, &ev);
	} else {
		if (suffix == NULL) {
			suffix = _("Nothing");
			sensitive = FALSE;
		}

		text = g_strdup_printf ("%s : %s", prefix, suffix);

871
		bonobo_ui_component_set_prop (wbcg->uic, verb_path,
872 873 874 875 876 877 878
					      "label", text, &ev);
		bonobo_ui_component_set_prop (wbcg->uic, verb_path,
					      "sensitive", sensitive ? "1" : "0", &ev);
		g_free (text);
	}
	CORBA_exception_free (&ev);
}
Jody Goldberg's avatar
enable.  
Jody Goldberg committed
879
#endif
Almer S. Tigelaar's avatar
Almer S. Tigelaar committed
880

Almer S. Tigelaar's avatar
Almer S. Tigelaar committed
881
static void
882
wbcg_menu_state_update (WorkbookControl *wbc, Sheet const *sheet, int flags)
Almer S. Tigelaar's avatar
Almer S. Tigelaar committed
883 884
{
	WorkbookControlGUI *wbcg = (WorkbookControlGUI *)wbc;
Morten Welinder's avatar
Morten Welinder committed
885

Almer S. Tigelaar's avatar
Almer S. Tigelaar committed
886 887 888
	g_return_if_fail (wbcg != NULL);

#ifndef ENABLE_BONOBO
Morten Welinder's avatar
Morten Welinder committed
889
	if (MS_INSERT_COLS & flags)
Jody Goldberg's avatar
Jody Goldberg committed
890 891
		change_menu_sensitivity (wbcg->menu_item_insert_cols,
					 sheet->priv->enable_insert_cols);
892
	if (MS_INSERT_ROWS & flags)
Jody Goldberg's avatar
Jody Goldberg committed
893 894
		change_menu_sensitivity (wbcg->menu_item_insert_rows,
					 sheet->priv->enable_insert_rows);
895
	if (MS_INSERT_CELLS & flags)
Jody Goldberg's avatar
Jody Goldberg committed
896 897
		change_menu_sensitivity (wbcg->menu_item_insert_cells,
					 sheet->priv->enable_insert_cells);
898
	if (MS_SHOWHIDE_DETAIL & flags) {
899 900 901 902 903
		change_menu_sensitivity (wbcg->menu_item_show_detail,
					 sheet->priv->enable_showhide_detail);
		change_menu_sensitivity (wbcg->menu_item_hide_detail,
					 sheet->priv->enable_showhide_detail);
	}
904
	if (MS_PASTE_SPECIAL & flags)
905 906
		change_menu_sensitivity (wbcg->menu_item_paste_special,
					 sheet->priv->enable_paste_special);
907
	if (MS_PRINT_SETUP & flags)
908
		change_menu_sensitivity (wbcg->menu_item_print_setup,
909
					 !wbcg_edit_has_guru (wbcg));
910
	if (MS_SEARCH_REPLACE & flags)
911
		change_menu_sensitivity (wbcg->menu_item_search_replace,
912
					 !wbcg_edit_has_guru (wbcg));
913
	if (MS_DEFINE_NAME & flags)
914
		change_menu_sensitivity (wbcg->menu_item_define_name,
915
					 !wbcg_edit_has_guru (wbcg));
916
	if (MS_CONSOLIDATE & flags)
Almer S. Tigelaar's avatar
Almer S. Tigelaar committed
917 918
		change_menu_sensitivity (wbcg->menu_item_consolidate,
					 !wbcg_edit_has_guru (wbcg));
Almer S. Tigelaar's avatar
Almer S. Tigelaar committed
919
#else