← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~m2j/openlp/cleanups into lp:openlp

 

Meinert Jordan has proposed merging lp:~m2j/openlp/cleanups into lp:openlp.

Requested reviews:
  Raoul Snyman (raoul-snyman)
  Jonathan Corwin (j-corwin)

For more details, see:
https://code.launchpad.net/~m2j/openlp/cleanups/+merge/95868

This are some cleanups. 

There were five methods to create a action in OpenLP, so I thought: Why not add a sixth method. ;)
Well, I was a bit surprised of the freeze as I was just about merging my editior into the OpenLP source tree. Therefore I didn't had the chance yet to go through the sources and replace the current action creation methods where it makes sense.

Some paths are handled through Pythons os.path instead of Qts methods (we use os.path at most places of the code so it is more consistent)
The path seperator in zip files is always a slash (/): http://www.pkware.com/documents/casestudies/APPNOTE.TXT
-- 
https://code.launchpad.net/~m2j/openlp/cleanups/+merge/95868
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/lib/mediamanageritem.py'
--- openlp/core/lib/mediamanageritem.py	2011-12-30 21:40:13 +0000
+++ openlp/core/lib/mediamanageritem.py	2012-03-05 10:15:33 +0000
@@ -36,8 +36,8 @@
 from openlp.core.lib import SettingsManager, OpenLPToolbar, ServiceItem, \
     StringContent, build_icon, translate, Receiver, ListWidgetWithDnD
 from openlp.core.lib.searchedit import SearchEdit
-from openlp.core.lib.ui import UiStrings, context_menu_action, \
-    context_menu_separator, critical_error_message_box
+from openlp.core.lib.ui import UiStrings, create_widget_action, \
+    critical_error_message_box
 
 log = logging.getLogger(__name__)
 
@@ -147,43 +147,6 @@
             self.toolbar = OpenLPToolbar(self)
             self.pageLayout.addWidget(self.toolbar)
 
-    def addToolbarButton(
-        self, title, tooltip, icon, slot=None, checkable=False):
-        """
-        A method to help developers easily add a button to the toolbar.
-
-        ``title``
-            The title of the button.
-
-        ``tooltip``
-            The tooltip to be displayed when the mouse hovers over the
-            button.
-
-        ``icon``
-            The icon of the button. This can be an instance of QIcon, or a
-            string containing either the absolute path to the image, or an
-            internal resource path starting with ':/'.
-
-        ``slot``
-            The method to call when the button is clicked.
-
-        ``checkable``
-            If *True* the button has two, *off* and *on*, states. Default is
-            *False*, which means the buttons has only one state.
-        """
-        # NB different order (when I broke this out, I didn't want to
-        # break compatability), but it makes sense for the icon to
-        # come before the tooltip (as you have to have an icon, but
-        # not neccesarily a tooltip)
-        return self.toolbar.addToolbarButton(title, icon, tooltip, slot,
-            checkable)
-
-    def addToolbarSeparator(self):
-        """
-        A very simple method to add a separator to the toolbar.
-        """
-        self.toolbar.addSeparator()
-
     def setupUi(self):
         """
         This method sets up the interface on the button. Plugin
@@ -208,40 +171,41 @@
         toolbar_actions = []
         ## Import Button ##
         if self.hasImportIcon:
-            toolbar_actions.append([StringContent.Import,
+            toolbar_actions.append([u'Import', StringContent.Import,
             u':/general/general_import.png', self.onImportClick])
         ## Load Button ##
         if self.hasFileIcon:
-            toolbar_actions.append([StringContent.Load,
+            toolbar_actions.append([u'Load', StringContent.Load,
                 u':/general/general_open.png', self.onFileClick])
         ## New Button ##
         if self.hasNewIcon:
-            toolbar_actions.append([StringContent.New,
+            toolbar_actions.append([u'New', StringContent.New,
                 u':/general/general_new.png', self.onNewClick])
         ## Edit Button ##
         if self.hasEditIcon:
-            toolbar_actions.append([StringContent.Edit,
+            toolbar_actions.append([u'Edit', StringContent.Edit,
                 u':/general/general_edit.png', self.onEditClick])
         ## Delete Button ##
         if self.hasDeleteIcon:
-            toolbar_actions.append([StringContent.Delete,
+            toolbar_actions.append([u'Delete', StringContent.Delete,
                 u':/general/general_delete.png', self.onDeleteClick])
         ## Preview ##
-        toolbar_actions.append([StringContent.Preview,
+        toolbar_actions.append([u'Preview', StringContent.Preview,
             u':/general/general_preview.png', self.onPreviewClick])
         ## Live Button ##
-        toolbar_actions.append([StringContent.Live,
+        toolbar_actions.append([u'Live', StringContent.Live,
             u':/general/general_live.png', self.onLiveClick])
         ## Add to service Button ##
-        toolbar_actions.append([StringContent.Service,
+        toolbar_actions.append([u'Service', StringContent.Service,
             u':/general/general_add.png', self.onAddClick])
         for action in toolbar_actions:
             if action[0] == StringContent.Preview:
-                self.addToolbarSeparator()
-            self.addToolbarButton(
-                self.plugin.getString(action[0])[u'title'],
-                self.plugin.getString(action[0])[u'tooltip'],
-                action[1], action[2])
+                self.toolbar.addSeparator()
+            self.toolbar.addToolbarAction(
+                u'%s%sAction' % (self.plugin.name, action[0]),
+                text=self.plugin.getString(action[1])[u'title'], icon=action[2],
+                tooltip=self.plugin.getString(action[1])[u'tooltip'],
+                triggers=action[3])
 
     def addListViewToToolBar(self):
         """
@@ -259,35 +223,37 @@
         # define and add the context menu
         self.listView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
         if self.hasEditIcon:
-            context_menu_action(
-                self.listView, u':/general/general_edit.png',
-                self.plugin.getString(StringContent.Edit)[u'title'],
-                self.onEditClick)
-            context_menu_separator(self.listView)
+            create_widget_action(self.listView,
+                text=self.plugin.getString(StringContent.Edit)[u'title'],
+                icon=u':/general/general_edit.png',
+                triggers=self.onEditClick)
+            create_widget_action(self.listView, separator=True)
         if self.hasDeleteIcon:
-            context_menu_action(
-                self.listView, u':/general/general_delete.png',
-                self.plugin.getString(StringContent.Delete)[u'title'],
-                self.onDeleteClick, [QtCore.Qt.Key_Delete])
-            context_menu_separator(self.listView)
-        context_menu_action(
-            self.listView, u':/general/general_preview.png',
-            self.plugin.getString(StringContent.Preview)[u'title'],
-            self.onPreviewClick, [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return])
-        context_menu_action(
-            self.listView, u':/general/general_live.png',
-            self.plugin.getString(StringContent.Live)[u'title'],
-            self.onLiveClick, [QtCore.Qt.ShiftModifier + QtCore.Qt.Key_Enter,
-            QtCore.Qt.ShiftModifier + QtCore.Qt.Key_Return])
-        context_menu_action(
-            self.listView, u':/general/general_add.png',
-            self.plugin.getString(StringContent.Service)[u'title'],
-            self.onAddClick, [QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal])
+            create_widget_action(self.listView,
+                text=self.plugin.getString(StringContent.Delete)[u'title'],
+                icon=u':/general/general_delete.png',
+                shortcuts=[QtCore.Qt.Key_Delete], triggers=self.onDeleteClick)
+            create_widget_action(self.listView, separator=True)
+        create_widget_action(self.listView,
+            text=self.plugin.getString(StringContent.Preview)[u'title'],
+            icon=u':/general/general_preview.png',
+            shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return],
+            triggers=self.onPreviewClick)
+        create_widget_action(self.listView,
+            text=self.plugin.getString(StringContent.Live)[u'title'],
+            icon=u':/general/general_live.png',
+            shortcuts=[QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter,
+            QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return],
+            triggers=self.onLiveClick)
+        create_widget_action(self.listView,
+            text=self.plugin.getString(StringContent.Service)[u'title'],
+            icon=u':/general/general_add.png',
+            shortcuts=[QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal],
+            triggers=self.onAddClick)
         if self.addToServiceItem:
-            context_menu_action(
-                self.listView, u':/general/general_add.png',
-                translate('OpenLP.MediaManagerItem',
-                '&Add to selected Service Item'), self.onAddEditClick)
+            create_widget_action(self.listView, text=translate(
+                'OpenLP.MediaManagerItem', '&Add to selected Service Item'),
+                icon=u':/general/general_add.png', triggers=self.onAddEditClick)
         self.addCustomContextActions()
         # Create the context menu and add all actions from the listView.
         self.menu = QtGui.QMenu()

=== modified file 'openlp/core/lib/searchedit.py'
--- openlp/core/lib/searchedit.py	2011-12-27 10:33:55 +0000
+++ openlp/core/lib/searchedit.py	2012-03-05 10:15:33 +0000
@@ -30,7 +30,7 @@
 from PyQt4 import QtCore, QtGui
 
 from openlp.core.lib import build_icon
-from openlp.core.lib.ui import icon_action
+from openlp.core.lib.ui import create_widget_action
 
 log = logging.getLogger(__name__)
 
@@ -150,12 +150,8 @@
         menu = QtGui.QMenu(self)
         first = None
         for identifier, icon, title in items:
-            action = icon_action(menu, u'', icon)
-            action.setText(title)
-            action.setData(QtCore.QVariant(identifier))
-            menu.addAction(action)
-            QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'),
-                self._onMenuActionTriggered)
+            action = create_widget_action(menu, text=title, icon=icon,
+                data=identifier, triggers=self._onMenuActionTriggered)
             if first is None:
                 first = action
                 self._currentSearchType = identifier

=== modified file 'openlp/core/lib/spelltextedit.py'
--- openlp/core/lib/spelltextedit.py	2011-12-27 10:33:55 +0000
+++ openlp/core/lib/spelltextedit.py	2012-03-05 10:15:33 +0000
@@ -40,7 +40,7 @@
 from PyQt4 import QtCore, QtGui
 
 from openlp.core.lib import translate, FormattingTags
-from openlp.core.lib.ui import checkable_action
+from openlp.core.lib.ui import create_action
 
 log = logging.getLogger(__name__)
 
@@ -90,9 +90,8 @@
             lang_menu = QtGui.QMenu(
                 translate('OpenLP.SpellTextEdit', 'Language:'))
             for lang in enchant.list_languages():
-                action = checkable_action(
-                    lang_menu, lang, lang == self.dictionary.tag)
-                action.setText(lang)
+                action = create_action(lang_menu, lang, text=lang,
+                    checked=lang == self.dictionary.tag)
                 lang_menu.addAction(action)
             popupMenu.insertSeparator(popupMenu.actions()[0])
             popupMenu.insertMenu(popupMenu.actions()[0], lang_menu)

=== modified file 'openlp/core/lib/toolbar.py'
--- openlp/core/lib/toolbar.py	2011-12-27 10:33:55 +0000
+++ openlp/core/lib/toolbar.py	2012-03-05 10:15:33 +0000
@@ -31,7 +31,7 @@
 
 from PyQt4 import QtCore, QtGui
 
-from openlp.core.lib import build_icon
+from openlp.core.lib.ui import create_widget_action
 
 log = logging.getLogger(__name__)
 
@@ -46,122 +46,41 @@
         """
         QtGui.QToolBar.__init__(self, parent)
         # useful to be able to reuse button icons...
-        self.icons = {}
         self.setIconSize(QtCore.QSize(20, 20))
         self.actions = {}
         log.debug(u'Init done for %s' % parent.__class__.__name__)
 
-    def addToolbarButton(self, title, icon, tooltip=None, slot=None,
-        checkable=False, shortcuts=None, context=QtCore.Qt.WidgetShortcut):
+    def addToolbarAction(self, name, **kwargs):
         """
         A method to help developers easily add a button to the toolbar.
-
-        ``title``
-            The title of the button.
-
-        ``icon``
-            The icon of the button. This can be an instance of QIcon, or a
-            string containing either the absolute path to the image, or an
-            internal resource path starting with ':/'.
-
-        ``tooltip``
-            A hint or tooltip for this button.
-
-        ``slot``
-            The method to run when this button is clicked.
-
-        ``checkable``
-            If *True* the button has two, *off* and *on*, states. Default is
-            *False*, which means the buttons has only one state.
-
-        ``shortcuts``
-            The list of shortcuts for this action
-
-        ``context``
-            Specify the context in which this shortcut is valid
-        """
-        if icon:
-            actionIcon = build_icon(icon)
-            if slot and not checkable:
-                newAction = self.addAction(actionIcon, title, slot)
+        A new QAction is created by calling ``create_action()``. The action is
+        added to the toolbar and the toolbar is set as parent.
+        For more details please look at openlp.core.lib.ui.create_action()
+        """
+        action = create_widget_action(self, name, **kwargs)
+        self.actions[name] = action
+        return action
+
+    def addToolbarWidget(self, widget):
+        """
+        Add a widget and store it's handle under the widgets object name.
+        """
+        action = self.addWidget(widget)
+        self.actions[unicode(widget.objectName())] = action
+
+    def setWidgetVisible(self, widgets, visible=True):
+        """
+        Set the visibitity for a widget or a list of widgets.
+
+        ``widget``
+            A list of string with widget object names.
+
+        ``visible``
+            The new state as bool.
+        """
+        for handle in widgets:
+            if handle in self.actions:
+                self.actions[handle].setVisible(visible)
             else:
-                newAction = self.addAction(actionIcon, title)
-            self.icons[title] = actionIcon
-        else:
-            newAction = QtGui.QAction(title, self)
-            self.addAction(newAction)
-            QtCore.QObject.connect(newAction,
-                QtCore.SIGNAL(u'triggered()'), slot)
-        if tooltip:
-            newAction.setToolTip(tooltip)
-        if checkable:
-            newAction.setCheckable(True)
-            QtCore.QObject.connect(newAction,
-                QtCore.SIGNAL(u'toggled(bool)'), slot)
-        self.actions[title] = newAction
-        if shortcuts is not None:
-            newAction.setShortcuts(shortcuts)
-            newAction.setShortcutContext(context)
-        return newAction
-
-    def addToolbarSeparator(self, handle):
-        """
-        Add a Separator bar to the toolbar and store it's Handle
-        """
-        action = self.addSeparator()
-        self.actions[handle] = action
-
-    def addToolbarWidget(self, handle, widget):
-        """
-        Add a Widget to the toolbar and store it's Handle
-        """
-        action = self.addWidget(widget)
-        self.actions[handle] = action
-
-    def getIconFromTitle(self, title):
-        """
-        Search through the list of icons for an icon with a particular title,
-        and return that icon.
-
-        ``title``
-            The title of the icon to search for.
-        """
-        title = QtCore.QString(title)
-        try:
-            if self.icons[title]:
-                return self.icons[title]
-        except KeyError:
-            log.exception(u'getIconFromTitle - no icon for %s' % title)
-            return QtGui.QIcon()
-
-    def makeWidgetsInvisible(self, widgets):
-        """
-        Hide a set of widgets.
-
-        ``widgets``
-            The list of names of widgets to be hidden.
-        """
-        for widget in widgets:
-            self.actions[widget].setVisible(False)
-
-    def makeWidgetsVisible(self, widgets):
-        """
-        Show a set of widgets.
-
-        ``widgets``
-            The list of names of widgets to be shown.
-        """
-        for widget in widgets:
-            self.actions[widget].setVisible(True)
-
-    def addPushButton(self, image_file=None, text=u''):
-        """
-        Adds a push button to the toolbar.
-
-        Returns the push button
-        """
-        push_button = QtGui.QPushButton(build_icon(image_file), text)
-        push_button.setCheckable(True)
-        push_button.setFlat(True)
-        self.addWidget(push_button)
-        return push_button
+                log.warn(u'No handle "%s" in actions list.', unicode(handle))
+

=== modified file 'openlp/core/lib/ui.py'
--- openlp/core/lib/ui.py	2011-12-27 10:33:55 +0000
+++ openlp/core/lib/ui.py	2012-03-05 10:15:33 +0000
@@ -93,6 +93,7 @@
         self.New = translate('OpenLP.Ui', 'New')
         self.NewService = translate('OpenLP.Ui', 'New Service')
         self.NewTheme = translate('OpenLP.Ui', 'New Theme')
+        self.NextTrack = translate('OpenLP.Ui', 'Next Track')
         self.NFSs = translate('OpenLP.Ui', 'No File Selected', 'Singular')
         self.NFSp = translate('OpenLP.Ui', 'No Files Selected', 'Plural')
         self.NISs = translate('OpenLP.Ui', 'No Item Selected', 'Singular')
@@ -280,100 +281,102 @@
         QtCore.SIGNAL(u'clicked()'), parent.onDownButtonClicked)
     return up_button, down_button
 
-def base_action(parent, name, category=None):
-    """
-    Return the most basic action with the object name set.
-
-    ``category``
-        The category the action should be listed in the shortcut dialog. If you
-        not wish, that this action is added to the shortcut dialog, then do not
-        state any.
-    """
-    action = QtGui.QAction(parent)
-    action.setObjectName(name)
-    if category is not None:
-        action_list = ActionList.get_instance()
-        action_list.add_action(action, category)
-    return action
-
-def checkable_action(parent, name, checked=None, category=None):
-    """
-    Return a standard action with the checkable attribute set.
-    """
-    action = base_action(parent, name, category)
-    action.setCheckable(True)
-    if checked is not None:
-        action.setChecked(checked)
-    return action
-
-def icon_action(parent, name, icon, checked=None, category=None):
-    """
-    Return a standard action with an icon.
-    """
-    if checked is not None:
-        action = checkable_action(parent, name, checked, category)
-    else:
-        action = base_action(parent, name, category)
-    action.setIcon(build_icon(icon))
-    return action
-
-def shortcut_action(parent, name, shortcuts, function, icon=None, checked=None,
-    category=None, context=QtCore.Qt.WindowShortcut):
-    """
-    Return a shortcut enabled action.
-    """
-    action = QtGui.QAction(parent)
-    action.setObjectName(name)
-    if icon is not None:
-        action.setIcon(build_icon(icon))
-    if checked is not None:
-        action.setCheckable(True)
-        action.setChecked(checked)
-    if shortcuts:
-        action.setShortcuts(shortcuts)
-        action.setShortcutContext(context)
-    action_list = ActionList.get_instance()
-    action_list.add_action(action, category)
-    QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'), function)
-    return action
-
-def context_menu_action(base, icon, text, slot, shortcuts=None, category=None,
-    context=QtCore.Qt.WidgetShortcut):
-    """
-    Utility method to help build context menus.
-
-    ``base``
-        The parent menu to add this menu item to
+def create_action(parent, name, **kwargs):
+    """
+    Return an action with the object name set and the given parameters.
+
+    ``parent``
+        A QtCore.QObject for the actions parent (required).
+
+    ``name``
+        A string which is set as object name (required).
+
+    ``text``
+        A string for the action text.
 
     ``icon``
-        An icon for this action
-
-    ``text``
-        The text to display for this action
-
-    ``slot``
-        The code to run when this action is triggered
+        Either a QIcon, a resource string, or a file location string for the
+        action icon.
+
+    ``tooltip``
+        A string for the action tool tip.
+
+    ``statustip``
+        A string for the action status tip.
+
+    ``checked``
+        A bool for the state. If ``None`` the Action is not checkable.
+
+    ``enabled``
+        False in case the action should be disabled.
+
+    ``visible``
+        False in case the action should be hidden.
+
+    ``separator``
+        True in case the action will be considered a separator.
+
+    ``data``
+        Data which is set as QVariant type.
 
     ``shortcuts``
-        The action's shortcuts.
-
-    ``category``
-        The category the shortcut should be listed in the shortcut dialog. If
-        left to ``None``, then the action will be hidden in the shortcut dialog.
+        A QList<QKeySequence> (or a list of strings) which are set as shortcuts.
 
     ``context``
-        The context the shortcut is valid.
+        A context for the shortcut execution.
+
+    ``category``
+        A category the action should be listed in the shortcut dialog.
+
+    ``triggers``
+        A slot which is connected to the actions ``triggered()`` slot.
     """
-    action = QtGui.QAction(text, base)
-    if icon:
-        action.setIcon(build_icon(icon))
-    QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'), slot)
-    if shortcuts is not None:
-        action.setShortcuts(shortcuts)
-        action.setShortcutContext(context)
+    action = QtGui.QAction(parent)
+    action.setObjectName(name)
+    if kwargs.get(u'text'):
+        action.setText(kwargs.pop(u'text'))
+    if kwargs.get(u'icon'):
+        action.setIcon(build_icon(kwargs.pop(u'icon')))
+    if kwargs.get(u'tooltip'):
+        action.setToolTip(kwargs.pop(u'tooltip'))
+    if kwargs.get(u'statustip'):
+        action.setStatusTip(kwargs.pop(u'statustip'))
+    if kwargs.get(u'checked') is not None:
+        action.setCheckable(True)
+        action.setChecked(kwargs.pop(u'checked'))
+    if not kwargs.pop(u'enabled', True):
+        action.setEnabled(False)
+    if not kwargs.pop(u'visible', True):
+        action.setVisible(False)
+    if kwargs.pop(u'separator', False):
+        action.setSeparator(True)
+    if u'data' in kwargs:
+        action.setData(QtCore.QVariant(kwargs.pop(u'data')))
+    if kwargs.get(u'shortcuts'):
+        action.setShortcuts(kwargs.pop(u'shortcuts'))
+    if u'context' in kwargs:
+        action.setShortcutContext(kwargs.pop(u'context'))
+    if kwargs.get(u'category'):
         action_list = ActionList.get_instance()
-        action_list.add_action(action)
-    base.addAction(action)
+        action_list.add_action(action, unicode(kwargs.pop(u'category')))
+    if kwargs.get(u'triggers'):
+        QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'),
+            kwargs.pop(u'triggers'))
+    for key in kwargs.keys():
+        if key not in [u'text', u'icon', u'tooltip', u'statustip', u'checked',
+            u'shortcuts', u'category', u'triggers']:
+            log.warn(u'Parameter %s was not consumed in create_action().', key)
+    return action
+
+def create_widget_action(parent, name=u'', **kwargs):
+    """
+    Return a new QAction by calling ``create_action(parent, name, **kwargs)``.
+    The shortcut context defaults to ``QtCore.Qt.WidgetShortcut`` and the action
+    is added to the parents action list.
+    """
+    kwargs.setdefault(u'context', QtCore.Qt.WidgetShortcut) 
+    action = create_action(parent, name, **kwargs)
+    parent.addAction(action)
     return action
 
 def context_menu(base, icon, text):
@@ -393,18 +396,6 @@
     action.setIcon(build_icon(icon))
     return action
 
-def context_menu_separator(base):
-    """
-    Add a separator to a context menu
-
-    ``base``
-        The menu object to add the separator to
-    """
-    action = QtGui.QAction(u'', base)
-    action.setSeparator(True)
-    base.addAction(action)
-    return action
-
 def add_widget_completer(cache, widget):
     """
     Adds a text autocompleter to a widget.

