← Back to team overview

openlp-core team mailing list archive

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

 

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

Requested reviews:
  Raoul Snyman (raoul-snyman)


Ok her it are the post Alpha goodies!

* Refactor the Alerts plugin and remove an un-needed screen
* Fix saving serviceitems from manager so data is saved correctly(not backward compatible)
* Clean up the Editing code for Songs so Editall works better
* Add missing icons to slidecontroller for theme and hide.  (Restore does not work yet!)
* Add ability to add to existing service items for images and bibles
* Add ability to reorder leaves within serviceitems (Images only)
* Refactor the dynamic image replacement code in plugins
* Allow multiple images to be deleted from plugin
* Add more items to context menus.

-- 
https://code.launchpad.net/~trb143/openlp/newfeatures/+merge/22330
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/lib/mediamanageritem.py'
--- openlp/core/lib/mediamanageritem.py	2010-03-23 19:04:15 +0000
+++ openlp/core/lib/mediamanageritem.py	2010-03-28 16:03:18 +0000
@@ -114,6 +114,7 @@
         self.Toolbar = None
         self.remoteTriggered = None
         self.ServiceItemIconName = None
+        self.addToServiceItem = False
         self.PageLayout = QtGui.QVBoxLayout(self)
         self.PageLayout.setSpacing(0)
         self.PageLayout.setContentsMargins(4, 0, 4, 0)
@@ -279,6 +280,13 @@
                     u'%s %s' % (self.trUtf8('&Edit'), self.PluginNameVisible),
                     self.onEditClick))
             self.ListView.addAction(contextMenuSeparator(self.ListView))
+        if self.hasDeleteIcon:
+            self.ListView.addAction(
+                contextMenuAction(
+                    self.ListView, u':/general/general_delete.png',
+                    u'%s %s' % (self.trUtf8('&Delete'), self.PluginNameVisible),
+                    self.onDeleteClick))
+            self.ListView.addAction(contextMenuSeparator(self.ListView))
         self.ListView.addAction(
             contextMenuAction(
                 self.ListView, u':/general/general_preview.png',
@@ -292,6 +300,12 @@
             contextMenuAction(
                 self.ListView, u':/general/general_add.png',
                 self.trUtf8('&Add to Service'), self.onAddClick))
+        if self.addToServiceItem:
+            self.ListView.addAction(
+                contextMenuAction(
+                    self.ListView, u':/general/general_add.png',
+                    self.trUtf8('&Add to selected Service Item'),
+                    self.onAddEditClick))
         QtCore.QObject.connect(
             self.ListView, QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
             self.onPreviewClick)
@@ -366,7 +380,7 @@
             log.debug(self.PluginNameShort + u' Preview requested')
             service_item = self.buildServiceItem()
             if service_item:
-                service_item.fromPlugin = True
+                service_item.from_plugin = True
                 self.parent.preview_controller.addServiceItem(service_item)
 
     def onLiveClick(self):
@@ -378,7 +392,7 @@
             log.debug(self.PluginNameShort + u' Live requested')
             service_item = self.buildServiceItem()
             if service_item:
-                service_item.fromPlugin = True
+                service_item.from_plugin = True
                 self.parent.live_controller.addServiceItem(service_item)
 
     def onAddClick(self):
@@ -390,8 +404,30 @@
             log.debug(self.PluginNameShort + u' Add requested')
             service_item = self.buildServiceItem()
             if service_item:
-                service_item.fromPlugin = False
-                self.parent.service_manager.addServiceItem(service_item)
+                service_item.from_plugin = False
+                self.parent.service_manager.addServiceItem(service_item)
+
+    def onAddEditClick(self):
+        if not self.ListView.selectedIndexes() and not self.remoteTriggered:
+            QtGui.QMessageBox.information(self,
+                self.trUtf8('No items selected...'),
+                self.trUtf8('You must select one or more items'))
+        else:
+            log.debug(self.PluginNameShort + u' Add requested')
+            service_item = self.parent.service_manager.getServiceItem()
+            if not service_item:
+                QtGui.QMessageBox.information(self,
+                    self.trUtf8('No Service Item Selected'),
+                    self.trUtf8('You must select a existing service item to add to.'))
+            elif self.title == service_item.name:
+                self.generateSlideData(service_item)
+                self.parent.service_manager.addServiceItem(service_item)
+            else:
+                #Turn off the remote edit update message indicator
+                self.parent.service_manager.remoteEditTriggered = False
+                QtGui.QMessageBox.information(self,
+                    self.trUtf8('Invalid Service Item'),
+                    self.trUtf8(unicode('You must select a %s service item.' % self.title)))
 
     def buildServiceItem(self):
         """
@@ -406,4 +442,4 @@
         if self.generateSlideData(service_item):
             return service_item
         else:
-            return None
+            return None
\ No newline at end of file

=== modified file 'openlp/core/lib/renderer.py'
--- openlp/core/lib/renderer.py	2010-03-26 08:49:26 +0000
+++ openlp/core/lib/renderer.py	2010-03-28 16:03:18 +0000
@@ -466,8 +466,7 @@
                         tlcorner=(x + display_shadow_size, y + display_shadow_size),
                         draw=True, color = self._theme.display_shadow_color)
                 self._get_extent_and_render(line, footer, tlcorner=(x, y), draw=True,
-                        outline_size=display_outline_size,
-                        outline_color=self._theme.display_outline_color)
+                        outline_size=display_outline_size)
             y += h
             if linenum == 0:
                 self._first_line_right_extent = rightextent
@@ -505,7 +504,7 @@
         self.mainFont.setPixelSize(self._theme.font_main_proportion)
 
     def _get_extent_and_render(self, line, footer, tlcorner=(0, 0), draw=False,
-        color=None, outline_size=0, outline_color=None):
+        color=None, outline_size=0):
         """
         Find bounding box of text - as render_single_line. If draw is set,
         actually draw the text to the current DC as well return width and
@@ -544,7 +543,7 @@
             else:
                 pen = QtGui.QColor(color)
             x, y = tlcorner
-            if self._theme.display_outline:
+            if self._theme.display_outline and outline_size != 0 and not footer:
                 path = QtGui.QPainterPath()
                 path.addText(QtCore.QPointF(x, y + metrics.ascent()), font, line)
                 self.painter.setBrush(self.painter.pen().brush())
@@ -555,7 +554,7 @@
             self.painter.drawText(x, y + metrics.ascent(), line)
             if self._theme.display_slideTransition:
                 # Print 2nd image with 70% weight
-                if self._theme.display_outline:
+                if self._theme.display_outline and outline_size != 0 and not footer:
                     path = QtGui.QPainterPath()
                     path.addText(QtCore.QPointF(x, y + metrics.ascent()), font, line)
                     self.painter2.setBrush(self.painter2.pen().brush())

=== modified file 'openlp/core/lib/serviceitem.py'
--- openlp/core/lib/serviceitem.py	2010-03-21 23:58:01 +0000
+++ openlp/core/lib/serviceitem.py	2010-03-28 16:03:18 +0000
@@ -66,14 +66,15 @@
         self.iconic_representation = None
         self.raw_footer = None
         self.theme = None
-        self.service_item_path = None
         self.service_item_type = None
         self.edit_enabled = False
+        self.maintain_allowed = False
         self._raw_frames = []
         self._display_frames = []
         self._uuid = unicode(uuid.uuid1())
-        self.autoPreviewAllowed = False
+        self.auto_preview_allowed = False
         self.notes = u''
+        self.from_plugin = False
 
     def addIcon(self, icon):
         """
@@ -156,9 +157,8 @@
             The actual image file name.
         """
         self.service_item_type = ServiceItemType.Image
-        self.service_item_path = path
         self._raw_frames.append(
-            {u'title': title, u'image': image})
+            {u'title': title, u'image': image, u'path': path})
 
     def add_from_text(self, title, raw_slide, verseTag=None):
         """
@@ -189,9 +189,8 @@
             The command of/for the slide.
         """
         self.service_item_type = ServiceItemType.Command
