workbook.c 19 KB
Newer Older
1 2 3 4 5 6 7
/*
 * workbook.c:  Workbook management (toplevel windows)
 *
 * Author:
 *    Miguel de Icaza (miguel@gnu.org).
 *
 */
8
#include <config.h>
Arturo Espinosa's avatar
Arturo Espinosa committed
9
#include <gnome.h>
10
#include <gdk/gdkkeysyms.h>
Arturo Espinosa's avatar
Arturo Espinosa committed
11
#include "gnumeric.h"
12
#include "gnumeric-util.h"
Arturo Espinosa's avatar
Arturo Espinosa committed
13
#include "gnumeric-sheet.h"
14
#include "dialogs.h"
15
#include "xml-io.h"
Arturo Espinosa's avatar
Arturo Espinosa committed
16
#include "pixmaps.h"
Arturo Espinosa's avatar
Arturo Espinosa committed
17

18 19 20
/* The locations within the main table in the workbook */
#define WB_EA_LINE   0
#define WB_EA_SHEETS 1
Arturo Espinosa's avatar
Arturo Espinosa committed
21
#define WB_EA_STATUS 2
22 23 24

#define WB_COLS      1

25
Workbook *current_workbook;
26

Arturo Espinosa's avatar
Arturo Espinosa committed
27
static void
28
new_cmd (void)
Arturo Espinosa's avatar
Arturo Espinosa committed
29
{
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
	Workbook *wb;
	
	wb = workbook_new_with_sheets (1);
	gtk_widget_show (wb->toplevel);
}

static void
open_cmd (void)
{
	char *fname = dialog_query_load_file ();
	Workbook *wb;
	
	if (!fname)
		return;
	wb = gnumericReadXmlWorkbook (fname);
	if (wb)
		gtk_widget_show (wb->toplevel);
Arturo Espinosa's avatar
Arturo Espinosa committed
47 48 49
}

static void
50
save_cmd (GtkWidget *widget, Workbook *wb)
Arturo Espinosa's avatar
Arturo Espinosa committed
51
{
52
	workbook_save (wb);
Arturo Espinosa's avatar
Arturo Espinosa committed
53 54 55
}

static void
56
save_as_cmd (GtkWidget *widget, Workbook *wb)
Arturo Espinosa's avatar
Arturo Espinosa committed
57
{
58
	workbook_save_as (wb);
Arturo Espinosa's avatar
Arturo Espinosa committed
59 60 61
}

static void
Arturo Espinosa's avatar
Arturo Espinosa committed
62
set_selection_halign (Workbook *wb, StyleHAlignFlags align)
Arturo Espinosa's avatar
Arturo Espinosa committed
63
{
Arturo Espinosa's avatar
Arturo Espinosa committed
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
	Sheet *sheet;
	GList *cells, *l;

	sheet = workbook_get_current_sheet (wb);
	cells = sheet_selection_to_list (sheet);

	for (l = cells; l; l = l->next){
		Cell *cell = l->data;
		
		cell_set_halign (cell, align);
	}
	g_list_free (cells);
}

static void
left_align_cmd (GtkWidget *widget, Workbook *wb)
{
	set_selection_halign (wb, HALIGN_LEFT);
Arturo Espinosa's avatar
Arturo Espinosa committed
82 83 84
}

static void
Arturo Espinosa's avatar
Arturo Espinosa committed
85
right_align_cmd (GtkWidget *widget, Workbook *wb)
Arturo Espinosa's avatar
Arturo Espinosa committed
86
{
Arturo Espinosa's avatar
Arturo Espinosa committed
87
	set_selection_halign (wb, HALIGN_RIGHT);
Arturo Espinosa's avatar
Arturo Espinosa committed
88 89 90
}

static void
Arturo Espinosa's avatar
Arturo Espinosa committed
91
center_cmd (GtkWidget *widget, Workbook *wb)
Arturo Espinosa's avatar
Arturo Espinosa committed
92
{
Arturo Espinosa's avatar
Arturo Espinosa committed
93
	set_selection_halign (wb, HALIGN_CENTER);
Arturo Espinosa's avatar
Arturo Espinosa committed
94 95
}

96 97 98 99 100 101 102 103 104
static void
create_line_cmd (GtkWidget *widget, Workbook *wb)
{
	Sheet *sheet;

	sheet = workbook_get_current_sheet (wb);
	sheet_set_mode_type (sheet, SHEET_MODE_CREATE_LINE);
}

