Embedding components in under 100 lines (Was Re: Embedding gnumeric...)



>    The document I mentioned above, in the section on CORBA and compound
> documents, states:
>
>   "Gnumeric is also available to other applications as a Bonobo component.
> (Bonobo is the compound document architecture of GNOME).  This enables
> your application to embed Gnumeric into your application for editing, or
> displaying information.  *One line of code would achieve all the magic you
> need.*"  [Emphasis mine]
>
>    Can somebody clue me in on what this "One line of code" might be?
> Because I certainly haven't been able to figure it out from reading the
> mailing list archives, or the bonobo/samples codes (which imply that one
> *thousand* lines of code is probably closer to the truth),

Well, 1 line is only true if you have your app bonoboised already.
10 lines is probably more of a reality if you don't.

Here's a short (80ish lines long) program that sticks any bonobo embeddable
into a GtkWindow.

/* Adding a bonobo component in two functions by Iain Holmes - Mostly copied
from
    bonobo/samples/compound-document/container/ */
/* Compile with (all one line):
gcc -o test-bonobo test.c -g `gnome-config --cflags bonobo gnomeui bonobox`
`gnome-config --libs bonobo gnomeui bonobox` */

#include <gtk/gtk.h>
#include <gnome.h>
#include <bonobo.h>

void
add_embeddable (GtkWidget *window,
                char *obj_id)
{
  BonoboObjectClient *server;
  BonoboClientSite *site;
  BonoboContainer *container;
  Bonobo_ClientSite corba_client_site;

  BonoboViewFrame *view_frame;
  GtkWidget *view_widget;

  /* Activate component */
  server = bonobo_object_activate (obj_id, 0);
  if (!server) {
    g_warning ("Error launching %s", obj_id);
    return;
  }

  /* New bonobo container to hold the embeddable */
  container = bonobo_container_new ();

  /* New client site for the container */
  site = bonobo_client_site_new (container);
  corba_client_site = bonobo_client_site_corba_object_create (BONOBO_OBJECT
(site));

  /* Not sure why we do this twice - Anyone? */
  site = bonobo_client_site_construct (site, corba_client_site, container);

  if (site) {
    bonobo_client_site_bind_embeddable (site, server);
    bonobo_object_unref (BONOBO_OBJECT (server));
    bonobo_container_add (container, BONOBO_OBJECT (site));

    /* Create a new view of the embeddable */
    view_frame = bonobo_client_site_new_view (site, NULL);

    /* Get the widget */
    view_widget = bonobo_view_frame_get_wrapper (view_frame);

    /* Bung it in the window */
    gtk_container_add (GTK_CONTAINER (window), view_widget);
    gtk_widget_show (view_widget);
  }
}

int main (int argc,
          char **argv)
{
  GtkWidget *window;
  CORBA_ORB orb;
  CORBA_Environment ev;
  char *required_interfaces [2] = {"IDL:Bonobo/Embeddable:1.0", NULL };
  char *obj_id;

  gnome_init ("Bonobo Example", "1.0", argc, argv);
  orb = oaf_init (argc, argv);

  if (bonobo_init (orb, NULL, NULL) == FALSE)
    g_error ("Could not initialize Bonobo!\n");

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW (window), "Bonobo Example");

  /* Select the component */
  obj_id = bonobo_selector_select_id ("Select an embeddable component",
                                      (const char **) required_interfaces);

  add_embeddable (window, obj_id);

  gtk_widget_show (window);
  bonobo_main ();
}

Okay, so it lacks a few things (activation, UIHandlers) but these things are
fairly
simple to add.

iain






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