diff options
author | Michael Zucci <zucchi@src.gnome.org> | 2004-09-20 13:59:55 +0800 |
---|---|---|
committer | Michael Zucci <zucchi@src.gnome.org> | 2004-09-20 13:59:55 +0800 |
commit | ef6a3af717132e0750f226fa8a0ee0f3c98e19f0 (patch) | |
tree | f4ed25f7a247a8ccb855a8d940777e7a3d21a3e3 /doc/devel | |
parent | 96111b1f1487ca3fe454b340a73ba927cc6bfb83 (diff) | |
download | gsoc2013-evolution-ef6a3af717132e0750f226fa8a0ee0f3c98e19f0.tar gsoc2013-evolution-ef6a3af717132e0750f226fa8a0ee0f3c98e19f0.tar.gz gsoc2013-evolution-ef6a3af717132e0750f226fa8a0ee0f3c98e19f0.tar.bz2 gsoc2013-evolution-ef6a3af717132e0750f226fa8a0ee0f3c98e19f0.tar.lz gsoc2013-evolution-ef6a3af717132e0750f226fa8a0ee0f3c98e19f0.tar.xz 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')
-rw-r--r-- | doc/devel/ChangeLog | 24 | ||||
-rw-r--r-- | doc/devel/evolution-plugin-manual.xml | 2915 |
2 files changed, 2939 insertions, 0 deletions
diff --git a/doc/devel/ChangeLog b/doc/devel/ChangeLog index 0f6ba969e2..89afe74c72 100644 --- a/doc/devel/ChangeLog +++ b/doc/devel/ChangeLog @@ -1,3 +1,27 @@ +2004-09-09 Not Zed <NotZed@Ximian.com> + + * evolution-plugin-manual.xml: updates. some not very readable, sigh. + + * images: Added e-popup-merge-[12].pic. + +2004-09-04 Not Zed <NotZed@Ximian.com> + + * images/Makefile: add a temporary makefile to build images from + source pic files. + + * evolution-plugin-manual.xml: updates/rearrangements. + +2004-09-01 Not Zed <NotZed@Ximian.com> + + * images/*: added some image files. + + * evolution-plugin-manual.xml: fix for some api changes. Updates. + +2004-08-25 Not Zed <NotZed@Ximian.com> + + * evolution-plugin-manual.xml: Added the working plugin manual + in-case i crash my bike going to work one day. + 2003-11-20 JP Rosevear <jpr@ximian.com> * Remove dead doc files. 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. "evolution"). 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. "Bob's Wonder + Extender" 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 + <perhaps it should embed the bonobouixml>. 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 "<constant>account</constant>". + </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> |