105 106 107 108 109 110 111 112 113
static void
create_arrow_cmd (GtkWidget *widget, Workbook *wb)
{
	Sheet *sheet;

	sheet = workbook_get_current_sheet (wb);
	sheet_set_mode_type (sheet, SHEET_MODE_CREATE_ARROW);
}

114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
static void
create_rectangle_cmd (GtkWidget *widget, Workbook *wb)
{
	Sheet *sheet;

	sheet = workbook_get_current_sheet (wb);
	sheet_set_mode_type (sheet, SHEET_MODE_CREATE_BOX);
}

static void
create_ellipse_cmd (GtkWidget *widget, Workbook *wb)
{
	Sheet *sheet;

	sheet = workbook_get_current_sheet (wb);
	sheet_set_mode_type (sheet, SHEET_MODE_CREATE_OVAL);
}

Arturo Espinosa's avatar
Arturo Espinosa committed
132 133 134 135 136 137
static void
quit_cmd (void)
{
	gtk_main_quit ();
}

138 139 140 141 142 143
static void
paste_cmd (GtkWidget *widget, Workbook *wb)
{
	Sheet *sheet;

	sheet = workbook_get_current_sheet (wb);
Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
144
	sheet_selection_paste (sheet, sheet->cursor_col, sheet->cursor_row, PASTE_DEFAULT);
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
}

static void
copy_cmd (GtkWidget *widget, Workbook *wb)
{
	Sheet *sheet;

	sheet = workbook_get_current_sheet (wb);
	sheet_selection_copy (sheet);
}

static void
cut_cmd (GtkWidget *widget, Workbook *wb)
{
	Sheet *sheet;
	
	sheet = workbook_get_current_sheet (wb);
	sheet_selection_cut (sheet);
}

static void
paste_special_cmd (GtkWidget *widget, Workbook *wb)
{
168 169 170 171 172
	Sheet *sheet;
	int flags;

	sheet = workbook_get_current_sheet (wb);
	flags = dialog_paste_special ();
Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
173
	sheet_selection_paste (sheet, sheet->cursor_col, sheet->cursor_row, flags);
174
	
175 176
}

177 178 179 180 181 182
static void
goto_cell_cmd (GtkWidget *widget, Workbook *wb)
{
	dialog_goto_cell (wb);
}

Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
183 184 185 186 187 188 189 190 191 192 193 194
static void
insert_cells_cmd (GtkWidget *widget, Workbook *wb)
{
	Sheet *sheet;

	sheet = workbook_get_current_sheet (wb);
	dialog_insert_cells (sheet);
}

static void
insert_cols_cmd (GtkWidget *widget, Workbook *wb)
{
195 196 197 198 199 200 201 202 203 204 205
	SheetSelection *ss;
	Sheet *sheet;
	int cols;
	
	sheet = workbook_get_current_sheet (wb);
	if (!sheet_verify_selection_simple (sheet, _("Insert rows")))
		return;
	
	ss = sheet->selections->data;
	cols = ss->end_col - ss->start_col + 1;
	sheet_insert_col (sheet, ss->start_col, cols);
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
206 207 208 209 210
}

static void
insert_rows_cmd (GtkWidget *widget, Workbook *wb)
{
211 212 213 214 215 216 217 218 219 220 221
	SheetSelection *ss;
	Sheet *sheet;
	int rows;
	
	sheet = workbook_get_current_sheet (wb);
	if (!sheet_verify_selection_simple (sheet, _("Insert rows")))
		return;

	ss = sheet->selections->data;
	rows = ss->end_row - ss->start_row + 1;
	sheet_insert_row (sheet, ss->start_row, rows);
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
222 223
}

Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
static void
clear_all_cmd (GtkWidget *widget, Workbook *wb)
{
	Sheet *sheet;

	sheet = workbook_get_current_sheet (wb);
	sheet_selection_clear (sheet);
}

static void
clear_formats_cmd (GtkWidget *widget, Workbook *wb)
{
	Sheet *sheet;

	sheet = workbook_get_current_sheet (wb);
	sheet_selection_clear_formats (sheet);
}

