sheet-object-bonobo.c 10.6 KB
Newer Older
1
/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 3 4 5 6 7 8
/*
 * sheet-object-container.c:
 *   SheetObject abstract class for Bonobo-based embeddings
 *
 *   See sheet-object-container.c for Gnome::View based embeddings
 *   See sheet-object-item.c for Gnome::Canvas based embeddings
 *
Michael Meeks's avatar
Michael Meeks committed
9
 * Authors:
10 11 12 13 14 15 16
 *   Miguel de Icaza (miguel@kernel.org)
 *   Michael Meeks (mmeeks@gnu.org)
 *
 * TODO:
 *
 *    Perhaps we should relay "realize" and get from the Bonobo
 *    versions both the GnomeCanvasItem to use for the gnumeric
17
 *    display and the BonoboViewFrame that logically "controls" this
18 19
 *    to keep track of the view frames.
 */
20
#include <gnumeric-config.h>
21
#include "gnumeric.h"
22 23
#include "sheet-object-bonobo.h"

24
#include "workbook.h"
25
#include "sheet.h"
26
#include "workbook-private.h"
27
#include "gui-util.h"
28

29 30
#include <math.h>
#include <gdk/gdkkeysyms.h>
4's avatar
4 committed
31
#include <bonobo/bonobo-item-container.h>
32 33
#include <bonobo/bonobo-stream-memory.h>

34
#include <gal/util/e-util.h>
35

36
static SheetObjectClass *sheet_object_bonobo_parent_class;
37

38
#define SOB_CLASS(o) SHEET_OBJECT_CLASS (G_OBJECT_GET_CLASS (o))
39 40 41 42 43

static void
sheet_object_bonobo_destroy (GtkObject *object)
{
	SheetObjectBonobo *sob = SHEET_OBJECT_BONOBO (object);
44

Jody Goldberg's avatar
Jody Goldberg committed
45 46 47
	if (sob->control_frame != NULL) {
		bonobo_object_unref (BONOBO_OBJECT (sob->control_frame));
		sob->control_frame = NULL;
Jody Goldberg's avatar
Jody Goldberg committed
48
	}
49

50 51 52
	if (sob->object_server != CORBA_OBJECT_NIL) {
		bonobo_object_release_unref (sob->object_server, NULL);
		sob->object_server = CORBA_OBJECT_NIL;
Jody Goldberg's avatar
Jody Goldberg committed
53
	}
54

Jody Goldberg's avatar
Jody Goldberg committed
55 56 57 58 59 60 61
	if (sob->object_id != NULL) {
		g_free (sob->object_id);
		sob->object_id = NULL;
	}

	/* Call parent's destroy method */
	GTK_OBJECT_CLASS (sheet_object_bonobo_parent_class)->destroy (object);
62 63 64 65 66 67
}

static char *
get_file_name (void)
{
	GtkFileSelection *fs;
68 69
	char *filename;
	char *basename;
70

71
	fs = GTK_FILE_SELECTION (gtk_file_selection_new ("Select filename"));
72

Jody Goldberg's avatar
Jody Goldberg committed
73 74 75 76 77 78
        g_signal_connect (G_OBJECT (fs->ok_button),
		"clicked",
		G_CALLBACK (gtk_main_quit), NULL);
        g_signal_connect (G_OBJECT (fs->cancel_button),
		"clicked",
		G_CALLBACK (gtk_main_quit), NULL);
79 80 81

	gtk_widget_show (GTK_WIDGET (fs));
	gtk_main ();
82 83 84 85 86 87 88 89

        filename = gtk_file_selection_get_filename (fs);

	if (!(basename = g_basename (filename)) ||
	    basename [0] == '\0')
		filename = NULL;
	else
		filename = g_strdup (filename);
90 91 92 93 94 95

	gtk_object_destroy (GTK_OBJECT (fs));

	return filename;
}

96 97
void
sheet_object_bonobo_load_persist_file (SheetObjectBonobo *sob,
Jody Goldberg's avatar
Jody Goldberg committed
98
				       const char *fname,
99
				       CORBA_Environment *ev)
