Note

Before Tomboy 0.7.2, Tomboy used another plugin system, which is incompatible with the current. Therefore, if your version of Tomboy is older than this, you should upgrade before you try to develop any add-ins.

Developing a note add-in

In this HowTo we will develop a simple add-in for Tomboy using C#. The add-in will insert the current date and time at the cursor position, much like the Insert Date/Time plugin in gedit.

Tomboy's InsertTimestamp add-in is a slightly more complete version of this add-in with a preferences dialog. The source code can be found in the Tomboy git repository. The attached files InsertDateTime.cs and InsertDateTime.addin.xml are a bit outdated.

Addendum to this tutorial explaining how to create the following Tomboy addin in MonoDevelop

The add-in file

Let's start with creating the add-in file called InsertDateTime.cs with the following content:

using Tomboy;

namespace Tomboy.InsertDateTime
{
        public class InsertDateTimeAddin : NoteAddin
        {
                public override void Initialize ()
                {
                }

                public override void Shutdown ()
                {
                }

                public override void OnNoteOpened ()
                {
                }
        }
}

The first thing you should notice is that our add-in extends the NoteAddin class. The name NoteAddin reveals how note add-ins are handled in Tomboy: an instance of the add-in is created per note. From within the add-in you have access to the associated note, its window and other stuff useful for a add-in.

A add-in must implement three abstract methods: Initialize, Shutdown and OnNoteOpened. Initialize is called at startup, when the add-in instances are created for each note, or when the add-in is activated in the preferences dialog. Respectively Shutdown is called when the add-in is deactivated. OnNoteOpened will be executed when the note window is opened for the first time.

The metadata file

We also need to create a metadata XML-file called InsertDateTime.addin.xml with the following content:

<Addin id="DateTimeAddin"
    namespace="Tomboy"
    name="Insert Date/Time"
    author="Tomboy Project"
    description="Inserts current date and time at the cursor position."
    category="Tools"
    defaultEnabled="false"
    version="0.1">

    <Runtime>
        <Import assembly="InsertDateTime.dll" />
    </Runtime>

    <Dependencies>
        <Addin id="Tomboy" version="0.10" />
    </Dependencies>

    <Extension path="/Tomboy/NoteAddins">
        <NoteAddin type="Tomboy.InsertDateTime.InsertDateTimeAddin" />
    </Extension>
</Addin>

This information is displayed on Tomboy's preferences dialog, and is what makes the add-in system understand that this is a add-in

Adding the menu item

using System;
using Mono.Unix;
using Gtk;
using Tomboy;

namespace Tomboy.InsertDateTime
{
        public class InsertDateTimeAddin : NoteAddin
        {
                Gtk.MenuItem item;

                public override void Initialize ()
                {
                        item = new Gtk.MenuItem (Catalog.GetString ("Insert date and time"));
                        item.Activated += OnMenuItemActivated;
                        item.Show ();
                        AddPluginMenuItem (item);
                }

                public override void Shutdown ()
                {
                        item.Activated -= OnMenuItemActivated;
                }

                public override void OnNoteOpened ()
                {
                }

                void OnMenuItemActivated (object sender, EventArgs args)
                {
                        Logger.Log ("Activated 'Insert date and time' menu item");
                }
        }
}

For inserting the date, our add-in will need an item in the menu. We create the entry in Initialize and store it in an instance variable for later usage. It should be possible to translate its text, that's why we get it from Catalog. The item is added to the menu via the helper method AddPluginMenuItem which is defined in the add-in's base class NoteAddin. When the item is activated, the callback method OnMenuItemActivated is called, which only writes a log message at the moment (Tomboy has its own logger class and does not use Console.WriteLine). The Shutdown method should do the clean up work, in our case, we have to remove the registered callback.

Sometimes it is necessary to do some initialisation work only once and not for every note. An example how to do that can be found in Tomboy's NoteOfTheDay plugin.

Inserting the date

Our last step is inserting the date at the cursor position. To achive this, we can use some stuff already used in Tomboy: the date format and the tag that defines the date's appearance. We get the buffer, which is a Gtk.TextBuffer, from the note that belongs to the add-in and insert the formatted date using the datetime tag.

void OnMenuItemActivated (object sender, EventArgs args)
{
        string format = Catalog.GetString ("dddd, MMMM d, h:mm tt");
        string text = DateTime.Now.ToString (format);

        NoteBuffer buffer = Note.Buffer;
        Gtk.TextIter cursor = buffer.GetIterAtMark (buffer.InsertMark);
        buffer.InsertWithTagsByName (ref cursor, text, "datetime");
}

Compiling

Compiling using Mono's gmcs is as simple as:

gmcs -debug -out:InsertDateTime.dll -target:library -pkg:tomboy-addins -r:Mono.Posix InsertDateTime.cs -resource:InsertDateTime.addin.xml