static void
clear_content_cmd (GtkWidget *widget, Workbook *wb)
{
	Sheet *sheet;

	sheet = workbook_get_current_sheet (wb);
	sheet_selection_clear_content (sheet);
}

static void
zoom_cmd (GtkWidget *widget, Workbook *wb)
{
	Sheet *sheet;

	sheet = workbook_get_current_sheet (wb);
	dialog_zoom (sheet);
}

Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
260 261 262 263 264 265 266 267 268
static void
format_cells_cmd (GtkWidget *widget, Workbook *wb)
{
	Sheet *sheet;
	
	sheet = workbook_get_current_sheet (wb);
	dialog_cell_format (sheet);
}

Arturo Espinosa's avatar
Arturo Espinosa committed
269
static GnomeUIInfo workbook_menu_file [] = {
270 271 272 273
	{ GNOME_APP_UI_ITEM, N_("New"), NULL, new_cmd, NULL, NULL,
	  GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_NEW },
	{ GNOME_APP_UI_ITEM, N_("Open"), NULL, open_cmd, NULL, NULL,
	  GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_OPEN },
274 275
	{ GNOME_APP_UI_ITEM, N_("Save"), NULL, save_cmd, NULL, NULL,
	  GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_SAVE },
276 277
	{ GNOME_APP_UI_ITEM, N_("Save as..."), NULL, save_as_cmd, NULL, NULL,
	  GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_SAVE },
Arturo Espinosa's avatar
Arturo Espinosa committed
278 279 280 281 282
	{ GNOME_APP_UI_ITEM, N_("Exit"), NULL, quit_cmd, NULL, NULL,
	  GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_EXIT },
	GNOMEUIINFO_END
};

Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
283 284 285 286 287 288 289
static GnomeUIInfo workbook_menu_edit_clear [] = {
	{ GNOME_APP_UI_ITEM, N_("All"),     NULL, clear_all_cmd },
	{ GNOME_APP_UI_ITEM, N_("Formats"), NULL, clear_formats_cmd },
	{ GNOME_APP_UI_ITEM, N_("Content"), NULL, clear_content_cmd },
	GNOMEUIINFO_END
};

290 291
static GnomeUIInfo workbook_menu_edit [] = {
	{ GNOME_APP_UI_ITEM, N_("Cut"), NULL, cut_cmd, NULL, NULL,
292
	  GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_CUT, GDK_x, GDK_CONTROL_MASK },
293
	{ GNOME_APP_UI_ITEM, N_("Copy"), NULL, copy_cmd, NULL, NULL,
294
	  GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_COPY, GDK_c, GDK_CONTROL_MASK },
295
	{ GNOME_APP_UI_ITEM, N_("Paste"), NULL, paste_cmd, NULL, NULL,
296
	  GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PASTE, GDK_v, GDK_CONTROL_MASK },
297 298
	{ GNOME_APP_UI_ITEM, N_("Paste special"), NULL, paste_special_cmd, NULL, NULL,
	  GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PASTE },
299
	GNOMEUIINFO_SEPARATOR,
Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
300 301
	{ GNOME_APP_UI_SUBTREE, N_("Clear"), NULL, &workbook_menu_edit_clear },
	GNOMEUIINFO_SEPARATOR,
302 303
	{ GNOME_APP_UI_ITEM, N_("Goto cell.."), NULL, goto_cell_cmd, NULL, NULL,
	  0, 0, GDK_i, GDK_CONTROL_MASK },
304 305 306
	GNOMEUIINFO_END
};

Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
307 308 309 310 311
static GnomeUIInfo workbook_menu_view [] = {
	{ GNOME_APP_UI_ITEM, N_("Zoom..."), NULL, zoom_cmd },
	GNOMEUIINFO_END
};

Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
312 313 314 315 316 317 318 319 320
static GnomeUIInfo workbook_menu_insert [] = {
	{ GNOME_APP_UI_ITEM, N_("Cells..."), NULL, insert_cells_cmd },
	{ GNOME_APP_UI_ITEM, N_("Rows"),     NULL, insert_rows_cmd },
	{ GNOME_APP_UI_ITEM, N_("Columns"),  NULL, insert_cols_cmd },
	GNOMEUIINFO_SEPARATOR,
	GNOMEUIINFO_END
};


Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
321 322 323 324 325
static GnomeUIInfo workbook_menu_format [] = {
	{ GNOME_APP_UI_ITEM, N_("Cells.."), NULL, format_cells_cmd, NULL, NULL,
	  0, 0, GDK_1, GDK_CONTROL_MASK },
	GNOMEUIINFO_END
};
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
326