100
{
101
	Bonobo_PersistFile pf;
102

103 104
	g_return_if_fail (IS_SHEET_OBJECT_BONOBO (sob));
	g_return_if_fail (sob->has_persist_file);
105

106 107 108
	pf = Bonobo_Unknown_queryInterface (
		sob->object_server, "IDL:Bonobo/PersistFile:1.0", ev);

109 110 111
	if (!BONOBO_EX (ev)) {
		Bonobo_PersistFile_load (pf, fname, ev);
		bonobo_object_release_unref (pf, NULL);
112 113 114
	}
}

115 116 117 118
void
sheet_object_bonobo_load_persist_stream (SheetObjectBonobo *sob,
				         BonoboStream      *stream,
					 CORBA_Environment *ev)
119
{
120
	Bonobo_PersistStream ps;
121

122 123 124
	bonobo_return_if_fail (IS_SHEET_OBJECT_BONOBO (sob), ev);
	g_return_if_fail (sob->has_persist_stream);

125 126 127
	ps = Bonobo_Unknown_queryInterface (
		sob->object_server, "IDL:Bonobo/PersistStream:1.0", ev);

128 129 130 131
	if (!BONOBO_EX (ev)) {
		Bonobo_PersistStream_load (ps,
			(Bonobo_Stream) BONOBO_OBJREF (stream), "", ev);
		bonobo_object_release_unref (ps, NULL);
132 133 134
	}
}

135 136 137 138 139 140 141 142 143 144
void
sheet_object_bonobo_save_persist_stream (SheetObjectBonobo const *sob,
				         BonoboStream      *stream,
					 CORBA_Environment *ev)
{
	Bonobo_PersistStream ps;

	bonobo_return_if_fail (IS_SHEET_OBJECT_BONOBO (sob), ev);
	g_return_if_fail (sob->has_persist_stream);

145 146 147
	ps = Bonobo_Unknown_queryInterface (
		sob->object_server, "IDL:Bonobo/PersistStream:1.0", ev);

148 149 150 151 152 153 154
	if (!BONOBO_EX (ev)) {
		Bonobo_PersistStream_save (ps,
			(Bonobo_Stream) BONOBO_OBJREF (stream), "", ev);
		bonobo_object_release_unref (ps, NULL);
	}
}

155
static void
156 157
sheet_object_bonobo_print (SheetObject const *so, GnomePrintContext *ctx,
			   double base_x, double base_y)
158
{
159
	SheetObjectBonobo const *sob;
160
	BonoboPrintClient *bpc;
161 162
	BonoboPrintData *bpd;
	double coords [4];
163

164 165
	sob = SHEET_OBJECT_BONOBO (so);
	g_return_if_fail (sob != NULL);
166
	g_return_if_fail (GNOME_IS_PRINT_CONTEXT (ctx));
167 168


169 170 171 172 173 174 175 176 177
	bpc = bonobo_print_client_get (sob->object_server);
	if (!bpc) {
		static gboolean warned = FALSE;
		if (!warned)
			g_warning ("Some bonobo objects are not printable");
		warned = TRUE;
		return;
	}

178
	sheet_object_position_pts_get (so, coords);
179 180 181 182 183
	bpd = bonobo_print_data_new ((coords [2] - coords [0]),
				     (coords [3] - coords [1]));
	bonobo_print_client_render (bpc, bpd);
	bonobo_print_data_render (ctx, base_x, base_y, bpd, 0.0, 0.0);
	bonobo_print_data_free (bpd);
184
}
Michael Meeks's avatar
Michael Meeks committed
185

186
void
Jody Goldberg's avatar
Jody Goldberg committed
187
sheet_object_bonobo_load_file (SheetObjectBonobo *sob, const gchar *fname,
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
		               CORBA_Environment *ev)
{
	BonoboStream *stream;

	bonobo_return_if_fail (IS_SHEET_OBJECT_BONOBO (sob), ev);
	g_return_if_fail (sob->has_persist_file || sob->has_persist_stream);

	if (sob->has_persist_file)
		sheet_object_bonobo_load_persist_file (sob, fname, ev);
	else {
		stream = bonobo_stream_open ("fs", fname,
					     Bonobo_Storage_READ, 0);
		sheet_object_bonobo_load_persist_stream (sob, stream, ev);
		bonobo_object_unref (BONOBO_OBJECT (stream));
	}
}