=== modified file 'openlp/core/resources.py'
--- openlp/core/resources.py	2012-01-29 21:22:20 +0000
+++ openlp/core/resources.py	2012-03-05 10:15:33 +0000
@@ -73947,6 +73947,40 @@
 \x23\xab\xe7\xf3\xa3\xf9\x51\x3d\x6f\x64\xcd\x9a\x10\x42\xfc\x07\
 \x7b\x2d\x6e\x9f\x2f\x2d\x37\x8c\x00\x00\x00\x00\x49\x45\x4e\x44\
 \xae\x42\x60\x82\
+\x00\x00\x01\xfa\
+\x89\
+\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
+\x00\x00\x10\x00\x00\x00\x10\x08\x04\x00\x00\x00\xb5\xfa\x37\xea\
+\x00\x00\x00\x02\x73\x42\x49\x54\x08\x08\x55\xec\x46\x04\x00\x00\
+\x00\x09\x70\x48\x59\x73\x00\x00\x01\xbb\x00\x00\x01\xbb\x01\x3a\
+\xec\xe3\xe2\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\x77\
+\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\
+\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x01\x79\x49\x44\x41\x54\
+\x18\x19\x05\xc1\x41\x4b\x53\x01\x1c\x00\xf0\xff\x3b\xf5\x11\x0a\
+\x3c\x75\x68\x1f\xc1\x4b\x5f\x20\x82\x52\xd7\x36\x19\xc3\x52\x48\
+\x13\x95\xe4\x6d\x62\x4d\x93\xf9\x10\xbb\x55\x74\x0a\x22\xfa\x16\
+\x1b\x65\xd0\x17\x08\x62\x50\x1e\x42\xbc\x78\x79\x19\xd5\x7a\x09\
+\x3b\xac\x8d\x5f\xbf\x5f\x08\x21\xc4\x61\xe9\x20\xcb\xba\x9d\xbc\
+\x93\x67\xdd\x83\xec\xb0\x24\x84\x10\x21\x44\x27\xd9\x4b\xdb\xc3\
+\xa6\x2d\x1d\x1d\x5b\x9a\xda\xc3\xbd\xb4\x93\x08\x11\x62\x27\x69\
+\xf7\x36\x3d\x72\xa4\xef\x9b\x13\x5f\x1d\xd9\xb6\xa9\xdd\xdb\x49\
+\x44\x88\x56\xba\xee\xb9\x2f\xbe\x1b\xf8\xeb\x42\xe1\x87\x53\xcf\
+\xac\x6b\xa5\x22\xd2\xd2\xc6\xb0\xe5\xd8\x7b\xbf\xfc\x33\x31\x31\
+\x36\x52\x38\xb3\x65\x63\x98\x96\x62\x2d\x5b\xf2\xd1\x4f\x6f\xbd\
+\x72\x0c\xd8\x54\x57\xe8\x5b\xb2\xb6\x1f\xcb\xdd\x15\x9f\x15\x5e\
+\xda\xf5\xd0\x1b\x17\x58\x31\x6d\xe4\xdc\xaa\xe5\x6e\x2c\xe6\x2d\
+\x7d\x03\x75\x15\xb7\xd5\x35\xf5\xcd\x9b\x32\x36\xb0\x6b\x31\x8f\
+\x85\xbc\xe9\x58\x61\xda\x65\x97\x5c\x73\xc7\x27\xb7\x84\x89\xc2\
+\x13\x0b\x79\x34\xba\x8b\xfa\x06\xae\xbb\xea\x8a\xa6\x3f\x28\x9b\
+\x32\x36\x70\x5f\xa3\x1b\x8d\xac\xe2\x9d\x73\x37\xdd\xf0\x01\x70\
+\xd7\xb4\x91\x13\x15\x8d\xfd\xa8\x97\xaa\xc3\x07\x4e\xbd\xf0\x1b\
+\x00\x63\x85\x96\xea\xb0\x5e\x0a\x51\x4b\x67\x3d\x75\xa6\x30\x32\
+\x36\x31\x36\x52\x78\x6d\x56\x2d\x15\x21\xe6\x93\x5a\x6f\xc6\xaa\
+\xbe\x73\x03\x85\x81\x13\x4d\x33\x6a\xbd\xf9\x44\x84\x10\xb5\xa4\
+\x92\x96\x87\x33\x16\x6c\x7b\xec\x9e\x19\xe5\x61\x25\xad\x25\x42\
+\x84\x10\x42\x54\x4b\x95\xac\xdc\x9d\xcb\xe7\xf2\x72\xb7\x92\x55\
+\x4b\x42\x08\xf1\x1f\x89\xdc\x66\xb7\x16\x84\x77\xf6\x00\x00\x00\
+\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
 \x00\x00\x02\x0f\
 \x89\
 \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
@@ -82318,6 +82352,11 @@
 \x00\x6d\
 \x00\x65\x00\x64\x00\x69\x00\x61\x00\x5f\x00\x70\x00\x6c\x00\x61\x00\x79\x00\x62\x00\x61\x00\x63\x00\x6b\x00\x5f\x00\x73\x00\x74\
 \x00\x61\x00\x72\x00\x74\x00\x2e\x00\x70\x00\x6e\x00\x67\
+\x00\x17\
+\x02\x02\x37\x87\
+\x00\x6d\
+\x00\x65\x00\x64\x00\x69\x00\x61\x00\x5f\x00\x70\x00\x6c\x00\x61\x00\x79\x00\x62\x00\x61\x00\x63\x00\x6b\x00\x5f\x00\x6e\x00\x65\
+\x00\x78\x00\x74\x00\x2e\x00\x70\x00\x6e\x00\x67\
 \x00\x0e\
 \x09\x02\x2d\x47\
 \x00\x73\
@@ -82559,15 +82598,15 @@
 
 qt_resource_struct = "\
 \x00\x00\x00\x00\x00\x02\x00\x00\x00\x12\x00\x00\x00\x01\
-\x00\x00\x00\xe6\x00\x02\x00\x00\x00\x06\x00\x00\x00\x82\
-\x00\x00\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x7e\
-\x00\x00\x00\xb4\x00\x02\x00\x00\x00\x03\x00\x00\x00\x7b\
-\x00\x00\x00\xd6\x00\x02\x00\x00\x00\x14\x00\x00\x00\x67\
-\x00\x00\x00\x2c\x00\x02\x00\x00\x00\x02\x00\x00\x00\x65\
-\x00\x00\x00\x14\x00\x02\x00\x00\x00\x02\x00\x00\x00\x63\
-\x00\x00\x00\xf4\x00\x02\x00\x00\x00\x05\x00\x00\x00\x5e\
-\x00\x00\x01\x2e\x00\x02\x00\x00\x00\x09\x00\x00\x00\x55\
-\x00\x00\x00\x8c\x00\x02\x00\x00\x00\x09\x00\x00\x00\x4c\
+\x00\x00\x00\xe6\x00\x02\x00\x00\x00\x06\x00\x00\x00\x83\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x7f\
+\x00\x00\x00\xb4\x00\x02\x00\x00\x00\x03\x00\x00\x00\x7c\
+\x00\x00\x00\xd6\x00\x02\x00\x00\x00\x14\x00\x00\x00\x68\
+\x00\x00\x00\x2c\x00\x02\x00\x00\x00\x02\x00\x00\x00\x66\
+\x00\x00\x00\x14\x00\x02\x00\x00\x00\x02\x00\x00\x00\x64\
+\x00\x00\x00\xf4\x00\x02\x00\x00\x00\x05\x00\x00\x00\x5f\
+\x00\x00\x01\x2e\x00\x02\x00\x00\x00\x09\x00\x00\x00\x56\
+\x00\x00\x00\x8c\x00\x02\x00\x00\x00\x0a\x00\x00\x00\x4c\
 \x00\x00\x00\xc4\x00\x02\x00\x00\x00\x03\x00\x00\x00\x49\
 \x00\x00\x00\x3c\x00\x02\x00\x00\x00\x10\x00\x00\x00\x39\
 \x00\x00\x00\x62\x00\x02\x00\x00\x00\x03\x00\x00\x00\x36\
@@ -82582,23 +82621,23 @@
 \x00\x00\x03\xec\x00\x00\x00\x00\x00\x01\x00\x05\x65\x6d\
 \x00\x00\x04\x1a\x00\x00\x00\x00\x00\x01\x00\x08\x06\x4f\
 \x00\x00\x03\xbc\x00\x00\x00\x00\x00\x01\x00\x02\xc4\x8b\
-\x00\x00\x0e\xf8\x00\x00\x00\x00\x00\x01\x00\x13\x7d\x14\
-\x00\x00\x0f\x68\x00\x00\x00\x00\x00\x01\x00\x13\x84\x5f\
-\x00\x00\x0e\xa8\x00\x00\x00\x00\x00\x01\x00\x13\x77\xb8\
-\x00\x00\x10\x46\x00\x00\x00\x00\x00\x01\x00\x13\x96\xdd\
-\x00\x00\x0f\xc8\x00\x00\x00\x00\x00\x01\x00\x13\x8c\x75\
-\x00\x00\x0e\x50\x00\x00\x00\x00\x00\x01\x00\x13\x70\x81\
-\x00\x00\x10\x98\x00\x00\x00\x00\x00\x01\x00\x13\x9c\xe4\
-\x00\x00\x0f\x90\x00\x00\x00\x00\x00\x01\x00\x13\x87\xd3\
-\x00\x00\x10\xe6\x00\x00\x00\x00\x00\x01\x00\x13\xa2\x10\
-\x00\x00\x0e\x7a\x00\x00\x00\x00\x00\x01\x00\x13\x73\x1f\
-\x00\x00\x10\x72\x00\x00\x00\x00\x00\x01\x00\x13\x9a\x10\
-\x00\x00\x10\x1c\x00\x00\x00\x00\x00\x01\x00\x13\x94\x65\
-\x00\x00\x0e\xce\x00\x00\x00\x00\x00\x01\x00\x13\x7a\x92\
-\x00\x00\x10\xc2\x00\x00\x00\x00\x00\x01\x00\x13\x9f\xc9\
-\x00\x00\x0f\xf0\x00\x00\x00\x00\x00\x01\x00\x13\x8f\xba\
-\x00\x00\x0f\x44\x00\x00\x00\x00\x00\x01\x00\x13\x81\x62\
-\x00\x00\x0f\x1e\x00\x00\x00\x00\x00\x01\x00\x13\x7f\x4b\
+\x00\x00\x0f\x2c\x00\x00\x00\x00\x00\x01\x00\x13\x7f\x12\
+\x00\x00\x0f\x9c\x00\x00\x00\x00\x00\x01\x00\x13\x86\x5d\
+\x00\x00\x0e\xdc\x00\x00\x00\x00\x00\x01\x00\x13\x79\xb6\
+\x00\x00\x10\x7a\x00\x00\x00\x00\x00\x01\x00\x13\x98\xdb\
+\x00\x00\x0f\xfc\x00\x00\x00\x00\x00\x01\x00\x13\x8e\x73\
+\x00\x00\x0e\x84\x00\x00\x00\x00\x00\x01\x00\x13\x72\x7f\
+\x00\x00\x10\xcc\x00\x00\x00\x00\x00\x01\x00\x13\x9e\xe2\
+\x00\x00\x0f\xc4\x00\x00\x00\x00\x00\x01\x00\x13\x89\xd1\
+\x00\x00\x11\x1a\x00\x00\x00\x00\x00\x01\x00\x13\xa4\x0e\
+\x00\x00\x0e\xae\x00\x00\x00\x00\x00\x01\x00\x13\x75\x1d\
+\x00\x00\x10\xa6\x00\x00\x00\x00\x00\x01\x00\x13\x9c\x0e\
+\x00\x00\x10\x50\x00\x00\x00\x00\x00\x01\x00\x13\x96\x63\
+\x00\x00\x0f\x02\x00\x00\x00\x00\x00\x01\x00\x13\x7c\x90\
+\x00\x00\x10\xf6\x00\x00\x00\x00\x00\x01\x00\x13\xa1\xc7\
+\x00\x00\x10\x24\x00\x00\x00\x00\x00\x01\x00\x13\x91\xb8\
+\x00\x00\x0f\x78\x00\x00\x00\x00\x00\x01\x00\x13\x83\x60\
+\x00\x00\x0f\x52\x00\x00\x00\x00\x00\x01\x00\x13\x81\x49\
 \x00\x00\x03\x66\x00\x00\x00\x00\x00\x01\x00\x00\x21\x92\
 \x00\x00\x0b\x44\x00\x00\x00\x00\x00\x01\x00\x11\xef\x19\
 \x00\x00\x0b\xc4\x00\x00\x00\x00\x00\x01\x00\x11\xf5\xdf\
@@ -82611,37 +82650,38 @@
 \x00\x00\x01\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
 \x00\x00\x01\xc2\x00\x00\x00\x00\x00\x01\x00\x00\x05\xe6\
 \x00\x00\x01\x8e\x00\x00\x00\x00\x00\x01\x00\x00\x02\xfe\
-\x00\x00\x0d\xa0\x00\x00\x00\x00\x00\x01\x00\x12\x11\xfa\
-\x00\x00\x0d\xca\x00\x00\x00\x00\x00\x01\x00\x12\x1b\x86\
-\x00\x00\x0d\xfa\x00\x00\x00\x00\x00\x01\x00\x12\x8a\xcb\
-\x00\x00\x0e\x1a\x00\x00\x00\x00\x00\x01\x00\x12\x91\x7c\
-\x00\x00\x11\x68\x00\x00\x00\x00\x00\x01\x00\x13\xa9\x24\
-\x00\x00\x11\x0e\x00\x00\x00\x00\x00\x01\x00\x13\xa4\x23\
-\x00\x00\x13\x86\x00\x00\x00\x00\x00\x01\x00\x13\xce\x33\
-\x00\x00\x11\xda\x00\x00\x00\x00\x00\x01\x00\x13\xaf\xb1\
-\x00\x00\x11\x34\x00\x00\x00\x00\x00\x01\x00\x13\xa7\x54\
-\x00\x00\x12\xd8\x00\x00\x00\x00\x00\x01\x00\x13\xbf\x0e\
-\x00\x00\x12\x76\x00\x00\x00\x00\x00\x01\x00\x13\xb6\xde\
-\x00\x00\x13\xac\x00\x00\x00\x00\x00\x01\x00\x13\xd1\x15\
-\x00\x00\x13\x52\x00\x00\x00\x00\x00\x01\x00\x13\xca\x56\
-\x00\x00\x12\xa2\x00\x00\x00\x00\x00\x01\x00\x13\xbb\xea\
-\x00\x00\x13\xde\x00\x00\x00\x00\x00\x01\x00\x13\xd4\xd2\
-\x00\x00\x11\xaa\x00\x00\x00\x00\x00\x01\x00\x13\xac\x77\
-\x00\x00\x12\xfa\x00\x00\x00\x00\x00\x01\x00\x13\xc3\x7d\
-\x00\x00\x12\x3e\x00\x00\x00\x00\x00\x01\x00\x13\xb4\x68\
-\x00\x00\x13\x28\x00\x00\x00\x00\x00\x01\x00\x13\xc7\xce\
-\x00\x00\x12\x08\x00\x00\x00\x00\x00\x01\x00\x13\xb1\xb8\
+\x00\x00\x0d\xd4\x00\x00\x00\x00\x00\x01\x00\x12\x13\xf8\
+\x00\x00\x0d\xfe\x00\x00\x00\x00\x00\x01\x00\x12\x1d\x84\
+\x00\x00\x0e\x2e\x00\x00\x00\x00\x00\x01\x00\x12\x8c\xc9\
+\x00\x00\x0e\x4e\x00\x00\x00\x00\x00\x01\x00\x12\x93\x7a\
+\x00\x00\x11\x9c\x00\x00\x00\x00\x00\x01\x00\x13\xab\x22\
+\x00\x00\x11\x42\x00\x00\x00\x00\x00\x01\x00\x13\xa6\x21\
+\x00\x00\x13\xba\x00\x00\x00\x00\x00\x01\x00\x13\xd0\x31\
+\x00\x00\x12\x0e\x00\x00\x00\x00\x00\x01\x00\x13\xb1\xaf\
+\x00\x00\x11\x68\x00\x00\x00\x00\x00\x01\x00\x13\xa9\x52\
+\x00\x00\x13\x0c\x00\x00\x00\x00\x00\x01\x00\x13\xc1\x0c\
+\x00\x00\x12\xaa\x00\x00\x00\x00\x00\x01\x00\x13\xb8\xdc\
+\x00\x00\x13\xe0\x00\x00\x00\x00\x00\x01\x00\x13\xd3\x13\
+\x00\x00\x13\x86\x00\x00\x00\x00\x00\x01\x00\x13\xcc\x54\
+\x00\x00\x12\xd6\x00\x00\x00\x00\x00\x01\x00\x13\xbd\xe8\
+\x00\x00\x14\x12\x00\x00\x00\x00\x00\x01\x00\x13\xd6\xd0\
+\x00\x00\x11\xde\x00\x00\x00\x00\x00\x01\x00\x13\xae\x75\
+\x00\x00\x13\x2e\x00\x00\x00\x00\x00\x01\x00\x13\xc5\x7b\
+\x00\x00\x12\x72\x00\x00\x00\x00\x00\x01\x00\x13\xb6\x66\
+\x00\x00\x13\x5c\x00\x00\x00\x00\x00\x01\x00\x13\xc9\xcc\
+\x00\x00\x12\x3c\x00\x00\x00\x00\x00\x01\x00\x13\xb3\xb6\
 \x00\x00\x0a\x10\x00\x00\x00\x00\x00\x01\x00\x0e\xec\xf7\
 \x00\x00\x0a\x30\x00\x00\x00\x00\x00\x01\x00\x0e\xf0\xd4\
 \x00\x00\x09\xea\x00\x00\x00\x00\x00\x01\x00\x0e\xea\x59\
-\x00\x00\x0d\x1c\x00\x00\x00\x00\x00\x01\x00\x12\x0b\x3d\
-\x00\x00\x0d\x76\x00\x00\x00\x00\x00\x01\x00\x12\x0f\xf6\
+\x00\x00\x0c\xb2\x00\x00\x00\x00\x00\x01\x00\x12\x02\xc6\
+\x00\x00\x0d\x50\x00\x00\x00\x00\x00\x01\x00\x12\x0d\x3b\
+\x00\x00\x0d\xaa\x00\x00\x00\x00\x00\x01\x00\x12\x11\xf4\
 \x00\x00\x0c\x48\x00\x00\x00\x00\x00\x01\x00\x11\xfe\xd6\
-\x00\x00\x0c\xf8\x00\x00\x00\x00\x00\x01\x00\x12\x08\x0a\
+\x00\x00\x0d\x2c\x00\x00\x00\x00\x00\x01\x00\x12\x0a\x08\
 \x00\x00\x0c\x7c\x00\x00\x00\x00\x00\x01\x00\x12\x00\xcd\
-\x00\x00\x0c\xb2\x00\x00\x00\x00\x00\x01\x00\x12\x02\xc6\
-\x00\x00\x0c\xd4\x00\x00\x00\x00\x00\x01\x00\x12\x04\xd9\
-\x00\x00\x0d\x52\x00\x00\x00\x00\x00\x01\x00\x12\x0d\x25\
+\x00\x00\x0c\xe6\x00\x00\x00\x00\x00\x01\x00\x12\x04\xc4\
+\x00\x00\x0d\x08\x00\x00\x00\x00\x00\x01\x00\x12\x06\xd7\
+\x00\x00\x0d\x86\x00\x00\x00\x00\x00\x01\x00\x12\x0f\x23\
 \x00\x00\x0c\x20\x00\x00\x00\x00\x00\x01\x00\x11\xfc\x1a\
 \x00\x00\x02\xee\x00\x00\x00\x00\x00\x01\x00\x00\x1b\x20\
 \x00\x00\x02\x72\x00\x00\x00\x00\x00\x01\x00\x00\x11\xc5\