-        self.service_item_path = path
         self._raw_frames.append(
-            {u'title': file_name, u'image': image})
+            {u'title': file_name, u'image': image, u'path': path})
 
     def get_service_repr(self):
         """
@@ -208,7 +207,10 @@
             u'type':self.service_item_type,
             u'audit':self.audit,
             u'notes':self.notes,
-            u'preview':self.autoPreviewAllowed
+            u'preview':self.auto_preview_allowed,
+            u'edit':self.edit_enabled,
+            u'maintain':self.maintain_allowed,
+            u'from_plugin':self.from_plugin
         }
         service_data = []
         if self.service_item_type == ServiceItemType.Text:
@@ -242,8 +244,11 @@
         self.addIcon(header[u'icon'])
         self.raw_footer = header[u'footer']
         self.audit = header[u'audit']
-        self.autoPreviewAllowed = header[u'preview']
+        self.auto_preview_allowed = header[u'preview']
         self.notes = header[u'notes']
+        self.edit_enabled = header[u'edit']
+        self.maintain_allowed = header[u'maintain']
+        self.from_plugin = header[u'from_plugin']
         if self.service_item_type == ServiceItemType.Text:
             for slide in serviceitem[u'serviceitem'][u'data']:
                 self._raw_frames.append(slide)
@@ -280,7 +285,7 @@
         return self._uuid != other._uuid
 
     def is_song(self):
-        return self.name == u'Songs'
+        return self.name.lower() == u'songs'
 
     def is_media(self):
         return self.name.lower() == u'media'
@@ -322,4 +327,4 @@
 
     def request_audit(self):
         if self.audit:
-            Receiver.send_message(u'songusage_live', self.audit)
+            Receiver.send_message(u'songusage_live', self.audit)
\ No newline at end of file

=== modified file 'openlp/core/ui/__init__.py'
--- openlp/core/ui/__init__.py	2010-03-21 23:58:01 +0000
+++ openlp/core/ui/__init__.py	2010-03-28 16:03:18 +0000
@@ -23,7 +23,9 @@
 # Temple Place, Suite 330, Boston, MA 02111-1307 USA                          #
 ###############################################################################
 
-from serviceitemform import ServiceItemNoteForm
+from slidecontroller import HideMode
+from servicenoteform import ServiceNoteForm
+from serviceitemeditform import ServiceItemEditForm
 from screen import ScreenList
 from maindisplay import MainDisplay
 from amendthemeform import AmendThemeForm
@@ -41,4 +43,4 @@
 
 __all__ = ['SplashScreen', 'AboutForm', 'SettingsForm', 'MainWindow',
     'MainDisplay', 'SlideController', 'ServiceManager', 'ThemeManager',
-    'AmendThemeForm', 'MediaDockManager', 'ServiceItemNoteForm']
+    'AmendThemeForm', 'MediaDockManager', 'ServiceItemNoteForm']
\ No newline at end of file

=== modified file 'openlp/core/ui/amendthemeform.py'
--- openlp/core/ui/amendthemeform.py	2010-03-21 23:58:01 +0000
+++ openlp/core/ui/amendthemeform.py	2010-03-28 16:03:18 +0000
@@ -393,6 +393,7 @@
             self.theme.background_type = u'solid'
             if self.theme.background_color is None :
                 self.theme.background_color = u'#000000'
+            self.ImageLineEdit.setText(u'')
         elif background == 1: # Gradient
             self.theme.background_type = u'gradient'
             if gradient == 0: # Horizontal
@@ -405,6 +406,7 @@
                 self.theme.background_startColor = u'#000000'
             if self.theme.background_endColor is None :
                 self.theme.background_endColor = u'#ff0000'
+            self.ImageLineEdit.setText(u'')
         else:
             self.theme.background_type = u'image'
         self.stateChanging(self.theme)
@@ -422,7 +424,6 @@
             self.Color1PushButton.setStyleSheet(
                 u'background-color: %s' % \
                     unicode(self.theme.background_startColor))
-
         self.previewTheme()
 
     def onColor2PushButtonClicked(self):
@@ -561,22 +562,18 @@
             u'background-color: %s' % unicode(theme.font_main_color))
         self.FontFooterColorPushButton.setStyleSheet(
             u'background-color: %s' % unicode(theme.font_footer_color))
-
         if not self.theme.font_main_override:
             self.FontMainDefaultCheckBox.setChecked(True)
         else:
             self.FontMainDefaultCheckBox.setChecked(False)
-
         if not self.theme.font_footer_override:
             self.FontFooterDefaultCheckBox.setChecked(True)
         else:
             self.FontFooterDefaultCheckBox.setChecked(False)
-
         self.OutlineColorPushButton.setStyleSheet(
             u'background-color: %s' % unicode(theme.display_outline_color))
         self.ShadowColorPushButton.setStyleSheet(
             u'background-color: %s' % unicode(theme.display_shadow_color))
-
         if self.theme.display_outline:
             self.OutlineCheckBox.setChecked(True)
             self.OutlineColorPushButton.setEnabled(True)
@@ -584,7 +581,6 @@
             self.OutlineCheckBox.setChecked(False)
             self.OutlineColorPushButton.setEnabled(False)
         self.OutlineSpinBox.setValue(int(self.theme.display_outline_size))
-
         if self.theme.display_shadow:
             self.ShadowCheckBox.setChecked(True)
             self.ShadowColorPushButton.setEnabled(True)
@@ -592,12 +588,10 @@
             self.ShadowCheckBox.setChecked(False)
             self.ShadowColorPushButton.setEnabled(False)
         self.ShadowSpinBox.setValue(int(self.theme.display_shadow_size))
-
         if self.theme.display_slideTransition:
             self.SlideTransitionCheckedBox.setCheckState(QtCore.Qt.Checked)
         else:
             self.SlideTransitionCheckedBox.setCheckState(QtCore.Qt.Unchecked)
-
         self.HorizontalComboBox.setCurrentIndex(
             self.theme.display_horizontalAlign)
         self.VerticalComboBox.setCurrentIndex(self.theme.display_verticalAlign)
@@ -657,7 +651,6 @@
                 self.ImageFilenameWidget.setVisible(True)
                 self.GradientLabel.setVisible(False)
                 self.GradientComboBox.setVisible(False)
-
         if not theme.font_main_override:
             self.FontMainXSpinBox.setEnabled(False)
             self.FontMainYSpinBox.setEnabled(False)

=== modified file 'openlp/core/ui/maindisplay.py'
--- openlp/core/ui/maindisplay.py	2010-03-21 23:58:01 +0000
+++ openlp/core/ui/maindisplay.py	2010-03-28 16:03:18 +0000
@@ -30,6 +30,7 @@
 from PyQt4.phonon import Phonon
 
 from openlp.core.lib import Receiver, resize_image
+from openlp.core.ui import HideMode
 
 log = logging.getLogger(__name__)
 
@@ -253,11 +254,17 @@
             self.waitingFrame = frame
             self.waitingFrameTrans = transition
 
-    def blankDisplay(self, blanked=True):
+    def blankDisplay(self, blankType=HideMode.Blank, blanked=True):
         log.debug(u'Blank main Display %d' % blanked)
         if blanked:
             self.displayBlank = True
-            self.display_text.setPixmap(QtGui.QPixmap.fromImage(self.blankFrame))
+            if blankType == HideMode.Blank:
+                self.display_text.setPixmap(QtGui.QPixmap.fromImage(self.blankFrame))
+            elif blankType == HideMode.Theme:
+                theme = self.parent.RenderManager.renderer.bg_frame
+                if not theme:
+                    theme = self.blankFrame
+                self.display_text.setPixmap(QtGui.QPixmap.fromImage(theme))
             self.waitingFrame = None
             self.waitingFrameTrans = False
         else:
@@ -313,4 +320,4 @@
         self.video.setVisible(False)
         self.display_text.show()
         self.display_image.show()
-        self.blankDisplay(False)
+        self.blankDisplay(False, False)
\ No newline at end of file

=== added file 'openlp/core/ui/serviceitemeditdialog.py'
--- openlp/core/ui/serviceitemeditdialog.py	1970-01-01 00:00:00 +0000
+++ openlp/core/ui/serviceitemeditdialog.py	2010-03-28 16:03:18 +0000
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection                                      #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2010 Raoul Snyman                                        #
+# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael      #
+# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin      #
+# Thompson, Jon Tibble, Carsten Tinggaard                                     #
+# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it     #
+# under the terms of the GNU General Public License as published by the Free  #
+# Software Foundation; version 2 of the License.                              #
+#                                                                             #
+# This program is distributed in the hope that it will be useful, but WITHOUT #
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       #
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    #
+# more details.                                                               #
+#                                                                             #
+# You should have received a copy of the GNU General Public License along     #
+# with this program; if not, write to the Free Software Foundation, Inc., 59  #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA                          #
+###############################################################################
+
+from PyQt4 import QtCore, QtGui
+
+class Ui_ServiceItemEditDialog(object):
+    def setupUi(self, ServiceItemEditDialog):
+        ServiceItemEditDialog.setObjectName(u'ServiceItemEditDialog')
+        ServiceItemEditDialog.resize(386, 272)
+        self.layoutWidget = QtGui.QWidget(ServiceItemEditDialog)
+        self.layoutWidget.setGeometry(QtCore.QRect(20, 20, 351, 241))
+        self.layoutWidget.setObjectName(u'layoutWidget')
+        self.outerLayout = QtGui.QVBoxLayout(self.layoutWidget)
+        self.outerLayout.setObjectName(u'outerLayout')
+        self.topLayout = QtGui.QHBoxLayout()
+        self.topLayout.setObjectName(u'topLayout')
+        self.listWidget = QtGui.QListWidget(self.layoutWidget)
+        self.listWidget.setAlternatingRowColors(True)
+        self.listWidget.setObjectName(u'listWidget')
+        self.topLayout.addWidget(self.listWidget)
+        self.buttonLayout = QtGui.QVBoxLayout()
+        self.buttonLayout.setObjectName(u'buttonLayout')
+        self.upButton = QtGui.QPushButton(self.layoutWidget)
+        self.upButton.setObjectName(u'upButton')
+        self.buttonLayout.addWidget(self.upButton)
+        spacerItem = QtGui.QSpacerItem(20, 40,
+                    QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
+        self.buttonLayout.addItem(spacerItem)
+        self.deleteButton = QtGui.QPushButton(self.layoutWidget)
+        self.deleteButton.setObjectName(u'deleteButton')
+        self.buttonLayout.addWidget(self.deleteButton)
+        self.downButton = QtGui.QPushButton(self.layoutWidget)
+        self.downButton.setObjectName(u'downButton')
+        self.buttonLayout.addWidget(self.downButton)
+        self.topLayout.addLayout(self.buttonLayout)
+        self.outerLayout.addLayout(self.topLayout)
+        self.buttonBox = QtGui.QDialogButtonBox(self.layoutWidget)
+        self.buttonBox.setStandardButtons(
+                    QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Save)
+        self.buttonBox.setObjectName(u'buttonBox')
+        self.outerLayout.addWidget(self.buttonBox)
+
+        self.retranslateUi(ServiceItemEditDialog)
+        QtCore.QMetaObject.connectSlotsByName(ServiceItemEditDialog)
+
+    def retranslateUi(self, ServiceItemEditDialog):
+        ServiceItemEditDialog.setWindowTitle(self.trUtf8('Service Item Maintenance'))
+        self.upButton.setText(self.trUtf8('Up'))
+        self.deleteButton.setText(self.trUtf8('Delete'))
+        self.downButton.setText(self.trUtf8('Down'))
+

=== added file 'openlp/core/ui/serviceitemeditform.py'
--- openlp/core/ui/serviceitemeditform.py	1970-01-01 00:00:00 +0000
+++ openlp/core/ui/serviceitemeditform.py	2010-03-28 16:03:18 +0000
@@ -0,0 +1,116 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection                                      #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2010 Raoul Snyman                                        #
+# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael      #
+# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin      #
+# Thompson, Jon Tibble, Carsten Tinggaard                                     #
+# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it     #
+# under the terms of the GNU General Public License as published by the Free  #
+# Software Foundation; version 2 of the License.                              #
+#                                                                             #
+# This program is distributed in the hope that it will be useful, but WITHOUT #
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       #
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    #
+# more details.                                                               #
+#                                                                             #
+# You should have received a copy of the GNU General Public License along     #
+# with this program; if not, write to the Free Software Foundation, Inc., 59  #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA                          #
+###############################################################################
+
+from PyQt4 import QtCore, QtGui
+from serviceitemeditdialog import Ui_ServiceItemEditDialog
+
+class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
+    """
+    This is the form that is used to edit the verses of the song.
+    """
+    def __init__(self, parent=None):
+        """
+        Constructor
+        """
+        QtGui.QDialog.__init__(self, parent)
+        self.setupUi(self)
+        self.itemList = []
+        # enable drop
+        QtCore.QObject.connect(self.upButton,
+                               QtCore.SIGNAL(u'clicked()'),
+                               self.onItemUp)
+        QtCore.QObject.connect(self.downButton,
+                               QtCore.SIGNAL(u'clicked()'),
+                               self.onItemDown)
+        QtCore.QObject.connect(self.deleteButton,
+                               QtCore.SIGNAL(u'clicked()'),
+                               self.onItemDelete)
+        QtCore.QObject.connect(self.buttonBox,
+                               QtCore.SIGNAL(u'accepted()'),
+                               self.accept)
+        QtCore.QObject.connect(self.buttonBox,
+                               QtCore.SIGNAL(u'rejected()'),
+                               self.reject)
+
+    def setServiceItem(self, item):
+        self.item = item
+        self.itemList = []
+        if self.item.is_image():
+            self.data = True
+            for frame in self.item._raw_frames:
+                self.itemList.append(frame)
+        self.loadData()
+
+    def getServiceItem(self):
+        if self.data:
+            self.item._raw_frames = []
+            if self.item.is_image():
+                for item in self.itemList:
+                    self.item.add_from_image(item[u'path'],
+                                             item[u'title'], item[u'image'])
+            self.item.render()
+        return self.item
+
+    def loadData(self):
+        self.listWidget.clear()
+        for frame in self.itemList:
+            item_name = QtGui.QListWidgetItem(frame[u'title'])
+            self.listWidget.addItem(item_name)
+
+    def onItemDelete(self):
+        """
+        Delete the selected row
+        """
+        items = self.listWidget.selectedItems()
+        for item in items:
+            row =  self.listWidget.row(item)
+            self.itemList.remove(self.itemList[row])
+            self.loadData()
+
+    def onItemUp(self):
+        """
+        Move the selected row up in the list
+        """
+        items = self.listWidget.selectedItems()
+        for item in items:
+            row =  self.listWidget.row(item)
+            if row > 0:
+                temp = self.itemList[row]
+                self.itemList.remove(self.itemList[row])
+                self.itemList.insert(row - 1, temp)
+                self.loadData()
+
+    def onItemDown(self):
+        """
+        Move the selected row down in the list
+        """
+        items = self.listWidget.selectedItems()
+        for item in items:
+            row =  self.listWidget.row(item)
+            if row < len(self.itemList) and row is not -1:
+                temp = self.itemList[row]
+                self.itemList.remove(self.itemList[row])
+                self.itemList.insert(row + 1, temp)
+                self.loadData()

=== modified file 'openlp/core/ui/servicemanager.py'
--- openlp/core/ui/servicemanager.py	2010-03-25 19:27:46 +0000
+++ openlp/core/ui/servicemanager.py	2010-03-28 16:03:18 +0000
@@ -34,7 +34,7 @@
 
 from openlp.core.lib import PluginConfig, OpenLPToolbar, ServiceItem, \
     contextMenuAction, Receiver, str_to_bool, build_icon
-from openlp.core.ui import ServiceItemNoteForm
+from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm
 
 class ServiceManagerList(QtGui.QTreeWidget):
 
@@ -106,7 +106,8 @@
         #Indicates if remoteTriggering is active.  If it is the next addServiceItem call
         #will replace the currently selected one.
         self.remoteEditTriggered = False
-        self.serviceItemNoteForm = ServiceItemNoteForm()
+        self.serviceNoteForm = ServiceNoteForm()
+        self.serviceItemEditForm = ServiceItemEditForm()
         #start with the layout
         self.Layout = QtGui.QVBoxLayout(self)
         self.Layout.setSpacing(0)
@@ -203,6 +204,8 @@
         self.menu = QtGui.QMenu()
         self.editAction = self.menu.addAction(self.trUtf8('&Edit Item'))
         self.editAction.setIcon(build_icon(u':/general/general_edit.png'))
+        self.maintainAction = self.menu.addAction(self.trUtf8('&Maintain Item'))
+        self.editAction.setIcon(build_icon(u':/general/general_edit.png'))
         self.notesAction = self.menu.addAction(self.trUtf8('&Notes'))
         self.notesAction.setIcon(build_icon(u':/services/service_notes.png'))
         self.deleteAction = self.menu.addAction(self.trUtf8('&Delete From Service'))
@@ -228,9 +231,12 @@
             pos = item.parent().data(0, QtCore.Qt.UserRole).toInt()[0]
         serviceItem = self.serviceItems[pos - 1]
         self.editAction.setVisible(False)
+        self.maintainAction.setVisible(False)
         self.notesAction.setVisible(False)
         if serviceItem[u'service_item'].edit_enabled:
             self.editAction.setVisible(True)
+        if serviceItem[u'service_item'].maintain_allowed:
+            self.maintainAction.setVisible(True)
         if item.parent() is None:
             self.notesAction.setVisible(True)
         self.themeMenu.menuAction().setVisible(False)
@@ -239,6 +245,8 @@
         action = self.menu.exec_(self.ServiceManagerList.mapToGlobal(point))
         if action == self.editAction:
             self.remoteEdit()
+        if action == self.maintainAction:
+            self.onServiceItemEditForm()
         if action == self.deleteAction:
             self.onDeleteFromService()
         if action == self.notesAction:
@@ -253,11 +261,20 @@
 
     def onServiceItemNoteForm(self):
         item, count = self.findServiceItem()
-        self.serviceItemNoteForm.textEdit.setPlainText(
+        self.serviceNoteForm.textEdit.setPlainText(
             self.serviceItems[item][u'service_item'].notes)
-        if self.serviceItemNoteForm.exec_():
+        if self.serviceNoteForm.exec_():
             self.serviceItems[item][u'service_item'].notes = \
-                self.serviceItemNoteForm.textEdit.toPlainText()
+                self.serviceNoteForm.textEdit.toPlainText()
+            self.repaintServiceList(item, 0)
+
+    def onServiceItemEditForm(self):
+        item, count = self.findServiceItem()
+        self.serviceItemEditForm.setServiceItem(
+            self.serviceItems[item][u'service_item'])
+        if self.serviceItemEditForm.exec_():
+            self.serviceItems[item][u'service_item'] = \
+                self.serviceItemEditForm.getServiceItem()
             self.repaintServiceList(item, 0)
 
     def nextItem(self):
@@ -354,7 +371,7 @@
     def onServiceUp(self):
         """
         Move the current ServiceItem up in the list
-        Note move up means move to top of area  ie 0.
+        Note move up means move to top of area ie 0.
         """
         item, count = self.findServiceItem()
         if item > 0:
@@ -500,7 +517,7 @@
                     if item[u'service_item'].uses_file():
                         for frame in item[u'service_item'].get_frames():
                             path_from = unicode(os.path.join(
-                                item[u'service_item'].service_item_path,
+                                frame[u'path'],
                                 frame[u'title']))
                             zip.write(path_from)
                 file = open(servicefile, u'wb')
@@ -642,11 +659,17 @@
             self.repaintServiceList(sitem + 1, 0)
             self.parent.LiveController.replaceServiceManagerItem(item)
         else:
-            #nothing selected or dnd
+            #nothing selected for dnd
             if self.droppos == 0:
-                self.serviceItems.append({u'service_item': item,
-                    u'order': len(self.serviceItems) + 1,
-                    u'expanded':expand})
+                if isinstance(item, list):
+                    for inditem in item:
+                        self.serviceItems.append({u'service_item': inditem,
+                            u'order': len(self.serviceItems) + 1,
+                            u'expanded':expand})
+                else:
+                    self.serviceItems.append({u'service_item': item,
+                        u'order': len(self.serviceItems) + 1,
+                        u'expanded':expand})
                 self.repaintServiceList(len(self.serviceItems) + 1, 0)
             else:
                 self.serviceItems.insert(self.droppos, {u'service_item': item,
@@ -667,6 +690,17 @@
         self.parent.PreviewController.addServiceManagerItem(
             self.serviceItems[item][u'service_item'], count)
 
+    def getServiceItem(self):
+        """
+        Send the current item to the Preview slide controller
+        """
+        item, count = self.findServiceItem()
+        if item == -1:
+            return False
+        else:
+            #Switch on remote edit update functionality.
+            self.remoteEditTriggered = True
+            return self.serviceItems[item][u'service_item']
 
     def makeLive(self):
         """
@@ -679,7 +713,7 @@
                         get_config(u'auto preview', u'False')):
             item += 1
             if self.serviceItems and item < len(self.serviceItems) and \
-                self.serviceItems[item][u'service_item'].autoPreviewAllowed:
+                self.serviceItems[item][u'service_item'].auto_preview_allowed:
                     self.parent.PreviewController.addServiceManagerItem(
                         self.serviceItems[item][u'service_item'], 0)
 

=== renamed file 'openlp/core/ui/serviceitemdialog.py' => 'openlp/core/ui/servicenotedialog.py'
=== renamed file 'openlp/core/ui/serviceitemform.py' => 'openlp/core/ui/servicenoteform.py'
--- openlp/core/ui/serviceitemform.py	2010-03-21 23:58:01 +0000
+++ openlp/core/ui/servicenoteform.py	2010-03-28 16:03:18 +0000
@@ -26,7 +26,7 @@
 from PyQt4 import QtCore, QtGui
 from serviceitemdialog import Ui_ServiceNoteEdit
 
-class ServiceItemNoteForm(QtGui.QDialog, Ui_ServiceNoteEdit):
+class ServiceNoteForm(QtGui.QDialog, Ui_ServiceNoteEdit):
     """
     This is the form that is used to edit the verses of the song.
     """

=== modified file 'openlp/core/ui/slidecontroller.py'
--- openlp/core/ui/slidecontroller.py	2010-03-23 19:04:15 +0000
+++ openlp/core/ui/slidecontroller.py	2010-03-28 16:03:18 +0000
@@ -30,6 +30,15 @@
 from PyQt4 import QtCore, QtGui
 from PyQt4.phonon import Phonon
 
+class HideMode(object):
+    """
+    This is basically an enumeration class which specifies the mode of a Bible.
+    Mode refers to whether or not a Bible in OpenLP is a full Bible or needs to
+    be downloaded from the Internet on an as-needed basis.
+    """
+    Blank = 1
+    Theme = 2
+
 from openlp.core.lib import OpenLPToolbar, Receiver, str_to_bool, \
     PluginConfig, resize_image
 
@@ -94,6 +103,10 @@
         self.song_edit_list = [
             u'Edit Song',
         ]
+        if isLive:
+            self.labelWidth = 20
+        else:
+            self.labelWidth = 0
         self.timer_id = 0
         self.songEdit = False
         self.selectedRow = 0
@@ -133,12 +146,14 @@
         self.ControllerLayout.setMargin(0)
         # Controller list view
         self.PreviewListWidget = SlideList(self)
-        self.PreviewListWidget.setColumnCount(1)
+        self.PreviewListWidget.setColumnCount(2)
         self.PreviewListWidget.horizontalHeader().setVisible(False)
         self.PreviewListWidget.verticalHeader().setVisible(False)
-        self.PreviewListWidget.setColumnWidth(1, self.Controller.width())
+        self.PreviewListWidget.setColumnWidth(1, self.labelWidth)
+        self.PreviewListWidget.setColumnWidth(1, self.Controller.width() - self.labelWidth)
         self.PreviewListWidget.isLive = self.isLive
         self.PreviewListWidget.setObjectName(u'PreviewListWidget')
+        self.PreviewListWidget.setSelectionBehavior(1)
         self.PreviewListWidget.setEditTriggers(
             QtGui.QAbstractItemView.NoEditTriggers)
         self.PreviewListWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
@@ -172,6 +187,12 @@
             self.blankButton = self.Toolbar.addToolbarButton(
                 u'Blank Screen', u':/slides/slide_blank.png',
                 self.trUtf8('Blank Screen'), self.onBlankDisplay, True)
+            self.themeButton = self.Toolbar.addToolbarButton(
+                u'Display Theme', u':/slides/slide_theme.png',
+                self.trUtf8('Theme Screen'), self.onThemeDisplay, True)
+            self.hideButton = self.Toolbar.addToolbarButton(
+                u'Hide screen', u':/slides/slide_desktop.png',
+                self.trUtf8('Hide Screen'), self.onHideDisplay, True)
             QtCore.QObject.connect(Receiver.get_receiver(),
                 QtCore.SIGNAL(u'live_slide_blank'), self.blankScreen)
         if not self.isLive:
@@ -309,7 +330,8 @@
         """
         width = self.parent.ControlSplitter.sizes()[self.split]
         height = width * self.parent.RenderManager.screen_ratio
-        self.PreviewListWidget.setColumnWidth(0, width)
+        self.PreviewListWidget.setColumnWidth(0, self.labelWidth)
+        self.PreviewListWidget.setColumnWidth(1, width - self.labelWidth)
         #Sort out image hights (Songs , bibles excluded)
         if self.serviceItem and not self.serviceItem.is_text():
             for framenumber, frame in enumerate(self.serviceItem.get_frames()):
@@ -354,7 +376,8 @@
         if item.is_text():
             self.Toolbar.makeWidgetsInvisible(self.image_list)
             if item.is_song() and \
-                str_to_bool(self.songsconfig.get_config(u'show songbar', True)):
+                str_to_bool(self.songsconfig.get_config(u'show songbar', True)) \
+                and len(self.slideList) > 0:
                 self.Toolbar.makeWidgetsVisible([u'Song Menu'])
         elif item.is_image():
             #Not sensible to allow loops with 1 frame
@@ -372,7 +395,7 @@
         self.Toolbar.setVisible(True)
         self.Mediabar.setVisible(False)
         self.Toolbar.makeWidgetsInvisible(self.song_edit_list)
-        if item.edit_enabled and item.fromPlugin:
+        if item.edit_enabled and item.from_plugin:
             self.Toolbar.makeWidgetsVisible(self.song_edit_list)
         elif item.is_media():
             self.Toolbar.setVisible(False)
@@ -453,12 +476,15 @@
         self.serviceItem = serviceItem
         self.PreviewListWidget.clear()
         self.PreviewListWidget.setRowCount(0)
-        self.PreviewListWidget.setColumnWidth(0, width)
+        self.PreviewListWidget.setColumnWidth(0, self.labelWidth)
+        self.PreviewListWidget.setColumnWidth(1, width - self.labelWidth)
         if self.isLive:
             self.SongMenu.menu().clear()
+        row = 0
         for framenumber, frame in enumerate(self.serviceItem.get_frames()):
             self.PreviewListWidget.setRowCount(
                 self.PreviewListWidget.rowCount() + 1)
+            rowitem = QtGui.QTableWidgetItem()
             item = QtGui.QTableWidgetItem()
             slide_height = 0
             #It is a based Text Render
@@ -474,12 +500,12 @@
                     else:
                         tag = bits[0]
                         row = bits[0][0:1]
-                    try:
-                        test = self.slideList[tag]
-                    except:
+                    if tag not in self.slideList:
                         self.slideList[tag] = framenumber
                         self.SongMenu.menu().addAction(self.trUtf8(u'%s'%tag),
                             self.onSongBarHandler)
+                else:
+                    row += 1
                 item.setText(frame[u'text'])
             else:
                 label = QtGui.QLabel()
@@ -489,15 +515,18 @@
                                       self.parent.RenderManager.height)
                 label.setScaledContents(True)
                 label.setPixmap(QtGui.QPixmap.fromImage(pixmap))
-                self.PreviewListWidget.setCellWidget(framenumber, 0, label)
+                self.PreviewListWidget.setCellWidget(framenumber, 1, label)
                 slide_height = width * self.parent.RenderManager.screen_ratio
-            self.PreviewListWidget.setItem(framenumber, 0, item)
+            rowitem.setText(unicode(row))
+            self.PreviewListWidget.setItem(framenumber, 0, rowitem)
+            self.PreviewListWidget.setItem(framenumber, 1, item)
             if slide_height != 0:
                 self.PreviewListWidget.setRowHeight(framenumber, slide_height)
         if self.serviceItem.is_text():
             self.PreviewListWidget.resizeRowsToContents()
-        self.PreviewListWidget.setColumnWidth(
-            0, self.PreviewListWidget.viewport().size().width())
+        self.PreviewListWidget.setColumnWidth(0, self.labelWidth)
+        self.PreviewListWidget.setColumnWidth(1,
+                        self.PreviewListWidget.viewport().size().width() - self.labelWidth )
         if slideno > self.PreviewListWidget.rowCount():
             self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount())
         else:
@@ -531,11 +560,32 @@
         log.debug(u'onBlankDisplay %d' % force)
         if force:
             self.blankButton.setChecked(True)
-        self.blankScreen(self.blankButton.isChecked())
+        self.blankScreen(HideMode.Blank, self.blankButton.isChecked())
         self.parent.generalConfig.set_config(u'screen blank',
                                             self.blankButton.isChecked())
 
-    def blankScreen(self, blanked=False):
+    def onThemeDisplay(self, force=False):
+        """
+        Handle the Theme screen button
+        """
+        log.debug(u'onThemeDisplay %d' % force)
+        if force:
+            self.themeButton.setChecked(True)
+        self.blankScreen(HideMode.Theme, self.themeButton.isChecked())
+
+    def onHideDisplay(self, force=False):
+        """
+        Handle the Hide screen button
+        """
+        log.debug(u'onHideDisplay %d' % force)
+        if force:
+            self.themeButton.setChecked(True)
+        if self.hideButton.isChecked():
+            self.parent.mainDisplay.hideDisplay()
+        else:
+            self.parent.mainDisplay.showDisplay()
+
+    def blankScreen(self, blankType, blanked=False):
         """
         Blank the display screen.
         """
@@ -546,9 +596,9 @@
                 else:
                     Receiver.send_message(u'%s_unblank'% self.serviceItem.name.lower())
             else:
-                self.parent.mainDisplay.blankDisplay(blanked)
+                self.parent.mainDisplay.blankDisplay(blankType, blanked)
         else:
-            self.parent.mainDisplay.blankDisplay(blanked)
+            self.parent.mainDisplay.blankDisplay(blankType, blanked)
 
     def onSlideSelected(self):
         """
@@ -592,7 +642,7 @@
             QtCore.QTimer.singleShot(2.5, self.grabMainDisplay)
         else:
             label = self.PreviewListWidget.cellWidget(
-                self.PreviewListWidget.currentRow(), 0)
+                self.PreviewListWidget.currentRow(), 1)
             self.SlidePreview.setPixmap(label.pixmap())
 
     def grabMainDisplay(self):
@@ -661,7 +711,8 @@
                 self.serviceItem.name.lower(), self.isLive)
             self.updatePreview()
         else:
-            self.PreviewListWidget.selectRow(self.PreviewListWidget.rowCount() - 1)
+            self.PreviewListWidget.selectRow(
+                        self.PreviewListWidget.rowCount() - 1)
             self.onSlideSelected()
 
     def onStartLoop(self):

=== modified file 'openlp/plugins/alerts/alertsplugin.py'
--- openlp/plugins/alerts/alertsplugin.py	2010-03-21 23:58:01 +0000
+++ openlp/plugins/alerts/alertsplugin.py	2010-03-28 16:03:18 +0000
@@ -29,7 +29,7 @@
 
 from openlp.core.lib import Plugin, build_icon, PluginStatus
 from openlp.plugins.alerts.lib import AlertsManager, DBManager
-from openlp.plugins.alerts.forms import AlertsTab, AlertForm, AlertEditForm
+from openlp.plugins.alerts.forms import AlertsTab, AlertForm
 
 log = logging.getLogger(__name__)
 
@@ -43,7 +43,6 @@
         self.alertsmanager = AlertsManager(self)
         self.manager = DBManager(self.config)
         self.alertForm = AlertForm(self.manager, self)
-        self.alertEditForm = AlertEditForm(self.manager, self)
         self.status = PluginStatus.Active
 
     def get_settings_tab(self):
@@ -90,10 +89,6 @@
         self.alertForm.loadList()
         self.alertForm.exec_()
 
-    def onAlertsEdit(self):
-        self.alertEditForm.loadList()
-        self.alertEditForm.exec_()
-
     def about(self):
         about_text = self.trUtf8('<b>Alerts Plugin</b><br>This plugin '
             'controls the displaying of alerts on the presentations screen')

=== modified file 'openlp/plugins/alerts/forms/__init__.py'
--- openlp/plugins/alerts/forms/__init__.py	2010-03-21 23:58:01 +0000
+++ openlp/plugins/alerts/forms/__init__.py	2010-03-28 16:03:18 +0000
@@ -25,4 +25,3 @@
 
 from alertstab import AlertsTab
 from alertform import AlertForm
-from alerteditform import AlertEditForm

=== removed file 'openlp/plugins/alerts/forms/alerteditdialog.py'
--- openlp/plugins/alerts/forms/alerteditdialog.py	2010-03-21 23:58:01 +0000
+++ openlp/plugins/alerts/forms/alerteditdialog.py	1970-01-01 00:00:00 +0000
@@ -1,83 +0,0 @@
-# -*- coding: utf-8 -*-
-# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
-
-###############################################################################
-# OpenLP - Open Source Lyrics Projection                                      #
-# --------------------------------------------------------------------------- #
-# Copyright (c) 2008-2010 Raoul Snyman                                        #
-# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael      #
-# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin      #
-# Thompson, Jon Tibble, Carsten Tinggaard                                     #
-# --------------------------------------------------------------------------- #
-# This program is free software; you can redistribute it and/or modify it     #
-# under the terms of the GNU General Public License as published by the Free  #
-# Software Foundation; version 2 of the License.                              #
-#                                                                             #
-# This program is distributed in the hope that it will be useful, but WITHOUT #
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       #
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    #
-# more details.                                                               #
-#                                                                             #
-# You should have received a copy of the GNU General Public License along     #
-# with this program; if not, write to the Free Software Foundation, Inc., 59  #
-# Temple Place, Suite 330, Boston, MA 02111-1307 USA                          #
-###############################################################################
-
-from PyQt4 import QtCore, QtGui
-
-class Ui_AlertEditDialog(object):
-    def setupUi(self, AlertEditDialog):
-        AlertEditDialog.setObjectName(u'AlertEditDialog')
-        AlertEditDialog.resize(400, 300)
-        self.buttonBox = QtGui.QDialogButtonBox(AlertEditDialog)
-        self.buttonBox.setGeometry(QtCore.QRect(220, 270, 173, 27))
-        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel)
-        self.buttonBox.setObjectName(u'buttonBox')
-        self.layoutWidget = QtGui.QWidget(AlertEditDialog)
-        self.layoutWidget.setGeometry(QtCore.QRect(20, 10, 361, 251))
-        self.layoutWidget.setObjectName(u'layoutWidget')
-        self.verticalLayout_2 = QtGui.QVBoxLayout(self.layoutWidget)
-        self.verticalLayout_2.setObjectName(u'verticalLayout_2')
-        self.horizontalLayout_2 = QtGui.QHBoxLayout()
-        self.horizontalLayout_2.setObjectName(u'horizontalLayout_2')
-        self.AlertLineEdit = QtGui.QLineEdit(self.layoutWidget)
-        self.AlertLineEdit.setObjectName(u'AlertLineEdit')
-        self.horizontalLayout_2.addWidget(self.AlertLineEdit)
-        self.verticalLayout_2.addLayout(self.horizontalLayout_2)
-        self.horizontalLayout = QtGui.QHBoxLayout()
-        self.horizontalLayout.setObjectName(u'horizontalLayout')
-        self.AlertListWidget = QtGui.QListWidget(self.layoutWidget)
-        self.AlertListWidget.setAlternatingRowColors(True)
-        self.AlertListWidget.setObjectName(u'AlertListWidget')
-        self.horizontalLayout.addWidget(self.AlertListWidget)
-        self.verticalLayout = QtGui.QVBoxLayout()
-        self.verticalLayout.setObjectName(u'verticalLayout')
-        self.SaveButton = QtGui.QPushButton(self.layoutWidget)
-        self.SaveButton.setObjectName(u'SaveButton')
-        self.verticalLayout.addWidget(self.SaveButton)
-        self.ClearButton = QtGui.QPushButton(self.layoutWidget)
-        self.ClearButton.setObjectName(u'ClearButton')
-        self.verticalLayout.addWidget(self.ClearButton)
-        self.AddButton = QtGui.QPushButton(self.layoutWidget)
-        self.AddButton.setObjectName(u'AddButton')
-        self.verticalLayout.addWidget(self.AddButton)
-        self.EditButton = QtGui.QPushButton(self.layoutWidget)
-        self.EditButton.setObjectName(u'EditButton')
-        self.verticalLayout.addWidget(self.EditButton)
-        self.DeleteButton = QtGui.QPushButton(self.layoutWidget)
-        self.DeleteButton.setObjectName(u'DeleteButton')
-        self.verticalLayout.addWidget(self.DeleteButton)
-        self.horizontalLayout.addLayout(self.verticalLayout)
-        self.verticalLayout_2.addLayout(self.horizontalLayout)
-
-        self.retranslateUi(AlertEditDialog)
-        QtCore.QMetaObject.connectSlotsByName(AlertEditDialog)
-
-    def retranslateUi(self, AlertEditDialog):
-        AlertEditDialog.setWindowTitle(self.trUtf8('Maintain Alerts'))
-        self.SaveButton.setText(self.trUtf8('Save'))
-        self.ClearButton.setText(self.trUtf8('Clear'))
-        self.AddButton.setText(self.trUtf8('Add'))
-        self.EditButton.setText(self.trUtf8('Edit'))
-        self.DeleteButton.setText(self.trUtf8('Delete'))
-

=== removed file 'openlp/plugins/alerts/forms/alerteditform.py'
--- openlp/plugins/alerts/forms/alerteditform.py	2010-03-21 23:58:01 +0000
+++ openlp/plugins/alerts/forms/alerteditform.py	1970-01-01 00:00:00 +0000
@@ -1,166 +0,0 @@
-# -*- coding: utf-8 -*-
-# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
-
-###############################################################################
-# OpenLP - Open Source Lyrics Projection                                      #
-# --------------------------------------------------------------------------- #
-# Copyright (c) 2008-2010 Raoul Snyman                                        #
-# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael      #
-# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin      #
-# Thompson, Jon Tibble, Carsten Tinggaard                                     #
-# --------------------------------------------------------------------------- #
-# This program is free software; you can redistribute it and/or modify it     #
-# under the terms of the GNU General Public License as published by the Free  #
-# Software Foundation; version 2 of the License.                              #
-#                                                                             #
-# This program is distributed in the hope that it will be useful, but WITHOUT #
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       #
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    #
-# more details.                                                               #
-#                                                                             #
-# You should have received a copy of the GNU General Public License along     #
-# with this program; if not, write to the Free Software Foundation, Inc., 59  #
-# Temple Place, Suite 330, Boston, MA 02111-1307 USA                          #
-###############################################################################
-
-from PyQt4 import QtGui, QtCore
-from openlp.plugins.alerts.lib.models import AlertItem
-
-from alerteditdialog import Ui_AlertEditDialog
-
-class AlertEditForm(QtGui.QDialog, Ui_AlertEditDialog):
-    """
-    Class documentation goes here.
-    """
-    def __init__(self, manager, parent):
-        """
-        Constructor
-        """
-        self.manager = manager
-        self.parent = parent
-        QtGui.QDialog.__init__(self, None)
-        self.setupUi(self)
-        QtCore.QObject.connect(self.DeleteButton,
-                               QtCore.SIGNAL(u'clicked()'),
-                               self.onDeleteClick)
-        QtCore.QObject.connect(self.ClearButton,
-                               QtCore.SIGNAL(u'clicked()'),
-                               self.onClearClick)
-        QtCore.QObject.connect(self.EditButton,
-                               QtCore.SIGNAL(u'clicked()'),
-                               self.onEditClick)
-        QtCore.QObject.connect(self.AddButton,
-                               QtCore.SIGNAL(u'clicked()'),
-                               self.onAddClick)
-        QtCore.QObject.connect(self.SaveButton,
-                               QtCore.SIGNAL(u'clicked()'),
-                               self.onSaveClick)
-        QtCore.QObject.connect(self.buttonBox,
-                               QtCore.SIGNAL(u'rejected()'), self.close)
-        QtCore.QObject.connect(self.AlertLineEdit,
-            QtCore.SIGNAL(u'textChanged(const QString&)'),
-            self.onTextChanged)
-        QtCore.QObject.connect(self.AlertListWidget,
-            QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
-            self.onItemSelected)
-        QtCore.QObject.connect(self.AlertListWidget,
-            QtCore.SIGNAL(u'clicked(QModelIndex)'),
-            self.onItemSelected)
-
-    def loadList(self):
-        self.AlertListWidget.clear()
-        alerts = self.manager.get_all_alerts()
-        for alert in alerts:
-            item_name = QtGui.QListWidgetItem(alert.text)
-            item_name.setData(
-                QtCore.Qt.UserRole, QtCore.QVariant(alert.id))
-            self.AlertListWidget.addItem(item_name)
-        self.AddButton.setEnabled(True)
-        self.ClearButton.setEnabled(False)
-        self.SaveButton.setEnabled(False)
-        self.EditButton.setEnabled(False)
-        self.DeleteButton.setEnabled(False)
-
-    def onItemSelected(self):
-        if self.AlertLineEdit.text():
-            QtGui.QMessageBox.information(self,
-                self.trUtf8('Item selected to Edit'),
-                self.trUtf8('Please save or clear selected item'))
-        else:
-            self.EditButton.setEnabled(True)
-            self.DeleteButton.setEnabled(True)
-
-    def onDeleteClick(self):
-        item = self.AlertListWidget.currentItem()
-        if item:
-            item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
-            self.parent.manager.delete_alert(item_id)
-            row = self.AlertListWidget.row(item)
-            self.AlertListWidget.takeItem(row)
-        self.AddButton.setEnabled(True)
-        self.SaveButton.setEnabled(False)
-        self.DeleteButton.setEnabled(False)
-        self.EditButton.setEnabled(False)
-
-    def onEditClick(self):
-        item = self.AlertListWidget.currentItem()
-        if item:
-            self.item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
-            self.AlertLineEdit.setText(unicode(item.text()))
-        self.AddButton.setEnabled(True)
-        self.ClearButton.setEnabled(True)
-        self.SaveButton.setEnabled(True)
-        self.DeleteButton.setEnabled(True)
-        self.EditButton.setEnabled(False)
-
-    def onClearClick(self):
-        self.AlertLineEdit.setText(u'')
-        self.AddButton.setEnabled(False)
-        self.ClearButton.setEnabled(True)
-        self.SaveButton.setEnabled(False)
-        self.DeleteButton.setEnabled(False)
-        self.EditButton.setEnabled(False)
-
-    def onAddClick(self):
-        if len(self.AlertLineEdit.text()) == 0:
-            QtGui.QMessageBox.information(self,
-                self.trUtf8('Item selected to Add'),
-                self.trUtf8('Missing data'))
-        else:
-            alert = AlertItem()
-            alert.text = unicode(self.AlertLineEdit.text())
-            self.manager.save_alert(alert)
-        self.onClearClick()
-        self.loadList()
-
-    def onSaveClick(self):
-        alert = self.manager.get_alert(self.item_id)
-        alert.text = unicode(self.AlertLineEdit.text())
-        self.manager.save_alert(alert)
-        self.onClearClick()
-        self.loadList()
-
-    def onTextChanged(self):
-        self.AddButton.setEnabled(True)
-
-    def onDoubleClick(self):
-        """
-        List item has been double clicked to display it
-        """
-        items = self.AlertListWidget.selectedIndexes()
-        for item in items:
-            bitem = self.AlertListWidget.item(item.row())
-            self.triggerAlert(bitem.text())
-
-    def onSingleClick(self):
-        """
-        List item has been single clicked to add it to
-        the edit field so it can be changed.
-        """
-        items = self.AlertListWidget.selectedIndexes()
-        for item in items:
-            bitem = self.AlertListWidget.item(item.row())
-            self.AlertEntryEditItem.setText(bitem.text())
-
-    def triggerAlert(self, text):
-        self.parent.alertsmanager.displayAlert(text)