Michael Meeks's avatar
Michael Meeks committed
205
static void
206
open_cb (GtkMenuItem *item, SheetObjectBonobo *sob)
Michael Meeks's avatar
Michael Meeks committed
207
{
208 209 210 211 212
	gchar *filename;
	CORBA_Environment ev;

	g_return_if_fail (sob->has_persist_file || sob->has_persist_stream);

Jody Goldberg's avatar
Jody Goldberg committed
213 214 215 216
	filename = get_file_name ();
	if (filename == NULL)
		return;

217 218 219 220 221 222 223 224 225 226
	CORBA_exception_init (&ev);

	sheet_object_bonobo_load_file (sob, filename, &ev);
	g_free (filename);
	if (BONOBO_EX (&ev)) {
		g_warning ("Could not open: %s",
			   bonobo_exception_get_text (&ev));
	}

	CORBA_exception_free (&ev);
Michael Meeks's avatar
Michael Meeks committed
227 228 229
}

static void
230 231 232
sheet_object_bonobo_populate_menu (SheetObject *so,
			           GtkObject   *obj_view,
			           GtkMenu     *menu)
Michael Meeks's avatar
Michael Meeks committed
233
{
234 235
	SheetObjectBonobo *sob;
	GtkWidget *item;
Michael Meeks's avatar
Michael Meeks committed
236

237
	sob = SHEET_OBJECT_BONOBO (so);
238 239
	g_return_if_fail (sob != NULL);

240
	if (sob->has_persist_file || sob->has_persist_stream) {
Jody Goldberg's avatar
Jody Goldberg committed
241
		item = gtk_menu_item_new_with_label (_("Open..."));
Jody Goldberg's avatar
Jody Goldberg committed
242 243 244
		g_signal_connect (G_OBJECT (item),
			"activate",
			G_CALLBACK (open_cb), so);
245 246
		gtk_menu_append (menu, item);
	}
Michael Meeks's avatar
Michael Meeks committed
247 248

	if (sheet_object_bonobo_parent_class->populate_menu)
249
		sheet_object_bonobo_parent_class->populate_menu (so, obj_view, menu);
Michael Meeks's avatar
Michael Meeks committed
250
}
251

252 253 254 255
static gboolean
sheet_object_bonobo_read_xml (SheetObject *so,
			      XmlParseContext const *ctxt, xmlNodePtr	tree)
{
256 257 258 259 260 261 262 263 264 265 266 267
	/* Leave crufty old bonobo-io override in place until we have something
	 * better
	 */
	if (ctxt->read_fn != NULL)
		return ctxt->read_fn (tree, so, ctxt->sheet, ctxt->user_data);

#if 0
	BonoboStream *stream;
	stream = bonobo_stream_mem_create (data, len, TRUE, FALSE);
	sheet_object_bonobo_load_persist_stream (sob);
	bonobo_object_unref (BONOBO_OBJECT (stream));
#endif
268

269
	return FALSE;
270 271 272 273 274 275
}

static gboolean
sheet_object_bonobo_write_xml (SheetObject const *so,
			       XmlParseContext const *ctxt, xmlNodePtr tree)
{
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
	SheetObjectBonobo const *sob = SHEET_OBJECT_BONOBO (so);
	BonoboStream *stream = NULL;
	gboolean res = FALSE;

	if (ctxt->write_fn != NULL)
		return ctxt->write_fn (tree, so, ctxt->user_data);

	if (sob->has_persist_stream) {
		CORBA_Environment ev;

		stream = bonobo_stream_mem_create (NULL, 0, FALSE, TRUE);

		CORBA_exception_init (&ev);
		sheet_object_bonobo_save_persist_stream (sob, stream, &ev);
		if (BONOBO_EX (&ev)) {
			/* TODO : Generate a decent message when sheetobjects
			 * get user visible ids */
			gnumeric_io_error_save (ctxt->io_context,
				   bonobo_exception_get_text (&ev));
		} else
			res = TRUE;

		CORBA_exception_free (&ev);
	} else if (sob->has_persist_file) {
		/* Copy approach from gnum_file_saver_save_to_stream_real. */
301
	}
302 303 304 305 306
	if (res) {
		/* store this somewhere, somehow */
		bonobo_object_unref (BONOBO_OBJECT (stream));
	}
	return res;
307 308
}