@@ -82657,10 +82697,10 @@
 \x00\x00\x04\xb8\x00\x00\x00\x00\x00\x01\x00\x0d\x50\x06\
 \x00\x00\x05\x52\x00\x00\x00\x00\x00\x01\x00\x0d\x56\x1f\
 \x00\x00\x05\x20\x00\x00\x00\x00\x00\x01\x00\x0d\x54\x57\
-\x00\x00\x14\x46\x00\x00\x00\x00\x00\x01\x00\x13\xde\x06\
-\x00\x00\x14\x7a\x00\x00\x00\x00\x00\x01\x00\x13\xe0\xd6\
-\x00\x00\x14\x02\x00\x00\x00\x00\x00\x01\x00\x13\xd8\x85\
-\x00\x00\x14\x26\x00\x00\x00\x00\x00\x01\x00\x13\xdb\x83\
+\x00\x00\x14\x7a\x00\x00\x00\x00\x00\x01\x00\x13\xe0\x04\
+\x00\x00\x14\xae\x00\x00\x00\x00\x00\x01\x00\x13\xe2\xd4\
+\x00\x00\x14\x36\x00\x00\x00\x00\x00\x01\x00\x13\xda\x83\
+\x00\x00\x14\x5a\x00\x00\x00\x00\x00\x01\x00\x13\xdd\x81\
 \x00\x00\x06\xde\x00\x00\x00\x00\x00\x01\x00\x0e\xaa\x8e\
 \x00\x00\x07\xc4\x00\x00\x00\x00\x00\x01\x00\x0e\xbb\x82\
 \x00\x00\x09\xca\x00\x00\x00\x00\x00\x01\x00\x0e\xe6\x66\
@@ -82684,10 +82724,10 @@
 \x00\x00\x0a\x74\x00\x00\x00\x00\x00\x01\x00\x0e\xf7\xe1\
 \x00\x00\x0a\x52\x00\x00\x00\x00\x00\x01\x00\x0e\xf4\x0e\
 \x00\x00\x0a\xa6\x00\x00\x00\x00\x00\x01\x00\x11\xe5\x3f\
-\x00\x00\x14\xaa\x00\x00\x00\x00\x00\x01\x00\x13\xe3\xcf\
-\x00\x00\x15\x0c\x00\x00\x00\x00\x00\x01\x00\x13\xea\x45\
-\x00\x00\x14\xde\x00\x00\x00\x00\x00\x01\x00\x13\xe7\x31\
-\x00\x00\x15\x34\x00\x00\x00\x00\x00\x01\x00\x13\xec\xe3\
+\x00\x00\x14\xde\x00\x00\x00\x00\x00\x01\x00\x13\xe5\xcd\
+\x00\x00\x15\x40\x00\x00\x00\x00\x00\x01\x00\x13\xec\x43\
+\x00\x00\x15\x12\x00\x00\x00\x00\x00\x01\x00\x13\xe9\x2f\
+\x00\x00\x15\x68\x00\x00\x00\x00\x00\x01\x00\x13\xee\xe1\
 \x00\x00\x06\x18\x00\x00\x00\x00\x00\x01\x00\x0d\x91\xaf\
 \x00\x00\x05\xb8\x00\x00\x00\x00\x00\x01\x00\x0d\x62\x6f\
 \x00\x00\x05\x88\x00\x00\x00\x00\x00\x01\x00\x0d\x57\xdb\

=== modified file 'openlp/core/ui/exceptionform.py'
--- openlp/core/ui/exceptionform.py	2012-01-18 13:50:06 +0000
+++ openlp/core/ui/exceptionform.py	2012-03-05 10:15:33 +0000
@@ -150,7 +150,7 @@
             translate('OpenLP.ExceptionForm',
             'Text files (*.txt *.log *.text)'))
         if filename:
-            filename = unicode(QtCore.QDir.toNativeSeparators(filename))
+            filename = unicode(filename).replace(u'/', os.path.sep)
             SettingsManager.set_last_dir(self.settingsSection, os.path.dirname(
                 filename))
             report_text = report_text % self._createReport()

=== modified file 'openlp/core/ui/firsttimelanguageform.py'
--- openlp/core/ui/firsttimelanguageform.py	2011-12-27 10:33:55 +0000
+++ openlp/core/ui/firsttimelanguageform.py	2012-03-05 10:15:33 +0000
@@ -27,6 +27,7 @@
 
 from PyQt4 import QtGui
 
+from openlp.core.lib.ui import create_action
 from openlp.core.utils import LanguageManager
 from firsttimelanguagedialog import Ui_FirstTimeLanguageDialog
 
@@ -55,8 +56,7 @@
             LanguageManager.set_language(False, False)
         else:
             LanguageManager.auto_language = False
-            action = QtGui.QAction(None)
-            action.setObjectName(unicode(self.languageComboBox.currentText()))
+            action = create_action(None, self.languageComboBox.currentText())
             LanguageManager.set_language(action, False)
         return QtGui.QDialog.accept(self)
 

=== modified file 'openlp/core/ui/generaltab.py'
--- openlp/core/ui/generaltab.py	2012-02-06 13:28:16 +0000
+++ openlp/core/ui/generaltab.py	2012-03-05 10:15:33 +0000
@@ -175,6 +175,9 @@
         self.startPausedCheckBox = QtGui.QCheckBox(self.audioGroupBox)
         self.startPausedCheckBox.setObjectName(u'startPausedCheckBox')
         self.audioLayout.addWidget(self.startPausedCheckBox)
+        self.repeatListCheckBox = QtGui.QCheckBox(self.audioGroupBox)
+        self.repeatListCheckBox.setObjectName(u'repeatListCheckBox')
+        self.audioLayout.addWidget(self.repeatListCheckBox)
         self.rightLayout.addWidget(self.audioGroupBox)
         self.rightLayout.addStretch()
         # Signals and slots
@@ -251,6 +254,8 @@
             translate('OpenLP.GeneralTab', 'Background Audio'))
         self.startPausedCheckBox.setText(
             translate('OpenLP.GeneralTab', 'Start background audio paused'))
+        self.repeatListCheckBox.setText(
+            translate('OpenLP.GeneralTab', 'Repeat track list'))
 
     def load(self):
         """
@@ -298,6 +303,8 @@
             QtCore.QVariant(self.screens.current[u'size'].width())).toInt()[0])
         self.startPausedCheckBox.setChecked(settings.value(
             u'audio start paused', QtCore.QVariant(True)).toBool())
+        self.repeatListCheckBox.setChecked(settings.value(
+            u'audio repeat list', QtCore.QVariant(False)).toBool())
         settings.endGroup()
         self.customXValueEdit.setEnabled(self.overrideCheckBox.isChecked())
         self.customYValueEdit.setEnabled(self.overrideCheckBox.isChecked())
@@ -350,7 +357,9 @@
             QtCore.QVariant(self.overrideCheckBox.isChecked()))
         settings.setValue(u'audio start paused',
             QtCore.QVariant(self.startPausedCheckBox.isChecked()))
-        settings.endGroup()        
+        settings.setValue(u'audio repeat list',
+            QtCore.QVariant(self.repeatListCheckBox.isChecked()))
+        settings.endGroup()
         # On save update the screens as well
         self.postSetUp(True)
 

=== modified file 'openlp/core/ui/maindisplay.py'
--- openlp/core/ui/maindisplay.py	2012-01-19 19:13:19 +0000
+++ openlp/core/ui/maindisplay.py	2012-03-05 10:15:33 +0000
@@ -30,7 +30,6 @@
 """
 import cgi
 import logging
-import os
 import sys
 
 from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL
@@ -136,12 +135,12 @@
                 QtCore.Qt.WindowStaysOnTopHint
         if QtCore.QSettings().value(u'advanced/x11 bypass wm',
             QtCore.QVariant(True)).toBool():
-            windowFlags = windowFlags | QtCore.Qt.X11BypassWindowManagerHint
+            windowFlags |= QtCore.Qt.X11BypassWindowManagerHint
         # FIXME: QtCore.Qt.SplashScreen is workaround to make display screen
         # stay always on top on Mac OS X. For details see bug 906926.
         # It needs more investigation to fix it properly.
         if sys.platform == 'darwin':
-            windowFlags = windowFlags | QtCore.Qt.SplashScreen
+            windowFlags |= QtCore.Qt.SplashScreen
         self.setWindowFlags(windowFlags)
         self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
         self.setTransparency(True)
@@ -493,11 +492,15 @@
         QtCore.QObject.__init__(self, parent)
         self.currentIndex = -1
         self.playlist = []
+        self.repeat = False
         self.mediaObject = Phonon.MediaObject()
+        self.mediaObject.setTickInterval(100)
         self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory)
         Phonon.createPath(self.mediaObject, self.audioObject)
         QtCore.QObject.connect(self.mediaObject,
             QtCore.SIGNAL(u'aboutToFinish()'), self.onAboutToFinish)