Arturo Espinosa's avatar
Arturo Espinosa committed
327
static GnomeUIInfo workbook_menu [] = {
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
328 329
	{ GNOME_APP_UI_SUBTREE, N_("File"),   NULL, &workbook_menu_file },
	{ GNOME_APP_UI_SUBTREE, N_("Edit"),   NULL, &workbook_menu_edit },
Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
330
	{ GNOME_APP_UI_SUBTREE, N_("View"),   NULL, &workbook_menu_view },
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
331
	{ GNOME_APP_UI_SUBTREE, N_("Insert"), NULL, &workbook_menu_insert },
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
332
	{ GNOME_APP_UI_SUBTREE, N_("Format"), NULL, &workbook_menu_format },
Arturo Espinosa's avatar
Arturo Espinosa committed
333 334 335
	GNOMEUIINFO_END
};

Arturo Espinosa's avatar
Arturo Espinosa committed
336 337 338
static GnomeUIInfo workbook_toolbar [] = {
	GNOMEUIINFO_ITEM_STOCK (N_("New"),
				N_("Create a new sheet"),
339
				new_cmd, GNOME_STOCK_PIXMAP_NEW),
Arturo Espinosa's avatar
Arturo Espinosa committed
340 341
	GNOMEUIINFO_ITEM_STOCK (N_("Open"),
				N_("Opens an existing workbook"),
342
				open_cmd, GNOME_STOCK_PIXMAP_OPEN),
Arturo Espinosa's avatar
Arturo Espinosa committed
343 344
	GNOMEUIINFO_ITEM_STOCK (N_("Save"),
				N_("Saves the workbook"),
345
				save_cmd, GNOME_STOCK_PIXMAP_SAVE),
Arturo Espinosa's avatar
Arturo Espinosa committed
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
	GNOMEUIINFO_SEPARATOR,
	GNOMEUIINFO_ITEM_STOCK (N_("Cut"),
				N_("Cuts the selection to the clipboard"),
				cut_cmd, GNOME_STOCK_PIXMAP_CUT),
	GNOMEUIINFO_ITEM_STOCK (N_("Copy"),
				N_("Copies the selection to the clipboard"),
				copy_cmd, GNOME_STOCK_PIXMAP_COPY),
	GNOMEUIINFO_ITEM_STOCK (N_("Paste"),
				N_("Pastes the clipboard"),
				paste_cmd, GNOME_STOCK_PIXMAP_PASTE),
	GNOMEUIINFO_SEPARATOR,
	GNOMEUIINFO_ITEM_DATA (N_("Left align"),
			       N_("Sets the cell alignment to the left"),
			       left_align_cmd, NULL, align_left),
	GNOMEUIINFO_ITEM_DATA (N_("Center"),
				N_("Centers the cell contents"),
				center_cmd, NULL, align_center),
	GNOMEUIINFO_ITEM_DATA (N_("Right align"),
				N_("Sets the cell alignment to the right"),
				right_align_cmd, NULL, align_right),
366
	GNOMEUIINFO_SEPARATOR,
367 368 369
	GNOMEUIINFO_ITEM_DATA (N_("Line"),
			       N_("Creates a line object"),
			       create_line_cmd, NULL, line_xpm),
370 371 372
	GNOMEUIINFO_ITEM_DATA (N_("Arrow"),
			       N_("Creates an arrow object"),
			       create_arrow_cmd, NULL, arrow_xpm),
373 374 375 376 377 378
	GNOMEUIINFO_ITEM_DATA (N_("Rectangle"),
			       N_("Creates a rectangle object"),
			       create_rectangle_cmd, NULL, rect_xpm),
	GNOMEUIINFO_ITEM_DATA (N_("Ellipse"),
			       N_("Creates an ellipse object"),
			       create_ellipse_cmd, NULL, oval_xpm),
379
	
Arturo Espinosa's avatar
Arturo Espinosa committed
380 381 382
	GNOMEUIINFO_END
};

