1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 2000 Alexander Larsson
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include <gnome.h>
24 #include <bonobo.h>
25 #include <liboaf/liboaf.h>
26
27 #include "display.h"
28 #include "menus.h"
29 #include "disp_callbacks.h"
30 #include "app_procs.h"
31 #include "interface.h"
32 #include "load_save.h"
33
34 #ifdef GNOME_PRINT
35 # include "render_gnomeprint.h"
36 #endif
37
38 typedef struct _EmbeddedDia EmbeddedDia;
39 typedef struct _EmbeddedView EmbeddedView;
40
41 struct _EmbeddedDia {
42 BonoboEmbeddable *embeddable;
43
44 Diagram *diagram;
45 };
46
47 struct _EmbeddedView {
48 BonoboView *view;
49 EmbeddedDia *embedded_dia;
50 DDisplay *display;
51 };
52
53 static BonoboGenericFactory *factory = NULL;
54
55 static void
view_show_hide(EmbeddedView * view_data,gboolean activate)56 view_show_hide (EmbeddedView *view_data,
57 gboolean activate)
58 {
59 DDisplay *ddisp = view_data->display;
60
61 if (activate) {
62 toolbox_show();
63
64 display_rulers_show(ddisp);
65 gtk_widget_show(ddisp->hsb);
66 gtk_widget_show(ddisp->vsb);
67 gtk_widget_show(ddisp->zoom_status->parent);
68 gtk_widget_show(ddisp->modified_status);
69 } else {
70 toolbox_hide();
71
72 display_rulers_hide(ddisp);
73 gtk_widget_hide(ddisp->hsb);
74 gtk_widget_hide(ddisp->vsb);
75 gtk_widget_hide(ddisp->zoom_status->parent);
76 gtk_widget_hide(ddisp->modified_status);
77 }
78 }
79
80 static void
dia_view_activate(BonoboView * view,gboolean activate,EmbeddedView * view_data)81 dia_view_activate(BonoboView *view, gboolean activate,
82 EmbeddedView *view_data)
83 {
84 bonobo_view_activate_notify(view, activate);
85 view_show_hide(view_data,activate);
86 }
87
88 static void
dia_view_display_destroy(GtkWidget * ddisp_shell,EmbeddedView * view_data)89 dia_view_display_destroy (GtkWidget *ddisp_shell, EmbeddedView *view_data)
90 {
91 view_data->display = NULL;
92 bonobo_object_unref(BONOBO_OBJECT(view_data->view));
93 }
94
95 static void
dia_view_destroy(BonoboView * view,EmbeddedView * view_data)96 dia_view_destroy (BonoboView *view, EmbeddedView *view_data)
97 {
98 if (view_data->display)
99 ddisplay_destroy(view_data->display->shell, view_data->display);
100 g_free(view_data);
101 }
102
103 static void
dia_embeddable_destroy(BonoboEmbeddable * embeddable,EmbeddedDia * embedded_dia)104 dia_embeddable_destroy(BonoboEmbeddable *embeddable,
105 EmbeddedDia *embedded_dia)
106 {
107 Diagram *dia = embedded_dia->diagram;
108 DDisplay *ddisp;
109
110 /* Destroy all views: */
111 while (dia->displays) {
112 ddisp = (DDisplay *)dia->displays->data;
113 gtk_widget_destroy(ddisp->shell);
114 }
115
116 diagram_destroy(embedded_dia->diagram);
117 g_free(embedded_dia);
118 }
119
120 static void
dia_view_system_exception(BonoboView * view,CORBA_Object corba_object,CORBA_Environment * ev,gpointer data)121 dia_view_system_exception(BonoboView *view, CORBA_Object corba_object,
122 CORBA_Environment *ev, gpointer data)
123 {
124 bonobo_object_unref(BONOBO_OBJECT(view));
125 }
126
127 static void
dia_embeddable_system_exception(BonoboEmbeddable * embeddable,CORBA_Object corba_object,CORBA_Environment * ev,gpointer data)128 dia_embeddable_system_exception(BonoboEmbeddable *embeddable, CORBA_Object corba_object,
129 CORBA_Environment *ev, gpointer data)
130 {
131 bonobo_object_unref(BONOBO_OBJECT(embeddable));
132 }
133
134 static BonoboView *
view_factory(BonoboEmbeddable * embeddable,const Bonobo_ViewFrame view_frame,EmbeddedDia * embedded_dia)135 view_factory (BonoboEmbeddable *embeddable,
136 const Bonobo_ViewFrame view_frame,
137 EmbeddedDia *embedded_dia)
138 {
139 EmbeddedView *view_data;
140 BonoboView *view;
141
142 /*
143 * Create the private view data.
144 */
145 view_data = g_new0 (EmbeddedView, 1);
146 view_data->embedded_dia = embedded_dia;
147
148 view_data->display = new_display(embedded_dia->diagram);
149
150 view_show_hide (view_data, FALSE);
151
152 g_signal_connect (GTK_OBJECT (view_data->display->shell), "destroy",
153 G_CALLBACK (dia_view_display_destroy),
154 view_data);
155
156 view = bonobo_view_new (view_data->display->shell);
157 view_data->view = view;
158 gtk_object_set_data (GTK_OBJECT (view), "view_data", view_data);
159
160 g_signal_connect(GTK_OBJECT (view), "activate",
161 G_CALLBACK (dia_view_activate), view_data);
162
163 g_signal_connect(GTK_OBJECT (view), "system_exception",
164 G_CALLBACK (dia_view_system_exception), view_data);
165
166 g_signal_connect (GTK_OBJECT (view), "destroy",
167 G_CALLBACK (dia_view_destroy), view_data);
168
169
170 #if 0
171 menuitem = menus_get_item_from_path("<Display>/File/New diagram");
172 gtk_widget_hide(menuitem);
173 menuitem = menus_get_item_from_path("<Display>/File/Open...");
174 gtk_widget_hide(menuitem);
175 menuitem = menus_get_item_from_path("<Display>/File/Save As...");
176 gtk_widget_hide(menuitem);
177 menuitem = menus_get_item_from_path("<Display>/File/Close");
178 gtk_widget_hide(menuitem);
179 menuitem = menus_get_item_from_path("<Display>/File/Exit");
180 gtk_widget_hide(menuitem);
181 menuitem = menus_get_item_from_path("<Display>/View/New View");
182 gtk_widget_hide(menuitem);
183 #endif
184
185 return view;
186 }
187
188 static int
save_fn(BonoboPersistFile * pf,const CORBA_char * filename,CORBA_Environment * ev,void * closure)189 save_fn (BonoboPersistFile *pf,
190 const CORBA_char *filename,
191 CORBA_Environment *ev,
192 void *closure)
193 {
194 EmbeddedDia *dia = closure;
195
196 if (!diagram_save (dia->diagram, filename))
197 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
198 ex_Bonobo_Storage_IOError, NULL);
199 return 0;
200 }
201
202 static void
refresh_view(DDisplay * ddisp)203 refresh_view (DDisplay *ddisp)
204 {
205 Point middle;
206 Rectangle *visible;
207
208 visible = &ddisp->visible;
209 middle.x = visible->left*0.5 + visible->right*0.5;
210 middle.y = visible->top*0.5 + visible->bottom*0.5;
211
212 ddisplay_zoom(ddisp, &middle, 1.0);
213 gtk_widget_queue_draw(ddisp->shell);
214 }
215
216 static int
load_fn(BonoboPersistFile * pf,const CORBA_char * filename,CORBA_Environment * ev,void * closure)217 load_fn (BonoboPersistFile *pf,
218 const CORBA_char *filename,
219 CORBA_Environment *ev,
220 void *closure)
221 {
222 EmbeddedDia *dia = closure;
223
224 if (!diagram_load_into (dia->diagram, filename, NULL)) {
225 g_warning ("Failed to load '%s'", filename);
226 CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
227 ex_Bonobo_Persist_WrongDataType,
228 NULL);
229 } else {
230 GSList *l;
231 diagram_update_extents(dia->diagram);
232 for (l=dia->diagram->displays;l;l=l->next)
233 refresh_view (l->data);
234 }
235 return 0;
236 }
237
238 #ifdef GNOME_PRINT
239 static void
object_print(GnomePrintContext * ctx,double width,double height,const Bonobo_PrintScissor * scissor,gpointer user_data)240 object_print (GnomePrintContext *ctx,
241 double width,
242 double height,
243 const Bonobo_PrintScissor *scissor,
244 gpointer user_data)
245 {
246 RendererGPrint *rend;
247 EmbeddedDia *edia = user_data;
248 Diagram *dia = edia->diagram;
249 Rectangle *extents;
250 double scalex, scaley;
251
252 rend = new_gnomeprint_renderer(dia, ctx);
253
254 /*
255 * FIXME: we need to de-complicate all this - this should
256 * probably be done by scaling the view to the extent or
257 * alternatively keeping the visible bounds on the embeddable
258 * not the view; or possibly none of these.
259 */
260 extents = &dia->data->extents;
261
262 scalex = width / (extents->right - extents->left);
263 scaley = -height / (extents->bottom - extents->top);
264
265 gnome_print_translate (ctx, - scalex* extents->left,
266 height - scaley * extents->top);
267 gnome_print_scale (ctx, scalex, scaley);
268
269
270 data_render(dia->data, (Renderer *)rend, extents, NULL, NULL);
271
272 g_free (rend);
273 }
274 #endif
275
276 static BonoboObject *
embeddable_factory(BonoboGenericFactory * this,void * data)277 embeddable_factory (BonoboGenericFactory *this,
278 void *data)
279 {
280 BonoboPersistFile *pfile;
281 BonoboEmbeddable *embeddable;
282 BonoboPrint *print;
283 EmbeddedDia *embedded_dia;
284
285 embedded_dia = g_new0 (EmbeddedDia, 1);
286 if (embedded_dia == NULL)
287 return NULL;
288
289 embedded_dia->diagram = new_diagram("foobar_embedd");
290
291 embeddable = bonobo_embeddable_new (BONOBO_VIEW_FACTORY (view_factory),
292 embedded_dia);
293
294 if (embeddable == NULL) {
295 diagram_destroy (embedded_dia->diagram);
296 return NULL;
297 }
298
299 embedded_dia->embeddable = embeddable;
300
301 g_signal_connect(GTK_OBJECT(embeddable), "system_exception",
302 G_CALLBACK (dia_embeddable_system_exception),
303 embedded_dia);
304
305 g_signal_connect(GTK_OBJECT(embeddable), "destroy",
306 G_CALLBACK (dia_embeddable_destroy),
307 embedded_dia);
308
309 /* Register the Bonobo::PersistFile interface. */
310 pfile = bonobo_persist_file_new (load_fn, save_fn, embedded_dia);
311 bonobo_object_add_interface (
312 BONOBO_OBJECT (embeddable),
313 BONOBO_OBJECT (pfile));
314
315 #ifdef GNOME_PRINT
316 /* Register the Bonobo::Print interface */
317 print = bonobo_print_new (object_print, embedded_dia);
318 if (!print) {
319 bonobo_object_unref (BONOBO_OBJECT (embeddable));
320 return NULL;
321 }
322
323 bonobo_object_add_interface (BONOBO_OBJECT (embeddable),
324 BONOBO_OBJECT (print));
325 #endif
326
327 return BONOBO_OBJECT (embeddable);
328 }
329
330 static BonoboGenericFactory *
init_dia_factory(void)331 init_dia_factory (void)
332 {
333 return bonobo_generic_factory_new ("OAFIID:GNOME_Dia_DiagramFactory",
334 embeddable_factory, NULL);
335 }
336
337 static void
init_server_factory(int argc,char ** argv)338 init_server_factory (int argc, char **argv)
339 {
340 CORBA_ORB orb;
341
342 gnome_init_with_popt_table ("dia-embedd", VERSION,
343 argc, argv, oaf_popt_options, 0, NULL);
344
345 orb = oaf_init (argc, argv);
346
347 if (bonobo_init (orb, NULL, NULL) == FALSE)
348 g_error (_("Could not initialize Bonobo!"));
349 bonobo_activate ();
350 }
351
352 int
app_is_embedded(void)353 app_is_embedded(void)
354 {
355 return 1;
356 }
357
358 static void
last_unref_cb(BonoboObject * bonobo_object,gpointer dummy)359 last_unref_cb (BonoboObject *bonobo_object,
360 gpointer dummy)
361 {
362 bonobo_object_unref (BONOBO_OBJECT (factory));
363 gtk_main_quit ();
364 }
365
366 int
main(int argc,char ** argv)367 main (int argc, char **argv)
368 {
369 GtkWidget *menuitem;
370
371 init_server_factory (argc, argv);
372 factory = init_dia_factory ();
373
374 app_init(0, NULL);
375 app_splash_done();
376
377 /*
378 The hiding of some of our menu entries is necessary to
379 adapt to the 'run-embeded' case, e.g. no File/(New|Open|Exit)
380 because these would conflict with the embedder's menu entries.
381 */
382 #ifdef GNOME
383 menuitem = menus_get_item("/ToolboxMenu/File/FileNew");
384 gtk_widget_hide(menuitem);
385 menuitem = menus_get_item("/ToolboxMenu/File/FileOpen");
386 gtk_widget_hide(menuitem);
387 menuitem = menus_get_item("/ToolboxMenu/File/FileExit");
388 gtk_widget_hide(menuitem);
389 #else
390 menuitem = menus_get_item("/ToolboxMenu/File/FileNew");
391 gtk_widget_hide(menuitem);
392 menuitem = menus_get_item("/ToolboxMenu/File/FileOpen");
393 gtk_widget_hide(menuitem);
394 menuitem = menus_get_item("/ToolboxMenu/File/FileSep1");
395 gtk_widget_hide(menuitem);
396 menuitem = menus_get_item("/ToolboxMenu/File/FileQuit");
397 gtk_widget_hide(menuitem);
398 #endif
399
400 g_signal_connect (GTK_OBJECT (bonobo_context_running_get ()),
401 "last_unref",
402 G_CALLBACK (last_unref_cb),
403 NULL);
404 /*
405 * Start processing.
406 */
407 bonobo_main ();
408
409 return 0;
410 }
411
412