+        QtCore.QObject.connect(self.mediaObject,
+            QtCore.SIGNAL(u'finished()'), self.onFinished)
 
     def __del__(self):
         """
@@ -516,6 +519,14 @@
         if len(self.playlist) > self.currentIndex:
             self.mediaObject.enqueue(self.playlist[self.currentIndex])
 
+    def onFinished(self):
+        if self.repeat:
+            log.debug(u'Repeat is enabled... here we go again!')
+            self.mediaObject.clearQueue()
+            self.mediaObject.clear()
+            self.currentIndex = -1
+            self.play()
+
     def connectVolumeSlider(self, slider):
         slider.setAudioOutput(self.audioObject)
 
@@ -563,3 +574,27 @@
         for filename in filenames:
             self.playlist.append(Phonon.MediaSource(filename))
 
+    def next(self):
+        if not self.repeat and self.currentIndex + 1 == len(self.playlist):
+            return
+        isPlaying = self.mediaObject.state() == Phonon.PlayingState
+        self.currentIndex += 1
+        if self.repeat and self.currentIndex == len(self.playlist):
+            self.currentIndex = 0
+        self.mediaObject.clearQueue()
+        self.mediaObject.clear()
+        self.mediaObject.enqueue(self.playlist[self.currentIndex])
+        if isPlaying:
+            self.mediaObject.play()
+
+    def goTo(self, index):
+        isPlaying = self.mediaObject.state() == Phonon.PlayingState
+        self.mediaObject.clearQueue()
+        self.mediaObject.clear()
+        self.currentIndex = index
+        self.mediaObject.enqueue(self.playlist[self.currentIndex])
+        if isPlaying:
+            self.mediaObject.play()
+
+    def connectSlot(self, signal, slot):
+        QtCore.QObject.connect(self.mediaObject, signal, slot)

=== modified file 'openlp/core/ui/mainwindow.py'
--- openlp/core/ui/mainwindow.py	2012-02-06 17:35:41 +0000
+++ openlp/core/ui/mainwindow.py	2012-03-05 10:15:33 +0000
@@ -36,8 +36,7 @@
 
 from openlp.core.lib import Renderer, build_icon, OpenLPDockWidget, \
     PluginManager, Receiver, translate, ImageManager, PluginStatus
-from openlp.core.lib.ui import UiStrings, base_action, checkable_action, \
-    icon_action, shortcut_action
+from openlp.core.lib.ui import UiStrings, create_action
 from openlp.core.lib import SlideLimits
 from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \
     ThemeManager, SlideController, PluginForm, MediaDockManager, \
@@ -179,75 +178,78 @@
         action_list = ActionList.get_instance()
         action_list.add_category(unicode(UiStrings().File),
             CategoryOrder.standardMenu)
-        self.fileNewItem = shortcut_action(mainWindow, u'fileNewItem',
-            [QtGui.QKeySequence(u'Ctrl+N')],
-            self.serviceManagerContents.onNewServiceClicked,
-            u':/general/general_new.png', category=unicode(UiStrings().File))
-        self.fileOpenItem = shortcut_action(mainWindow, u'fileOpenItem',
-            [QtGui.QKeySequence(u'Ctrl+O')],
-            self.serviceManagerContents.onLoadServiceClicked,
-            u':/general/general_open.png', category=unicode(UiStrings().File))
-        self.fileSaveItem = shortcut_action(mainWindow, u'fileSaveItem',
-            [QtGui.QKeySequence(u'Ctrl+S')],
-            self.serviceManagerContents.saveFile,
-            u':/general/general_save.png', category=unicode(UiStrings().File))
-        self.fileSaveAsItem = shortcut_action(mainWindow, u'fileSaveAsItem',
-            [QtGui.QKeySequence(u'Ctrl+Shift+S')],
-            self.serviceManagerContents.saveFileAs,
-            category=unicode(UiStrings().File))
-        self.printServiceOrderItem = shortcut_action(mainWindow,
-            u'printServiceItem', [QtGui.QKeySequence(u'Ctrl+P')],
-            self.serviceManagerContents.printServiceOrder,
-            category=unicode(UiStrings().File))
-        self.fileExitItem = shortcut_action(mainWindow, u'fileExitItem',
-            [QtGui.QKeySequence(u'Alt+F4')], mainWindow.close,
-            u':/system/system_exit.png', category=unicode(UiStrings().File))
+        self.fileNewItem = create_action(mainWindow, u'fileNewItem',
+            icon=u':/general/general_new.png',
+            shortcuts=[QtGui.QKeySequence(u'Ctrl+N')],
+            category=UiStrings().File,
+            triggers=self.serviceManagerContents.onNewServiceClicked)
+        self.fileOpenItem = create_action(mainWindow, u'fileOpenItem',
+            icon=u':/general/general_open.png',
+            shortcuts=[QtGui.QKeySequence(u'Ctrl+O')],
+            category=UiStrings().File,
+            triggers=self.serviceManagerContents.onLoadServiceClicked)
+        self.fileSaveItem = create_action(mainWindow, u'fileSaveItem',
+            icon=u':/general/general_save.png',
+            shortcuts=[QtGui.QKeySequence(u'Ctrl+S')],
+            category=UiStrings().File,
+            triggers=self.serviceManagerContents.saveFile)
+        self.fileSaveAsItem = create_action(mainWindow, u'fileSaveAsItem',
+            shortcuts=[QtGui.QKeySequence(u'Ctrl+Shift+S')],
+            category=UiStrings().File,
+            triggers=self.serviceManagerContents.saveFileAs)
+        self.printServiceOrderItem = create_action(mainWindow,
+            u'printServiceItem', shortcuts=[QtGui.QKeySequence(u'Ctrl+P')],
+            category=UiStrings().File,
+            triggers=self.serviceManagerContents.printServiceOrder)
+        self.fileExitItem = create_action(mainWindow, u'fileExitItem',
+            icon=u':/system/system_exit.png',
+            shortcuts=[QtGui.QKeySequence(u'Alt+F4')],
+            category=UiStrings().File, triggers=mainWindow.close)
         action_list.add_category(unicode(UiStrings().Import),
             CategoryOrder.standardMenu)
-        self.importThemeItem = base_action(
-            mainWindow, u'importThemeItem', unicode(UiStrings().Import))
-        self.importLanguageItem = base_action(
-            mainWindow, u'importLanguageItem')#, unicode(UiStrings().Import))
+        self.importThemeItem = create_action(mainWindow,
+            u'importThemeItem', category=UiStrings().Import)
+        self.importLanguageItem = create_action(mainWindow,
+            u'importLanguageItem')#, category=UiStrings().Import)
         action_list.add_category(unicode(UiStrings().Export),
             CategoryOrder.standardMenu)
-        self.exportThemeItem = base_action(
-            mainWindow, u'exportThemeItem', unicode(UiStrings().Export))
-        self.exportLanguageItem = base_action(
-            mainWindow, u'exportLanguageItem')#, unicode(UiStrings().Export))
+        self.exportThemeItem = create_action(mainWindow,
+            u'exportThemeItem', category=UiStrings().Export)
+        self.exportLanguageItem = create_action(mainWindow,
+            u'exportLanguageItem')#, category=UiStrings().Export)
         action_list.add_category(unicode(UiStrings().View),
             CategoryOrder.standardMenu)
-        self.viewMediaManagerItem = shortcut_action(mainWindow,
-            u'viewMediaManagerItem', [QtGui.QKeySequence(u'F8')],
-            self.toggleMediaManager, u':/system/system_mediamanager.png',
-            self.mediaManagerDock.isVisible(), unicode(UiStrings().View))
-        self.viewThemeManagerItem = shortcut_action(mainWindow,
-            u'viewThemeManagerItem', [QtGui.QKeySequence(u'F10')],
-            self.toggleThemeManager, u':/system/system_thememanager.png',
-            self.themeManagerDock.isVisible(), unicode(UiStrings().View))
-        self.viewServiceManagerItem = shortcut_action(mainWindow,
-            u'viewServiceManagerItem', [QtGui.QKeySequence(u'F9')],
-            self.toggleServiceManager, u':/system/system_servicemanager.png',
-            self.serviceManagerDock.isVisible(), unicode(UiStrings().View))
-        self.viewPreviewPanel = shortcut_action(mainWindow,
-            u'viewPreviewPanel', [QtGui.QKeySequence(u'F11')],
-            self.setPreviewPanelVisibility, checked=previewVisible,
-            category=unicode(UiStrings().View))
-        self.viewLivePanel = shortcut_action(mainWindow, u'viewLivePanel',
-            [QtGui.QKeySequence(u'F12')], self.setLivePanelVisibility,
-            checked=liveVisible, category=unicode(UiStrings().View))
-        self.lockPanel = shortcut_action(mainWindow, u'lockPanel',
-            None, self.setLockPanel,
-            checked=panelLocked, category=None)
+        self.viewMediaManagerItem = create_action(mainWindow,
+            u'viewMediaManagerItem', shortcuts=[QtGui.QKeySequence(u'F8')],
+            icon=u':/system/system_mediamanager.png',
+            checked=self.mediaManagerDock.isVisible(),
+            category=UiStrings().View, triggers=self.toggleMediaManager)
+        self.viewThemeManagerItem = create_action(mainWindow,
+            u'viewThemeManagerItem', shortcuts=[QtGui.QKeySequence(u'F10')],
+            icon=u':/system/system_thememanager.png',
+            checked=self.themeManagerDock.isVisible(),
+            category=UiStrings().View, triggers=self.toggleThemeManager)
+        self.viewServiceManagerItem = create_action(mainWindow,
+            u'viewServiceManagerItem', shortcuts=[QtGui.QKeySequence(u'F9')],
+            icon=u':/system/system_servicemanager.png',
+            checked=self.serviceManagerDock.isVisible(),
+            category=UiStrings().View, triggers=self.toggleServiceManager)
+        self.viewPreviewPanel = create_action(mainWindow, u'viewPreviewPanel',
+            shortcuts=[QtGui.QKeySequence(u'F11')], checked=previewVisible,
+            category=UiStrings().View, triggers=self.setPreviewPanelVisibility)
+        self.viewLivePanel = create_action(mainWindow, u'viewLivePanel',
+            shortcuts=[QtGui.QKeySequence(u'F12')], checked=liveVisible,
+            category=UiStrings().View, triggers=self.setLivePanelVisibility)
+        self.lockPanel = create_action(mainWindow, u'lockPanel',
+            checked=panelLocked, triggers=self.setLockPanel)
         action_list.add_category(unicode(UiStrings().ViewMode),
             CategoryOrder.standardMenu)
-        self.modeDefaultItem = checkable_action(
-            mainWindow, u'modeDefaultItem',
-            category=unicode(UiStrings().ViewMode))
-        self.modeSetupItem = checkable_action(
-            mainWindow, u'modeSetupItem',
-            category=unicode(UiStrings().ViewMode))
-        self.modeLiveItem = checkable_action(
-            mainWindow, u'modeLiveItem', True, unicode(UiStrings().ViewMode))
+        self.modeDefaultItem = create_action(mainWindow, u'modeDefaultItem',
+            checked=False, category=UiStrings().ViewMode)
+        self.modeSetupItem = create_action(mainWindow, u'modeSetupItem',
+            checked=False, category=UiStrings().ViewMode)
+        self.modeLiveItem = create_action(mainWindow, u'modeLiveItem',
+            checked=True, category=UiStrings().ViewMode)
         self.modeGroup = QtGui.QActionGroup(mainWindow)
         self.modeGroup.addAction(self.modeDefaultItem)
         self.modeGroup.addAction(self.modeSetupItem)
@@ -255,25 +257,27 @@
         self.modeDefaultItem.setChecked(True)
         action_list.add_category(unicode(UiStrings().Tools),
             CategoryOrder.standardMenu)
-        self.toolsAddToolItem = icon_action(mainWindow, u'toolsAddToolItem',
-            u':/tools/tools_add.png', category=unicode(UiStrings().Tools))
-        self.toolsOpenDataFolder = icon_action(mainWindow,
-            u'toolsOpenDataFolder', u':/general/general_open.png',
-            category=unicode(UiStrings().Tools))
-        self.toolsFirstTimeWizard = icon_action(mainWindow,
-            u'toolsFirstTimeWizard', u':/general/general_revert.png',
-            category=unicode(UiStrings().Tools))
-        self.updateThemeImages = base_action(mainWindow,
-            u'updateThemeImages', category=unicode(UiStrings().Tools))
+        self.toolsAddToolItem = create_action(mainWindow,
+            u'toolsAddToolItem', icon=u':/tools/tools_add.png',
+            category=UiStrings().Tools)
+        self.toolsOpenDataFolder = create_action(mainWindow,
+            u'toolsOpenDataFolder', icon=u':/general/general_open.png',
+            category=UiStrings().Tools)
+        self.toolsFirstTimeWizard = create_action(mainWindow,
+            u'toolsFirstTimeWizard', icon=u':/general/general_revert.png',
+            category=UiStrings().Tools)
+        self.updateThemeImages = create_action(mainWindow,
+            u'updateThemeImages', category=UiStrings().Tools)
         action_list.add_category(unicode(UiStrings().Settings),
             CategoryOrder.standardMenu)
-        self.settingsPluginListItem = shortcut_action(mainWindow,
-            u'settingsPluginListItem', [QtGui.QKeySequence(u'Alt+F7')],
-            self.onPluginItemClicked, u':/system/settings_plugin_list.png',
-            category=unicode(UiStrings().Settings))
+        self.settingsPluginListItem = create_action(mainWindow,
+            u'settingsPluginListItem',
+            icon=u':/system/settings_plugin_list.png',
+            shortcuts=[QtGui.QKeySequence(u'Alt+F7')],
+            category=UiStrings().Settings, triggers=self.onPluginItemClicked)
         # i18n Language Items
-        self.autoLanguageItem = checkable_action(mainWindow,
-            u'autoLanguageItem', LanguageManager.auto_language)
+        self.autoLanguageItem = create_action(mainWindow, u'autoLanguageItem',
+            checked=LanguageManager.auto_language)
         self.languageGroup = QtGui.QActionGroup(mainWindow)
         self.languageGroup.setExclusive(True)
         self.languageGroup.setObjectName(u'languageGroup')
@@ -281,44 +285,43 @@
         qmList = LanguageManager.get_qm_list()
         savedLanguage = LanguageManager.get_language()
         for key in sorted(qmList.keys()):
-            languageItem = checkable_action(
-                mainWindow, key, qmList[key] == savedLanguage)
+            languageItem = create_action(mainWindow, key,
+                checked=qmList[key] == savedLanguage)
             add_actions(self.languageGroup, [languageItem])
-        self.settingsShortcutsItem = icon_action(mainWindow,
+        self.settingsShortcutsItem = create_action(mainWindow,
             u'settingsShortcutsItem',
-            u':/system/system_configure_shortcuts.png',
-            category=unicode(UiStrings().Settings))
+            icon=u':/system/system_configure_shortcuts.png',
+            category=UiStrings().Settings)
         # Formatting Tags were also known as display tags.
-        self.formattingTagItem = icon_action(mainWindow,
-            u'displayTagItem', u':/system/tag_editor.png',
-            category=unicode(UiStrings().Settings))
-        self.settingsConfigureItem = icon_action(mainWindow,
-            u'settingsConfigureItem', u':/system/system_settings.png',
-            category=unicode(UiStrings().Settings))
-        self.settingsImportItem = base_action(mainWindow,
-           u'settingsImportItem', category=unicode(UiStrings().Settings))
-        self.settingsExportItem = base_action(mainWindow,
-           u'settingsExportItem', category=unicode(UiStrings().Settings))
+        self.formattingTagItem = create_action(mainWindow,
+            u'displayTagItem', icon=u':/system/tag_editor.png',
+            category=UiStrings().Settings)
+        self.settingsConfigureItem = create_action(mainWindow,
+            u'settingsConfigureItem', icon=u':/system/system_settings.png',
+            category=UiStrings().Settings)
+        self.settingsImportItem = create_action(mainWindow,
+           u'settingsImportItem', category=UiStrings().Settings)
+        self.settingsExportItem = create_action(mainWindow,
+           u'settingsExportItem', category=UiStrings().Settings)
         action_list.add_category(unicode(UiStrings().Help),
             CategoryOrder.standardMenu)
-        self.aboutItem = shortcut_action(mainWindow, u'aboutItem',
-            [QtGui.QKeySequence(u'Ctrl+F1')], self.onAboutItemClicked,
-            u':/system/system_about.png', category=unicode(UiStrings().Help))
+        self.aboutItem = create_action(mainWindow, u'aboutItem',
+            icon=u':/system/system_about.png',
+            shortcuts=[QtGui.QKeySequence(u'Ctrl+F1')],
+            category=UiStrings().Help, triggers=self.onAboutItemClicked)
         if os.name == u'nt':
             self.localHelpFile = os.path.join(
                 AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm')
-            self.offlineHelpItem = shortcut_action(
-                mainWindow, u'offlineHelpItem', [QtGui.QKeySequence(u'F1')],
-                self.onOfflineHelpClicked,
-                u':/system/system_help_contents.png',
-                category=unicode(UiStrings().Help))
-        self.onlineHelpItem = shortcut_action(
-            mainWindow, u'onlineHelpItem',
-            [QtGui.QKeySequence(u'Alt+F1')], self.onOnlineHelpClicked,
-            u':/system/system_online_help.png',
-            category=unicode(UiStrings().Help))
-        self.webSiteItem = base_action(
-            mainWindow, u'webSiteItem', category=unicode(UiStrings().Help))
+            self.offlineHelpItem = create_action(mainWindow, u'offlineHelpItem',
+                icon=u':/system/system_help_contents.png',
+                shortcuts=[QtGui.QKeySequence(u'F1')],
+                category=UiStrings().Help, triggers=self.onOfflineHelpClicked)
+        self.onlineHelpItem = create_action(mainWindow, u'onlineHelpItem',
+            icon=u':/system/system_online_help.png',
+            shortcuts=[QtGui.QKeySequence(u'Alt+F1')],
+            category=UiStrings().Help, triggers=self.onOnlineHelpClicked)
+        self.webSiteItem = create_action(mainWindow,
+            u'webSiteItem', category=UiStrings().Help)
         add_actions(self.fileImportMenu, (self.settingsImportItem, None,
             self.importThemeItem, self.importLanguageItem))
         add_actions(self.fileExportMenu, (self.settingsExportItem, None,
@@ -1378,27 +1381,24 @@
         recentFileCount = QtCore.QSettings().value(
             u'advanced/recent file count', QtCore.QVariant(4)).toInt()[0]
         existingRecentFiles = [recentFile for recentFile in self.recentFiles
-            if QtCore.QFile.exists(recentFile)]
+            if os.path.isfile(unicode(recentFile))]
         recentFilesToDisplay = existingRecentFiles[0:recentFileCount]
         self.recentFilesMenu.clear()
         for fileId, filename in enumerate(recentFilesToDisplay):
             log.debug('Recent file name: %s', filename)
-            action =  base_action(self, u'')
-            action.setText(u'&%d %s' %
-                (fileId + 1, QtCore.QFileInfo(filename).fileName()))
-            action.setData(QtCore.QVariant(filename))
-            self.connect(action, QtCore.SIGNAL(u'triggered()'),
-                self.serviceManagerContents.onRecentServiceClicked)
+            action = create_action(self, u'',
+                text=u'&%d %s' % (fileId + 1, os.path.splitext(os.path.basename(
+                unicode(filename)))[0]), data=filename,
+                triggers=self.serviceManagerContents.onRecentServiceClicked)
             self.recentFilesMenu.addAction(action)
-        clearRecentFilesAction =  base_action(self, u'')
-        clearRecentFilesAction.setText(
-            translate('OpenLP.MainWindow', 'Clear List',
-            'Clear List of recent files'))
-        clearRecentFilesAction.setStatusTip(
-            translate('OpenLP.MainWindow', 'Clear the list of recent files.'))
+        clearRecentFilesAction = create_action(self, u'',
+            text=translate('OpenLP.MainWindow', 'Clear List',
+            'Clear List of recent files'),
+            statustip=translate('OpenLP.MainWindow',
+            'Clear the list of recent files.'),
+            enabled=not self.recentFiles.isEmpty(),
+            triggers=self.recentFiles.clear)
         add_actions(self.recentFilesMenu, (None, clearRecentFilesAction))
-        self.connect(clearRecentFilesAction, QtCore.SIGNAL(u'triggered()'),
-            self.recentFiles.clear)
         clearRecentFilesAction.setEnabled(not self.recentFiles.isEmpty())
 
     def addRecentFile(self, filename):

=== modified file 'openlp/core/ui/media/mediacontroller.py'
--- openlp/core/ui/media/mediacontroller.py	2012-03-03 22:36:46 +0000
+++ openlp/core/ui/media/mediacontroller.py	2012-03-05 10:15:33 +0000
@@ -204,18 +204,21 @@
         controller.media_info = MediaInfo()
         # Build a Media ToolBar
         controller.mediabar = OpenLPToolbar(controller)
-        controller.mediabar.addToolbarButton(
-            u'media_playback_play', u':/slides/media_playback_start.png',
-            translate('OpenLP.SlideController', 'Start playing media.'),
-            controller.sendToPlugins)
-        controller.mediabar.addToolbarButton(
-            u'media_playback_pause', u':/slides/media_playback_pause.png',
-            translate('OpenLP.SlideController', 'Pause playing media.'),
-            controller.sendToPlugins)
-        controller.mediabar.addToolbarButton(
-            u'media_playback_stop', u':/slides/media_playback_stop.png',
-            translate('OpenLP.SlideController', 'Stop playing media.'),
-            controller.sendToPlugins)
+        controller.mediabar.addToolbarAction(u'playbackPlay',
+            text=u'media_playback_play',
+            icon=u':/slides/media_playback_start.png',
+            tooltip=translate('OpenLP.SlideController', 'Start playing media.'),
+            triggers=controller.sendToPlugins)
+        controller.mediabar.addToolbarAction(u'playbackPause',
+            text=u'media_playback_pause',
+            icon=u':/slides/media_playback_pause.png',
+            tooltip=translate('OpenLP.SlideController', 'Pause playing media.'),
+            triggers=controller.sendToPlugins)
+        controller.mediabar.addToolbarAction(u'playbackStop',
+            text=u'media_playback_stop',
+            icon=u':/slides/media_playback_stop.png',
+            tooltip=translate('OpenLP.SlideController', 'Stop playing media.'),
+            triggers=controller.sendToPlugins)
         # Build the seekSlider.
         controller.seekSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
         controller.seekSlider.setMaximum(1000)
@@ -223,9 +226,8 @@
         controller.seekSlider.setToolTip(translate(
             'OpenLP.SlideController', 'Video position.'))
         controller.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
-        controller.seekSlider.setObjectName(u'seek_slider')
-        controller.mediabar.addToolbarWidget(u'Seek Slider',
-            controller.seekSlider)
+        controller.seekSlider.setObjectName(u'seekSlider')
+        controller.mediabar.addToolbarWidget(controller.seekSlider)
         # Build the volumeSlider.
         controller.volumeSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
         controller.volumeSlider.setTickInterval(10)
@@ -237,9 +239,8 @@
             'OpenLP.SlideController', 'Audio Volume.'))
         controller.volumeSlider.setValue(controller.media_info.volume)
         controller.volumeSlider.setGeometry(QtCore.QRect(90, 160, 221, 24))
-        controller.volumeSlider.setObjectName(u'volume_slider')
-        controller.mediabar.addToolbarWidget(u'Audio Volume',
-            controller.volumeSlider)
+        controller.volumeSlider.setObjectName(u'volumeSlider')
+        controller.mediabar.addToolbarWidget(controller.volumeSlider)
         control_panel.addWidget(controller.mediabar)
         controller.mediabar.setVisible(False)
         # Signals

=== modified file 'openlp/core/ui/media/vlc.py'
--- openlp/core/ui/media/vlc.py	2011-12-08 20:51:44 +0000
+++ openlp/core/ui/media/vlc.py	2012-03-05 10:15:33 +0000
@@ -126,7 +126,7 @@
 try:
     _Ints = (int, long)
 except NameError:  # no long in Python 3+
-    _Ints =  int
+    _Ints = int
 
 # Default instance. It is used to instanciate classes directly in the
 # OO-wrapper.

=== modified file 'openlp/core/ui/media/vlcplayer.py'
--- openlp/core/ui/media/vlcplayer.py	2012-01-19 19:13:19 +0000
+++ openlp/core/ui/media/vlcplayer.py	2012-03-05 10:15:33 +0000
@@ -49,7 +49,7 @@
 
 log = logging.getLogger(__name__)
 
-AUDIO_EXT =  [
+AUDIO_EXT = [
       u'*.mp3'
     , u'*.wav'
     , u'*.ogg'

=== modified file 'openlp/core/ui/media/webkitplayer.py'
--- openlp/core/ui/media/webkitplayer.py	2011-12-07 20:20:23 +0000
+++ openlp/core/ui/media/webkitplayer.py	2012-03-05 10:15:33 +0000
@@ -246,7 +246,7 @@
             , u'*.swf'
         ]
 
-AUDIO_EXT =  [
+AUDIO_EXT = [
               u'*.mp3'
             , u'*.ogg'
         ]

=== modified file 'openlp/core/ui/servicemanager.py'
--- openlp/core/ui/servicemanager.py	2012-02-07 22:07:24 +0000
+++ openlp/core/ui/servicemanager.py	2012-03-05 10:15:33 +0000
@@ -41,7 +41,7 @@
     ItemCapabilities, SettingsManager, translate, str_to_bool
 from openlp.core.lib.theme import ThemeLevel
 from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
-    context_menu_action, context_menu_separator, find_and_set_in_combo_box
+    create_widget_action, find_and_set_in_combo_box
 from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm, StartTimeForm
 from openlp.core.ui.printserviceform import PrintServiceForm
 from openlp.core.utils import AppLocation, delete_file, split_filename
@@ -117,22 +117,23 @@
         self.layout.setMargin(0)
         # Create the top toolbar
         self.toolbar = OpenLPToolbar(self)
-        self.toolbar.addToolbarButton(
-            UiStrings().NewService, u':/general/general_new.png',
-            UiStrings().CreateService, self.onNewServiceClicked)
-        self.toolbar.addToolbarButton(
-            UiStrings().OpenService, u':/general/general_open.png',
-            translate('OpenLP.ServiceManager', 'Load an existing service.'),
-            self.onLoadServiceClicked)
-        self.toolbar.addToolbarButton(
-            UiStrings().SaveService, u':/general/general_save.png',
-            translate('OpenLP.ServiceManager', 'Save this service.'),
-            self.saveFile)
+        self.toolbar.addToolbarAction(u'newService',
+            text=UiStrings().NewService, icon=u':/general/general_new.png',
+            tooltip=UiStrings().CreateService,
+            triggers=self.onNewServiceClicked)
+        self.toolbar.addToolbarAction(u'openService',
+            text=UiStrings().OpenService, icon=u':/general/general_open.png',
+            tooltip=translate('OpenLP.ServiceManager',
+            'Load an existing service.'), triggers=self.onLoadServiceClicked)
+        self.toolbar.addToolbarAction(u'saveService',
+            text=UiStrings().SaveService, icon=u':/general/general_save.png',
+            tooltip=translate('OpenLP.ServiceManager', 'Save this service.'),
+            triggers=self.saveFile)
         self.toolbar.addSeparator()
         self.themeLabel = QtGui.QLabel(u'%s:' % UiStrings().Theme, self)
         self.themeLabel.setMargin(3)
         self.themeLabel.setObjectName(u'themeLabel')
-        self.toolbar.addToolbarWidget(u'ThemeLabel', self.themeLabel)
+        self.toolbar.addToolbarWidget(self.themeLabel)
         self.themeComboBox = QtGui.QComboBox(self.toolbar)
         self.themeComboBox.setToolTip(translate('OpenLP.ServiceManager',
             'Select a theme for the service.'))
@@ -141,7 +142,7 @@
         self.themeComboBox.setSizePolicy(
             QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
         self.themeComboBox.setObjectName(u'themeComboBox')
-        self.toolbar.addToolbarWidget(u'ThemeWidget', self.themeComboBox)
+        self.toolbar.addToolbarWidget(self.themeComboBox)
         self.toolbar.setObjectName(u'toolbar')
         self.layout.addWidget(self.toolbar)
         # Create the service manager list
@@ -168,99 +169,77 @@
         self.layout.addWidget(self.serviceManagerList)
         # Add the bottom toolbar
         self.orderToolbar = OpenLPToolbar(self)
-        self.serviceManagerList.moveTop = self.orderToolbar.addToolbarButton(
-            translate('OpenLP.ServiceManager', 'Move to &top'),
-            u':/services/service_top.png',
-            translate('OpenLP.ServiceManager',
-            'Move item to the top of the service.'),
-            self.onServiceTop, shortcuts=[QtCore.Qt.Key_Home])
-        self.serviceManagerList.moveTop.setObjectName(u'moveTop')
         action_list = ActionList.get_instance()
         action_list.add_category(
             unicode(UiStrings().Service), CategoryOrder.standardToolbar)
-        action_list.add_action(
-            self.serviceManagerList.moveTop, unicode(UiStrings().Service))
-        self.serviceManagerList.moveUp = self.orderToolbar.addToolbarButton(
-            translate('OpenLP.ServiceManager', 'Move &up'),
-            u':/services/service_up.png',
-            translate('OpenLP.ServiceManager',
+        self.serviceManagerList.moveTop = self.orderToolbar.addToolbarAction(
+            u'moveTop', text=translate('OpenLP.ServiceManager', 'Move to &top'),
+            icon=u':/services/service_top.png', tooltip=translate(
+            'OpenLP.ServiceManager', 'Move item to the top of the service.'),
+            shortcuts=[QtCore.Qt.Key_Home], category=UiStrings().Service,
+            triggers=self.onServiceTop)
+        self.serviceManagerList.moveUp = self.orderToolbar.addToolbarAction(
+            u'moveUp', text=translate('OpenLP.ServiceManager', 'Move &up'),
+            icon=u':/services/service_up.png',
+            tooltip=translate( 'OpenLP.ServiceManager',
             'Move item up one position in the service.'),
-            self.onServiceUp, shortcuts=[QtCore.Qt.Key_PageUp])
-        self.serviceManagerList.moveUp.setObjectName(u'moveUp')
-        action_list.add_action(
-            self.serviceManagerList.moveUp, unicode(UiStrings().Service))
-        self.serviceManagerList.moveDown = self.orderToolbar.addToolbarButton(
-            translate('OpenLP.ServiceManager', 'Move &down'),
-            u':/services/service_down.png',
-            translate('OpenLP.ServiceManager',
+            shortcuts=[QtCore.Qt.Key_PageUp], category=UiStrings().Service,
+            triggers=self.onServiceUp)
+        self.serviceManagerList.moveDown = self.orderToolbar.addToolbarAction(
+            u'moveDown', text=translate('OpenLP.ServiceManager', 'Move &down'),
+            icon=u':/services/service_down.png',
+            tooltip=translate('OpenLP.ServiceManager',
             'Move item down one position in the service.'),
-            self.onServiceDown, shortcuts=[QtCore.Qt.Key_PageDown])
-        self.serviceManagerList.moveDown.setObjectName(u'moveDown')
-        action_list.add_action(
-            self.serviceManagerList.moveDown, unicode(UiStrings().Service))
-        self.serviceManagerList.moveBottom = self.orderToolbar.addToolbarButton(
-            translate('OpenLP.ServiceManager', 'Move to &bottom'),
-            u':/services/service_bottom.png',
-            translate('OpenLP.ServiceManager',
-            'Move item to the end of the service.'),
-            self.onServiceEnd, shortcuts=[QtCore.Qt.Key_End])
-        self.serviceManagerList.moveBottom.setObjectName(u'moveBottom')
-        action_list.add_action(
-            self.serviceManagerList.moveBottom, unicode(UiStrings().Service))
-        self.serviceManagerList.down = self.orderToolbar.addToolbarButton(
-            translate('OpenLP.ServiceManager', 'Move &down'),
-            None,
-            translate('OpenLP.ServiceManager',
-            'Moves the selection down the window.'),
-            self.onMoveSelectionDown, shortcuts=[QtCore.Qt.Key_Down])
-        self.serviceManagerList.down.setObjectName(u'down')
+            shortcuts=[QtCore.Qt.Key_PageDown], category=UiStrings().Service,
+            triggers=self.onServiceDown)
+        self.serviceManagerList.moveBottom = self.orderToolbar.addToolbarAction(
+            u'moveBottom',
+            text=translate('OpenLP.ServiceManager', 'Move to &bottom'),
+            icon=u':/services/service_bottom.png', tooltip=translate(
+            'OpenLP.ServiceManager', 'Move item to the end of the service.'),
+            shortcuts=[QtCore.Qt.Key_End], category=UiStrings().Service,
+            triggers=self.onServiceEnd)
+        self.serviceManagerList.down = self.orderToolbar.addToolbarAction(
+            u'down', text=translate('OpenLP.ServiceManager', 'Move &down'),
+            tooltip=translate('OpenLP.ServiceManager',
+            'Moves the selection down the window.'), visible=False,
+            shortcuts=[QtCore.Qt.Key_Down], triggers=self.onMoveSelectionDown)
         action_list.add_action(self.serviceManagerList.down)
-        self.serviceManagerList.down.setVisible(False)
-        self.serviceManagerList.up = self.orderToolbar.addToolbarButton(
-            translate('OpenLP.ServiceManager', 'Move up'),
-            None,
-            translate('OpenLP.ServiceManager',
-            'Moves the selection up the window.'),
-            self.onMoveSelectionUp, shortcuts=[QtCore.Qt.Key_Up])
-        self.serviceManagerList.up.setObjectName(u'up')
+        self.serviceManagerList.up = self.orderToolbar.addToolbarAction(
+            u'up', text=translate('OpenLP.ServiceManager', 'Move up'),
+            tooltip=translate('OpenLP.ServiceManager',
+            'Moves the selection up the window.'), visible=False,
+            shortcuts=[QtCore.Qt.Key_Up], triggers=self.onMoveSelectionUp)
         action_list.add_action(self.serviceManagerList.up)
-        self.serviceManagerList.up.setVisible(False)
         self.orderToolbar.addSeparator()
-        self.serviceManagerList.delete = self.orderToolbar.addToolbarButton(
-            translate('OpenLP.ServiceManager', '&Delete From Service'),
-            u':/general/general_delete.png',
-            translate('OpenLP.ServiceManager',
+        self.serviceManagerList.delete = self.orderToolbar.addToolbarAction(
+            u'delete',
+            text=translate('OpenLP.ServiceManager', '&Delete From Service'),
+            icon=u':/general/general_delete.png',
+            tooltip=translate('OpenLP.ServiceManager',
             'Delete the selected item from the service.'),
-            self.onDeleteFromService)
-        self.orderToolbar.addSeparator()
-        self.serviceManagerList.expand = self.orderToolbar.addToolbarButton(
-            translate('OpenLP.ServiceManager', '&Expand all'),
-            u':/services/service_expand_all.png',
-            translate('OpenLP.ServiceManager',
-            'Expand all the service items.'),
-            self.onExpandAll, shortcuts=[QtCore.Qt.Key_Plus])
-        self.serviceManagerList.expand.setObjectName(u'expand')
-        action_list.add_action(
-            self.serviceManagerList.expand, unicode(UiStrings().Service))
-        self.serviceManagerList.collapse = self.orderToolbar.addToolbarButton(
-            translate('OpenLP.ServiceManager', '&Collapse all'),
-            u':/services/service_collapse_all.png',
-            translate('OpenLP.ServiceManager',
-            'Collapse all the service items.'),
-            self.onCollapseAll, shortcuts=[QtCore.Qt.Key_Minus])
-        self.serviceManagerList.collapse.setObjectName(u'collapse')
-        action_list.add_action(
-            self.serviceManagerList.collapse, unicode(UiStrings().Service))
-        self.orderToolbar.addSeparator()
-        self.serviceManagerList.makeLive = self.orderToolbar.addToolbarButton(
-            translate('OpenLP.ServiceManager', 'Go Live'),
-            u':/general/general_live.png',
-            translate('OpenLP.ServiceManager',
-            'Send the selected item to Live.'), self.makeLive,
-            shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return])
-        self.serviceManagerList.makeLive.setObjectName(u'orderToolbar')
-        action_list.add_action(
-            self.serviceManagerList.makeLive, unicode(UiStrings().Service))
+            triggers=self.onDeleteFromService)
+        self.orderToolbar.addSeparator()
+        self.serviceManagerList.expand = self.orderToolbar.addToolbarAction(
+            u'expand', text=translate('OpenLP.ServiceManager', '&Expand all'),
+            icon=u':/services/service_expand_all.png', tooltip=translate(
+            'OpenLP.ServiceManager', 'Expand all the service items.'),
+            shortcuts=[QtCore.Qt.Key_Plus], category=UiStrings().Service,
+            triggers=self.onExpandAll)
+        self.serviceManagerList.collapse = self.orderToolbar.addToolbarAction(
+            u'collapse',
+            text=translate('OpenLP.ServiceManager', '&Collapse all'),
+            icon=u':/services/service_collapse_all.png', tooltip=translate(
+            'OpenLP.ServiceManager', 'Collapse all the service items.'),
+            shortcuts=[QtCore.Qt.Key_Minus], category=UiStrings().Service,
+            triggers=self.onCollapseAll)
+        self.orderToolbar.addSeparator()
+        self.serviceManagerList.makeLive = self.orderToolbar.addToolbarAction(
+            u'makeLive', text=translate('OpenLP.ServiceManager', 'Go Live'),
+            icon=u':/general/general_live.png', tooltip=translate(
+            'OpenLP.ServiceManager', 'Send the selected item to Live.'),
+            shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return],
+            category=UiStrings().Service, triggers=self.makeLive)
         self.layout.addWidget(self.orderToolbar)
         # Connect up our signals and slots
         QtCore.QObject.connect(self.themeComboBox,
@@ -305,34 +284,32 @@
         self.addToAction.setIcon(build_icon(u':/general/general_edit.png'))
         # build the context menu
         self.menu = QtGui.QMenu()
-        self.editAction = context_menu_action(
-            self.menu, u':/general/general_edit.png',
-            translate('OpenLP.ServiceManager', '&Edit Item'), self.remoteEdit)
-        self.maintainAction = context_menu_action(
-            self.menu, u':/general/general_edit.png',
-            translate('OpenLP.ServiceManager', '&Reorder Item'),
-            self.onServiceItemEditForm)
-        self.notesAction = context_menu_action(
-            self.menu, u':/services/service_notes.png',
-            translate('OpenLP.ServiceManager', '&Notes'),
-            self.onServiceItemNoteForm)
-        self.timeAction = context_menu_action(
-            self.menu, u':/media/media_time.png',
-            translate('OpenLP.ServiceManager', '&Start Time'),
-            self.onStartTimeForm)
-        self.deleteAction = context_menu_action(
-            self.menu, u':/general/general_delete.png',
-            translate('OpenLP.ServiceManager', '&Delete From Service'),
-            self.onDeleteFromService)
-        context_menu_separator(self.menu)
-        self.previewAction = context_menu_action(
-            self.menu, u':/general/general_preview.png',
-            translate('OpenLP.ServiceManager', 'Show &Preview'),
-            self.makePreview)
-        self.liveAction = context_menu_action(
-            self.menu, u':/general/general_live.png',
-            translate('OpenLP.ServiceManager', 'Show &Live'), self.makeLive)
-        context_menu_separator(self.menu)
+        self.editAction = create_widget_action(self.menu,
+            text=translate('OpenLP.ServiceManager', '&Edit Item'),
+            icon=u':/general/general_edit.png', triggers=self.remoteEdit)
+        self.maintainAction = create_widget_action(self.menu,
+            text=translate('OpenLP.ServiceManager', '&Reorder Item'),
+            icon=u':/general/general_edit.png',
+            triggers=self.onServiceItemEditForm)
+        self.notesAction = create_widget_action(self.menu,
+            text=translate('OpenLP.ServiceManager', '&Notes'),
+            icon=u':/services/service_notes.png',
+            triggers=self.onServiceItemNoteForm)
+        self.timeAction = create_widget_action(self.menu,
+            text=translate('OpenLP.ServiceManager', '&Start Time'),
+            icon=u':/media/media_time.png', triggers=self.onStartTimeForm)
+        self.deleteAction = create_widget_action(self.menu,
+            text=translate('OpenLP.ServiceManager', '&Delete From Service'),
+            icon=u':/general/general_delete.png',
+            triggers=self.onDeleteFromService)
+        self.menu.addSeparator()
+        self.previewAction = create_widget_action(self.menu,
+            text=translate('OpenLP.ServiceManager', 'Show &Preview'),
+            icon=u':/general/general_preview.png', triggers=self.makePreview)
+        self.liveAction = create_widget_action(self.menu,
+            text=translate('OpenLP.ServiceManager', 'Show &Live'),
+            icon=u':/general/general_live.png', triggers=self.makeLive)
+        self.menu.addSeparator()
         self.themeMenu = QtGui.QMenu(
             translate('OpenLP.ServiceManager', '&Change Item Theme'))
         self.menu.addMenu(self.themeMenu)
@@ -683,7 +660,7 @@
                         'File is not a valid service.\n'
                         'The content encoding is not UTF-8.'))
                     continue
-                osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile))
+                osfile = ucsfile.replace(u'/', os.path.sep)
                 if not osfile.startswith(u'audio'):
                     osfile = os.path.split(osfile)[1]
                 log.debug(u'Extract file: %s', osfile)
@@ -1143,12 +1120,9 @@
         sure the theme combo box is in the correct state.
         """
         log.debug(u'themeChange')