383 384 385 386 387 388 389 390 391 392 393 394
static void
workbook_setup_sheets (Workbook *wb)
{
	wb->notebook = gtk_notebook_new ();
	gtk_notebook_set_tab_pos (GTK_NOTEBOOK (wb->notebook), GTK_POS_BOTTOM);

	gtk_table_attach (GTK_TABLE (wb->table), wb->notebook,
			  0, WB_COLS, WB_EA_SHEETS, WB_EA_SHEETS+1,
			  GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND,
			  0, 0);
}

395
Sheet *
Arturo Espinosa's avatar
Arturo Espinosa committed
396
workbook_get_current_sheet (Workbook *wb)
397 398 399
{
	GtkWidget *current_notebook;
	Sheet *sheet;
Arturo Espinosa's avatar
Arturo Espinosa committed
400 401

	g_return_val_if_fail (wb != NULL, NULL);
402 403 404
	
	current_notebook = GTK_NOTEBOOK (wb->notebook)->cur_page->child;
	sheet = gtk_object_get_data (GTK_OBJECT (current_notebook), "sheet");
Arturo Espinosa's avatar
Arturo Espinosa committed
405 406 407 408 409 410 411 412 413 414

	if (sheet == NULL)
		g_warning ("There is no current sheet in this workbook");
	
	return sheet;
}

Sheet *
workbook_focus_current_sheet (Workbook *wb)
{
Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
415
	SheetView *sheet_view;
Arturo Espinosa's avatar
Arturo Espinosa committed
416 417 418
	Sheet *sheet;

	g_return_val_if_fail (wb != NULL, NULL);
419
	
Arturo Espinosa's avatar
Arturo Espinosa committed
420
	sheet = workbook_get_current_sheet (wb);
Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
421
	sheet_view = SHEET_VIEW (sheet->sheet_views->data);
Arturo Espinosa's avatar
Arturo Espinosa committed
422
	
Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
423
	gtk_window_set_focus (GTK_WINDOW (wb->toplevel), sheet_view->sheet_view);
424 425 426 427 428 429
	return sheet;
}

static void
wb_input_finished (GtkEntry *entry, Workbook *wb)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
430 431
	Sheet *sheet;
	
432
	printf ("FOCUS!\n");
Arturo Espinosa's avatar
Arturo Espinosa committed
433 434
	sheet = workbook_get_current_sheet (wb);

Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
435
	sheet_set_current_value (sheet);
436 437 438
	workbook_focus_current_sheet (wb);
}

439 440 441 442 443 444 445 446 447 448 449 450
int
workbook_parse_and_jump (Workbook *wb, char *text)
{
	int col, row;

	col = row = 0;

	if (!parse_cell_name (text, &col, &row)){
		gnumeric_notice (_("You should introduce a valid cell name"));
		return FALSE;
	} else {
		Sheet *sheet = workbook_get_current_sheet (wb);
Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
451 452

		sheet_cursor_move (sheet, col, row);
453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474
		return TRUE;
	}
}

static void
wb_jump_to_cell (GtkEntry *entry, Workbook *wb)
{
	char *text = gtk_entry_get_text (entry);

	workbook_parse_and_jump (wb, text);
	workbook_focus_current_sheet (wb);
}

void
workbook_set_region_status (Workbook *wb, char *str)
{
	g_return_if_fail (wb != NULL);
	g_return_if_fail (str != NULL);
	
	gtk_entry_set_text (GTK_ENTRY (wb->ea_status), str);
}

