1.  Popup Menus

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.

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.

1.1. Defining a popup hook

Not sure if this fits here as such. Probably temporary placeholder.

	    
<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>

Need to define menu tag

type
The menu item type. The type maps directly to the corresponding EPopupItem types.
active
If present, then radio or toggle menu items are active when first shown. After the first instantiation, they will remember their active state.
path
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.
label
The text to be displayed on the menu item. This will be translated based on the plugin translation domain.
icon
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.
visible
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.
enable
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.
activate
A plugin-type specific function specification. This function will be resolved and called when the menu item is activated.

1.2. Merging Plugin Items

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.

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.

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:

  • Selecting items based on the target qualifiers
  • Sorting the remaining items based on their path.
  • Building this sorted list into a menu.

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.

Figure 3.1. Merging a menu with many items selected.

Showing how a display list of menu items is selected
		  and then sorted for display.

The first diagram shows when the target qualifiers are many, and mark_unread. 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).

Figure 3.2. Merging a menu with one item selected.

Showing how a display list of menu items is selected
		  and then sorted for display with different qualifiers.

This diagram shows when the target qualifiers are one, and mark_read. The menu items which operate on only many selected messages are not shown. Similarly for those able to be marked as read.