309 310 311
static void
sheet_object_bonobo_class_init (GtkObjectClass *object_class)
{
312
	SheetObjectClass *sheet_object_class;
313

314 315
	sheet_object_bonobo_parent_class = gtk_type_class (sheet_object_get_type ());

316
	/* GtkObject class method overrides */
317
	object_class->destroy = sheet_object_bonobo_destroy;
318

319 320 321
	/* SheetObject class method overrides */
	sheet_object_class = SHEET_OBJECT_CLASS (object_class);
	sheet_object_class->print         = sheet_object_bonobo_print;
Michael Meeks's avatar
Michael Meeks committed
322
	sheet_object_class->populate_menu = sheet_object_bonobo_populate_menu;
323 324
	sheet_object_class->read_xml	  = sheet_object_bonobo_read_xml;
	sheet_object_class->write_xml	  = sheet_object_bonobo_write_xml;
325 326
}

327 328
E_MAKE_TYPE (sheet_object_bonobo, "SheetObjectBonobo", SheetObjectBonobo,
	     sheet_object_bonobo_class_init, NULL, SHEET_OBJECT_TYPE);
329 330

SheetObjectBonobo *
331
sheet_object_bonobo_construct (SheetObjectBonobo   *sob,
Jody Goldberg's avatar
Jody Goldberg committed
332
			       Bonobo_UIContainer *container,
333
			       char const *object_id)
334 335 336
{
	g_return_val_if_fail (IS_SHEET_OBJECT_BONOBO (sob), NULL);

337 338
	sob->object_id     = NULL;
	sob->object_server = NULL;
Jody Goldberg's avatar
Jody Goldberg committed
339
	sob->control_frame = bonobo_control_frame_new (container);
340
	if (object_id != NULL &&
341
	    !sheet_object_bonobo_set_object_iid (sob, object_id)) {
Jody Goldberg's avatar
Jody Goldberg committed
342 343
		bonobo_object_unref (BONOBO_OBJECT (sob->control_frame));
		sob->control_frame = NULL;
344
		return NULL;
345
	}
346 347 348 349

	return sob;
}

350
char const *
351 352 353 354 355 356 357
sheet_object_bonobo_get_object_iid (SheetObjectBonobo const *sob)
{
	g_return_val_if_fail (IS_SHEET_OBJECT_BONOBO (sob), NULL);

	return sob->object_id;
}

358 359 360 361 362 363 364 365
/**
 * sheet_object_bonobo_set_object_iid :
 *
 * @sob : The Sheet bonobo object
 * @object_id : An optional id
 *
 * returns TRUE if things succeed.
 */
366
gboolean
367 368
sheet_object_bonobo_set_object_iid (SheetObjectBonobo *sob,
				    char const *object_id)
369
{
370
	BonoboObjectClient *server;
371
	gboolean result;
372

373 374 375 376
	g_return_val_if_fail (IS_SHEET_OBJECT_BONOBO (sob), FALSE);
	g_return_val_if_fail (sob->object_id == NULL, FALSE);
	g_return_val_if_fail (object_id != NULL, FALSE);

377
	server = bonobo_object_activate (object_id, 0);
378
	if (!server)
379
		return FALSE;
380 381 382 383 384 385

	result = sheet_object_bonobo_set_server (sob, server);
	bonobo_object_unref (BONOBO_OBJECT (server));
	if (result == TRUE) {
		sob->object_id = g_strdup (object_id);
		return (TRUE);
386
	}
387

388
	return (FALSE);
389 390 391 392 393 394 395
}

gboolean
sheet_object_bonobo_set_server (SheetObjectBonobo *sob,
				BonoboObjectClient *server)
{
	g_return_val_if_fail (IS_SHEET_OBJECT_BONOBO (sob), FALSE);
396
	g_return_val_if_fail (sob->object_server == CORBA_OBJECT_NIL, FALSE);
397

Jody Goldberg's avatar
Jody Goldberg committed
398
	if (!bonobo_client_site_bind_embeddable (sob->control_frame, server))
399
		return FALSE;
400

401
	bonobo_object_ref (BONOBO_OBJECT (server));
402
	sob->object_server = server;
403

404 405 406 407 408
	sob->has_persist_file = bonobo_object_client_has_interface (server,
					"IDL:Bonobo/PersistFile:1.0", NULL);
	sob->has_persist_stream = bonobo_object_client_has_interface (server,
					"IDL:Bonobo/PersistStream:1.0", NULL);

409
	return TRUE;
410
}