[gnumeric] Add component support in sheets.



commit 0c9854a65ea547a1d07912e2b8c6b560c15ec213
Author: Jean Brefort <jean brefort normalesup org>
Date:   Wed Aug 3 10:39:39 2011 +0200

    Add component support in sheets.

 ChangeLog                     |   18 ++
 component/gnumeric.c          |   74 ++++++---
 src/GNOME_Gnumeric-gtk.xml.in |    6 +-
 src/Makefile.am               |    2 +
 src/commands.c                |   73 +++++++++
 src/gnm-pane.c                |   31 +++--
 src/libgnumeric.c             |    5 +
 src/main-application.c        |   11 +-
 src/sheet-control-gui.c       |    9 +-
 src/sheet-object-component.c  |  345 +++++++++++++++++++++++++++++++++++++++++
 src/sheet-object-component.h  |   45 ++++++
 src/sheet-object-impl.h       |    2 +
 src/sheet-object.c            |   40 ++++--
 src/sheet-object.h            |    2 +
 src/wbc-gtk-actions.c         |   85 ++++++++++-
 src/wbc-gtk.c                 |    9 +-
 src/xml-sax-read.c            |    6 +-
 17 files changed, 706 insertions(+), 57 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index d3253a3..6d6324d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,23 @@
 2011-08-03  Jean Brefort  <jean brefort normalesup org>
 
