← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~trb143/openlp/singleton into lp:openlp

 

Tim Bentley has proposed merging lp:~trb143/openlp/singleton into lp:openlp.

Requested reviews:
  OpenLP Core (openlp-core)

For more details, see:
https://code.launchpad.net/~trb143/openlp/singleton/+merge/144640

Introduce a Registry for Components.

- Register all major components with the Registry
- Use the Registry to make components available and remove passing objects in the constructors.
- Remove the chaining of references to find an object.
- Remove pluginHelpers
- make all components names python style
- Unit test Registry and convert ServiceItem tests
- clean up code when found and it had been missed.  
-- 
https://code.launchpad.net/~trb143/openlp/singleton/+merge/144640
Your team OpenLP Core is requested to review the proposed merge of lp:~trb143/openlp/singleton into lp:openlp.
=== modified file 'openlp/core/__init__.py'
--- openlp/core/__init__.py	2013-01-23 20:30:59 +0000
+++ openlp/core/__init__.py	2013-01-24 06:06:24 +0000
@@ -43,15 +43,14 @@
 
 from PyQt4 import QtCore, QtGui
 
-from openlp.core.lib import Receiver, Settings, check_directory_exists, ScreenList, UiStrings
+from openlp.core.lib import Receiver, Settings, check_directory_exists, ScreenList, UiStrings, Registry
 from openlp.core.resources import qInitResources
 from openlp.core.ui.mainwindow import MainWindow
 from openlp.core.ui.firsttimelanguageform import FirstTimeLanguageForm
 from openlp.core.ui.firsttimeform import FirstTimeForm
 from openlp.core.ui.exceptionform import ExceptionForm
 from openlp.core.ui import SplashScreen
-from openlp.core.utils import AppLocation, LanguageManager, VersionThread, \
-    get_application_version
+from openlp.core.utils import AppLocation, LanguageManager, VersionThread, get_application_version
 
 
 __all__ = [u'OpenLP', u'main']
@@ -284,6 +283,7 @@
     else:
         app.setApplicationName(u'OpenLP')
         set_up_logging(AppLocation.get_directory(AppLocation.CacheDir))
+    registry = Registry.create()
     app.setApplicationVersion(get_application_version()[u'version'])
     # Instance check
     if not options.testing:

=== modified file 'openlp/core/lib/__init__.py'
--- openlp/core/lib/__init__.py	2013-01-23 20:30:59 +0000
+++ openlp/core/lib/__init__.py	2013-01-24 06:06:24 +0000
@@ -386,6 +386,7 @@
             u'Locale list separator: start') % (stringlist[0], merged)
 
 
+from registry import Registry
 from uistrings import UiStrings
 from eventreceiver import Receiver
 from screen import ScreenList

=== modified file 'openlp/core/lib/imagemanager.py'
--- openlp/core/lib/imagemanager.py	2013-01-10 23:07:48 +0000
+++ openlp/core/lib/imagemanager.py	2013-01-24 06:06:24 +0000
@@ -39,7 +39,7 @@
 
 from PyQt4 import QtCore
 
-from openlp.core.lib import resize_image, image_to_byte, Receiver, ScreenList
+from openlp.core.lib import resize_image, image_to_byte, Receiver, Registry, ScreenList
 
 log = logging.getLogger(__name__)
 
@@ -182,6 +182,7 @@
 
     def __init__(self):
         QtCore.QObject.__init__(self)
+        Registry().register(u'image_manager', self)
         currentScreen = ScreenList().current
         self.width = currentScreen[u'size'].width()
         self.height = currentScreen[u'size'].height()

=== modified file 'openlp/core/lib/mediamanageritem.py'
--- openlp/core/lib/mediamanageritem.py	2013-01-18 18:50:46 +0000
+++ openlp/core/lib/mediamanageritem.py	2013-01-24 06:06:24 +0000
@@ -35,8 +35,8 @@
 
 from PyQt4 import QtCore, QtGui
 
-from openlp.core.lib import SettingsManager, OpenLPToolbar, ServiceItem, StringContent, build_icon, translate, \
-    Receiver, ListWidgetWithDnD, ServiceItemContext, Settings, UiStrings
+from openlp.core.lib import OpenLPToolbar, ServiceItem, StringContent, build_icon, translate, Receiver, \
+    ListWidgetWithDnD, ServiceItemContext, Settings, Registry, UiStrings
 from openlp.core.lib.searchedit import SearchEdit
 from openlp.core.lib.ui import create_widget_action, critical_error_message_box
 
@@ -99,6 +99,7 @@
         self.plugin = plugin
         visible_title = self.plugin.getString(StringContent.VisibleName)
         self.title = unicode(visible_title[u'title'])
+        Registry().register(self.title, self)
         self.settingsSection = self.plugin.name
         self.icon = None
         if icon:
@@ -469,7 +470,7 @@
             serviceItem = self.buildServiceItem()
             if serviceItem:
                 serviceItem.from_plugin = True
-                self.plugin.previewController.addServiceItem(serviceItem)
+                self.preview_controller.addServiceItem(serviceItem)
                 if keepFocus:
                     self.listView.setFocus()
 
@@ -495,7 +496,7 @@
                 serviceItem.from_plugin = True
             if remote:
                 serviceItem.will_auto_start = True
-            self.plugin.liveController.addServiceItem(serviceItem)
+            self.live_controller.addServiceItem(serviceItem)
 
     def createItemFromId(self, item_id):
         item = QtGui.QListWidgetItem()
@@ -510,7 +511,7 @@
             QtGui.QMessageBox.information(self, UiStrings().NISp,
                 translate('OpenLP.MediaManagerItem', 'You must select one or more items to add.'))
         else:
-            # Is it posssible to process multiple list items to generate
+            # Is it possible to process multiple list items to generate
             # multiple service items?
             if self.singleServiceItem or self.remoteTriggered:
                 log.debug(u'%s Add requested', self.plugin.name)
@@ -524,7 +525,7 @@
         serviceItem = self.buildServiceItem(item, True, remote=remote, context=ServiceItemContext.Service)
         if serviceItem:
             serviceItem.from_plugin = False
-            self.plugin.serviceManager.addServiceItem(serviceItem, replace=replace)
+            self.service_manager.addServiceItem(serviceItem, replace=replace)
 
     def onAddEditClick(self):
         """
@@ -541,7 +542,7 @@
                     translate('OpenLP.MediaManagerItem', 'You must select an existing service item to add to.'))
             elif self.plugin.name == serviceItem.name:
                 self.generateSlideData(serviceItem)
-                self.plugin.serviceManager.addServiceItem(serviceItem, replace=True)
+                self.service_manager.addServiceItem(serviceItem, replace=True)
             else:
                 # Turn off the remote edit update message indicator
                 QtGui.QMessageBox.information(self, translate('OpenLP.MediaManagerItem', 'Invalid Service Item'),
@@ -617,3 +618,73 @@
         Performs a plugin specific search for items containing ``string``
         """
         raise NotImplementedError(u'Plugin.search needs to be defined by the plugin')
+
+    def _get_main_window(self):
+        """
+        Adds the main window to the class dynamically
+        """
+        if not hasattr(self, u'_main_window'):
+            self._main_window = Registry().get(u'main_window')
+        return self._main_window
+
+    main_window = property(_get_main_window)
+
+    def _get_renderer(self):
+        """
+        Adds the Renderer to the class dynamically
+        """
+        if not hasattr(self, u'_renderer'):
+            self._renderer = Registry().get(u'renderer')
+        return self._renderer
+
+    renderer = property(_get_renderer)
+
+    def _get_live_controller(self):
+        """
+        Adds the live controller to the class dynamically
+        """
+        if not hasattr(self, u'_live_controller'):
+            self._live_controller = Registry().get(u'live_controller')
+        return self._live_controller
+
+    live_controller = property(_get_live_controller)
+
+    def _get_preview_controller(self):
+        """
+        Adds the preview controller to the class dynamically
+        """
+        if not hasattr(self, u'_preview_controller'):
+            self._preview_controller = Registry().get(u'preview_controller')
+        return self._preview_controller
+
+    preview_controller = property(_get_preview_controller)
+
+    def _get_plugin_manager(self):
+        """
+        Adds the plugin manager to the class dynamically
+        """
+        if not hasattr(self, u'_plugin_manager'):
+            self._plugin_manager = Registry().get(u'plugin_manager')
+        return self._plugin_manager
+
+    plugin_manager = property(_get_plugin_manager)
+
+    def _get_media_controller(self):
+        """
+        Adds the media controller to the class dynamically
+        """
+        if not hasattr(self, u'_media_controller'):
+            self._media_controller = Registry().get(u'media_controller')
+        return self._media_controller
+
+    media_controller = property(_get_media_controller)
+
+    def _get_service_manager(self):
+        """
+        Adds the plugin manager to the class dynamically
+        """
+        if not hasattr(self, u'_service_manager'):
+            self._service_manager = Registry().get(u'service_manager')
+        return self._service_manager
+
+    service_manager = property(_get_service_manager)
\ No newline at end of file

=== modified file 'openlp/core/lib/plugin.py'
--- openlp/core/lib/plugin.py	2013-01-18 20:35:30 +0000
+++ openlp/core/lib/plugin.py	2013-01-24 06:06:24 +0000
@@ -33,7 +33,7 @@
 
 from PyQt4 import QtCore
 
-from openlp.core.lib import Receiver, Settings, UiStrings
+from openlp.core.lib import Receiver, Settings, Registry, UiStrings
 from openlp.core.utils import get_application_version
 
 log = logging.getLogger(__name__)
@@ -118,8 +118,7 @@
     """
     log.info(u'loaded')
 
-    def __init__(self, name, default_settings, plugin_helpers=None, media_item_class=None,
-        settings_tab_class=None, version=None):
+    def __init__(self, name, default_settings, media_item_class=None, settings_tab_class=None, version=None):
         """
         This is the constructor for the plugin object. This provides an easy
         way for descendent plugins to populate common data. This method *must*
@@ -135,9 +134,6 @@
         ``default_settings``
             A dict containing the plugin's settings. The value to each key is the default value to be used.
 
-        ``plugin_helpers``
-            Defaults to *None*. A list of helper objects.
-
         ``media_item_class``
             The class name of the plugin's media item.
 
@@ -165,15 +161,6 @@
         self.mediaItem = None
         self.weight = 0
         self.status = PluginStatus.Inactive
-        self.previewController = plugin_helpers[u'preview']
-        self.liveController = plugin_helpers[u'live']
-        self.renderer = plugin_helpers[u'renderer']
-        self.serviceManager = plugin_helpers[u'service']
-        self.settingsForm = plugin_helpers[u'settings form']
-        self.mediaDock = plugin_helpers[u'toolbox']
-        self.pluginManager = plugin_helpers[u'pluginmanager']
-        self.formParent = plugin_helpers[u'formparent']
-        self.mediaController = plugin_helpers[u'mediacontroller']
         # Add the default status to the default settings.
         default_settings[name + u'/status'] = PluginStatus.Inactive
         default_settings[name + u'/last directory'] = u''
@@ -228,7 +215,7 @@
         you need, and return it for integration into OpenLP.
         """
         if self.mediaItemClass:
-            self.mediaItem = self.mediaItemClass(self.mediaDock.media_dock, self, self.icon)
+            self.mediaItem = self.mediaItemClass(self.main_window.mediaDockManager.media_dock, self, self.icon)
 
     def addImportMenuItem(self, importMenu):
         """
@@ -298,14 +285,14 @@
         """
         if self.mediaItem:
             self.mediaItem.initialise()
-            self.mediaDock.insert_dock(self.mediaItem, self.icon, self.weight)
+            self.main_window.mediaDockManager.insert_dock(self.mediaItem, self.icon, self.weight)
 
     def finalise(self):
         """
         Called by the plugin Manager to cleanup things.
         """
         if self.mediaItem:
-            self.mediaDock.remove_dock(self.mediaItem)
+            self.main_window.mediaDockManager.remove_dock(self.mediaItem)
 
     def appStartup(self):
         """
@@ -421,3 +408,14 @@
         The plugin's config has changed
         """
         pass
+
+    def _get_main_window(self):
+        """
+        Adds the main window to the class dynamically
+        """
+        if not hasattr(self, u'_main_window'):
+            self._main_window = Registry().get(u'main_window')
+        return self._main_window
+
+    main_window = property(_get_main_window)
+

=== modified file 'openlp/core/lib/pluginmanager.py'
--- openlp/core/lib/pluginmanager.py	2012-12-29 20:56:56 +0000
+++ openlp/core/lib/pluginmanager.py	2013-01-24 06:06:24 +0000
@@ -33,7 +33,7 @@
 import sys
 import logging
 
-from openlp.core.lib import Plugin, PluginStatus
+from openlp.core.lib import Plugin, PluginStatus, Registry
 
 log = logging.getLogger(__name__)
 
@@ -43,13 +43,6 @@
     and executes all the hooks, as and when necessary.
     """
     log.info(u'Plugin manager loaded')