Testing

The easiest way to test is copying the generated .dll to the add-in directory inside your home directory. After that restart tomboy and the add-in should be automatically loaded, but not yet enabled. To enable it, go to the Addins tab in the configuration window.

It its also useful to run tomboy from command line to check its log messages.

Developing a multiple export add-in

In Tomboy 1.7.1 and onwards, new functionality has been introduced which makes it easy to export multiple notes to a desired format. This is accomplished by subclassing the ExportAllApplicationAddin and implementing the required methods to export a single note, and the superclass will take care of the rest. This includes things like menu entries, save dialogs, traversing the notebooks and creating a folder structure that mirrors the notebooks.

For this tutorial we will be looking at the Tomboy add-in ExportToHtmlApplicationAddin (available from the Tomboy git repository) and assume that you have understood the previous tutorial.

The add-in file

There are two methods that must be implemented:

SetNames () informs Tomboy about the file suffix to use when exporting and what the human-readable name is. The strings must be set exactly like this, so it's a good idea to just copy this example code and switch out html and HTML with whatever you are interested in exporting.

                /// <summary>
                /// Sets the names of the export type.
                /// </summary>
                protected override void SetNames ()
                {
                        export_file_suffix = "html";
                        export_type_pretty_name = Catalog.GetString ("HTML");
                }

ExportSingleNote (Note note, string output_folder) is a method that exports a single note note to a specified folder (which the superclass will have set up according to notebook). This is where you place all the logic needed to convert a single note from Tomboy's format to your chosen format and save it to disk. For ExportToHtmlApplicationAddin it looks like this:

                /// <summary>
                /// Exports a single Note to HTML in a specified location.
                /// </summary>
                public override void ExportSingleNote (Note note,
                                                string output_folder)
                {
                        string output_path = output_folder + SanitizeNoteTitle (note.Title)
                                + "." + export_file_suffix;

                        Logger.Debug ("Exporting Note '{0}' to '{1}'...", note.Title, output_path);

                        StreamWriter writer = null;

                        try {
                                // FIXME: Warn about file existing.  Allow overwrite.
                                File.Delete (output_path);
                        } catch {
                        }

                        writer = new StreamWriter (output_path);

                        WriteHTMLForNote (writer, note);

                        if (writer != null)
                                writer.Close ();

                        return;
                }

Helper methods

ExportAllApplicationAddin also provides a couple of helper methods which you may use if you like:

SanitizeNoteTitle (string note_title) Will replace any characters in a note title that might disrupt the saving of files on your system (like "/" or "\") with an underscore and return that string.

ResolveRelativePath (Note note_from, string title_to) Will return a string with a file system-dependent relative path between one note and another. Useful for when you export to a format like HTML that allows links between files. (The HTML add-in replaces the system-dependent directory separators with "/".)

The metadata file

The meta-data file is very similar to the previous tutorial, with a slightly different entry for the application add-in. Notice that application add-ins and note add-ins can co-exist in the same DLL, in this case we have a Export All add-in and a Export Single Note add-in that share some logic between them.

<Addin id="ExportToHtmlAddin"
        namespace="Tomboy"
        name="Export to HTML"
        author="Tomboy Project"
        description="Exports individual notes to HTML."
        category="Tools"
        defaultEnabled="true"
        version="0.2">

        <Runtime>
                <Import assembly="ExportToHtml.dll" />
        </Runtime>

        <Dependencies>
                <Addin id="Tomboy" version="0.10" />
        </Dependencies>

        <Extension path="/Tomboy/ApplicationAddins">
                <ApplicationAddin type="Tomboy.ExportToHtml.ExportToHtmlApplicationAddin" />
        </Extension>

        <Extension path="/Tomboy/NoteAddins">
                <NoteAddin type="Tomboy.ExportToHtml.ExportToHtmlNoteAddin" />
        </Extension>
</Addin>

Using command line arguments for add-ins

Starting in Tomboy 1.11.1, new functionality has been added that allows add-ins to listen for command line arguments. If there are any arguments prefixed with "--addin:", an event called Tomboy.DefaultNoteManager.CommandLine.AddinCmdLineArgsDetected will be fired which add-ins can listen to. Note that this event will be fired for any argument starting with "--addin:" and will send every argument with that prefix as its arguments, so the individual add-in is responsible for identifying and using the relevant commands.

For an example of how to implement this, see the ExportAllApplicationAddin class. It listens for "--addin:XXX-export-all [path]" and "--addin:XXX-export-all-quit [path]", where XXX is any subclass of ExportAll. In a standard Tomboy install, "--addin:html-export-all-quit [path]" will export all notes to the set location and then quit Tomboy, well suited for backup scripts or similar.

Apps/Tomboy/HowToCreateAddins (last edited 2013-08-13 04:00:04 by rupert0)