Plugin development tutorial
What's a plugin?
At the most basic level, plugin for ToDo is simply a .net dll library conforming to the ToDo.Plugin specifications.
In this tutorial, we are going to create a simple plugin for gljakal's To Do, using SharpDevelop, a free .net1.1 IDE. You can apply the same instructions to VisualStudio.net almost without any change. You can find the plugin source code in the ToDo directory, in a compressed folder named sampleplugin.zip
Creating a new project
Open SharpDevelop. On the main menu select File > New Combine.
On the "New project" dialog select Class Library and choose a name and a suitable location for the project.
The first thing to do is to add a reference to the ToDo plugin library. Right click References on the "Projects" bar and choose Add Reference.
On the "Add Reference" window, select .NET Assembly Browser > Browse. Select the file ToDo.Plugin.dll, that is located in the installation directory for gljakal's ToDo. [Ok] your way out.
Creating a pluggable class
Now create a new class file (I usually delete the "myClass.cs" file SharpDevelop creates automatically): Right click the project icon, select add > new file > class.
In order to be recognized as a plugin by ToDo, your class must inherit from ToDo.Plugin.PluginBase, so be sure to specify it!
The first thing to do is to create a new constructor. A "pluggable" class must have a default constructor accepting an IComunicator as a parameter. You don't need to do anything fancy with it, just pass it to the base constructor:
using System; namespace test { public class MessagePlugin : ToDo.Plugin.PluginBase { public MessagePlugin(ToDo.Plugin.IComunicator c) : base(c) { } } }
Comunication
How does the plugin comunicate with ToDo? I'm sure you guessed it, it uses the IComunicator interface. The comunicator exposes several events and methods that allow the plugin to interact with the program.
In this example, we are going to use the SelectedItemChanged event and SelectedItem property to change the color and the title of our TextBox.
public MessagePlugin(ToDo.Plugin.IComunicator c) : base(c) { ... this.Comunicator.SelectedItemChanged += new EventHandler(this.SelectedItemChanged); } private void SelectedItemChanged(object sender, EventArgs e) { if(this.Comunicator.SelectedItem!=null) { pTextbox.Text = this.Comunicator.SelectedItem.Title; pTextbox.BackColor = this.Comunicator.SelectedItem.GetColor(); } else { pTextbox.Text = ""; } }
Default methods
There are two default methods that are used by ToDo: getAdditionalControls() and getAdditionalMenus(): the first tells ToDo you want to add more controls to the main form, and the latter tells ToDo that you wand to add more menus.
Adding a new menu item
In our example, we are going to add a new menu item in ToDo's window. This is simply done by overriding the getAdditionalMenus() method.
First, let's add a new private variable for the menu item and let's initialize it in the class constructor. The new menu item will be placed under the Edit main menu:
private ToDo.Plugin.MenuItem pItem; public MessagePlugin(ToDo.Plugin.IComunicator c) : base(c) { MenuItem tMenuItem; tMenuItem = new MenuItem(); tMenuItem.Text="Test plugin"; tMenuItem.Click += new EventHandler(pMenuItem_Click); pItem = new ToDo.Plugin.MenuItem(tMenuItem, ToDo.Plugin.MenuType.MenuEdit); }
Next, we add the code to handle the click event on our new menu item. We show a message box displaying the ID of the selected ToDo item. ToDo uses Guids to identify each item, so you can store additional information about any item in a separate file, without relying on variable information such as the task description, the todo list filename or the task position in the list.
private void pMenuItem_Click(object sender, EventArgs e) { if(this.Comunicator.SelectedItem!=null) MessageBox.Show(this.Comunicator.SelectedItem.Guid.ToString(), "Hello Plugin!"); else MessageBox.Show("No ToDo item selected!"); }
Finally, we override the getAdditionalMenus() method to return our private menu:
public override ToDo.Plugin.MenuItem []getAdditionalMenus() { return new ToDo.Plugin.MenuItem []{pItem}; }
Adding one additional control to the main form
In this example, we are going to add an additional control in the main todo window. We will add a simple text box.
First, let's add the TextBox control as a private variable in our class. We also need to initialize it inside the constructor. It is important to set the dock style and the size, in order to place the control more conveniently inside the main form.
private TextBox pTextbox; public MessagePlugin(ToDo.Plugin.Comunicator c) : base(c) { ... pTextbox = new TextBox(); pTextbox.Size = new System.Drawing.Size(100, 20); pTextbox.Dock = DockStyle.Bottom; pTextbox.TextChanged += new EventHandler(pText_Changed); }
Next, let's override the getAdditionalControls() method to return our textbox:
public override Control []getAdditionalControls() { return new Control []{pTextbox}; }
Finally, we handle the TextChanged event of our TextBox, updating the selected task's title.
private void pText_Changed(object sender, EventArgs e) { if(this.Comunicator.SelectedItem!=null) { this.Comunicator.SelectedItem.Title = pTextbox.Text; } }