GOffice components



Hi,

I'd like to discuss some aspects of the component system I have been
implementing recently. The guidelines came essentially from what had
been done for charts in abiword. The main issues are :
- what should be added/changed so that it might be useful to embed
components in other applications.
- portability issues.

I'll not discuss writing a component plugin here (I intedn to write
about that too, but later), but just concentrate on the client
application point of view. There is already an implementation in the
AbiGOffice plugin (you need to configure abiword-plugins with
--without-abigochart since the two plugins are not compatible).
To test, I'd recommend using the plugin I wrote for DrGeo, which is
available from gnome cvs (branch goffice). It is not fully functional
yet, but gives a good overview of what can be done.

Here is the relevant part of the API (still very unstable):

* retrieving general information:


GSList *go_components_get_mime_types (void);

Gets the list of mime types supported by at least one plugin


GOMimePriority go_components_get_priority (char const *mime_type);

Gets the level of support. The returned value is one of the following:
GO_MIME_PRIORITY_INVALID: an error occurred (this should never happen)
GO_MIME_PRIORITY_DISPLAY: the component can just display the contents.
GO_MIME_PRIORITY_PRINT: the component can display and print the
contents.
GO_MIME_PRIORITY_PARTIAL: there is some editing capacity, but not all
features are supported.
GO_MIME_PRIORITY_FULL: full editing support.
GO_MIME_PRIORITY_NATIVE: the same as above, but the plugin is provided
by the application which is associated with the mime type.

For example, the gnumeric component plugin (currently in development)
will have GO_MIME_PRIORITY_NATIVE for gnumeric files and
GO_MIME_PRIORITY_PARTIAL for excel files (and others).

When several plugins claim supporting the same mime type, the one having
the highest priority (hence the name) is used.

* Creating an object:
Three functions are available.
GOComponent  *go_component_new_by_type	(GOComponentType const *type);
GOComponent  *go_component_new_by_name	(char const *id);
GOComponent  *go_component_new_by_mime_type	(char const *mime_type);

The first one is used internally by the framework and will generally not
be used by applications. The second might be used if somebody wants to
use one plugin with low priority for a given mime type, it is also used
by the framework, and is generally not so useful.
Normally the third one is the one to use.
The mime type of an embedded object is implemented as a GObject
property, so it can be retrieved width g_object_get.

* Data management:
void go_component_set_data (GOComponent *component, char const *data, int length);

This one is used to provide the data to the components.

gboolean go_component_get_data (GOComponent *component, gpointer *data, int *length,
						void (**clearfunc) (gpointer));

This one is for retrieving the data from the object and should be used
when the object has been edited (it has emitted the "changed" signal).

* Size:
void go_component_set_default_size (GOComponent *component, double width, double ascent, double descent);

This is to give a default size for a component. It is mainly useful if
the object has no intrinsic size.

void go_component_set_size (GOComponent *component, double width, double height);
Sets the size of the embedded object. Should be used when the user has
resized the object.

gboolean go_component_is_resizable (GOComponent *component);
Returns true if the object size can be changed.

Components also have properties related to size. These are "width",
"height", "ascent", "descent".GOC_PARAM_PERSISTENT


* Display and print.
There are two ways to display an embedded object: in a window (using
Xembed) or using a pixbuf. The second is highly recommended. I
implemented the first one when I tried to embed mozilla plugins (I don't
work anymore on that).

gboolean go_component_needs_window (GOComponent *component);
Returns true if the component needs a window (currently, all components
I'm working on return FALSE).

void go_component_set_window (GOComponent *component, GdkWindow *window);
void go_component_set_pixbuf (GOComponent *component, GdkPixbuf *pixbuf);

These two are used to set the target used for drawing. The use of
GdkWindow and GdkPixbuf is a portability problem for Abiword, but only
the plugins need access to them, so that using a gpointer instead would
solve the problem at the GOffice level.
The first one should be used only when the plugin needs a window (may be
some client application might prefer to always use a window, this is
quite feasible although not implemented at the moment).

void go_component_draw (GOComponent *component, int width_pixels, int
height_pixels);
Request drawing the embedded object.

void go_component_print (GOComponent *component, GnomePrintContext *gpc,
double width, double height);
Prints the object. Here also, the GnomePrintContext* might be replaced
by a gpointer.

I'm thinking to implement some sort of cairo_draw method which might
solve the portability problems in this area.

* Editing.

gboolean go_component_is_editable (GOComponent *component);
Tells if the component can be edited.

gboolean go_component_edit (GOComponent *component);
Edits the component. Although not evident at first sight, this is the
main portability concern at the moment. The components I'm implementing
use Gtk+ and the main loop of the client application for editing. I
don't know at the moment how this might be made portable. Just think
that on MSWin, Gnumeric uses gtk+ while Abiword doesn't.

* Components properties.

Components might need extra data (which cells to display from a Gnumeric
workbook or so). The client application must serialize these properties.
They are implemented as GObject properties with the special flag
GOC_PARAM_PERSISTENT.

Hope I did not forget any important point and waiting for comments.

Cheers,
Jean





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