+	* component/gnumeric.c: update component.
+	* src/GNOME_Gnumeric-gtk.xml.in: add component support in sheets.
+	* src/Makefile.am: ditto.
+	* src/commands.c: ditto.
+	* src/gnm-pane.c: ditto.
+	* src/libgnumeric.c: ditto.
+	* src/main-application.c: ditto.
+	* src/sheet-control-gui.c: ditto.
+	* src/sheet-object.c: ditto.
+	* src/sheet-object.h: ditto.
+	* src/sheet-object-component.c: ditto.
+	* src/sheet-object-component.h: ditto.
+	* src/wbc-gtk-actions.c: ditto.
+	* src/wbc-gtk.c: ditto.
+	* src/xml-sax-read.c: ditto.
+
+2011-08-03  Jean Brefort  <jean brefort normalesup org>
+
 	* src/wbc-gtk.c (cb_add_menus_toolbars): set the "hexpand" property to
 	TRUE for toolbars. [#655858]
 
diff --git a/component/gnumeric.c b/component/gnumeric.c
index b6051bf..99b9a88 100644
--- a/component/gnumeric.c
+++ b/component/gnumeric.c
@@ -3,7 +3,7 @@
  * Gnumeric GOffice component
  * gnumeric.c
  *
- * Copyright (C) 2006-2009
+ * Copyright (C) 2006-2010
  *
  * Developed by Jean BrÃfort <jean brefort normalesup org>
  *
@@ -66,6 +66,7 @@ typedef struct {
 	GOComponent parent;
 
 	WorkbookView	*wv;
+	Workbook	*wb;
 	WBCGtk		*edited;
 	Sheet		*sheet;
 	int col_start, col_end, row_start, row_end;
@@ -87,16 +88,14 @@ go_gnm_component_get_data (GOComponent *component, gpointer *data, int *length,
 									void (**clearfunc) (gpointer), gpointer *user_data)
 {
 	GOGnmComponent *gognm = GO_GNM_COMPONENT (component);
-	if (gognm->edited) {
+	if (gognm->wv) {
 		GOCmdContext *cc = go_component_get_command_context ();
 		GOIOContext *io_context = go_io_context_new (cc);
 		GsfOutput *output = gsf_output_memory_new ();
-		WorkbookView *wbv = wb_control_view (WORKBOOK_CONTROL (gognm->edited));
-		Workbook *wb = wb_view_get_workbook (wbv);
-		GOFileSaver *gfs = workbook_get_file_saver (wb);
+		GOFileSaver *gfs = workbook_get_file_saver (gognm->wb);
 		if (gfs == NULL)
 			gfs = go_file_saver_get_default ();
-		wbv_save_to_output (wbv, gfs, output, io_context);
+		wbv_save_to_output (gognm->wv, gfs, output, io_context);
 		*data = (gpointer) gsf_output_memory_get_bytes (GSF_OUTPUT_MEMORY (output));
 		*length = gsf_output_size (output);
 		*clearfunc = g_object_unref;
@@ -107,20 +106,10 @@ go_gnm_component_get_data (GOComponent *component, gpointer *data, int *length,
 }
 
 static void
-go_gnm_component_set_data (GOComponent *component)
+go_gnm_component_update_data (GOGnmComponent *gognm)
 {
-	GOGnmComponent *gognm = GO_GNM_COMPONENT (component);
 	SheetView *sv;
 	GnmRange const *range;
-	GOCmdContext *cc = go_component_get_command_context ();
-	GOIOContext *io_context = go_io_context_new (cc);
-	GsfInput *input = gsf_input_memory_new (component->data, component->length, FALSE);
-
-	g_object_set (G_OBJECT (io_context), "exec-main-loop", FALSE, NULL);
-	if (gognm->wv != NULL)
-		g_object_unref (gognm->wv);
-	gognm->wv = wb_view_new_from_input (input, NULL, NULL, io_context, NULL);
-	g_object_unref (io_context);
 	gognm->sheet = wb_view_cur_sheet (gognm->wv);
 	sv = sheet_get_view (gognm->sheet, gognm->wv);
 	range = selection_first_range (sv, NULL, NULL);
@@ -130,11 +119,30 @@ go_gnm_component_set_data (GOComponent *component)
 	gognm->row_end = range->end.row;
 	gognm->width = sheet_col_get_distance_pts (
 		gognm->sheet, gognm->col_start, gognm->col_end + 1);
-	component->width = gognm->width / 72.;
-	component->descent = 0.;
+	gognm->parent.width = gognm->width / 72.;
+	gognm->parent.descent = 0.;
 	gognm->height = sheet_row_get_distance_pts (
 		gognm->sheet, gognm->row_start, gognm->row_end + 1);
-	component->ascent = gognm->height  / 72.;
+	gognm->parent.ascent = gognm->parent.height = gognm->height  / 72.;
+}
+
+static void
+go_gnm_component_set_data (GOComponent *component)
+{
+	GOGnmComponent *gognm = GO_GNM_COMPONENT (component);
+	GOCmdContext *cc = go_component_get_command_context ();
+	GOIOContext *io_context = go_io_context_new (cc);
+	GsfInput *input = gsf_input_memory_new (component->data, component->length, FALSE);
+
+	g_object_set (G_OBJECT (io_context), "exec-main-loop", FALSE, NULL);
+	if (gognm->wv != NULL) {
+		g_object_unref (gognm->wv);
+		g_object_unref (gognm->wb);
+	}
+	gognm->wv = wb_view_new_from_input (input, NULL, NULL, io_context, NULL);
+	gognm->wb = wb_view_get_workbook (gognm->wv);
+	g_object_unref (io_context);
+	go_gnm_component_update_data (gognm);
 }
 
 static void
@@ -143,6 +151,9 @@ go_gnm_component_render (GOComponent *component, cairo_t *cr, double width_pixel
 	GOGnmComponent *gognm = GO_GNM_COMPONENT (component);
 	GnmRange range;
 
+	if (!gognm->sheet)
+		go_gnm_component_update_data (gognm);
+
 	range_init (&range, gognm->col_start, gognm->row_start, gognm->col_end, gognm->row_end);
 	cairo_save (cr);
 	cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
@@ -162,6 +173,19 @@ cb_gognm_save (G_GNUC_UNUSED GtkAction *a, WBCGtk *wbcg)
 	gpointer data = g_object_get_data (G_OBJECT (wbcg), "component");
 	if (GO_IS_COMPONENT (data)) {
 		GOComponent *component = GO_COMPONENT (data);
+		/* update the component data since not all clients will call set_data */
+		GOGnmComponent *gognm = GO_GNM_COMPONENT (component);
+		WorkbookView *wv = wb_control_view (WORKBOOK_CONTROL (wbcg));
+		if (wv != gognm->wv) {
+			if (gognm->wv != NULL) {
+				g_object_unref (gognm->wv);
+				g_object_unref (gognm->wb);
+			}
+			gognm->wv = g_object_ref (wv);
+			gognm->wb = g_object_ref (wb_view_get_workbook (wv));
+		}
+		go_doc_set_dirty (GO_DOC (gognm->wb), FALSE);
+		go_gnm_component_update_data (gognm);
 		go_component_emit_changed (component);
 	} else
 		gui_file_save (wbcg, wb_control_view (WORKBOOK_CONTROL (wbcg)));
@@ -196,7 +220,7 @@ go_gnm_component_edit (GOComponent *component)
 		wv = workbook_view_new (workbook_new_with_sheets (1));
 	} else {
 		GOCmdContext *cc = go_component_get_command_context ();
-		GOIOContext *io_context = go_io_context_new (cc);
+		GOIOContext *io_context = GO_IS_IO_CONTEXT (cc)? GO_IO_CONTEXT (g_object_ref (cc)): go_io_context_new (cc);
 		GsfInput *input = gsf_input_memory_new (component->data, component->length, FALSE);
 
 		g_object_set (G_OBJECT (io_context), "exec-main-loop", FALSE, NULL);
@@ -218,6 +242,7 @@ go_gnm_component_finalize (GObject *obj)
 	GOGnmComponent *gognm = GO_GNM_COMPONENT (obj);
 	if (gognm->wv != NULL) {
 		g_object_unref (gognm->wv);
+		g_object_unref (gognm->wb);
 		gognm->wv = NULL;
 	}
 	if (gognm->edited != NULL) {
@@ -234,6 +259,9 @@ go_gnm_component_init (GOComponent *component)
 	component->resizable = FALSE;
 	component->editable = TRUE;
 	component->needs_window = FALSE;
+#ifdef GO_SNAPSHOT_SVG
+	component->snapshot_type = GO_SNAPSHOT_SVG;
+#endif
 	gognm->row_start = gognm->col_start = 0;
 	gognm->sheet = NULL;
 	gognm->row_end = 9;
@@ -293,11 +321,11 @@ go_plugin_init (GOPlugin *plugin, G_GNUC_UNUSED GOCmdContext *cc)
 
 	go_components_set_mime_suffix ("application/x-gnumeric", "*.gnumeric");
 
-/* WHERE IS THIS DEFINED */
-	go_plugins_add (go_component_get_command_context (),
+	go_plugins_init (go_component_get_command_context (),
 			gnm_conf_get_plugins_file_states (),
 			gnm_conf_get_plugins_active (),
 			dir_list,
+			gnm_conf_get_plugins_activate_new (),
 			gnm_plugin_loader_module_get_type ());
 }
 
diff --git a/src/GNOME_Gnumeric-gtk.xml.in b/src/GNOME_Gnumeric-gtk.xml.in
index de7d0c0..46d54fc 100644
--- a/src/GNOME_Gnumeric-gtk.xml.in
+++ b/src/GNOME_Gnumeric-gtk.xml.in
@@ -120,7 +120,11 @@
       <menuitem action="SheetInsert"/>
       <separator/>
       <menuitem action="ChartGuru"/>
-<!-- These don't work yet for Gnome 2
+      <menu name="Object" action="MenuInsertObject">
+        <menuitem action="NewGOComponent" />
+        <menuitem action="GOComponentFromFile" />
+      </menu>
+<!-- These don't work yet for Gnome 2 
 	    <menuitem action="InsertComponent" />
 	    <menuitem action="InsertShapedComponent" />
 	    <separator/>
diff --git a/src/Makefile.am b/src/Makefile.am
index b6647de..d71f523 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -162,6 +162,7 @@ libspreadsheet_la_SOURCES =			\
 	gnm-so-filled.c				\
 	gnm-so-line.c				\
 	gnm-so-polygon.c			\
+	sheet-object-component.c		\
 	sheet-object-graph.c			\
 	sheet-object-image.c			\
 	sheet-object-widget.c			\
@@ -291,6 +292,7 @@ libspreadsheet_include_HEADERS = 	\
 	gnm-so-filled.h				\
 	gnm-so-line.h				\
 	gnm-so-polygon.h			\
+	sheet-object-component.h		\
 	sheet-object-graph.h			\
 	sheet-object-image.h			\
 	sheet-object-widget.h			\
diff --git a/src/commands.c b/src/commands.c
index 1ff0fde..291678d 100644
--- a/src/commands.c
+++ b/src/commands.c
@@ -63,6 +63,7 @@
 #include "sheet-object-cell-comment.h"
 #include "sheet-object-widget.h"
 #include "sheet-object.h"
+#include "sheet-object-component.h"
 #include "sheet-object-graph.h"
 #include "sheet-control.h"
 #include "sheet-control-gui.h"
@@ -6913,6 +6914,78 @@ cmd_so_graph_config (WorkbookControl *wbc, SheetObject *so,
 
 /******************************************************************/
 
+#define CMD_SO_COMPONENT_CONFIG_TYPE (cmd_so_component_config_get_type ())
+#define CMD_SO_COMPONENT_CONFIG(o)   (G_TYPE_CHECK_INSTANCE_CAST ((o), CMD_SO_COMPONENT_CONFIG_TYPE, CmdSOComponentConfig))
+
+typedef struct {
+	GnmCommand cmd;
+	SheetObject *so;
+	GOComponent *new_obj;
+	GOComponent *old_obj;
+} CmdSOComponentConfig;
+
+MAKE_GNM_COMMAND (CmdSOComponentConfig, cmd_so_component_config, NULL)
+
+static gboolean
+cmd_so_component_config_redo (GnmCommand *cmd,
+			  G_GNUC_UNUSED WorkbookControl *wbc)
+{
+	CmdSOComponentConfig *me = CMD_SO_COMPONENT_CONFIG (cmd);
+	sheet_object_component_set_component (me->so, me->new_obj);
+	return FALSE;
+}
+
+static gboolean
+cmd_so_component_config_undo (GnmCommand *cmd,
+			  G_GNUC_UNUSED WorkbookControl *wbc)
+{
+	CmdSOComponentConfig *me = CMD_SO_COMPONENT_CONFIG (cmd);
+	sheet_object_component_set_component (me->so, me->old_obj);
+	return FALSE;
+}
+
+static void
+cmd_so_component_config_finalize (GObject *cmd)
+{
+	CmdSOComponentConfig *me = CMD_SO_COMPONENT_CONFIG (cmd);
+
+	g_object_unref (me->so);
+	g_object_unref (me->new_obj);
+	g_object_unref (me->old_obj);
+
+	gnm_command_finalize (cmd);
+}
+
+gboolean
+cmd_so_component_config (WorkbookControl *wbc, SheetObject *so,
+		     GObject *n_obj, GObject *o_obj)
+{
+	CmdSOComponentConfig *me;
+
+	g_return_val_if_fail (IS_WORKBOOK_CONTROL (wbc), TRUE);
+	g_return_val_if_fail (IS_SHEET_OBJECT_COMPONENT (so), TRUE);
+	g_return_val_if_fail (GO_IS_COMPONENT (n_obj), TRUE);
+	g_return_val_if_fail (GO_IS_COMPONENT (o_obj), TRUE);
+
+	me = g_object_new (CMD_SO_COMPONENT_CONFIG_TYPE, NULL);
+
+	me->so = so;
+	g_object_ref (G_OBJECT (so));
+
+	me->new_obj = GO_COMPONENT (n_obj);
+	g_object_ref (G_OBJECT (me->new_obj));
+	me->old_obj = GO_COMPONENT (o_obj);
+	g_object_ref (G_OBJECT (me->old_obj));
+
+	me->cmd.sheet = sheet_object_get_sheet (so);;
+	me->cmd.size = 10;
+	me->cmd.cmd_descriptor = g_strdup (_("Reconfigure Object"));
+
+	return gnm_command_push_undo (wbc, G_OBJECT (me));
+}
+
+/******************************************************************/
+
 #define CMD_TOGGLE_RTL_TYPE (cmd_toggle_rtl_get_type ())
 #define CMD_TOGGLE_RTL(o)   (G_TYPE_CHECK_INSTANCE_CAST ((o), CMD_TOGGLE_RTL_TYPE, CmdToggleRTL))
 
diff --git a/src/gnm-pane.c b/src/gnm-pane.c
index af5151a..ea06c7b 100644
--- a/src/gnm-pane.c
+++ b/src/gnm-pane.c
@@ -2619,6 +2619,11 @@ gnm_pane_object_start_resize (GnmPane *pane, int button, guint64 x, gint64 y,
 
 	g_return_if_fail (NULL != ctrl_pts);
 
+	if (is_creation && !sheet_object_can_resize (so)) {
+		scg_objects_drag_commit (pane->simple.scg, 9, TRUE,
+					 NULL, NULL, NULL);
+		return;
+	}
 	gnm_simple_canvas_grab (ctrl_pts [drag_type],
 		GDK_POINTER_MOTION_MASK |
 		GDK_BUTTON_PRESS_MASK |
@@ -3034,18 +3039,20 @@ gnm_pane_object_update_bbox (GnmPane *pane, SheetObject *so)
 
 	/* set the acetate 1st so that the other points will override it */
 	set_acetate_coords (pane, so, ctrl_pts, pts[0], pts[1], pts[2], pts[3]);
-	set_item_x_y (pane, so, ctrl_pts, 0, pts[0], pts[1], TRUE);
-	set_item_x_y (pane, so, ctrl_pts, 1, (pts[0] + pts[2]) / 2, pts[1],
-		      fabs (pts[2]-pts[0]) >= CTRL_PT_TOTAL_SIZE);
-	set_item_x_y (pane, so, ctrl_pts, 2, pts[2], pts[1], TRUE);
-	set_item_x_y (pane, so, ctrl_pts, 3, pts[0], (pts[1] + pts[3]) / 2,
-		      fabs (pts[3]-pts[1]) >= CTRL_PT_TOTAL_SIZE);
-	set_item_x_y (pane, so, ctrl_pts, 4, pts[2], (pts[1] + pts[3]) / 2,
-		      fabs (pts[3]-pts[1]) >= CTRL_PT_TOTAL_SIZE);
-	set_item_x_y (pane, so, ctrl_pts, 5, pts[0], pts[3], TRUE);
-	set_item_x_y (pane, so, ctrl_pts, 6, (pts[0] + pts[2]) / 2, pts[3],
-		      fabs (pts[2]-pts[0]) >= CTRL_PT_TOTAL_SIZE);
-	set_item_x_y (pane, so, ctrl_pts, 7, pts[2], pts[3], TRUE);
+	if (sheet_object_can_resize (so)) {
+		set_item_x_y (pane, so, ctrl_pts, 0, pts[0], pts[1], TRUE);
+		set_item_x_y (pane, so, ctrl_pts, 1, (pts[0] + pts[2]) / 2, pts[1],
+			      fabs (pts[2]-pts[0]) >= CTRL_PT_TOTAL_SIZE);
+		set_item_x_y (pane, so, ctrl_pts, 2, pts[2], pts[1], TRUE);
+		set_item_x_y (pane, so, ctrl_pts, 3, pts[0], (pts[1] + pts[3]) / 2,
+			      fabs (pts[3]-pts[1]) >= CTRL_PT_TOTAL_SIZE);
+		set_item_x_y (pane, so, ctrl_pts, 4, pts[2], (pts[1] + pts[3]) / 2,
+			      fabs (pts[3]-pts[1]) >= CTRL_PT_TOTAL_SIZE);
+		set_item_x_y (pane, so, ctrl_pts, 5, pts[0], pts[3], TRUE);
+		set_item_x_y (pane, so, ctrl_pts, 6, (pts[0] + pts[2]) / 2, pts[3],
+			      fabs (pts[2]-pts[0]) >= CTRL_PT_TOTAL_SIZE);
+		set_item_x_y (pane, so, ctrl_pts, 7, pts[2], pts[3], TRUE);
+	}
 }
 
 static void
diff --git a/src/libgnumeric.c b/src/libgnumeric.c
index 2b73586..3793c0d 100644
--- a/src/libgnumeric.c
+++ b/src/libgnumeric.c
@@ -253,6 +253,11 @@ call_gnome_vfs_init (void)
 void
 gnm_init (void)
 {
+	static gboolean inited = FALSE;
+	if (inited)
+		return;
+	inited = TRUE;
+
 	call_gnome_vfs_init ();
 
 	libgoffice_init ();
diff --git a/src/main-application.c b/src/main-application.c
index f1d2629..3d0d5c2 100644
--- a/src/main-application.c
+++ b/src/main-application.c
@@ -298,6 +298,7 @@ main (int argc, char const **argv)
 	GOIOContext *ioc;
 	WorkbookView *wbv;
 	GSList *wbcgs_to_kill = NULL;
+	GOCmdContext *cc;
 
 #ifdef G_OS_WIN32
 	gboolean has_console;
@@ -347,19 +348,19 @@ main (int argc, char const **argv)
 	gnm_init ();
 
 	if (with_gui) {
-		ioc = GO_IO_CONTEXT
-			(g_object_new (GO_TYPE_IO_CONTEXT_GTK,
+		cc = g_object_new (GO_TYPE_IO_CONTEXT_GTK,
 				       "show-splash", !gnumeric_no_splash,
 				       "show-warnings", !gnumeric_no_warnings,
-				       NULL));
+				       NULL);
+		ioc = GO_IO_CONTEXT (cc);
 		handle_paint_events ();
 		pathetic_qt_workaround ();
 	} else {
 		/* TODO: Make this inconsistency go away */
-		GOCmdContext *cc = cmd_context_stderr_new ();
+		cc = cmd_context_stderr_new ();
 		ioc = go_io_context_new (cc);
-		g_object_unref (cc);
 	}
+	go_component_set_command_context (cc);
 
 	if (func_state_file)
 		return gnm_dump_func_defs (func_state_file, 0);
diff --git a/src/sheet-control-gui.c b/src/sheet-control-gui.c
index ff30de9..440df48 100644
--- a/src/sheet-control-gui.c
+++ b/src/sheet-control-gui.c
@@ -2452,7 +2452,7 @@ scg_object_select (SheetControlGUI *scg, SheetObject *so)
 	}
 
 	coords = g_new (double, 4);
-	scg_object_anchor_to_coords (scg, sheet_object_get_anchor (so), coords);
+	scg_object_anchor_to_coords (scg, sheet_object_get_anchor (so), coords);	
 	g_hash_table_insert (scg->selected_objects, so, coords);
 	g_signal_connect_object (so, "unrealized",
 		G_CALLBACK (scg_mode_edit), scg, G_CONNECT_SWAPPED);
@@ -2714,6 +2714,13 @@ cb_collect_objects_to_commit (SheetObject *so, double *coords, CollectObjectsDat
 {
 	SheetObjectAnchor *anchor = sheet_object_anchor_dup (
 		sheet_object_get_anchor (so));
+	if (!sheet_object_can_resize (so)) {
+		sheet_object_default_size (so, coords + 2, coords + 3);
+		coords[2] *= gnm_app_display_dpi_get (TRUE) / 72;
+		coords[3] *= gnm_app_display_dpi_get (FALSE) / 72;
+		coords[2] += coords[0];
+		coords[3] += coords[1];
+	}
 	scg_object_coords_to_anchor (data->scg, coords, anchor);
 	data->objects = g_slist_prepend (data->objects, so);
 	data->anchors = g_slist_prepend (data->anchors, anchor);
diff --git a/src/sheet-object-component.c b/src/sheet-object-component.c
new file mode 100644
index 0000000..20b4029
--- /dev/null
+++ b/src/sheet-object-component.c
@@ -0,0 +1,345 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * sheet-object-component.c
+ *
+ * Copyright (C) 2008 Jean BrÃfort <jean brefort normalesup org>
+ *
+ * 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
+ */
+
+#include <gnumeric-config.h>
+#include "gnumeric.h"
+#include "application.h"
+#include "gnm-pane-impl.h"
+#include "gui-util.h"
+#include "sheet-control-gui.h"
+#include "sheet-object-component.h"
+#include "sheet-object-impl.h"
+#include "wbc-gtk.h"
+#include <goffice/goffice.h>
+#include <goffice/component/go-component.h>
+#include <gsf/gsf-impl-utils.h>
+#include <glib/gi18n-lib.h>
+
+
+static void
+so_component_view_set_bounds (SheetObjectView *sov, double const *coords, gboolean visible)
+{
+	GocItem *view = GOC_ITEM (GOC_GROUP (sov)->children->data);
+	double scale = goc_canvas_get_pixels_per_unit (view->canvas);
+
+	if (visible) {
+		GOComponent *component = sheet_object_component_get_component (sheet_object_view_get_so (sov));
+		double width, height;
+		goc_item_set (GOC_ITEM (sov),
+			"x", MIN (coords [0], coords[2]) / scale,
+			"y", MIN (coords [3], coords[1]) / scale,
+			NULL);
+		if (component && ! go_component_is_resizable (component)) {
+			go_component_get_size (component, &width, &height);
+			goc_item_set (view,
+				"width", width * gnm_app_display_dpi_get (TRUE),
+				"height", height * gnm_app_display_dpi_get (FALSE),
+				NULL);
+		} else
+			goc_item_set (view,
+				"width", (fabs (coords [2] - coords [0]) + 1.) / scale,
+				"height", (fabs (coords [3] - coords [1]) + 1.) / scale,
+				NULL);
+
+		goc_item_show (view);
+	} else
+		goc_item_hide (view);
+}
+
+typedef SheetObjectView		SOComponentGocView;
+typedef SheetObjectViewClass	SOComponentGocViewClass;
+
+static void
+so_component_goc_view_class_init (SheetObjectViewClass *sov_klass)
+{
+	sov_klass->set_bounds	= so_component_view_set_bounds;
+}
+
+static GSF_CLASS (SOComponentGocView, so_component_goc_view,
+	so_component_goc_view_class_init, NULL,
+	SHEET_OBJECT_VIEW_TYPE)
+
+
+/****************************************************************************/
+#define SHEET_OBJECT_CONFIG_KEY "sheet-object-component-key"
+
+#define SHEET_OBJECT_COMPONENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), SHEET_OBJECT_COMPONENT_TYPE, SheetObjectComponentClass))
+
+typedef struct {
+	SheetObject  base;
+	GOComponent	*component;
+	guint changed_signal;
+} SheetObjectComponent;
+typedef SheetObjectClass SheetObjectComponentClass;
+
+static GObjectClass *parent_klass;
+
+static void
+gnm_soc_finalize (GObject *obj)
+{
+	SheetObjectComponent *soc = SHEET_OBJECT_COMPONENT (obj);
+
+	g_object_unref (soc->component);
+
+	parent_klass->finalize (obj);
+}
+
+static SheetObjectView *
+gnm_soc_new_view (SheetObject *so, SheetObjectViewContainer *container)
+{
+	GnmPane *pane = GNM_PANE (container);
+	SheetObjectComponent *soc = SHEET_OBJECT_COMPONENT (so);
+	GocItem *view = goc_item_new (pane->object_views,
+		so_component_goc_view_get_type (),
+		NULL);
+	goc_item_hide (goc_item_new (GOC_GROUP (view),
+		      GOC_TYPE_COMPONENT,
+		      "object", soc->component,
+		      NULL));
+	return gnm_pane_object_register (so, view, TRUE);
+}
+
+static GtkTargetList *
+gnm_soc_get_target_list (SheetObject const *so)
+{
+	GtkTargetList *tl = gtk_target_list_new (NULL, 0);
+	return tl;
+}
+
+static GtkTargetList *
+gnm_soc_get_object_target_list (SheetObject const *so)
+{
+	GtkTargetList *tl = gtk_target_list_new (NULL, 0);
+	return tl;
+}
+
+static void
+gnm_soc_write_image (SheetObject const *so, char const *format, double resolution,
+		     GsfOutput *output, GError **err)
+{
+}
+
+static void
+soc_cb_save_as (SheetObject *so, SheetControl *sc)
+{
+}
+
+static void
+gnm_soc_populate_menu (SheetObject *so, GPtrArray *actions)
+{
+	static SheetObjectAction const soc_actions[] = {
+		{ GTK_STOCK_SAVE_AS, N_("_Save as Image"), NULL, 0, soc_cb_save_as }
+	};
+
+	unsigned int i;
+
+	SHEET_OBJECT_CLASS (parent_klass)->populate_menu (so, actions);
+
+	for (i = 0; i < G_N_ELEMENTS (soc_actions); i++)
+		go_ptr_array_insert (actions, (gpointer) (soc_actions + i), 1 + i);
+}
+
+static void
+gnm_soc_write_object (SheetObject const *so, char const *format,
+		      GsfOutput *output, GError **err,
+		      GnmConventions const *convs)
+{
+}
+
+static void
+gnm_soc_write_xml_sax (SheetObject const *so, GsfXMLOut *output,
+		       GnmConventions const *convs)
+{
+	SheetObjectComponent const *soc = SHEET_OBJECT_COMPONENT (so);
+	go_component_write_xml_sax (soc->component, output);
+}
+
+static void
+soc_xml_finish (GOComponent *component, SheetObject *so)
+{
+	sheet_object_component_set_component (so, component);
+}
+
+static void
+gnm_soc_prep_sax_parser (SheetObject *so, GsfXMLIn *xin, xmlChar const **attrs,
+			 GnmConventions const *convs)
+{
+	go_component_sax_push_parser (xin, attrs,
+				    (GOComponentSaxHandler) soc_xml_finish, so);
+}
+
+static void
+gnm_soc_copy (SheetObject *dst, SheetObject const *src)
+{
+}
+
+static void
+gnm_soc_default_size (SheetObject const *so, double *w, double *h)
+{
+	SheetObjectComponent const *soc = SHEET_OBJECT_COMPONENT (so);
+	if (soc->component && !go_component_is_resizable (soc->component)) {
+		go_component_get_size (soc->component, w, h);
+		*w = GO_IN_TO_PT (*w);
+		*h = GO_IN_TO_PT (*h);
+	} else {
+		*w = GO_CM_TO_PT ((double)5);
+		*h = GO_CM_TO_PT ((double)5);
+	}
+}
+
+static void
+gnm_soc_user_config (SheetObject *so, SheetControl *sc)
+{
+	SheetObjectComponent *soc = SHEET_OBJECT_COMPONENT (so);
+	GtkWidget *w;
+	g_return_if_fail (soc && soc->component);
+
+	w = (GtkWidget *) go_component_edit (soc->component);
+	if (w)
+		wbc_gtk_attach_guru (scg_wbcg (SHEET_CONTROL_GUI (sc)), w);
+}
+
+static void
+gnm_soc_draw_cairo (SheetObject const *so, cairo_t *cr,
+			  double width, double height)
+{
+	SheetObjectComponent *soc = SHEET_OBJECT_COMPONENT (so);
+	g_return_if_fail (soc && soc->component);
+
+	go_component_render (soc->component, cr, width, height);
+}
+
+static void
+gnm_soc_class_init (GObjectClass *klass)
+{
+	SheetObjectClass	*so_class  = SHEET_OBJECT_CLASS (klass);
+
+	parent_klass = g_type_class_peek_parent (klass);
+
+	/* Object class method overrides */
+	klass->finalize = gnm_soc_finalize;
+
+	/* SheetObject class method overrides */
+	so_class->new_view		= gnm_soc_new_view;
+	so_class->populate_menu		= gnm_soc_populate_menu;
+	so_class->write_xml_sax		= gnm_soc_write_xml_sax;
+	so_class->prep_sax_parser	= gnm_soc_prep_sax_parser;
+	so_class->copy			= gnm_soc_copy;
+	so_class->user_config		= gnm_soc_user_config;
+	so_class->default_size		= gnm_soc_default_size;
+	so_class->draw_cairo		= gnm_soc_draw_cairo;
+
+	so_class->rubber_band_directly = FALSE;
+}
+
+static void
+gnm_soc_init (GObject *obj)
+{
+	SheetObject *so = SHEET_OBJECT (obj);
+	so->anchor.base.direction = GOD_ANCHOR_DIR_DOWN_RIGHT;
+}
+
+static void
+soc_imageable_init (SheetObjectImageableIface *soi_iface)
+{
+	soi_iface->get_target_list = gnm_soc_get_target_list;
+	soi_iface->write_image	   = gnm_soc_write_image;
+}
+
+static void
+soc_exportable_init (SheetObjectExportableIface *soe_iface)
+{
+	soe_iface->get_target_list = gnm_soc_get_object_target_list;
+	soe_iface->write_object	   = gnm_soc_write_object;
+}
+
+GSF_CLASS_FULL (SheetObjectComponent, sheet_object_component,
+		NULL, NULL, gnm_soc_class_init,NULL,
+		gnm_soc_init, SHEET_OBJECT_TYPE, 0,
+		GSF_INTERFACE (soc_imageable_init, SHEET_OBJECT_IMAGEABLE_TYPE) \
+		GSF_INTERFACE (soc_exportable_init, SHEET_OBJECT_EXPORTABLE_TYPE));
+
+/**
+ * sheet_object_component_new :
+ **/
+SheetObject *
+sheet_object_component_new (GOComponent *component)
+{
+	SheetObjectComponent *soc = g_object_new (SHEET_OBJECT_COMPONENT_TYPE, NULL);
+	sheet_object_component_set_component (SHEET_OBJECT (soc), component);
+	return SHEET_OBJECT (soc);
+}
+
+void
+sheet_object_component_edit (WBCGtk *wbcg, GOComponent *component, GClosure *closure)
+{
+}
+
+GOComponent*
+sheet_object_component_get_component (SheetObject *soc)
+{
+	g_return_val_if_fail (IS_SHEET_OBJECT_COMPONENT (soc), NULL);
+
+	return ((SheetObjectComponent *) soc)->component;
+}
+
+static void
+component_changed_cb (SheetObject *so)
+{
+	if (!(so->flags & SHEET_OBJECT_CAN_RESIZE)) {
+		GList *l = so->realized_list;
+		double coords[4];
+		g_object_get (l->data, "x", coords, "y", coords + 1, NULL);
+		coords[2] = coords[3] = G_MAXDOUBLE;
+		for (l = so->realized_list; l; l = l->next) {
+			if (l->data)
+				sheet_object_view_set_bounds (l->data, coords, so->flags & SHEET_OBJECT_IS_VISIBLE);
+		}
+		sheet_object_update_bounds (so, NULL);
+	}
+}
+
+void
+sheet_object_component_set_component (SheetObject *so, GOComponent *component)
+{
+	SheetObjectComponent *soc;
+
+	g_return_if_fail (IS_SHEET_OBJECT_COMPONENT (so));
+	soc = SHEET_OBJECT_COMPONENT (so);
+	if (soc->component != NULL) {
+		g_signal_handler_disconnect (soc->component, soc->changed_signal);
+		g_object_unref (soc->component);
+	}
+
+	soc->component = component;
+	if (component) {
+		if (go_component_is_resizable (component))
+			so->flags |= SHEET_OBJECT_CAN_RESIZE;
+		else
+			so->flags &= ~SHEET_OBJECT_CAN_RESIZE;
+		if (go_component_is_editable (component))
+			so->flags |= SHEET_OBJECT_CAN_EDIT;
+		else
+			so->flags &= ~SHEET_OBJECT_CAN_EDIT;
+		g_signal_connect_swapped (soc->component, "changed", G_CALLBACK (component_changed_cb), soc);
+	}
+}
diff --git a/src/sheet-object-component.h b/src/sheet-object-component.h
new file mode 100644
index 0000000..56a5a3a
--- /dev/null
+++ b/src/sheet-object-component.h
@@ -0,0 +1,45 @@
+/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * sheet-object-component.h
+ *
+ * Copyright (C) 2009 Jean BrÃfort <jean brefort normalesup org>
+ *
+ * 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
+ */
+
+#ifndef _GNM_SHEET_OBJECT_COMPONENT_H_
+#define _GNM_SHEET_OBJECT_COMPONENT_H_
+
+#include "sheet-object.h"
+#include "gui-gnumeric.h"
+#include <goffice/component/go-component.h>
+
+G_BEGIN_DECLS
+
+#define SHEET_OBJECT_COMPONENT_TYPE  (sheet_object_component_get_type ())
+#define IS_SHEET_OBJECT_COMPONENT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SHEET_OBJECT_COMPONENT_TYPE))
+#define SHEET_OBJECT_COMPONENT(o)	 (G_TYPE_CHECK_INSTANCE_CAST((o), SHEET_OBJECT_COMPONENT_TYPE, SheetObjectComponent))
+
+GType	     sheet_object_component_get_type (void);
+SheetObject *sheet_object_component_new  (GOComponent *component);
+
+void	     sheet_object_component_edit (WBCGtk *wbcg, GOComponent *component, GClosure *closure);
+GOComponent *sheet_object_component_get_component (SheetObject *soc);
+void	     sheet_object_component_set_component (SheetObject *soc, GOComponent *component);
+
+G_END_DECLS
+
+#endif	/* _GNM_SHEET_OBJECT_COMPONENT_H_ */
diff --git a/src/sheet-object-impl.h b/src/sheet-object-impl.h
index 3c32b58..12b2704 100644
--- a/src/sheet-object-impl.h
+++ b/src/sheet-object-impl.h
@@ -15,6 +15,8 @@ typedef enum {
 	SHEET_OBJECT_IS_VISIBLE	= 1 << 0,	/* user selectable */
 	SHEET_OBJECT_PRINT	= 1 << 1,
 	SHEET_OBJECT_CAN_PRESS	= 1 << 2,
+	SHEET_OBJECT_CAN_RESIZE	= 1 << 3,
+	SHEET_OBJECT_CAN_EDIT	= 1 << 4,
 
 	/* Gnumeric specific properties */
 	SHEET_OBJECT_MOVE_WITH_CELLS	= 1 << 16,
diff --git a/src/sheet-object.c b/src/sheet-object.c
index a9a4ba3..4f02f1c 100644
--- a/src/sheet-object.c
+++ b/src/sheet-object.c
@@ -192,7 +192,7 @@ sheet_object_populate_menu_real (SheetObject *so, GPtrArray *actions)
 			{ "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++)
+		for (i = sheet_object_can_edit (so)? 0: 1 ; 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));
 	}
@@ -306,6 +306,7 @@ sheet_object_init (GObject *object)
 
 	so->sheet = NULL;
 	so->flags = SHEET_OBJECT_IS_VISIBLE | SHEET_OBJECT_PRINT |
+		SHEET_OBJECT_CAN_RESIZE | SHEET_OBJECT_CAN_EDIT |
 		SHEET_OBJECT_MOVE_WITH_CELLS | SHEET_OBJECT_SIZE_WITH_CELLS;
 
 	/* Store the logical position as A1 */
@@ -642,6 +643,20 @@ sheet_object_can_print (SheetObject const *so)
 		SO_CLASS (so)->draw_cairo != NULL;
 }
 
+gboolean
+sheet_object_can_resize (SheetObject const *so)
+{
+	g_return_val_if_fail (IS_SHEET_OBJECT (so), FALSE);
+	return  so->flags & SHEET_OBJECT_CAN_RESIZE;
+}
+
+gboolean
+sheet_object_can_edit (SheetObject const *so)
+{
+	g_return_val_if_fail (IS_SHEET_OBJECT (so), FALSE);
+	return  so->flags & SHEET_OBJECT_CAN_EDIT;
+}
+
 /**
  * sheet_object_draw_cairo :
  *
@@ -661,12 +676,6 @@ sheet_object_draw_cairo (SheetObject const *so, cairo_t *cr, gboolean rtl)
 		SheetObjectAnchor const *anchor;
 		double x = 0., y = 0., width, height, cell_width, cell_height;
 		anchor = sheet_object_get_anchor (so);
-		width = sheet_col_get_distance_pts (so->sheet,
-					anchor->cell_bound.start.col,
-					anchor->cell_bound.end.col + 1);
-		height = sheet_row_get_distance_pts (so->sheet,
-					anchor->cell_bound.start.row,
-					anchor->cell_bound.end.row + 1);
 		cell_width = sheet_col_get_distance_pts (so->sheet,
 					anchor->cell_bound.start.col,
 					anchor->cell_bound.start.col + 1);
@@ -674,22 +683,31 @@ sheet_object_draw_cairo (SheetObject const *so, cairo_t *cr, gboolean rtl)
 					anchor->cell_bound.start.row,
 					anchor->cell_bound.start.row + 1);
 		x = cell_width * anchor->offset[0];
-		width -= x;
 
 		y = cell_height * anchor->offset[1];
-		height -= y;
 		cell_width = sheet_col_get_distance_pts (so->sheet,
 					anchor->cell_bound.end.col,
 					anchor->cell_bound.end.col + 1);
 		cell_height = sheet_row_get_distance_pts (so->sheet,
 					anchor->cell_bound.end.row,
 					anchor->cell_bound.end.row + 1);
-		width -= cell_width * (1. - anchor->offset[2]);
-		height -= cell_height * (1 - anchor->offset[3]);
 
 		if (rtl) {
 			x = cell_width * (1 - anchor->offset[2]);
 		}
+		if (sheet_object_can_resize (so)) {
+			width = sheet_col_get_distance_pts (so->sheet,
+						anchor->cell_bound.start.col,
+						anchor->cell_bound.end.col + 1);
+			height = sheet_row_get_distance_pts (so->sheet,
+						anchor->cell_bound.start.row,
+						anchor->cell_bound.end.row + 1);
+			width -= x;
+			height -= y;
+			width -= cell_width * (1. - anchor->offset[2]);
+			height -= cell_height * (1 - anchor->offset[3]);
+		} else
+			sheet_object_default_size ((SheetObject *) so, &width, &height);
 
 		/* we don't need to save/restore cairo, the caller must do it */
 		cairo_translate (cr, x, y);
diff --git a/src/sheet-object.h b/src/sheet-object.h
index 42556a7..cc11e6d 100644
--- a/src/sheet-object.h
+++ b/src/sheet-object.h
@@ -70,6 +70,8 @@ void          sheet_object_set_print_flag (SheetObject *so, gboolean *print);
 
 SheetObject  *sheet_object_dup		 (SheetObject const *so);
 gboolean      sheet_object_can_print	 (SheetObject const *so);
+gboolean      sheet_object_can_resize	 (SheetObject const *so);
+gboolean      sheet_object_can_edit	 (SheetObject const *so);
 
 void	     sheet_object_get_editor	 (SheetObject *so, SheetControl *sc);
 void	     sheet_object_populate_menu  (SheetObject *so, GPtrArray *actions);
diff --git a/src/wbc-gtk-actions.c b/src/wbc-gtk-actions.c
index 8ffd398..42b9864 100644
--- a/src/wbc-gtk-actions.c
+++ b/src/wbc-gtk-actions.c
@@ -58,6 +58,7 @@
 #include "gnm-so-filled.h"
 #include "gnm-so-line.h"
 #include "sheet-object-graph.h"
+#include "sheet-object-component.h"
 #include "gui-util.h"
 #include "gui-file.h"
 #include "gnumeric-gconf.h"
@@ -67,6 +68,7 @@
 #include "gnm-pane-impl.h"
 
 #include <goffice/goffice.h>
+#include <goffice/component/goffice-component.h>
 
 #include "widgets/widget-editable-label.h"
 #include <gtk/gtk.h>
@@ -1387,6 +1389,72 @@ static GNM_ACTION_DEF (cb_launch_chart_guru)
 }
 
 static void
+cb_add_component_new (GOComponent *component, gpointer wbcg)
+{
+	wbcg_insert_object (WBC_GTK (wbcg), sheet_object_component_new (component));
+}
+
+static void
+cb_add_component_from_file (GOComponent *component, gpointer wbcg)
+{
+	wbcg_insert_object (WBC_GTK (wbcg), sheet_object_component_new (component));
+}
+
+static gboolean
+button_press_cb (GtkDialog *dlg, GdkEventButton *ev)
+{
+	if (ev->type == GDK_2BUTTON_PRESS)
+		gtk_dialog_response (dlg, GTK_RESPONSE_OK);
+	return FALSE;
+}
+
+static void
+component_changed_cb (GOComponent *component, gpointer data)
+{
+	cb_add_component_new (component, data);
+}
+
+static GNM_ACTION_DEF (cb_launch_go_component_new)
+{
+	gchar const *mime_type;
+	gint result;
+	GtkWidget *dialog = go_component_mime_dialog_new ();
+	result = gtk_dialog_run (GTK_DIALOG (dialog));
+	if (result == GTK_RESPONSE_OK) {
+		mime_type = go_component_mime_dialog_get_mime_type ((GOComponentMimeDialog *) dialog);
+		if (mime_type) {
+			GtkWindow *win;
+			GOComponent *component = go_component_new_by_mime_type (mime_type);
+			if (component) {
+				g_signal_connect (G_OBJECT (component), "changed", G_CALLBACK (component_changed_cb), wbcg);
+				win = go_component_edit (component);
+				gtk_window_set_transient_for (win, GTK_WINDOW (wbcg_toplevel (wbcg)));
+			}
+		}
+	}
+	gtk_widget_destroy (dialog);
+}
+
+static GNM_ACTION_DEF (cb_launch_go_component_from_file)
+{
+	GtkWidget *dlg = gtk_file_chooser_dialog_new (_("Choose object file"),
+	                                              GTK_WINDOW (wbcg_toplevel (wbcg)),
+	                                              GTK_FILE_CHOOSER_ACTION_OPEN,
+	                                              GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+	                                              GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+	                                              NULL);
+	go_components_add_filter (GTK_FILE_CHOOSER (dlg));
+	if (gtk_dialog_run (GTK_DIALOG (dlg)) == GTK_RESPONSE_ACCEPT) {
+		char *uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dlg));
+		GOComponent *component = go_component_new_from_uri (uri);
+		g_free (uri);
+		if (component)
+			wbcg_insert_object (WBC_GTK (wbcg), sheet_object_component_new (component));
+	}
+	gtk_widget_destroy (dlg);
+}
+
+static void
 create_object (WBCGtk *wbcg, GType t,
 	       char const *first_property_name,
 	       ...)
@@ -1903,6 +1971,13 @@ static GNM_ACTION_DEF (cb_file_menu)
 	wbc_gtk_load_templates (wbcg);
 }
 
+static GNM_ACTION_DEF (cb_insert_menu)
+{
+	GtkAction *action = gtk_action_group_get_action (wbcg->permanent_actions, "MenuInsertObject");
+	SheetControlGUI	*scg = wbcg_cur_scg (wbcg);
+	gtk_action_set_sensitive (action, go_components_get_mime_types () != NULL && scg && scg_sheet (scg)->sheet_type == GNM_SHEET_DATA);
+}
+
 /* Actions that are always sensitive */
 static GtkActionEntry const permanent_actions[] = {
 	{ "MenuFile",		NULL, N_("_File"), NULL, NULL, G_CALLBACK (cb_file_menu) },
@@ -1917,7 +1992,9 @@ static GtkActionEntry const permanent_actions[] = {
 	{ "MenuView",		NULL, N_("_View") },
 		{ "MenuViewWindows",		NULL, N_("_Windows") },
 		{ "MenuViewToolbars",		NULL, N_("_Toolbars") },
-	{ "MenuInsert",		NULL, N_("_Insert") },
+	{ "MenuInsert",		NULL, N_("_Insert"), NULL, NULL, G_CALLBACK (cb_insert_menu)  },
+		{ "MenuInsertObject",		NULL, N_("_Object") },
+		{ "MenuInsertNames",		NULL, N_("_Names") },
 		{ "MenuInsertSpecial",		NULL, N_("S_pecial") },
 		{ "MenuInsertFormulaWrap", "Gnumeric_FormulaGuru",
 		  N_("Func_tion Wrapper") },
@@ -2265,6 +2342,12 @@ static GtkActionEntry const actions[] = {
 	{ "ChartGuru", "Gnumeric_GraphGuru", N_("C_hart..."),
 		NULL, N_("Insert a Chart"),
 		G_CALLBACK (cb_launch_chart_guru) },
+	{ "NewGOComponent", "New Goffice_Component", N_("_New..."),
+		NULL, N_("Insert a new Goffice component object"),
+		G_CALLBACK (cb_launch_go_component_new) },
+	{ "GOComponentFromFile", "New Goffice_Component from a file", N_("_From file..."),
+		NULL, N_("Insert a new Goffice component object from a file"),
+		G_CALLBACK (cb_launch_go_component_from_file) },
 	{ "InsertImage", "Gnumeric_InsertImage", N_("_Image..."),
 		NULL, N_("Insert an image"),
 		G_CALLBACK (cb_insert_image) },
diff --git a/src/wbc-gtk.c b/src/wbc-gtk.c
index 570bd9b..7f08d9f 100644
--- a/src/wbc-gtk.c
+++ b/src/wbc-gtk.c
@@ -1954,8 +1954,13 @@ wbc_gtk_close (WBCGtk *wbcg)
 		g_return_val_if_fail (wb->wb_views != NULL, TRUE);
 
 		/* This is the last view */
-		if (wb->wb_views->len <= 1)
-			return wbcg_close_if_user_permits (wbcg, wb_view, TRUE, FALSE, TRUE) == 0;
+		if (wb->wb_views->len <= 1) {
+			if (wbcg_close_if_user_permits (wbcg, wb_view, TRUE, FALSE, TRUE) == 0)
+				return TRUE;
+			if (G_IS_OBJECT (wbcg)) /* the wbcg might be unrefd */
+				g_object_unref (G_OBJECT (wbcg));
+			return FALSE;
+		}
 
 		g_object_unref (G_OBJECT (wb_view));
 	} else
diff --git a/src/xml-sax-read.c b/src/xml-sax-read.c
index 8076032..6b3aac5 100644
--- a/src/xml-sax-read.c
+++ b/src/xml-sax-read.c
@@ -58,6 +58,7 @@
 #include "gnm-so-filled.h"
 #include "gnm-format.h"
 #include "sheet-object-graph.h"
+#include "sheet-object-component.h"
 #include "application.h"
 #include "gutils.h"
 #include "clipboard.h"
@@ -2304,6 +2305,8 @@ xml_sax_read_obj (GsfXMLIn *xin, gboolean needs_cleanup,
 		so = g_object_new (GNM_SO_FILLED_TYPE, NULL);
 	else if (!strcmp (type_name, "SheetObjectText"))
 		so = g_object_new (GNM_SO_FILLED_TYPE, NULL);
+	else if (!strcmp (type_name, "SheetObjectComponent"))
+		so = sheet_object_component_new (NULL);
 
 	else {
 		GType type = g_type_from_name (type_name);
@@ -3021,7 +3024,8 @@ GSF_XML_IN_NODE_FULL (START, WB, GNM, "Workbook", GSF_XML_NO_CONTENT, TRUE, TRUE
 	GSF_XML_IN_NODE (SHEET_OBJECTS, OBJECT_OLD_TEXT, GNM, "SheetObjectText", GSF_XML_NO_CONTENT,	&xml_sax_object_start, &xml_sax_object_end),
 	GSF_XML_IN_NODE (SHEET_OBJECTS, OBJECT_GRAPH, GNM, "SheetObjectGraph", GSF_XML_NO_CONTENT,	&xml_sax_object_start, &xml_sax_object_end),
 	GSF_XML_IN_NODE (SHEET_OBJECTS, OBJECT_IMAGE, GNM, "SheetObjectImage", GSF_XML_NO_CONTENT,	&xml_sax_object_start, &xml_sax_object_end),
-
+	GSF_XML_IN_NODE (SHEET_OBJECTS, OBJECT_COMPONENT, GNM, "SheetObjectComponent", GSF_XML_NO_CONTENT, &xml_sax_object_start, &xml_sax_object_end),
+	
   GSF_XML_IN_NODE (WB, WB_GEOMETRY, GNM, "Geometry", GSF_XML_NO_CONTENT, &xml_sax_wb_view, NULL),
   GSF_XML_IN_NODE (WB, WB_VIEW, GNM, "UIData", GSF_XML_NO_CONTENT, &xml_sax_wb_view, NULL),
   GSF_XML_IN_NODE (WB, WB_CALC, GNM, "Calculation", GSF_XML_NO_CONTENT, &xml_sax_calculation, NULL),



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