[gnumeric] Implement graph only sheets. [#158170]



commit 621aaac166e51107897ea0d0f9be4c25689062ad
Author: Jean Brefort <jean brefort normalesup org>
Date:   Wed Apr 21 17:00:29 2010 +0200

    Implement graph only sheets. [#158170]

 ChangeLog                          |   35 ++
 NEWS                               |    3 +
 src/commands.c                     |   16 +
 src/dialogs/ChangeLog              |    6 +
 src/dialogs/dialog-printer-setup.c |   18 +
 src/gnumeric.h                     |    6 +
 src/graph.h                        |    2 +-
 src/print.c                        |  101 ++++---
 src/sheet-control-gui.c            |  607 ++++++++++++++++++++----------------
 src/sheet-object-graph.c           |  112 ++++++-
 src/sheet-object-graph.h           |    1 +
 src/sheet-object.c                 |  190 +++++++++---
 src/sheet-object.h                 |    1 +
 src/sheet.c                        |    3 +
 src/sheet.h                        |    5 -
 src/wbc-gtk-actions.c              |   52 +++-
 src/wbc-gtk.c                      |   23 ++-
 src/workbook.c                     |   28 ++
 src/workbook.h                     |    1 +
 src/xml-sax-read.c                 |    8 +-
 src/xml-sax-write.c                |    2 +
 21 files changed, 814 insertions(+), 406 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index cc99285..ecd63c6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,38 @@
+2010-04-21  Jean Brefort  <jean brefort normalesup org>
+
+	reviewed by: <delete if not using a buddy>
+
+	* src/commands.c (update_sheet_graph_cb), (cmd_print_setup_undo),
+	(cmd_print_setup_redo):
+	* src/gnumeric.h:
+	* src/graph.h:
+	* src/print.c (print_page):
+	* src/sheet-control-gui.c (scg_resize), (scg_scrollbar_config),
+	(scg_set_top_left), (scg_make_cell_visible), (scg_set_panes),
+	(set_resize_pane_pos), (post_create_cb), (sheet_control_gui_new),
+	(scg_finalize), (scg_unant), (scg_ant), (scg_adjust_preferences),
+	(scg_object_create_view):
+	* src/sheet-object-graph.c (cb_graph_size_changed),
+	(cb_post_new_view), (gnm_sog_new_view), (gnm_sog_bounds_changed),
+	(cb_sheet_target_changed), (sheet_object_graph_guru),
+	(sheet_object_graph_ensure_size):
+	* src/sheet-object-graph.h:
+	* src/sheet-object.c (sheet_object_populate_menu_real),
+	(sheet_object_draw_cairo_sized), (sheet_object_view_enter_notify),
+	(cb_so_menu_activate), (cb_ptr_array_free), (build_so_menu),
+	(sheet_object_view_button_pressed):
+	* src/sheet-object.h:
+	* src/sheet.c (sheet_new_with_type):
+	* src/sheet.h:
+	* src/wbc-gtk-actions.c (cb_add_graph):
+	* src/wbc-gtk.c (wbcg_update_action_sensitivity),
+	(wbcg_set_direction), (cb_scroll_wheel), (wbcg_get_n_scg):
+	* src/workbook.c (workbook_sheet_add_with_type):
+	* src/workbook.h:
+	* src/xml-sax-read.c (xml_sax_wb_sheetsize),
+	(xml_sax_wb_sheetname):
+	* src/xml-sax-write.c (xml_write_sheet_names):
+
 2010-04-16  Morten Welinder <terra gnome org>
 
 	* configure.in: Post-release bump.
diff --git a/NEWS b/NEWS
index ecca0c9..99563de 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,9 @@ Gnumeric 1.10.3
 Andreas:
 	* Fix CHITEST for rectangular ranges. [#615920]
 
+Jean
+	* Implement graph only sheets. [#158170]
+
 --------------------------------------------------------------------------
 Gnumeric 1.10.2
 
diff --git a/src/commands.c b/src/commands.c
index 1e3bfac..7324bf1 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -5622,6 +5622,14 @@ typedef struct {
 
 MAKE_GNM_COMMAND (CmdPrintSetup, cmd_print_setup, NULL)
 
+static void
+update_sheet_graph_cb (Sheet *sheet)
+{
+	g_return_if_fail (IS_SHEET (sheet) && sheet->sheet_type == GNM_SHEET_OBJECT);
+
+	sheet_object_graph_ensure_size (SHEET_OBJECT (sheet->sheet_objects->data));
+}
+
 static gboolean
 cmd_print_setup_undo (GnmCommand *cmd, WorkbookControl *wbc)
 {
@@ -5636,6 +5644,8 @@ cmd_print_setup_undo (GnmCommand *cmd, WorkbookControl *wbc)
 		PrintInformation *pi = me->old_pi->data;
 		print_info_free (me->cmd.sheet->print_info);
 		me->cmd.sheet->print_info = print_info_dup (pi);
+		if (me->cmd.sheet->sheet_type == GNM_SHEET_OBJECT)
+			update_sheet_graph_cb (me->cmd.sheet);
 	} else {
 		book = wb_control_get_workbook(wbc);
 		n = workbook_sheet_count (book);
@@ -5650,6 +5660,8 @@ cmd_print_setup_undo (GnmCommand *cmd, WorkbookControl *wbc)
 
 			print_info_free (sheet->print_info);
 			sheet->print_info = print_info_dup (pi);
+			if (sheet->sheet_type == GNM_SHEET_OBJECT)
+				update_sheet_graph_cb (sheet);
 			infos = infos->next;
 		}
 	}
@@ -5670,6 +5682,8 @@ cmd_print_setup_redo (GnmCommand *cmd, WorkbookControl *wbc)
 		else
 			print_info_free (me->cmd.sheet->print_info);
 		me->cmd.sheet->print_info = print_info_dup (me->new_pi);
+		if (me->cmd.sheet->sheet_type == GNM_SHEET_OBJECT)
+			update_sheet_graph_cb (me->cmd.sheet);
 	} else {
 		book = wb_control_get_workbook(wbc);
 		n = workbook_sheet_count (book);
@@ -5681,6 +5695,8 @@ cmd_print_setup_redo (GnmCommand *cmd, WorkbookControl *wbc)
 			else
 				print_info_free (sheet->print_info);
 			sheet->print_info = print_info_dup (me->new_pi);
+			if (sheet->sheet_type == GNM_SHEET_OBJECT)
+				update_sheet_graph_cb (sheet);
 		}
 		if (save_pis)
 			me->old_pi = g_slist_reverse (me->old_pi);
diff --git a/src/dialogs/ChangeLog b/src/dialogs/ChangeLog
index e3ab68c..837adc1 100644
--- a/src/dialogs/ChangeLog
+++ b/src/dialogs/ChangeLog
@@ -1,3 +1,9 @@
+2010-04-21  Jean Brefort  <jean brefort normalesup org>
+
+	reviewed by: <delete if not using a buddy>
+
+	* dialog-printer-setup.c (cb_do_print_preview):
+
 2010-04-16  Morten Welinder <terra gnome org>
 
 	* Release 1.10.2
diff --git a/src/dialogs/dialog-printer-setup.c b/src/dialogs/dialog-printer-setup.c
index 3d672f5..028bdb8 100644
--- a/src/dialogs/dialog-printer-setup.c
+++ b/src/dialogs/dialog-printer-setup.c
@@ -35,6 +35,7 @@
 #include <print.h>
 #include <ranges.h>
 #include <sheet.h>
+#include <sheet-object-graph.h>
 #include <workbook.h>
 #include <wbc-gtk.h>
 #include <style.h>
@@ -2443,12 +2444,29 @@ static void
 cb_do_print_preview (PrinterSetupState *state)
 {
 	PrintInformation *old_pi;
+	double width, height;
+	GogGraph *graph = NULL;
 
 	fetch_settings (state);
 	old_pi = state->sheet->print_info;
 	state->sheet->print_info = state->pi;
+	if (state->sheet->sheet_type == GNM_SHEET_OBJECT) {
+		graph = GOG_GRAPH (sheet_object_graph_get_gog (SHEET_OBJECT (state->sheet->sheet_objects->data)));
+		if (graph) {
+			double top, bottom, left, right, edge_to_below_header, edge_to_above_footer, w, h;
+			gog_graph_get_size (graph, &width, &height);
+			w = print_info_get_paper_width (state->pi, GTK_UNIT_POINTS);
+			h = print_info_get_paper_height (state->pi, GTK_UNIT_POINTS);
+			print_info_get_margins (state->pi, &top, &bottom, &left, &right, &edge_to_below_header, &edge_to_above_footer);
+			w -= left + right;
+			h -= top + bottom + edge_to_above_footer + edge_to_below_header;
+			gog_graph_set_size (graph, w, h);
+		}
+	}
 	gnm_print_sheet (WORKBOOK_CONTROL (state->wbcg),
 		state->sheet, TRUE, PRINT_ACTIVE_SHEET, NULL);
+	if (graph)
+		gog_graph_set_size (graph, width, height);
 	state->sheet->print_info = old_pi;
 }
 
diff --git a/src/gnumeric.h b/src/gnumeric.h
index bd2de8d..9713e55 100644
--- a/src/gnumeric.h
+++ b/src/gnumeric.h
@@ -34,6 +34,12 @@ typedef enum {
 	GNM_SHEET_VISIBILITY_HIDDEN,
 	GNM_SHEET_VISIBILITY_VERY_HIDDEN
 } GnmSheetVisibility;
+typedef enum {
+	GNM_SHEET_DATA,
+	GNM_SHEET_OBJECT,
+	GNM_SHEET_XLM
+} GnmSheetType;
+
 typedef struct _Sheet			Sheet;
 typedef struct _SheetView		SheetView;
 typedef struct _SheetControl		SheetControl;
diff --git a/src/graph.h b/src/graph.h
index 6b7aef9..1aa7d36 100644
--- a/src/graph.h
+++ b/src/graph.h
@@ -42,7 +42,7 @@ GOData	*gnm_go_data_matrix_new_expr  (Sheet *sheet, GnmExprTop const *texpr);
 /* closure for data allocation */
 typedef struct {
 	int colrowmode; /* 0 = auto; 1 = columns; 2 = rows */
-	gboolean share_x;
+	gboolean share_x, new_sheet;
 	GObject *obj;
 	GogDataAllocator *dalloc;
 } GraphDataClosure;
diff --git a/src/print.c b/src/print.c
index 736c333..f90ca66 100644
--- a/src/print.c
+++ b/src/print.c
@@ -508,70 +508,77 @@ print_page (GtkPrintOperation *operation,
 	}
 	cairo_scale (cr, px, py);
 
+	if (sheet->sheet_type == GNM_SHEET_OBJECT) {
+		SheetObject *so = (SheetObject *) sheet->sheet_objects->data;
+		if (so)
+			sheet_object_draw_cairo_sized (so, cr, width, height);
+	} else {
+
 /* printing column and row headers */
 
-	if (sheet->print_info->print_titles) {
-		cairo_save (cr);
-		if (gsr->n_rep_cols > 0) {
-			print_page_col_headers (context, pi, cr, sheet,
-						&r_repeating_intersect,
+		if (sheet->print_info->print_titles) {
+			cairo_save (cr);
+			if (gsr->n_rep_cols > 0) {
+				print_page_col_headers (context, pi, cr, sheet,
+							&r_repeating_intersect,
+							row_header_width, col_header_height);
+				cairo_translate (cr, dir * rep_col_width, 0 );
+			}
+			print_page_col_headers (context, pi, cr, sheet, &gsr->range,
 						row_header_width, col_header_height);
-			cairo_translate (cr, dir * rep_col_width, 0 );
-		}
-		print_page_col_headers (context, pi, cr, sheet, &gsr->range,
-					row_header_width, col_header_height);
-		cairo_restore (cr);
-		cairo_save (cr);
-		if (gsr->n_rep_rows > 0) {
-			print_page_row_headers (context, pi, cr, sheet,
-						&r_repeating_intersect,
+			cairo_restore (cr);
+			cairo_save (cr);
+			if (gsr->n_rep_rows > 0) {
+				print_page_row_headers (context, pi, cr, sheet,
+							&r_repeating_intersect,
+							row_header_width, col_header_height);
+				cairo_translate (cr, 0, rep_row_height);
+			}
+			print_page_row_headers (context, pi, cr, sheet, &gsr->range,
 						row_header_width, col_header_height);
-			cairo_translate (cr, 0, rep_row_height);
+			cairo_restore (cr);
+			cairo_translate (cr, dir * row_header_width, col_header_height);
 		}
-		print_page_row_headers (context, pi, cr, sheet, &gsr->range,
-					row_header_width, col_header_height);
-		cairo_restore (cr);
-		cairo_translate (cr, dir * row_header_width, col_header_height);
-	}
 
 /* printing repeated row/col intersect */
 
-	if ((gsr->n_rep_rows > 0) && (gsr->n_rep_cols > 0)) {
-		print_page_cells (context, pi, cr, sheet,
-				  &r_repeating_intersect,
-				  dir * GNM_COL_MARGIN, -GNM_ROW_MARGIN);
-	}
+		if ((gsr->n_rep_rows > 0) && (gsr->n_rep_cols > 0)) {
+			print_page_cells (context, pi, cr, sheet,
+					  &r_repeating_intersect,
+					  dir * GNM_COL_MARGIN, -GNM_ROW_MARGIN);
+		}
 
 /* printing repeated rows  */
 
-	if (gsr->n_rep_rows > 0) {
-		GnmRange r;
-		range_init (&r, gsr->range.start.col, gsr->first_rep_rows,
-			    gsr->range.end.col, gsr->first_rep_rows + gsr->n_rep_rows - 1);
-		cairo_save (cr);
-		if (gsr->n_rep_cols > 0)
-			cairo_translate (cr, dir * rep_col_width, 0 );
-		print_page_cells (context, pi, cr, sheet, &r,
-				  dir * GNM_COL_MARGIN, -GNM_ROW_MARGIN);
-		cairo_restore (cr);
-		cairo_translate (cr, 0, rep_row_height );
-	}
+		if (gsr->n_rep_rows > 0) {
+			GnmRange r;
+			range_init (&r, gsr->range.start.col, gsr->first_rep_rows,
+				    gsr->range.end.col, gsr->first_rep_rows + gsr->n_rep_rows - 1);
+			cairo_save (cr);
+			if (gsr->n_rep_cols > 0)
+				cairo_translate (cr, dir * rep_col_width, 0 );
+			print_page_cells (context, pi, cr, sheet, &r,
+					  dir * GNM_COL_MARGIN, -GNM_ROW_MARGIN);
+			cairo_restore (cr);
+			cairo_translate (cr, 0, rep_row_height );
+		}
 
 /* printing repeated cols */
 
-	if (gsr->n_rep_cols > 0) {
-		GnmRange r;
-		range_init (&r, gsr->first_rep_cols, gsr->range.start.row,
-			    gsr->first_rep_cols + gsr->n_rep_cols - 1, gsr->range.end.row);
-		print_page_cells (context, pi, cr, sheet, &r,
-				  dir * GNM_COL_MARGIN, -GNM_ROW_MARGIN);
-		cairo_translate (cr, dir * rep_col_width, 0 );
-	}
+		if (gsr->n_rep_cols > 0) {
+			GnmRange r;
+			range_init (&r, gsr->first_rep_cols, gsr->range.start.row,
+				    gsr->first_rep_cols + gsr->n_rep_cols - 1, gsr->range.end.row);
+			print_page_cells (context, pi, cr, sheet, &r,
+					  dir * GNM_COL_MARGIN, -GNM_ROW_MARGIN);
+			cairo_translate (cr, dir * rep_col_width, 0 );
+		}
 
 /* printing page content  */
 
-	print_page_cells (context, pi, cr, sheet, &gsr->range,
-			  dir * GNM_COL_MARGIN, -GNM_ROW_MARGIN);
+		print_page_cells (context, pi, cr, sheet, &gsr->range,
+				  dir * GNM_COL_MARGIN, -GNM_ROW_MARGIN);
+	}
 
 	cairo_restore (cr);
 	return 1;
diff --git a/src/sheet-control-gui.c b/src/sheet-control-gui.c
index e38ef7f..6caf24a 100644
--- a/src/sheet-control-gui.c
+++ b/src/sheet-control-gui.c
@@ -308,80 +308,82 @@ scg_resize (SheetControlGUI *scg, gboolean force_scroll)
 	GnmPane *pane = scg_pane (scg, 0);
 	int h, w, btn_h, btn_w, tmp;
 
-	/* Recalibrate the starting offsets */
-	pane->first_offset.x = scg_colrow_distance_get (scg,
-		TRUE, 0, pane->first.col);
-	pane->first_offset.y = scg_colrow_distance_get (scg,
-		FALSE, 0, pane->first.row);
-
-	/* resize Pane[0] headers */
-	h = item_bar_calc_size (scg->pane[0]->col.item);
-	btn_h = h - item_bar_indent (scg->pane[0]->col.item);
-	w = item_bar_calc_size (scg->pane[0]->row.item);
-	btn_w = w - item_bar_indent (scg->pane[0]->row.item);
-	gtk_widget_set_size_request (scg->select_all_btn, btn_w, btn_h);
-	gtk_widget_set_size_request (GTK_WIDGET (scg->pane[0]->col.canvas), -1, h);
-	gtk_widget_set_size_request (GTK_WIDGET (scg->pane[0]->row.canvas), w, -1);
-
-	tmp = item_bar_group_size (scg->pane[0]->col.item,
-		sheet->cols.max_outline_level);
-	scg_setup_group_buttons (scg, sheet->cols.max_outline_level,
-		scg->pane[0]->col.item, TRUE,
-		tmp, tmp, scg->col_group.buttons, scg->col_group.button_box);
-	scg_setup_group_buttons (scg, sheet->rows.max_outline_level,
-		scg->pane[0]->row.item, FALSE,
-		-1, btn_h, scg->row_group.buttons, scg->row_group.button_box);
-
-	if (scg->active_panes != 1 && sv_is_frozen (scg_view (scg))) {
-		GnmCellPos const *tl = &scg_view (scg)->frozen_top_left;
-		GnmCellPos const *br = &scg_view (scg)->unfrozen_top_left;
-		int const l = scg_colrow_distance_get (scg, TRUE,
-			0, tl->col);
-		int const r = scg_colrow_distance_get (scg, TRUE,
-			tl->col, br->col) + l;
-		int const t = scg_colrow_distance_get (scg, FALSE,
-			0, tl->row);
-		int const b = scg_colrow_distance_get (scg, FALSE,
-			tl->row, br->row) + t;
-		int i;
+	if (pane) {
+		/* Recalibrate the starting offsets */
+		pane->first_offset.x = scg_colrow_distance_get (scg,
+			TRUE, 0, pane->first.col);
+		pane->first_offset.y = scg_colrow_distance_get (scg,
+			FALSE, 0, pane->first.row);
+
+		/* resize Pane[0] headers */
+		h = item_bar_calc_size (scg->pane[0]->col.item);
+		btn_h = h - item_bar_indent (scg->pane[0]->col.item);
+		w = item_bar_calc_size (scg->pane[0]->row.item);
+		btn_w = w - item_bar_indent (scg->pane[0]->row.item);
+		gtk_widget_set_size_request (scg->select_all_btn, btn_w, btn_h);
+		gtk_widget_set_size_request (GTK_WIDGET (scg->pane[0]->col.canvas), -1, h);
+		gtk_widget_set_size_request (GTK_WIDGET (scg->pane[0]->row.canvas), w, -1);
+
+		tmp = item_bar_group_size (scg->pane[0]->col.item,
+			sheet->cols.max_outline_level);
+		scg_setup_group_buttons (scg, sheet->cols.max_outline_level,
+			scg->pane[0]->col.item, TRUE,
+			tmp, tmp, scg->col_group.buttons, scg->col_group.button_box);
+		scg_setup_group_buttons (scg, sheet->rows.max_outline_level,
+			scg->pane[0]->row.item, FALSE,
+			-1, btn_h, scg->row_group.buttons, scg->row_group.button_box);
+
+		if (scg->active_panes != 1 && sv_is_frozen (scg_view (scg))) {
+			GnmCellPos const *tl = &scg_view (scg)->frozen_top_left;
+			GnmCellPos const *br = &scg_view (scg)->unfrozen_top_left;
+			int const l = scg_colrow_distance_get (scg, TRUE,
+				0, tl->col);
+			int const r = scg_colrow_distance_get (scg, TRUE,
+				tl->col, br->col) + l;
+			int const t = scg_colrow_distance_get (scg, FALSE,
+				0, tl->row);
+			int const b = scg_colrow_distance_get (scg, FALSE,
+				tl->row, br->row) + t;
+			int i;
+
+			/* pane 0 has already been done */
+			for (i = scg->active_panes; i-- > 1 ; ) {
+				GnmPane *pane = scg->pane[i];
+				if (NULL != pane) {
+					pane->first_offset.x = scg_colrow_distance_get (
+						scg, TRUE, 0, pane->first.col);
+					pane->first_offset.y = scg_colrow_distance_get (
+						scg, FALSE, 0, pane->first.row);
+				}
+			}
 
-		/* pane 0 has already been done */
-		for (i = scg->active_panes; i-- > 1 ; ) {
-			GnmPane *pane = scg->pane[i];
-			if (NULL != pane) {
-				pane->first_offset.x = scg_colrow_distance_get (
-					scg, TRUE, 0, pane->first.col);
-				pane->first_offset.y = scg_colrow_distance_get (
-					scg, FALSE, 0, pane->first.row);
+			if (scg->pane[1]) {
+				gtk_widget_set_size_request (GTK_WIDGET (scg->pane[1]), r - l, -1);
+				/* The item_bar_calcs should be equal */
+				/* FIXME : The canvas gets confused when the initial scroll
+				 * region is set too early in its life cycle.
+				 * It likes it to be at the origin, we can live with that for now.
+				 * However, we really should track the bug eventually.
+				 */
+				h = item_bar_calc_size (scg->pane[1]->col.item);
+				gtk_widget_set_size_request (GTK_WIDGET (scg->pane[1]->col.canvas), r - l, h);
 			}
-		}
 
-		if (scg->pane[1]) {
-			gtk_widget_set_size_request (GTK_WIDGET (scg->pane[1]), r - l, -1);
-			/* The item_bar_calcs should be equal */
-			/* FIXME : The canvas gets confused when the initial scroll
-			 * region is set too early in its life cycle.
-			 * It likes it to be at the origin, we can live with that for now.
-			 * However, we really should track the bug eventually.
-			 */
-			h = item_bar_calc_size (scg->pane[1]->col.item);
-			gtk_widget_set_size_request (GTK_WIDGET (scg->pane[1]->col.canvas), r - l, h);
-		}
+			if (scg->pane[3]) {
+				gtk_widget_set_size_request (GTK_WIDGET (scg->pane[3]), -1,    b - t);
+				/* The item_bar_calcs should be equal */
+				w = item_bar_calc_size (scg->pane[3]->row.item);
+				gtk_widget_set_size_request (GTK_WIDGET (scg->pane[3]->row.canvas), w, b - t);
+			}
 
-		if (scg->pane[3]) {
-			gtk_widget_set_size_request (GTK_WIDGET (scg->pane[3]), -1,    b - t);
-			/* The item_bar_calcs should be equal */
-			w = item_bar_calc_size (scg->pane[3]->row.item);
-			gtk_widget_set_size_request (GTK_WIDGET (scg->pane[3]->row.canvas), w, b - t);
+			if (scg->pane[2])
+				gtk_widget_set_size_request (GTK_WIDGET (scg->pane[2]), r - l, b - t);
 		}
 
-		if (scg->pane[2])
-			gtk_widget_set_size_request (GTK_WIDGET (scg->pane[2]), r - l, b - t);
+		SCG_FOREACH_PANE (scg, pane, {
+			gnm_pane_reposition_cursors (pane);
+		});
 	}
-
-	SCG_FOREACH_PANE (scg, pane, {
-		gnm_pane_reposition_cursors (pane);
-	});
 }
 
 static void
@@ -416,39 +418,42 @@ scg_scrollbar_config (SheetControl const *sc)
 	GnmPane *pane = scg_pane (scg, 0);
 	SheetView const *sv = sc->view;
 	Sheet const *sheet = sv->sheet;
-	int const last_col = pane->last_full.col;
-	int const last_row = pane->last_full.row;
-	int max_col = last_col;
-	int max_row = last_row;
 
-	if (sv_is_frozen (sv)) {
-		ha->lower = sv->unfrozen_top_left.col;
-		va->lower = sv->unfrozen_top_left.row;
-	} else
-		ha->lower = va->lower = 0;
-
-	if (max_row < sheet->rows.max_used)
-		max_row = sheet->rows.max_used;
-	if (max_row < sheet->max_object_extent.row)
-		max_row = sheet->max_object_extent.row;
-	va->upper = max_row + 1;
-	va->value = pane->first.row;
-	va->page_size = last_row - pane->first.row + 1;
-	va->page_increment = MAX (va->page_size - 3.0, 1.0);
-	va->step_increment = 1;
-
-	if (max_col < sheet->cols.max_used)
-		max_col = sheet->cols.max_used;
-	if (max_col < sheet->max_object_extent.col)
-		max_col = sheet->max_object_extent.col;
-	ha->upper = max_col + 1;
-	ha->page_size = last_col - pane->first.col + 1;
-	ha->value = pane->first.col;
-	ha->page_increment = MAX (ha->page_size - 3.0, 1.0);
-	ha->step_increment = 1;
-
-	gtk_adjustment_changed (va);
-	gtk_adjustment_changed (ha);
+	if (pane) {
+		int const last_col = pane->last_full.col;
+		int const last_row = pane->last_full.row;
+		int max_col = last_col;
+		int max_row = last_row;
+
+		if (sv_is_frozen (sv)) {
+			ha->lower = sv->unfrozen_top_left.col;
+			va->lower = sv->unfrozen_top_left.row;
+		} else
+			ha->lower = va->lower = 0;
+
+		if (max_row < sheet->rows.max_used)
+			max_row = sheet->rows.max_used;
+		if (max_row < sheet->max_object_extent.row)
+			max_row = sheet->max_object_extent.row;
+		va->upper = max_row + 1;
+		va->value = pane->first.row;
+		va->page_size = last_row - pane->first.row + 1;
+		va->page_increment = MAX (va->page_size - 3.0, 1.0);
+		va->step_increment = 1;
+
+		if (max_col < sheet->cols.max_used)
+			max_col = sheet->cols.max_used;
+		if (max_col < sheet->max_object_extent.col)
+			max_col = sheet->max_object_extent.col;
+		ha->upper = max_col + 1;
+		ha->page_size = last_col - pane->first.col + 1;
+		ha->value = pane->first.col;
+		ha->page_increment = MAX (ha->page_size - 3.0, 1.0);
+		ha->step_increment = 1;
+
+		gtk_adjustment_changed (va);
+		gtk_adjustment_changed (ha);
+	}
 }
 
 void
@@ -853,6 +858,8 @@ scg_set_top_left (SheetControl *sc, int col, int row)
 
 	g_return_if_fail (IS_SHEET_CONTROL_GUI (scg));
 
+	if (!scg->pane[0])
+		return;
 	/* We could be faster if necessary */
 	scg_set_left_col (scg, col);
 	scg_set_top_row (scg, row);
@@ -956,6 +963,9 @@ scg_make_cell_visible (SheetControlGUI *scg, int col, int row,
 
 	g_return_if_fail (IS_SHEET_CONTROL_GUI (scg));
 
+	if (!scg->active_panes)
+		return;
+
 	tl = &sv->frozen_top_left;
 	br = &sv->unfrozen_top_left;
 	if (col < br->col) {
@@ -1033,6 +1043,8 @@ scg_set_panes (SheetControl *sc)
 
 	g_return_if_fail (IS_SHEET_VIEW (sv));
 
+	if (!scg->pane[0])
+		return;
 	if (being_frozen) {
 		GnmCellPos const *tl = &sv->frozen_top_left;
 		GnmCellPos const *br = &sv->unfrozen_top_left;
@@ -1237,6 +1249,9 @@ set_resize_pane_pos (SheetControlGUI *scg, GtkPaned *p)
 {
 	int handle_size, pane_pos, size;
 
+	if (!scg->pane[0])
+		return;
+
 	if (p == scg->vpane) {
 		gtk_widget_get_size_request (
 			GTK_WIDGET (scg->pane[0]->col.canvas), NULL, &pane_pos);
@@ -1365,6 +1380,15 @@ cb_check_resize (GtkPaned *p, GtkAllocation *allocation,
 	}
 }
 
+static gboolean
+post_create_cb (SheetControlGUI *scg)
+{
+	Sheet *sheet = sc_sheet (SHEET_CONTROL (scg));
+	if (sheet->sheet_objects)
+		scg_object_select (scg, (SheetObject *) sheet->sheet_objects->data);
+	return FALSE;
+}
+
 SheetControlGUI *
 sheet_control_gui_new (SheetView *sv, WBCGtk *wbcg)
 {
@@ -1387,154 +1411,182 @@ sheet_control_gui_new (SheetView *sv, WBCGtk *wbcg)
 		(GWeakNotify) cb_wbc_destroyed,
 		scg);
 
-	scg->active_panes = 1;
-	scg->pane[0] = NULL;
-	scg->pane[1] = NULL;
-	scg->pane[2] = NULL;
-	scg->pane[3] = NULL;
-	scg->pane_drag_handler = 0;
-
-	scg->col_group.buttons = g_ptr_array_new ();
-	scg->row_group.buttons = g_ptr_array_new ();
-	scg->col_group.button_box = gtk_vbox_new (TRUE, 0);
-	scg->row_group.button_box = gtk_hbox_new (TRUE, 0);
-	scg->select_all_btn = gtk_drawing_area_new ();
-	gtk_widget_add_events (scg->select_all_btn, GDK_BUTTON_PRESS_MASK);
-	g_signal_connect (G_OBJECT (scg->select_all_btn), "expose-event",
-			  G_CALLBACK (cb_select_all_btn_expose), scg);
-	g_signal_connect (G_OBJECT (scg->select_all_btn), "event",
-			  G_CALLBACK (cb_select_all_btn_event), scg);
-
-	scg->corner	 = GTK_TABLE (gtk_table_new (2, 2, FALSE));
-	gtk_table_attach (scg->corner, scg->col_group.button_box,
-		1, 2, 0, 1,
-		GTK_SHRINK,
-		GTK_EXPAND | GTK_FILL | GTK_SHRINK,
-		0, 0);
-	gtk_table_attach (scg->corner, scg->row_group.button_box,
-		0, 1, 1, 2,
-		GTK_EXPAND | GTK_FILL | GTK_SHRINK,
-		GTK_SHRINK,
-		0, 0);
-	gtk_table_attach (scg->corner, scg->select_all_btn,
-		1, 2, 1, 2,
-		0,
-		0,
-		0, 0);
-
-	scg->pane[1] = scg->pane[2] = scg->pane[3] = NULL;
-	scg->pane[0] = gnm_pane_new (scg, TRUE, TRUE, 0);
-	gnm_pane_set_direction (scg->pane[0], direction);
-	scg->inner_table = GTK_TABLE (gtk_table_new (3, 3, FALSE));
-	gtk_table_attach (scg->inner_table, GTK_WIDGET (scg->corner),
-		0, 1, 0, 1,
-		GTK_FILL,
-		GTK_FILL,
-		0, 0);
-	gtk_table_attach (scg->inner_table, GTK_WIDGET (scg->pane[0]->col.alignment),
-		2, 3, 0, 1,
-		GTK_EXPAND | GTK_FILL | GTK_SHRINK,
-		GTK_FILL,
-		0, 0);
-	gtk_table_attach (scg->inner_table, GTK_WIDGET (scg->pane[0]->row.alignment),
-		0, 1, 2, 3,
-		GTK_FILL,
-		GTK_EXPAND | GTK_FILL | GTK_SHRINK,
-		0, 0);
-	gtk_table_attach (scg->inner_table, GTK_WIDGET (scg->pane[0]),
-		2, 3, 2, 3,
-		GTK_EXPAND | GTK_FILL | GTK_SHRINK,
-		GTK_EXPAND | GTK_FILL | GTK_SHRINK,
-		0, 0);
-	gtk_widget_show_all (GTK_WIDGET (scg->inner_table));
-
-	/* Scroll bars and their adjustments */
-	scroll_update_policy = gnm_conf_get_core_gui_editing_livescrolling ()
-		? GTK_UPDATE_CONTINUOUS : GTK_UPDATE_DELAYED;
-	scg->va = (GtkAdjustment *)gtk_adjustment_new (0., 0., 1, 1., 1., 1.);
-	scg->vs = g_object_new (GTK_TYPE_VSCROLLBAR,
-			"adjustment",	 scg->va,
-			"update-policy", scroll_update_policy,
-			NULL);
-	g_signal_connect (G_OBJECT (scg->vs),
-		"value_changed",
-		G_CALLBACK (cb_vscrollbar_value_changed), scg);
-	g_signal_connect (G_OBJECT (scg->vs),
-		"adjust_bounds",
-		G_CALLBACK (cb_vscrollbar_adjust_bounds), sheet);
-
-	scg->ha = (GtkAdjustment *)gtk_adjustment_new (0., 0., 1, 1., 1., 1.);
-	scg->hs = g_object_new (GTK_TYPE_HSCROLLBAR,
-			"adjustment", scg->ha,
-			"update-policy", scroll_update_policy,
-			NULL);
-	g_signal_connect (G_OBJECT (scg->hs),
-		"value_changed",
-		G_CALLBACK (cb_hscrollbar_value_changed), scg);
-	g_signal_connect (G_OBJECT (scg->hs),
-		"adjust_bounds",
-		G_CALLBACK (cb_hscrollbar_adjust_bounds), sheet);
-
-	scg->table = GTK_TABLE (gtk_table_new (4, 4, FALSE));
-	g_object_ref (scg->table);
-	gtk_table_attach (scg->table, GTK_WIDGET (scg->inner_table),
-		0, 1, 0, 1,
-		GTK_EXPAND | GTK_FILL | GTK_SHRINK,
-		GTK_EXPAND | GTK_FILL | GTK_SHRINK,
-		0, 0);
-	scg->vpane = g_object_new (GTK_TYPE_VPANED, NULL);
-	gtk_paned_add1 (scg->vpane, gtk_label_new (NULL)); /* use a spacer */
-	gtk_paned_add2 (scg->vpane, scg->vs);
-	scg_gtk_paned_set_position (scg, scg->vpane, 0);
-	gtk_table_attach (scg->table, GTK_WIDGET (scg->vpane),
-		1, 2, 0, 1,
-		GTK_FILL,
-		GTK_EXPAND | GTK_FILL | GTK_SHRINK,
-		0, 0);
-	scg->hpane = g_object_new (GTK_TYPE_HPANED, NULL);
-	gtk_paned_add1 (scg->hpane, gtk_label_new (NULL)); /* use a spacer */
-	gtk_paned_add2 (scg->hpane, scg->hs);
-	scg_gtk_paned_set_position (scg, scg->hpane, 0);
-	gtk_table_attach (scg->table, GTK_WIDGET (scg->hpane),
-		0, 1, 1, 2,
-		GTK_EXPAND | GTK_FILL | GTK_SHRINK,
-		GTK_FILL,
-		0, 0);
-	/* do not connect until after setting position */
-	g_signal_connect (G_OBJECT (scg->vpane), "notify::position",
-		G_CALLBACK (cb_resize_pane_motion), scg);
-	g_signal_connect (G_OBJECT (scg->hpane), "notify::position",
-		G_CALLBACK (cb_resize_pane_motion), scg);
-	g_signal_connect_after (G_OBJECT (scg->vpane), "size-allocate",
-		G_CALLBACK (cb_check_resize), scg);
-	g_signal_connect_after (G_OBJECT (scg->hpane), "size-allocate",
-		G_CALLBACK (cb_check_resize), scg);
-
-	g_signal_connect_data (G_OBJECT (scg->table),
-		"size-allocate",
-		G_CALLBACK (scg_scrollbar_config), scg, NULL,
-		G_CONNECT_AFTER | G_CONNECT_SWAPPED);
-	g_signal_connect_object (G_OBJECT (scg->table),
-		"destroy",
-		G_CALLBACK (cb_table_destroy), G_OBJECT (scg),
-		G_CONNECT_SWAPPED);
-
-	sv_attach_control (sv, SHEET_CONTROL (scg));
-
-	g_object_connect (G_OBJECT (sheet),
-		 "swapped_signal::notify::text-is-rtl", cb_scg_direction_changed, scg,
-		 "swapped_signal::notify::display-formulas", cb_scg_redraw, scg,
-		 "swapped_signal::notify::display-zeros", cb_scg_redraw, scg,
-		 "swapped_signal::notify::display-grid", cb_scg_redraw, scg,
-		 "swapped_signal::notify::display-column-header", scg_adjust_preferences, scg,
-		 "swapped_signal::notify::display-row-header", scg_adjust_preferences, scg,
-		 "swapped_signal::notify::use-r1c1", cb_scg_redraw, scg,
-		 "swapped_signal::notify::display-outlines", cb_scg_redraw_resize, scg,
-		 "swapped_signal::notify::display-outlines-below", cb_scg_redraw_resize, scg,
-		 "swapped_signal::notify::display-outlines-right", cb_scg_redraw_resize, scg,
-		 "swapped_signal::notify::columns", cb_scg_sheet_resized, scg,
-		 "swapped_signal::notify::rows", cb_scg_sheet_resized, scg,
-		 NULL);
+	if (sheet->sheet_type == GNM_SHEET_DATA) {
+		scg->active_panes = 1;
+		scg->pane[0] = NULL;
+		scg->pane[1] = NULL;
+		scg->pane[2] = NULL;
+		scg->pane[3] = NULL;
+		scg->pane_drag_handler = 0;
+
+		scg->col_group.buttons = g_ptr_array_new ();
+		scg->row_group.buttons = g_ptr_array_new ();
+		scg->col_group.button_box = gtk_vbox_new (TRUE, 0);
+		scg->row_group.button_box = gtk_hbox_new (TRUE, 0);
+		scg->select_all_btn = gtk_drawing_area_new ();
+		gtk_widget_add_events (scg->select_all_btn, GDK_BUTTON_PRESS_MASK);
+		g_signal_connect (G_OBJECT (scg->select_all_btn), "expose-event",
+				  G_CALLBACK (cb_select_all_btn_expose), scg);
+		g_signal_connect (G_OBJECT (scg->select_all_btn), "event",
+				  G_CALLBACK (cb_select_all_btn_event), scg);
+
+		scg->corner	 = GTK_TABLE (gtk_table_new (2, 2, FALSE));
+		gtk_table_attach (scg->corner, scg->col_group.button_box,
+			1, 2, 0, 1,
+			GTK_SHRINK,
+			GTK_EXPAND | GTK_FILL | GTK_SHRINK,
+			0, 0);
+		gtk_table_attach (scg->corner, scg->row_group.button_box,
+			0, 1, 1, 2,
+			GTK_EXPAND | GTK_FILL | GTK_SHRINK,
+			GTK_SHRINK,
+			0, 0);
+		gtk_table_attach (scg->corner, scg->select_all_btn,
+			1, 2, 1, 2,
+			0,
+			0,
+			0, 0);
+
+		scg->pane[1] = scg->pane[2] = scg->pane[3] = NULL;
+		scg->pane[0] = gnm_pane_new (scg, TRUE, TRUE, 0);
+		gnm_pane_set_direction (scg->pane[0], direction);
+		scg->inner_table = GTK_TABLE (gtk_table_new (3, 3, FALSE));
+		gtk_table_attach (scg->inner_table, GTK_WIDGET (scg->corner),
+			0, 1, 0, 1,
+			GTK_FILL,
+			GTK_FILL,
+			0, 0);
+		gtk_table_attach (scg->inner_table, GTK_WIDGET (scg->pane[0]->col.alignment),
+			2, 3, 0, 1,
+			GTK_EXPAND | GTK_FILL | GTK_SHRINK,
+			GTK_FILL,
+			0, 0);
+		gtk_table_attach (scg->inner_table, GTK_WIDGET (scg->pane[0]->row.alignment),
+			0, 1, 2, 3,
+			GTK_FILL,
+			GTK_EXPAND | GTK_FILL | GTK_SHRINK,
+			0, 0);
+		gtk_table_attach (scg->inner_table, GTK_WIDGET (scg->pane[0]),
+			2, 3, 2, 3,
+			GTK_EXPAND | GTK_FILL | GTK_SHRINK,
+			GTK_EXPAND | GTK_FILL | GTK_SHRINK,
+			0, 0);
+		gtk_widget_show_all (GTK_WIDGET (scg->inner_table));
+
+		/* Scroll bars and their adjustments */
+		scroll_update_policy = gnm_conf_get_core_gui_editing_livescrolling ()
+			? GTK_UPDATE_CONTINUOUS : GTK_UPDATE_DELAYED;
+		scg->va = (GtkAdjustment *)gtk_adjustment_new (0., 0., 1, 1., 1., 1.);
+		scg->vs = g_object_new (GTK_TYPE_VSCROLLBAR,
+				"adjustment",	 scg->va,
+				"update-policy", scroll_update_policy,
+				NULL);
+		g_signal_connect (G_OBJECT (scg->vs),
+			"value_changed",
+			G_CALLBACK (cb_vscrollbar_value_changed), scg);
+		g_signal_connect (G_OBJECT (scg->vs),
+			"adjust_bounds",
+			G_CALLBACK (cb_vscrollbar_adjust_bounds), sheet);
+
+		scg->ha = (GtkAdjustment *)gtk_adjustment_new (0., 0., 1, 1., 1., 1.);
+		scg->hs = g_object_new (GTK_TYPE_HSCROLLBAR,
+				"adjustment", scg->ha,
+				"update-policy", scroll_update_policy,
+				NULL);
+		g_signal_connect (G_OBJECT (scg->hs),
+			"value_changed",
+			G_CALLBACK (cb_hscrollbar_value_changed), scg);
+		g_signal_connect (G_OBJECT (scg->hs),
+			"adjust_bounds",
+			G_CALLBACK (cb_hscrollbar_adjust_bounds), sheet);
+
+		scg->table = GTK_TABLE (gtk_table_new (4, 4, FALSE));
+		g_object_ref (scg->table);
+		gtk_table_attach (scg->table, GTK_WIDGET (scg->inner_table),
+			0, 1, 0, 1,
+			GTK_EXPAND | GTK_FILL | GTK_SHRINK,
+			GTK_EXPAND | GTK_FILL | GTK_SHRINK,
+			0, 0);
+		scg->vpane = g_object_new (GTK_TYPE_VPANED, NULL);
+		gtk_paned_add1 (scg->vpane, gtk_label_new (NULL)); /* use a spacer */
+		gtk_paned_add2 (scg->vpane, scg->vs);
+		scg_gtk_paned_set_position (scg, scg->vpane, 0);
+		gtk_table_attach (scg->table, GTK_WIDGET (scg->vpane),
+			1, 2, 0, 1,
+			GTK_FILL,
+			GTK_EXPAND | GTK_FILL | GTK_SHRINK,
+			0, 0);
+		scg->hpane = g_object_new (GTK_TYPE_HPANED, NULL);
+		gtk_paned_add1 (scg->hpane, gtk_label_new (NULL)); /* use a spacer */
+		gtk_paned_add2 (scg->hpane, scg->hs);
+		scg_gtk_paned_set_position (scg, scg->hpane, 0);
+		gtk_table_attach (scg->table, GTK_WIDGET (scg->hpane),
+			0, 1, 1, 2,
+			GTK_EXPAND | GTK_FILL | GTK_SHRINK,
+			GTK_FILL,
+			0, 0);
+		/* do not connect until after setting position */
+		g_signal_connect (G_OBJECT (scg->vpane), "notify::position",
+			G_CALLBACK (cb_resize_pane_motion), scg);
+		g_signal_connect (G_OBJECT (scg->hpane), "notify::position",
+			G_CALLBACK (cb_resize_pane_motion), scg);
+		g_signal_connect_after (G_OBJECT (scg->vpane), "size-allocate",
+			G_CALLBACK (cb_check_resize), scg);
+		g_signal_connect_after (G_OBJECT (scg->hpane), "size-allocate",
+			G_CALLBACK (cb_check_resize), scg);
+
+		g_signal_connect_data (G_OBJECT (scg->table),
+			"size-allocate",
+			G_CALLBACK (scg_scrollbar_config), scg, NULL,
+			G_CONNECT_AFTER | G_CONNECT_SWAPPED);
+		g_signal_connect_object (G_OBJECT (scg->table),
+			"destroy",
+			G_CALLBACK (cb_table_destroy), G_OBJECT (scg),
+			G_CONNECT_SWAPPED);
+
+		sv_attach_control (sv, SHEET_CONTROL (scg));
+
+		g_object_connect (G_OBJECT (sheet),
+			 "swapped_signal::notify::text-is-rtl", cb_scg_direction_changed, scg,
+			 "swapped_signal::notify::display-formulas", cb_scg_redraw, scg,
+			 "swapped_signal::notify::display-zeros", cb_scg_redraw, scg,
+			 "swapped_signal::notify::display-grid", cb_scg_redraw, scg,
+			 "swapped_signal::notify::display-column-header", scg_adjust_preferences, scg,
+			 "swapped_signal::notify::display-row-header", scg_adjust_preferences, scg,
+			 "swapped_signal::notify::use-r1c1", cb_scg_redraw, scg,
+			 "swapped_signal::notify::display-outlines", cb_scg_redraw_resize, scg,
+			 "swapped_signal::notify::display-outlines-below", cb_scg_redraw_resize, scg,
+			 "swapped_signal::notify::display-outlines-right", cb_scg_redraw_resize, scg,
+			 "swapped_signal::notify::columns", cb_scg_sheet_resized, scg,
+			 "swapped_signal::notify::rows", cb_scg_sheet_resized, scg,
+			 NULL);
+	} else {
+		GtkStyle *style;
+		scg->active_panes = 0;
+		scg->table = GTK_TABLE (gtk_table_new (1, 1, FALSE));
+		g_object_ref (scg->table);
+		sheet->hide_col_header = sheet->hide_row_header = FALSE;
+		if (sheet->sheet_type == GNM_SHEET_OBJECT) {
+			scg->vs = g_object_new (GOC_TYPE_CANVAS, NULL);
+			gtk_table_attach (scg->table, scg->vs,
+				0, 1, 0, 1,
+				GTK_EXPAND | GTK_FILL | GTK_SHRINK,
+				GTK_EXPAND | GTK_FILL | GTK_SHRINK,
+				0, 0);
+		}
+		style = gtk_style_copy (scg->vs->style);
+		style->bg[GTK_STATE_NORMAL] = style->white;
+		gtk_widget_set_style (scg->vs, style);
+		g_object_unref (style);
+
+		sv_attach_control (sv, SHEET_CONTROL (scg));
+		g_object_set_data (G_OBJECT (scg->vs), "sheet-control", scg);
+		if (sheet->sheet_objects) {
+			/* we need an idle function because not every thing is intialized at this point */
+			sheet_object_new_view ((SheetObject *) sheet->sheet_objects->data, (SheetObjectViewContainer*) scg->vs);
+			g_idle_add ((GSourceFunc) post_create_cb, scg);
+		}
+	}
 
 	scg->label = editable_label_new
 		(sheet->name_unquoted,
@@ -1567,14 +1619,17 @@ scg_finalize (GObject *object)
 	GSList *ptr;
 
 	/* remove the object view before we disappear */
-	for (ptr = sheet->sheet_objects; ptr != NULL ; ptr = ptr->next )
-		SCG_FOREACH_PANE (scg, pane,
-			g_object_unref (
-				sheet_object_get_view (ptr->data, (SheetObjectViewContainer *)pane));
-		);
+	if (*scg->pane)
+		for (ptr = sheet->sheet_objects; ptr != NULL ; ptr = ptr->next )
+			SCG_FOREACH_PANE (scg, pane,
+				g_object_unref (
+					sheet_object_get_view (ptr->data, (SheetObjectViewContainer *)pane));
+			);
 
-	g_ptr_array_free (scg->col_group.buttons, TRUE);
-	g_ptr_array_free (scg->row_group.buttons, TRUE);
+	if (scg->col_group.buttons) {
+		g_ptr_array_free (scg->col_group.buttons, TRUE);
+		g_ptr_array_free (scg->row_group.buttons, TRUE);
+	}
 
 	scg_comment_timer_clear (scg);
 
@@ -1621,7 +1676,7 @@ scg_unant (SheetControl *sc)
 	g_return_if_fail (IS_SHEET_CONTROL_GUI (scg));
 
 	/* Always have a pane 0 */
-	if (scg->pane[0]->cursor.animated == NULL)
+	if (scg->active_panes == 0  || scg->pane[0]->cursor.animated == NULL)
 		return;
 
 	SCG_FOREACH_PANE (scg, pane, {
@@ -1643,6 +1698,9 @@ scg_ant (SheetControl *sc)
 
 	g_return_if_fail (IS_SHEET_CONTROL_GUI (scg));
 
+	if (scg->active_panes == 0)
+		return;
+
 	/* Always have a grid 0 */
 	if (NULL != scg->pane[0]->cursor.animated)
 		scg_unant (sc);
@@ -1685,22 +1743,24 @@ scg_adjust_preferences (SheetControlGUI *scg)
 		}
 	});
 
-	if (sheet->hide_col_header || sheet->hide_row_header)
-		gtk_widget_hide (GTK_WIDGET (scg->corner));
-	else
-		gtk_widget_show (GTK_WIDGET (scg->corner));
-
-	if (scg_wbc (scg) != NULL) {
-		WorkbookView *wbv = wb_control_view (scg_wbc (scg));
-		if (wbv->show_horizontal_scrollbar)
-			gtk_widget_show (scg->hs);
+	if (scg->corner) {
+		if (sheet->hide_col_header || sheet->hide_row_header)
+			gtk_widget_hide (GTK_WIDGET (scg->corner));
 		else
-			gtk_widget_hide (scg->hs);
+			gtk_widget_show (GTK_WIDGET (scg->corner));
 
-		if (wbv->show_vertical_scrollbar)
-			gtk_widget_show (scg->vs);
-		else
-			gtk_widget_hide (scg->vs);
+		if (scg_wbc (scg) != NULL) {
+			WorkbookView *wbv = wb_control_view (scg_wbc (scg));
+			if (wbv->show_horizontal_scrollbar)
+				gtk_widget_show (scg->hs);
+			else
+				gtk_widget_hide (scg->hs);
+
+			if (wbv->show_vertical_scrollbar)
+				gtk_widget_show (scg->vs);
+			else
+				gtk_widget_hide (scg->vs);
+		}
 	}
 }
 
@@ -3120,8 +3180,11 @@ static void
 scg_object_create_view	(SheetControl *sc, SheetObject *so)
 {
 	SheetControlGUI *scg = SHEET_CONTROL_GUI (sc);
-	SCG_FOREACH_PANE (scg, pane,
-		sheet_object_new_view (so, (SheetObjectViewContainer *)pane););
+	if (scg->active_panes)
+		SCG_FOREACH_PANE (scg, pane,
+			sheet_object_new_view (so, (SheetObjectViewContainer *)pane););
+	else
+		sheet_object_new_view (so, (SheetObjectViewContainer *)scg->vs);
 }
 
 static void
diff --git a/src/sheet-object-graph.c b/src/sheet-object-graph.c
index c70e4b9..9a03d5c 100644
--- a/src/sheet-object-graph.c
+++ b/src/sheet-object-graph.c
@@ -35,6 +35,7 @@
 #include "commands.h"
 #include "application.h"
 #include "sheet.h"
+#include "print-info.h"
 #include <graph.h>
 
 #include <goffice/goffice.h>
@@ -151,19 +152,75 @@ gnm_sog_finalize (GObject *obj)
 	parent_klass->finalize (obj);
 }
 
+static void
+cb_graph_size_changed (GocItem *item, GtkAllocation *allocation)
+{
+	GogRenderer *rend;
+	GogGraph *graph;
+	SheetObject *so = sheet_object_view_get_so (SHEET_OBJECT_VIEW (item->parent));
+	PrintInformation *pi = so->sheet->print_info;
+	double top, bottom, left, right, edge_to_below_header, edge_to_above_footer, w, h, x = 0., y = 0.;
+	w = print_info_get_paper_width (pi, GTK_UNIT_POINTS);
+	h = print_info_get_paper_height (pi, GTK_UNIT_POINTS);
+	print_info_get_margins (pi, &top, &bottom, &left, &right, &edge_to_below_header, &edge_to_above_footer);
+	w -= left + right;
+	h -= top + bottom + edge_to_above_footer + edge_to_below_header;
+	g_object_get (item, "renderer", &rend, NULL);
+	g_object_get (rend, "model", &graph, NULL);
+	gog_graph_set_size (graph, w, h);
+	if (w / allocation->width > h / allocation->height) {
+		h = allocation->width * h / w;
+		w = allocation->width;
+		y = (allocation->height - h) / 2.;
+	} else {
+		w = allocation->height * w / h;
+		h = allocation->height;
+		x = (allocation->width - w) / 2.;
+	}
+	goc_item_set (item, "x", x, "width", w, "y", y, "height", h, NULL);
+	g_object_unref (graph);
+	g_object_unref (rend);
+}
+
+static gboolean
+cb_post_new_view (GocItem *item)
+{
+	GtkAllocation alloc;
+	alloc.width = goc_canvas_get_width (item->canvas);
+	alloc.height = goc_canvas_get_height (item->canvas);
+	cb_graph_size_changed (item, &alloc);
+	return FALSE;
+}
+
 static SheetObjectView *
 gnm_sog_new_view (SheetObject *so, SheetObjectViewContainer *container)
 {
-	GnmPane *pane = GNM_PANE (container);
+	GnmPane *pane;
 	SheetObjectGraph *sog = SHEET_OBJECT_GRAPH (so);
-	GocItem *view = goc_item_new (pane->object_views,
-		so_graph_goc_view_get_type (),
-		NULL);
-	goc_item_new (GOC_GROUP (view),
-		      GOC_TYPE_GRAPH,
-		      "renderer", sog->renderer,
-		      NULL);
-	return gnm_pane_object_register (so, view, TRUE);
+	if (IS_GNM_PANE (container)) {
+		GocItem *view;
+		pane = GNM_PANE (container);
+		view = goc_item_new (pane->object_views,
+			so_graph_goc_view_get_type (),
+			NULL);
+		goc_item_new (GOC_GROUP (view),
+			      GOC_TYPE_GRAPH,
+			      "renderer", sog->renderer,
+			      NULL);
+		return gnm_pane_object_register (so, view, TRUE);
+	} else {
+		GocCanvas *canvas = GOC_CANVAS (container);
+		GocItem *view = goc_item_new (goc_canvas_get_root (canvas),
+			so_graph_goc_view_get_type (),
+			NULL);
+		GocItem *item = goc_item_new (GOC_GROUP (view),
+			      GOC_TYPE_GRAPH,
+			      "renderer", sog->renderer,
+			      NULL);
+		g_idle_add ((GSourceFunc) cb_post_new_view, item); 
+		g_signal_connect_swapped (canvas, "size_allocate", G_CALLBACK (cb_graph_size_changed), item);
+		return (SheetObjectView *) view;
+	}
 }
 
 static GtkTargetList *
@@ -454,9 +511,14 @@ gnm_sog_bounds_changed (SheetObject *so)
 	/* If it has not been realized there is no renderer yet */
 	if (sog->renderer != NULL) {
 		double coords [4];
-		sheet_object_position_pts_get (so, coords);
-		gog_graph_set_size (sog->graph, fabs (coords[2] - coords[0]),
-				    fabs (coords[3] - coords[1]));
+		if (so->sheet->sheet_type == GNM_SHEET_DATA) {
+			sheet_object_position_pts_get (so, coords);
+			gog_graph_set_size (sog->graph, fabs (coords[2] - coords[0]),
+					    fabs (coords[3] - coords[1]));
+		} else {
+			/*FIXME: get dimensions from print settings */
+			gog_graph_set_size (sog->graph, 400., 300.);
+		}
 	}
 }
 
@@ -628,6 +690,12 @@ cb_shared_mode_changed (GtkToggleButton *btn, GraphDataClosure *data)
 	}
 }
 
+static void
+cb_sheet_target_changed (GtkToggleButton *btn, GraphDataClosure *data)
+{
+	data->new_sheet = gtk_toggle_button_get_active (btn);
+}
+
 void
 sheet_object_graph_guru (WBCGtk *wbcg, GogGraph *graph,
 			 GClosure *closure)
@@ -636,7 +704,7 @@ sheet_object_graph_guru (WBCGtk *wbcg, GogGraph *graph,
 		GO_CMD_CONTEXT (wbcg), closure);
 	if (!graph) {
 		GraphDataClosure *data = (GraphDataClosure *) g_new0 (GraphDataClosure, 1);
-		GtkWidget *custom = gtk_table_new (2, 2, FALSE), *w;
+		GtkWidget *custom = gtk_table_new (2, 3, FALSE), *w;
 		GObject *object;
 
 		data->dalloc = GOG_DATA_ALLOCATOR (wbcg);
@@ -654,6 +722,9 @@ sheet_object_graph_guru (WBCGtk *wbcg, GogGraph *graph,
 		w = gtk_check_button_new_with_label (_("Use first series as shared abscissa"));
 		g_signal_connect (G_OBJECT (w), "toggled", G_CALLBACK (cb_shared_mode_changed), data);
 		gtk_table_attach (GTK_TABLE (custom), w, 0, 2, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
+		w = gtk_check_button_new_with_label (_("New graph sheet"));
+		g_signal_connect (G_OBJECT (w), "toggled", G_CALLBACK (cb_sheet_target_changed), data);
+		gtk_table_attach (GTK_TABLE (custom), w, 0, 2, 2, 3, GTK_FILL, GTK_FILL, 0, 0);
 		data->obj = G_OBJECT (custom);
 		gog_guru_add_custom_widget (dialog, custom);
 		object = (GObject*) g_object_get_data (data->obj, "graph");
@@ -672,3 +743,18 @@ sheet_object_graph_guru (WBCGtk *wbcg, GogGraph *graph,
 	wbc_gtk_attach_guru (wbcg, dialog);
 	gtk_widget_show (dialog);
 }
+
+/**
+ * @so: #SheetObject
+ *
+ * Updates the size of the graph item in the canvas for graph sheets objects.
+ */
+void
+sheet_object_graph_ensure_size (SheetObject *so)
+{
+	GList *ptr = so->realized_list;
+	while (ptr) {
+		cb_post_new_view (GOC_ITEM (GOC_GROUP (ptr->data)->children->data));
+		ptr = ptr->next;
+	}
+}
diff --git a/src/sheet-object-graph.h b/src/sheet-object-graph.h
index 52d75af..470d5c7 100644
--- a/src/sheet-object-graph.h
+++ b/src/sheet-object-graph.h
@@ -20,6 +20,7 @@ void	     sheet_object_graph_set_gog (SheetObject *sog, GogGraph *graph);
 void sheet_object_graph_guru (WBCGtk *wbcg, GogGraph *graph,
 			      GClosure *closure);
 
+void	     sheet_object_graph_ensure_size (SheetObject *sog);
 G_END_DECLS
 
 #endif /* _GNM_SHEET_OBJECT_GRAPH_H_ */
diff --git a/src/sheet-object.c b/src/sheet-object.c
index cfe716a..92e1137 100644
--- a/src/sheet-object.c
+++ b/src/sheet-object.c
@@ -155,26 +155,37 @@ cb_so_copy (SheetObject *so, SheetControl *sc)
 static void
 sheet_object_populate_menu_real (SheetObject *so, GPtrArray *actions)
 {
-	static SheetObjectAction const so_actions [] = {
-		{ "gtk-properties",	NULL,		NULL,  0, sheet_object_get_editor },
-		{ NULL,	NULL, NULL, 0, NULL },
-		{ GTK_STOCK_LEAVE_FULLSCREEN, N_("Size _& Position"),	NULL,  0, cb_so_size_position },
-		{ "gtk-fullscreen",	N_("_Snap to Grid"),	NULL,  0, cb_so_snap_to_grid },
-		{ NULL,			N_("_Order"),	NULL,  1, NULL },
-			{ NULL,			N_("Pul_l to Front"),	NULL,  0, cb_so_pull_to_front },
-			{ NULL,			N_("Pull _Forward"),	NULL,  0, cb_so_pull_forward },
-			{ NULL,			N_("Push _Backward"),	NULL,  0, cb_so_push_backward },
-			{ NULL,			N_("Pus_h to Back"),	NULL,  0, cb_so_push_to_back },
-			{ NULL,			NULL,			NULL, -1, NULL },
-		{ NULL,	NULL, NULL, 0, NULL },
-		{ "gtk-cut",		NULL,		NULL,  0, cb_so_cut },
-		{ "gtk-copy",		NULL,		NULL,  0, cb_so_copy },
-		{ "gtk-delete",		NULL,		NULL, 0, cb_so_delete },
-	};
 	unsigned i;
-	for (i = 0 ; i < G_N_ELEMENTS (so_actions); i++)
-		if (i != 0 || SO_CLASS(so)->user_config != NULL)
-			g_ptr_array_add (actions, (gpointer) (so_actions + i));
+	if (so->sheet->sheet_type == GNM_SHEET_OBJECT) {
+		static SheetObjectAction const so_actions [] = {
+			{ "gtk-properties",	NULL,		NULL,  0, sheet_object_get_editor },
+			{ NULL,	NULL, NULL, 0, NULL },
+			{ "gtk-copy",		NULL,		NULL,  0, cb_so_copy },
+		};
+		for (i = 0 ; i < G_N_ELEMENTS (so_actions); i++)
+			if (i != 0 || SO_CLASS(so)->user_config != NULL)
+				g_ptr_array_add (actions, (gpointer) (so_actions + i));
+	} else {
+		static SheetObjectAction const so_actions [] = {
+			{ "gtk-properties",	NULL,		NULL,  0, sheet_object_get_editor },
+			{ NULL,	NULL, NULL, 0, NULL },
+			{ GTK_STOCK_LEAVE_FULLSCREEN, N_("Size _& Position"),	NULL,  0, cb_so_size_position },
+			{ "gtk-fullscreen",	N_("_Snap to Grid"),	NULL,  0, cb_so_snap_to_grid },
+			{ NULL,			N_("_Order"),	NULL,  1, NULL },
+				{ NULL,			N_("Pul_l to Front"),	NULL,  0, cb_so_pull_to_front },
+				{ NULL,			N_("Pull _Forward"),	NULL,  0, cb_so_pull_forward },
+				{ NULL,			N_("Push _Backward"),	NULL,  0, cb_so_push_backward },
+				{ NULL,			N_("Pus_h to Back"),	NULL,  0, cb_so_push_to_back },
+				{ NULL,			NULL,			NULL, -1, NULL },
+			{ NULL,	NULL, NULL, 0, NULL },
+			{ "gtk-cut",		NULL,		NULL,  0, cb_so_cut },
+			{ "gtk-copy",		NULL,		NULL,  0, cb_so_copy },
+			{ "gtk-delete",		NULL,		NULL, 0, cb_so_delete },
+		};
+		for (i = 0 ; i < G_N_ELEMENTS (so_actions); i++)
+			if (i != 0 || SO_CLASS(so)->user_config != NULL)
+				g_ptr_array_add (actions, (gpointer) (so_actions + i));
+	}
 }
 
 /**
@@ -672,6 +683,12 @@ sheet_object_draw_cairo (SheetObject const *so, cairo_t *cr, gboolean rtl)
 	}
 }
 
+void
+sheet_object_draw_cairo_sized (SheetObject const *so, cairo_t *cr, double width, double height)
+{
+	SO_CLASS (so)->draw_cairo (so, cr, width, height);
+}
+
 GnmRange const *
 sheet_object_get_range (SheetObject const *so)
 {
@@ -1199,7 +1216,7 @@ sheet_object_view_enter_notify (GocItem *item, double x, double y)
 {
 	SheetObject *so;
 
-	if (scg_wbcg (GNM_SIMPLE_CANVAS (item->canvas)->scg)->new_object) {
+	if (IS_GNM_PANE (item->canvas) && scg_wbcg (GNM_SIMPLE_CANVAS (item->canvas)->scg)->new_object) {
 		ItemGrid *grid = GNM_PANE (item->canvas)->grid;
 		return GOC_ITEM_GET_CLASS (grid)->enter_notify (GOC_ITEM (grid), x, y);
 	}
@@ -1210,45 +1227,120 @@ sheet_object_view_enter_notify (GocItem *item, double x, double y)
 	return FALSE;
 }
 
+static void
+cb_so_menu_activate (GObject *menu, GocItem *view)
+{
+	SheetObjectAction const *a = g_object_get_data (menu, "action");
+	SheetObject *so = sheet_object_view_get_so (SHEET_OBJECT_VIEW (view));
+	if (a->func)
+		(a->func) (so,
+			   SHEET_CONTROL (g_object_get_data (G_OBJECT (view->canvas), "sheet-control")));
+}
+
+static void
+cb_ptr_array_free (GPtrArray *actions)
+{
+	g_ptr_array_free (actions, TRUE);
+}
+
+static GtkWidget *
+build_so_menu (SheetObjectViewContainer *cont, SheetObjectView *view,
+	       GPtrArray const *actions, unsigned *i)
+{
+	SheetObjectAction const *a;
+	GtkWidget *item, *menu = gtk_menu_new ();
+
+	while (*i < actions->len) {
+		a = g_ptr_array_index (actions, *i);
+		(*i)++;
+		if (a->submenu < 0)
+			break;
+		if (a->icon != NULL) {
+			if (a->label != NULL) {
+				item = gtk_image_menu_item_new_with_mnemonic (_(a->label));
+				gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
+					gtk_image_new_from_stock (a->icon, GTK_ICON_SIZE_MENU));
+			} else
+				item = gtk_image_menu_item_new_from_stock (a->icon, NULL);
+		} else if (a->label != NULL)
+			item = gtk_menu_item_new_with_mnemonic (_(a->label));
+		else
+			item = gtk_separator_menu_item_new ();
+		if (a->submenu > 0)
+			gtk_menu_item_set_submenu (GTK_MENU_ITEM (item),
+				build_so_menu (cont, view, actions, i));
+		else if (a->label != NULL || a->icon != NULL) { /* not a separator or menu */
+			g_object_set_data (G_OBJECT (item), "action", (gpointer)a);
+			g_signal_connect_object (G_OBJECT (item), "activate",
+				G_CALLBACK (cb_so_menu_activate), view, 0);
+		}
+		gtk_menu_shell_append (GTK_MENU_SHELL (menu),  item);
+	}
+	return menu;
+}
+
 static gboolean
 sheet_object_view_button_pressed (GocItem *item, int button, double x, double y)
 {
 	GnmPane *pane;
 	SheetObject *so;
+	if (IS_GNM_PANE (item->canvas)) {
+		if (scg_wbcg (GNM_SIMPLE_CANVAS (item->canvas)->scg)->new_object) {
+			ItemGrid *grid = GNM_PANE (item->canvas)->grid;
+			return GOC_ITEM_GET_CLASS (grid)->button_pressed (GOC_ITEM (grid), button, x, y);
+		}
 
-	if (scg_wbcg (GNM_SIMPLE_CANVAS (item->canvas)->scg)->new_object) {
-		ItemGrid *grid = GNM_PANE (item->canvas)->grid;
-		return GOC_ITEM_GET_CLASS (grid)->button_pressed (GOC_ITEM (grid), button, x, y);
-	}
-
-	if (button > 3)
-		return FALSE;
-
-	pane = GNM_PANE (item->canvas);
-	so = (SheetObject *) g_object_get_qdata (G_OBJECT (item), sov_so_quark);
+		if (button > 3)
+			return FALSE;
 
-	x *= goc_canvas_get_pixels_per_unit (item->canvas);
-	y *= goc_canvas_get_pixels_per_unit (item->canvas);
-	/* cb_sheet_object_widget_canvas_event calls even if selected */
-	if (NULL == g_hash_table_lookup (pane->drag.ctrl_pts, so)) {
-		SheetObjectClass *soc =
-			G_TYPE_INSTANCE_GET_CLASS (so, SHEET_OBJECT_TYPE, SheetObjectClass);
-		GdkEventButton *event = (GdkEventButton *) goc_canvas_get_cur_event (item->canvas);
+		pane = GNM_PANE (item->canvas);
+		so = (SheetObject *) g_object_get_qdata (G_OBJECT (item), sov_so_quark);
+
+		x *= goc_canvas_get_pixels_per_unit (item->canvas);
+		y *= goc_canvas_get_pixels_per_unit (item->canvas);
+		/* cb_sheet_object_widget_canvas_event calls even if selected */
+		if (NULL == g_hash_table_lookup (pane->drag.ctrl_pts, so)) {
+			SheetObjectClass *soc =
+				G_TYPE_INSTANCE_GET_CLASS (so, SHEET_OBJECT_TYPE, SheetObjectClass);
+			GdkEventButton *event = (GdkEventButton *) goc_canvas_get_cur_event (item->canvas);
+
+			if (soc->interactive && button != 3)
+				return FALSE;
+
+			if (!(event->state & GDK_SHIFT_MASK))
+				scg_object_unselect (pane->simple.scg, NULL);
+			scg_object_select (pane->simple.scg, so);
+			if (NULL == g_hash_table_lookup (pane->drag.ctrl_pts, so))
+				return FALSE;	/* protected ? */
+		}
 
-		if (soc->interactive && button != 3)
-			return FALSE;
+		if (button < 3)
+			gnm_pane_object_start_resize (pane, button, x, y, so, 8, FALSE);
+		else
+			gnm_pane_display_object_menu (pane, so, goc_canvas_get_cur_event (item->canvas));
+	} else {
+		if (button == 3) {
+			GPtrArray *actions = g_ptr_array_new ();
+			GtkWidget *menu;
+			unsigned i = 0;
+
+			so = (SheetObject *) g_object_get_qdata (G_OBJECT (item), sov_so_quark);
+			sheet_object_populate_menu (so, actions);
+
+			if (actions->len == 0) {
+				g_ptr_array_free (actions, TRUE);
+				return FALSE;
+			}
 
-		if (!(event->state & GDK_SHIFT_MASK))
-			scg_object_unselect (pane->simple.scg, NULL);
-		scg_object_select (pane->simple.scg, so);
-		if (NULL == g_hash_table_lookup (pane->drag.ctrl_pts, so))
-			return FALSE;	/* protected ? */
+			menu = build_so_menu ((SheetObjectViewContainer *) item->canvas,
+				sheet_object_get_view (so, (SheetObjectViewContainer *) item->canvas),
+				actions, &i);
+			g_object_set_data_full (G_OBJECT (menu), "actions", actions,
+				(GDestroyNotify) cb_ptr_array_free);
+			gtk_widget_show_all (menu);
+			gnumeric_popup_menu (GTK_MENU (menu), &goc_canvas_get_cur_event (item->canvas)->button);
+		}
 	}
-
-	if (button < 3)
-		gnm_pane_object_start_resize (pane, button, x, y, so, 8, FALSE);
-	else
-		gnm_pane_display_object_menu (pane, so, goc_canvas_get_cur_event (item->canvas));
 	return TRUE;
 }
 
diff --git a/src/sheet-object.h b/src/sheet-object.h
index 5cf3730..147c2a3 100644
--- a/src/sheet-object.h
+++ b/src/sheet-object.h
@@ -140,6 +140,7 @@ void sheet_object_write_object	(SheetObject const *so,
 
 /* cairo rendering */
 void sheet_object_draw_cairo (SheetObject const *so, cairo_t *cr, gboolean rtl);
+void sheet_object_draw_cairo_sized (SheetObject const *so, cairo_t *cr, double width, double height);
 
 /* management routine to register all the builtin object types */
 void sheet_objects_init (void);
diff --git a/src/sheet.c b/src/sheet.c
index 45eac1e..b979395 100644
--- a/src/sheet.c
+++ b/src/sheet.c
@@ -1334,6 +1334,9 @@ sheet_new_with_type (Workbook *wb, char const *name, GnmSheetType type,
 			      "zoom-factor", gnm_conf_get_core_gui_window_zoom (),
 			      NULL);
 
+	if (type == GNM_SHEET_OBJECT)
+		print_info_set_paper_orientation (sheet->print_info, GTK_PAGE_ORIENTATION_LANDSCAPE);
+
 	return sheet;
 }
 
diff --git a/src/sheet.h b/src/sheet.h
index 2178399..a274efc 100644
--- a/src/sheet.h
+++ b/src/sheet.h
@@ -15,11 +15,6 @@ struct _GnmSheetSize {
 };
 
 typedef struct _SheetPrivate SheetPrivate;
-typedef enum {
-	GNM_SHEET_DATA,
-	GNM_SHEET_OBJECT,
-	GNM_SHEET_XLM
-} GnmSheetType;
 GType gnm_sheet_type_get_type (void);
 #define GNM_SHEET_TYPE_TYPE (gnm_sheet_type_get_type ())
 
diff --git a/src/wbc-gtk-actions.c b/src/wbc-gtk-actions.c
index 973a758..ac5d2b3 100644
--- a/src/wbc-gtk-actions.c
+++ b/src/wbc-gtk-actions.c
@@ -62,6 +62,7 @@
 #include "gnumeric-gconf.h"
 #include "expr.h"
 #include "print.h"
+#include "print-info.h"
 #include "gnm-pane-impl.h"
 
 #include <goffice/goffice.h>
@@ -1180,6 +1181,26 @@ static GNM_ACTION_DEF (cb_sort_descending) { sort_by_rows (wbcg, TRUE); }
 static void
 cb_add_graph (GogGraph *graph, gpointer wbcg)
 {
+	GraphDataClosure *data = (GraphDataClosure *) g_object_get_data (G_OBJECT (graph), "data-closure");
+	if (data) {
+		if (data->new_sheet) {
+			WorkbookControl *wbc = WORKBOOK_CONTROL (wbcg);
+			Sheet *sheet = wb_control_cur_sheet (wbc);
+			WorkbookSheetState *old_state = workbook_sheet_state_new (wb_control_get_workbook (wbc));
+			Sheet *new_sheet = workbook_sheet_add_with_type (
+				wb_control_get_workbook (wbc),
+				GNM_SHEET_OBJECT, -1,
+				gnm_sheet_get_max_cols (sheet),
+				gnm_sheet_get_max_rows (sheet));
+			SheetObject *sog = sheet_object_graph_new (graph);
+			print_info_set_paper_orientation (new_sheet->print_info, GTK_PAGE_ORIENTATION_LANDSCAPE);
+			sheet_object_set_sheet (sog, new_sheet);
+			wb_view_sheet_focus (wb_control_view (wbc), new_sheet);
+			cmd_reorganize_sheets (wbc, old_state, sheet);
+			g_object_unref (sog);
+			return;
+		}
+	}
 	wbcg_insert_object (WBC_GTK (wbcg), sheet_object_graph_new (graph));
 }
 
@@ -1742,6 +1763,22 @@ static GtkActionEntry const permanent_actions[] = {
 		NULL, N_("Send the current file via email"),
 		G_CALLBACK (cb_file_sendto) },
 	{ "FilePrintArea",      NULL, N_("Print Area")},
+#ifdef HAVE_GTK_ADJUSTMENT_CONFIGURE
+	/* gtk_adjustment_configure implies gtk 2.14 or later */
+	/* that is required for GTK_STOCK_PAGE_SETUP */
+	{ "FilePageSetup", GTK_STOCK_PAGE_SETUP, N_("Page Set_up..."),
+#else
+	{ "FilePageSetup", NULL, N_("Page Set_up..."),
+#endif
+		NULL, N_("Setup the page settings for your current printer"),
+		G_CALLBACK (cb_file_page_setup) },
+	{ "FilePrintPreview", GTK_STOCK_PRINT_PREVIEW, NULL,
+		NULL, N_("Print preview"),
+		G_CALLBACK (cb_file_print_preview) },
+	{ "FilePrint", GTK_STOCK_PRINT, NULL,
+		"<control>p", N_("Print the current file"),
+		G_CALLBACK (cb_file_print) },
+
 	{ "FileHistoryFull", NULL, N_("Full _History..."),
 		NULL, N_("Access previously used file"),
 		G_CALLBACK (cb_file_history_full) },
@@ -1797,21 +1834,6 @@ static GtkActionEntry const permanent_actions[] = {
 
 static GtkActionEntry const actions[] = {
 /* File */
-#ifdef HAVE_GTK_ADJUSTMENT_CONFIGURE
-	/* gtk_adjustment_configure implies gtk 2.14 or later */
-	/* that is required for GTK_STOCK_PAGE_SETUP */
-	{ "FilePageSetup", GTK_STOCK_PAGE_SETUP, N_("Page Set_up..."),
-#else
-	{ "FilePageSetup", NULL, N_("Page Set_up..."),
-#endif
-		NULL, N_("Setup the page settings for your current printer"),
-		G_CALLBACK (cb_file_page_setup) },
-	{ "FilePrintPreview", GTK_STOCK_PRINT_PREVIEW, NULL,
-		NULL, N_("Print preview"),
-		G_CALLBACK (cb_file_print_preview) },
-	{ "FilePrint", GTK_STOCK_PRINT, NULL,
-		"<control>p", N_("Print the current file"),
-		G_CALLBACK (cb_file_print) },
 	{ "FileMetaData", GTK_STOCK_PROPERTIES, N_("Document Proper_ties..."),
 		NULL, N_("Edit document properties"),
 		G_CALLBACK (cb_doc_meta_data) },
diff --git a/src/wbc-gtk.c b/src/wbc-gtk.c
index 925f33a..502d84a 100644
--- a/src/wbc-gtk.c
+++ b/src/wbc-gtk.c
@@ -372,6 +372,21 @@ wbcg_update_action_sensitivity (WorkbookControl *wbc)
 	g_object_set (G_OBJECT (wbcg->font_actions),
 		"sensitive", enable_actions || enable_edit_ok_cancel,
 		NULL);
+
+	if (scg && scg_sheet (scg)->sheet_type == GNM_SHEET_OBJECT) {
+		GtkAction *action = gtk_action_group_get_action (wbcg->permanent_actions, "EditPaste");
+		gtk_action_set_sensitive (action, FALSE);
+		action = gtk_action_group_get_action (wbcg->permanent_actions, "EditCut");
+		gtk_action_set_sensitive (action, FALSE);
+		gtk_widget_set_sensitive (GTK_WIDGET (wbcg->edit_line.entry), FALSE);
+		gtk_widget_set_sensitive (GTK_WIDGET (wbcg->selection_descriptor), FALSE);
+	} else {
+		GtkAction *action = gtk_action_group_get_action (wbcg->permanent_actions, "EditPaste");
+		gtk_action_set_sensitive (action, TRUE);
+		action = gtk_action_group_get_action (wbcg->permanent_actions, "EditCut");
+		gtk_action_set_sensitive (action, TRUE);
+		gtk_widget_set_sensitive (GTK_WIDGET (wbcg->selection_descriptor), TRUE);
+	}
 }
 
 static gboolean
@@ -775,7 +790,8 @@ wbcg_set_direction (SheetControlGUI const *scg)
 
 	if (dir != gtk_widget_get_direction (w))
 		set_dir (w, &dir);
-	g_object_set (scg->hs, "inverted", text_is_rtl, NULL);
+	if (scg->hs)
+		g_object_set (scg->hs, "inverted", text_is_rtl, NULL);
 }
 
 static void
@@ -1947,7 +1963,7 @@ cb_scroll_wheel (GtkWidget *w, GdkEventScroll *event,
 	gboolean go_back = (event->direction == GDK_SCROLL_UP ||
 			    event->direction == GDK_SCROLL_LEFT);
 
-	if (!GTK_WIDGET_REALIZED (w))
+	if (!pane || !GTK_WIDGET_REALIZED (w))
 		return FALSE;
 
 	if ((event->state & GDK_MOD1_MASK))
@@ -5473,7 +5489,8 @@ wbcg_set_transient (WBCGtk *wbcg, GtkWindow *window)
 int
 wbcg_get_n_scg (WBCGtk const *wbcg)
 {
-	return gtk_notebook_get_n_pages (wbcg->snotebook);
+	return (GTK_IS_NOTEBOOK (wbcg->snotebook))?
+		gtk_notebook_get_n_pages (wbcg->snotebook): -1;
 }
 
 /**
diff --git a/src/workbook.c b/src/workbook.c
index d1d449c..dbf8d47 100644
--- a/src/workbook.c
+++ b/src/workbook.c
@@ -907,6 +907,34 @@ workbook_sheet_add (Workbook *wb, int pos, int columns, int rows)
 }
 
 /**
+ * workbook_sheet_add_with_type :
+ * @wb :
+ * @pos : position to add, -1 meaning append.
+ * @type : sheet type.
+ *
+ * Create and name a new sheet, putting it at position @pos.  The sheet
+ * returned is not ref'd.  (The ref belongs to the workbook.)
+ */
+Sheet *
+workbook_sheet_add_with_type (Workbook *wb, GnmSheetType sheet_type, int pos, int columns, int rows)
+{
+	char *name = workbook_sheet_get_free_name (wb, (sheet_type == GNM_SHEET_OBJECT)? _("Graph"): _("Sheet"), TRUE, FALSE);
+	Sheet *new_sheet = sheet_new_with_type (wb, name, sheet_type, columns, rows);
+	g_free (name);
+
+	if (pos == -1)
+		pos = wb->sheets->len;
+	workbook_sheet_attach_at_pos (wb, new_sheet, pos);
+
+	/* FIXME: Why here?  */
+	g_signal_emit (G_OBJECT (wb), signals [SHEET_ADDED], 0);
+
+	g_object_unref (new_sheet);
+
+	return new_sheet;
+}
+
+/**
  * workbook_sheet_delete:
  * @sheet: the sheet that we want to delete from its workbook
  *
diff --git a/src/workbook.h b/src/workbook.h
index 89d8bc4..04a537a 100644
--- a/src/workbook.h
+++ b/src/workbook.h
@@ -24,6 +24,7 @@ Sheet      *workbook_sheet_by_name       (Workbook const *wb, char const *sheet_
 void        workbook_sheet_attach        (Workbook *wb, Sheet *new_sheet);
 void        workbook_sheet_attach_at_pos (Workbook *wb, Sheet *new_sheet, int pos);
 Sheet	   *workbook_sheet_add		 (Workbook *wb, int pos, int columns, int rows);
+Sheet	   *workbook_sheet_add_with_type (Workbook *wb, GnmSheetType sheet_type, int pos, int columns, int rows);
 void        workbook_sheet_delete        (Sheet *sheet);
 void        workbook_sheet_move          (Sheet *sheet, int direction);
 char       *workbook_sheet_get_free_name (Workbook *wb,
diff --git a/src/xml-sax-read.c b/src/xml-sax-read.c
index 5841618..5477238 100644
--- a/src/xml-sax-read.c
+++ b/src/xml-sax-read.c
@@ -347,6 +347,7 @@ typedef struct {
 	SheetObject *so;
 
 	int sheet_rows, sheet_cols;
+	GnmSheetType sheet_type;
 
 	GnmPageBreaks *page_breaks;
 
@@ -499,12 +500,16 @@ xml_sax_wb_sheetsize (GsfXMLIn *xin, xmlChar const **attrs)
 	/* Defaults for legacy files.  */
 	state->sheet_cols = 256;
 	state->sheet_rows = 65536;
+	state->sheet_type = GNM_SHEET_DATA;
 
 	for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2) {
 		if (gnm_xml_attr_int (attrs, "gnm:Cols", &state->sheet_cols))
 			; /* Nothing more */
 		else if (gnm_xml_attr_int (attrs, "gnm:Rows", &state->sheet_rows))
 			; /* Nothing more */
+		else if (!strcmp (CXML2C (attrs[0]), "gnm:SheetType") &&
+			 !strcmp (CXML2C (attrs[1]), "object"))
+			state->sheet_type = GNM_SHEET_OBJECT;
 		else
 			unknown_attr (xin, attrs);
 	}
@@ -528,7 +533,8 @@ xml_sax_wb_sheetname (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
 						&state->sheet_rows);
 		}
 
-		sheet = sheet_new (wb, name,
+		sheet = sheet_new_with_type (wb, name,
+				   state->sheet_type,
 				   state->sheet_cols,
 				   state->sheet_rows);
 		workbook_sheet_attach (wb, sheet);
diff --git a/src/xml-sax-write.c b/src/xml-sax-write.c
index dac3340..bc016fb 100644
--- a/src/xml-sax-write.c
+++ b/src/xml-sax-write.c
@@ -182,6 +182,8 @@ xml_write_sheet_names (GnmOutputXML *state)
 	for (i = 0 ; i < n ; i++) {
 		sheet = workbook_sheet_by_index (state->wb, i);
 		gsf_xml_out_start_element (state->output, GNM "SheetName");
+		if (sheet->sheet_type == GNM_SHEET_OBJECT)
+			gsf_xml_out_add_cstr (state->output, GNM "SheetType", "object");
 		gsf_xml_out_add_int (state->output, GNM "Cols",
 							 gnm_sheet_get_max_cols (sheet));
 		gsf_xml_out_add_int (state->output, GNM "Rows",



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]