Contents

Extending F-Spot

Starting from version 0.4.1 (SVN r3054), F-Spot can be extended by writing your own extensions. The extension mechanism is provided by Mono.Addins. Both Mono.Addins and the support for extensions in F-Spot are still in development, but they are already usable in F-Spot.

There are currently 3 types of extensions, 'export extensions' to implement exporters for any destinations you think about, 'command extensions' to implement some generic tools (like a duplicate finder, finding the orphaned images, ...) and 'service extensions' for service needed at startup

Available extensions are listed here.

Building extensions

You don't need F-Spot sources to build extensions, you only need to have it properly installed. For a simple extension containing a single code file and a manifest, you should be able to compile it like this:

gmcs -t:library MyExtension.cs -resource:MyExtension.addin.xml -pkg:f-spot

Installing extensions

The assembly containing your extension (and the manifest file if not bundled as resource in the assembly) have to be copied either in $PREFIX/lib/f-spot/extensions (e.g. /usr/lib/f-spot/extensions) to make it available system-wide, or in $XDG_CONFIG_HOME/f-spot/addins if you don't have enough rights to install it system-wide.

Distributing your extensions

If you think the extensions you wrote could be useful for others, please let us know, and we'll consider making them part of the F-Spot distribution or we will publish them on this wiki as 'contrib' code. In the future, we'd like to have a extensions repository for auto-provisioning and auto-updating F-spot instances in the field via the network, but it's not implemented yet.

Export Extensions

There are 2 required tasks for writing an export extension: write a manifest and develop a class implementing the IExporter interface.

Manifest file for Export Extension

A manifest file is an xml file containing the required information to declare the extension to the extension engine. This file can be copied aside of the assembly implementing the plugin, or bundled as a ressource in the assembly itself (recommended).

Here's the content of MyExporter.addin.xml Insert non-formatted text here

<Addin namespace="FSpot"
       version="1.0.0.0"
       name="My Exporter"
       author="Marty MacFly"
       category="Export">
	<Dependencies>
		<Addin id="Core" version="1.2"/>
	</Dependencies>
	<Extension path = "/FSpot/Menus/Exports">
		<ExportMenuItem id="FileList" _label = "Dump the list of files" class = "MyExporter.Dump" />
	</Extension>
</Addin>

The manifest file has to be named with a .addin or a .addin.xml file extension. The previous manifest does these few things:

  • declare that it will extend FSpot.Core, using the 1.0 extension definition
  • add a menuitem in the File>Export submenu. This item has an id (normally not used), a _label that will be the entry showed in the menu and a command_type, which is the class that will be instanciated (the real code for the exporter)
note 1: It's "_label", not "label". The underscore is there so intltool can be used to translate the menu entries.
note 2: Do not try to extend, with the same scheme, other paths than /FSpot/Menus/Exports, it will not work.

Example code for an export Extension

To create an export extension, you have to write a class that implements the FSpot.Extensions.IExporter interface. Nothing less, nothing more. Choose your own Namespace and the class name you want. The Namespace plus the ClassName is the command_type parameter in the manifest file (in this example, the namespace is MyExporter and the class implementing FSpot.Extensions.IExporter is Dump). The following code will not really export anything to anywhere, but dump filenames at the console. If you want to write an export extension for F-Spot, it's your job to implement the Run() method.

//MyExporter.cs

using FSpot;
using FSpot.Extensions;
using System;

namespace MyExporter
{
	public class Dump : IExporter
	{
		public void Run (IBrowsableCollection photos)
		{
			foreach (IBrowsableItem photo in photos.Items)
			{
				Console.WriteLine (photo.Name);
			}
		}
	}
}

That's it! Compile this example extension with:

gmcs -t:library MyExporter.cs -pkg:f-spot -resource:MyExporter.addin.xml

This will create an assembly and bundle the manifest file as a resource.

Install this very useful extension:

cp MyExporter.dll ~/.gnome2/f-spot/addins/

Now, you can run f-spot and look at the added extension in the File>Export menu

note 1: In real export extensions, consider using the FSpot.Filters for any preprocessing. 
You can find Filters already written for resizing, rotating, changing image format, ...
note 2: The only documentation for FSpot.IBrowsableCollection and FSpot.IBrowsableItem is in the source tree.

Command Extensions

An obvious extension node for that type of extension is the Tool menu. But the current items ot the PhotoPopup are also defined using this scheme.

There's 2 steps in defining a command extension: first write the manifest, then write a class that implements ICommand

Manifest for Tool Extension

<Addin namespace="FSpot">
	<Dependencies>
		<Addin id="Core" version="1.1"/>
	</Dependencies>
	<Extension path = "/FSpot/Menus/Tools">
		<Command id="MyTool" _label = "Start my tool" command_type = "MyClass" />
	</Extension>
</Addin>

Service Extensions

Service extensions should implement the IService interface, which contains a Start () and a Stop () methods. While implementing those methods, keep them as small as possible as they'll affect startup time. Think async if your addin Startup is longer than a few milliseconds.

Enabled services will automatically be started during f-spot startup.

Manifest for a Service Extension

<Addin namespace="FSpot" category="Services">
        <Dependencies>
                <Addin id="Core" version="0.4.4.2"/>
        </Dependencies>
        <Extension path = "/FSpot/Services">
                <Service class="MyService"/>
        </Extension>
</Addin>

Editor Extensions

Editor extensions add new editing tools to the sidebar. All editors are a subclass of Editor, which resides in the FSpot.Editors namespace. Only the constructor, which sets up the editor parameters and the Process function are obligatory. Optional configuration widgets or a fast previewing function can be provided by overriding the needed methods. Have a look at Editor or any of the existing editors for examples.

Manifest for an Editor Extension

<Addin namespace="FSpot" category="Editors">
        <Dependencies>
                <Addin id="Core" version="0.4.4.102"/>
        </Dependencies>
        <Extension path = "/FSpot/Editors">
                <Editor editor_type = "MyEditor"/>
        </Extension>
</Addin>

Embed a Glade file in a extension

You can use Glade for drawing extensions' dialog, which may result easier and better good looking than creating it by hand into the code.

Makefile

In your Makefile you will need to add gtk-sharp-2.0 to PACKAGES

 PACKAGES = \
 ...
 -pkg:gtk-sharp-2.0 \
 ...

Add the .glade file to RESOURCES

 RESOURCES = \
 ...
 -resource:YourExtensionName.glade \
 ...

Edit the %.dll line to reflect the following

 %.dll: %.cs %.glade

Add *.gladep to clean

 rm -f *.dll *~ *.bak .mpack *.gladep

The .cs file

Define your dialog and the properties you need, as usual.

 [Glade.Widget] Gtk.Dialog yourextensionname_dialog_name;
 [Glade.Widget] Gtk.HBox tagentry_box;
 ...

Load it!

 public void ShowDialog() {
   Glade.XML xml = new Glade.XML (null, "YourExtensionName.glade", "yourextensionname_dialog_name", "f-spot");
   xml.Autoconnect (this);
   yourextensionname_dialog_name.Modal = false;   
   yourextensionname_dialog_name.TransientFor = null;
   yourextensionname_dialog_name.Response += on_dialog_response;
   yourextensionname_dialog_name.ShowAll();
 }

Finally, read the dialog!

 void on_dialog_response (object obj, ResponseArgs args) {
   if (args.ResponseId == ResponseType.Ok) {
     do_something();
   }
   yourextensionname_dialog_name.Destroy();
 }

This page was last modified on 13 January 2009, at 07:46. This page has been accessed 18,654 times.


Powered by MediaWiki
Copyright © 2005. Powered by MediaWiki. Valid XHTML & CSS