-        if self.mainwindow.renderer.theme_level == ThemeLevel.Global:
-            self.toolbar.actions[u'ThemeLabel'].setVisible(False)
-            self.toolbar.actions[u'ThemeWidget'].setVisible(False)
-        else:
-            self.toolbar.actions[u'ThemeLabel'].setVisible(True)
-            self.toolbar.actions[u'ThemeWidget'].setVisible(True)
+        visible = self.mainwindow.renderer.theme_level == ThemeLevel.Global
+        self.themeLabel.setVisible(visible)
+        self.themeComboBox.setVisible(visible)
 
     def regenerateServiceItems(self):
         """
@@ -1450,19 +1424,16 @@
         themeGroup.setObjectName(u'themeGroup')
         # Create a "Default" theme, which allows the user to reset the item's
         # theme to the service theme or global theme.
-        defaultTheme = context_menu_action(self.themeMenu, None,
-            UiStrings().Default, self.onThemeChangeAction)
-        defaultTheme.setCheckable(True)
+        defaultTheme = create_widget_action(self.themeMenu,
+            text=UiStrings().Default, checked=False,
+            triggers=self.onThemeChangeAction)
         self.themeMenu.setDefaultAction(defaultTheme)
         themeGroup.addAction(defaultTheme)
-        context_menu_separator(self.themeMenu)
+        self.themeMenu.addSeparator()
         for theme in theme_list:
             self.themeComboBox.addItem(theme)
-            themeAction = context_menu_action(self.themeMenu, None, theme,
-                self.onThemeChangeAction)
-            themeAction.setObjectName(theme)
-            themeAction.setCheckable(True)
-            themeGroup.addAction(themeAction)
+            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.regenerateServiceItems()

=== modified file 'openlp/core/ui/slidecontroller.py'
--- openlp/core/ui/slidecontroller.py	2012-02-15 10:37:42 +0000
+++ openlp/core/ui/slidecontroller.py	2012-03-05 10:15:33 +0000
@@ -33,8 +33,8 @@
 from PyQt4 import QtCore, QtGui
 
 from openlp.core.lib import OpenLPToolbar, Receiver, ItemCapabilities, \
-    translate, build_icon, ServiceItem, build_html, PluginManager, ServiceItem
-from openlp.core.lib.ui import UiStrings, shortcut_action
+    translate, build_icon, build_html, PluginManager, ServiceItem
+from openlp.core.lib.ui import UiStrings, create_action
 from openlp.core.lib import SlideLimits, ServiceItemAction
 from openlp.core.ui import HideMode, MainDisplay, Display, ScreenList
 from openlp.core.utils.actions import ActionList, CategoryOrder
@@ -46,9 +46,10 @@
     Customised version of QTableWidget which can respond to keyboard
     events.
     """
-    def __init__(self, parent=None, name=None):
+    def __init__(self, parent=None):
         QtGui.QTableWidget.__init__(self, parent.controller)
 
+
 class Controller(QtGui.QWidget):
     """
     Controller is a general controller widget.
@@ -91,16 +92,14 @@
         self.imageManager = self.parent().imageManager
         self.mediaController = self.parent().mediaController
         self.loopList = [
-            u'Play Slides Menu',
-            u'Loop Separator',
-            u'Image SpinBox'
-        ]
-        self.songEditList = [
-            u'Edit Song',
-        ]
-        self.nextPreviousList = [
-            u'Previous Slide',
-            u'Next Slide'
+            u'playSlidesMenu',
+            u'loopSeparator',
+            u'delaySpinBox'
+        ]
+        self.audioList = [
+            u'songMenu',
+            u'audioPauseItem',
+            u'audioTimeLabel'
         ]
         self.timer_id = 0
         self.songEdit = False
@@ -122,10 +121,14 @@
             self.typePrefix = u'live'
             self.keypress_queue = deque()
             self.keypress_loop = False
+            self.category = UiStrings().LiveToolbar
+            ActionList.get_instance().add_category(
+                unicode(self.category), CategoryOrder.standardToolbar)
         else:
             self.typeLabel.setText(UiStrings().Preview)
             self.split = 0
             self.typePrefix = u'preview'
+            self.category = None
         self.typeLabel.setStyleSheet(u'font-weight: bold; font-size: 12pt;')
         self.typeLabel.setAlignment(QtCore.Qt.AlignCenter)
         self.panelLayout.addWidget(self.typeLabel)
@@ -168,72 +171,71 @@
         sizeToolbarPolicy.setHeightForWidth(
             self.toolbar.sizePolicy().hasHeightForWidth())
         self.toolbar.setSizePolicy(sizeToolbarPolicy)
-        self.previousItem = self.toolbar.addToolbarButton(
-            u'Previous Slide',
-            u':/slides/slide_previous.png',
-            translate('OpenLP.SlideController', 'Move to previous.'),
-            self.onSlideSelectedPrevious,
+        self.previousItem = create_action(self,
+            u'previousItem_' + self.typePrefix,
+            text=translate('OpenLP.SlideController', 'Previous Slide'),
+            icon=u':/slides/slide_previous.png',
+            tooltip=translate('OpenLP.SlideController', 'Move to previous.'),
             shortcuts=[QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp],
-            context=QtCore.Qt.WidgetWithChildrenShortcut)
-        self.nextItem = self.toolbar.addToolbarButton(
-            u'Next Slide',
-            u':/slides/slide_next.png',
-            translate('OpenLP.SlideController', 'Move to next.'),
-            self.onSlideSelectedNext,
+            context=QtCore.Qt.WidgetWithChildrenShortcut,
+            category=self.category, triggers=self.onSlideSelectedPrevious)
+        self.toolbar.addAction(self.previousItem)
+        self.nextItem = create_action(self, u'nextItem_' + self.typePrefix,
+            text=translate('OpenLP.SlideController', 'Next Slide'),
+            icon=u':/slides/slide_next.png',
+            tooltip=translate('OpenLP.SlideController', 'Move to next.'),
             shortcuts=[QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown],
-            context=QtCore.Qt.WidgetWithChildrenShortcut)
-        self.toolbar.addToolbarSeparator(u'Close Separator')
+            context=QtCore.Qt.WidgetWithChildrenShortcut,
+            category=self.category, triggers=self.onSlideSelectedNext)
+        self.toolbar.addAction(self.nextItem)
+        self.toolbar.addSeparator()
         if self.isLive:
             # Hide Menu
             self.hideMenu = QtGui.QToolButton(self.toolbar)
+            self.hideMenu.setObjectName(u'hideMenu')
             self.hideMenu.setText(translate('OpenLP.SlideController', 'Hide'))
             self.hideMenu.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
-            self.toolbar.addToolbarWidget(u'Hide Menu', self.hideMenu)
             self.hideMenu.setMenu(QtGui.QMenu(
                 translate('OpenLP.SlideController', 'Hide'), self.toolbar))
-            self.blankScreen = shortcut_action(self.hideMenu, u'blankScreen',
-                [QtCore.Qt.Key_Period], self.onBlankDisplay,
-                u':/slides/slide_blank.png', False,
-                unicode(UiStrings().LiveToolbar))
-            self.blankScreen.setText(
-                translate('OpenLP.SlideController', 'Blank Screen'))
-            self.themeScreen = shortcut_action(self.hideMenu, u'themeScreen',
-                [QtGui.QKeySequence(u'T')], self.onThemeDisplay,
-                u':/slides/slide_theme.png', False,
-                unicode(UiStrings().LiveToolbar))
-            self.themeScreen.setText(
-                translate('OpenLP.SlideController', 'Blank to Theme'))
-            self.desktopScreen = shortcut_action(self.hideMenu,
-                u'desktopScreen', [QtGui.QKeySequence(u'D')],
-                self.onHideDisplay, u':/slides/slide_desktop.png', False,
-                unicode(UiStrings().LiveToolbar))
-            self.desktopScreen.setText(
-                translate('OpenLP.SlideController', 'Show Desktop'))
+            self.toolbar.addToolbarWidget(self.hideMenu)
+            self.blankScreen = create_action(self, u'blankScreen',
+                text=translate('OpenLP.SlideController', 'Blank Screen'),
+                icon=u':/slides/slide_blank.png', checked=False,
+                shortcuts=[QtCore.Qt.Key_Period],
+                category=self.category, triggers=self.onBlankDisplay)
+            self.themeScreen = create_action(self, u'themeScreen',
+                text=translate('OpenLP.SlideController', 'Blank to Theme'),
+                icon=u':/slides/slide_theme.png', checked=False,
+                shortcuts=[QtGui.QKeySequence(u'T')],
+                category=self.category, triggers=self.onThemeDisplay)
+            self.desktopScreen = create_action(self, u'desktopScreen',
+                text=translate('OpenLP.SlideController', 'Show Desktop'),
+                icon=u':/slides/slide_desktop.png', checked=False,
+                shortcuts=[QtGui.QKeySequence(u'D')],
+                category=self.category, triggers=self.onHideDisplay)
             self.hideMenu.setDefaultAction(self.blankScreen)
             self.hideMenu.menu().addAction(self.blankScreen)
             self.hideMenu.menu().addAction(self.themeScreen)
             self.hideMenu.menu().addAction(self.desktopScreen)
-            self.toolbar.addToolbarSeparator(u'Loop Separator')
+            self.toolbar.addToolbarAction(u'loopSeparator', separator=True)
             # Play Slides Menu
             self.playSlidesMenu = QtGui.QToolButton(self.toolbar)
+            self.playSlidesMenu.setObjectName(u'playSlidesMenu')
             self.playSlidesMenu.setText(translate('OpenLP.SlideController',
                 'Play Slides'))
             self.playSlidesMenu.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
-            self.toolbar.addToolbarWidget(u'Play Slides Menu',
-                self.playSlidesMenu)
             self.playSlidesMenu.setMenu(QtGui.QMenu(
                 translate('OpenLP.SlideController', 'Play Slides'),
                 self.toolbar))
-            self.playSlidesLoop = shortcut_action(self.playSlidesMenu,
-                u'playSlidesLoop', [], self.onPlaySlidesLoop,
-                u':/media/media_time.png', False,
-                unicode(UiStrings().LiveToolbar))
-            self.playSlidesLoop.setText(UiStrings().PlaySlidesInLoop)
-            self.playSlidesOnce = shortcut_action(self.playSlidesMenu,
-                u'playSlidesOnce', [], self.onPlaySlidesOnce,
-                u':/media/media_time.png', False,
-                unicode(UiStrings().LiveToolbar))
-            self.playSlidesOnce.setText(UiStrings().PlaySlidesToEnd)
+            self.toolbar.addToolbarWidget(self.playSlidesMenu)
+            self.playSlidesLoop = create_action(self, u'playSlidesLoop',
+                text=UiStrings().PlaySlidesInLoop,
+                icon=u':/media/media_time.png', checked=False, shortcuts=[],
+                category=self.category, triggers=self.onPlaySlidesLoop)
+            self.playSlidesOnce = create_action(self, u'playSlidesOnce',
+                text=UiStrings().PlaySlidesToEnd,
+                icon=u':/media/media_time.png', checked=False, shortcuts=[],
+                category=self.category, triggers=self.onPlaySlidesOnce)
             if QtCore.QSettings().value(self.parent().generalSettingsSection +
                 u'/enable slide loop', QtCore.QVariant(True)).toBool():
                 self.playSlidesMenu.setDefaultAction(self.playSlidesLoop)
@@ -243,47 +245,75 @@
             self.playSlidesMenu.menu().addAction(self.playSlidesOnce)
             # Loop Delay Spinbox
             self.delaySpinBox = QtGui.QSpinBox()
+            self.delaySpinBox.setObjectName(u'delaySpinBox')
             self.delaySpinBox.setRange(1, 180)
-            self.toolbar.addToolbarWidget(u'Image SpinBox', self.delaySpinBox)
             self.delaySpinBox.setSuffix(UiStrings().Seconds)
             self.delaySpinBox.setToolTip(translate('OpenLP.SlideController',
                 'Delay between slides in seconds.'))
+            self.toolbar.addToolbarWidget(self.delaySpinBox)
         else:
-            self.toolbar.addToolbarButton(
-                # Does not need translating - control string.
-                u'Go Live', u':/general/general_live.png',
-                translate('OpenLP.SlideController', 'Move to live.'),
-                self.onGoLive)
-            self.toolbar.addToolbarButton(
-                # Does not need translating - control string.
-                u'Add to Service', u':/general/general_add.png',
-                translate('OpenLP.SlideController', 'Add to Service.'),
-                self.onPreviewAddToService)
-            self.toolbar.addToolbarSeparator(u'Close Separator')
-            self.toolbar.addToolbarButton(
-                # Does not need translating - control string.
-                u'Edit Song', u':/general/general_edit.png',
-                translate('OpenLP.SlideController',
-                'Edit and reload song preview.'),
-                self.onEditSong)
+            self.toolbar.addToolbarAction(u'goLive',
+                icon=u':/general/general_live.png',
+                tooltip=translate('OpenLP.SlideController', 'Move to live.'),
+                triggers=self.onGoLive)
+            self.toolbar.addToolbarAction(u'addToService',
+                icon=u':/general/general_add.png',
+                tooltip=translate('OpenLP.SlideController', 'Add to Service.'),
+                triggers=self.onPreviewAddToService)
+            self.toolbar.addSeparator()
+            self.toolbar.addToolbarAction(u'editSong',
+                icon=u':/general/general_edit.png',
+                tooltip=translate('OpenLP.SlideController',
+                'Edit and reload song preview.'), triggers=self.onEditSong)
         self.controllerLayout.addWidget(self.toolbar)
         # Build the Media Toolbar
         self.mediaController.add_controller_items(self, self.controllerLayout)
         if self.isLive:
             # Build the Song Toolbar
             self.songMenu = QtGui.QToolButton(self.toolbar)
+            self.songMenu.setObjectName(u'songMenu')
             self.songMenu.setText(translate('OpenLP.SlideController', 'Go To'))
             self.songMenu.setPopupMode(QtGui.QToolButton.InstantPopup)
-            self.toolbar.addToolbarWidget(u'Song Menu', self.songMenu)
             self.songMenu.setMenu(QtGui.QMenu(
                 translate('OpenLP.SlideController', 'Go To'), self.toolbar))
-            self.toolbar.makeWidgetsInvisible([u'Song Menu'])
+            self.toolbar.addToolbarWidget(self.songMenu)
             # Stuff for items with background audio.
-            self.audioPauseItem = self.toolbar.addToolbarButton(
-                u'Pause Audio', u':/slides/media_playback_pause.png',
-                translate('OpenLP.SlideController', 'Pause audio.'),
-                self.onAudioPauseClicked, True)
-            self.audioPauseItem.setVisible(False)
+            self.audioPauseItem = self.toolbar.addToolbarAction(
+                u'audioPauseItem', icon=u':/slides/media_playback_pause.png',
+                text=translate('OpenLP.SlideController', 'Pause Audio'),
+                tooltip=translate('OpenLP.SlideController', 'Pause audio.'),
+                checked=False, visible=False, category=self.category,
+                triggers=self.onAudioPauseClicked)
+            self.audioMenu = QtGui.QMenu(
+                translate('OpenLP.SlideController', 'Background Audio'), self)
+            self.audioPauseItem.setMenu(self.audioMenu)
+            self.audioPauseItem.setParent(self)
+            self.toolbar.widgetForAction(self.audioPauseItem).setPopupMode(
+                QtGui.QToolButton.MenuButtonPopup)
+            self.nextTrackItem = create_action(self, u'nextTrackItem',
+                text=translate('OpenLP.SlideController', 'Next Track'),
+                icon=u':/slides/media_playback_next.png', tooltip=translate(
+                'OpenLP.SlideController', 'Go to next audio track.'),
+                category=self.category, context=QtCore.Qt.WindowShortcut,
+                triggers=self.onNextTrackClicked)
+            self.audioMenu.addAction(self.nextTrackItem)
+            self.trackMenu = self.audioMenu.addMenu(
+                translate('OpenLP.SlideController', 'Tracks'))
+            self.audioTimeLabel = QtGui.QLabel(u' 00:00 ', self.toolbar)
+            self.audioTimeLabel.setAlignment(
+                QtCore.Qt.AlignCenter|QtCore.Qt.AlignHCenter)
+            self.audioTimeLabel.setStyleSheet(
+                u'background-color: palette(background); '
+                u'border-top-color: palette(shadow); '
+                u'border-left-color: palette(shadow); '
+                u'border-bottom-color: palette(light); '
+                u'border-right-color: palette(light); '
+                u'border-radius: 3px; border-style: inset; '
+                u'border-width: 1; font-family: monospace; margin: 2px;'
+            )
+            self.audioTimeLabel.setObjectName(u'audioTimeLabel')
+            self.toolbar.addToolbarWidget(self.audioTimeLabel)
+            self.toolbar.setWidgetVisible(self.audioList, False)
         # Screen preview area
         self.previewFrame = QtGui.QFrame(self.splitter)
         self.previewFrame.setGeometry(QtCore.QRect(0, 0, 300, 300 * self.ratio))
@@ -328,89 +358,31 @@
             self.shortcutTimer = QtCore.QTimer()
             self.shortcutTimer.setObjectName(u'shortcutTimer')
             self.shortcutTimer.setSingleShot(True)
-            self.verseShortcut = shortcut_action(self, u'verseShortcut',
-                [QtGui.QKeySequence(u'V')], self.slideShortcutActivated,
-                category=unicode(UiStrings().LiveToolbar),
-                context=QtCore.Qt.WidgetWithChildrenShortcut)
-            self.verseShortcut.setText(translate(
-                'OpenLP.SlideController', 'Go to "Verse"'))
-            self.shortcut0 = shortcut_action(self, u'0',
-                [QtGui.QKeySequence(u'0')], self.slideShortcutActivated,
-                context=QtCore.Qt.WidgetWithChildrenShortcut)
-            self.shortcut1 = shortcut_action(self, u'1',
-                [QtGui.QKeySequence(u'1')], self.slideShortcutActivated,
-                context=QtCore.Qt.WidgetWithChildrenShortcut)
-            self.shortcut2 = shortcut_action(self, u'2',
-                [QtGui.QKeySequence(u'2')], self.slideShortcutActivated,
-                context=QtCore.Qt.WidgetWithChildrenShortcut)
-            self.shortcut3 = shortcut_action(self, u'3',
-                [QtGui.QKeySequence(u'3')], self.slideShortcutActivated,
-                context=QtCore.Qt.WidgetWithChildrenShortcut)
-            self.shortcut4 = shortcut_action(self, u'4',
-                [QtGui.QKeySequence(u'4')], self.slideShortcutActivated,
-                context=QtCore.Qt.WidgetWithChildrenShortcut)
-            self.shortcut5 = shortcut_action(self, u'5',
-                [QtGui.QKeySequence(u'5')], self.slideShortcutActivated,
-                context=QtCore.Qt.WidgetWithChildrenShortcut)
-            self.shortcut6 = shortcut_action(self, u'6',
-                [QtGui.QKeySequence(u'6')], self.slideShortcutActivated,
-                context=QtCore.Qt.WidgetWithChildrenShortcut)
-            self.shortcut7 = shortcut_action(self, u'7',
-                [QtGui.QKeySequence(u'7')], self.slideShortcutActivated,
-                context=QtCore.Qt.WidgetWithChildrenShortcut)
-            self.shortcut8 = shortcut_action(self, u'8',
-                [QtGui.QKeySequence(u'8')], self.slideShortcutActivated,
-                context=QtCore.Qt.WidgetWithChildrenShortcut)
-            self.shortcut9 = shortcut_action(self, u'9',
-                [QtGui.QKeySequence(u'9')], self.slideShortcutActivated,
-                context=QtCore.Qt.WidgetWithChildrenShortcut)
-            self.chorusShortcut = shortcut_action(self, u'chorusShortcut',
-                [QtGui.QKeySequence(u'C')], self.slideShortcutActivated,
-                category=unicode(UiStrings().LiveToolbar),
-                context=QtCore.Qt.WidgetWithChildrenShortcut)
-            self.chorusShortcut.setText(translate(
-                'OpenLP.SlideController', 'Go to "Chorus"'))
-            self.bridgeShortcut = shortcut_action(self, u'bridgeShortcut',
-                [QtGui.QKeySequence(u'B')], self.slideShortcutActivated,
-                category=unicode(UiStrings().LiveToolbar),
-                context=QtCore.Qt.WidgetWithChildrenShortcut)
-            self.bridgeShortcut.setText(translate(
-                'OpenLP.SlideController', 'Go to "Bridge"'))
-            self.preChorusShortcut = shortcut_action(self, u'preChorusShortcut',
-                [QtGui.QKeySequence(u'P')], self.slideShortcutActivated,
-                category=unicode(UiStrings().LiveToolbar),
-                context=QtCore.Qt.WidgetWithChildrenShortcut)
-            self.preChorusShortcut.setText(translate(
-                'OpenLP.SlideController', 'Go to "Pre-Chorus"'))
-            self.introShortcut = shortcut_action(self, u'introShortcut',
-                [QtGui.QKeySequence(u'I')], self.slideShortcutActivated,
-                category=unicode(UiStrings().LiveToolbar),
-                context=QtCore.Qt.WidgetWithChildrenShortcut)
-            self.introShortcut.setText(translate(
-                'OpenLP.SlideController', 'Go to "Intro"'))
-            self.endingShortcut = shortcut_action(self, u'endingShortcut',
-                [QtGui.QKeySequence(u'E')], self.slideShortcutActivated,
-                category=unicode(UiStrings().LiveToolbar),
-                context=QtCore.Qt.WidgetWithChildrenShortcut)
-            self.endingShortcut.setText(translate(
-                'OpenLP.SlideController', 'Go to "Ending"'))
-            self.otherShortcut = shortcut_action(self, u'otherShortcut',
-                [QtGui.QKeySequence(u'O')], self.slideShortcutActivated,
-                category=unicode(UiStrings().LiveToolbar),
-                context=QtCore.Qt.WidgetWithChildrenShortcut)
-            self.otherShortcut.setText(translate(
-                'OpenLP.SlideController', 'Go to "Other"'))
-            self.previewListWidget.addActions([
-                self.shortcut0, self.shortcut1, self.shortcut2, self.shortcut3,
-                self.shortcut4, self.shortcut5, self.shortcut6, self.shortcut7,
-                self.shortcut8, self.shortcut9, self.verseShortcut,
-                self.chorusShortcut, self.bridgeShortcut,
-                self.preChorusShortcut, self.introShortcut, self.endingShortcut,
-                self.otherShortcut
-            ])
+            shortcuts = [{u'key': u'V', u'configurable': True,
+                u'text': translate('OpenLP.SlideController', 'Go to "Verse"')},
+                {u'key': u'C', u'configurable': True,
+                u'text': translate('OpenLP.SlideController', 'Go to "Chorus"')},
+                {u'key': u'B', u'configurable': True,
+                u'text': translate('OpenLP.SlideController', 'Go to "Bridge"')},
+                {u'key': u'P', u'configurable': True,
+                u'text': translate('OpenLP.SlideController',
+                'Go to "Pre-Chorus"')},
+                {u'key': u'I', u'configurable': True,
+                u'text': translate('OpenLP.SlideController', 'Go to "Intro"')},
+                {u'key': u'E', u'configurable': True,
+                u'text': translate('OpenLP.SlideController', 'Go to "Ending"')},
+                {u'key': u'O', u'configurable': True,
+                u'text': translate('OpenLP.SlideController', 'Go to "Other"')}]
+            shortcuts += [{u'key': unicode(number)} for number in range(0, 10)]
+            self.previewListWidget.addActions([create_action(self,
+                u'shortcutAction_%s' % s[u'key'], text=s.get(u'text'),
+                shortcuts=[QtGui.QKeySequence(s[u'key'])],
+                context=QtCore.Qt.WidgetWithChildrenShortcut,
+                category=self.category if s.get(u'configurable') else None,
+                triggers=self._slideShortcutActivated) for s in shortcuts])
             QtCore.QObject.connect(
                 self.shortcutTimer, QtCore.SIGNAL(u'timeout()'),
-                self.slideShortcutActivated)
+                self._slideShortcutActivated)
         # Signals
         QtCore.QObject.connect(self.previewListWidget,
             QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
@@ -421,20 +393,18 @@
             QtCore.QObject.connect(Receiver.get_receiver(),
                 QtCore.SIGNAL(u'slidecontroller_toggle_display'),
                 self.toggleDisplay)
-            self.toolbar.makeWidgetsInvisible(self.loopList)
+            self.toolbar.setWidgetVisible(self.loopList, False)
         else:
             QtCore.QObject.connect(self.previewListWidget,
                 QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
                 self.onGoLiveClick)
-            self.toolbar.makeWidgetsInvisible(self.songEditList)
+            self.toolbar.setWidgetVisible([u'editSong'], False)
         if self.isLive:
             self.setLiveHotkeys(self)
             self.__addActionsToWidget(self.previewListWidget)
         else:
-            self.setPreviewHotkeys()
             self.previewListWidget.addActions(
-                [self.nextItem,
-                self.previousItem])
+                [self.nextItem, self.previousItem])
         QtCore.QObject.connect(Receiver.get_receiver(),
             QtCore.SIGNAL(u'slidecontroller_%s_stop_loop' % self.typePrefix),
             self.onStopLoop)
@@ -460,7 +430,7 @@
             QtCore.SIGNAL(u'slidecontroller_update_slide_limits'),
             self.updateSlideLimits)
 
-    def slideShortcutActivated(self):
+    def _slideShortcutActivated(self):
         """
         Called, when a shortcut has been activated to jump to a chorus, verse,
         etc.