=== modified file 'openlp/plugins/alerts/forms/alertstab.py'
--- openlp/plugins/alerts/forms/alertstab.py	2010-03-21 23:58:01 +0000
+++ openlp/plugins/alerts/forms/alertstab.py	2010-03-28 16:03:18 +0000
@@ -26,6 +26,7 @@
 from PyQt4 import QtCore, QtGui
 
 from openlp.core.lib import SettingsTab, str_to_bool
+from openlp.plugins.alerts.lib.models import AlertItem
 
 class AlertsTab(SettingsTab):
     """
@@ -33,6 +34,7 @@
     """
     def __init__(self, parent, section=None):
         self.parent = parent
+        self.manager = parent.manager
         SettingsTab.__init__(self, parent.name, section)
 
     def setupUi(self):
@@ -149,22 +151,6 @@
             QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
         self.HistoryLayout.addItem(self.HistorySpacer)
         self.FontLayout.addWidget(self.HistoryWidget)
-        self.HistoryEditWidget = QtGui.QWidget(self.FontGroupBox)
-        self.HistoryEditWidget.setObjectName(u'HistoryEditWidget')
-        self.HistoryEditLayout = QtGui.QHBoxLayout(self.HistoryEditWidget)
-        self.HistoryEditLayout.setSpacing(8)
-        self.HistoryEditLayout.setMargin(0)
-        self.HistoryEditLayout.setObjectName(u'HistoryEditLayout')
-        self.HistoryEditLabel = QtGui.QLabel(self.HistoryEditWidget)
-        self.HistoryEditLabel.setObjectName(u'HistoryEditLabel')
-        self.HistoryEditLayout.addWidget(self.HistoryEditLabel)
-        self.HistoryEditPushButton = QtGui.QPushButton(self.HistoryEditWidget)
-        self.HistoryEditPushButton.setObjectName(u'HistoryEditPushButton')
-        self.HistoryEditLayout.addWidget(self.HistoryEditPushButton)
-        self.HistoryEditSpacer = QtGui.QSpacerItem(147, 20,
-            QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
-        self.HistoryEditLayout.addItem(self.HistoryEditSpacer)
-        self.FontLayout.addWidget(self.HistoryEditWidget)
         self.SlideLeftLayout.addWidget(self.FontGroupBox)
         self.SlideLeftSpacer = QtGui.QSpacerItem(20, 94,
             QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
@@ -201,6 +187,43 @@
         self.SlideRightSpacer = QtGui.QSpacerItem(20, 40,
             QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
         self.SlideRightLayout.addItem(self.SlideRightSpacer)
+        self.layoutWidget = QtGui.QWidget(self)
+        self.layoutWidget.setGeometry(QtCore.QRect(20, 10, 361, 251))
+        self.layoutWidget.setObjectName(u'layoutWidget')
+        self.verticalLayout_2 = QtGui.QVBoxLayout(self.layoutWidget)
+        self.verticalLayout_2.setObjectName(u'verticalLayout_2')
+        self.horizontalLayout_2 = QtGui.QHBoxLayout()
+        self.horizontalLayout_2.setObjectName(u'horizontalLayout_2')
+        self.AlertLineEdit = QtGui.QLineEdit(self.layoutWidget)
+        self.AlertLineEdit.setObjectName(u'AlertLineEdit')
+        self.horizontalLayout_2.addWidget(self.AlertLineEdit)
+        self.verticalLayout_2.addLayout(self.horizontalLayout_2)
+        self.horizontalLayout = QtGui.QHBoxLayout()
+        self.horizontalLayout.setObjectName(u'horizontalLayout')
+        self.AlertListWidget = QtGui.QListWidget(self.layoutWidget)
+        self.AlertListWidget.setAlternatingRowColors(True)
+        self.AlertListWidget.setObjectName(u'AlertListWidget')
+        self.horizontalLayout.addWidget(self.AlertListWidget)
+        self.verticalLayout = QtGui.QVBoxLayout()
+        self.verticalLayout.setObjectName(u'verticalLayout')
+        self.SaveButton = QtGui.QPushButton(self.layoutWidget)
+        self.SaveButton.setObjectName(u'SaveButton')
+        self.verticalLayout.addWidget(self.SaveButton)
+        self.ClearButton = QtGui.QPushButton(self.layoutWidget)
+        self.ClearButton.setObjectName(u'ClearButton')
+        self.verticalLayout.addWidget(self.ClearButton)
+        self.AddButton = QtGui.QPushButton(self.layoutWidget)
+        self.AddButton.setObjectName(u'AddButton')
+        self.verticalLayout.addWidget(self.AddButton)
+        self.EditButton = QtGui.QPushButton(self.layoutWidget)
+        self.EditButton.setObjectName(u'EditButton')
+        self.verticalLayout.addWidget(self.EditButton)
+        self.DeleteButton = QtGui.QPushButton(self.layoutWidget)
+        self.DeleteButton.setObjectName(u'DeleteButton')
+        self.verticalLayout.addWidget(self.DeleteButton)
+        self.horizontalLayout.addLayout(self.verticalLayout)
+        self.verticalLayout_2.addLayout(self.horizontalLayout)
+        self.SlideRightLayout.addWidget(self.layoutWidget)
         self.AlertsLayout.addWidget(self.AlertRightColumn)
         # Signals and slots
         QtCore.QObject.connect(self.HistoryCheckBox,
@@ -210,8 +233,6 @@
             QtCore.SIGNAL(u'pressed()'), self.onBackgroundColorButtonClicked)
         QtCore.QObject.connect(self.FontColorButton,
             QtCore.SIGNAL(u'pressed()'), self.onFontColorButtonClicked)
-        QtCore.QObject.connect(self.HistoryEditPushButton,
-            QtCore.SIGNAL(u'pressed()'), self.onHistoryEditButtonClicked)
         QtCore.QObject.connect(self.FontComboBox,
             QtCore.SIGNAL(u'activated(int)'), self.onFontComboBoxClicked)
         QtCore.QObject.connect(self.LocationComboBox,
@@ -220,6 +241,27 @@
             QtCore.SIGNAL(u'valueChanged(int)'), self.onTimeoutSpinBoxChanged)
         QtCore.QObject.connect(self.FontSizeSpinBox,
             QtCore.SIGNAL(u'valueChanged(int)'), self.onFontSizeSpinBoxChanged)
+        QtCore.QObject.connect(self.DeleteButton,
+                               QtCore.SIGNAL(u'clicked()'),
+                               self.onDeleteClick)
+        QtCore.QObject.connect(self.ClearButton,
+                               QtCore.SIGNAL(u'clicked()'),
+                               self.onClearClick)
+        QtCore.QObject.connect(self.EditButton,
+                               QtCore.SIGNAL(u'clicked()'),
+                               self.onEditClick)
+        QtCore.QObject.connect(self.AddButton,
+                               QtCore.SIGNAL(u'clicked()'),
+                               self.onAddClick)
+        QtCore.QObject.connect(self.SaveButton,
+                               QtCore.SIGNAL(u'clicked()'),
+                               self.onSaveClick)
+        QtCore.QObject.connect(self.AlertListWidget,
+            QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
+            self.onItemSelected)
+        QtCore.QObject.connect(self.AlertListWidget,
+            QtCore.SIGNAL(u'clicked(QModelIndex)'),
+            self.onItemSelected)
 
     def retranslateUi(self):
         self.FontGroupBox.setTitle(self.trUtf8('Font'))
@@ -232,11 +274,15 @@
         self.TimeoutSpinBox.setSuffix(self.trUtf8('s'))
         self.LocationLabel.setText(self.trUtf8('Location:'))
         self.HistoryLabel.setText(self.trUtf8('Keep History:'))
-        self.HistoryEditLabel.setText(self.trUtf8('Edit History:'))
         self.PreviewGroupBox.setTitle(self.trUtf8('Preview'))
         self.FontPreview.setText(self.trUtf8('openlp.org'))
         self.LocationComboBox.setItemText(0, self.trUtf8('Top'))
         self.LocationComboBox.setItemText(1, self.trUtf8('Bottom'))
+        self.SaveButton.setText(self.trUtf8('Save'))
+        self.ClearButton.setText(self.trUtf8('Clear'))
+        self.AddButton.setText(self.trUtf8('Add'))
+        self.EditButton.setText(self.trUtf8('Edit'))
+        self.DeleteButton.setText(self.trUtf8('Delete'))
 
     def onBackgroundColorButtonClicked(self):
         self.bg_color = QtGui.QColorDialog.getColor(
@@ -271,9 +317,6 @@
         self.font_size = self.FontSizeSpinBox.value()
         self.updateDisplay()
 
-    def onHistoryEditButtonClicked(self):
-        self.parent.onAlertsEdit()
-
     def load(self):
         self.timeout = int(self.config.get_config(u'timeout', 5))
         self.font_color = unicode(
@@ -298,6 +341,75 @@
         font.setFamily(self.font_face)
         self.FontComboBox.setCurrentFont(font)
         self.updateDisplay()
+        self.loadList()
+
+    def loadList(self):
+        self.AlertListWidget.clear()
+        alerts = self.manager.get_all_alerts()
+        for alert in alerts:
+            item_name = QtGui.QListWidgetItem(alert.text)
+            item_name.setData(
+                QtCore.Qt.UserRole, QtCore.QVariant(alert.id))
+            self.AlertListWidget.addItem(item_name)
+        self.AddButton.setEnabled(True)
+        self.ClearButton.setEnabled(False)
+        self.SaveButton.setEnabled(False)
+        self.EditButton.setEnabled(False)
+        self.DeleteButton.setEnabled(False)
+
+    def onItemSelected(self):
+        self.EditButton.setEnabled(True)
+        self.DeleteButton.setEnabled(True)
+
+    def onDeleteClick(self):
+        item = self.AlertListWidget.currentItem()
+        if item:
+            item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
+            self.parent.manager.delete_alert(item_id)
+            row = self.AlertListWidget.row(item)
+            self.AlertListWidget.takeItem(row)
+        self.AddButton.setEnabled(True)
+        self.SaveButton.setEnabled(False)
+        self.DeleteButton.setEnabled(False)
+        self.EditButton.setEnabled(False)
+
+    def onEditClick(self):
+        item = self.AlertListWidget.currentItem()
+        if item:
+            self.item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
+            self.AlertLineEdit.setText(unicode(item.text()))
+        self.AddButton.setEnabled(True)
+        self.ClearButton.setEnabled(True)
+        self.SaveButton.setEnabled(True)
+        self.DeleteButton.setEnabled(True)
+        self.EditButton.setEnabled(False)
+
+    def onClearClick(self):
+        self.AlertLineEdit.setText(u'')
+        self.AddButton.setEnabled(False)
+        self.ClearButton.setEnabled(True)
+        self.SaveButton.setEnabled(False)
+        self.DeleteButton.setEnabled(False)
+        self.EditButton.setEnabled(False)
+
+    def onAddClick(self):
+        if len(self.AlertLineEdit.text()) == 0:
+            QtGui.QMessageBox.information(self,
+                self.trUtf8('Item selected to Add'),
+                self.trUtf8('Missing data'))
+        else:
+            alert = AlertItem()
+            alert.text = unicode(self.AlertLineEdit.text())
+            self.manager.save_alert(alert)
+        self.onClearClick()
+        self.loadList()
+
+    def onSaveClick(self):
+        alert = self.manager.get_alert(self.item_id)
+        alert.text = unicode(self.AlertLineEdit.text())
+        self.manager.save_alert(alert)
+        self.onClearClick()
+        self.loadList()
 
     def save(self):
         self.font_face = self.FontComboBox.currentFont().family()

=== modified file 'openlp/plugins/bibles/lib/mediaitem.py'
--- openlp/plugins/bibles/lib/mediaitem.py	2010-03-27 19:59:35 +0000
+++ openlp/plugins/bibles/lib/mediaitem.py	2010-03-28 16:03:18 +0000
@@ -59,6 +59,7 @@
         self.ListViewWithDnD_class = BibleListView
         self.servicePath = None
         self.lastReference = []
+        self.addToServiceItem = True
         MediaManagerItem.__init__(self, parent, icon, title)
         # place to store the search results
         self.search_results = {}
@@ -80,6 +81,7 @@
         self.hasNewIcon = False
         self.hasEditIcon = False
         self.hasDeleteIcon = False
+        self.addToServiceItem = True
 
     def addEndHeaderBar(self):
         self.SearchTabWidget = QtGui.QTabWidget(self)
@@ -447,7 +449,7 @@
         raw_slides = []
         raw_footer = []
         bible_text = u''
-        service_item.autoPreviewAllowed = True
+        service_item.auto_preview_allowed = True
         #If we want to use a 2nd translation / version
         bible2 = u''
         if self.SearchTabWidget.currentIndex() == 0:
@@ -506,7 +508,11 @@
                 if self.parent.settings_tab.layout_style == 0:
                     raw_slides.append(bible_text)
                     bible_text = u''
-            service_item.title = u'%s %s' % (book, verse_text)
+            if not service_item.title:
+                service_item.title = u'%s %s' % (book, verse_text)
+            elif service_item.title.find(self.trUtf8(u'etc')) == -1:
+                service_item.title = u'%s, %s' \
+                    % (service_item.title, self.trUtf8(u'etc'))
         if  len(self.parent.settings_tab.bible_theme) == 0:
             service_item.theme = None
         else:
@@ -602,4 +608,4 @@
 
     def searchByReference(self, bible, search):
         log.debug(u'searchByReference %s, %s', bible, search)
-        self.search_results = self.parent.manager.get_verses(bible, search)
+        self.search_results = self.parent.manager.get_verses(bible, search)
\ No newline at end of file

=== modified file 'openlp/plugins/custom/lib/mediaitem.py'
--- openlp/plugins/custom/lib/mediaitem.py	2010-03-21 23:58:01 +0000
+++ openlp/plugins/custom/lib/mediaitem.py	2010-03-28 16:03:18 +0000
@@ -144,7 +144,7 @@
             item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
         else:
             item_id = self.remoteCustom
-        service_item.autoPreviewAllowed = True
+        service_item.auto_preview_allowed = True
         customSlide = self.parent.custommanager.get_custom(item_id)
         title = customSlide.title
         credit = customSlide.credits
@@ -166,4 +166,4 @@
         else:
             raw_footer.append(u'')
         service_item.raw_footer = raw_footer
-        return True
+        return True
\ No newline at end of file

=== modified file 'openlp/plugins/images/lib/mediaitem.py'
--- openlp/plugins/images/lib/mediaitem.py	2010-03-21 23:58:01 +0000
+++ openlp/plugins/images/lib/mediaitem.py	2010-03-28 16:03:18 +0000
@@ -27,7 +27,8 @@
 import os
 
 from PyQt4 import QtCore, QtGui
-from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon
+from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
+contextMenuAction, contextMenuSeparator
 
 log = logging.getLogger(__name__)
 
@@ -53,7 +54,6 @@
         self.ListViewWithDnD_class = ImageListView
         self.servicePath = None
         MediaManagerItem.__init__(self, parent, icon, title)
-        self.overrideActive = False
 
     def initPluginNameVisible(self):
         self.PluginNameVisible = self.trUtf8('Image')
@@ -68,6 +68,7 @@
         self.hasFileIcon = True
         self.hasNewIcon = False
         self.hasEditIcon = False
+        self.addToServiceItem = True
 
     def initialise(self):
         log.debug(u'initialise')
@@ -81,6 +82,15 @@
             os.mkdir(self.servicePath)
         self.loadList(self.parent.config.load_list(self.ConfigSection))
 
+    def addListViewToToolBar(self):
+        MediaManagerItem.addListViewToToolBar(self)
+        self.ListView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
+        self.ListView.addAction(
+            contextMenuAction(
+                self.ListView, u':/slides/slide_blank.png',
+                self.trUtf8('Replace Live Background'),
+                self.onReplaceClick))
+
     def addEndHeaderBar(self):
         self.ImageWidget = QtGui.QWidget(self)
         sizePolicy = QtGui.QSizePolicy(
@@ -91,38 +101,24 @@
             self.ImageWidget.sizePolicy().hasHeightForWidth())
         self.ImageWidget.setSizePolicy(sizePolicy)
         self.ImageWidget.setObjectName(u'ImageWidget')
-        self.OverrideLayout = QtGui.QVBoxLayout(self.ImageWidget)
-        self.OverrideLayout.setMargin(5)
-        self.OverrideLayout.setSpacing(4)
-        self.OverrideLayout.setObjectName(u'OverrideLayout')
-        self.OverrideCheckBox = QtGui.QCheckBox(self.ImageWidget)
-        self.OverrideCheckBox.setObjectName(u'OverrideCheckBox')
-        self.OverrideCheckBox.setCheckable(True)
-        self.OverrideCheckBox.setChecked(False)
-        self.OverrideCheckBox.setText(self.trUtf8('Override background'))
-        self.OverrideCheckBox.setStatusTip(
-            self.trUtf8('Allow the background of live slide to be overridden'))
-        self.OverrideLayout.addWidget(self.OverrideCheckBox)
-        self.OverrideLabel = QtGui.QLabel(self.ImageWidget)
-        self.OverrideLabel.setObjectName(u'OverrideLabel')
-        self.OverrideLayout.addWidget(self.OverrideLabel)
+        self.blankButton = self.Toolbar.addToolbarButton(
+            u'Replace Background', u':/slides/slide_blank.png',
+            self.trUtf8('Replace Live Background'), self.onReplaceClick, False)
         # Add the song widget to the page layout
         self.PageLayout.addWidget(self.ImageWidget)
-        QtCore.QObject.connect(self.OverrideCheckBox,
-            QtCore.SIGNAL(u'stateChanged(int)'),
-            self.toggleOverrideState)
 
     def onDeleteClick(self):
-        item = self.ListView.currentItem()
-        if item:
-            try:
-                os.remove(os.path.join(self.servicePath, unicode(item.text())))
-            except:
-                #if not present do not worry
-                pass
-            row = self.ListView.row(item)
-            self.ListView.takeItem(row)
-            self.parent.config.set_list(self.ConfigSection, self.getFileList())
+        items = self.ListView.selectedIndexes()
+        if items:
+            for item in items:
+                text = self.ListView.item(item.row())
+                try:
+                    os.remove(os.path.join(self.servicePath, unicode(text.text())))
+                except:
+                    #if not present do not worry
+                    pass
+                self.ListView.takeItem(item.row())
+                self.parent.config.set_list(self.ConfigSection, self.getFileList())
 
     def loadList(self, list):
         for file in list:
@@ -144,7 +140,8 @@
         items = self.ListView.selectedIndexes()
         if items:
             service_item.title = self.trUtf8('Image(s)')
-            service_item.autoPreviewAllowed = True
+            service_item.auto_preview_allowed = True
+            service_item.maintain_allowed = True
             for item in items:
                 bitem = self.ListView.item(item.row())
                 filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString())
@@ -155,24 +152,17 @@
         else:
             return False
 
-    def toggleOverrideState(self):
-        self.overrideActive = not self.overrideActive
-        if not self.overrideActive:
-            self.OverrideLabel.setText(u'')
-            self.parent.render_manager.override_background = None
+    def onReplaceClick(self):
+        if not self.ListView.selectedIndexes():
+            QtGui.QMessageBox.information(self,
+                self.trUtf8('No item selected...'),
+                self.trUtf8('You must select one item'))
+        items = self.ListView.selectedIndexes()
+        for item in items:
+            bitem = self.ListView.item(item.row())
+            filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString())
+            frame = QtGui.QImage(unicode(filename))
+            self.parent.maindisplay.addImageWithText(frame)
 
     def onPreviewClick(self):
-        if self.overrideActive:
-            if not self.ListView.selectedIndexes():
-                QtGui.QMessageBox.information(self,
-                    self.trUtf8('No items selected...'),
-                    self.trUtf8('You must select one or more items'))
-            items = self.ListView.selectedIndexes()
-            for item in items:
-                bitem = self.ListView.item(item.row())
-                filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString())
-                self.OverrideLabel.setText(bitem.text())
-                frame = QtGui.QImage(unicode(filename))
-                self.parent.maindisplay.addImageWithText(frame)
-        else:
-            MediaManagerItem.onPreviewClick(self)
+        MediaManagerItem.onPreviewClick(self)
\ No newline at end of file

=== modified file 'openlp/plugins/songs/forms/editsongform.py'
--- openlp/plugins/songs/forms/editsongform.py	2010-03-23 15:14:20 +0000
+++ openlp/plugins/songs/forms/editsongform.py	2010-03-28 16:03:18 +0000
@@ -411,9 +411,10 @@
             self.SongTabWidget.setCurrentIndex(2)
             self.AuthorsListView.setFocus()
         #split the verse list by space and mark lower case for testing
+        taglist = unicode(self.trUtf8(' bcitped'))
         for verse in unicode(self.VerseOrderEdit.text()).lower().split(u' '):
             if len(verse) > 1:
-                if verse[0:1] == u'v' and verse[1:].isdigit():
+                if verse[0:1] == u'%s' % self.trUtf8('v') and verse[1:].isdigit():
                     pass
                 else:
                     self.SongTabWidget.setCurrentIndex(0)
@@ -421,7 +422,7 @@
                     return False, \
                         self.trUtf8('Invalid verse entry - vX')
             else:
-                if u' bcitped'.find(verse) > -1:
+                if taglist.find(verse) > -1:
                     pass
                 else:
                     self.SongTabWidget.setCurrentIndex(0)

=== modified file 'openlp/plugins/songs/forms/editverseform.py'
--- openlp/plugins/songs/forms/editverseform.py	2010-03-21 23:58:01 +0000
+++ openlp/plugins/songs/forms/editverseform.py	2010-03-28 16:03:18 +0000
@@ -53,32 +53,59 @@
         QtCore.QObject.connect(self.VerseListComboBox,
             QtCore.SIGNAL(u'activated(int)'), self.onVerseComboChanged)
 
+    def startNewLine(self):
+        if self.VerseTextEdit.textCursor().columnNumber() != 0:
+            self.VerseTextEdit.insertPlainText(u'\n')
+
     def onAddIntro(self):
-        self.VerseTextEdit.insertPlainText(u'---[Intro:1]---')
+        self.startNewLine()
+        self.VerseTextEdit.insertPlainText(u'---[%s:1]---\n'
+                                           % self.trUtf8('Intro'))
+        self.VerseTextEdit.setFocus()
 
     def onAddEnding(self):
-        self.VerseTextEdit.insertPlainText(u'---[Ending:1]---')
+        self.startNewLine()
+        self.VerseTextEdit.insertPlainText(u'---[%s:1]---\n'
+                                           % self.trUtf8('Ending'))
+        self.VerseTextEdit.setFocus()
 
     def onAddOther(self):
-        self.VerseTextEdit.insertPlainText(u'---[Other:1]---')
+        self.startNewLine()
+        self.VerseTextEdit.insertPlainText(u'---[%s:1]---\n'
+                                           % self.trUtf8('Other'))
+        self.VerseTextEdit.setFocus()
 
     def onAddPreChorus(self):
-        self.VerseTextEdit.insertPlainText(u'---[PreChorus:1]---')
+        self.startNewLine()
+        self.VerseTextEdit.insertPlainText(u'---[%s:1]---\n'
+                                           % self.trUtf8('Pre-Chorus'))
+        self.VerseTextEdit.setFocus()
 
     def onAddBridge(self):
-        self.VerseTextEdit.insertPlainText(u'---[Bridge:1]---')
+        self.startNewLine()
+        self.VerseTextEdit.insertPlainText(u'---[%s:1]---\n'
+                                           % self.trUtf8('Bridge'))
+        self.VerseTextEdit.setFocus()
 
     def onAddChorus(self):
-        self.VerseTextEdit.insertPlainText(u'---[Chorus:1]---')
+        self.startNewLine()
+        self.VerseTextEdit.insertPlainText(u'---[%s:1]---\n'
+                                           % self.trUtf8('Chorus'))
+        self.VerseTextEdit.setFocus()
 
     def onAddVerse(self):
-        self.VerseTextEdit.insertPlainText(u'---[Verse:1]---')
+        self.startNewLine()
+        count = self.VerseTextEdit.toPlainText().\
+                        count(u'---[%s' % self.trUtf8('Verse'))
+        self.VerseTextEdit.insertPlainText(u'---[%s:%s]---\n'
+                                           % (self.trUtf8('Verse'), count + 1))
+        self.VerseTextEdit.setFocus()
 
     def setVerse(self, text, verseCount=0, single=False, tag=u'Verse:1'):
         posVerse = 0
         posSub = 0
         if len(text) == 0 and not single:
-            text = u'---[Verse:1]---\n'
+            text = u'---[%s:1]---\n' % self.trUtf8('Verse')
         if single:
             id = tag.split(u':')
             posVerse = self.VerseListComboBox.findText(id[0], QtCore.Qt.MatchExactly)
@@ -124,11 +151,11 @@
     def getVerseAll(self):
         text = self.VerseTextEdit.toPlainText()
         if not text.startsWith(u'---['):
-            text = u'---[Verse:1]---\n%s' % text
+            text = u'---[%s:1]---\n%s' % (self.trUtf8('Verse'),  text)
         return text
 
     def onVerseComboChanged(self, id):
-        if unicode(self.VerseListComboBox.currentText()) == u'Verse':
+        if unicode(self.VerseListComboBox.currentText()) == self.trUtf8('Verse'):
             self.SubVerseListComboBox.setEnabled(True)
         else:
             self.SubVerseListComboBox.setEnabled(False)

=== modified file 'openlp/plugins/songs/lib/mediaitem.py'
--- openlp/plugins/songs/lib/mediaitem.py	2010-03-23 15:14:20 +0000
+++ openlp/plugins/songs/lib/mediaitem.py	2010-03-28 16:03:18 +0000
@@ -290,7 +290,7 @@
             item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
         else:
             item_id = self.remoteSong
-        service_item.autoPreviewAllowed = True
+        service_item.auto_preview_allowed = True
         song = self.parent.songmanager.get_song(item_id)
         service_item.theme = song.theme_name
         service_item.edit_enabled = True
@@ -345,4 +345,4 @@
         service_item.audit = [
             song.title, author_audit, song.copyright, song.ccli_number
         ]
-        return True
+        return True
\ No newline at end of file

=== added file 'resources/forms/serviceitemeditdialog.ui'
--- resources/forms/serviceitemeditdialog.ui	1970-01-01 00:00:00 +0000
+++ resources/forms/serviceitemeditdialog.ui	2010-03-28 16:03:18 +0000
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ServiceItemEditDialog</class>
+ <widget class="QWidget" name="ServiceItemEditDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>386</width>
+    <height>272</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Service Item Maintenance</string>
+  </property>
+  <widget class="QWidget" name="layoutWidget">
+   <property name="geometry">
+    <rect>
+     <x>20</x>
+     <y>20</y>
+     <width>351</width>
+     <height>241</height>
+    </rect>
+   </property>
+   <layout class="QVBoxLayout" name="outerLayout">
+    <item>
+     <layout class="QHBoxLayout" name="topLayout">
+      <item>
+       <widget class="QListWidget" name="listWidget">
+        <property name="alternatingRowColors">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <layout class="QVBoxLayout" name="buttonLayout">
+        <item>
+         <widget class="QPushButton" name="upButton">
+          <property name="text">
+           <string>Up</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="verticalSpacer">
+          <property name="orientation">
+           <enum>Qt::Vertical</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>20</width>
+            <height>40</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item>
+         <widget class="QPushButton" name="deleteButton">
+          <property name="text">
+           <string>Delete</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="downButton">
+          <property name="text">
+           <string>Down</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </item>
+    <item>
+     <widget class="QDialogButtonBox" name="buttonBox">
+      <property name="standardButtons">
+       <set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
+      </property>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>

=== renamed file 'resources/forms/serviceitemdialog.ui' => 'resources/forms/servicenotedialog.ui'

Follow ups