aboutsummaryrefslogtreecommitdiffstats
path: root/doc/devel/evolution-plugin-manual.xml
diff options
context:
space:
mode:
authorMichael Zucci <zucchi@src.gnome.org>2004-09-20 13:59:55 +0800
committerMichael Zucci <zucchi@src.gnome.org>2004-09-20 13:59:55 +0800
commitef6a3af717132e0750f226fa8a0ee0f3c98e19f0 (patch)
treef4ed25f7a247a8ccb855a8d940777e7a3d21a3e3 /doc/devel/evolution-plugin-manual.xml
parent96111b1f1487ca3fe454b340a73ba927cc6bfb83 (diff)
downloadgsoc2013-evolution-ef6a3af717132e0750f226fa8a0ee0f3c98e19f0.tar.gz
gsoc2013-evolution-ef6a3af717132e0750f226fa8a0ee0f3c98e19f0.tar.zst
gsoc2013-evolution-ef6a3af717132e0750f226fa8a0ee0f3c98e19f0.zip
Merged notzed-eplugin-2-branch to head.
svn path=/trunk/; revision=27300
Diffstat (limited to 'doc/devel/evolution-plugin-manual.xml')
-rw-r--r--doc/devel/evolution-plugin-manual.xml2915
1 files changed, 2915 insertions, 0 deletions
diff --git a/doc/devel/evolution-plugin-manual.xml b/doc/devel/evolution-plugin-manual.xml
new file mode 100644
index 0000000000..9e3331d74a
--- /dev/null
+++ b/doc/devel/evolution-plugin-manual.xml
@@ -0,0 +1,2915 @@
+<?xml version='1.0'?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+
+<!ENTITY Evolution "<application>Evolution</application>">
+<!ENTITY GNOME "<application>GNOME</application>">
+<!ENTITY eclipse "<application>Eclipse</application>">
+<!ENTITY Camel "<application>Camel</application>">
+<!ENTITY EPlugin "<application>EPlugin</application>">
+<!ENTITY e-popup-reference SYSTEM "e-popup.xml">
+<!ENTITY e-menu-reference SYSTEM "e-menu.xml">
+<!ENTITY e-config-reference SYSTEM "e-config.xml">
+<!ENTITY e-event-reference SYSTEM "e-event.xml">
+<!ENTITY e-plugin-reference SYSTEM "e-plugin.xml">
+
+<!ENTITY em-popup-reference SYSTEM "em-popup.xml">
+<!ENTITY em-format-reference SYSTEM "em-format.xml">
+
+]>
+<?xml-stylesheet href="sdocbook.css" type="text/css"?>
+
+<book lang="en">
+ <!-- DocBook file was created by LyX 1.3
+ See http://www.lyx.org/ for more information -->
+ <bookinfo>
+ <title>
+ &Evolution; Plugin Development Manual
+ </title>
+
+ <authorgroup>
+ <corpauthor>
+ Novell, Inc.
+ </corpauthor>
+ <author>
+ <firstname>Michael</firstname><surname>Zucchi</surname>
+ </author>
+ </authorgroup>
+
+ <copyright>
+ <year>2004</year>
+ <holder>Novell, Inc.</holder>
+ </copyright>
+
+ </bookinfo>
+
+ <preface id="preface">
+ <title>Preface</title>
+
+ <para>
+ This document is work-in-progress. Its structure and design is still as
+ fluid as the underlying strucutre and design of some parts of EPlugin.
+ There's no guarantee it will be updated at regular intervals,
+ particularly this version.
+ </para>
+ <para>
+ The API documentation is currently generated using the Linux kernel-doc
+ script. The stylesheets used to generate the HTML you're seeing seems to
+ have bugs which duplicates some sections. It is also ugly and difficult
+ to navigate.
+ </para>
+
+ <sect1>
+ <title>Conventions</title>
+ <para>
+ The following conventions are used in the manual ... (insert details
+ here).
+ </para>
+ <sect2>
+ <title>XML Annotation</title>
+ <para>
+ XML definitions are annotated with BNF-style markers to indicate
+ alternative (|), multiples (* or +), and optional (?) items. If no
+ annotation is present then the item must be present once.
+ </para>
+ <variablelist>
+ <varlistentry>
+ <!-- is symbol the right one here? -->
+ <term><symbol>|</symbol></term>
+ <listitem>
+ <simpara>Indicates an alternative option. Only one of the items
+ separated by <symbol>|</symbol> is to be chosen.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><symbol>*</symbol></term>
+ <listitem>
+ <simpara>Following an item, <symbol>*</symbol> indicates the item
+ may occur any number of times, including no times (0 or more
+ multiple).
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><symbol>+</symbol></term>
+ <listitem>
+ <simpara>Following an item, <symbol>+</symbol> indicates the item
+ must occur at least once, but may occur more than ones (1 or
+ more multiple).
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><symbol>?</symbol></term>
+ <listitem>
+ <simpara>Following an item, <symbol>?</symbol> indicates the item
+ may occur at most once, if present (0 or 1 times).
+ </simpara>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ </sect1>
+
+ </preface>
+
+ <part id="informational">
+ <title>
+ EPlugin
+ </title>
+ <chapter>
+ <title>
+ Introduction
+ </title>
+ <para>
+ This book aims to be a comprehensive technical manual for the
+ development of plugins for &Evolution;, a personal information manager
+ for &GNOME;.
+ </para>
+ <para>
+ Up-to, and including, &Evolution; version 2.0, &Evolution; contained
+ limited extensibility interfaces. There were only two ways to extend
+ &Evolution;; by implementing a new top-level component, or by
+ implementing a &Camel; provider. When implementing a top-level component,
+ there was still little integration, and in effect it was merely a more
+ complex way of writing a separate &GNOME; application. &Camel; providers
+ were only designed to be e-mail storage backends, so were of limited
+ use for general extensibility. Despite this, both mechanisms were used
+ for example for the Exchange Connector, although the system made the
+ integration clumsy and difficult.
+ </para>
+ <para>
+ This lack of extensibility has severaly stifled external developer
+ contributions by forcing any extensions to be considered as core
+ features. &Evolution; being a commercial product, it has tight usability
+ and quality requirements that limits the ability to experiment with
+ the core feature set in this way. As a result, very few lines of code
+ or new features have been implemented by external contributors.
+ </para>
+ <para>
+ One of the major goals for the 2.2 release was to implement an
+ extensibility system, given the working name of EPlugin, which must
+ provide a frame-work for both providing extensibility hooks, and for
+ extending the functionality of &Evolution;.
+ </para>
+ <sect1>
+ <title>
+ Plugin System
+ </title>
+ <para>
+ Any plugin system will generally have a number of goals:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ Provide a language independent invocation mechanism
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ Allow extension of parts of the user interface and processing elements
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ Require minimal extra or foreign code to implement in the core application
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ Require minimal interface code to implement the extensions
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ Not to impact performance or increase resource usage unduly
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ Versioning
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ Be able to be extended itself fairly easily.
+ </simpara>
+ </listitem>
+ </itemizedlist>
+ <para>
+ EPlugin manages to fulfill these goals in most cases. EPlugin isn't a
+ single object or interface in itself, although there is an object
+ titled EPlugin, it is a synergistic
+ <footnote><simpara>I've always wanted to use
+ <emphasis>synergistic</emphasis> in a sentence since
+ I read it on the back of the Commodore 64 Users
+ Guide.</simpara></footnote>
+ collection of integrated and
+ continually evolving objects which work together to achieve these
+ goals (and that will definitly be the end of the MarketSpeak). It
+ consists of a loader to invoke extension callbacks, hooks to resolve
+ these callbacks, targets to identify context, and managers which are
+ used by the core code to provide functionality and merging points for
+ the extensions.
+ </para>
+ <para>
+ EPlugin's design was inspired and influenced by the &eclipse;
+ project. It aims at a lower target however, so it was able more easily
+ implemented in a practical time-frame.
+ </para>
+ <para>
+ &EPlugin; was chosen as an approach to the problem of adding
+ scriptability to &Evolution;. Instead of just linking to Perl, or
+ Python, or even Mono by itself an approach was taken which focuses on
+ the application end of the system. So instead of making every part
+ of the application export its functionality and have to deal with
+ whatever script engine is present, EPlugin addresses the hooking part
+ of the equation in a language-independent manner. It also attemps to
+ do it in a way which doesn't impact on the application development
+ either.
+ </para>
+ <para>
+ The EPlugin world is awash with its own language. The next few
+ sections will introduce the basic plugin nomenclature and high-level
+ view of this world.
+ </para>
+
+ </sect1>
+
+ <sect1>
+ <title>
+ Loaders
+ </title>
+ <para>
+ The core of EPlugin is a light-weight object loader and callback
+ invocation system. Because of the varied calling conventions of
+ different languages, and to reduce the overhead of the plugin system
+ itself, all callbacks only receive and return a single argument. By
+ using structures to pass complex arguments, native C plugins require
+ no extra overhead, and marshalling details are moved into the plugin
+ implementation itself where required. It also simplifies memory
+ management issues significantly. For example, the C plugin handler
+ merely loads a shared library using GModule, and resolves a symbol by
+ name; and is so all of 50 lines of code, total. The loaders are the
+ only modules which need to interace with non-native code or
+ conventions.
+ </para>
+ <para>
+ The other task of the plugin core is to load XML definitions of the
+ plugins. Extension hooks are registered with the plugin core before
+ the plugins are scanned, and are automatically instantiated to load
+ each definition appropriately as they are encountered.
+ </para>
+ <para>
+ At each layer, a level of indirection is used so that new loaders and
+ new hooks can be added transparently, and extend the plugin
+ definition freely with any information they require.
+ </para>
+ </sect1>
+
+ <sect1>
+ <title>
+ Hooks
+ </title>
+ <para>
+ The hooks
+ <footnote>
+ <para>A hook is something you can hang your stuff on.</para>
+ </footnote>
+ which are registered with the loader provide meta-data for
+ the management implementation layer for extending it at
+ run-time. Their primary
+ functions are to load the detail of the XML plugin definition, map it
+ to the implementation, and marshal the implementation callbacks to
+ the common plugin interface. How they do this depends on the
+ implementation itself, and ranges from registering factory methods to
+ simply adding the items directly.
+ </para>
+ <para>
+ In most cases the physical object need not be loaded until the
+ callback is invoked, since the plugin definitions provide enough
+ contextual information to build the interface or determine when they
+ need to be invoked.
+ </para>
+ </sect1>
+
+ <sect1>
+ <title>
+ Managers
+ </title>
+ <para>
+ Managers
+ <footnote>
+ <para>
+ Unlike real managers, these are the ones that do the heavy lifting.
+ </para>
+ </footnote>
+ provide tools for the core code to extend itself at specific
+ points, and in many cases are the objects used directly in the code
+ to implement core features. In other cases they simply provide the
+ hooks with an entry point into &Evolution;. For example, for the main
+ menu hook, the manager is a thin layer to BonoboUI. On the other
+ hand, EPopup is a complete implementation of a popup menu management
+ system which was already used in &Evolution; 2.0. Some managers are
+ one-off objects used as constructors for other objects, others are
+ view-dependent, and some are static objects, such as the Event
+ routers.
+ </para>
+ </sect1>
+
+ <sect1>
+ <title>
+ Items
+ </title>
+ <para>
+ Each manager uses a number of items to describe the object they
+ control or create. The items are added to each manager instance from
+ the plugins or from core code. The items from all of these sources
+ are then merged together when required and processed accordingly. For
+ example, menu items are merged into a tree of GtkMenus. Events on the
+ other hand are simply ordered and then invoked in the order of their
+ priority. Items are part of the manager implementation, and in
+ &EPlugin; they are all extensible objects too, which the hooks use to
+ perform mapping to the plugin. Items may be extended by code hooking
+ into the implementation, either the plugin hooks, or the core code.
+ </para>
+ </sect1>
+
+ <sect1>
+ <title>
+ Targets
+ </title>
+ <para>
+ Targets
+ <footnote><para>Think of a target as the target of
+ interest.</para></footnote>
+ are view or component specific context objects. They contain
+ enough information to be used as stand-alone contexts to implement
+ callbacks for both core functions and plugin hooks. For example for
+ the mail view, a select target contains a folder and a list of
+ selected messages. An attachment (part) target contains the
+ &Camel; representation of the part and the mime-type for
+ that part. Targets are part of the manager implementation and are
+ extended by subclassing the manager.
+ </para>
+ </sect1>
+ </chapter>
+
+ <chapter id="plugin-loaders">
+ <title>
+ Plugin Loaders
+ </title>
+ <para>
+ Plugin loaders implement a hool to a new language, or loading system in the
+ plugin system. The actual binding of new languages to the plugin system or
+ other parst of &Evolution;s api's are beyond the scope of this
+ document, some languages make this easier than others.
+ </para>
+ <sect1 id="plugin-loaders-base">
+ <title>
+ Base Plugin
+ </title>
+ <para>
+ The <link linkend="API-struct--EPlugin">EPlugin base class</link>
+ is an abstract class which provides the basic services for plugin
+ implementations. The main services are:
+ <itemizedlist>
+ <listitem><simpara>Resolve plugin type and instantiate an EPlugin
+ object to represent and manage it.</simpara></listitem>
+ <listitem><simpara>Load the base structure of the XML plugin
+ definition files.</simpara></listitem>
+ <listitem><simpara>Resolve plugin hook types and instantiate a
+ EPluginHook to represent and manage it.</simpara></listitem>
+ <listitem><simpara>Provide a simple, language-independent api for
+ invoking plugin callbacks</simpara></listitem>
+ <listitem><simpara>Provide I18N context for plugins.</simpara></listitem>
+ <listitem><simpara>Some simple static helper methods to simplify each
+ implementing class.</simpara></listitem>
+ </itemizedlist>
+ See the <xref linkend="REF-EPlugin"/> for
+ these details.
+ </para>
+
+ <sect2 id="plugin-loaders-definition">
+ <title>Definition of a Plugin</title>
+ <para>
+ The base plugin XML definition. Subclasses of EPlugin extend this
+ basic structure with additional parameters or elements as they
+ require.
+ </para>
+ <para>
+ Note that there may be any number of <sgmltag>e-plugin</sgmltag>
+ elements in a given plugin file, this may be used to simplify
+ distribution of plugin packages.
+ </para>
+ <programlisting>
+ <![CDATA[
+<?xml version="1.0">
+<e-plugin-list>
+ <e-plugin
+ type="loader type"
+ domain="translation domain" ?
+ name="plugin name"
+ ...>
+ <description>long description</description> ?
+ <hook
+ class="hook class"
+ ...>
+ ...
+ </hook> +
+ </e-plugin> +
+</e-plugin-list>]]></programlisting>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <simpara>
+ The type name of the plugin loader. Currently <link
+ linkend="plugin-loaders-lib">shlib</link> and <link
+ linkend="plugin-loaders-mono">mono</link> are the only
+ supported values. If no known handler is registered for this
+ type, the plugin definition is silently ignored.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>domain</parameter></term>
+ <listitem>
+ <simpara>
+ The translation domain for this plugin, as passed to the
+ <function>dcgettext</function> call of the gettext package.
+ If not supplied then the default application domain is used
+ (i.e. &quot;evolution&quot;). This is used to translate
+ translatable strings for display.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>name</parameter></term>
+ <listitem>
+ <simpara>
+ A short name for the plugin. &quot;Bob's Wonder
+ Extender&quot; might be suitable. This value will be
+ translated.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>description</parameter></term>
+ <listitem>
+ <simpara>
+ A longer description of the plugin's purpose. This value will be
+ translated.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>hook</parameter></term>
+ <listitem>
+ <simpara>
+ This is a list of all of the hooks that this plugin wishes to
+ hook into. See the <link linkend="plugin-hooks">Plugin
+ Hooks</link> section for the details of the basic hook
+ types defined.
+ </simpara>
+ <simpara>
+ The hook <parameter>class</parameter> is resolved using the
+ registered hook types, and if none can be found, or a version
+ mismatch occurs, then the hook is silently ignored.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ </sect1>
+
+ <sect1 id="plugin-loaders-lib">
+ <title>
+ Shared Library Loader
+ </title>
+ <para>
+ The shared library loader <link
+ linkend="API-struct--EPluginLib">EPluginLib</link> implements a
+ concrete EPlugin type which loads GNU shared libraries via the
+ GModule api. It simply resolves symbols directly from the loaded
+ shared object and invokes them with the same arguments as the
+ <link linkend="API-e-plugin-invoke">e_plugin_invoke</link> method.
+ </para>
+
+ <sect2 id="plugin-loaders-lib-definition">
+ <title>Definition</title>
+ <para>The shared library loader only requires one extra parameter in
+ the base plugin definition.
+ </para>
+ <programlisting>
+ <![CDATA[
+<e-plugin
+ ...
+ type="shlib"
+ location="/full/path/name.so"
+ ...
+ <hook class="...">
+ ...
+</e-plugin>]]></programlisting>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <simpara>
+ The type name of the shared library plugin is
+ <constant>shlib</constant>.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>location</parameter></term>
+ <listitem>
+ <simpara>
+ The location parameter contains
+ the full path-name of a shared object to load.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2 id="plugin-loaders-lib-invocation">
+ <title>Invocation</title>
+ <simplesect>
+ <title>Function specification
+ </title>
+ <para>Where a function spec is required in a plugin
+ hook definition, it should simply be the full name of an
+ exported symbol in the shared object.
+ </para>
+ </simplesect>
+ <simplesect>
+ <title>Callback signature</title>
+ <funcsynopsis><funcprototype>
+ <funcdef>void * <function>function</function></funcdef>
+ <paramdef>EPlugin * <parameter>ep</parameter></paramdef>
+ <paramdef>void * <parameter>data</parameter></paramdef>
+ </funcprototype></funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><function>function</function></term>
+ <listitem>
+ <simpara>
+ The callback function.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>ep</parameter></term>
+ <listitem>
+ <simpara>
+ The container EPlugin representing this plugin.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>data</parameter></term>
+ <listitem>
+ <simpara>
+ Hook context data. It is part of the hook's api to specify
+ the type of this pointer.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>return value</returnvalue></term>
+ <listitem>
+ <simpara>
+ Return data. It is part of the hook's api to specify the
+ type of this pointer.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </simplesect>
+ </sect2>
+ </sect1>
+
+ <sect1 id="plugin-loaders-mono">
+ <title>
+ Mono Assembly Loader
+ </title>
+ <para>
+ The mono assembly loader <link
+ linkend="API-struct--EPluginMono">EPluginMono</link> implements a
+ concrete EPlugin type which loads C# assemblies using Mono. Apart
+ from loading the assembly, it can optionally instantiate a class to
+ implement the callback or invoke static methods directly.
+ </para>
+
+ <sect2 id="plugin-loaders-mono-definition">
+ <title>Definition</title>
+ <para>The mono assembly loader needs the name of the assembly and
+ optionally the name of the class for handling the callbacks.
+ </para>
+ <programlisting>
+ <![CDATA[
+<e-plugin
+ ...
+ type="mono"
+ location="/full/path/name.dll"
+ handler="PluginClass" ?
+ ...
+ <hook class="...">
+ ...
+</e-plugin>]]></programlisting>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <simpara>
+ The type name of a mono assembly plugin is
+ <constant>mono</constant>.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>location</parameter></term>
+ <listitem>
+ <simpara>
+ The location parameter contains
+ the full path-name of an assembly to load.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>handler</parameter></term>
+ <listitem>
+ <simpara>
+ If supplied, the handler contains the fully qualified name of
+ the class which handles all callbacks for this plugin. If a
+ handling class is used, then the function specifications
+ become relative to this class.
+ </simpara>
+ <simpara>
+ This class will be
+ instantiated once upon the first callback invocation, and
+ remain active for the life of the plugin (or application).
+ </simpara>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2 id="plugin-loaders-mono-invocation">
+ <title>Invocation</title>
+ <simplesect>
+ <title>Function specification
+ </title>
+ <para>If no <parameter>handler</parameter> class is specified, then
+ the function specification must match a static method in the
+ assembly. This is passed to <function>mono_method_desc_new</function>
+ and <function>mono_method_desc_search_in_image</function>,
+ typically <function>FunctionName(intptr)</function>.
+ </para>
+ <para>
+ If the handler is specified, then the function specification is
+ relative to the handler class. This is passed to
+ <function>mono_method_desc_new</function> and
+ <function>mono_method_desc_search_in_class</function>, typically
+ <function>:MethodName(intptr)</function>.
+ </para>
+ </simplesect>
+ <simplesect>
+ <title>Callback signature</title>
+ <funcsynopsis><funcprototype>
+ <funcdef>IntPtr <function>function</function></funcdef>
+ <paramdef>IntPtr <parameter>data</parameter></paramdef>
+ </funcprototype></funcsynopsis>
+ <variablelist>
+ <varlistentry>
+ <term><function>function</function></term>
+ <listitem>
+ <simpara>
+ The callback method.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>data</parameter></term>
+ <listitem>
+ <simpara>
+ The hook context data. This is a pointer to unmanaged data, and it is up-to the plugin to interpret this
+ data right now, although some helper binding classes are
+ planned. FIXME: hook-up when they and doco are done.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><returnvalue>return value</returnvalue></term>
+ <listitem>
+ <simpara>
+ The callback return data. It is up to the hook's api to
+ define the type of this pointer. It may be a simple boxed
+ value type, or a memory pointer allocated in unmanaged memory (e.g. a
+ GObject handle or a CamelObject cobject value).
+ </simpara>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </simplesect>
+ </sect2>
+ </sect1>
+
+ </chapter>
+
+ <chapter id="plugin-hooks">
+ <title>
+ Plugin Hooks
+ </title>
+ <para>
+ This chapter will introduce the available plugin hook types. A given
+ plugin can hook into any of these hooks any number of times. Some refer
+ to specific instances of objects and others are implicitly defined.
+ </para>
+ <para>
+ By design, there is considerable similarity and orthogonality amongst
+ all of the various hook types and management objects.
+ </para>
+ <sect1 id="plugin-hooks-popup">
+ <title>
+ Popup Menus
+ </title>
+ <para>
+ The popup menu hook lets you hook into any of the context menus in
+ &Evolution;, by name and context. Complex, dynamic, and multi-level
+ menus are created on the fly by merging the items for a given menu as
+ it is being shown. Each component provides its own context targets to
+ self-describe the situation under which the menu is invoked. Plugins
+ and core code alike are then invoked at the user's direction. The
+ popup manager and all context data lives as long as the menu and
+ until a choice is made, simplifying memory management.
+ </para>
+ <para>
+ The menu is merged from multiple plugins and core application code by
+ using a simple lexiographical sort of an absolute path to the menu
+ item. This merged list is then scanned and expanded into a tree of
+ menus. Individual items can be hidden or inactive based on the target
+ and a simple mask which is defined by the component itself. A rich
+ collection of menu item types are possible, from simple, to
+ checkboxes or images. The popup code is simple, and easy to use, and
+ simplifies the use of popup menu's in the core application anyway,
+ that they are pluggable is a free-bonus.
+ </para>
+ <sect2>
+ <title>Defining a popup hook</title>
+ <para>
+ Not sure if this fits here as such. Probably temporary placeholder.
+ </para>
+ <programlisting>
+ <![CDATA[
+<hook class="com.ximian.evolution.mail.popup:1.0">
+ <menu id="menuid" target="targettype">
+ <item
+ type="item | toggle | radio | image | submenu | bar"
+ active ?
+ path="foo/bar"
+ label="menu text"
+ icon="icon name" ?
+ visible="target mask" ?
+ enable="target mask" ?
+ activate="function spec"/> *
+ </menu> *
+</hook>]]></programlisting>
+ <!-- this is all too bloody verbose, is there a better way? -->
+ <para>
+ <emphasis>Need to define menu tag</emphasis>
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <simpara>
+ The menu item type. The type maps directly to the
+ corresponding EPopupItem types.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>active</parameter></term>
+ <listitem>
+ <simpara>
+ If present, then radio or toggle menu items are active when
+ first shown. After the first instantiation, they will
+ remember their active state.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>path</parameter></term>
+ <listitem>
+ <simpara>
+ A '/' separated path used to position the item within menu
+ and in the right submenu. Each menu and plugin should
+ define how its menu's are layed out so other plugins can
+ determine what value to use here.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>label</parameter></term>
+ <listitem>
+ <simpara>
+ The text to be displayed on the menu item. This will be
+ translated based on the plugin translation domain.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>icon</parameter></term>
+ <listitem>
+ <simpara>
+ The name of a gnome-icon-theme standard icon, or the full
+ path-name of an icon image to use as menu item icon. This
+ will be blank if not supplied.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>visible</parameter></term>
+ <listitem>
+ <simpara>
+ A comma separated list of mask enumeration values used to
+ define when this item is shown. What values are valid
+ depend on the menu hook class of the menu being hooked
+ onto.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>enable</parameter></term>
+ <listitem>
+ <simpara>
+ A comma separated list of mask enumeration values used to
+ define when this item is enabled. What values are valid
+ depend on the menu hook class of the menu being hooked
+ onto. This is currently unimplemented.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>activate</parameter></term>
+ <listitem>
+ <simpara>
+ A plugin-type specific function specification. This
+ function will be resolved and called when the menu item is
+ activated.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ <sect2>
+ <title>Merging Plugin Items</title>
+ <para>
+ A very simple algorithm is used to form the menu by merging the
+ plugin's menu items with the system menu items for a given menu.
+ What follows is a simple example of how this is done. It will be
+ demonstrated using a simplified menu from the message-list, as used
+ in the &Evolution; Mail component, and a simple plugin which adds a
+ single menu item and menu separator into the middle of the menu,
+ when appropriate.
+ </para>
+ <para>
+ When the application wishes to show a specific popup menu, it
+ creates a new EPopup object with a unique menu id to manage it. It
+ adds all of the items it wishes to add to the menu (see "Builtin
+ Items" in the following diagrams). The application then asks for
+ the menu to be created. The menu building
+ process adds all of the menu items from all plugins that target
+ this specific menu into a flat list, discarding those which don't
+ match the current Target qualifications. The result is then
+ sorted using a simple ASCII sort, and then a menu built from the
+ remaining items. This is probably best described by some diagrams.
+ </para>
+ <para>
+ The following two diagrams show how a popup menu is automatically
+ customised depending on the context. On the left of each diagram
+ are all of the menu items which apply to the example menu. The
+ menu label, with the qualifiers listed underneath, with the menu
+ item path along-side. On the right-hand side of each diagram is
+ the result of:
+ </para>
+ <itemizedlist>
+ <listitem><simpara>Selecting items based on the target
+ qualifiers</simpara></listitem>
+ <listitem><simpara>Sorting the remaining items based on their
+ path.</simpara></listitem>
+ <listitem><simpara>Building this sorted list into a
+ menu.</simpara></listitem>
+ </itemizedlist>
+
+ <para>
+ The actual list of target qualifiers are defined by the application
+ itself. Generally a specific menu will have only one possible
+ target, and a list of matching target qualifiers. The example
+ shows how a plugin can insert a menu item anwhere it wishes in the
+ menu system. Submenus are also supported, and they work in exactly
+ the same manner, with / characters used to separate submenu paths.
+ A submenu must sort into the position immediately before the
+ definition of its items.
+ </para>
+
+ <figure id="e-popup-merge-1">
+ <title>Merging a menu with many items selected.</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/e-popup-merge-1.pic" format="PIC" />
+ </imageobject>
+ <imageobject>
+ <imagedata fileref="images/e-popup-merge-1.eps" format="EPS"/>
+ </imageobject>
+ <imageobject>
+ <imagedata fileref="images/e-popup-merge-1.png" format="PNG"/>
+ </imageobject>
+ <textobject>
+ <phrase>Showing how a display list of menu items is selected
+ and then sorted for display.</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+
+ <para>
+ The first diagram shows when the target qualifiers are
+ <parameter>many</parameter>, and
+ <parameter>mark_unread</parameter>. The menu items which operate
+ on only one selected message are not shown. Similarly for those
+ able to be marked as unread (i.e. they are currently read).
+ </para>
+
+ <figure id="e-popup-merge-2">
+ <title>Merging a menu with one item selected.</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/e-popup-merge-2.pic" format="PIC"/>
+ </imageobject>
+ <imageobject>
+ <imagedata fileref="images/e-popup-merge-2.eps" format="EPS"/>
+ </imageobject>
+ <imageobject>
+ <imagedata fileref="images/e-popup-merge-2.png" format="PNG"/>
+ </imageobject>
+ <textobject>
+ <phrase>Showing how a display list of menu items is selected
+ and then sorted for display with different qualifiers.</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+
+ <para>
+ This diagram shows when the target qualifiers are
+ <parameter>one</parameter>, and
+ <parameter>mark_read</parameter>. The menu items which operate
+ on only many selected messages are not shown. Similarly for those
+ able to be marked as read.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="plugin-hooks-menu">
+ <title>
+ Main menus
+ </title>
+ <para>
+ The main menu hook lets you hook into various main menus in
+ &Evolution;, based on the current active view (component). The system
+ works by piggy-backing on the existing use of the BonoboUI menu
+ system used by all of the &Evolution; components. Bonobo handles the
+ menu merging and user input, and the hook resolves the verb being
+ invoked and redirects it to the plugin. Each view defines a single
+ target which describes the appropriate context. For the Mail view,
+ this is the current folder and currently selected message(s).
+ </para>
+ <para>
+ Each view keeps track of its own manager object. When it is
+ (de)activated, it also (de)activates the management object which
+ dynamically adds and removes the menu items from the
+ BonoboUIContainer via a supplied BonoboUI XML definition file
+ &lt;perhaps it should embed the bonobouixml&gt;. If the target
+ changes, the view lets the manager know, and it updates the
+ visibility and sensitivity of objects appropriately, allowing
+ reasonably dynamic user-interfaces to be managed automatically. The
+ plugin itself isn't loaded until the menu item in question is invoked
+ </para>
+ <para>
+ Simple menu items and toggle menu items are supported currently.
+ Also, because actual menu display is driven by BonoboUI, then toolbar
+ items can also be added using this mechanism.
+ </para>
+ <sect2>
+ <title>Defining a menu hook</title>
+ <para>
+ Not sure if this fits here as such. Probably temporary placeholder.
+ </para>
+ <programlisting>
+ <![CDATA[
+<hook class="com.ximian.evolution.mail.bonoboMenu:1.0">
+ <menu id="menuid" target="targettype"
+ <ui file="/path/to/bonobo-ui-menu-definition.xml"> +
+ <item
+ type="item | toggle | radio"
+ active ?
+ path="/commands/FooBar"
+ verb="FooBar"
+ visible="target mask" ?
+ enable="target mask" ?
+ activate="function spec"/> *
+ </menu> *
+</hook>]]></programlisting>
+ <para>
+ <emphasis>Need to define menu tag</emphasis>
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>ui</parameter></term>
+ <listitem>
+ <simpara>
+ The <parameter>ui</parameter> element contains a filename of the
+ BonoboUI XML menu definition to load when the view is activated. Any number of
+ <parameter>ui</parameter> elements may be defined, and they
+ are all loaded.
+ </simpara>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <simpara>
+ The menu item type. The type maps directly to the
+ corresponding EMenuItem types.
+ <parameter>radio</parameter> is currently not implemented.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>active</parameter></term>
+ <listitem>
+ <simpara>
+ If present, then radio or toggle menu items are active when
+ first shown. After the first instantiation, they will
+ remember their active state.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>path</parameter></term>
+ <listitem>
+ <simpara>
+ The BonoboUI element path corresponding to this menu item.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>verb</parameter></term>
+ <listitem>
+ <simpara>
+ The BonoboUI verb corresponding to the item to be listened to.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>visible</parameter></term>
+ <listitem>
+ <simpara>
+ A comma separated list of mask enumeration values used to
+ define when this item is shown. What values are valid
+ depend on the menu hook class of the menu being hooked
+ onto.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>enable</parameter></term>
+ <listitem>
+ <simpara>
+ A comma separated list of mask enumeration values used to
+ define when this item is sensitive. What values are valid
+ depend on the menu hook class of the menu being hooked
+ onto.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>activate</parameter></term>
+ <listitem>
+ <simpara>
+ A plugin-type specific function specification. This
+ function will be resolved and called when the menu item is
+ activated. The funciton's parameters will depend on the type
+ of menu item being invoked.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ <sect2>
+ <title>Merging Plugin Items</title>
+ <para>
+ Merging is performed by BonoboUI, and the source of the menu data
+ is defined by the <parameter>ui</parameter> file.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="plugin-hooks-config">
+ <title>
+ Configuration Pages and Wizards
+ </title>
+ <para>
+ Configuration pages are somewhat more complex than any of the other
+ types of hookable object. This is reflected in the complexity of the
+ items and callbacks involved.
+ </para>
+ <para>
+ Essentially, the EConfig object is used in combination to both
+ instrument existing windows and building new content. Each
+ configuration window comprises of several basic elements with some
+ minor variations allowed. It consists of a number of pages in a
+ specific order, each containing a number of titled sections in a specific
+ order, each containing a number of items. The variations are that
+ the top-level widget may be a GtkNotebook or a GnomeDruid; and each
+ section may instrument a GtkBox, or a GtkTable. The definition of
+ the available hooks will define what form they take.
+ </para>
+ <para>
+ The EConfig manager uses the description of all the items supplied to
+ it to build the complete window. It can also drive various aspects
+ of the UI, such as navigating through a druid or handling
+ instant-apply vs. modify-and-save dialogues.
+ </para>
+ <figure id="e-config-flow">
+ <title>Event and Data Flow in EMConfig</title>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="images/e-config-flow.pic" format="PIC"/>
+ </imageobject>
+ <imageobject>
+ <imagedata fileref="images/e-config-flow.eps" format="EPS"/>
+ </imageobject>
+ <imageobject>
+ <imagedata fileref="images/e-config-flow.png" format="PNG"/>
+ </imageobject>
+ <textobject>
+ <phrase>The flow of information and control signals in the
+ configuration management object.</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+
+ <sect2>
+ <title>Defining a configuration page hook</title>
+ <para>
+ Not sure if this fits here as such. Probably temporary placeholder.
+ </para>
+ <programlisting>
+ <![CDATA[
+<hook class="com.ximian.evolution.mail.bonoboMenu:1.0">
+ <group
+ id="window id"
+ target="targettype"
+ commit="function spec"?
+ abort="function spec"?>
+ <item
+ type="book | druid | page | page_start | page_finish | section | section_table | item"
+ path="/absolute/path"
+ label="name" | factory="function spec"
+ /> *
+ </menu> *
+</hook>]]></programlisting>
+ <para>
+ <emphasis>Need to define group tag</emphasis>
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <simpara>
+ The menu item type. The type maps directly to the
+ corresponding EConfigItem types. Only one of
+ <parameter>book</parameter> and <parameter>druid</parameter>
+ may be supplied for the entire configuration page, and this
+ will usually already be defined by the application.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>path</parameter></term>
+ <listitem>
+ <simpara>
+ The path to the configuration item in question. This is a
+ simple string that when sorted using an ASCII sort will place
+ the items in the right order. That is, sections before items
+ before pages before the root object.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>label</parameter></term>
+ <listitem>
+ <simpara>
+ The textual label of this item. This may only be supplied
+ for the section and page types. For sections it will be the
+ section frame text. For pages this will be the druid page
+ title or the notebook tab text. If a
+ <parameter>factory</parameter>is supplied then this value is
+ not used. This will be translated based on the plugin
+ translation domain.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>factory</parameter></term>
+ <listitem>
+ <simpara>
+ If supplied, the factory method used to create the GtkWidget
+ elements for this configuration item. Factories may be
+ supplied for any of the item types. If no
+ <parameter>label</parameter> is set then the
+ <parameter>factory</parameter> must be set.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ <sect2>
+ <title>Generating Configuration Pages</title>
+ <para>
+ Configuration items essentially spam 3 dimensions, but are
+ merged in a similar fashion to the way Popup items are merged. The
+ main difference is that there are no target qualifiers used to
+ select which items are shown, it is up to the item factory to
+ either create or not create the item as it sees fit. The EConfig
+ manager takes care of the rest, including removing un-used sections
+ or pages.
+ </para>
+ <para>
+ All items for a given configuration screen are converted into a
+ list and sorted based on the <parameter>path</parameter>. The
+ configuration builder then goes through each item, creating
+ container widgets or calling factories as required. If a given
+ page or section is empty, then it is removed automatically. This
+ process isn't only a one-off process. For certain complex
+ configuration screens, items or even pages and sections need to be
+ dynamic based on a previous setting. EConfig supports this mode of
+ operation too, in which case it re-builds the configuration screen
+ the same way, and automatically destroys the old widgets
+ <footnote><simpara>In most cases, in some cases additional manual
+ processing is required in the factory
+ callback.</simpara></footnote> and even re-orders pages and
+ sections where appropriate to make the user-interface consistent.
+ </para>
+ <para>
+ The following few examples some of the flexibility of the EConfig
+ system.
+ </para>
+ <figure id="e-config-build-1">
+ <title>The application defined, unaltered configuration page.</title>
+ <mediaobject>
+ <!-- do we need to build our own eps for the image? -->
+ <imageobject>
+ <imagedata fileref="images/e-config-build-1.png" format="PNG"/>
+ </imageobject>
+ <textobject>
+ <phrase>Shows the original HTML Mail settings page.</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+ <para>
+ First we have the original configuration window. This is defined
+ by the application, the application uses EConfig to build this
+ window, and in the process EConfig instruments the sections that
+ the application defines. This allows plugins to add new
+ pages/sections/items anywhere on the page - to a granularity as
+ defined by the application. For example the application may at
+ minimum merely define the top-level notebook or druid object and a
+ number of pages. When the pages are created the application could
+ add as much content as it wants, which would still allow plugins to
+ extend the user interface, but only by adding options to the end of
+ each page. At the other end of the scale the application could
+ enumerate every single item (i.e. row) in every section on every
+ page, allowing plugins to put new items anywhere in the display.
+ </para>
+ <figure id="e-config-build-2">
+ <title>A plugin adding a new section to an existing page.</title>
+ <mediaobject>
+ <!-- do we need to build our own eps for the image? -->
+ <imageobject>
+ <imagedata fileref="images/e-config-build-2.png" format="PNG"/>
+ </imageobject>
+ <textobject>
+ <phrase>Shows the HTML Mail settings page with a new section
+ and item added by a plugin.</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+ <para>
+ In this case the plugin has merely added a new section on the
+ bottom of the HTML Mail settings page. When the factory is called
+ the plugin has a parent GtkTable (in this case, it could be a VBox)
+ and borderless frame already defined, and it just has to
+ instantiate its own control widgets, add them to the table, and
+ return one of the widgets. The returned widget is used later if
+ the window needs to be reconfigured, although this particular configuration
+ page is static so it isn't needed.
+ </para>
+ <figure id="e-config-build-3">
+ <title>A plugin inserting a new page for its settings.</title>
+ <mediaobject>
+ <!-- do we need to build our own eps for the image? -->
+ <imageobject>
+ <imagedata fileref="images/e-config-build-3.png" format="PNG"/>
+ </imageobject>
+ <textobject>
+ <phrase>Shows the plugin adding a new page for its setting as
+ an alternative.</phrase>
+ </textobject>
+ </mediaobject>
+ </figure>
+ <para>
+ And finally we have exactly the same plugin, which has exactly the
+ same code. But a small change to the plugin definition allows the
+ plugin to add an arbitrary new page (in an arbitrary position) into
+ the whole window. If this was a druid, then new druid pages can
+ also be inserted at arbitrary locations, and page navigation (in a
+ strictly linear manner) is automatically controlled by EConfig as
+ per <xref linkend="e-config-flow"/>.
+ </para>
+ <para>
+ In practice, EConfig provides more than it takes the application to
+ use - generally little or no extra application code is required to
+ use it. It also
+ <footnote><simpara>Or it will - the code needs some
+ tweaking.</simpara></footnote> enforces and simplifies HIG
+ compliance. And as a side-benefit to the application it
+ transparently provides extension hooks for
+ external code to provide a seamlessly integrated user experience.
+ </para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="plugin-hooks-event">
+ <title>
+ Events
+ </title>
+ <para>
+ No extensibility framework would be complete without an event
+ system. Events are used to reflect changes in internal state of the
+ application, and track actions by the user. They can contain any
+ information and additionally can be filtered based on the information
+ itself. Special targets are used, as in the other plugin hooks, to
+ hold this information.
+ </para>
+ <para>
+ Event managers are defined to contain the different event types that
+ a given component can export. Only one event manager object is
+ instantiated for each component, and each plugin listening to events
+ from that component are registered on that event manager directly.
+ </para>
+ <para>
+ Events handlers have priorities, and can swallow events, allowing
+ some level of complexity of event routing. This feature might not
+ prove useful and may be removed in the future if it isn't.
+ </para>
+ <sect2>
+ <title>Defining an event hook</title>
+ <para>
+ Not sure if this fits here as such. Probably temporary placeholder.
+ </para>
+
+ <programlisting>
+ <![CDATA[
+<hook class="com.ximian.evolution.mail.events:1.0">
+ <event
+ type="pass | sink"
+ priority="signed integer"
+ id="event name"
+ enable="target mask" ?
+ handle="function spec"/> *
+ </event> *
+</hook>]]></programlisting>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>type</parameter></term>
+ <listitem>
+ <simpara>
+ The event listener type. The type maps directly to the corresponding
+ corresponding EEventItem types.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>priority</parameter></term>
+ <listitem>
+ <simpara>
+ A signed integer specifying the priority of this event
+ listener. 0 (zero) should be used normally, although positive
+ and negative integers in the range -128 to 127 may aslo be
+ used.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>id</parameter></term>
+ <listitem>
+ <simpara>
+ The name of the event to listen to.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>enable</parameter></term>
+ <listitem>
+ <simpara>
+ A comma separated list of mask enumeration values used to
+ qualify when this event listener is invoked. What values are valid
+ depend on the event hook class.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>handle</parameter></term>
+ <listitem>
+ <simpara>
+ A plugin-type specific function specification. This
+ function will be resolved and called when an event is routed to
+ this listener.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ </sect1>
+
+ <sect1 id="plugin-hooks-format">
+ <title>
+ Mail Formatter
+ </title>
+ <para>
+ The mail formatter plugin will invoke plugin code to format any part
+ of an email based on mime-type. There are several formatters used
+ internally by the mailer for different contexts, and each can be
+ hooked into separately, providing extensible mail formatting for
+ everything from the primary mail display, to printing, to reply
+ quoting and more. If you are implementing a handler for a given
+ mime-type, each formatter appropriate for the data-type should be
+ hooked into, so that it displays properly in all contexts.
+ </para>
+ <para>
+ Since the management object in this case is the same formatting
+ object as used by the core mail display engine, a plugin may override
+ or reimplement complete new functionality seamlessly.
+ </para>
+ <para>
+ This plugin hook isn't strictly part of the core functionality as it
+ is provided only by the mail component. It however demonstrates that the
+ plugin system is extensible itself.
+ </para>
+ <sect2>
+ <title>Defining a formatter hook</title>
+ <para>
+ Not sure if this fits here as such. Probably temporary placeholder.
+ </para>
+
+ <programlisting>
+ <![CDATA[
+<hook class="com.novell.evolution.mail.format:1.0">
+ <group id="formatter type">
+ <item
+ flags="handler flags"
+ mime_type="major/minor"
+ format="function spec"/> +
+ </group> +
+</hook>]]></programlisting>
+ <variablelist>
+ <varlistentry>
+ <term><parameter>id</parameter></term>
+ <listitem>
+ <simpara>
+ The actual formatter this applies to. e.g. EMFormat for the
+ base formatter class, EMFormatHTML for HTML output to a
+ GtkHTML object, etc.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>flags</parameter></term>
+ <listitem>
+ <simpara>
+ Flags to define whether this is an attachment or inline
+ content.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>id</parameter></term>
+ <listitem>
+ <simpara>
+ The name of the event to listen to.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>mime_type</parameter></term>
+ <listitem>
+ <simpara>
+ The type of object this handler formats.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><parameter>format</parameter></term>
+ <listitem>
+ <simpara>
+ A plugin-type specific function specification. This
+ function will be invoked to format objects of the specified
+ <parameter>mime_type</parameter>.
+ </simpara>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+
+ <sect2>
+ <title>The formatting process</title>
+ <para>
+ The formatting process is driven by the <link
+ linkend="API-struct--EMFormat">EMFormat</link> object, although
+ there are different subclasses of this object used for different
+ purposes. These behave quite differently so each must be explained
+ separately. There is the basic formatter type which converts a
+ CamelMimeMessage into a stream of data, and there is a HTML
+ <link linkend="API-struct--EMFormatHTML">formatter type</link>
+ which uses a GtkHTML object to parse the content
+ and may request further information required to complete the
+ formatting.
+ </para>
+ <para>
+ A basic formatter goes through the following steps:
+ </para>
+ <orderedlist>
+ <listitem>
+ <simpara>Outputs pre-amble information. e.g. Flag-For-Followup
+ status.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>Invokes <methodname>format_message</methodname> to begin the message
+ formatting. <methodname>format_message</methodname> displays the message header, then
+ looks up the content object.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>Using the mime-type of the content object (whether
+ supplied or calculated), a handler is looked up from a
+ per-class table to process the type.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>If no handler exists, then the data is formatted as an
+ attachment.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>If a handler exists, then it is invoked to display that
+ type. Depending on whether the data is to be displayed
+ 'inline' or not, the data may also get an attachment expander
+ and button.</simpara>
+ </listitem>
+ <listitem>
+ <simpara>The handler transforms the part's data, if need be, and
+ writes the appropriate format output to a stream.</simpara>
+ </listitem>
+ </orderedlist>
+ <para>
+ For conglomerate types, the formatting process is continued
+ recursively, until all parts have been displayed, as appropriate.
+ </para>
+ <para>
+ A HTML formatter goes through the same basic steps, but has
+ additional features and requirements. It uses multiple
+ threads. At least one other thread is used for all of the
+ Camel message content operations since some of them may block on
+ remote I/O. This also simplifies cancellation processing. Also,
+ because it has access to a full HTML rendering object, references
+ to embedded content (images, buttons, etc.) are also processed.
+ </para>
+ <para>
+ Most format handlers don't need to know about all the fiddly
+ details however. If they are just outputting HTML content with no
+ out of band references, they work identical to the basic format
+ handlers with the exception they cannot call any Gtk GUI code
+ because of threading issues. This can still be done by using an
+ IFRAME. If they want to embed an icon or other image,
+ they simply need to insert the HTML IMG tag reference in their
+ format handler, and setup a callback to handle it when GtkHTML
+ requests it. EMFormat has some helper classes to make this
+ only a few lines of code, including generation of the IMG SRC URL.
+ IFRAMEs work identically to IMG tags, and similar process is
+ involved with embedding custom widgets using the OBJECT tag.
+ EMFormatHTML takes care of calling the right callbacks for the
+ right embedded reference from the right thread.
+ </para>
+ <para>
+ Since format handlers are chained off a given type, then a plugin
+ can also inherit formatting behaviour as well as override it. This
+ gives much greater flexibility since the plugin need only implement
+ its behaviour in specific situations. e.g. an OpenPGP message
+ handler could fall-back to the normal text-formatter if it doesn't
+ detect the ASCII armour in a text/plain part. Or another handler
+ may disable itself based on configuration or state.
+ </para>
+ <para>
+ All format handlers for all types must also be fully re-entrant
+ code (more or less write-once global and static variables) if
+ they call any other formatting functions.
+ </para>
+ </sect2>
+ </sect1>
+ </chapter>
+ </part>
+
+ <part>
+ <title>
+ &Evolution; Hook Points.
+ </title>
+ <partintro>
+ <para>
+ This section enumerates all of the published hook points and target
+ types available in each component in &Evolution;.
+ </para>
+
+ <simplesect>
+ <title>Table Format</title>
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody>
+ <row>
+ <entry>Name</entry>
+ <entry>The hook point id.</entry>
+ </row>
+ <row>
+ <entry>Target</entry>
+ <entry>The target which this hook uses for its context data.
+ Targets are described in a following section.
+ </entry>
+ </row>
+ <row>
+ <entry>Items</entry>
+ <entry>If appropriate and defined, specifies identifying path
+ names of items which make up the hook. e.g. popup menu
+ items, and configuration pages. These item specifications
+ allow the plugin writer to position their items
+ appropriately.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </simplesect>
+
+ </partintro>
+ <chapter id="mail-hooks">
+ <title>
+ Mail Hooks
+ </title>
+ <para>
+ <emphasis>
+ Need to find out the right docbook to mark-up most of this
+ text.
+ </emphasis>
+ </para>
+
+ <sect1 id="mail-hooks-popup">
+ <title>Popup menus</title>
+
+ <para>
+ The mail popup menu class is
+ <interfacename>com.ximian.evolution.mail.popup:1.0</interfacename>.
+ </para>
+ <para>
+ The plugin callback data will be the target matching the plugin
+ menu itself, and the callback returns no value.
+ </para>
+
+ <sect2>
+ <title>Folder Tree Context Menu</title>
+ <para>
+ This is the context menu shown on the folder tree.
+ </para>
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><interfacename>com.ximian.mail.storageset.popup.select</interfacename></entry>
+ </row>
+ <row>
+ <entry>Target</entry>
+ <entry>
+ <link
+ linkend="mail-hooks-popup-EMPopupTargetFolder">EMPopupTargetFolder</link>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2>
+ <title>Message List Context Menu</title>
+ <para>
+ This is the context menu shown on the message list.
+ </para>
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><interfacename>com.ximian.mail.folderview.popup.select</interfacename></entry>
+ </row>
+ <row>
+ <entry>Target</entry>
+ <entry>
+ <link
+ linkend="mail-hooks-popup-EMPopupTargetSelect">EMPopupTargetSelect</link>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2>
+ <title>Inline URI Context Menu</title>
+ <para>
+ This is the context menu shown when clicking on inline URIs,
+ including addresses or normal HTML links that are displayed inside
+ the message view.
+ </para>
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><interfacename>com.ximian.mail.folderview.popup.uri</interfacename></entry>
+ </row>
+ <row>
+ <entry>Target</entry>
+ <entry><link
+ linkend="mail-hooks-popup-EMPopupTargetURI">EMPopupTargetURI</link></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2>
+ <title>Inline Content and Attachment Context Menu</title>
+ <para>
+ This context menu is shown when right-clicking on inline images, or
+ when clicking on the attachment expander button.
+ </para>
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><interfacename>com.ximian.mail.formathtmldisplay.popup.part</interfacename></entry>
+ </row>
+ <row>
+ <entry>Target</entry>
+ <entry><link
+ linkend="mail-hooks-popup-EMPopupTargetPart">EMPopupTargetPart</link></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2>
+ <title>Composer Attachment Bar Context Menu</title>
+ <para>
+ This context menu is displayed when the user brings up a context
+ menu on the attachment bar displayed in the composer.
+ </para>
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><interfacename>com.novell.evolution.mail.composer.attachmentBar</interfacename></entry>
+ </row>
+ <row>
+ <entry>Target</entry>
+ <entry><link
+ linkend="mail-hooks-popup-EMPopupTargetAttachments">EMPopupTargetAttachments</link></entry>
+ </row>
+ <row>
+ <entry>Qualifiers</entry>
+ <entry>
+ <simplelist>
+ <member><constant>one</constant> = <constant>EM_POPUP_ATTACHMENTS_ONE</constant></member>
+ <member><constant>many</constant> = <constant>EM_POPUP_ATTACHMENTS_MANY</constant></member>
+ </simplelist>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2>
+ <title>Internal popup menus</title>
+ <para>
+ The following popup menus are defined, but they are used with no
+ target, and so provide no useful context if they were to be hooked
+ onto.
+ </para>
+ <para>
+ <interfacename>com.ximian.mail.messagelist.popup.drop</interfacename>
+ is used for the ASK drop type on the message list.
+ </para>
+ <para>
+ <interfacename>com.ximian.mail.storageset.popup.drop</interfacename>
+ is used for the ASK drop type on the folder tree.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Mail Popup Targets</title>
+
+ <para>
+ <emphasis>
+ Not sure if this needs to explain the qualifier meanings, or
+ leave it to the in-line comment stuff in the enumeration
+ definition. Maybe it just needs a direct link to the
+ enumeration.
+ </emphasis>
+ </para>
+
+ <sect3 id="mail-hooks-popup-EMPopupTargetFolder">
+ <title>Folder Target</title>
+
+ <para>
+ This target is used to define actions on a folder context.
+ Normally associated with the folder tree.
+ </para>
+
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><constant>folder</constant></entry>
+ </row>
+ <row>
+ <entry>Structure</entry>
+ <entry>
+ <link
+ linkend="API-struct--EMPopupTargetFolder">EMPopupTargetFolder</link>
+ </entry>
+ </row>
+ <row>
+ <entry>Qualifiers</entry>
+ <entry>
+ <simplelist>
+ <member><constant>folder</constant> = <constant>EM_POPUP_FOLDER_FOLDER</constant></member>
+ <member><constant>store</constant> = <constant>EM_POPUP_FOLDER_STORE</constant></member>
+ <member><constant>inferiors</constant> = <constant>EM_POPUP_FOLDER_INFERIORS</constant></member>
+ <member><constant>delete</constant> = <constant>EM_POPUP_FOLDER_DELETE</constant></member>
+ <member><constant>select</constant> = <constant>EM_POPUP_FOLDER_SELECT</constant></member>
+ </simplelist>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect3>
+
+ <sect3 id="mail-hooks-popup-EMPopupTargetSelect">
+ <title>Selection Target</title>
+
+ <para>This target is used to define context for actions associated
+ with a selection of mail messages from a specific folder.</para>
+
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><constant>select</constant></entry>
+ </row>
+ <row>
+ <entry>Structure</entry>
+ <entry>
+ <link
+ linkend="API-struct--EMPopupTargetSelect">EMPopupTargetSelect</link>
+ </entry>
+ </row>
+ <row>
+ <entry>Qualifiers</entry>
+ <entry>
+ <simplelist>
+ <member><constant>one</constant> = <constant>EM_POPUP_SELECT_ONE</constant></member>
+ <member><constant>many</constant> = <constant>EM_POPUP_SELECT_MANY</constant></member>
+ <member><constant>mark_read</constant> = <constant>EM_POPUP_SELECT_MARK_READ</constant></member>
+ <member><constant>mark_unread</constant> = <constant>EM_POPUP_SELECT_MARK_UNREAD</constant></member>
+ <member><constant>delete</constant> = <constant>EM_POPUP_SELECT_DELETE</constant></member>
+ <member><constant>undelete</constant> = <constant>EM_POPUP_SELECT_UNDELETE</constant></member>
+ <member><constant>mailing_list</constant> = <constant>EM_POPUP_SELECT_MAILING_LIST</constant></member>
+ <member><constant>resend</constant> = <constant>EM_POPUP_SELECT_EDIT</constant></member>
+ <member><constant>mark_important</constant> = <constant>EM_POPUP_SELECT_MARK_IMPORTANT</constant></member>
+ <member><constant>mark_unimportant</constant> = <constant>EM_POPUP_SELECT_MARK_UNIMPORTANT</constant></member>
+ <member><constant>flag_followup</constant> = <constant>EM_POPUP_SELECT_FLAG_FOLLOWUP</constant></member>
+ <member><constant>flag_completed</constant> = <constant>EM_POPUP_SELECT_FLAG_COMPLETED</constant></member>
+ <member><constant>flag_clear</constant> = <constant>EM_POPUP_SELECT_FLAG_CLEAR</constant></member>
+ <member><constant>add_sender</constant> = <constant>EM_POPUP_SELECT_ADD_SENDER</constant></member>
+ <member><constant>mark_junk</constant> = <constant>EM_POPUP_SELECT_MARK_JUNK</constant></member>
+ <member><constant>mark_nojunk</constant> = <constant>EM_POPUP_SELECT_MARK_NOJUNK</constant></member>
+ <member><constant>folder</constant> = <constant>EM_POPUP_SELECT_FOLDER</constant></member>
+ </simplelist>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect3>
+
+ <sect3 id="mail-hooks-popup-EMPopupTargetURI">
+ <title>URI Target</title>
+
+ <para>This target defines context for operations on a URI, normally
+ displayed inline somewhere in the message view.</para>
+
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><constant>uri</constant></entry>
+ </row>
+ <row>
+ <entry>Structure</entry>
+ <entry><link
+ linkend="API-struct--EMPopupTargetURI">EMPopupTargetURI</link></entry>
+ </row>
+ <row>
+ <entry>Qualifiers</entry>
+ <entry>
+ <simplelist>
+ <member><constant>http</constant> = <constant>EM_POPUP_URI_HTTP</constant></member>
+ <member><constant>mailto</constant> = <constant>EM_POPUP_URI_MAILTO</constant></member>
+ <member><constant>notmailto</constant> = <constant>EM_POPUP_URI_NOT_MAILTO</constant></member>
+ </simplelist>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect3>
+
+ <sect3 id="mail-hooks-popup-EMPopupTargetPart">
+ <title>Message Part Target</title>
+
+ <para>This target defines context for operations on messages, or
+ individual message parts. The same target is used for inline
+ images or other content which can be encapsulated in a MIME part
+ (i.e. anything).</para>
+
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><constant>part</constant></entry>
+ </row>
+ <row>
+ <entry>Structure</entry>
+ <entry><link
+ linkend="API-struct--EMPopupTargetPart">EMPopupTargetPart</link></entry>
+ </row>
+ <row>
+ <entry>Qualifiers</entry>
+ <entry>
+ <simplelist>
+ <member><constant>message</constant> = <constant>EM_POPUP_PART_MESSAGE</constant></member>
+ <member><constant>image</constant> = <constant>EM_POPUP_PART_IMAGE</constant></member>
+ </simplelist>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect3>
+
+ <sect3 id="mail-hooks-popup-EMPopupTargetAttachments">
+ <title>Attachments Target</title>
+
+ <para>This target is used to define context for operations on the
+ mail composer attachment bar.</para>
+
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><constant>attachments</constant></entry>
+ </row>
+ <row>
+ <entry>Structure</entry>
+ <entry><link
+ linkend="API-struct--EMPopupTargetAttachments">EMPopupTargetAttachments</link></entry>
+ </row>
+ <row>
+ <entry>Qualifiers</entry>
+ <entry>
+ <simplelist>
+ <member><constant>one</constant> = <constant>EM_POPUP_ATTACHMENTS_ONE</constant></member>
+ <member><constant>many</constant> = <constant>EM_POPUP_ATTACHMENTS_MANY</constant></member>
+ </simplelist>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect3>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="mail-hooks-menu">
+ <title>Main menus</title>
+
+ <para>
+ The mail popup menu class is
+ <interfacename>com.ximian.evolution.mail.bonobomenu:1.0</interfacename>.
+ </para>
+ <para>
+ The plugin callback data will be the target matching the plugin
+ menu itself, and the callback returns no value.
+ </para>
+
+ <sect2>
+ <title>Main Mail Menu</title>
+
+ <para>
+ This is the main mail view embedded in the &Evolution; Shell.
+ </para>
+
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><interfacename>com.novell.evolution.mail.browser</interfacename></entry>
+ </row>
+ <row>
+ <entry>Target</entry>
+ <entry>
+ <link
+ linkend="mail-hooks-menu-EMMenuTargetSelect">EMMenuTargetSelect</link>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2>
+ <title>Standalone Message View Menu</title>
+
+ <para>
+ This is the popup mail-message view.
+ </para>
+
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><interfacename>com.novell.evolution.mail.messagebrowser</interfacename></entry>
+ </row>
+ <row>
+ <entry>Target</entry>
+ <entry>
+ <link
+ linkend="mail-hooks-menu-EMMenuTargetSelect">EMMenuTargetSelect</link>,
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2>
+ <title>Composer Menu</title>
+ <para>
+ This is the mail message composer. This is currently not implemented.
+ </para>
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><interfacename>com.novell.evolution.mail.composer</interfacename></entry>
+ </row>
+ <row>
+ <entry>Target</entry>
+ <entry>Undefined</entry>
+ </row>
+ <row>
+ <entry>Qualifiers</entry>
+ <entry>Undefined</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2>
+ <title>Mail Menu Targets</title>
+
+ <sect3 id="mail-hooks-menu-EMMenuTargetSelect">
+ <title>Message Selection Target</title>
+
+ <para>This target is used to define context for operations on a
+ selection of messages in the view's message list.</para>
+
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><constant>select</constant></entry>
+ </row>
+ <row>
+ <entry>Structure</entry>
+ <entry>
+ <link
+ linkend="API-struct--EMMenuTargeSelect">EMMenuTargetSelect</link>
+ </entry>
+ </row>
+ <row>
+ <entry>Qualifiers</entry>
+ <entry>
+ <simplelist>
+ <member><constant>one</constant> = <constant>EM_MENU_SELECT_ONE</constant></member>
+ <member><constant>many</constant> = <constant>EM_MENU_SELECT_MANY</constant></member>
+ <member><constant>mark_read</constant> = <constant>EM_MENU_SELECT_MARK_READ</constant></member>
+ <member><constant>mark_unread</constant> = <constant>EM_MENU_SELECT_MARK_UNREAD</constant></member>
+ <member><constant>delete</constant> = <constant>EM_MENU_SELECT_DELETE</constant></member>
+ <member><constant>undelete</constant> = <constant>EM_MENU_SELECT_UNDELETE</constant></member>
+ <member><constant>mailing_list</constant> = <constant>EM_MENU_SELECT_MAILING_LIST</constant></member>
+ <member><constant>resend</constant> = <constant>EM_MENU_SELECT_EDIT</constant></member>
+ <member><constant>mark_important</constant> = <constant>EM_MENU_SELECT_MARK_IMPORTANT</constant></member>
+ <member><constant>mark_unimportant</constant> = <constant>EM_MENU_SELECT_MARK_UNIMPORTANT</constant></member>
+ <member><constant>flag_followup</constant> = <constant>EM_MENU_SELECT_FLAG_FOLLOWUP</constant></member>
+ <member><constant>flag_completed</constant> = <constant>EM_MENU_SELECT_FLAG_COMPLETED</constant></member>
+ <member><constant>flag_clear</constant> = <constant>EM_MENU_SELECT_FLAG_CLEAR</constant></member>
+ <member><constant>add_sender</constant> = <constant>EM_MENU_SELECT_ADD_SENDER</constant></member>
+ <member><constant>mark_junk</constant> = <constant>EM_MENU_SELECT_MARK_JUNK</constant></member>
+ <member><constant>mark_nojunk</constant> = <constant>EM_MENU_SELECT_MARK_NOJUNK</constant></member>
+ <member><constant>folder</constant> = <constant>EM_MENU_SELECT_FOLDER</constant></member>
+ </simplelist>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 id="mail-hooks-config">
+ <title>Config Windows and Druids</title>
+
+ <para>
+ The mail config class is
+ <interfacename>com.novell.evolution.mail.config:1.0</interfacename>.
+ </para>
+
+ <sect2>
+ <title>Account Editor Druid</title>
+ <para>
+ This is the GnomeDruid which is shown when you create a new mail account.
+ </para>
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><interfacename>com.novell.evolution.mail.config.accountDruid</interfacename></entry>
+ </row>
+ <row>
+ <entry>Target</entry>
+ <entry>
+ <link
+ linkend="mail-hooks-config-EMConfigTargetAccount">EMConfigTargetAccount</link>
+ </entry>
+ </row>
+ <row>
+ <entry>Items</entry>
+ <entry>Define some of the items available and where they fit
+ in the gui</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2>
+ <title>Account Editor Window</title>
+ <para>
+ This is the editor notebook which is shown when you edit an
+ existing mail account.
+ </para>
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><interfacename>com.novell.evolution.mail.config.accountEditor</interfacename></entry>
+ </row>
+ <row>
+ <entry>Target</entry>
+ <entry>
+ <link
+ linkend="API-struct--EMConfigTargetAccount">EMConfigTargetAccount</link>, plugin target is &quot;<constant>account</constant>&quot;.
+ </entry>
+ </row>
+ <row>
+ <entry>Items</entry>
+ <entry>Define some of the items available and where they fit
+ in the gui</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2>
+ <title>Composer Preferences</title>
+ <para>
+ This is the notebook of configuration items for the composer which
+ are accessed via the main settings window under the Composer tab.
+ </para>
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><interfacename>com.novell.evolution.mail.composerPrefs</interfacename></entry>
+ </row>
+ <row>
+ <entry>Target</entry>
+ <entry>
+ <link
+ linkend="mail-hooks-config-EMConfigTargetPrefs">EMConfigTargetPrefs</link>
+ </entry>
+ </row>
+ <row>
+ <entry>Items</entry>
+ <entry>Define some of the items available and where they fit
+ in the gui</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2>
+ <title>Mail Preferences</title>
+ <para>
+ This is the notebook of configuration items for the mailer which
+ are accessed via the main settings window under the Mail Settings tab.
+ </para>
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><interfacename>com.novell.evolution.mail.prefs</interfacename></entry>
+ </row>
+ <row>
+ <entry>Target</entry>
+ <entry>
+ <link
+ linkend="mail-hooks-config-EMConfigTargetPrefs">EMConfigTargetPrefs</link>
+ </entry>
+ </row>
+ <row>
+ <entry>Items</entry>
+ <entry>Define some of the items available and where they fit
+ in the gui</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2>
+ <title>Folder Properties</title>
+ <para>
+ This is the notebook of configuration items for a given mail folder
+ which is accessed via the Folder Properties item in the main menu item or
+ folder-tree context menu.
+ </para>
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><interfacename>com.novell.evolution.mail.folderConfig</interfacename></entry>
+ </row>
+ <row>
+ <entry>Target</entry>
+ <entry>
+ <link
+ linkend="mail-hooks-config-EMConfigTargetFolder">EMConfigTargetFolder</link>
+ </entry>
+ </row>
+ <row>
+ <entry>Items</entry>
+ <entry>Define some of the items available and where they fit
+ in the gui</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2>
+ <title>Mail Config Targets</title>
+
+ <sect3 id="mail-hooks-config-EMConfigTargetAccount">
+ <title>Account Target</title>
+
+ <para>The account target is used for configuring accounts, and so
+ has a pointer to the EAccount being configured. This is a copy
+ of the actual account object, and is copied to the original once
+ the data is ready to commit.</para>
+
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><constant>account</constant></entry>
+ </row>
+ <row>
+ <entry>Structure</entry>
+ <entry>
+ <link
+ linkend="API-struct--EMConfigTargetAccount">EMConfigTargetAccount</link>
+ </entry>
+ </row>
+ <row>
+ <entry>Items</entry>
+ <entry>Define some of the items available and where they fit
+ in the gui</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect3>
+
+ <sect3 id="mail-hooks-config-EMConfigTargetPrefs">
+ <title>Preferences Target</title>
+
+ <para>The preferences target is used for global preferences. As
+ such it just contains a pointer to the global configuration store
+ - a GConfClient.</para>
+
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><constant>prefs</constant></entry>
+ </row>
+ <row>
+ <entry>Structure</entry>
+ <entry>
+ <link
+ linkend="API-struct--EMConfigTargetPrefs">EMConfigTargetPrefs</link>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect3>
+
+ <sect3 id="mail-hooks-config-EMConfigTargetFolder">
+ <title>Folder Target</title>
+
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><constant>folder</constant></entry>
+ </row>
+ <row>
+ <entry>Structure</entry>
+ <entry>
+ <link
+ linkend="API-struct--EMConfigTargetFolder">EMConfigTargetFolder</link>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect3>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="mail-hooks-event">
+ <title>Events</title>
+
+ <para>
+ The mail event class is
+ <interfacename>com.ximian.evolution.mail.events:1.0</interfacename>.
+ </para>
+
+ <sect2>
+ <title>Folder Changed Event</title>
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><constant>folder.changed</constant></entry>
+ </row>
+ <row>
+ <entry>Target</entry>
+ <entry>
+ <link
+ linkend="mail-hooks-event-EMEventTargetFolder">EMEventTargetFolder</link>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2>
+ <title>Mail Event Targets</title>
+
+ <sect3 id="mail-hooks-event-EMEventTargetFolder">
+ <title>Folder Target</title>
+
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><constant>folder</constant></entry>
+ </row>
+ <row>
+ <entry>Structure</entry>
+ <entry>
+ <link
+ linkend="API-struct--EMEventTargetFolder">EMEventTargetFolder</link>
+ </entry>
+ </row>
+ <row>
+ <entry>Qualifiers</entry>
+ <entry>List qualifiers</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect3>
+ </sect2>
+ </sect1>
+
+ <sect1 id="mail-hooks-format">
+ <title>Formatters</title>
+
+ <para>
+ The mail formatter hook class is
+ <interfacename>com.novell.evolution.mail.format:1.0</interfacename>.
+ </para>
+
+ <sect2>
+ <title>Base Formatter</title>
+
+ <para>
+ The EMFormat class is the base class for all formatting types.
+ It should only be used to define compound and complex types which
+ do not rely on outputting any textual information, or rely on any
+ screen or print output differences.
+ </para>
+
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><constant>EMFormat</constant></entry>
+ </row>
+ <row>
+ <entry>Target</entry>
+ <entry>
+ <link
+ linkend="mail-hooks-format-EMFormatHookTarget">EMFormatHookTarget</link>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2>
+ <title>HTML Formatter</title>
+
+ <para>
+ The EMFormatHTML class is the base class for most formatting types
+ which generate HTML output. It renders output to a GtkHTML
+ object. It uses a fairly complex multi-thread approach to the
+ formatting to ensure the user-interface is not blocked for
+ processing. GtkHTML is used in a limited way by this class for
+ HTML parsing and resolution of embedded objects. Embedded objects
+ and Widgets may not be used from formatters which hook onto this
+ entry point.
+ </para>
+
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><constant>EMFormatHTML</constant></entry>
+ </row>
+ <row>
+ <entry>Target</entry>
+ <entry>
+ <link
+ linkend="mail-hooks-format-EMFormatHookTarget">EMFormatHookTarget</link>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>
+ <emphasis>This section needs a huge amount of
+ explanation, and/or more detail needs to be added to another
+ section about the formatter class</emphasis>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>HTML Display Formatter</title>
+
+ <para>
+ The EMFormatHTMLDisplay class is a subclass of EMFormatHTML, and is
+ used as a mail display widget. As such, it has access to all of
+ the facilities of GtkHTML, such as embedded widgets. Like the
+ EMFormatHTML class, this uses a complex multi-thread architecture.
+ </para>
+
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><constant>EMFormatHTMLDisplay</constant></entry>
+ </row>
+ <row>
+ <entry>Target</entry>
+ <entry>
+ <link
+ linkend="mail-hooks-format-EMFormatHookTarget">EMFormatHookTarget</link>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>
+ <emphasis>This section needs a huge amount of
+ explanation, and/or more detail needs to be added to another
+ section about the formatter class</emphasis>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>HTML Print Formatter</title>
+
+ <para>
+ The EMFormatHTMLPrint class is a subclass of EMFormatHTML, and is
+ used as a mail printing widget. It cannot access embedded
+ widgets. For most purposes you would normally only connect to the
+ EMFormatHTML hook, and generate generic HTML output which could be
+ printed or shown on-screen if it isn't overriden by the display
+ formatter.
+ </para>
+
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><constant>EMFormatHTMLPrint</constant></entry>
+ </row>
+ <row>
+ <entry>Target</entry>
+ <entry>
+ <link
+ linkend="mail-hooks-format-EMFormatHookTarget">EMFormatHookTarget</link>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>
+ <emphasis>This section needs a huge amount of
+ explanation, and/or more detail needs to be added to another
+ section about the formatter class</emphasis>
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Mail Quote Formatter</title>
+ <para>
+ The EMFormatQuote class is a subclass of EMFormat, and is
+ used as generator for quoted mail content and for
+ inline-forwarding. This formatter converts message objects into
+ a pure HTML stream, which is not parsed directly, but normally fed
+ to the message composer.
+ </para>
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Name</entry>
+ <entry><constant>EMFormatQuote</constant></entry>
+ </row>
+ <row>
+ <entry>Target</entry>
+ <entry>
+ <link
+ linkend="mail-hooks-EMFormatHookTarget">EMFormatHookTarget</link>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </sect2>
+
+ <sect2 id="mail-hooks-format-EMFormatHookTarget">
+ <title>Mail Formatter Targets</title>
+
+ <para>There is only one target for all mail formatters, and it is
+ implied automatically for all formatter hooks.</para>
+
+ <informaltable>
+ <tgroup cols="2">
+ <colspec colnum="1" colname="field" colwidth="1*"/>
+ <colspec colnum="2" colname="value" colwidth="4*"/>
+ <tbody valign="top">
+ <row>
+ <entry>Structure</entry>
+ <entry>
+ <link
+ linkend="API-struct--EMFormatHookTarget">EMFormatHookTarget</link>
+ </entry>
+ </row>
+ <row>
+ <entry>Flags</entry>
+ <entry>
+ <simplelist>
+ <member><constant>inline</constant> = <constant>EM_FORMAT_HANDLER_INLINE</constant></member>
+ <member><constant>inline_disposition</constant> =
+ <constant>EM_FORMAT_HANDLER_INLINE_DISPOSITION</constant></member>
+ </simplelist>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ </sect2>
+ </sect1>
+ </chapter>
+
+ <chapter id="contacts-hooks">
+ <title>
+ Contacts Hooks
+ </title>
+ <para>
+ None defined.
+ </para>
+ </chapter>
+
+ <chapter id="calendar-hooks">
+ <title>
+ Calendar and Tasks Hooks
+ </title>
+ <para>
+ None defined.
+ </para>
+ </chapter>
+
+ <chapter id="shell-hooks">
+ <title>
+ Shell Hooks
+ </title>
+ <para>
+ None defined.
+ </para>
+ </chapter>
+
+ </part>
+
+ <part id="reference">
+ <title>
+ Reference
+ </title>
+ <partintro>
+ <para>
+ This section of the book is a detailed API reference of the
+ objects and methods that implement the core plugin system and hooks.
+ </para>
+ <para>
+ It contains the detailed information required for all uses of the
+ plugin system. That is, implementors
+ of new hook types, application developers providing hook points, and
+ plugin developers.
+ </para>
+ </partintro>
+ <chapter id="REF-EPlugin">
+ <title>
+ EPlugin
+ </title>
+ <para>
+ The EPlugin object manages the loading and invocation of physical
+ plugin definitions and plugin binaries. The base EPlugin class is an
+ abstract class which loads plugin definitons, resolving hooks, and
+ provides an api for invoking callbacks.
+ </para>
+ <para>
+ The EPluginLib object is a concrete derived class of EPlugin which
+ handles loading shared libraries using the GModule interface.
+ </para>
+ &e-plugin-reference;
+ </chapter>
+
+ <chapter>
+ <title>
+ EPopup
+ </title>
+ <para>
+ The EPopup object manages a single popup menu. It is used to
+ application code as a convenience function for building dynamic popup
+ menus based on a specific context.
+ </para>
+ <para>
+ The EPopupHook object is loaded by
+ the &EPlugin; system, and is used to provide dynamic extension to the
+ application context menus.
+ </para>
+ &e-popup-reference;
+
+ <!-- this looks like bum here, not sure where else to put it though -->
+ &em-popup-reference;
+ </chapter>
+
+ <chapter>
+ <title>
+ EMenu
+ </title>
+ <para>
+ The EMenu object manages the menus for a given view or component. It
+ is used by application code to allow the plugin system an entry point
+ to current application view. It may also be used by the application as
+ a convenience function to dynamically alter the menu system based on
+ user context.
+ </para>
+ <para>
+ The EMenuHook object is loaded by the &EPlugin; system, and is used to
+ provide dynamic extension to the application menus.
+ </para>
+ &e-menu-reference;
+ </chapter>
+
+ <chapter>
+ <title>
+ EConfig
+ </title>
+ <para>
+ The EConfig object manages the building of dynamic configuration pages
+ to configure specific application objects. The same basic object can
+ be used to fully drive a wizard-like druid object, or to drive a
+ note-book of configuration options. It is used by application code to
+ provide the core controller in a model-view-controller implementation
+ of a UI window.
+ </para>
+ <para>
+ The EConfigHook object is loaded by the &EPlugin; system, and is used hook
+ in additional configuration items into configuration windows or druids
+ dynamically.
+ </para>
+ &e-config-reference;
+ </chapter>
+
+ <chapter>
+ <title>
+ EEvent
+ </title>
+ <para>
+ The EEvent object manages broadcast of events for a given component or
+ application. It is used by application code to provide the plugin
+ system with an entry point for user and system state events.
+ </para>
+ <para>
+ The EEventHook object is loaded by the &EPlugin; system, and is used hook
+ event listeners into dynamically loaded event handlers.
+ </para>
+ &e-event-reference;
+ </chapter>
+
+ <chapter>
+ <title>
+ EMFormat
+ </title>
+ <para>
+ The EMFormat object drives the formatting of MIME message content for
+ display, print, and replying. EMFormatHTML is an implementation of
+ EMFormat which writes its output to a GtkHTML instance.
+ </para>
+ <para>
+ The EMFormatHook object is loaded by the &EPlugin; system, and is used hook
+ event listeners into dynamically loaded event handlers.
+ </para>
+ &em-format-reference;
+ </chapter>
+ </part>
+
+</book>