@@ -476,52 +446,38 @@
             SONGS_PLUGIN_AVAILABLE = True
         except ImportError:
             SONGS_PLUGIN_AVAILABLE = False
-        verse_type = unicode(self.sender().objectName())
-        if verse_type.startswith(u'verseShortcut'):
-            if SONGS_PLUGIN_AVAILABLE:
+        sender_name = unicode(self.sender().objectName())
+        verse_type = sender_name[15:] \
+            if sender_name[:15] == u'shortcutAction_' else u''
+        if SONGS_PLUGIN_AVAILABLE:
+            if verse_type == u'V':
                 self.current_shortcut = \
                     VerseType.TranslatedTags[VerseType.Verse]
-            else:
-                self.current_shortcut = u'V'
-        elif verse_type.startswith(u'chorusShortcut'):
-            if SONGS_PLUGIN_AVAILABLE:
+            elif verse_type == u'C':
                 self.current_shortcut = \
                     VerseType.TranslatedTags[VerseType.Chorus]
-            else:
-                self.current_shortcut = u'C'
-        elif verse_type.startswith(u'bridgeShortcut'):
-            if SONGS_PLUGIN_AVAILABLE:
+            elif verse_type == u'B':
                 self.current_shortcut = \
                     VerseType.TranslatedTags[VerseType.Bridge]
-            else:
-                self.current_shortcut = u'B'
-        elif verse_type.startswith(u'preChorusShortcut'):
-            if SONGS_PLUGIN_AVAILABLE:
+            elif verse_type == u'P':
                 self.current_shortcut = \
                     VerseType.TranslatedTags[VerseType.PreChorus]
-            else:
-                self.current_shortcut = u'P'
-        elif verse_type.startswith(u'introShortcut'):
-            if SONGS_PLUGIN_AVAILABLE:
+            elif verse_type == u'I':
                 self.current_shortcut = \
                     VerseType.TranslatedTags[VerseType.Intro]
-            else:
-                self.current_shortcut = u'I'
-        elif verse_type.startswith(u'endingShortcut'):
-            if SONGS_PLUGIN_AVAILABLE:
+            elif verse_type == u'E':
                 self.current_shortcut = \
                     VerseType.TranslatedTags[VerseType.Ending]
-            else:
-                self.current_shortcut = u'E'
-        elif verse_type.startswith(u'otherShortcut'):
-            if SONGS_PLUGIN_AVAILABLE:
+            elif verse_type == u'O':
                 self.current_shortcut = \
                     VerseType.TranslatedTags[VerseType.Other]
-            else:
-                self.current_shortcut = u'O'
+            elif verse_type.isnumeric():
+                self.current_shortcut += verse_type
+            self.current_shortcut = self.current_shortcut.upper()
         elif verse_type.isnumeric():
             self.current_shortcut += verse_type
-        self.current_shortcut = self.current_shortcut.upper()
+        elif verse_type:
+            self.current_shortcut = verse_type
         keys = self.slideList.keys()
         matches = [match for match in keys
             if match.startswith(self.current_shortcut)]
@@ -530,7 +486,7 @@
             self.current_shortcut = u''
             self.__checkUpdateSelectedSlide(self.slideList[matches[0]])
             self.slideSelected()
-        elif verse_type != u'shortcutTimer':
+        elif sender_name != u'shortcutTimer':
             # Start the time as we did not have any match.
             self.shortcutTimer.start(350)
         else:
@@ -544,39 +500,22 @@
            # Reset the shortcut.
             self.current_shortcut = u''
 
-    def setPreviewHotkeys(self, parent=None):
-        self.previousItem.setObjectName(u'previousItemPreview')
-        self.nextItem.setObjectName(u'nextItemPreview')
-        action_list = ActionList.get_instance()
-        action_list.add_action(self.previousItem)
-        action_list.add_action(self.nextItem)
-
     def setLiveHotkeys(self, parent=None):
-        self.previousItem.setObjectName(u'previousItemLive')
-        self.nextItem.setObjectName(u'nextItemLive')
-        action_list = ActionList.get_instance()
-        action_list.add_category(
-            unicode(UiStrings().LiveToolbar), CategoryOrder.standardToolbar)
-        action_list.add_action(self.previousItem)
-        action_list.add_action(self.nextItem)
-        self.previousService = shortcut_action(parent, u'previousService',
-            [QtCore.Qt.Key_Left], self.servicePrevious,
-            category=unicode(UiStrings().LiveToolbar),
-            context=QtCore.Qt.WidgetWithChildrenShortcut)
-        self.previousService.setText(
-            translate('OpenLP.SlideController', 'Previous Service'))
-        self.nextService = shortcut_action(parent, 'nextService',
-            [QtCore.Qt.Key_Right], self.serviceNext,
-            category=unicode(UiStrings().LiveToolbar),
-            context=QtCore.Qt.WidgetWithChildrenShortcut)
-        self.nextService.setText(
-            translate('OpenLP.SlideController', 'Next Service'))
-        self.escapeItem = shortcut_action(parent, 'escapeItem',
-            [QtCore.Qt.Key_Escape], self.liveEscape,
-            category=unicode(UiStrings().LiveToolbar),
-            context=QtCore.Qt.WidgetWithChildrenShortcut)
-        self.escapeItem.setText(
-            translate('OpenLP.SlideController', 'Escape Item'))
+        self.previousService = create_action(parent, u'previousService',
+            text=translate('OpenLP.SlideController', 'Previous Service'),
+            shortcuts=[QtCore.Qt.Key_Left],
+            context=QtCore.Qt.WidgetWithChildrenShortcut,
+            category=self.category, triggers=self.servicePrevious)
+        self.nextService = create_action(parent, 'nextService',
+            text=translate('OpenLP.SlideController', 'Next Service'),
+            shortcuts=[QtCore.Qt.Key_Right],
+            context=QtCore.Qt.WidgetWithChildrenShortcut,
+            category=self.category, triggers=self.serviceNext)
+        self.escapeItem = create_action(parent, 'escapeItem',
+            text=translate('OpenLP.SlideController', 'Escape Item'),
+            shortcuts=[QtCore.Qt.Key_Escape],
+            context=QtCore.Qt.WidgetWithChildrenShortcut,
+            category=self.category, triggers=self.liveEscape)
 
     def liveEscape(self):
         self.display.setVisible(False)
@@ -621,7 +560,7 @@
                 self.keypress_loop = True
                 keypressCommand = self.keypress_queue.popleft()
                 if keypressCommand == ServiceItemAction.Previous:
-                    Receiver.send_message('servicemanager_previous_item', None)
+                    Receiver.send_message('servicemanager_previous_item')
                 elif keypressCommand == ServiceItemAction.PreviousLastSlide:
                     # Go to the last slide of the previous item
                     Receiver.send_message('servicemanager_previous_item', u'last slide')
@@ -642,6 +581,8 @@
         self.display.setup()
         if self.isLive:
             self.__addActionsToWidget(self.display)
+            self.display.audioPlayer.connectSlot(
+                QtCore.SIGNAL(u'tick(qint64)'), self.onAudioTimeRemaining)
         # The SlidePreview's ratio.
         try:
             self.ratio = float(self.screens.current[u'size'].width()) / \
@@ -653,7 +594,7 @@
         self.previewDisplay.setup()
         serviceItem = ServiceItem()
         self.previewDisplay.webView.setHtml(build_html(serviceItem,
-            self.previewDisplay.screen, None, self.isLive, None,
+            self.previewDisplay.screen, None, self.isLive,
             plugins=PluginManager.get_instance().plugins))
         self.mediaController.setup_display(self.previewDisplay)
         if self.serviceItem:
@@ -715,7 +656,7 @@
         Adjusts the value of the ``delaySpinBox`` to the given one.
         """
         self.delaySpinBox.setValue(int(value))
-    
+
     def updateSlideLimits(self):
         """
         Updates the Slide Limits variable from the settings.
@@ -741,9 +682,9 @@
         # Work-around for OS X, hide and then show the toolbar
         # See bug #791050
         self.toolbar.hide()
-        self.mediabar.setVisible(False)
-        self.toolbar.makeWidgetsInvisible([u'Song Menu'])
-        self.toolbar.makeWidgetsInvisible(self.loopList)
+        self.mediabar.hide()
+        self.songMenu.hide()
+        self.toolbar.setWidgetVisible(self.loopList, False)
         # Reset the button
         self.playSlidesOnce.setChecked(False)
         self.playSlidesOnce.setIcon(build_icon(u':/media/media_time.png'))
@@ -753,17 +694,16 @@
             if QtCore.QSettings().value(
                 self.parent().songsSettingsSection + u'/display songbar',
                 QtCore.QVariant(True)).toBool() and len(self.slideList) > 0:
-                self.toolbar.makeWidgetsVisible([u'Song Menu'])
+                self.songMenu.show()
         if item.is_capable(ItemCapabilities.CanLoop) and \
             len(item.get_frames()) > 1:
-            self.toolbar.makeWidgetsVisible(self.loopList)
+            self.toolbar.setWidgetVisible(self.loopList)
         if item.is_media():
-            self.mediabar.setVisible(True)
-            self.toolbar.makeWidgetsInvisible(self.nextPreviousList)
-        else:
-            # Work-around for OS X, hide and then show the toolbar
-            # See bug #791050
-            self.toolbar.makeWidgetsVisible(self.nextPreviousList)
+            self.mediabar.show()
+        self.previousItem.setVisible(not item.is_media())
+        self.nextItem.setVisible(not item.is_media())
+        # Work-around for OS X, hide and then show the toolbar
+        # See bug #791050
         self.toolbar.show()
 
     def enablePreviewToolBar(self, item):
@@ -773,17 +713,16 @@
         # Work-around for OS X, hide and then show the toolbar
         # See bug #791050
         self.toolbar.hide()
-        self.mediabar.setVisible(False)
-        self.toolbar.makeWidgetsInvisible(self.songEditList)
+        self.mediabar.hide()
+        self.toolbar.setWidgetVisible([u'editSong'], False)
         if item.is_capable(ItemCapabilities.CanEdit) and item.from_plugin:
-            self.toolbar.makeWidgetsVisible(self.songEditList)
+            self.toolbar.setWidgetVisible([u'editSong'])
         elif item.is_media():