475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506
static void
workbook_setup_edit_area (Workbook *wb)
{
	GtkWidget *ok_button, *cancel_button, *box, *box2;
	GtkWidget *pix;
	
	wb->ea_status = gtk_entry_new ();
	wb->ea_input  = gtk_entry_new ();
	ok_button     = gtk_button_new ();
	cancel_button = gtk_button_new ();
	box           = gtk_hbox_new (0, 0);
	box2          = gtk_hbox_new (0, 0);
	
	gtk_widget_set_usize (wb->ea_status, 100, 0);
	
	/* Ok */
	pix = gnome_stock_pixmap_widget_new (wb->toplevel, GNOME_STOCK_BUTTON_OK);
	gtk_container_add (GTK_CONTAINER (ok_button), pix);

	/* Cancel */
	pix = gnome_stock_pixmap_widget_new (wb->toplevel, GNOME_STOCK_BUTTON_CANCEL);
	gtk_container_add (GTK_CONTAINER (cancel_button), pix);

	gtk_box_pack_start (GTK_BOX (box2), wb->ea_status, 0, 0, 0);
	gtk_box_pack_start (GTK_BOX (box), ok_button, 0, 0, 0);
	gtk_box_pack_start (GTK_BOX (box), cancel_button, 0, 0, 0);
	gtk_box_pack_start (GTK_BOX (box2), box, 0, 0, 0);
	gtk_box_pack_end   (GTK_BOX (box2), wb->ea_input, 1, 1, 0);

	gtk_table_attach (GTK_TABLE (wb->table), box2,
			  0, 1, 0, 1,
			  GTK_FILL | GTK_EXPAND, 0, 0, 0);
507 508 509 510 511

	/* Do signal setup for the editing input line */
	gtk_signal_connect (GTK_OBJECT (wb->ea_input), "activate",
			    GTK_SIGNAL_FUNC(wb_input_finished),
			    wb);
Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
512
#if 0
513 514 515
	gtk_signal_connect (GTK_OBJECT (wb->ea_input), "key_press_event",
			    GTK_SIGNAL_FUNC(wb_edit_key_pressed),
			    wb);
Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
516 517
#endif
	
518 519 520 521
	/* Do signal setup for the status input line */
	gtk_signal_connect (GTK_OBJECT (wb->ea_status), "activate",
			    GTK_SIGNAL_FUNC (wb_jump_to_cell),
			    wb);
522 523
}

524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594

struct {
	char *displayed_name;
	char *function;
} quick_compute_routines [] = {
	{ N_("Sum"),   	       "SUM(SELECTION())" },
	{ N_("Min"),   	       "MIN(SELECTION())" },
	{ N_("Max"),   	       "MAX(SELECTION())" },
	{ N_("Average"),       "AVERAGE(SELECTION())" },
	{ N_("Count"),         "COUNT(SELECTION())" },
	{ NULL, NULL }
};

/*
 * Sets the expression that gets evaluated whenever the
 * selection in the sheet changes
 */
static char *
workbook_set_auto_expr (Workbook *wb, char *description, char *expression)
{
	char *error = NULL;
	
	if (wb->auto_expr){
		g_assert (wb->auto_expr->ref_count == 1);
		expr_tree_unref (wb->auto_expr);
		string_unref (wb->auto_expr_desc);
	}
	wb->auto_expr = expr_parse_string (expression, 0, 0, &error);
	wb->auto_expr_desc = string_get (description);

	return error;
}

static void
change_auto_expr (GtkWidget *item, Workbook *wb)
{
	char *expr, *name;

	expr = gtk_object_get_data (GTK_OBJECT (item), "expr");
	name = gtk_object_get_data (GTK_OBJECT (item), "name");
	workbook_set_auto_expr (wb, name, expr);
	sheet_update_auto_expr (workbook_get_current_sheet (wb));
}

static void
change_auto_expr_menu (GtkWidget *widget, GdkEventButton *event, Workbook *wb)
{
	static GtkWidget *menu;

	if (!menu){
		GtkWidget *item;
		int i;
		
		menu = gtk_menu_new ();

		for (i = 0; quick_compute_routines [i].displayed_name; i++){
			item = gtk_menu_item_new_with_label (
				_(quick_compute_routines [i].displayed_name));
			gtk_menu_append (GTK_MENU (menu), item);
			gtk_widget_show (item);
			gtk_signal_connect (GTK_OBJECT (item), "activate",
					    GTK_SIGNAL_FUNC(change_auto_expr), wb);
			gtk_object_set_data (GTK_OBJECT (item), "expr",
					     quick_compute_routines [i].function);
			gtk_object_set_data (GTK_OBJECT (item), "name",
					     quick_compute_routines [i].displayed_name);
		}
	}
	gtk_menu_popup (GTK_MENU (menu), NULL, NULL, 0, NULL, 1, event->time);
}