-    __instance__ = None
-    @staticmethod
-    def get_instance():
-        """
-        Obtain a single instance of class.
-        """
-        return PluginManager.__instance__
 
     def __init__(self, plugin_dir):
         """
@@ -60,7 +53,7 @@
             The directory to search for plugins.
         """
         log.info(u'Plugin manager Initialising')
-        PluginManager.__instance__ = self
+        Registry().register(u'plugin_manager', self)
         if not plugin_dir in sys.path:
             log.debug(u'Inserting %s into sys.path', plugin_dir)
             sys.path.insert(0, plugin_dir)
@@ -69,7 +62,7 @@
         self.plugins = []
         log.info(u'Plugin manager Initialised')
 
-    def find_plugins(self, plugin_dir, plugin_helpers):
+    def find_plugins(self, plugin_dir):
         """
         Scan the directory ``plugin_dir`` for objects inheriting from the
         ``Plugin`` class.
@@ -77,9 +70,6 @@
         ``plugin_dir``
             The directory to scan.
 
-        ``plugin_helpers``
-            A list of helper objects to pass to the plugins.
-
         """
         log.info(u'Finding plugins')
         startdepth = len(os.path.abspath(plugin_dir).split(os.sep))
@@ -117,7 +107,7 @@
         plugin_objects = []
         for p in plugin_classes:
             try:
-                plugin = p(plugin_helpers)
+                plugin = p()
                 log.debug(u'Loaded plugin %s', unicode(p))
                 plugin_objects.append(plugin)
             except TypeError:

=== added file 'openlp/core/lib/registry.py'
--- openlp/core/lib/registry.py	1970-01-01 00:00:00 +0000
+++ openlp/core/lib/registry.py	2013-01-24 06:06:24 +0000
@@ -0,0 +1,77 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection                                      #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2013 Raoul Snyman                                        #
+# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan      #
+# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub,      #
+# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer.   #
+# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru,          #
+# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith,             #
+# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock,              #
+# Frode Woldsund, Martin Zibricky, Patrick Zimmermann                         #
+# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it     #
+# under the terms of the GNU General Public License as published by the Free  #
+# Software Foundation; version 2 of the License.                              #
+#                                                                             #
+# This program is distributed in the hope that it will be useful, but WITHOUT #
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       #
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    #
+# more details.                                                               #
+#                                                                             #
+# You should have received a copy of the GNU General Public License along     #
+# with this program; if not, write to the Free Software Foundation, Inc., 59  #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA                          #
+###############################################################################
+"""
+Provide Registry Services
+"""
+import logging
+
+log = logging.getLogger(__name__)
+
+class Registry(object):
+    """
+    This is the Component Registry.  It is a singleton object and is used to provide a
+    look up service for common objects.
+    """
+    log.info(u'Registry loaded')
+    __instance__ = None
+
+    def __new__(cls):
+        if not cls.__instance__:
+            cls.__instance__ = object.__new__(cls)
+        return cls.__instance__
+
+    @classmethod
+    def create(cls):
+        """
+        The constructor for the component registry providing a single registry of objects.
+        """
+        log.info(u'Registry Initialising')
+        registry = cls()
+        registry.service_list = {}
+        return registry
+
+    def get(self, key):
+        """
+        Extracts the registry value from the list based on the key passed in
+        """
+        if key in self.service_list:
+            return self.service_list[key]
+        else:
+            log.error(u'Service %s not found in list' % key)
+            return None
+
+    def register(self, key, reference):
+        """
+        Registers a component against a key.
+        """
+        if key in self.service_list:
+            log.error(u'Duplicate service exception %s' % key)
+            raise Exception(u'Duplicate service exception %s' % key)
+        else:
+            self.service_list[key] = reference

=== modified file 'openlp/core/lib/renderer.py'
--- openlp/core/lib/renderer.py	2013-01-10 23:07:48 +0000
+++ openlp/core/lib/renderer.py	2013-01-24 06:06:24 +0000
@@ -32,7 +32,7 @@
 from PyQt4 import QtGui, QtCore, QtWebKit
 
 from openlp.core.lib import ServiceItem, expand_tags, build_lyrics_format_css, build_lyrics_outline_css, Receiver, \
-    ItemCapabilities, FormattingTags, ImageSource, ScreenList
+    ItemCapabilities, FormattingTags, ImageSource, Registry, ScreenList
 from openlp.core.lib.theme import ThemeLevel
 from openlp.core.ui import MainDisplay
 
@@ -57,7 +57,7 @@
     """
     log.info(u'Renderer Loaded')
 
-    def __init__(self, image_manager, theme_manager):
+    def __init__(self):
         """
         Initialise the renderer.
 
@@ -69,15 +69,14 @@
             The theme_manager instance, used to get the current theme details.
         """
         log.debug(u'Initialisation started')
-        self.theme_manager = theme_manager
-        self.image_manager = image_manager
         self.screens = ScreenList()
+        Registry().register(u'renderer', self)
         self.theme_level = ThemeLevel.Global
         self.global_theme_name = u''
         self.service_theme_name = u''
         self.item_theme_name = u''
         self.force_page = False
-        self.display = MainDisplay(None, self.image_manager, False, self)
+        self.display = MainDisplay(None, False, self)
         self.display.setup()
         self._theme_dimensions = {}
         self._calculate_default()
@@ -94,7 +93,7 @@
         self._calculate_default()
         if self.display:
             self.display.close()
-        self.display = MainDisplay(None, self.image_manager, False, self)
+        self.display = MainDisplay(None, False, self)
         self.display.setup()
         self._theme_dimensions = {}
 
@@ -236,7 +235,6 @@
             serviceItem.add_from_text(VERSE_FOR_LINE_COUNT)
         else:
             serviceItem.add_from_text(VERSE)
-        serviceItem.renderer = self
         serviceItem.raw_footer = FOOTER
         # if No file do not update cache
         if theme_data.background_filename:
@@ -644,3 +642,23 @@
         # this parse we are to be wordy
         line = line.replace(u'\n', u' ')
         return line.split(u' ')
+
+    def _get_image_manager(self):
+        """
+        Adds the image manager to the class dynamically
+        """
+        if not hasattr(self, u'_image_manager'):
+            self._image_manager = Registry().get(u'image_manager')
+        return self._image_manager
+
+    image_manager = property(_get_image_manager)
+
+    def _get_theme_manager(self):
+        """
+        Adds the theme manager to the class dynamically
+        """
+        if not hasattr(self, u'_theme_manager'):
+            self._theme_manager = Registry().get(u'theme_manager')
+        return self._theme_manager
+
+    theme_manager = property(_get_theme_manager)
\ No newline at end of file

=== modified file 'openlp/core/lib/serviceitem.py'
--- openlp/core/lib/serviceitem.py	2013-01-21 19:47:53 +0000
+++ openlp/core/lib/serviceitem.py	2013-01-24 06:06:24 +0000
@@ -39,7 +39,7 @@
 
 from PyQt4 import QtGui
 
-from openlp.core.lib import build_icon, clean_tags, expand_tags, translate, ImageSource, Settings
+from openlp.core.lib import build_icon, clean_tags, expand_tags, translate, ImageSource, Settings, Registry
 
 log = logging.getLogger(__name__)
 
@@ -148,7 +148,6 @@
             The plugin that this service item belongs to.
         """
         if plugin:
-            self.renderer = plugin.renderer
             self.name = plugin.name
         self.title = u''
         self.shortname = u''
@@ -293,7 +292,7 @@
             self.image_border = background
         self.service_item_type = ServiceItemType.Image
         self._raw_frames.append({u'title': title, u'path': path})
-        self.renderer.image_manager.addImage(path, ImageSource.ImagePlugin, self.image_border)
+        self.image_manager.addImage(path, ImageSource.ImagePlugin, self.image_border)
         self._new_item()
 
     def add_from_text(self, raw_slide, verse_tag=None):
@@ -644,3 +643,23 @@
                     type = frame[u'title'].split(u'.')[-1]
                     if type.lower() not in suffix_list:
                         self.is_valid = False
+
+    def _get_renderer(self):
+        """
+        Adds the Renderer to the class dynamically
+        """
+        if not hasattr(self, u'_renderer'):
+            self._renderer = Registry().get(u'renderer')
+        return self._renderer
+
+    renderer = property(_get_renderer)
+
+    def _get_image_manager(self):
+        """
+        Adds the image manager to the class dynamically
+        """
+        if not hasattr(self, u'_image_manager'):
+            self._image_manager = Registry().get(u'image_manager')
+        return self._image_manager
+
+    image_manager = property(_get_image_manager)
\ No newline at end of file

=== modified file 'openlp/core/ui/maindisplay.py'
--- openlp/core/ui/maindisplay.py	2013-01-10 23:07:48 +0000
+++ openlp/core/ui/maindisplay.py	2013-01-24 06:06:24 +0000
@@ -38,8 +38,8 @@
 from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL
 from PyQt4.phonon import Phonon
 
-from openlp.core.lib import Receiver, build_html, ServiceItem, image_to_byte, translate, PluginManager, expand_tags,\
-    Settings, ImageSource
+from openlp.core.lib import Receiver, build_html, ServiceItem, image_to_byte, translate, expand_tags,\
+    Settings, ImageSource, Registry
 from openlp.core.lib.theme import BackgroundType
 
 from openlp.core.lib import ScreenList
@@ -66,7 +66,6 @@
         self.isLive = live
         self.controller = controller
         self.screen = {}
-        self.plugins = PluginManager.get_instance().plugins
         # FIXME: On Mac OS X (tested on 10.7) the display screen is corrupt with
         # OpenGL. Only white blank screen is shown on the 2nd monitor all the
         # time. We need to investigate more how to use OpenGL properly on Mac OS
@@ -116,9 +115,8 @@
     """
     This is the display screen as a specialized class from the Display class
     """
-    def __init__(self, parent, imageManager, live, controller):
+    def __init__(self, parent, live, controller):
         Display.__init__(self, parent, live, controller)
-        self.imageManager = imageManager
         self.screens = ScreenList()
         self.rebuildCSS = False
         self.hideMode = None
@@ -173,8 +171,8 @@
         Call the plugins to rebuild the Live display CSS as the screen has
         not been rebuild on exit of config.
         """
-        if self.rebuildCSS and self.plugins:
-            for plugin in self.plugins:
+        if self.rebuildCSS and self.plugin_manager.plugins:
+            for plugin in self.plugin_manager.plugins:
                 plugin.refreshCss(self.frame)
         self.rebuildCSS = False
 
@@ -213,8 +211,8 @@
                 splash_image)
             serviceItem = ServiceItem()
             serviceItem.bg_image_bytes = image_to_byte(self.initialFrame)
-            self.webView.setHtml(build_html(serviceItem, self.screen,
-                self.isLive, None, plugins=self.plugins))
+            self.webView.setHtml(build_html(serviceItem, self.screen, self.isLive, None,
+                plugins=self.plugin_manager.plugins))
             self.__hideMouse()
         log.debug(u'Finished MainDisplay setup')
 
@@ -280,7 +278,7 @@
         """
         API for replacement backgrounds so Images are added directly to cache.
         """
-        self.imageManager.addImage(path, ImageSource.ImagePlugin, background)
+        self.image_manager.addImage(path, ImageSource.ImagePlugin, background)
         if not hasattr(self, u'serviceItem'):
             return False
         self.override[u'image'] = path
@@ -302,8 +300,8 @@
             re-added to the image manager.
         """
         log.debug(u'image to display')
-        image = self.imageManager.getImageBytes(path, ImageSource.ImagePlugin)
-        self.controller.mediaController.media_reset(self.controller)
+        image = self.image_manager.getImageBytes(path, ImageSource.ImagePlugin)
+        self.controller.media_controller.media_reset(self.controller)
         self.displayImage(image)
 
     def displayImage(self, image):
@@ -383,17 +381,18 @@
                 self.override = {}
             else:
                 # replace the background
-                background = self.imageManager.getImageBytes(self.override[u'image'], ImageSource.ImagePlugin)
+                background = self.image_manager.getImageBytes(self.override[u'image'], ImageSource.ImagePlugin)
         self.setTransparency(self.serviceItem.themedata.background_type ==
             BackgroundType.to_string(BackgroundType.Transparent))
         if self.serviceItem.themedata.background_filename:
-            self.serviceItem.bg_image_bytes = self.imageManager.getImageBytes(
+            self.serviceItem.bg_image_bytes = self.image_manager.getImageBytes(
                 self.serviceItem.themedata.background_filename,ImageSource.Theme)
         if image_path:
-            image_bytes = self.imageManager.getImageBytes(image_path, ImageSource.ImagePlugin)
+            image_bytes = self.image_manager.getImageBytes(image_path, ImageSource.ImagePlugin)
         else:
             image_bytes = None
-        html = build_html(self.serviceItem, self.screen, self.isLive, background, image_bytes, self.plugins)
+        html = build_html(self.serviceItem, self.screen, self.isLive, background, image_bytes,
+            plugins=self.plugin_manager.plugins)
         log.debug(u'buildHtml - pre setHtml')
         self.webView.setHtml(html)
         log.debug(u'buildHtml - post setHtml')
@@ -468,6 +467,26 @@
             self.setCursor(QtCore.Qt.ArrowCursor)
             self.frame.evaluateJavaScript('document.body.style.cursor = "auto"')
 
+    def _get_plugin_manager(self):
+        """
+        Adds the Renderer to the class dynamically
+        """
+        if not hasattr(self, u'_plugin_manager'):
+            self._plugin_manager = Registry().get(u'plugin_manager')
+        return self._plugin_manager
+
+    plugin_manager = property(_get_plugin_manager)
+
+    def _get_image_manager(self):
+        """
+        Adds the image manager to the class dynamically
+        """
+        if not hasattr(self, u'_image_manager'):
+            self._image_manager = Registry().get(u'image_manager')
+        return self._image_manager
+
+    image_manager = property(_get_image_manager)
+
 
 class AudioPlayer(QtCore.QObject):
     """
@@ -591,3 +610,4 @@
     #@todo is this used?
     def connectSlot(self, signal, slot):
         QtCore.QObject.connect(self.mediaObject, signal, slot)
+

=== modified file 'openlp/core/ui/mainwindow.py'
--- openlp/core/ui/mainwindow.py	2013-01-18 21:24:25 +0000
+++ openlp/core/ui/mainwindow.py	2013-01-24 06:06:24 +0000
@@ -40,9 +40,8 @@
 from PyQt4 import QtCore, QtGui
 
 from openlp.core.lib import Renderer, build_icon, OpenLPDockWidget, PluginManager, Receiver, translate, ImageManager, \
-    PluginStatus, ScreenList, UiStrings
-from openlp.core.lib.ui import create_action
-from openlp.core.lib import Settings
+    PluginStatus, Registry, Settings, ScreenList
+from openlp.core.lib.ui import UiStrings, create_action
 from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, ThemeManager, SlideController, PluginForm, \
     MediaDockManager, ShortcutListForm, FormattingTagForm
 from openlp.core.ui.media import MediaController
@@ -159,12 +158,12 @@
         # Create the service manager
         self.serviceManagerDock = OpenLPDockWidget(mainWindow, u'serviceManagerDock',
             u':/system/system_servicemanager.png')
-        self.serviceManagerContents = ServiceManager(mainWindow, self.serviceManagerDock)
+        self.serviceManagerContents = ServiceManager(self.serviceManagerDock)
         self.serviceManagerDock.setWidget(self.serviceManagerContents)
         mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.serviceManagerDock)
         # Create the theme manager
         self.themeManagerDock = OpenLPDockWidget(mainWindow, u'themeManagerDock', u':/system/system_thememanager.png')
-        self.themeManagerContents = ThemeManager(mainWindow, self.themeManagerDock)
+        self.themeManagerContents = ThemeManager(self.themeManagerDock)
         self.themeManagerContents.setObjectName(u'themeManagerContents')
         self.themeManagerDock.setWidget(self.themeManagerContents)
         mainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.themeManagerDock)
@@ -456,6 +455,7 @@
         plugins.
         """
         QtGui.QMainWindow.__init__(self)
+        Registry().register(u'main_window', self)
         self.application = application
         self.clipboard = self.application.clipboard()
         self.arguments = self.application.args
@@ -475,14 +475,13 @@
         self.serviceNotSaved = False
         self.aboutForm = AboutForm(self)
         self.mediaController = MediaController(self)
-        self.settingsForm = SettingsForm(self, self)
+        self.settingsForm = SettingsForm(self)
         self.formattingTagForm = FormattingTagForm(self)
         self.shortcutForm = ShortcutListForm(self)
         self.recentFiles = []
         # Set up the path with plugins
         plugin_path = AppLocation.get_directory(AppLocation.PluginsDir)
         self.pluginManager = PluginManager(plugin_path)
-        self.pluginHelpers = {}
         self.imageManager = ImageManager()
         # Set up the interface
         self.setupUi(self)
@@ -543,21 +542,11 @@
         # warning cyclic dependency
         # renderer needs to call ThemeManager and
         # ThemeManager needs to call Renderer
-        self.renderer = Renderer(self.imageManager, self.themeManagerContents)
+        self.renderer = Renderer()
         # Define the media Dock Manager
         self.mediaDockManager = MediaDockManager(self.mediaToolBox)
         log.info(u'Load Plugins')
-        # make the controllers available to the plugins
-        self.pluginHelpers[u'preview'] = self.previewController
-        self.pluginHelpers[u'live'] = self.liveController
-        self.pluginHelpers[u'renderer'] = self.renderer
-        self.pluginHelpers[u'service'] = self.serviceManagerContents
-        self.pluginHelpers[u'settings form'] = self.settingsForm
-        self.pluginHelpers[u'toolbox'] = self.mediaDockManager
-        self.pluginHelpers[u'pluginmanager'] = self.pluginManager
-        self.pluginHelpers[u'formparent'] = self
-        self.pluginHelpers[u'mediacontroller'] = self.mediaController
-        self.pluginManager.find_plugins(plugin_path, self.pluginHelpers)
+        self.pluginManager.find_plugins(plugin_path)
         # hook methods have to happen after find_plugins. Find plugins needs
         # the controllers hence the hooks have moved from setupUI() to here
         # Find and insert settings tabs
@@ -1341,3 +1330,4 @@
         # Check if the new data path is our default.
         if self.newDataPath == AppLocation.get_directory(AppLocation.DataDir):
             settings.remove(u'advanced/data path')
+

=== modified file 'openlp/core/ui/media/mediacontroller.py'
--- openlp/core/ui/media/mediacontroller.py	2013-01-20 12:23:22 +0000
+++ openlp/core/ui/media/mediacontroller.py	2013-01-24 06:06:24 +0000
@@ -32,7 +32,7 @@
 import datetime
 from PyQt4 import QtCore, QtGui
 
-from openlp.core.lib import OpenLPToolbar, Receiver, translate, Settings, UiStrings
+from openlp.core.lib import OpenLPToolbar, Receiver, translate, Settings, Registry, UiStrings
 from openlp.core.lib.ui import critical_error_message_box
 from openlp.core.ui.media import MediaState, MediaInfo, MediaType, get_media_players, set_media_players
 from openlp.core.ui.media.mediaplayer import MediaPlayer
@@ -88,6 +88,7 @@
     """
     def __init__(self, parent):
         self.mainWindow = parent
+        Registry().register(u'media_controller', self)
         self.mediaPlayers = {}
         self.displayControllers = {}
         self.currentMediaPlayer = {}
@@ -130,14 +131,14 @@
                 for item in player.audio_extensions_list:
                     if not item in self.audio_extensions_list:
                         self.audio_extensions_list.append(item)
-                        self.mainWindow.serviceManagerContents.supportedSuffixes(item[2:])
+                        self.service_manager.supportedSuffixes(item[2:])
         self.video_extensions_list = []
         for player in self.mediaPlayers.values():
             if player.isActive:
                 for item in player.video_extensions_list:
                     if item not in self.video_extensions_list:
                         self.video_extensions_list.extend(item)
-                        self.mainWindow.serviceManagerContents.supportedSuffixes(item[2:])
+                        self.service_manager.supportedSuffixes(item[2:])
 
     def register_players(self, player):
         """
@@ -729,3 +730,13 @@
         if controller.isLive:
             return controller.display
         return controller.previewDisplay
+
+    def _get_service_manager(self):
+        """
+        Adds the plugin manager to the class dynamically
+        """
+        if not hasattr(self, u'_service_manager'):
+            self._service_manager = Registry().get(u'service_manager')
+        return self._service_manager
+
+    service_manager = property(_get_service_manager)
\ No newline at end of file

=== modified file 'openlp/core/ui/servicemanager.py'
--- openlp/core/ui/servicemanager.py	2013-01-21 19:47:53 +0000
+++ openlp/core/ui/servicemanager.py	2013-01-24 06:06:24 +0000
@@ -39,8 +39,8 @@
 
 from PyQt4 import QtCore, QtGui
 
-from openlp.core.lib import OpenLPToolbar, ServiceItem, Receiver, build_icon, ItemCapabilities, \
-    translate, str_to_bool, check_directory_exists, Settings, PluginStatus, UiStrings
+from openlp.core.lib import OpenLPToolbar, ServiceItem, Receiver, build_icon, ItemCapabilities, SettingsManager, \
+    translate, str_to_bool, check_directory_exists, Settings, PluginStatus, Registry, UiStrings
 from openlp.core.lib.theme import ThemeLevel
 from openlp.core.lib.ui import critical_error_message_box, create_widget_action, find_and_set_in_combo_box
 from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
@@ -98,14 +98,14 @@
     the resources used into one OSZ or oszl file for use on any OpenLP v2
     installation. Also handles the UI tasks of moving things up and down etc.
     """
-    def __init__(self, mainwindow, parent=None):
+    def __init__(self, parent=None):
         """
         Sets up the service manager, toolbars, list view, et al.
         """
         QtGui.QWidget.__init__(self, parent)
         self.active = build_icon(QtGui.QImage(u':/media/auto-start_active.png'))
         self.inactive = build_icon(QtGui.QImage(u':/media/auto-start_inactive.png'))
-        self.mainwindow = mainwindow
+        Registry().register(u'service_manager', self)
         self.serviceItems = []
         self.suffixes = []
         self.dropPosition = 0
@@ -115,9 +115,9 @@
         self._modified = False
         self._fileName = u''
         self.service_has_all_original_files = True
-        self.serviceNoteForm = ServiceNoteForm(self.mainwindow)
-        self.serviceItemEditForm = ServiceItemEditForm(self.mainwindow)
-        self.startTimeForm = StartTimeForm(self.mainwindow)
+        self.serviceNoteForm = ServiceNoteForm(self.main_window)
+        self.serviceItemEditForm = ServiceItemEditForm(self.main_window)
+        self.startTimeForm = StartTimeForm(self.main_window)
         # start with the layout
         self.layout = QtGui.QVBoxLayout(self)
         self.layout.setSpacing(0)
@@ -231,7 +231,7 @@
         QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'theme_update_global'), self.themeChange)
         QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'service_item_update'), self.serviceItemUpdate)
         # Last little bits of setting up
-        self.service_theme = Settings().value(self.mainwindow.serviceManagerSettingsSection + u'/service theme')
+        self.service_theme = Settings().value(self.main_window.serviceManagerSettingsSection + u'/service theme')
         self.servicePath = AppLocation.get_section_data_path(u'servicemanager')
         # build the drag and drop context menu
         self.dndMenu = QtGui.QMenu()
@@ -300,7 +300,7 @@
             self.serviceId += 1
         self._modified = modified
         serviceFile = self.shortFileName() or translate('OpenLP.ServiceManager', 'Untitled Service')
-        self.mainwindow.setServiceModified(modified, serviceFile)
+        self.main_window.setServiceModified(modified, serviceFile)
 
     def isModified(self):
         """
@@ -313,8 +313,7 @@
         Setter for service file.
         """
         self._fileName = unicode(fileName)
-        self.mainwindow.setServiceModified(self.isModified(),
-            self.shortFileName())
+        self.main_window.setServiceModified(self.isModified(), self.shortFileName())
         Settings().setValue(u'servicemanager/last file', fileName)
         self._saveLite = self._fileName.endswith(u'.oszl')
 
@@ -382,19 +381,20 @@
             elif result == QtGui.QMessageBox.Save:
                 self.decideSaveMethod()
         if not loadFile:
-            fileName = QtGui.QFileDialog.getOpenFileName(self.mainwindow,
+            fileName = QtGui.QFileDialog.getOpenFileName(self.main_window,
                 translate('OpenLP.ServiceManager', 'Open File'),
-                Settings().value(self.mainwindow.serviceManagerSettingsSection + u'/last directory'),
-                translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz *.oszl)'))
+                    SettingsManager.get_last_dir(self.main_window.serviceManagerSettingsSection),
+                    translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz *.oszl)'))
             if not fileName:
                 return False
         else:
             fileName = loadFile
-        Settings().setValue(self.mainwindow.serviceManagerSettingsSection + u'/last directory', split_filename(fileName)[0])
+        Settings().setValue(self.main_window.serviceManagerSettingsSection + u'/last directory',
+            split_filename(fileName)[0])
         self.loadFile(fileName)
 
     def saveModifiedService(self):
-        return QtGui.QMessageBox.question(self.mainwindow,
+        return QtGui.QMessageBox.question(self.main_window,
             translate('OpenLP.ServiceManager', 'Modified Service'),
             translate('OpenLP.ServiceManager',
                 'The current service has been modified. Would you like to save this service?'),
@@ -436,7 +436,7 @@
         basename = os.path.splitext(file_name)[0]
         service_file_name = '%s.osd' % basename
         log.debug(u'ServiceManager.saveFile - %s', path_file_name)
-        Settings().setValue(self.mainwindow.serviceManagerSettingsSection + u'/last directory', path)
+        Settings().setValue(self.main_window.serviceManagerSettingsSection + u'/last directory', path)
         service = []
         write_list = []
         missing_list = []
@@ -444,7 +444,7 @@
         total_size = 0
         Receiver.send_message(u'cursor_busy')
         # Number of items + 1 to zip it
-        self.mainwindow.displayProgressBar(len(self.serviceItems) + 1)
+        self.main_window.displayProgressBar(len(self.serviceItems) + 1)
         # Get list of missing files, and list of files to write
         for item in self.serviceItems:
             if not item[u'service_item'].uses_file():
@@ -466,12 +466,12 @@
             answer = QtGui.QMessageBox.critical(self, title, message,
                 QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel))
             if answer == QtGui.QMessageBox.Cancel:
-                self.mainwindow.finishedProgressBar()
+                self.main_window.finishedProgressBar()
                 return False
             Receiver.send_message(u'cursor_busy')
         # Check if item contains a missing file.
         for item in list(self.serviceItems):
-            self.mainwindow.incrementProgressBar()
+            self.main_window.incrementProgressBar()
             item[u'service_item'].remove_invalid_frames(missing_list)
             if item[u'service_item'].missing_frames():
                 self.serviceItems.remove(item)
@@ -498,7 +498,7 @@
         log.debug(u'ServiceManager.saveFile - allowZip64 is %s' % allow_zip_64)
         zip = None
         success = True
-        self.mainwindow.incrementProgressBar()
+        self.main_window.incrementProgressBar()
         try:
             zip = zipfile.ZipFile(temp_file_name, 'w', zipfile.ZIP_STORED, allow_zip_64)
             # First we add service contents.
@@ -530,14 +530,14 @@
         finally:
             if zip:
                 zip.close()
-        self.mainwindow.finishedProgressBar()
+        self.main_window.finishedProgressBar()
         Receiver.send_message(u'cursor_normal')
         if success:
             try:
                 shutil.copy(temp_file_name, path_file_name)
             except:
                 return self.saveFileAs()
-            self.mainwindow.addRecentFile(path_file_name)
+            self.main_window.addRecentFile(path_file_name)
             self.setModified(False)
         delete_file(temp_file_name)
         return success
@@ -562,21 +562,21 @@
         basename = os.path.splitext(file_name)[0]
         service_file_name = '%s.osd' % basename
         log.debug(u'ServiceManager.saveFile - %s', path_file_name)
-        Settings().setValue(self.mainwindow.serviceManagerSettingsSection + u'/last directory', path)
+        Settings().setValue(self.main_window.serviceManagerSettingsSection + u'/last directory', path)
         service = []
         Receiver.send_message(u'cursor_busy')
         # Number of items + 1 to zip it
-        self.mainwindow.displayProgressBar(len(self.serviceItems) + 1)
+        self.main_window.displayProgressBar(len(self.serviceItems) + 1)
         for item in self.serviceItems:
-            self.mainwindow.incrementProgressBar()
+            self.main_window.incrementProgressBar()
             service_item = item[u'service_item'].get_service_repr(self._saveLite)
             #@todo check for file item on save.
             service.append({u'serviceitem': service_item})
-            self.mainwindow.incrementProgressBar()
+            self.main_window.incrementProgressBar()
         service_content = cPickle.dumps(service)
         zip = None
         success = True
-        self.mainwindow.incrementProgressBar()
+        self.main_window.incrementProgressBar()
         try:
             zip = zipfile.ZipFile(temp_file_name, 'w', zipfile.ZIP_STORED,
                 True)
@@ -592,14 +592,14 @@
         finally:
             if zip:
                 zip.close()
-        self.mainwindow.finishedProgressBar()
+        self.main_window.finishedProgressBar()
         Receiver.send_message(u'cursor_normal')
         if success:
             try:
                 shutil.copy(temp_file_name, path_file_name)
             except:
                 return self.saveFileAs()
-            self.mainwindow.addRecentFile(path_file_name)
+            self.main_window.addRecentFile(path_file_name)
             self.setModified(False)
         delete_file(temp_file_name)
         return success
@@ -627,16 +627,16 @@
             default_filename = format_time(default_pattern, local_time)
         else:
             default_filename = u''
-        directory = Settings().value(self.mainwindow.serviceManagerSettingsSection + u'/last directory')
+        directory = Settings().value(self.main_window.serviceManagerSettingsSection + u'/last directory')
         path = os.path.join(directory, default_filename)
         # SaveAs from osz to oszl is not valid as the files will be deleted
         # on exit which is not sensible or usable in the long term.
         if self._fileName.endswith(u'oszl') or self.service_has_all_original_files:
-            fileName = QtGui.QFileDialog.getSaveFileName(self.mainwindow, UiStrings().SaveService, path,
+            fileName = QtGui.QFileDialog.getSaveFileName(self.main_window, UiStrings().SaveService, path,
                 translate('OpenLP.ServiceManager',
                     'OpenLP Service Files (*.osz);; OpenLP Service Files - lite (*.oszl)'))
         else:
-            fileName = QtGui.QFileDialog.getSaveFileName(self.mainwindow, UiStrings().SaveService, path,
+            fileName = QtGui.QFileDialog.getSaveFileName(self.main_window, UiStrings().SaveService, path,
                 translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz);;'))
         if not fileName:
             return False
@@ -695,11 +695,10 @@
                 fileTo.close()
                 self.newFile()
                 self.setFileName(fileName)
-                self.mainwindow.displayProgressBar(len(items))
+                self.main_window.displayProgressBar(len(items))
                 for item in items:
-                    self.mainwindow.incrementProgressBar()
+                    self.main_window.incrementProgressBar()
                     serviceItem = ServiceItem()
-                    serviceItem.renderer = self.mainwindow.renderer
                     if self._saveLite:
                         serviceItem.set_from_service(item)
                     else:
@@ -714,7 +713,7 @@
                         serviceItem.temporary_edit = self.load_item_temporary
                     self.addServiceItem(serviceItem, repaint=False)
                 delete_file(p_file)
-                self.mainwindow.addRecentFile(fileName)
+                self.main_window.addRecentFile(fileName)
                 self.setModified(False)
                 Settings().setValue('servicemanager/last file', fileName)
             else:
@@ -741,7 +740,7 @@
                 fileTo.close()
             if zip:
                 zip.close()
-        self.mainwindow.finishedProgressBar()
+        self.main_window.finishedProgressBar()
         Receiver.send_message(u'cursor_normal')
         self.repaintServiceList(-1, -1)
 
@@ -802,13 +801,13 @@
                 self.autoStartAction.setText(translate('OpenLP.ServiceManager', '&Auto Start - active'))
                 self.autoStartAction.setIcon(self.active)
         if serviceItem[u'service_item'].is_text():
-            for plugin in self.mainwindow.pluginManager.plugins:
+            for plugin in self.plugin_manager.plugins:
                 if plugin.name == u'custom' and plugin.status == PluginStatus.Active:
                     self.create_custom_action.setVisible(True)
                     break
         self.themeMenu.menuAction().setVisible(False)
         # Set up the theme menu.
-        if serviceItem[u'service_item'].is_text() and self.mainwindow.renderer.theme_level == ThemeLevel.Song:
+        if serviceItem[u'service_item'].is_text() and self.renderer.theme_level == ThemeLevel.Song:
             self.themeMenu.menuAction().setVisible(True)
             # The service item does not have a theme, check the "Default".
             if serviceItem[u'service_item'].theme is None:
@@ -1193,8 +1192,8 @@
         """
         log.debug(u'onThemeComboBoxSelected')
         self.service_theme = self.themeComboBox.currentText()
-        self.mainwindow.renderer.set_service_theme(self.service_theme)
-        Settings().setValue(self.mainwindow.serviceManagerSettingsSection + u'/service theme', self.service_theme)
+        self.renderer.set_service_theme(self.service_theme)
+        Settings().setValue(self.main_window.serviceManagerSettingsSection + u'/service theme', self.service_theme)
         self.regenerateServiceItems(True)
 
     def themeChange(self):
@@ -1203,7 +1202,7 @@
         sure the theme combo box is in the correct state.
         """
         log.debug(u'themeChange')
-        visible = self.mainwindow.renderer.theme_level == ThemeLevel.Global
+        visible = self.renderer.theme_level == ThemeLevel.Global
         self.themeLabel.setVisible(visible)
         self.themeComboBox.setVisible(visible)
 
@@ -1266,7 +1265,7 @@
                 newItem.merge(item[u'service_item'])
                 item[u'service_item'] = newItem
                 self.repaintServiceList(itemcount + 1, 0)
-                self.mainwindow.liveController.replaceServiceManagerItem(newItem)
+                self.live_controller.replaceServiceManagerItem(newItem)
                 self.setModified()
 
     def addServiceItem(self, item, rebuild=False, expand=None, replace=False, repaint=True, selected=False):
@@ -1288,7 +1287,7 @@
             item.merge(self.serviceItems[sitem][u'service_item'])
             self.serviceItems[sitem][u'service_item'] = item
             self.repaintServiceList(sitem, child)
-            self.mainwindow.liveController.replaceServiceManagerItem(item)
+            self.live_controller.replaceServiceManagerItem(item)
         else:
             item.render()
             # nothing selected for dnd
@@ -1311,7 +1310,7 @@
                 self.repaintServiceList(self.dropPosition, -1)
             # if rebuilding list make sure live is fixed.
             if rebuild:
-                self.mainwindow.liveController.replaceServiceManagerItem(item)
+                self.live_controller.replaceServiceManagerItem(item)
         self.dropPosition = 0
         self.setModified()
 
@@ -1322,8 +1321,7 @@
         Receiver.send_message(u'cursor_busy')
         item, child = self.findServiceItem()
         if self.serviceItems[item][u'service_item'].is_valid:
-            self.mainwindow.previewController.addServiceManagerItem(
-                self.serviceItems[item][u'service_item'], child)
+            self.preview_controller.addServiceManagerItem(self.serviceItems[item][u'service_item'], child)
         else:
             critical_error_message_box(translate('OpenLP.ServiceManager', 'Missing Display Handler'),
                 translate('OpenLP.ServiceManager',
@@ -1363,16 +1361,15 @@
             child = row
         Receiver.send_message(u'cursor_busy')
         if self.serviceItems[item][u'service_item'].is_valid:
-            self.mainwindow.liveController.addServiceManagerItem(
-                self.serviceItems[item][u'service_item'], child)
-            if Settings().value(self.mainwindow.generalSettingsSection + u'/auto preview'):
+            self.live_controller.addServiceManagerItem(self.serviceItems[item][u'service_item'], child)
+            if Settings().value(self.main_window.generalSettingsSection + u'/auto preview'):
                 item += 1
                 if self.serviceItems and item < len(self.serviceItems) and \
                         self.serviceItems[item][u'service_item'].is_capable(ItemCapabilities.CanPreview):
-                    self.mainwindow.previewController.addServiceManagerItem(self.serviceItems[item][u'service_item'], 0)
+                    self.preview_controller.addServiceManagerItem(self.serviceItems[item][u'service_item'], 0)
                     next_item = self.serviceManagerList.topLevelItem(item)
                     self.serviceManagerList.setCurrentItem(next_item)
-                    self.mainwindow.liveController.previewListWidget.setFocus()
+                    self.live_controller.previewListWidget.setFocus()
         else:
             critical_error_message_box(translate('OpenLP.ServiceManager', 'Missing Display Handler'),
                 translate('OpenLP.ServiceManager',
@@ -1516,7 +1513,7 @@
             themeGroup.addAction(create_widget_action(self.themeMenu, theme, text=theme, checked=False,
                 triggers=self.onThemeChangeAction))
         find_and_set_in_combo_box(self.themeComboBox, self.service_theme)
-        self.mainwindow.renderer.set_service_theme(self.service_theme)
+        self.renderer.set_service_theme(self.service_theme)
         self.regenerateServiceItems()
 
     def onThemeChangeAction(self):
@@ -1539,5 +1536,55 @@
         """
         Print a Service Order Sheet.
         """
-        settingDialog = PrintServiceForm(self.mainwindow, self)
+        settingDialog = PrintServiceForm(self.main_window, self)
         settingDialog.exec_()
+
+    def _get_renderer(self):
+        """
+        Adds the Renderer to the class dynamically
+        """
+        if not hasattr(self, u'_renderer'):
+            self._renderer = Registry().get(u'renderer')
+        return self._renderer
+
+    renderer = property(_get_renderer)
+
+    def _get_live_controller(self):
+        """
+        Adds the live controller to the class dynamically
+        """
+        if not hasattr(self, u'_live_controller'):
+            self._live_controller = Registry().get(u'live_controller')
+        return self._live_controller
+
+    live_controller = property(_get_live_controller)
+
+    def _get_preview_controller(self):
+        """
+        Adds the preview controller to the class dynamically
+        """
+        if not hasattr(self, u'_preview_controller'):
+            self._preview_controller = Registry().get(u'preview_controller')
+        return self._preview_controller
+
+    preview_controller = property(_get_preview_controller)
+
+    def _get_plugin_manager(self):
+        """
+        Adds the plugin manager to the class dynamically
+        """
+        if not hasattr(self, u'_plugin_manager'):
+            self._plugin_manager = Registry().get(u'plugin_manager')
+        return self._plugin_manager
+
+    plugin_manager = property(_get_plugin_manager)
+
+    def _get_main_window(self):
+        """
+        Adds the main window to the class dynamically
+        """
+        if not hasattr(self, u'_main_window'):
+            self._main_window = Registry().get(u'main_window')
+        return self._main_window
+
+    main_window = property(_get_main_window)
\ No newline at end of file

=== modified file 'openlp/core/ui/settingsform.py'
--- openlp/core/ui/settingsform.py	2013-01-18 23:31:02 +0000
+++ openlp/core/ui/settingsform.py	2013-01-24 06:06:24 +0000
@@ -33,7 +33,7 @@
 
 from PyQt4 import QtGui
 
-from openlp.core.lib import Receiver, build_icon, PluginStatus
+from openlp.core.lib import Receiver, build_icon, PluginStatus, Registry
 from openlp.core.ui import AdvancedTab, GeneralTab, ThemesTab
 from openlp.core.ui.media import PlayerTab
 from settingsdialog import Ui_SettingsDialog
@@ -44,21 +44,21 @@
     """
     Provide the form to manipulate the settings for OpenLP
     """
-    def __init__(self, mainWindow, parent=None):
+    def __init__(self, parent=None):
         """
         Initialise the settings form
         """
-        self.mainWindow = mainWindow
+        Registry().register(u'settings_form', self)
         QtGui.QDialog.__init__(self, parent)
         self.setupUi(self)
         # General tab
         self.generalTab = GeneralTab(self)
         # Themes tab
-        self.themesTab = ThemesTab(self, mainWindow)
+        self.themesTab = ThemesTab(self, self.main_window)
         # Advanced tab
         self.advancedTab = AdvancedTab(self)
         # Advanced tab
-        self.playerTab = PlayerTab(self, mainWindow)
+        self.playerTab = PlayerTab(self, self.main_window)
 
     def exec_(self):
         # load all the settings
@@ -142,3 +142,13 @@
         if self.resetSuffixes:
             self.mainWindow.serviceManagerContents.resetSupportedSuffixes()
             self.resetSuffixes = False
+
+    def _get_main_window(self):
+        """
+        Adds the main window to the class dynamically
+        """
+        if not hasattr(self, u'_main_window'):
+            self._main_window = Registry().get(u'main_window')
+        return self._main_window
+
+    main_window = property(_get_main_window)
\ No newline at end of file

=== modified file 'openlp/core/ui/slidecontroller.py'
--- openlp/core/ui/slidecontroller.py	2013-01-21 19:47:53 +0000
+++ openlp/core/ui/slidecontroller.py	2013-01-24 06:06:24 +0000
@@ -35,10 +35,9 @@
 from PyQt4 import QtCore, QtGui
 
 from openlp.core.lib import OpenLPToolbar, Receiver, ItemCapabilities, translate, build_icon, build_html, \
-    PluginManager, ServiceItem, ImageSource, SlideLimits, ServiceItemAction, Settings, ScreenList, UiStrings
+    ServiceItem, ImageSource, SlideLimits, ServiceItemAction, Settings, Registry, UiStrings, ScreenList
+from openlp.core.ui import HideMode, MainDisplay, Display, DisplayControllerType
 from openlp.core.lib.ui import create_action
-from openlp.core.lib import SlideLimits, ServiceItemAction
-from openlp.core.ui import HideMode, MainDisplay, Display, DisplayControllerType
 from openlp.core.utils.actions import ActionList, CategoryOrder
 
 log = logging.getLogger(__name__)
@@ -83,8 +82,6 @@
             self.ratio = float(self.screens.current[u'size'].width()) / float(self.screens.current[u'size'].height())
         except ZeroDivisionError:
             self.ratio = 1
-        self.imageManager = self.parent().imageManager
-        self.mediaController = self.parent().mediaController
         self.loopList = [
             u'playSlidesMenu',
             u'loopSeparator',
@@ -110,6 +107,7 @@
         # Type label for the top of the slide controller
         self.typeLabel = QtGui.QLabel(self.panel)
         if self.isLive:
+            Registry().register(u'live_controller', self)
             self.typeLabel.setText(UiStrings().Live)
             self.split = 1
             self.typePrefix = u'live'
@@ -118,6 +116,7 @@
             self.category = UiStrings().LiveToolbar
             ActionList.get_instance().add_category(unicode(self.category), CategoryOrder.standardToolbar)
         else:
+            Registry().register(u'preview_controller', self)
             self.typeLabel.setText(UiStrings().Preview)
             self.split = 0
             self.typePrefix = u'preview'
@@ -231,7 +230,7 @@
                 tooltip=translate('OpenLP.SlideController', 'Edit and reload song preview.'), triggers=self.onEditSong)
         self.controllerLayout.addWidget(self.toolbar)
         # Build the Media Toolbar
-        self.mediaController.register_controller(self)
+        self.media_controller.register_controller(self)
         if self.isLive:
             # Build the Song Toolbar
             self.songMenu = QtGui.QToolButton(self.toolbar)
@@ -354,8 +353,7 @@
             self.setLiveHotkeys(self)
             self.__addActionsToWidget(self.previewListWidget)
         else:
-            self.previewListWidget.addActions(
-                [self.nextItem, self.previousItem])
+            self.previewListWidget.addActions([self.nextItem, self.previousItem])
         QtCore.QObject.connect(Receiver.get_receiver(),
             QtCore.SIGNAL(u'slidecontroller_%s_stop_loop' % self.typePrefix), self.onStopLoop)
         QtCore.QObject.connect(Receiver.get_receiver(),
@@ -450,7 +448,7 @@
 
     def liveEscape(self):
         self.display.setVisible(False)
-        self.mediaController.media_stop(self)
+        self.media_controller.media_stop(self)
 
     def toggleDisplay(self, action):
         """
@@ -507,7 +505,7 @@
         # rebuild display as screen size changed
         if self.display:
             self.display.close()
-        self.display = MainDisplay(self, self.imageManager, self.isLive, self)
+        self.display = MainDisplay(self, self.isLive, self)
         self.display.setup()
         if self.isLive:
             self.__addActionsToWidget(self.display)
@@ -517,13 +515,13 @@
             self.ratio = float(self.screens.current[u'size'].width()) / float(self.screens.current[u'size'].height())
         except ZeroDivisionError:
             self.ratio = 1
-        self.mediaController.setup_display(self.display, False)
+        self.media_controller.setup_display(self.display, False)
         self.previewSizeChanged()
         self.previewDisplay.setup()
         serviceItem = ServiceItem()
         self.previewDisplay.webView.setHtml(build_html(serviceItem, self.previewDisplay.screen, None, self.isLive,
-            plugins=PluginManager.get_instance().plugins))
-        self.mediaController.setup_display(self.previewDisplay,True)
+            plugins=self.plugin_manager.plugins))
+        self.media_controller.setup_display(self.previewDisplay,True)
         if self.serviceItem:
             self.refreshServiceItem()
 
@@ -773,9 +771,9 @@
                 else:
                     # If current slide set background to image
                     if framenumber == slideno:
-                        self.serviceItem.bg_image_bytes = self.imageManager.getImageBytes(frame[u'path'],
+                        self.serviceItem.bg_image_bytes = self.image_manager.getImageBytes(frame[u'path'],
                             ImageSource.ImagePlugin)
-                    image = self.imageManager.getImage(frame[u'path'], ImageSource.ImagePlugin)
+                    image = self.image_manager.getImage(frame[u'path'], ImageSource.ImagePlugin)
                     label.setPixmap(QtGui.QPixmap.fromImage(image))
                 self.previewListWidget.setCellWidget(framenumber, 0, label)
                 slideHeight = width * (1 / self.ratio)
@@ -1223,7 +1221,7 @@
         Respond to the arrival of a media service item
         """
         log.debug(u'SlideController onMediaStart')
-        self.mediaController.video(self.controllerType, item, self.hideMode())
+        self.media_controller.video(self.controllerType, item, self.hideMode())
         if not self.isLive:
             self.previewDisplay.show()
             self.slidePreview.hide()
@@ -1233,7 +1231,7 @@
         Respond to a request to close the Video
         """
         log.debug(u'SlideController onMediaClose')
-        self.mediaController.media_reset(self)
+        self.media_controller.media_reset(self)
         self.previewDisplay.hide()
         self.slidePreview.show()
 
@@ -1279,3 +1277,34 @@
     def onTrackTriggered(self):
         action = self.sender()
         self.display.audioPlayer.goTo(action.data())
+
+    def _get_plugin_manager(self):
+        """
+        Adds the plugin manager to the class dynamically
+        """
+        if not hasattr(self, u'_plugin_manager'):
+            self._plugin_manager = Registry().get(u'plugin_manager')
+        return self._plugin_manager
+
+    plugin_manager = property(_get_plugin_manager)
+
+    def _get_image_manager(self):
+        """
+        Adds the image manager to the class dynamically
+        """
+        if not hasattr(self, u'_image_manager'):
+            self._image_manager = Registry().get(u'image_manager')
+        return self._image_manager
+
+    image_manager = property(_get_image_manager)
+
+    def _get_media_controller(self):
+        """
+        Adds the media controller to the class dynamically
+        """
+        if not hasattr(self, u'_media_controller'):
+            self._media_controller = Registry().get(u'media_controller')
+        return self._media_controller
+
+    media_controller = property(_get_media_controller)
+

=== modified file 'openlp/core/ui/thememanager.py'
--- openlp/core/ui/thememanager.py	2013-01-17 22:14:06 +0000
+++ openlp/core/ui/thememanager.py	2013-01-24 06:06:24 +0000
@@ -37,7 +37,8 @@
 from PyQt4 import QtCore, QtGui
 
 from openlp.core.lib import OpenLPToolbar, get_text_file_string, build_icon, Receiver, SettingsManager, translate, \
-    check_item_selected, check_directory_exists, create_thumb, validate_thumb, ImageSource, Settings, UiStrings
+    check_item_selected, check_directory_exists, create_thumb, validate_thumb, ImageSource, Settings, Registry, \
+    UiStrings
 from openlp.core.lib.theme import ThemeXML, BackgroundType, VerticalType, BackgroundGradientType
 from openlp.core.lib.ui import critical_error_message_box, create_widget_action
 from openlp.core.theme import Theme
@@ -50,9 +51,9 @@
     """
     Manages the orders of Theme.
     """
-    def __init__(self, mainwindow, parent=None):
+    def __init__(self, parent=None):
         QtGui.QWidget.__init__(self, parent)
-        self.mainwindow = mainwindow
+        Registry().register(u'theme_manager', self)
         self.settingsSection = u'themes'
         self.themeForm = ThemeForm(self)
         self.fileRenameForm = FileRenameForm(self)
@@ -261,11 +262,10 @@
                     old_theme_data = self.getThemeData(old_theme_name)
                     self.cloneThemeData(old_theme_data, new_theme_name)
                     self.deleteTheme(old_theme_name)
-                    for plugin in self.mainwindow.pluginManager.plugins:
+                    for plugin in self.plugin_manager.plugins:
                         if plugin.usesTheme(old_theme_name):
                             plugin.renameTheme(old_theme_name, new_theme_name)
-                    self.mainwindow.renderer.update_theme(
-                        new_theme_name, old_theme_name)
+                    self.renderer.update_theme(new_theme_name, old_theme_name)
                     self.loadThemes()
 
     def onCopyTheme(self):
@@ -312,7 +312,7 @@
             self.themeForm.theme = theme
             self.themeForm.exec_(True)
             self.oldBackgroundImage = None
-            self.mainwindow.renderer.update_theme(theme.theme_name)
+            self.renderer.update_theme(theme.theme_name)
             self.loadThemes()
 
     def onDeleteTheme(self):
@@ -327,7 +327,7 @@
             row = self.themeListWidget.row(item)
             self.themeListWidget.takeItem(row)
             self.deleteTheme(theme)
-            self.mainwindow.renderer.update_theme(theme, only_delete=True)
+            self.renderer.update_theme(theme, only_delete=True)
             # As we do not reload the themes, push out the change. Reload the
             # list as the internal lists and events need to be triggered.
             self._pushThemes()
@@ -631,9 +631,9 @@
         """
         self._writeTheme(theme, image_from, image_to)
         if theme.background_type == BackgroundType.to_string(BackgroundType.Image):
-            self.mainwindow.imageManager.updateImageBorder(theme.background_filename,
+            self.image_manager.updateImageBorder(theme.background_filename,
                 ImageSource.Theme, QtGui.QColor(theme.background_border_color))
-            self.mainwindow.imageManager.processUpdates()
+            self.image_manager.processUpdates()
 
     def _writeTheme(self, theme, image_from, image_to):
         """
@@ -680,11 +680,11 @@
         """
         Called to update the themes' preview images.
         """
-        self.mainwindow.displayProgressBar(len(self.themeList))
+        self.main_window.displayProgressBar(len(self.themeList))
         for theme in self.themeList:
-            self.mainwindow.incrementProgressBar()
+            self.main_window.incrementProgressBar()
             self.generateAndSaveImage(self.path, theme, self.getThemeData(theme))
-        self.mainwindow.finishedProgressBar()
+        self.main_window.finishedProgressBar()
         self.loadThemes()
 
     def generateImage(self, theme_data, forcePage=False):
@@ -698,7 +698,7 @@
             Flag to tell message lines per page need to be generated.
         """
         log.debug(u'generateImage \n%s ', theme_data)
-        return self.mainwindow.renderer.generate_preview(theme_data, forcePage)
+        return self.renderer.generate_preview(theme_data, forcePage)
 
     def getPreviewImage(self, theme):
         """
@@ -747,7 +747,7 @@
                 return False
             # check for use in the system else where.
             if testPlugin:
-                for plugin in self.mainwindow.pluginManager.plugins:
+                for plugin in self.plugin_manager.plugins:
                     if plugin.usesTheme(theme):
                         critical_error_message_box(translate('OpenLP.ThemeManager', 'Validation Error'),
                             translate('OpenLP.ThemeManager', 'Theme %s is used in the %s plugin.') %
@@ -805,3 +805,42 @@
         new_theme.display_vertical_align = vAlignCorrection
         return new_theme.extract_xml()
 
+    def _get_renderer(self):
+        """
+        Adds the Renderer to the class dynamically
+        """
+        if not hasattr(self, u'_renderer'):
+            self._renderer = Registry().get(u'renderer')
+        return self._renderer
+
+    renderer = property(_get_renderer)
+
+    def _get_image_manager(self):
+        """
+        Adds the image manager to the class dynamically
+        """
+        if not hasattr(self, u'_image_manager'):
+            self._image_manager = Registry().get(u'image_manager')
+        return self._image_manager
+
+    image_manager = property(_get_image_manager)
+
+    def _get_plugin_manager(self):
+        """
+        Adds the Renderer to the class dynamically
+        """
+        if not hasattr(self, u'_plugin_manager'):
+            self._plugin_manager = Registry().get(u'plugin_manager')
+        return self._plugin_manager
+
+    plugin_manager = property(_get_plugin_manager)
+
+    def _get_main_window(self):
+        """
+        Adds the main window to the class dynamically
+        """
+        if not hasattr(self, u'_main_window'):
+            self._main_window = Registry().get(u'main_window')
+        return self._main_window
+
+    main_window = property(_get_main_window)

=== modified file 'openlp/plugins/alerts/alertsplugin.py'
--- openlp/plugins/alerts/alertsplugin.py	2013-01-16 11:28:38 +0000
+++ openlp/plugins/alerts/alertsplugin.py	2013-01-24 06:06:24 +0000
@@ -128,8 +128,8 @@
 class AlertsPlugin(Plugin):
     log.info(u'Alerts Plugin loaded')
 
-    def __init__(self, plugin_helpers):
-        Plugin.__init__(self, u'alerts', __default_settings__, plugin_helpers, settings_tab_class=AlertsTab)
+    def __init__(self):
+        Plugin.__init__(self, u'alerts', __default_settings__, settings_tab_class=AlertsTab)
         self.weight = -3
         self.iconPath = u':/plugins/plugin_alerts.png'
         self.icon = build_icon(self.iconPath)
@@ -151,7 +151,7 @@
             text=translate('AlertsPlugin', '&Alert'), icon=u':/plugins/plugin_alerts.png',
             statustip=translate('AlertsPlugin', 'Show an alert message.'),
             visible=False, shortcuts=[u'F7'], triggers=self.onAlertsTrigger)
-        self.serviceManager.mainwindow.toolsMenu.addAction(self.toolsAlertItem)
+        self.main_window.toolsMenu.addAction(self.toolsAlertItem)
 
     def initialise(self):
         log.info(u'Alerts Initialising')

=== modified file 'openlp/plugins/alerts/forms/alertform.py'
--- openlp/plugins/alerts/forms/alertform.py	2013-01-01 16:33:41 +0000
+++ openlp/plugins/alerts/forms/alertform.py	2013-01-24 06:06:24 +0000
@@ -45,7 +45,7 @@
         self.manager = plugin.manager
         self.plugin = plugin
         self.item_id = None
-        QtGui.QDialog.__init__(self, plugin.formParent)
+        QtGui.QDialog.__init__(self, self.plugin.main_window)
         self.setupUi(self)
         QtCore.QObject.connect(self.displayButton, QtCore.SIGNAL(u'clicked()'), self.onDisplayClicked)
         QtCore.QObject.connect(self.displayCloseButton, QtCore.SIGNAL(u'clicked()'), self.onDisplayCloseClicked)

=== modified file 'openlp/plugins/bibles/bibleplugin.py'
--- openlp/plugins/bibles/bibleplugin.py	2013-01-20 12:23:22 +0000
+++ openlp/plugins/bibles/bibleplugin.py	2013-01-24 06:06:24 +0000
@@ -68,8 +68,8 @@
 class BiblePlugin(Plugin):
     log.info(u'Bible Plugin loaded')
 
-    def __init__(self, plugin_helpers):
-        Plugin.__init__(self, u'bibles', __default_settings__, plugin_helpers, BibleMediaItem, BiblesTab)
+    def __init__(self):
+        Plugin.__init__(self, u'bibles', __default_settings__, BibleMediaItem, BiblesTab)
         self.weight = -9
         self.iconPath = u':/plugins/plugin_bibles.png'
         self.icon = build_icon(self.iconPath)
@@ -108,7 +108,7 @@
         """
         Plugin.appStartup(self)
         if self.manager.old_bible_databases:
-            if QtGui.QMessageBox.information(self.formParent,
+            if QtGui.QMessageBox.information(self.main_window,
                 translate('OpenLP', 'Information'),
                 translate('OpenLP', 'Bible format has changed.\nYou have to upgrade your existing Bibles.\n'
                     'Should OpenLP upgrade now?'),
@@ -149,7 +149,7 @@
         Upgrade older bible databases.
         """
         if not hasattr(self, u'upgrade_wizard'):
-            self.upgrade_wizard = BibleUpgradeForm(self.formParent, self.manager, self)
+            self.upgrade_wizard = BibleUpgradeForm(self.main_window, self.manager, self)
         # If the import was not cancelled then reload.
         if self.upgrade_wizard.exec_():
             self.mediaItem.reloadBibles()

=== modified file 'openlp/plugins/bibles/lib/mediaitem.py'
--- openlp/plugins/bibles/lib/mediaitem.py	2013-01-21 23:39:10 +0000
+++ openlp/plugins/bibles/lib/mediaitem.py	2013-01-24 06:06:24 +0000
@@ -479,7 +479,7 @@
         elif self.advancedTab.isVisible():
             bible = self.advancedVersionComboBox.currentText()
         if bible:
-            self.editBibleForm = EditBibleForm(self, self.plugin.formParent, self.plugin.manager)
+            self.editBibleForm = EditBibleForm(self, self.main_window, self.plugin.manager)
             self.editBibleForm.loadBible(bible)
             if self.editBibleForm.exec_():
                 self.reloadBibles()

=== modified file 'openlp/plugins/custom/customplugin.py'
--- openlp/plugins/custom/customplugin.py	2013-01-18 21:36:15 +0000
+++ openlp/plugins/custom/customplugin.py	2013-01-24 06:06:24 +0000
@@ -60,8 +60,8 @@
     """
     log.info(u'Custom Plugin loaded')
 
-    def __init__(self, plugin_helpers):
-        Plugin.__init__(self, u'custom', __default_settings__, plugin_helpers, CustomMediaItem, CustomTab)
+    def __init__(self):
+        Plugin.__init__(self, u'custom', __default_settings__, CustomMediaItem, CustomTab)
         self.weight = -5
         self.manager = Manager(u'custom', init_schema)
         self.iconPath = u':/plugins/plugin_custom.png'

=== modified file 'openlp/plugins/custom/lib/mediaitem.py'
--- openlp/plugins/custom/lib/mediaitem.py	2013-01-11 00:19:11 +0000
+++ openlp/plugins/custom/lib/mediaitem.py	2013-01-24 06:06:24 +0000
@@ -57,7 +57,7 @@
     def __init__(self, parent, plugin, icon):
         self.IconPath = u'custom/custom'
         MediaManagerItem.__init__(self, parent, plugin, icon)
-        self.edit_custom_form = EditCustomForm(self, self.plugin.formParent, self.plugin.manager)
+        self.edit_custom_form = EditCustomForm(self, self.main_window, self.plugin.manager)
         self.singleServiceItem = False
         self.quickPreviewAllowed = True
         self.hasSearch = True

=== modified file 'openlp/plugins/images/imageplugin.py'
--- openlp/plugins/images/imageplugin.py	2013-01-18 19:24:06 +0000
+++ openlp/plugins/images/imageplugin.py	2013-01-24 06:06:24 +0000
@@ -45,8 +45,8 @@
 class ImagePlugin(Plugin):
     log.info(u'Image Plugin loaded')
 
-    def __init__(self, plugin_helpers):
-        Plugin.__init__(self, u'images', __default_settings__, plugin_helpers, ImageMediaItem, ImageTab)
+    def __init__(self):
+        Plugin.__init__(self, u'images', __default_settings__, ImageMediaItem, ImageTab)
         self.weight = -7
         self.iconPath = u':/plugins/plugin_images.png'
         self.icon = build_icon(self.iconPath)

=== modified file 'openlp/plugins/images/lib/mediaitem.py'
--- openlp/plugins/images/lib/mediaitem.py	2013-01-18 19:24:06 +0000
+++ openlp/plugins/images/lib/mediaitem.py	2013-01-24 06:06:24 +0000
@@ -100,22 +100,22 @@
             row_list = [item.row() for item in self.listView.selectedIndexes()]
             row_list.sort(reverse=True)
             Receiver.send_message(u'cursor_busy')
-            self.plugin.formParent.displayProgressBar(len(row_list))
+            self.main_window.displayProgressBar(len(row_list))
             for row in row_list:
                 text = self.listView.item(row)
                 if text:
                     delete_file(os.path.join(self.servicePath, text.text()))
                 self.listView.takeItem(row)
-                self.plugin.formParent.incrementProgressBar()
-            Settings().setValue(self.settingsSection + u'/images files', self.getFileList())
-            self.plugin.formParent.finishedProgressBar()
+                self.main_window.incrementProgressBar()
+            SettingsManager.setValue(self.settingsSection + u'/images files', self.getFileList())
+            self.main_window.finishedProgressBar()
             Receiver.send_message(u'cursor_normal')
         self.listView.blockSignals(False)
 
     def loadList(self, images, initialLoad=False):
         if not initialLoad:
             Receiver.send_message(u'cursor_busy')
-            self.plugin.formParent.displayProgressBar(len(images))
+            self.main_window.displayProgressBar(len(images))
         # Sort the images by its filename considering language specific
         # characters.
         images.sort(cmp=locale_compare, key=lambda filename: os.path.split(unicode(filename))[1])
@@ -135,9 +135,9 @@
             item_name.setData(QtCore.Qt.UserRole, imageFile)
             self.listView.addItem(item_name)
             if not initialLoad:
-                self.plugin.formParent.incrementProgressBar()
+                self.main_window.incrementProgressBar()
         if not initialLoad:
-            self.plugin.formParent.finishedProgressBar()
+            self.main_window.finishedProgressBar()
             Receiver.send_message(u'cursor_normal')
 
     def generateSlideData(self, service_item, item=None, xmlVersion=False,

=== modified file 'openlp/plugins/media/lib/mediaitem.py'
--- openlp/plugins/media/lib/mediaitem.py	2013-01-20 12:23:22 +0000
+++ openlp/plugins/media/lib/mediaitem.py	2013-01-24 06:06:24 +0000
@@ -64,14 +64,14 @@
         self.mediaObject = None
         self.displayController = DisplayController(parent)
         self.displayController.controllerLayout = QtGui.QVBoxLayout()
-        self.plugin.mediaController.register_controller(self.displayController)
-        self.plugin.mediaController.set_controls_visible(self.displayController, False)
+        self.media_controller.register_controller(self.displayController)
+        self.media_controller.set_controls_visible(self.displayController, False)
         self.displayController.previewDisplay = Display(self.displayController, False, self.displayController)
         self.displayController.previewDisplay.hide()
         self.displayController.previewDisplay.setGeometry(QtCore.QRect(0, 0, 300, 300))
         self.displayController.previewDisplay.screen = {u'size':self.displayController.previewDisplay.geometry()}
         self.displayController.previewDisplay.setup()
-        self.plugin.mediaController.setup_display(self.displayController.previewDisplay, False)
+        self.media_controller.setup_display(self.displayController.previewDisplay, False)
         QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'video_background_replaced'),
             self.videobackgroundReplaced)
         QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'mediaitem_media_rebuild'), self.rebuild_players)
@@ -131,7 +131,7 @@
         """
         Called to reset the Live background with the media selected,
         """
-        self.plugin.liveController.mediaController.media_reset(self.plugin.liveController)
+        self.live_controller.mediaController.media_reset(self.plugin.liveController)
         self.resetAction.setVisible(False)
 
     def videobackgroundReplaced(self):
@@ -154,7 +154,7 @@
                 service_item.shortname = service_item.title
                 (path, name) = os.path.split(filename)
                 service_item.add_from_command(path, name,CLAPPERBOARD)
-                if self.plugin.liveController.mediaController.video(DisplayControllerType.Live, service_item,
+                if self.live_controller.mediaController.video(DisplayControllerType.Live, service_item,
                         videoBehindText=True):
                     self.resetAction.setVisible(True)
                 else:
@@ -186,7 +186,7 @@
         # Only get start and end times if going to a service
         if context == ServiceItemContext.Service:
             # Start media and obtain the length
-            if not self.plugin.mediaController.media_length(service_item):
+            if not self.media_controller.media_length(service_item):
                 return False
         service_item.add_capability(ItemCapabilities.CanAutoStartForLive)
         service_item.add_capability(ItemCapabilities.RequiresMedia)
@@ -212,11 +212,11 @@
         """
         self.populateDisplayTypes()
         self.onNewFileMasks = translate('MediaPlugin.MediaItem', 'Videos (%s);;Audio (%s);;%s (*)') % (
-            u' '.join(self.plugin.mediaController.video_extensions_list),
-            u' '.join(self.plugin.mediaController.audio_extensions_list), UiStrings().AllFiles)
+            u' '.join(self.media_controller.video_extensions_list),
+            u' '.join(self.media_controller.audio_extensions_list), UiStrings().AllFiles)
 
     def displaySetup(self):
-        self.plugin.mediaController.setup_display(self.displayController.previewDisplay, False)
+        self.media_controller.setup_display(self.displayController.previewDisplay, False)
 
     def populateDisplayTypes(self):
         """
@@ -228,7 +228,7 @@
         self.displayTypeComboBox.blockSignals(True)
         self.displayTypeComboBox.clear()
         usedPlayers, overridePlayer = get_media_players()
-        mediaPlayers = self.plugin.mediaController.mediaPlayers
+        mediaPlayers = self.media_controller.mediaPlayers
         currentIndex = 0
         for player in usedPlayers:
             # load the drop down selection
@@ -270,7 +270,7 @@
             elif track_info.isFile():
                 filename = os.path.split(unicode(track))[1]
                 item_name = QtGui.QListWidgetItem(filename)
-                if u'*.%s' % (filename.split(u'.')[-1].lower()) in self.plugin.mediaController.audio_extensions_list:
+                if u'*.%s' % (filename.split(u'.')[-1].lower()) in self.media_controller.audio_extensions_list:
                     item_name.setIcon(AUDIO)
                 else:
                     item_name.setIcon(VIDEO)
@@ -288,9 +288,9 @@
         media.sort(cmp=locale_compare, key=lambda filename: os.path.split(unicode(filename))[1])
         ext = []
         if type == MediaType.Audio:
-            ext = self.plugin.mediaController.audio_extensions_list
+            ext = self.media_controller.audio_extensions_list
         else:
-            ext = self.plugin.mediaController.video_extensions_list
+            ext = self.media_controller.video_extensions_list
         ext = map(lambda x: x[1:], ext)
         media = filter(lambda x: os.path.splitext(x)[1] in ext, media)
         return media

=== modified file 'openlp/plugins/media/mediaplugin.py'
--- openlp/plugins/media/mediaplugin.py	2013-01-18 19:24:06 +0000
+++ openlp/plugins/media/mediaplugin.py	2013-01-24 06:06:24 +0000
@@ -31,7 +31,7 @@
 
 from PyQt4 import QtCore
 
-from openlp.core.lib import Plugin, StringContent, build_icon, translate, Settings
+from openlp.core.lib import Plugin, StringContent, build_icon, translate, Settings, Registry
 from openlp.plugins.media.lib import MediaMediaItem, MediaTab
 
 log = logging.getLogger(__name__)
@@ -46,8 +46,8 @@
 class MediaPlugin(Plugin):
     log.info(u'%s MediaPlugin loaded', __name__)
 
-    def __init__(self, plugin_helpers):
-        Plugin.__init__(self, u'media', __default_settings__, plugin_helpers, MediaMediaItem)
+    def __init__(self):
+        Plugin.__init__(self, u'media', __default_settings__, MediaMediaItem)
         self.weight = -6
         self.iconPath = u':/plugins/plugin_media.png'
         self.icon = build_icon(self.iconPath)
@@ -97,26 +97,26 @@
         Time to tidy up on exit
         """
         log.info(u'Media Finalising')
-        self.mediaController.finalise()
+        self.media_controller.finalise()
         Plugin.finalise(self)
 
     def getDisplayCss(self):
         """
         Add css style sheets to htmlbuilder
         """
-        return self.mediaController.get_media_display_css()
+        return self.media_controller.get_media_display_css()
 
     def getDisplayJavaScript(self):
         """
         Add javascript functions to htmlbuilder
         """
-        return self.mediaController.get_media_display_javascript()
+        return self.media_controller.get_media_display_javascript()
 
     def getDisplayHtml(self):
         """
         Add html code to htmlbuilder
         """
-        return self.mediaController.get_media_display_html()
+        return self.media_controller.get_media_display_html()
 
     def appStartup(self):
         """
@@ -129,7 +129,7 @@
         settings.beginGroup(self.settingsSection)
         if settings.contains(u'use phonon'):
             log.info(u'Found old Phonon setting')
-            players = self.mediaController.mediaPlayers.keys()
+            players = self.media_controller.mediaPlayers.keys()
             has_phonon = u'phonon' in players
             if settings.value(u'use phonon')  and has_phonon:
                 log.debug(u'Converting old setting to new setting')
@@ -137,8 +137,18 @@
                 if players:
                     new_players = [player for player in players if player != u'phonon']
                 new_players.insert(0, u'phonon')
-                self.mediaController.mediaPlayers[u'phonon'].isActive = True
+                self.media_controller.mediaPlayers[u'phonon'].isActive = True
                 settings.setValue(u'players', u','.join(new_players))
                 self.settingsTab.load()
             settings.remove(u'use phonon')
         settings.endGroup()
+
+    def _get_media_controller(self):
+        """
+        Adds the media controller to the class dynamically
+        """
+        if not hasattr(self, u'_media_controller'):
+            self._media_controller = Registry().get(u'media_controller')
+        return self._media_controller
+
+    media_controller = property(_get_media_controller)

=== modified file 'openlp/plugins/presentations/lib/mediaitem.py'
--- openlp/plugins/presentations/lib/mediaitem.py	2013-01-18 19:24:06 +0000
+++ openlp/plugins/presentations/lib/mediaitem.py	2013-01-24 06:06:24 +0000
@@ -153,13 +153,13 @@
         Receiver.send_message(u'cursor_busy')
         if not initialLoad:
             Receiver.send_message(u'cursor_busy')
-            self.plugin.formParent.displayProgressBar(len(files))
+            self.main_window.displayProgressBar(len(files))
         # Sort the presentations by its filename considering language specific characters.
         files.sort(cmp=locale_compare,
             key=lambda filename: os.path.split(unicode(filename))[1])
         for file in files:
             if not initialLoad:
-                self.plugin.formParent.incrementProgressBar()
+                self.main_window.incrementProgressBar()
             if currlist.count(file) > 0:
                 continue
             filename = os.path.split(unicode(file))[1]
@@ -208,7 +208,7 @@
                 self.listView.addItem(item_name)
         Receiver.send_message(u'cursor_normal')
         if not initialLoad:
-            self.plugin.formParent.finishedProgressBar()
+            self.main_window.finishedProgressBar()
             Receiver.send_message(u'cursor_normal')
 
     def onDeleteClick(self):
@@ -220,15 +220,15 @@
             row_list = [item.row() for item in items]
             row_list.sort(reverse=True)
             Receiver.send_message(u'cursor_busy')
-            self.plugin.formParent.displayProgressBar(len(row_list))
+            self.main_window.displayProgressBar(len(row_list))
             for item in items:
                 filepath = unicode(item.data(QtCore.Qt.UserRole))
                 for cidx in self.controllers:
                     doc = self.controllers[cidx].add_document(filepath)
                     doc.presentation_deleted()
                     doc.close_presentation()
-                self.plugin.formParent.incrementProgressBar()
-            self.plugin.formParent.finishedProgressBar()
+                self.main_window.incrementProgressBar()
+            self.main_window.finishedProgressBar()
             Receiver.send_message(u'cursor_normal')
             for row in row_list:
                 self.listView.takeItem(row)

=== modified file 'openlp/plugins/presentations/presentationplugin.py'
--- openlp/plugins/presentations/presentationplugin.py	2013-01-18 21:36:15 +0000
+++ openlp/plugins/presentations/presentationplugin.py	2013-01-24 06:06:24 +0000
@@ -59,13 +59,13 @@
     """
     log = logging.getLogger(u'PresentationPlugin')
 
-    def __init__(self, plugin_helpers):
+    def __init__(self):
         """
         PluginPresentation constructor.
         """
         log.debug(u'Initialised')
         self.controllers = {}
-        Plugin.__init__(self, u'presentations', __default_settings__, plugin_helpers, __default_settings__)
+        Plugin.__init__(self, u'presentations', __default_settings__, __default_settings__)
         self.weight = -8
         self.iconPath = u':/plugins/plugin_presentations.png'
         self.icon = build_icon(self.iconPath)
@@ -111,7 +111,7 @@
         Create the Media Manager List
         """
         self.mediaItem = PresentationMediaItem(
-            self.mediaDock.media_dock, self, self.icon, self.controllers)
+            self.main_window.mediaDockManager.media_dock, self, self.icon, self.controllers)
 
     def registerControllers(self, controller):
         """

=== modified file 'openlp/plugins/remotes/remoteplugin.py'
--- openlp/plugins/remotes/remoteplugin.py	2013-01-16 11:28:38 +0000
+++ openlp/plugins/remotes/remoteplugin.py	2013-01-24 06:06:24 +0000
@@ -44,11 +44,11 @@
 class RemotesPlugin(Plugin):
     log.info(u'Remote Plugin loaded')
 
-    def __init__(self, plugin_helpers):
+    def __init__(self):
         """
         remotes constructor
         """
-        Plugin.__init__(self, u'remotes', __default_settings__, plugin_helpers, settings_tab_class=RemoteTab)
+        Plugin.__init__(self, u'remotes', __default_settings__, settings_tab_class=RemoteTab)
         self.iconPath = u':/plugins/plugin_remote.png'
         self.icon = build_icon(self.iconPath)
         self.weight = -1

=== modified file 'openlp/plugins/songs/forms/editsongform.py'
--- openlp/plugins/songs/forms/editsongform.py	2013-01-18 21:36:15 +0000
+++ openlp/plugins/songs/forms/editsongform.py	2013-01-24 06:06:24 +0000
@@ -39,8 +39,8 @@
 from PyQt4 import QtCore, QtGui
 
 from openlp.core.lib import PluginStatus, Receiver, MediaType, translate, create_separated_list, \
-    check_directory_exists, UiStrings
-from openlp.core.lib.ui import set_case_insensitive_completer, critical_error_message_box, \
+    check_directory_exists, Registry, UiStrings
+from openlp.core.lib.ui import UiStrings, set_case_insensitive_completer, critical_error_message_box, \
     find_and_set_in_combo_box
 from openlp.core.utils import AppLocation
 from openlp.plugins.songs.forms import EditVerseForm, MediaFilesForm
@@ -88,8 +88,7 @@
             self.onVerseListViewClicked)
         QtCore.QObject.connect(self.verseOrderEdit, QtCore.SIGNAL(u'textChanged(QString)'),
             self.onVerseOrderTextChanged)
-        QtCore.QObject.connect(self.themeAddButton, QtCore.SIGNAL(u'clicked()'),
-            self.mediaitem.plugin.renderer.theme_manager.onAddTheme)
+        QtCore.QObject.connect(self.themeAddButton, QtCore.SIGNAL(u'clicked()'), self.theme_manager.onAddTheme)
         QtCore.QObject.connect(self.maintenanceButton, QtCore.SIGNAL(u'clicked()'), self.onMaintenanceButtonClicked)
         QtCore.QObject.connect(self.audioAddFromFileButton, QtCore.SIGNAL(u'clicked()'),
             self.onAudioAddFromFileButtonClicked)
@@ -909,3 +908,12 @@
         except:
             log.exception(u'Problem processing song Lyrics \n%s', sxml.dump_xml())
 
+    def _get_theme_manager(self):
+        """
+        Adds the theme manager to the class dynamically
+        """
+        if not hasattr(self, u'_theme_manager'):
+            self._theme_manager = Registry().get(u'theme_manager')
+        return self._theme_manager
+
+    theme_manager = property(_get_theme_manager)
\ No newline at end of file

=== modified file 'openlp/plugins/songs/forms/songimportform.py'
--- openlp/plugins/songs/forms/songimportform.py	2013-01-18 20:35:30 +0000
+++ openlp/plugins/songs/forms/songimportform.py	2013-01-24 06:06:24 +0000
@@ -59,7 +59,7 @@
         ``plugin``
             The songs plugin.
         """
-        self.clipboard = plugin.formParent.clipboard
+        self.clipboard = self.main_window.clipboard
         OpenLPWizard.__init__(self, parent, plugin, u'songImportWizard', u':/wizards/wizard_importsong.bmp')
 
     def setupUi(self, image):

=== modified file 'openlp/plugins/songs/lib/mediaitem.py'
--- openlp/plugins/songs/lib/mediaitem.py	2013-01-11 00:19:11 +0000
+++ openlp/plugins/songs/lib/mediaitem.py	2013-01-24 06:06:24 +0000
@@ -71,8 +71,7 @@
     def __init__(self, parent, plugin, icon):
         self.IconPath = u'songs/song'
         MediaManagerItem.__init__(self, parent, plugin, icon)
-        self.editSongForm = EditSongForm(self, self.plugin.formParent,
-            self.plugin.manager)
+        self.editSongForm = EditSongForm(self, self.main_window, self.plugin.manager)
         self.openLyrics = OpenLyrics(self.plugin.manager)
         self.singleServiceItem = False
         self.songMaintenanceForm = SongMaintenanceForm(self.plugin.manager, self)
@@ -373,7 +372,7 @@
                 QtGui.QMessageBox.Yes) == QtGui.QMessageBox.No:
                 return
             Receiver.send_message(u'cursor_busy')
-            self.plugin.formParent.displayProgressBar(len(items))
+            self.main_window.displayProgressBar(len(items))
             for item in items:
                 item_id = item.data(QtCore.Qt.UserRole)
                 media_files = self.plugin.manager.get_all_objects(MediaFile, MediaFile.song_id == item_id)
@@ -389,8 +388,8 @@
                 except OSError:
                     log.exception(u'Could not remove directory: %s', save_path)
                 self.plugin.manager.delete_object(Song, item_id)
-                self.plugin.formParent.incrementProgressBar()
-            self.plugin.formParent.finishedProgressBar()
+                self.main_window.incrementProgressBar()
+            self.main_window.finishedProgressBar()
             Receiver.send_message(u'cursor_normal')
             self.onSearchTextButtonClicked()
 

=== modified file 'openlp/plugins/songs/songsplugin.py'
--- openlp/plugins/songs/songsplugin.py	2013-01-18 21:36:15 +0000
+++ openlp/plugins/songs/songsplugin.py	2013-01-24 06:06:24 +0000
@@ -73,11 +73,11 @@
     """
     log.info(u'Song Plugin loaded')
 
-    def __init__(self, plugin_helpers):
+    def __init__(self):
         """
         Create and set up the Songs plugin.
         """
-        Plugin.__init__(self, u'songs', __default_settings__, plugin_helpers, SongMediaItem, SongsTab)
+        Plugin.__init__(self, u'songs', __default_settings__, SongMediaItem, SongsTab)
         self.manager = Manager(u'songs', init_schema, upgrade_mod=upgrade)
         self.weight = -10
         self.iconPath = u':/plugins/plugin_songs.png'
@@ -157,7 +157,7 @@
         if maxSongs == 0:
             return
         progressDialog = QtGui.QProgressDialog(translate('SongsPlugin', 'Reindexing songs...'), UiStrings().Cancel,
-            0, maxSongs, self.formParent)
+            0, maxSongs, self.main_window)
         progressDialog.setWindowTitle(translate('SongsPlugin', 'Reindexing songs'))
         progressDialog.setWindowModality(QtCore.Qt.WindowModal)
         songs = self.manager.get_all_objects(Song)
@@ -200,8 +200,7 @@
         ``newTheme``
             The new name the plugin should now use.
         """
-        songsUsingTheme = self.manager.get_all_objects(Song,
-            Song.theme_name == oldTheme)
+        songsUsingTheme = self.manager.get_all_objects(Song, Song.theme_name == oldTheme)
         for song in songsUsingTheme:
             song.theme_name = newTheme
             self.manager.save_object(song)
@@ -261,7 +260,7 @@
         if not song_dbs:
             return
         Receiver.send_message(u'openlp_process_events')
-        progress = QtGui.QProgressDialog(self.formParent)
+        progress = QtGui.QProgressDialog(self.main_window)
         progress.setWindowModality(QtCore.Qt.WindowModal)
         progress.setWindowTitle(translate('OpenLP.Ui', 'Importing Songs'))
         progress.setLabelText(translate('OpenLP.Ui', 'Starting import...'))

=== modified file 'openlp/plugins/songusage/songusageplugin.py'
--- openlp/plugins/songusage/songusageplugin.py	2013-01-18 12:25:05 +0000
+++ openlp/plugins/songusage/songusageplugin.py	2013-01-24 06:06:24 +0000
@@ -60,8 +60,8 @@
 class SongUsagePlugin(Plugin):
     log.info(u'SongUsage Plugin loaded')
 
-    def __init__(self, plugin_helpers):
-        Plugin.__init__(self, u'songusage', __default_settings__, plugin_helpers)
+    def __init__(self):
+        Plugin.__init__(self, u'songusage', __default_settings__)
         self.manager = Manager(u'songusage', init_schema, upgrade_mod=upgrade)
         self.weight = -4
         self.icon = build_icon(u':/plugins/plugin_songusage.png')
@@ -107,12 +107,12 @@
         self.songUsageMenu.addSeparator()
         self.songUsageMenu.addAction(self.songUsageReport)
         self.songUsageMenu.addAction(self.songUsageDelete)
-        self.songUsageActiveButton = QtGui.QToolButton(self.formParent.statusBar)
+        self.songUsageActiveButton = QtGui.QToolButton(self.main_window.statusBar)
         self.songUsageActiveButton.setCheckable(True)
         self.songUsageActiveButton.setAutoRaise(True)
         self.songUsageActiveButton.setStatusTip(translate('SongUsagePlugin', 'Toggle the tracking of song usage.'))
         self.songUsageActiveButton.setObjectName(u'songUsageActiveButton')
-        self.formParent.statusBar.insertPermanentWidget(1, self.songUsageActiveButton)
+        self.main_window.statusBar.insertPermanentWidget(1, self.songUsageActiveButton)
         self.songUsageActiveButton.hide()
         # Signals and slots
         QtCore.QObject.connect(self.songUsageStatus, QtCore.SIGNAL(u'visibilityChanged(bool)'),
@@ -134,8 +134,8 @@
         action_list.add_action(self.songUsageStatus, translate('SongUsagePlugin', 'Song Usage'))
         action_list.add_action(self.songUsageDelete, translate('SongUsagePlugin', 'Song Usage'))
         action_list.add_action(self.songUsageReport, translate('SongUsagePlugin', 'Song Usage'))
-        self.songUsageDeleteForm = SongUsageDeleteForm(self.manager, self.formParent)
-        self.songUsageDetailForm = SongUsageDetailForm(self, self.formParent)
+        self.songUsageDeleteForm = SongUsageDeleteForm(self.manager, self.main_window)
+        self.songUsageDetailForm = SongUsageDetailForm(self, self.main_window)
         self.songUsageMenu.menuAction().setVisible(True)
         self.songUsageActiveButton.show()
 

=== added file 'tests/functional/openlp_core_lib/test_registry.py'
--- tests/functional/openlp_core_lib/test_registry.py	1970-01-01 00:00:00 +0000
+++ tests/functional/openlp_core_lib/test_registry.py	2013-01-24 06:06:24 +0000
@@ -0,0 +1,41 @@
+"""
+    Package to test the openlp.core.lib package.
+"""
+import os
+
+from unittest import TestCase
+from mock import MagicMock
+from openlp.core.lib import Registry
+
+TESTPATH = os.path.abspath(os.path.join(os.path.dirname(__file__), u'..', u'..', u'resources'))
+
+class TestServiceItem(TestCase):
+
+    def registry_basic_test(self):
+        """
+        Test the Service Item basic test
+        """
+        # GIVEN: A new registry
+        registry = Registry.create()
+
+        # WHEN: I add a service it should save it
+        mock_1 = MagicMock()
+        Registry().register(u'test1', mock_1)
+
+        # THEN: we should be able retrieve the saved object
+        assert Registry().get(u'test1') == mock_1, u'The saved service can be retrieved and matches'
+
+        # WHEN: I add a service it should save it a second time
+        # THEN  I will get an exception
+        try:
+            Registry().register(u'test1', mock_1)
+        except Exception, e:
+            pass
+
+
+        # WHEN I try to get back a non existent service
+        # THEN I will get an exception
+        try:
+            assert Registry().get(u'test2') == mock_1, u'This should not be fired'
+        except Exception, e:
+            pass
\ No newline at end of file

=== modified file 'tests/functional/openlp_core_lib/test_serviceitem.py'
--- tests/functional/openlp_core_lib/test_serviceitem.py	2013-01-20 20:53:58 +0000
+++ tests/functional/openlp_core_lib/test_serviceitem.py	2013-01-24 06:06:24 +0000
@@ -5,7 +5,7 @@
 
 from unittest import TestCase
 from mock import MagicMock
-from openlp.core.lib import ServiceItem
+from openlp.core.lib import ServiceItem, Registry
 
 VERSE = u'The Lord said to {r}Noah{/r}: \n'\
         'There\'s gonna be a {su}floody{/su}, {sb}floody{/sb}\n'\
@@ -20,6 +20,17 @@
 
 class TestServiceItem(TestCase):
 
+    def setUp(self):
+        """
+        Set up the Registry
+        """
+        registry = Registry.create()
+        mocked_renderer =  MagicMock()
+        mocked_image_manager =  MagicMock()
+        mocked_renderer.format_slide.return_value = [VERSE]
+        Registry().register(u'renderer', mocked_renderer)
+        Registry().register(u'image_manager', mocked_image_manager)
+
     def serviceitem_basic_test(self):
         """
         Test the Service Item basic test
@@ -48,11 +59,6 @@
         assert service_item.is_valid is True, u'The new service item should be valid'
         assert service_item.missing_frames() is False, u'check frames loaded '
 
-        # GIVEN: A service item with text
-        mocked_renderer =  MagicMock()
-        mocked_renderer.format_slide.return_value = [VERSE]
-        service_item.renderer = mocked_renderer
-
         # WHEN: Render called
         assert len(service_item._display_frames) == 0, u'A blank Service Item with no display frames'
         service_item.render(True)
@@ -68,8 +74,6 @@
         # GIVEN: A new service item and a mocked renderer
         service_item = ServiceItem(None)
         service_item.name = u'test'
-        mocked_renderer =  MagicMock()
-        service_item.renderer = mocked_renderer
 
         # WHEN: adding image to a service item
         test_image = os.path.join(TESTPATH, u'church.jpg')
@@ -125,8 +129,6 @@
         # GIVEN: A new service item and a mocked renderer
         service_item = ServiceItem(None)
         service_item.name = u'test'
-        mocked_renderer =  MagicMock()
-        service_item.renderer = mocked_renderer
 
         # WHEN: adding image to a service item
         test_file = os.path.join(TESTPATH, u'church.jpg')


Follow ups