-            self.mediabar.setVisible(True)
-            self.toolbar.makeWidgetsInvisible(self.nextPreviousList)
-        if not item.is_media():
-            # Work-around for OS X, hide and then show the toolbar
-            # See bug #791050
-            self.toolbar.makeWidgetsVisible(self.nextPreviousList)
+            self.mediabar.show()
+        self.previousItem.setVisible(not item.is_media())
+        self.nextItem.setVisible(not item.is_media())
+        # Work-around for OS X, hide and then show the toolbar
+        # See bug #791050
         self.toolbar.show()
 
     def refreshServiceItem(self):
@@ -860,10 +799,23 @@
             self.display.audioPlayer.reset()
             self.setAudioItemsVisibility(False)
             self.audioPauseItem.setChecked(False)
+            # If the current item has background audio
             if self.serviceItem.is_capable(ItemCapabilities.HasBackgroundAudio):
                 log.debug(u'Starting to play...')
                 self.display.audioPlayer.addToPlaylist(
                     self.serviceItem.background_audio)
+                self.trackMenu.clear()
+                for counter in range(len(self.serviceItem.background_audio)):
+                    action = self.trackMenu.addAction(os.path.basename(
+                        self.serviceItem.background_audio[counter]))
+                    action.setData(counter)
+                    QtCore.QObject.connect(action,
+                        QtCore.SIGNAL(u'triggered(bool)'),
+                        self.onTrackTriggered)
+                self.display.audioPlayer.repeat = QtCore.QSettings().value(
+                    self.parent().generalSettingsSection + \
+                        u'/audio repeat list',
+                    QtCore.QVariant(False)).toBool()
                 if QtCore.QSettings().value(
                     self.parent().generalSettingsSection + \
                         u'/audio start paused',
@@ -915,7 +867,7 @@
                 self.slideList[unicode(row)] = row - 1
             text.append(unicode(row))
             self.previewListWidget.setItem(framenumber, 0, item)
-            if slideHeight != 0:
+            if slideHeight:
                 self.previewListWidget.setRowHeight(framenumber, slideHeight)
         self.previewListWidget.setVerticalHeaderLabels(text)
         if self.serviceItem.is_text():
@@ -1117,7 +1069,7 @@
             else:
                 Receiver.send_message(u'live_display_show')
 
-    def onSlideSelected(self, start=False):
+    def onSlideSelected(self):
         """
         Slide selected in controller
         """
@@ -1130,7 +1082,7 @@
         """
         row = self.previewListWidget.currentRow()
         self.selectedRow = 0
-        if row > -1 and row < self.previewListWidget.rowCount():
+        if -1 < row < self.previewListWidget.rowCount():
             if self.serviceItem.is_command():
                 if self.isLive and not start:
                     Receiver.send_message(
@@ -1266,7 +1218,7 @@
         """
         Stop the timer loop running
         """
-        if self.timer_id != 0:
+        if self.timer_id:
             self.killTimer(self.timer_id)
             self.timer_id = 0
 
@@ -1313,7 +1265,7 @@
         self.onToggleLoop()
 
     def setAudioItemsVisibility(self, visible):
-        self.audioPauseItem.setVisible(visible)
+        self.toolbar.setWidgetVisible(self.audioList, visible)
 
     def onAudioPauseClicked(self, checked):
         if not self.audioPauseItem.isVisible():
@@ -1367,7 +1319,7 @@
         If preview copy slide item to live
         """
         row = self.previewListWidget.currentRow()
-        if row > -1 and row < self.previewListWidget.rowCount():
+        if -1 < row < self.previewListWidget.rowCount():
             if self.serviceItem.from_service:
                 Receiver.send_message('servicemanager_preview_live',
                     u'%s:%s' % (self.serviceItem._uuid, row))
@@ -1424,3 +1376,17 @@
             return HideMode.Screen
         else:
             return None
+
+    def onNextTrackClicked(self):
+        self.display.audioPlayer.next()
+
+    def onAudioTimeRemaining(self, time):
+        seconds = self.display.audioPlayer.mediaObject.remainingTime() // 1000
+        minutes = seconds // 60
+        seconds %= 60
+        self.audioTimeLabel.setText(u' %02d:%02d ' % (minutes, seconds))
+
+    def onTrackTriggered(self):
+        action = self.sender()
+        index = action.data().toInt()[0]
+        self.display.audioPlayer.goTo(index)

=== modified file 'openlp/core/ui/thememanager.py'
--- openlp/core/ui/thememanager.py	2012-01-18 13:50:06 +0000
+++ openlp/core/ui/thememanager.py	2012-03-05 10:15:33 +0000
@@ -41,7 +41,7 @@
 from openlp.core.lib.theme import ThemeXML, BackgroundType, VerticalType, \
     BackgroundGradientType
 from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
-    context_menu_action, context_menu_separator
+    create_widget_action
 from openlp.core.theme import Theme
 from openlp.core.ui import FileRenameForm, ThemeForm
 from openlp.core.utils import AppLocation, delete_file, get_filesystem_encoding
@@ -64,32 +64,32 @@
         self.layout.setMargin(0)
         self.layout.setObjectName(u'layout')
         self.toolbar = OpenLPToolbar(self)
-        self.toolbar.addToolbarButton(UiStrings().NewTheme,
-            u':/themes/theme_new.png',
-            translate('OpenLP.ThemeManager', 'Create a new theme.'),
-            self.onAddTheme)
-        self.toolbar.addToolbarButton(
-            translate('OpenLP.ThemeManager', 'Edit Theme'),
-            u':/themes/theme_edit.png',
-            translate('OpenLP.ThemeManager', 'Edit a theme.'),
-            self.onEditTheme)
-        self.deleteToolbarAction = self.toolbar.addToolbarButton(
-            translate('OpenLP.ThemeManager', 'Delete Theme'),
-            u':/general/general_delete.png',
-            translate('OpenLP.ThemeManager', 'Delete a theme.'),
-            self.onDeleteTheme)
+        self.toolbar.setObjectName(u'toolbar')
+        self.toolbar.addToolbarAction(u'newTheme',
+            text=UiStrings().NewTheme, icon=u':/themes/theme_new.png',
+            tooltip=translate('OpenLP.ThemeManager', 'Create a new theme.'),
+            triggers=self.onAddTheme)
+        self.toolbar.addToolbarAction(u'editTheme',
+            text=translate('OpenLP.ThemeManager', 'Edit Theme'),
+            icon=u':/themes/theme_edit.png',
+            tooltip=translate('OpenLP.ThemeManager', 'Edit a theme.'),
+            triggers=self.onEditTheme)
+        self.deleteToolbarAction = self.toolbar.addToolbarAction(u'deleteTheme',
+            text=translate('OpenLP.ThemeManager', 'Delete Theme'),
+            icon=u':/general/general_delete.png',
+            tooltip=translate('OpenLP.ThemeManager', 'Delete a theme.'),
+            triggers=self.onDeleteTheme)
         self.toolbar.addSeparator()
-        self.toolbar.addToolbarButton(
-            translate('OpenLP.ThemeManager', 'Import Theme'),
-            u':/general/general_import.png',
-            translate('OpenLP.ThemeManager', 'Import a theme.'),
-            self.onImportTheme)
-        self.toolbar.addToolbarButton(
-            translate('OpenLP.ThemeManager', 'Export Theme'),
-            u':/general/general_export.png',
-            translate('OpenLP.ThemeManager', 'Export a theme.'),
-            self.onExportTheme)
-        self.toolbar.setObjectName(u'toolbar')
+        self.toolbar.addToolbarAction(u'importTheme',
+            text=translate('OpenLP.ThemeManager', 'Import Theme'),
+            icon=u':/general/general_import.png',
+            tooltip=translate('OpenLP.ThemeManager', 'Import a theme.'),
+            triggers=self.onImportTheme)
+        self.toolbar.addToolbarAction(u'exportTheme',
+            text=translate('OpenLP.ThemeManager', 'Export Theme'),
+            icon=u':/general/general_export.png',
+            tooltip=translate('OpenLP.ThemeManager', 'Export a theme.'),
+            triggers=self.onExportTheme)
         self.layout.addWidget(self.toolbar)
         self.themeWidget = QtGui.QWidgetAction(self.toolbar)
         self.themeWidget.setObjectName(u'themeWidget')
@@ -105,29 +105,26 @@
             self.contextMenu)
         # build the context menu
         self.menu = QtGui.QMenu()
-        self.editAction = context_menu_action(
-            self.menu, u':/themes/theme_edit.png',
-            translate('OpenLP.ThemeManager', '&Edit Theme'), self.onEditTheme)
-        self.copyAction = context_menu_action(
-            self.menu, u':/themes/theme_edit.png',
-            translate('OpenLP.ThemeManager', '&Copy Theme'), self.onCopyTheme)
-        self.renameAction = context_menu_action(
-            self.menu, u':/themes/theme_edit.png',
-            translate('OpenLP.ThemeManager', '&Rename Theme'),
-            self.onRenameTheme)
-        self.deleteAction = context_menu_action(
-            self.menu, u':/general/general_delete.png',
-            translate('OpenLP.ThemeManager', '&Delete Theme'),
-            self.onDeleteTheme)
-        context_menu_separator(self.menu)
-        self.globalAction = context_menu_action(
-            self.menu, u':/general/general_export.png',
-            translate('OpenLP.ThemeManager', 'Set As &Global Default'),
-            self.changeGlobalFromScreen)
-        self.exportAction = context_menu_action(
-            self.menu, u':/general/general_export.png',
-            translate('OpenLP.ThemeManager', '&Export Theme'),
-            self.onExportTheme)
+        self.editAction = create_widget_action(self.menu,
+            text=translate('OpenLP.ThemeManager', '&Edit Theme'),
+            icon=u':/themes/theme_edit.png', triggers=self.onEditTheme)
+        self.copyAction = create_widget_action(self.menu,
+            text=translate('OpenLP.ThemeManager', '&Copy Theme'),
+            icon=u':/themes/theme_edit.png', triggers=self.onCopyTheme)
+        self.renameAction = create_widget_action(self.menu,
+            text=translate('OpenLP.ThemeManager', '&Rename Theme'),
+            icon=u':/themes/theme_edit.png', triggers=self.onRenameTheme)
+        self.deleteAction = create_widget_action(self.menu,
+            text=translate('OpenLP.ThemeManager', '&Delete Theme'),
+            icon=u':/general/general_delete.png', triggers=self.onDeleteTheme)
+        self.menu.addSeparator()
+        self.globalAction = create_widget_action(self.menu,
+            text=translate('OpenLP.ThemeManager', 'Set As &Global Default'),
+            icon=u':/general/general_export.png',
+            triggers=self.changeGlobalFromScreen)
+        self.exportAction = create_widget_action(self.menu,
+            text=translate('OpenLP.ThemeManager', '&Export Theme'),
+            icon=u':/general/general_export.png', triggers=self.onExportTheme)
         # Signals
         QtCore.QObject.connect(self.themeListWidget,
             QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
@@ -544,7 +541,7 @@
                         log.exception(u'Theme file contains non utf-8 filename'
                             u' "%s"' % name.decode(u'utf-8', u'replace'))
                         raise Exception(u'validation')
-                    uname = unicode(QtCore.QDir.toNativeSeparators(uname))
+                    uname = uname.replace(u'/', os.path.sep)
                     splitname = uname.split(os.path.sep)
                     if splitname[-1] == u'' or len(splitname) == 1:
                         # is directory or preview file

=== modified file 'openlp/core/ui/themestab.py'
--- openlp/core/ui/themestab.py	2011-12-27 10:33:55 +0000
+++ openlp/core/ui/themestab.py	2012-03-05 10:15:33 +0000
@@ -39,7 +39,7 @@
         self.mainwindow = mainwindow
         generalTranslated = translate('OpenLP.ThemesTab', 'Themes')
         SettingsTab.__init__(self, parent, u'Themes', generalTranslated)
-        self.icon_path =  u':/themes/theme_new.png'
+        self.icon_path = u':/themes/theme_new.png'
 
     def setupUi(self):
         self.setObjectName(u'ThemesTab')

=== modified file 'openlp/core/utils/actions.py'
--- openlp/core/utils/actions.py	2011-12-31 17:36:58 +0000
+++ openlp/core/utils/actions.py	2012-03-05 10:15:33 +0000
@@ -281,7 +281,7 @@
             return
         self.categories[category].actions.remove(action)
         # Remove empty categories.
-        if len(self.categories[category].actions) == 0:
+        if not self.categories[category].actions:
             self.categories.remove(category)
         shortcuts = map(unicode,
             map(QtGui.QKeySequence.toString, action.shortcuts()))
@@ -354,18 +354,31 @@
         ``action``
             The action which wants to use a particular shortcut.
         """
+        local = action.shortcutContext() in \
+            [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]
+        affected_actions = filter(lambda a: isinstance(a, QtGui.QAction),
+            self.getAllChildObjects(action.parent())) if local else []
         for existing_action in existing_actions:
             if action is existing_action:
                 continue
-            if existing_action.parent() is action.parent():
-                return False
-            if existing_action.shortcutContext() in [QtCore.Qt.WindowShortcut,
-                QtCore.Qt.ApplicationShortcut]:
-                return False
-            if action.shortcutContext() in [QtCore.Qt.WindowShortcut,
-                QtCore.Qt.ApplicationShortcut]:
+            if not local or existing_action in affected_actions:
+                return False
+            if existing_action.shortcutContext() \
+                in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
+                return False
+            elif action in self.getAllChildObjects(existing_action.parent()):
                 return False
         return True
+    
+    def getAllChildObjects(self, qobject):
+        """
+        Goes recursively through the children of ``qobject`` and returns a list
+        of all child objects.
+        """
+        children = [child for child in qobject.children()]
+        for child in qobject.children():
+            children.append(self.getAllChildObjects(child))
+        return children
 
 
 class CategoryOrder(object):

=== modified file 'openlp/plugins/alerts/alertsplugin.py'
--- openlp/plugins/alerts/alertsplugin.py	2011-12-27 10:33:55 +0000
+++ openlp/plugins/alerts/alertsplugin.py	2012-03-05 10:15:33 +0000
@@ -31,7 +31,7 @@
 
 from openlp.core.lib import Plugin, StringContent, build_icon, translate
 from openlp.core.lib.db import Manager
-from openlp.core.lib.ui import icon_action, UiStrings
+from openlp.core.lib.ui import create_action, UiStrings
 from openlp.core.lib.theme import VerticalType
 from openlp.core.utils.actions import ActionList
 from openlp.plugins.alerts.lib import AlertsManager, AlertsTab
@@ -133,16 +133,12 @@
             use it as their parent.
         """
         log.info(u'add tools menu')
-        self.toolsAlertItem = icon_action(tools_menu, u'toolsAlertItem',
-            u':/plugins/plugin_alerts.png')
-        self.toolsAlertItem.setText(translate('AlertsPlugin', '&Alert'))
-        self.toolsAlertItem.setStatusTip(
-            translate('AlertsPlugin', 'Show an alert message.'))
-        self.toolsAlertItem.setShortcut(u'F7')
+        self.toolsAlertItem = create_action(tools_menu, u'toolsAlertItem',
+            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)
-        QtCore.QObject.connect(self.toolsAlertItem,
-            QtCore.SIGNAL(u'triggered()'), self.onAlertsTrigger)
-        self.toolsAlertItem.setVisible(False)
 
     def initialise(self):
         log.info(u'Alerts Initialising')

=== modified file 'openlp/plugins/bibles/bibleplugin.py'
--- openlp/plugins/bibles/bibleplugin.py	2011-12-27 10:33:55 +0000
+++ openlp/plugins/bibles/bibleplugin.py	2012-03-05 10:15:33 +0000
@@ -30,7 +30,7 @@
 from PyQt4 import QtCore, QtGui
 
 from openlp.core.lib import Plugin, StringContent, build_icon, translate
-from openlp.core.lib.ui import base_action, UiStrings
+from openlp.core.lib.ui import create_action, UiStrings
 from openlp.core.utils.actions import ActionList
 from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem
 from openlp.plugins.bibles.forms import BibleUpgradeForm
@@ -93,19 +93,16 @@
                 self.onToolsUpgradeItemTriggered()
 
     def addImportMenuItem(self, import_menu):
-        self.importBibleItem = base_action(import_menu, u'importBibleItem')
-        self.importBibleItem.setText(translate('BiblesPlugin', '&Bible'))
+        self.importBibleItem = create_action(import_menu, u'importBibleItem',
+            text=translate('BiblesPlugin', '&Bible'), visible=False,
+            triggers=self.onBibleImportClick)
         import_menu.addAction(self.importBibleItem)
-        # signals and slots
-        QtCore.QObject.connect(self.importBibleItem,
-            QtCore.SIGNAL(u'triggered()'), self.onBibleImportClick)
-        self.importBibleItem.setVisible(False)
 
     def addExportMenuItem(self, export_menu):
-        self.exportBibleItem = base_action(export_menu, u'exportBibleItem')
-        self.exportBibleItem.setText(translate('BiblesPlugin', '&Bible'))
+        self.exportBibleItem = create_action(export_menu, u'exportBibleItem',
+            text=translate('BiblesPlugin', '&Bible'),
+            visible=False)
         export_menu.addAction(self.exportBibleItem)
-        self.exportBibleItem.setVisible(False)
 
     def addToolsMenuItem(self, tools_menu):
         """
@@ -117,17 +114,12 @@
             use it as their parent.
         """
         log.debug(u'add tools menu')
-        self.toolsUpgradeItem = QtGui.QAction(tools_menu)
-        self.toolsUpgradeItem.setObjectName(u'toolsUpgradeItem')
-        self.toolsUpgradeItem.setText(
-            translate('BiblesPlugin', '&Upgrade older Bibles'))
-        self.toolsUpgradeItem.setStatusTip(
-            translate('BiblesPlugin', 'Upgrade the Bible databases to the '
-            'latest format.'))
+        self.toolsUpgradeItem = create_action(tools_menu, u'toolsUpgradeItem',
+            text=translate('BiblesPlugin', '&Upgrade older Bibles'),
+            statustip=translate('BiblesPlugin',
+            'Upgrade the Bible databases to the latest format.'),
+            visible=False, triggers=self.onToolsUpgradeItemTriggered)
         tools_menu.addAction(self.toolsUpgradeItem)
-        QtCore.QObject.connect(self.toolsUpgradeItem,
-            QtCore.SIGNAL(u'triggered()'), self.onToolsUpgradeItemTriggered)
-        self.toolsUpgradeItem.setVisible(False)
 
     def onToolsUpgradeItemTriggered(self):
         """

=== modified file 'openlp/plugins/bibles/lib/__init__.py'
--- openlp/plugins/bibles/lib/__init__.py	2012-02-05 19:20:01 +0000
+++ openlp/plugins/bibles/lib/__init__.py	2012-03-05 10:15:33 +0000
@@ -89,7 +89,7 @@
         while u'||' in source_string:
             source_string = source_string.replace(u'||', u'|')
         if role != u'e':
-            REFERENCE_SEPARATORS[u'sep_%s_display' % role] =  \
+            REFERENCE_SEPARATORS[u'sep_%s_display' % role] = \
                 source_string.split(u'|')[0]
         # escape reserved characters
         for character in u'\\.^$*+?{}[]()':

=== modified file 'openlp/plugins/custom/lib/mediaitem.py'
--- openlp/plugins/custom/lib/mediaitem.py	2012-01-18 13:50:06 +0000
+++ openlp/plugins/custom/lib/mediaitem.py	2012-03-05 10:15:33 +0000
@@ -68,7 +68,7 @@
         self.manager = plugin.manager
 
     def addEndHeaderBar(self):
-        self.addToolbarSeparator()
+        self.toolbar.addSeparator()
         self.addSearchToToolBar()
         # Signals and slots
         QtCore.QObject.connect(self.searchTextEdit,

=== modified file 'openlp/plugins/images/lib/mediaitem.py'
--- openlp/plugins/images/lib/mediaitem.py	2012-01-18 13:50:06 +0000
+++ openlp/plugins/images/lib/mediaitem.py	2012-03-05 10:15:33 +0000
@@ -89,11 +89,11 @@
         self.listView.addAction(self.replaceAction)
 
     def addEndHeaderBar(self):
-        self.replaceAction = self.addToolbarButton(u'', u'',
-            u':/slides/slide_blank.png', self.onReplaceClick, False)
-        self.resetAction = self.addToolbarButton(u'', u'',
-            u':/system/system_close.png', self.onResetClick, False)
-        self.resetAction.setVisible(False)
+        self.replaceAction = self.toolbar.addToolbarAction(u'replaceAction',
+            icon=u':/slides/slide_blank.png', triggers=self.onReplaceClick)
+        self.resetAction = self.toolbar.addToolbarAction(u'resetAction',
+            icon=u':/system/system_close.png', visible=False,
+            triggers=self.onResetClick)
 
     def onDeleteClick(self):
         """

=== modified file 'openlp/plugins/media/lib/mediaitem.py'
--- openlp/plugins/media/lib/mediaitem.py	2012-01-18 13:50:06 +0000
+++ openlp/plugins/media/lib/mediaitem.py	2012-03-05 10:15:33 +0000
@@ -118,11 +118,11 @@
 
     def addEndHeaderBar(self):
         # Replace backgrounds do not work at present so remove functionality.
-        self.replaceAction = self.addToolbarButton(u'', u'',
-            u':/slides/slide_blank.png', self.onReplaceClick, False)
-        self.resetAction = self.addToolbarButton(u'', u'',
-            u':/system/system_close.png', self.onResetClick, False)
-        self.resetAction.setVisible(False)
+        self.replaceAction = self.toolbar.addToolbarAction(u'replaceAction',
+            icon=u':/slides/slide_blank.png', triggers=self.onReplaceClick)
+        self.resetAction = self.toolbar.addToolbarAction(u'resetAction',
+            icon=u':/system/system_close.png', visible=False,
+            triggers=self.onResetClick)
         self.mediaWidget = QtGui.QWidget(self)
         self.mediaWidget.setObjectName(u'mediaWidget')
         self.displayLayout = QtGui.QFormLayout(self.mediaWidget)

=== modified file 'openlp/plugins/songs/lib/mediaitem.py'
--- openlp/plugins/songs/lib/mediaitem.py	2012-02-26 21:27:05 +0000
+++ openlp/plugins/songs/lib/mediaitem.py	2012-03-05 10:15:33 +0000
@@ -36,8 +36,7 @@
 
 from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \
     translate, check_item_selected, PluginStatus, create_separated_list
-from openlp.core.lib.ui import UiStrings, context_menu_action, \
-    context_menu_separator
+from openlp.core.lib.ui import UiStrings, create_action, create_widget_action
 from openlp.core.utils import AppLocation
 from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \
     SongImportForm, SongExportForm
@@ -99,10 +98,11 @@
         self.plugin.manager.save_object(song, True)
 
     def addEndHeaderBar(self):
-        self.addToolbarSeparator()
+        self.toolbar.addSeparator()
         ## Song Maintenance Button ##
-        self.maintenanceAction = self.addToolbarButton(u'', u'',
-            ':/songs/song_maintenance.png', self.onSongMaintenanceClick)
+        self.maintenanceAction = self.toolbar.addToolbarAction(
+            u'maintenanceAction', icon=':/songs/song_maintenance.png',
+            triggers=self.onSongMaintenanceClick)
         self.addSearchToToolBar()
         # Signals and slots
         QtCore.QObject.connect(Receiver.get_receiver(),
@@ -122,11 +122,10 @@
             self.onSearchTextButtonClick)
 
     def addCustomContextActions(self):
-        context_menu_separator(self.listView)
-        context_menu_action(
-            self.listView, u':/general/general_clone.png',
-            translate('OpenLP.MediaManagerItem',
-            '&Clone'), self.onCloneClick)
+        create_widget_action(self.listView, separator=True)
+        create_widget_action(self.listView,
+            text=translate('OpenLP.MediaManagerItem', '&Clone'),
+            icon=u':/general/general_clone.png', triggers=self.onCloneClick)
 
     def onFocus(self):
         self.searchTextEdit.setFocus()

=== modified file 'openlp/plugins/songs/lib/opensongimport.py'
--- openlp/plugins/songs/lib/opensongimport.py	2011-12-27 10:33:55 +0000
+++ openlp/plugins/songs/lib/opensongimport.py	2012-03-05 10:15:33 +0000
@@ -238,7 +238,7 @@
                     verse_tag = match.group(1)
                     verse_num = match.group(2)
                     if not len(verse_tag):
-                        verse_tag =  VerseType.Tags[VerseType.Verse]
+                        verse_tag = VerseType.Tags[VerseType.Verse]
                 else:
                     # Assume it's no.1 if there are no digits
                     verse_tag = verse_def

=== modified file 'openlp/plugins/songs/lib/songstab.py'
--- openlp/plugins/songs/lib/songstab.py	2011-12-27 10:33:55 +0000
+++ openlp/plugins/songs/lib/songstab.py	2012-03-05 10:15:33 +0000
@@ -33,56 +33,56 @@
     """
     SongsTab is the Songs settings tab in the settings dialog.
     """
-    def __init__(self, parent, title, visible_title, icon_path):
-        SettingsTab.__init__(self, parent, title, visible_title, icon_path)
-
     def setupUi(self):
+        """
+        Set up the configuration tab UI.
+        """
         self.setObjectName(u'SongsTab')
         SettingsTab.setupUi(self)
-        self.SongsModeGroupBox = QtGui.QGroupBox(self.leftColumn)
-        self.SongsModeGroupBox.setObjectName(u'SongsModeGroupBox')
-        self.SongsModeLayout = QtGui.QVBoxLayout(self.SongsModeGroupBox)
-        self.SongsModeLayout.setObjectName(u'SongsModeLayout')
-        self.SearchAsTypeCheckBox = QtGui.QCheckBox(self.SongsModeGroupBox)
-        self.SearchAsTypeCheckBox.setObjectName(u'SearchAsTypeCheckBox')
-        self.SongsModeLayout.addWidget(self.SearchAsTypeCheckBox)
-        self.SongBarActiveCheckBox = QtGui.QCheckBox(self.SongsModeGroupBox)
-        self.SongBarActiveCheckBox.setObjectName(u'SongBarActiveCheckBox')
-        self.SongsModeLayout.addWidget(self.SongBarActiveCheckBox)
-        self.SongUpdateOnEditCheckBox = QtGui.QCheckBox(self.SongsModeGroupBox)
-        self.SongUpdateOnEditCheckBox.setObjectName(u'SongUpdateOnEditCheckBox')
-        self.SongsModeLayout.addWidget(self.SongUpdateOnEditCheckBox)
-        self.SongAddFromServiceCheckBox = QtGui.QCheckBox(
-            self.SongsModeGroupBox)
-        self.SongAddFromServiceCheckBox.setObjectName(
-            u'SongAddFromServiceCheckBox')
-        self.SongsModeLayout.addWidget(self.SongAddFromServiceCheckBox)
-        self.leftLayout.addWidget(self.SongsModeGroupBox)
+        self.modeGroupBox = QtGui.QGroupBox(self.leftColumn)
+        self.modeGroupBox.setObjectName(u'modeGroupBox')
+        self.modeLayout = QtGui.QVBoxLayout(self.modeGroupBox)
+        self.modeLayout.setObjectName(u'modeLayout')
+        self.searchAsTypeCheckBox = QtGui.QCheckBox(self.modeGroupBox)
+        self.searchAsTypeCheckBox.setObjectName(u'SearchAsTypeCheckBox')
+        self.modeLayout.addWidget(self.searchAsTypeCheckBox)
+        self.toolBarActiveCheckBox = QtGui.QCheckBox(self.modeGroupBox)
+        self.toolBarActiveCheckBox.setObjectName(u'toolBarActiveCheckBox')
+        self.modeLayout.addWidget(self.toolBarActiveCheckBox)
+        self.updateOnEditCheckBox = QtGui.QCheckBox(self.modeGroupBox)
+        self.updateOnEditCheckBox.setObjectName(u'updateOnEditCheckBox')
+        self.modeLayout.addWidget(self.updateOnEditCheckBox)
+        self.addFromServiceCheckBox = QtGui.QCheckBox(
+            self.modeGroupBox)
+        self.addFromServiceCheckBox.setObjectName(
+            u'addFromServiceCheckBox')
+        self.modeLayout.addWidget(self.addFromServiceCheckBox)
+        self.leftLayout.addWidget(self.modeGroupBox)
         self.leftLayout.addStretch()
         self.rightLayout.addStretch()
-        QtCore.QObject.connect(self.SearchAsTypeCheckBox,
+        QtCore.QObject.connect(self.searchAsTypeCheckBox,
             QtCore.SIGNAL(u'stateChanged(int)'),
             self.onSearchAsTypeCheckBoxChanged)
-        QtCore.QObject.connect(self.SongBarActiveCheckBox,
-            QtCore.SIGNAL(u'stateChanged(int)'),
-            self.onSongBarActiveCheckBoxChanged)
-        QtCore.QObject.connect(self.SongUpdateOnEditCheckBox,
-            QtCore.SIGNAL(u'stateChanged(int)'),
-            self.onSongUpdateOnEditCheckBoxChanged)
-        QtCore.QObject.connect(self.SongAddFromServiceCheckBox,
-            QtCore.SIGNAL(u'stateChanged(int)'),
-            self.onSongAddFromServiceCheckBoxChanged)
+        QtCore.QObject.connect(self.toolBarActiveCheckBox,
+            QtCore.SIGNAL(u'stateChanged(int)'),
+            self.onToolBarActiveCheckBoxChanged)
+        QtCore.QObject.connect(self.updateOnEditCheckBox,
+            QtCore.SIGNAL(u'stateChanged(int)'),
+            self.onUpdateOnEditCheckBoxChanged)
+        QtCore.QObject.connect(self.addFromServiceCheckBox,
+            QtCore.SIGNAL(u'stateChanged(int)'),
+            self.onAddFromServiceCheckBoxChanged)
 
     def retranslateUi(self):
-        self.SongsModeGroupBox.setTitle(
+        self.modeGroupBox.setTitle(
             translate('SongsPlugin.SongsTab', 'Songs Mode'))
-        self.SearchAsTypeCheckBox.setText(
+        self.searchAsTypeCheckBox.setText(
             translate('SongsPlugin.SongsTab', 'Enable search as you type'))
-        self.SongBarActiveCheckBox.setText(translate('SongsPlugin.SongsTab',
+        self.toolBarActiveCheckBox.setText(translate('SongsPlugin.SongsTab',
             'Display verses on live tool bar'))
-        self.SongUpdateOnEditCheckBox.setText(
+        self.updateOnEditCheckBox.setText(
             translate('SongsPlugin.SongsTab', 'Update service from song edit'))
-        self.SongAddFromServiceCheckBox.setText(
+        self.addFromServiceCheckBox.setText(
             translate('SongsPlugin.SongsTab',
             'Add missing songs when opening service'))
 
@@ -92,19 +92,19 @@
         if check_state == QtCore.Qt.Checked:
             self.song_search = True
 
-    def onSongBarActiveCheckBoxChanged(self, check_state):
-        self.song_bar = False
+    def onToolBarActiveCheckBoxChanged(self, check_state):
+        self.tool_bar = False
         # we have a set value convert to True/False
         if check_state == QtCore.Qt.Checked:
-            self.song_bar = True
+            self.tool_bar = True
 
-    def onSongUpdateOnEditCheckBoxChanged(self, check_state):
+    def onUpdateOnEditCheckBoxChanged(self, check_state):
         self.update_edit = False
         # we have a set value convert to True/False
         if check_state == QtCore.Qt.Checked:
             self.update_edit = True
 
-    def onSongAddFromServiceCheckBoxChanged(self, check_state):
+    def onAddFromServiceCheckBoxChanged(self, check_state):
         self.update_load = False
         # we have a set value convert to True/False
         if check_state == QtCore.Qt.Checked:
@@ -115,23 +115,23 @@
         settings.beginGroup(self.settingsSection)
         self.song_search = settings.value(
             u'search as type', QtCore.QVariant(False)).toBool()
-        self.song_bar = settings.value(
+        self.tool_bar = settings.value(
             u'display songbar', QtCore.QVariant(True)).toBool()
         self.update_edit = settings.value(
             u'update service on edit', QtCore.QVariant(False)).toBool()
         self.update_load = settings.value(
             u'add song from service', QtCore.QVariant(True)).toBool()
-        self.SearchAsTypeCheckBox.setChecked(self.song_search)
-        self.SongBarActiveCheckBox.setChecked(self.song_bar)
-        self.SongUpdateOnEditCheckBox.setChecked(self.update_edit)
-        self.SongAddFromServiceCheckBox.setChecked(self.update_load)
+        self.searchAsTypeCheckBox.setChecked(self.song_search)
+        self.toolBarActiveCheckBox.setChecked(self.tool_bar)
+        self.updateOnEditCheckBox.setChecked(self.update_edit)
+        self.addFromServiceCheckBox.setChecked(self.update_load)
         settings.endGroup()
 
     def save(self):
         settings = QtCore.QSettings()
         settings.beginGroup(self.settingsSection)
         settings.setValue(u'search as type', QtCore.QVariant(self.song_search))
-        settings.setValue(u'display songbar', QtCore.QVariant(self.song_bar))
+        settings.setValue(u'display songbar', QtCore.QVariant(self.tool_bar))
         settings.setValue(u'update service on edit',
             QtCore.QVariant(self.update_edit))
         settings.setValue(u'add song from service',

=== modified file 'openlp/plugins/songs/songsplugin.py'
--- openlp/plugins/songs/songsplugin.py	2011-12-27 10:33:55 +0000
+++ openlp/plugins/songs/songsplugin.py	2012-03-05 10:15:33 +0000
@@ -34,7 +34,7 @@
 from openlp.core.lib import Plugin, StringContent, build_icon, translate, \
     Receiver
 from openlp.core.lib.db import Manager
-from openlp.core.lib.ui import UiStrings, base_action, icon_action
+from openlp.core.lib.ui import UiStrings, create_action
 from openlp.core.utils.actions import ActionList
 from openlp.plugins.songs.lib import clean_song, upgrade, SongMediaItem, \
     SongsTab
@@ -93,14 +93,12 @@
             use it as their parent.
         """
         # Main song import menu item - will eventually be the only one
-        self.songImportItem = base_action(import_menu, u'songImportItem')
-        self.songImportItem.setText(translate('SongsPlugin', '&Song'))
-        self.songImportItem.setToolTip(translate('SongsPlugin',
-            'Import songs using the import wizard.'))
+        self.songImportItem = create_action(import_menu, u'songImportItem',
+            text=translate('SongsPlugin', '&Song'),
+            tooltip=translate('SongsPlugin',
+            'Import songs using the import wizard.'),
+            triggers=self.onSongImportItemClicked)
         import_menu.addAction(self.songImportItem)
-        # Signals and slots
-        QtCore.QObject.connect(self.songImportItem,
-            QtCore.SIGNAL(u'triggered()'), self.onSongImportItemClicked)
 
     def addExportMenuItem(self, export_menu):
         """
@@ -112,14 +110,12 @@
             use it as their parent.
         """
         # Main song import menu item - will eventually be the only one
-        self.songExportItem = base_action(export_menu, u'songExportItem')
-        self.songExportItem.setText(translate('SongsPlugin', '&Song'))
-        self.songExportItem.setToolTip(translate('SongsPlugin',
-            'Exports songs using the export wizard.'))
+        self.songExportItem = create_action(export_menu, u'songExportItem',
+            text=translate('SongsPlugin', '&Song'),
+            tooltip=translate('SongsPlugin',
+            'Exports songs using the export wizard.'),
+            triggers=self.onSongExportItemClicked)
         export_menu.addAction(self.songExportItem)
-        # Signals and slots
-        QtCore.QObject.connect(self.songExportItem,
-            QtCore.SIGNAL(u'triggered()'), self.onSongExportItemClicked)
 
     def addToolsMenuItem(self, tools_menu):
         """
@@ -131,17 +127,13 @@
             use it as their parent.
         """
         log.info(u'add tools menu')
-        self.toolsReindexItem = icon_action(tools_menu, u'toolsReindexItem',
-            u':/plugins/plugin_songs.png')
-        self.toolsReindexItem.setText(
-            translate('SongsPlugin', '&Re-index Songs'))
-        self.toolsReindexItem.setStatusTip(
-            translate('SongsPlugin', 'Re-index the songs database to improve '
-            'searching and ordering.'))
+        self.toolsReindexItem = create_action(tools_menu, u'toolsReindexItem',
+            text=translate('SongsPlugin', '&Re-index Songs'),
+            icon=u':/plugins/plugin_songs.png',
+            statustip=translate('SongsPlugin',
+            'Re-index the songs database to improve searching and ordering.'),
+            visible=False, triggers=self.onToolsReindexItemTriggered)
         tools_menu.addAction(self.toolsReindexItem)
-        QtCore.QObject.connect(self.toolsReindexItem,
-            QtCore.SIGNAL(u'triggered()'), self.onToolsReindexItemTriggered)
-        self.toolsReindexItem.setVisible(False)
 
     def onToolsReindexItemTriggered(self):
         """

=== modified file 'openlp/plugins/songusage/songusageplugin.py'
--- openlp/plugins/songusage/songusageplugin.py	2011-12-27 10:33:55 +0000
+++ openlp/plugins/songusage/songusageplugin.py	2012-03-05 10:15:33 +0000
@@ -33,7 +33,7 @@
 from openlp.core.lib import Plugin, StringContent, Receiver, build_icon, \
     translate
 from openlp.core.lib.db import Manager
-from openlp.core.lib.ui import base_action, shortcut_action
+from openlp.core.lib.ui import create_action
 from openlp.core.utils.actions import ActionList
 from openlp.plugins.songusage.forms import SongUsageDetailForm, \
     SongUsageDeleteForm
@@ -73,24 +73,24 @@
         self.songUsageMenu.setTitle(translate(
             'SongUsagePlugin', '&Song Usage Tracking'))
         # SongUsage Delete
-        self.songUsageDelete = base_action(tools_menu, u'songUsageDelete')
-        self.songUsageDelete.setText(translate('SongUsagePlugin',
-            '&Delete Tracking Data'))
-        self.songUsageDelete.setStatusTip(translate('SongUsagePlugin',
-            'Delete song usage data up to a specified date.'))
+        self.songUsageDelete = create_action(tools_menu, u'songUsageDelete',
+            text=translate('SongUsagePlugin', '&Delete Tracking Data'),
+            statustip=translate('SongUsagePlugin',
+            'Delete song usage data up to a specified date.'),
+            triggers=self.onSongUsageDelete)
         # SongUsage Report
-        self.songUsageReport = base_action(tools_menu, u'songUsageReport')
-        self.songUsageReport.setText(
-            translate('SongUsagePlugin', '&Extract Tracking Data'))
-        self.songUsageReport.setStatusTip(
-            translate('SongUsagePlugin', 'Generate a report on song usage.'))
+        self.songUsageReport = create_action(tools_menu, u'songUsageReport',
+            text=translate('SongUsagePlugin', '&Extract Tracking Data'),
+            statustip=translate('SongUsagePlugin',
+            'Generate a report on song usage.'),
+            triggers=self.onSongUsageReport)
         # SongUsage activation
-        self.songUsageStatus = shortcut_action(tools_menu, u'songUsageStatus',
-            [QtCore.Qt.Key_F4], self.toggleSongUsageState, checked=False)
-        self.songUsageStatus.setText(translate(
-            'SongUsagePlugin', 'Toggle Tracking'))
-        self.songUsageStatus.setStatusTip(translate('SongUsagePlugin',
-            'Toggle the tracking of song usage.'))
+        self.songUsageStatus = create_action(tools_menu, u'songUsageStatus',
+            text=translate('SongUsagePlugin', 'Toggle Tracking'),
+            statustip=translate('SongUsagePlugin',
+            'Toggle the tracking of song usage.'), checked=False,
+            shortcuts=[QtCore.Qt.Key_F4],
+            triggers=self.toggleSongUsageState)
         # Add Menus together
         self.toolsMenu.addAction(self.songUsageMenu.menuAction())
         self.songUsageMenu.addAction(self.songUsageStatus)
@@ -114,10 +114,6 @@
         QtCore.QObject.connect(self.songUsageActiveButton,
             QtCore.SIGNAL(u'toggled(bool)'),
             self.toggleSongUsageState)
-        QtCore.QObject.connect(self.songUsageDelete,
-            QtCore.SIGNAL(u'triggered()'), self.onSongUsageDelete)
-        QtCore.QObject.connect(self.songUsageReport,
-            QtCore.SIGNAL(u'triggered()'), self.onSongUsageReport)
         self.songUsageMenu.menuAction().setVisible(False)
 
     def initialise(self):

=== added file 'resources/images/media_playback_next.png'
Binary files resources/images/media_playback_next.png	1970-01-01 00:00:00 +0000 and resources/images/media_playback_next.png	2012-03-05 10:15:33 +0000 differ
=== modified file 'resources/images/openlp-2.qrc'
--- resources/images/openlp-2.qrc	2012-01-29 21:22:20 +0000
+++ resources/images/openlp-2.qrc	2012-03-05 10:15:33 +0000
@@ -68,6 +68,7 @@
     <file>media_playback_start.png</file>
     <file>media_playback_stop.png</file>
     <file>media_playback_pause.png</file>
+    <file>media_playback_next.png</file>
   </qresource>
   <qresource prefix="icon">
     <file>openlp-logo-16x16.png</file>

=== modified file 'scripts/resources.patch'
--- scripts/resources.patch	2011-05-24 20:47:05 +0000
+++ scripts/resources.patch	2012-03-05 10:15:33 +0000
@@ -12,12 +12,12 @@
 +###############################################################################
 +# OpenLP - Open Source Lyrics Projection                                      #
 +# --------------------------------------------------------------------------- #
-+# Copyright (c) 2008-2011 Raoul Snyman                                        #
-+# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael      #
-+# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        #
-+# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      #
-+# Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode       #
-+# Woldsund                                                                    #
++# Copyright (c) 2008-2012 Raoul Snyman                                        #
++# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan      #
++# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan,      #
++# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias     #
++# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith,    #
++# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund             #
 +# --------------------------------------------------------------------------- #
 +# 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  #

=== modified file 'scripts/translation_utils.py'
--- scripts/translation_utils.py	2012-02-11 18:02:33 +0000
+++ scripts/translation_utils.py	2012-03-05 10:15:33 +0000
@@ -5,12 +5,12 @@
 ###############################################################################
 # OpenLP - Open Source Lyrics Projection                                      #
 # --------------------------------------------------------------------------- #
-# Copyright (c) 2008-2011 Raoul Snyman                                        #
-# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael      #
-# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler,        #
-# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout,      #
-# Jeffrey Smith, Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode       #
-# Woldsund                                                                    #
+# Copyright (c) 2008-2012 Raoul Snyman                                        #
+# Portions copyright (c) 2008-2012 Tim Bentley, Gerald Britton, Jonathan      #
+# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan,      #
+# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias     #
+# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith,    #
+# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund             #
 # --------------------------------------------------------------------------- #
 # 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  #


Follow ups