Arturo Espinosa's avatar
Arturo Espinosa committed
595 596 597 598 599 600 601 602 603 604 605 606 607
static void
workbook_setup_status_area (Workbook *wb)
{
	GtkWidget *canvas;
	GnomeCanvasGroup *root;
	GtkWidget *t;
	
	t = gtk_table_new (0, 0, 0);
	gtk_table_attach (GTK_TABLE (wb->table), t,
			  0, WB_COLS, WB_EA_STATUS, WB_EA_STATUS+1, GTK_FILL | GTK_EXPAND, 0, 0, 0);

	canvas = gnome_canvas_new ();
	gtk_widget_set_usize (canvas, 1, 1);
608 609

	/* The canvas that displays text */
Arturo Espinosa's avatar
Arturo Espinosa committed
610 611 612 613 614 615 616 617 618 619 620 621
	root = GNOME_CANVAS_GROUP (GNOME_CANVAS (canvas)->root);
	wb->auto_expr_label = GNOME_CANVAS_ITEM (gnome_canvas_item_new (
		root, gnome_canvas_text_get_type (),
		"text",   "x",
		"x",      (double) 0,
		"y",      (double) 10,	/* FIXME :-) */
		"font",   "fixed", /* FIXME :-) */
		"anchor", GTK_ANCHOR_W,
		"fill_color", "black",
		NULL));
	
	gtk_table_attach (GTK_TABLE (t), canvas, 1, 2, 0, 1,
622 623 624 625 626 627 628 629 630 631 632
			  GTK_FILL, GTK_FILL, 0, 0);
	/* The following is just a trick to get the canvas to "adjust" his
	 * size to the proper value (as we created it with 1,1 and
	 * GTK_FILL options for X and Y
	 */
	gtk_table_attach (GTK_TABLE (t), gtk_label_new ("WWWWWWWWW"), 1, 2, 0, 1,
			  GTK_FILL, GTK_FILL, 0, 0);
	gtk_signal_connect (GTK_OBJECT (canvas), "button_press_event",
			    GTK_SIGNAL_FUNC (change_auto_expr_menu), wb);
	
	gtk_table_attach (GTK_TABLE (t), gtk_label_new ("Info"), 0, 1, 0, 1,
Arturo Espinosa's avatar
Arturo Espinosa committed
633 634 635 636
			  GTK_FILL | GTK_EXPAND, 0, 0, 0);
	gtk_widget_show_all (t);
}

637 638
void
workbook_auto_expr_label_set (Workbook *wb, char *text)
Arturo Espinosa's avatar
Arturo Espinosa committed
639
{
640
	char *res;
Arturo Espinosa's avatar
Arturo Espinosa committed
641

642 643 644 645 646 647 648 649 650
	g_return_if_fail (wb != NULL);
	g_return_if_fail (text != NULL);
	
	res = g_copy_strings (wb->auto_expr_desc->str, "=",
			      text, NULL);
	gnome_canvas_item_set (wb->auto_expr_label,
			       "text", res,
			       NULL);
	g_free (res);
Arturo Espinosa's avatar
Arturo Espinosa committed
651 652
}

Arturo Espinosa's avatar
Arturo Espinosa committed
653 654 655 656 657 658 659 660 661 662 663
/*
 * Sets up the workbook.
 * Right now it is adding some decorations to the window,
 * this is for testing purposes.
 */
Workbook *
workbook_new (void)
{
	Workbook *wb;

	wb = g_new0 (Workbook, 1);
Arturo Espinosa's avatar
Arturo Espinosa committed
664 665 666
	wb->toplevel  = gnome_app_new ("Gnumeric", "Gnumeric");
	wb->sheets    = g_hash_table_new (g_str_hash, g_str_equal);
	wb->table     = gtk_table_new (0, 0, 0);
667

668 669
	wb->max_iterations = 1;
	
Arturo Espinosa's avatar
Arturo Espinosa committed
670
	workbook_setup_status_area (wb);
671 672 673
	workbook_setup_edit_area (wb);
	workbook_setup_sheets (wb);
	gnome_app_set_contents (GNOME_APP (wb->toplevel), wb->table);
674
	gnome_app_create_menus_with_data (GNOME_APP (wb->toplevel), workbook_menu, wb);
Arturo Espinosa's avatar
Arturo Espinosa committed
675 676 677
	gnome_app_create_toolbar_with_data (GNOME_APP (wb->toplevel), workbook_toolbar, wb);
	gtk_toolbar_set_style (GTK_TOOLBAR (GNOME_APP (wb->toplevel)->toolbar), GTK_TOOLBAR_ICONS);
	
Miguel de Icaza's avatar
Today:  
Miguel de Icaza committed
678 679
/*	gtk_accel_group_attach (GTK_OBJECT (wb->toplevel)); */
		
Arturo Espinosa's avatar
Arturo Espinosa committed
680
	/* Set the default operation to be performed over selections */
681
	workbook_set_auto_expr (wb, "SUM", "SUM(SELECTION())");
Arturo Espinosa's avatar
Arturo Espinosa committed
682

683
	gtk_widget_show_all (wb->table);
Arturo Espinosa's avatar
Arturo Espinosa committed
684 685 686
	return wb;
}

687 688 689
static void
zoom_in (GtkButton *b, Sheet *sheet)
{
Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
690
	double pix = sheet->last_zoom_factor_used;
691 692 693 694 695 696 697 698 699 700
	
	if (pix < 10.0){
		pix += 0.5;
		sheet_set_zoom_factor (sheet, pix);
	}
}

static void
zoom_out (GtkButton *b, Sheet *sheet)
{
Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
701
	double pix = sheet->last_zoom_factor_used;
702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727
	
	if (pix > 1.0){
		pix -= 0.5;
		sheet_set_zoom_factor (sheet, pix);
	}
}

static void
buttons (Sheet *sheet, GtkTable *table)
{
	GtkWidget *b;
	
	b = gtk_button_new_with_label ("Zoom out");
	gtk_table_attach (table, b,
			  0, 1, 1, 2, 0, 0, 0, 0);
	gtk_signal_connect (GTK_OBJECT (b), "clicked",
			    GTK_SIGNAL_FUNC (zoom_out), sheet);

	b = gtk_button_new_with_label ("Zoom in");
	gtk_table_attach (table, b,
			  1, 2, 1, 2, 0, 0, 0, 0);
	gtk_signal_connect (GTK_OBJECT (b), "clicked",
			    GTK_SIGNAL_FUNC (zoom_in), sheet);
	
}

Arturo Espinosa's avatar
Arturo Espinosa committed
728 729 730
void
workbook_attach_sheet (Workbook *wb, Sheet *sheet)
{
731 732
	GtkWidget *t;

Arturo Espinosa's avatar
Arturo Espinosa committed
733
	g_hash_table_insert (wb->sheets, sheet->name, sheet);
734 735

	t = gtk_table_new (0, 0, 0);
Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
736
	gtk_table_attach (GTK_TABLE (t), GTK_WIDGET (sheet->sheet_views->data),
737 738 739 740
			  0, 3, 0, 1,
			  GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0);
	buttons (sheet, GTK_TABLE (t));
	gtk_widget_show_all (t);
741
	gtk_object_set_data (GTK_OBJECT (t), "sheet", sheet);
Arturo Espinosa's avatar
Arturo Espinosa committed
742
	gtk_notebook_append_page (GTK_NOTEBOOK (wb->notebook),
743
				  t, gtk_label_new (sheet->name));
Arturo Espinosa's avatar
Arturo Espinosa committed
744 745 746 747 748 749
}

Workbook *
workbook_new_with_sheets (int sheet_count)
{
	Workbook *wb;
750
	Sheet *first_sheet = 0;
Arturo Espinosa's avatar
Arturo Espinosa committed
751 752 753 754 755 756 757 758 759 760 761
	int i;

	wb = workbook_new ();

	for (i = 0; i < sheet_count; i++){
		Sheet *sheet;
		char name [80];

		snprintf (name, sizeof (name), "Sheet %d", i);
		sheet = sheet_new (wb, name);
		workbook_attach_sheet (wb, sheet);
762 763 764

		if (!first_sheet)
			first_sheet = sheet;
Arturo Espinosa's avatar
Arturo Espinosa committed
765
	}
766

Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
767 768 769
	workbook_focus_current_sheet (wb);
#if 0
	focus = SHEET_VIEW (first_sheet->sheet_views->data)->sheet_view;
770
	gtk_window_set_focus (GTK_WINDOW (wb->toplevel), focus);
Arturo Espinosa's avatar
Today:  
Arturo Espinosa committed
771
#endif
Arturo Espinosa's avatar
Arturo Espinosa committed
772 773
	return wb;
}
774 775 776 777 778 779 780 781 782

/*
 * This routine sets up the default styles for the
 * workbook
 */
void
workbook_realized (Workbook *workbook, GdkWindow *window)
{
}
783