Development:Plugin Developers Guide

From OpenLP

(Redirected from Plugin Developers Guide)
Jump to: navigation, search

Contents

Plugin Architecture

Directory Structure

All plugins need to have the same directory structure. The Songs plugin's directory structure is illustrated below as an example:

Plugin architecture.png

Each plugin has a directory within the openlp.org "plugins" directory. This directory is named the same as the plugin's name. Within the name directory there will be a nameplugin.py file which contains the NamePlugin class. This plugin class extends the builtin openlp.org Plugin class. This provides your plugin with a number of key methods to override.

Naming Conventions

Base Plugin Class

The base Plugin class is shown below, with all the hooks that you need to provide if you want to make use of its functionality.

Note: This is a cut down version of the Plugin class.

  1. class Plugin(object):
  2.     def __init__(self, name=None, version=None):
  3.         if name is not None:
  4.             self.name = name
  5.         else:
  6.             self.name = 'Plugin'
  7.         if version is not None:
  8.             self.version = version
  9.         self.icon = None
  10.         self.config = PluginConfig(self.name)
  11.         self.weight = 0
  12.         # Set up logging
  13.         self.log = logging.getLogger(self.name)
  14.  
  15.     def check_pre_conditions(self):
  16.         return True
  17.  
  18.     def get_media_manager_item(self):
  19.         pass
  20.  
  21.     def add_import_menu_item(self, import_menu):
  22.         pass
  23.  
  24.     def add_export_menu_item(self, export_menu):
  25.         pass
  26.  
  27.     def get_settings_tab(self):
  28.         pass
  29.  
  30.     def add_to_menu(self, menubar):
  31.         pass
  32.  
  33.     def handle_event(self, event):
  34.         pass
  35.  
  36.     def about(self):
  37.         pass
  38.  
  39.     def save(self, data):
  40.         pass
  41.  
  42.     def load(self, string):
  43.         pass
  44.  
  45.     def render(self, theme, screen=None):
  46.         pass
  47.  
  48.     def initalise(self):
  49.         pass

Developing An Example Plugin

Starting The Plugin

So let's start by building a very basic plugin, one that will add an item to the media manager, which will have a toolbar, and one button on the toolbar that pops up a "Hello World" message (we had to get the "Hello World" in *somewhere* ;-) ).

The Plugin Code

Next we'll need some code in that new plugin file. Copy and paste the following code into the new file. Don't forget to create yourself a little icon, and update the path to the icon to match your icon's path.

  1. import os
  2.  
  3. from openlp.core.lib import Plugin, MediaManagerItem
  4.  
  5. class HelloWorldPlugin(Plugin):
  6.     def __init__(self):
  7.         # Call the parent constructor
  8.         Plugin.__init__(self, 'HelloWorld', '1.9.0')
  9.         # Create the plugin icon
  10.         self.icon = QtGui.QIcon()
  11.         self.icon.addPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(
  12.             os.path.join(os.path.asbpath(os.path.basename(__file__)),
  13.             'resources', 'images', 'helloworld.png'))), QtGui.QIcon.Normal,
  14.             QtGui.QIcon.Off)
  15.  
  16.     def get_media_manager_item(self):
  17.         # Create the MediaManagerItem object
  18.         self.MediaManagerItem = MediaManagerItem(self.icon, 'Hello World')
  19.         # Add a toolbar
  20.         self.MediaManagerItem.addToolbar()
  21.         # Create button for the toolbar
  22.         self.MediaManagerItem.addToolbarButton('Hello World', 'Says, "Hello World"',
  23.             os.path.join(os.path.asbpath(os.path.basename(__file__)), 'resources',
  24.             'images', 'helloworld.png'), self.onHelloWorldClick, 'HelloWorldItem')
  25.  
  26.     def onHelloWorldClick(self):
  27.         QtGui.QMessageBox.information(None, 'Hello World!',
  28.             'This is just a little message box to say, "Hello World!"',
  29.             QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok), QtGui.QMessageBox.Ok)

An Explanation

So how does the plugin work?

Plugin Hooks

Hooks are special Python methods that are executed at various points throughout openlp.org. The list below shows all of these hooks, when each of them is activated, and what each one of them is supposed to do.

about()

Show a dialog when the user clicks on the 'About' button in the plugin manager.

save(media_item)

A plugin's media item is passed to this function, which should return a ServiceItem object which can be written to the service file.

load(service_item)

A ServiceItem object from the service file is passed in. This function parses and sets up an instance of the plugin's media item for use within the plugin.

render(screen, service_item, theme)

Render the screenth screenful of the service_item (a ServiceItem object), using theme settings in theme.

What is screen? An object, a number, a canvas?

get_media_manager_item()

Construct a MediaManagerItem object with all the buttons and things you need, and return it for integration into openlp.org's Media Manager.

add_import_menu_item(import_menu)

Given the import menu item, add an item to the Import menu.

add_export_menu_item(export_menu)

Given the export menu item, add an item to the Export menu.

add_to_menu(menubar)

Add menu items to the menu, given the menubar.

handle_event(event)

Handle the event contained in the event object.

initialise()

Called by the plugin manager to setup any additional features on creation.

Configuration

Configuration File

Each plugin comes with a built-in self.config object, which reads and writes to a plugin-specific section of the openlp.org configuration file. On Linux, Mac OS X, and other Unix-like operating systems, this configuration file can be found in the following location: ~/.openlp/openlp.conf. On Windows, this file is found in: C:\Documents and Settings\username\Application Data\.openlp\openlp.conf.

For example:

[<pluginName>]

last dir = /home/<name>/somedirectory

This is location where the last file loaded into the plugin came from.

list count = 2

This is a count of how many files are to be loaded into the plugin's list

list item 1 = /home/<name>/somedirectory/somefile.xyz

The location and name of the file to be loaded into the plugin's list.

PluginUtls Class

A PluginUtils class can be added the the Plugin's definition to provide access to a number of utility methods to reduce code duplication. These methods will return empty lists or strings if the configuration tags have not been defined.

add_to_context_menu(self, base, icon, text, slot)

Defines a Context menu item with icon 'icon' and text 'text'. Which is connected to list 'base' and will trigger action 'slot' when selected.

add_to_context_separator(self, base)

Defines a Context separator item for the context menu

_load_display_list()

Reads the configuration data and returns a list of items to the added to the display list.

_save_display_list(self, displaylist)

Takes a display list 'displaylist' and saves the details in the configuration file allowing the list to be reloaded later.

_get_last_dir

Reads the configuration file to provide the last directory used by the plugin

_save_last_directory(self, filename)

Extracts the directory part of the filename and saves that in the configuration file

Plugin Dialogs

Media Items

Settings Tabs

The Settings dialog calls each plugin using the get_settings_tab method. The plugin is able to create a tab on the Settings Dialog by returning a class extending SettingsTab.

  1. class HelloWorldTab(SettingsTab):
  2.     def __init__(self):
  3.         HelloWorldTab.__init__(self, u'Hello World')
  4.  
  5.     def setupUi(self):
  6.         self.setObjectName(u'HelloWorldTab')
  7.  
  8.     def retranslateUi(self):
  9.         pass   
  10.  
  11.  
  12.     def load(self):
  13.         pass
  14.  
  15.     def save(self):
  16.         pass
Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox