1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
5 * A simple program to act as a test container for embeddable
9 * Nat Friedman (nat@gnome-support.com)
10 * Miguel de Icaza (miguel@gnu.org)
18 #define GString G_String
20 #include <libgnorba/gnorba.h>
21 #include <gdk/gdkprivate.h>
23 #include <bonobo/gnome-bonobo.h>
30 #include "parseargs.h"
42 #include "GOutputDev.h"
43 #include "PSOutputDev.h"
44 #include "TextOutputDev.h"
54 const struct poptOption gpdf_popt_options [] = {
55 { "debug", '\0', POPT_ARG_INT, &gpdf_debug, 0,
56 N_("Enables some debugging functions"), N_("LEVEL") },
57 { NULL, '\0', 0, NULL, 0 }
61 * A handle to some Embeddables and their ClientSites so we can add
62 * views to existing components.
64 GnomeObjectClient *text_obj;
65 GnomeClientSite *text_client_site;
67 GnomeObjectClient *image_png_obj;
68 GnomeClientSite *image_client_site;
71 * The currently active view. We keep track of this
72 * so we can deactivate it when a new view is activated.
74 GnomeViewFrame *active_view_frame;
76 char *server_goadid = "gnome_xpdf_viewer";
80 GnomeContainer *container;
83 gboolean contains_pdf;
86 /* List of applications */
89 static Application * application_new (void);
92 application_destroy (Application *app)
94 apps = g_list_remove (apps, app);
95 gtk_widget_destroy (app->app);
102 applications_destroy ()
105 application_destroy ((Application *)apps->data);
108 static GnomeObjectClient *
109 launch_server (GnomeClientSite *client_site, GnomeContainer *container, char *goadid)
111 GnomeObjectClient *object_server;
113 gnome_container_add (container, GNOME_OBJECT (client_site));
115 printf ("Launching...\n");
116 object_server = gnome_object_activate_with_goad_id (NULL, goadid, GOAD_ACTIVATE_SHLIB, NULL);
117 printf ("Return: %p\n", object_server);
119 g_warning (_("Can not activate object_server\n"));
123 if (!gnome_client_site_bind_embeddable (client_site, object_server)){
124 g_warning (_("Can not bind object server to client_site\n"));
128 return object_server;
131 static GnomeObjectClient *
132 launch_server_moniker (GnomeClientSite *client_site, GnomeContainer *container, char *moniker)
134 GnomeObjectClient *object_server;
136 gnome_container_add (container, GNOME_OBJECT (client_site));
138 printf ("Launching moniker %s...\n", moniker);
139 object_server = gnome_object_activate (moniker, GOAD_ACTIVATE_SHLIB);
140 printf ("Return: %p\n", object_server);
142 g_warning (_("Can not activate object_server\n"));
146 if (!gnome_client_site_bind_embeddable (client_site, object_server)){
147 g_warning (_("Can not bind object server to client_site\n"));
151 return object_server;
155 * This function is called when the user double clicks on a View in
156 * order to activate it.
159 user_activation_request_cb (GnomeViewFrame *view_frame)
162 * If there is already an active View, deactivate it.
164 if (active_view_frame != NULL) {
166 * This just sends a notice to the embedded View that
167 * it is being deactivated. We will also forcibly
168 * cover it so that it does not receive any Gtk
171 gnome_view_frame_view_deactivate (active_view_frame);
174 * Here we manually cover it if it hasn't acquiesced.
175 * If it has consented to be deactivated, then it will
176 * already have notified us that it is inactive, and
177 * we will have covered it and set active_view_frame
178 * to NULL. Which is why this check is here.
180 if (active_view_frame != NULL)
181 gnome_view_frame_set_covered (active_view_frame, TRUE);
183 active_view_frame = NULL;
187 * Activate the View which the user clicked on. This just
188 * sends a request to the embedded View to activate itself.
189 * When it agrees to be activated, it will notify its
190 * ViewFrame, and our view_activated_cb callback will be
193 * We do not uncover the View here, because it may not wish to
194 * be activated, and so we wait until it notifies us that it
195 * has been activated to uncover it.
197 gnome_view_frame_view_activate (view_frame);
203 * Gets called when the View notifies the ViewFrame that it would like
204 * to be activated or deactivated.
207 view_activated_cb (GnomeViewFrame *view_frame, gboolean activated)
212 * If the View is requesting to be activated, then we
213 * check whether or not there is already an active
216 if (active_view_frame != NULL) {
217 g_warning ("View requested to be activated but there is already "
218 "an active View!\n");
223 * Otherwise, uncover it so that it can receive
224 * events, and set it as the active View.
226 gnome_view_frame_set_covered (view_frame, FALSE);
227 active_view_frame = view_frame;
230 * If the View is asking to be deactivated, always
231 * oblige. We may have already deactivated it (see
232 * user_activation_request_cb), but there's no harm in
233 * doing it again. There is always the possibility
234 * that a View will ask to be deactivated when we have
235 * not told it to deactivate itself, and that is
236 * why we cover the view here.
238 gnome_view_frame_set_covered (view_frame, TRUE);
240 if (view_frame == active_view_frame)
241 active_view_frame = NULL;
247 static GnomeViewFrame *
248 add_view (Application *app,
249 GnomeClientSite *client_site, GnomeObjectClient *server)
251 GnomeViewFrame *view_frame;
252 GtkWidget *view_widget;
254 view_frame = gnome_client_site_embeddable_new_view (client_site);
256 gtk_signal_connect (GTK_OBJECT (view_frame), "user_activate",
257 GTK_SIGNAL_FUNC (user_activation_request_cb), NULL);
258 gtk_signal_connect (GTK_OBJECT (view_frame), "view_activated",
259 GTK_SIGNAL_FUNC (view_activated_cb), NULL);
261 gnome_view_frame_set_ui_handler (view_frame, app->uih);
263 view_widget = gnome_view_frame_get_wrapper (view_frame);
265 gtk_box_pack_start (GTK_BOX (app->box), view_widget, TRUE, TRUE, 0);
266 gtk_widget_show_all (app->box);
271 static GnomeObjectClient *
272 add_cmd (Application *app, char *server_goadid,
273 GnomeClientSite **client_site)
275 GnomeObjectClient *server;
277 *client_site = gnome_client_site_new (app->container);
279 server = launch_server (*client_site, app->container, server_goadid);
283 add_view (app, *client_site, server);
288 open_pdf (Application *app, const char *name)
290 GnomeObjectClient *object;
292 GNOME_PersistStream persist;
294 object = add_cmd (app, "bonobo-object:image-x-pdf", &image_client_site);
295 if (object == NULL) {
296 gnome_error_dialog (_("Could not launch bonobo object."));
300 image_png_obj = object;
302 persist = GNOME_Unknown_query_interface (
303 gnome_object_corba_objref (GNOME_OBJECT (object)),
304 "IDL:GNOME/PersistStream:1.0", &ev);
306 if (ev._major != CORBA_NO_EXCEPTION ||
307 persist == CORBA_OBJECT_NIL) {
308 gnome_error_dialog ("Panic: component is well broken.");
312 stream = gnome_stream_fs_open (name, GNOME_Storage_READ);
314 if (stream == NULL) {
315 char *err = g_strconcat (_("Could not open "), name, NULL);
316 gnome_error_dialog_parented (err, GTK_WINDOW(app->app));
321 GNOME_PersistStream_load (persist,
322 (GNOME_Stream) gnome_object_corba_objref (GNOME_OBJECT (stream)), &ev);
324 GNOME_Unknown_unref (persist, &ev);
325 CORBA_Object_release (persist, &ev);
326 app->contains_pdf = TRUE;
330 set_ok (GtkWidget *widget, gboolean *dialog_result)
332 *dialog_result = TRUE;
337 file_dialog_delete_event (GtkWidget *widget, GdkEventAny *event)
344 file_open_cmd (GtkWidget *widget, Application *app)
346 GtkFileSelection *fsel;
347 gboolean accepted = FALSE;
349 fsel = GTK_FILE_SELECTION (gtk_file_selection_new (_("Load file")));
350 gtk_window_set_modal (GTK_WINDOW (fsel), TRUE);
352 gtk_window_set_transient_for (GTK_WINDOW (fsel),
353 GTK_WINDOW (app->app));
355 /* Connect the signals for Ok and Cancel */
356 gtk_signal_connect (GTK_OBJECT (fsel->ok_button), "clicked",
357 GTK_SIGNAL_FUNC (set_ok), &accepted);
358 gtk_signal_connect (GTK_OBJECT (fsel->cancel_button), "clicked",
359 GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
360 gtk_window_set_position (GTK_WINDOW (fsel), GTK_WIN_POS_MOUSE);
363 * Make sure that we quit the main loop if the window is destroyed
365 gtk_signal_connect (GTK_OBJECT (fsel), "delete_event",
366 GTK_SIGNAL_FUNC (file_dialog_delete_event), NULL);
369 gtk_widget_show (GTK_WIDGET (fsel));
370 gtk_grab_add (GTK_WIDGET (fsel));
374 char *name = gtk_file_selection_get_filename (fsel);
376 if (name [strlen (name)-1] != '/') {
377 if (app->contains_pdf)
378 app = application_new ();
379 char *fname = g_strdup (name);
380 open_pdf (app, fname);
384 dialog = gnome_message_box_new ("Can't open a directory",
385 GNOME_MESSAGE_BOX_ERROR,
386 GNOME_STOCK_BUTTON_OK, NULL);
387 gnome_dialog_set_parent (GNOME_DIALOG (dialog),
388 GTK_WINDOW (app->app));
389 gnome_dialog_run (GNOME_DIALOG (dialog));
393 gtk_widget_destroy (GTK_WIDGET (fsel));
397 close_cmd (GtkWidget *widget, Application *app)
399 application_destroy (app);
405 applications_destroy ();
408 static GnomeUIInfo container_file_menu [] = {
409 GNOMEUIINFO_MENU_OPEN_ITEM (file_open_cmd, NULL),
410 GNOMEUIINFO_SEPARATOR,
411 GNOMEUIINFO_MENU_CLOSE_ITEM(close_cmd, NULL),
412 GNOMEUIINFO_SEPARATOR,
413 GNOMEUIINFO_MENU_EXIT_ITEM (exit_cmd, NULL),
417 static GnomeUIInfo container_main_menu [] = {
418 GNOMEUIINFO_MENU_FILE_TREE (container_file_menu),
423 application_new (void)
426 GnomeUIHandlerMenuItem *menu_list;
428 app = g_new0 (Application, 1);
429 app->app = gnome_app_new ("gpdf",
431 app->container = GNOME_CONTAINER (gnome_container_new ());
432 app->contains_pdf = FALSE;
434 app->box = gtk_vbox_new (FALSE, 0);
435 gtk_widget_show (app->box);
436 gnome_app_set_contents (GNOME_APP (app->app), app->box);
441 app->uih = gnome_ui_handler_new ();
443 gnome_ui_handler_set_app (app->uih, GNOME_APP (app->app));
444 gnome_ui_handler_create_menubar (app->uih);
446 menu_list = gnome_ui_handler_menu_parse_uiinfo_list_with_data (container_main_menu, app);
447 gnome_ui_handler_menu_add_list (app->uih, "/", menu_list);
448 gnome_ui_handler_menu_free_list (menu_list);
450 /* gnome_ui_handler_create_toolbar (app->uih, "Common");
451 gnome_ui_handler_toolbar_new_item (app->uih,
453 "Container-added Item 1", "I am the container. Hear me roar.",
454 0, GNOME_UI_HANDLER_PIXMAP_NONE, NULL, 0, 0,
457 gtk_widget_show (app->app);
459 apps = g_list_append (apps, app);
464 main (int argc, char *argv [])
467 char **view_files = NULL;
470 server_goadid = argv [1];
473 CORBA_exception_init (&ev);
475 gnome_CORBA_init_with_popt_table ("PDFViewer", "0.0.1",
477 gpdf_popt_options, 0, &ctx,
478 GNORBA_INIT_SERVER_FUNC, &ev);
479 orb = gnome_CORBA_ORB ();
481 if (bonobo_init (orb, NULL, NULL) == FALSE)
482 g_error (_("Can not bonobo_init\n"));
484 app = application_new ();
486 view_files = poptGetArgs (ctx);
491 for (i = 0; view_files[i]; i++) {
492 if (app->contains_pdf)
493 app = application_new ();
494 open_pdf (app, view_files[i]);
498 poptFreeContext (ctx);
502 CORBA_exception_free (&ev);