← Back to team overview

openlp-core team mailing list archive

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

 

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

Requested reviews:
  OpenLP Core (openlp-core)


Fix indentation from last merge
Add time to more service item types
Add video slider bar to preview.
Change hide live to transparent live!
Split video out to own display so text over video can work.
Number of other bugs fixed.
Custom editor has slide split button now.
-- 
https://code.launchpad.net/~trb143/openlp/working/+merge/23159
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/lib/serviceitem.py'
--- openlp/core/lib/serviceitem.py	2010-04-03 07:10:31 +0000
+++ openlp/core/lib/serviceitem.py	2010-04-10 18:18:19 +0000
@@ -47,6 +47,7 @@
    AllowsEdit = 2
    AllowsMaintain = 3
    RequiresMedia = 4
+   AllowsLoop = 5
 
 
 class ServiceItem(object):

=== modified file 'openlp/core/ui/__init__.py'
--- openlp/core/ui/__init__.py	2010-03-28 21:57:54 +0000
+++ openlp/core/ui/__init__.py	2010-04-10 18:18:19 +0000
@@ -28,6 +28,7 @@
 from serviceitemeditform import ServiceItemEditForm
 from screen import ScreenList
 from maindisplay import MainDisplay
+from maindisplay import VideoDisplay
 from amendthemeform import AmendThemeForm
 from slidecontroller import SlideController
 from splashscreen import SplashScreen

=== modified file 'openlp/core/ui/maindisplay.py'
--- openlp/core/ui/maindisplay.py	2010-04-03 07:10:31 +0000
+++ openlp/core/ui/maindisplay.py	2010-04-10 18:18:19 +0000
@@ -95,13 +95,9 @@
         DisplayWidget.__init__(self, None)
         self.parent = parent
         self.setWindowTitle(u'OpenLP Display')
+        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
+        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
         self.screens = screens
-        self.mediaObject = Phonon.MediaObject(self)
-        self.video = Phonon.VideoWidget()
-        self.video.setVisible(False)
-        self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
-        Phonon.createPath(self.mediaObject, self.video)
-        Phonon.createPath(self.mediaObject, self.audio)
         self.display_image = QtGui.QLabel(self)
         self.display_image.setScaledContents(True)
         self.display_text = QtGui.QLabel(self)
@@ -113,25 +109,14 @@
         self.blankFrame = None
         self.frame = None
         self.firstTime = True
-        self.mediaLoaded = False
         self.hasTransition = False
         self.mediaBackground = False
         QtCore.QObject.connect(Receiver.get_receiver(),
             QtCore.SIGNAL(u'live_slide_hide'), self.hideDisplay)
         QtCore.QObject.connect(Receiver.get_receiver(),
             QtCore.SIGNAL(u'live_slide_show'), self.showDisplay)
-        QtCore.QObject.connect(self.mediaObject,
-            QtCore.SIGNAL(u'finished()'), self.onMediaFinish)
         QtCore.QObject.connect(Receiver.get_receiver(),
             QtCore.SIGNAL(u'media_start'), self.onMediaQueue)
-        QtCore.QObject.connect(Receiver.get_receiver(),
-            QtCore.SIGNAL(u'media_play'), self.onMediaPlay)
-        QtCore.QObject.connect(Receiver.get_receiver(),
-            QtCore.SIGNAL(u'media_pause'), self.onMediaPause)
-        QtCore.QObject.connect(Receiver.get_receiver(),
-            QtCore.SIGNAL(u'media_stop'), self.onMediaStop)
-        QtCore.QObject.connect(Receiver.get_receiver(),
-            QtCore.SIGNAL(u'update_config'), self.setup)
 
     def setup(self):
         """
@@ -144,7 +129,6 @@
         #Sort out screen locations and sizes
         self.setGeometry(self.screen[u'size'])
         self.display_alert.setGeometry(self.screen[u'size'])
-        self.video.setGeometry(self.screen[u'size'])
         self.display_image.resize(self.screen[u'size'].width(),
                             self.screen[u'size'].height())
         self.display_text.resize(self.screen[u'size'].width(),
@@ -177,6 +161,7 @@
                                          self.screen[u'size'].height())
         self.transparent.fill(QtCore.Qt.transparent)
         self.display_alert.setPixmap(self.transparent)
+        self.display_text.setPixmap(self.transparent)
         self.frameView(self.transparent)
         # To display or not to display?
         if not self.screen[u'primary']:
@@ -187,6 +172,7 @@
             self.primary = True
 
     def resetDisplay(self):
+        log.debug(u'resetDisplay')
         Receiver.send_message(u'stop_display_loop')
         if self.primary:
             self.setVisible(False)
@@ -194,28 +180,33 @@
             self.showFullScreen()
 
     def hideDisplay(self):
-        self.mediaLoaded = True
-        self.setVisible(False)
+        log.debug(u'hideDisplay')
+        self.display_image.setPixmap(self.transparent)
+        self.display_alert.setPixmap(self.transparent)
+        self.display_text.setPixmap(self.transparent)
 
     def showDisplay(self):
-        self.mediaLoaded = False
+        log.debug(u'showDisplay')
         if not self.primary:
             self.setVisible(True)
             self.showFullScreen()
         Receiver.send_message(u'flush_alert')
 
     def addImageWithText(self, frame):
+        log.debug(u'addImageWithText')
         frame = resize_image(frame,
                     self.screen[u'size'].width(),
                     self.screen[u'size'].height() )
         self.display_image.setPixmap(QtGui.QPixmap.fromImage(frame))
 
     def setAlertSize(self, top, height):
+        log.debug(u'setAlertSize')
         self.display_alert.setGeometry(
             QtCore.QRect(0, top,
                         self.screen[u'size'].width(), height))
 
     def addAlertImage(self, frame, blank=False):
+        log.debug(u'addAlertImage')
         if blank:
             self.display_alert.setPixmap(self.transparent)
         else:
@@ -277,48 +268,134 @@
 
     def onMediaQueue(self, message):
         log.debug(u'Queue new media message %s' % message)
-        self.display_image.close()
-        self.display_text.close()
-        self.display_alert.close()
+        self.hideDisplay()
+        self.activateWindow()
+
+class VideoWidget(QtGui.QWidget):
+    """
+    Customised version of QTableWidget which can respond to keyboard
+    events.
+    """
+    log.info(u'MainDisplay loaded')
+
+    def __init__(self, parent=None, name=None):
+        QtGui.QWidget.__init__(self, None)
+        self.parent = parent
+        self.hotkey_map = {QtCore.Qt.Key_Return: 'servicemanager_next_item',
+                           QtCore.Qt.Key_Space: 'live_slidecontroller_next_noloop',
+                           QtCore.Qt.Key_Enter: 'live_slidecontroller_next_noloop',
+                           QtCore.Qt.Key_0: 'servicemanager_next_item',
+                           QtCore.Qt.Key_Backspace: 'live_slidecontroller_previous_noloop'}
+
+    def keyPressEvent(self, event):
+        if type(event) == QtGui.QKeyEvent:
+            #here accept the event and do something
+            if event.key() == QtCore.Qt.Key_Up:
+                Receiver.send_message(u'live_slidecontroller_previous')
+                event.accept()
+            elif event.key() == QtCore.Qt.Key_Down:
+                Receiver.send_message(u'live_slidecontroller_next')
+                event.accept()
+            elif event.key() == QtCore.Qt.Key_PageUp:
+                Receiver.send_message(u'live_slidecontroller_first')
+                event.accept()
+            elif event.key() == QtCore.Qt.Key_PageDown:
+                Receiver.send_message(u'live_slidecontroller_last')
+                event.accept()
+            elif event.key() in self.hotkey_map:
+                Receiver.send_message(self.hotkey_map[event.key()])
+                event.accept()
+            elif event.key() == QtCore.Qt.Key_Escape:
+                self.resetDisplay()
+                event.accept()
+            event.ignore()
+        else:
+            event.ignore()
+
+class VideoDisplay(VideoWidget):
+    """
+    This is the form that is used to display videos on the projector.
+    """
+    log.info(u'VideoDisplay Loaded')
+
+    def __init__(self, parent, screens):
+        """
+        The constructor for the display form.
+
+        ``parent``
+            The parent widget.
+
+        ``screens``
+            The list of screens.
+        """
+        log.debug(u'VideoDisplay Initilisation started')
+        VideoWidget.__init__(self, parent)
+        self.setWindowTitle(u'OpenLP Video Display')
+        self.parent = parent
+        self.screens = screens
+        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
+        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
+        self.mediaObject = Phonon.MediaObject(self)
+        self.video = Phonon.VideoWidget()
+        self.video.setVisible(False)
+        self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
+        Phonon.createPath(self.mediaObject, self.video)
+        Phonon.createPath(self.mediaObject, self.audio)
+        self.firstTime = True
+        QtCore.QObject.connect(Receiver.get_receiver(),
+            QtCore.SIGNAL(u'media_start'), self.onMediaQueue)
+        QtCore.QObject.connect(Receiver.get_receiver(),
+            QtCore.SIGNAL(u'media_play'), self.onMediaPlay)
+        QtCore.QObject.connect(Receiver.get_receiver(),
+            QtCore.SIGNAL(u'media_pause'), self.onMediaPause)
+        QtCore.QObject.connect(Receiver.get_receiver(),
+            QtCore.SIGNAL(u'media_stop'), self.onMediaStop)
+        QtCore.QObject.connect(Receiver.get_receiver(),
+            QtCore.SIGNAL(u'update_config'), self.setup)
+
+    def setup(self):
+        """
+        Sets up the screen on a particular screen.
+        """
+        log.debug(u'VideoDisplay Setup %s for %s ' %(self.screens,
+                                         self.screens.monitor_number))
+        self.setVisible(False)
+        self.screen = self.screens.current
+        #Sort out screen locations and sizes
+        self.setGeometry(self.screen[u'size'])
+        self.video.setGeometry(self.screen[u'size'])
+
+    def onMediaQueue(self, message):
+        log.debug(u'VideoDisplay Queue new media message %s' % message)
         file = os.path.join(message[1], message[2])
         if self.firstTime:
-            self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
+            source = self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
             self.firstTime = False
         else:
             self.mediaObject.enqueue(Phonon.MediaSource(file))
         self.onMediaPlay()
 
     def onMediaPlay(self):
-        log.debug(u'Play the new media, Live ')
-        if not self.mediaLoaded and not self.displayBlank:
-            self.blankDisplay()
-            self.display_frame = self.blankFrame
+        log.debug(u'VideoDisplay Play the new media, Live ')
         self.firstTime = True
-        self.mediaLoaded = True
-        self.display_image.hide()
-        self.display_text.hide()
-        self.display_alert.hide()
+        self.setWindowState(QtCore.Qt.WindowMinimized)
         self.video.setFullScreen(True)
-        self.video.setVisible(True)
         self.mediaObject.play()
         self.setVisible(True)
-        self.hide()
+        self.lower()
 
     def onMediaPause(self):
-        log.debug(u'Media paused by user')
+        log.debug(u'VideoDisplay Media paused by user')
         self.mediaObject.pause()
 
     def onMediaStop(self):
-        log.debug(u'Media stopped by user')
+        log.debug(u'VideoDisplay Media stopped by user')
         self.mediaObject.stop()
         self.onMediaFinish()
 
     def onMediaFinish(self):
-        log.debug(u'Reached end of media playlist')
+        log.debug(u'VideoDisplay Reached end of media playlist')
         self.mediaObject.stop()
         self.mediaObject.clearQueue()
-        self.mediaLoaded = False
         self.video.setVisible(False)
-        self.display_text.show()
-        self.display_image.show()
-        self.blankDisplay(False, False)
+        self.setVisible(False)

=== modified file 'openlp/core/ui/mainwindow.py'
--- openlp/core/ui/mainwindow.py	2010-04-02 18:12:54 +0000
+++ openlp/core/ui/mainwindow.py	2010-04-10 18:18:19 +0000
@@ -30,7 +30,7 @@
 
 from openlp.core.ui import AboutForm, SettingsForm,  \
     ServiceManager, ThemeManager, MainDisplay, SlideController, \
-    PluginForm, MediaDockManager
+    PluginForm, MediaDockManager, VideoDisplay
 from openlp.core.lib import RenderManager, PluginConfig, build_icon, \
     OpenLPDockWidget, SettingsManager, PluginManager, Receiver, str_to_bool
 from openlp.core.utils import check_latest_version, AppLocation
@@ -443,6 +443,7 @@
         self.serviceNotSaved = False
         self.settingsmanager = SettingsManager(screens)
         self.generalConfig = PluginConfig(u'General')
+        self.videoDisplay = VideoDisplay(self, screens)
         self.mainDisplay = MainDisplay(self, screens)
         self.aboutForm = AboutForm(self, applicationVersion)
         self.settingsForm = SettingsForm(self.screens, self, self)
@@ -572,11 +573,14 @@
         self.showMaximized()
         #screen_number = self.getMonitorNumber()
         self.mainDisplay.setup()
+        self.videoDisplay.setup()
         if self.mainDisplay.isVisible():
             self.mainDisplay.setFocus()
         self.activateWindow()
         if str_to_bool(self.generalConfig.get_config(u'auto open', False)):
             self.ServiceManagerContents.onLoadService(True)
+        self.videoDisplay.lower()
+        self.mainDisplay.raise_()
 
     def blankCheck(self):
         if str_to_bool(self.generalConfig.get_config(u'screen blank', False)) \
@@ -633,16 +637,19 @@
             if ret == QtGui.QMessageBox.Save:
                 self.ServiceManagerContents.onSaveService()
                 self.mainDisplay.close()
+                self.videoDisplay.close()
                 self.cleanUp()
                 event.accept()
             elif ret == QtGui.QMessageBox.Discard:
                 self.mainDisplay.close()
+                self.videoDisplay.close()
                 self.cleanUp()
                 event.accept()
             else:
                 event.ignore()
         else:
             self.mainDisplay.close()
+            self.videoDisplay.close()
             self.cleanUp()
             event.accept()
 

=== modified file 'openlp/core/ui/slidecontroller.py'
--- openlp/core/ui/slidecontroller.py	2010-04-03 08:42:51 +0000
+++ openlp/core/ui/slidecontroller.py	2010-04-10 18:18:19 +0000
@@ -96,7 +96,7 @@
         self.isLive = isLive
         self.parent = parent
         self.songsconfig = PluginConfig(u'Songs')
-        self.image_list = [
+        self.loop_list = [
             u'Start Loop',
             u'Stop Loop',
             u'Loop Separator',
@@ -233,6 +233,12 @@
         self.Mediabar.addToolbarButton(
             u'Media Stop',  u':/slides/media_playback_stop.png',
             self.trUtf8('Start playing media'), self.onMediaStop)
+        if not self.isLive:
+            self.seekSlider = Phonon.SeekSlider()
+            self.seekSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
+            self.seekSlider.setObjectName(u'seekSlider')
+            self.Mediabar.addToolbarWidget(
+                u'Seek Slider', self.seekSlider)
         self.volumeSlider = Phonon.VolumeSlider()
         self.volumeSlider.setGeometry(QtCore.QRect(90, 260, 221, 24))
         self.volumeSlider.setObjectName(u'volumeSlider')
@@ -299,7 +305,7 @@
                 QtCore.SIGNAL(u'update_spin_delay'), self.receiveSpinDelay)
             Receiver.send_message(u'request_spin_delay')
         if isLive:
-            self.Toolbar.makeWidgetsInvisible(self.image_list)
+            self.Toolbar.makeWidgetsInvisible(self.loop_list)
         else:
             self.Toolbar.makeWidgetsInvisible(self.song_edit_list)
         self.Mediabar.setVisible(False)
@@ -374,20 +380,19 @@
         self.Toolbar.setVisible(True)
         self.Mediabar.setVisible(False)
         self.Toolbar.makeWidgetsInvisible([u'Song Menu'])
-        self.Toolbar.makeWidgetsInvisible(self.image_list)
+        self.Toolbar.makeWidgetsInvisible(self.loop_list)
         if item.is_text():
-            self.Toolbar.makeWidgetsInvisible(self.image_list)
+            self.Toolbar.makeWidgetsInvisible(self.loop_list)
             if 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
-            if len(item.get_frames()) > 1:
-                self.Toolbar.makeWidgetsVisible(self.image_list)
-        elif item.is_media():
+        if item.is_capable(ItemCapabilities.AllowsLoop) and \
+            len(item.get_frames()) > 1:
+                self.Toolbar.makeWidgetsVisible(self.loop_list)
+        if item.is_media():
             self.Toolbar.setVisible(False)
             self.Mediabar.setVisible(True)
-            self.volumeSlider.setAudioOutput(self.parent.mainDisplay.audio)
+            #self.volumeSlider.setAudioOutput(self.parent.mainDisplay.videoDisplay.audio)
 
     def enablePreviewToolBar(self, item):
         """
@@ -585,7 +590,7 @@
         """
         log.debug(u'onHideDisplay %d' % force)
         if force:
-            self.themeButton.setChecked(True)
+            self.hideButton.setChecked(True)
         if self.hideButton.isChecked():
             self.parent.mainDisplay.hideDisplay()
         else:
@@ -766,6 +771,8 @@
             self.mediaObject.clearQueue()
             file = os.path.join(item.get_frame_path(), item.get_frame_title())
             self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
+            self.seekSlider.setMediaObject(self.mediaObject)
+            self.seekSlider.show()
             self.onMediaPlay()
 
     def onMediaPause(self):

=== modified file 'openlp/plugins/alerts/forms/alertstab.py'
--- openlp/plugins/alerts/forms/alertstab.py	2010-03-22 18:33:54 +0000
+++ openlp/plugins/alerts/forms/alertstab.py	2010-04-10 18:18:19 +0000
@@ -27,6 +27,7 @@
 
 from openlp.core.lib import SettingsTab, str_to_bool
 from openlp.plugins.alerts.lib.models import AlertItem
+from openlp.plugins.alerts.lib import alertsmanager
 
 class AlertsTab(SettingsTab):
     """
@@ -35,6 +36,7 @@
     def __init__(self, parent, section=None):
         self.parent = parent
         self.manager = parent.manager
+        self.alertsmanager = parent.alertsmanager
         SettingsTab.__init__(self, parent.name, section)
 
     def setupUi(self):

=== modified file 'openlp/plugins/alerts/lib/alertsmanager.py'
--- openlp/plugins/alerts/lib/alertsmanager.py	2010-03-21 23:58:01 +0000
+++ openlp/plugins/alerts/lib/alertsmanager.py	2010-04-10 18:18:19 +0000
@@ -40,6 +40,7 @@
     def __init__(self, parent):
         QtCore.QObject.__init__(self)
         self.parent = parent
+        self.screen = None
         self.timer_id = 0
         self.alertList = []
         QtCore.QObject.connect(Receiver.get_receiver(),
@@ -53,8 +54,8 @@
 
     def screenChanged(self):
         log.debug(u'screen changed')
-        self.screen = self.parent.maindisplay.screen
         self.alertTab = self.parent.alertsTab
+        self.screen = self.parent.maindisplay.screens.current
         self.font = QtGui.QFont()
         self.font.setFamily(self.alertTab.font_face)
         self.font.setBold(True)
@@ -76,9 +77,11 @@
             display text
         """
         log.debug(u'display alert called %s' % text)
+        if not self.screen:
+            self.screenChanged()
         self.parent.maindisplay.parent.StatusBar.showMessage(u'')
         self.alertList.append(text)
-        if self.timer_id != 0 or self.parent.maindisplay.mediaLoaded:
+        if self.timer_id != 0:
             self.parent.maindisplay.parent.StatusBar.showMessage(\
                     self.trUtf8(u'Alert message created and delayed'))
             return

=== modified file 'openlp/plugins/bibles/lib/mediaitem.py'
--- openlp/plugins/bibles/lib/mediaitem.py	2010-04-05 06:45:01 +0000
+++ openlp/plugins/bibles/lib/mediaitem.py	2010-04-10 18:18:19 +0000
@@ -449,6 +449,7 @@
         raw_footer = []
         bible_text = u''
         service_item.add_capability(ItemCapabilities.AllowsPreview)
+        service_item.add_capability(ItemCapabilities.AllowsLoop)
         #If we want to use a 2nd translation / version
         bible2 = u''
         if self.SearchTabWidget.currentIndex() == 0:

=== modified file 'openlp/plugins/custom/forms/editcustomdialog.py'
--- openlp/plugins/custom/forms/editcustomdialog.py	2010-03-21 23:58:01 +0000
+++ openlp/plugins/custom/forms/editcustomdialog.py	2010-04-10 18:18:19 +0000
@@ -24,13 +24,14 @@
 ###############################################################################
 
 from PyQt4 import QtCore, QtGui
-from openlp.core.lib import build_icon
 
 class Ui_customEditDialog(object):
     def setupUi(self, customEditDialog):
         customEditDialog.setObjectName(u'customEditDialog')
         customEditDialog.resize(590, 541)
-        icon = build_icon(u':/icon/openlp.org-icon-32.bmp')
+        icon = QtGui.QIcon()
+        icon.addPixmap(QtGui.QPixmap(u':/icon/openlp.org-icon-32.bmp'),
+            QtGui.QIcon.Normal, QtGui.QIcon.Off)
         customEditDialog.setWindowIcon(icon)
         self.gridLayout = QtGui.QGridLayout(customEditDialog)
         self.gridLayout.setObjectName(u'gridLayout')
@@ -52,15 +53,19 @@
         self.verticalLayout = QtGui.QVBoxLayout()
         self.verticalLayout.setObjectName(u'verticalLayout')
         self.UpButton = QtGui.QPushButton(customEditDialog)
-        icon1 = build_icon(u':/services/service_up.png')
+        icon1 = QtGui.QIcon()
+        icon1.addPixmap(QtGui.QPixmap(u':/services/service_up.png'),
+            QtGui.QIcon.Normal, QtGui.QIcon.Off)
         self.UpButton.setIcon(icon1)
         self.UpButton.setObjectName(u'UpButton')
         self.verticalLayout.addWidget(self.UpButton)
-        spacerItem = QtGui.QSpacerItem(20, 128,
-            QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
+        spacerItem = QtGui.QSpacerItem(20, 128, QtGui.QSizePolicy.Minimum,
+            QtGui.QSizePolicy.Expanding)
         self.verticalLayout.addItem(spacerItem)
         self.DownButton = QtGui.QPushButton(customEditDialog)
-        icon2 = build_icon(u':/services/service_down.png')
+        icon2 = QtGui.QIcon()
+        icon2.addPixmap(QtGui.QPixmap(u':/services/service_down.png'),
+            QtGui.QIcon.Normal, QtGui.QIcon.Off)
         self.DownButton.setIcon(icon2)
         self.DownButton.setObjectName(u'DownButton')
         self.verticalLayout.addWidget(self.DownButton)
@@ -97,6 +102,9 @@
         self.ClearButton = QtGui.QPushButton(self.ButtonWidge)
         self.ClearButton.setObjectName(u'ClearButton')
         self.verticalLayout_2.addWidget(self.ClearButton)
+        self.SplitButton = QtGui.QPushButton(self.ButtonWidge)
+        self.SplitButton.setObjectName(u'SplitButton')
+        self.verticalLayout_2.addWidget(self.SplitButton)
         spacerItem1 = QtGui.QSpacerItem(20, 40,
             QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding)
         self.verticalLayout_2.addItem(spacerItem1)
@@ -121,16 +129,15 @@
         self.horizontalLayout_2.addWidget(self.CreditEdit)
         self.gridLayout.addLayout(self.horizontalLayout_2, 4, 0, 1, 1)
         self.buttonBox = QtGui.QDialogButtonBox(customEditDialog)
-        self.buttonBox.setStandardButtons(
-            QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Save)
+        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Save)
         self.buttonBox.setObjectName(u'buttonBox')
         self.gridLayout.addWidget(self.buttonBox, 5, 0, 1, 1)
 
         self.retranslateUi(customEditDialog)
-        QtCore.QObject.connect(self.buttonBox,
-            QtCore.SIGNAL(u'rejected()'), customEditDialog.closePressed)
-        QtCore.QObject.connect(self.buttonBox,
-            QtCore.SIGNAL(u'accepted()'), customEditDialog.accept)
+        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
+            customEditDialog.accept)
+        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'),
+            customEditDialog.closePressed)
         QtCore.QMetaObject.connectSlotsByName(customEditDialog)
         customEditDialog.setTabOrder(self.TitleEdit, self.VerseTextEdit)
         customEditDialog.setTabOrder(self.VerseTextEdit, self.AddButton)
@@ -143,12 +150,11 @@
         customEditDialog.setTabOrder(self.CreditEdit, self.UpButton)
         customEditDialog.setTabOrder(self.UpButton, self.DownButton)
         customEditDialog.setTabOrder(self.DownButton, self.ThemeComboBox)
-        customEditDialog.setTabOrder(self.ThemeComboBox, self.buttonBox)
 
     def retranslateUi(self, customEditDialog):
+        customEditDialog.setWindowTitle(self.trUtf8('Edit Custom Slides'))
         self.UpButton.setToolTip(self.trUtf8('Move slide Up 1'))
         self.DownButton.setToolTip(self.trUtf8('Move slide down 1'))
-        customEditDialog.setWindowTitle(self.trUtf8('Edit Custom Slides'))
         self.TitleLabel.setText(self.trUtf8('Title:'))
         self.AddButton.setText(self.trUtf8('Add New'))
         self.AddButton.setToolTip(self.trUtf8('Add new slide at bottom'))
@@ -162,6 +168,7 @@
         self.DeleteButton.setToolTip(self.trUtf8('Delete selected slide'))
         self.ClearButton.setText(self.trUtf8('Clear'))
         self.ClearButton.setToolTip(self.trUtf8('Clear edit area'))
+        self.SplitButton.setText(self.trUtf8('Split Slide'))
+        self.SplitButton.setToolTip(self.trUtf8('Add slide split'))
         self.ThemeLabel.setText(self.trUtf8('Theme:'))
-        self.ThemeComboBox.setToolTip(self.trUtf8('Set Theme for Slides'))
         self.CreditLabel.setText(self.trUtf8('Credits:'))

=== modified file 'openlp/plugins/custom/forms/editcustomform.py'
--- openlp/plugins/custom/forms/editcustomform.py	2010-03-21 23:58:01 +0000
+++ openlp/plugins/custom/forms/editcustomform.py	2010-04-10 18:18:19 +0000
@@ -68,6 +68,8 @@
             QtCore.SIGNAL(u'pressed()'), self.onUpButtonPressed)
         QtCore.QObject.connect(self.DownButton,
             QtCore.SIGNAL(u'pressed()'), self.onDownButtonPressed)
+        QtCore.QObject.connect(self.SplitButton,
+            QtCore.SIGNAL(u'pressed()'), self.onSplitButtonPressed)
         QtCore.QObject.connect(self.VerseListView,
             QtCore.SIGNAL(u'itemDoubleClicked(QListWidgetItem*)'),
             self.onVerseListViewSelected)
@@ -94,6 +96,7 @@
         self.EditAllButton.setEnabled(True)
         self.SaveButton.setEnabled(False)
         self.ClearButton.setEnabled(False)
+        self.SplitButton.setEnabled(False)
         self.TitleEdit.setText(u'')
         self.CreditEdit.setText(u'')
         self.VerseTextEdit.clear()
@@ -202,12 +205,14 @@
     def onEditAllButtonPressed(self):
         self.editAll = True
         self.AddButton.setEnabled(False)
+        self.SplitButton.setEnabled(True)
         if self.VerseListView.count() > 0:
             verse_list = u''
             for row in range(0, self.VerseListView.count()):
                 item = self.VerseListView.item(row)
                 verse_list += item.text()
-                verse_list += u'\n---\n'
+            if row != self.VerseListView.count() - 1:
+                verse_list += u'\n[---]\n'
             self.editText(verse_list)
 
     def editText(self, text):
@@ -222,7 +227,7 @@
     def onSaveButtonPressed(self):
         if self.editAll:
             self.VerseListView.clear()
-            for row in unicode(self.VerseTextEdit.toPlainText()).split(u'\n---\n'):
+            for row in unicode(self.VerseTextEdit.toPlainText()).split(u'\n[---]\n'):
                 self.VerseListView.addItem(row)
         else:
             self.VerseListView.currentItem().setText(
@@ -241,8 +246,15 @@
         self.SaveButton.setEnabled(False)
         self.EditButton.setEnabled(False)
         self.EditAllButton.setEnabled(True)
+        self.SplitButton.setEnabled(False)
         self.VerseTextEdit.clear()
 
+    def onSplitButtonPressed(self):
+        if self.VerseTextEdit.textCursor().columnNumber() != 0:
+            self.VerseTextEdit.insertPlainText(u'\n')
+        self.VerseTextEdit.insertPlainText(u'[---]\n' )
+        self.VerseTextEdit.setFocus()
+
     def onDeleteButtonPressed(self):
         self.VerseListView.takeItem(self.VerseListView.currentRow())
         self.EditButton.setEnabled(False)
@@ -258,5 +270,5 @@
             return False, self.trUtf8('You need to enter a slide')
         if self.VerseTextEdit.toPlainText():
             self.VerseTextEdit.setFocus()
-            return False, self.trUtf8('You have unsaved data')
+            return False, self.trUtf8('You have unsaved data, please save or clear')
         return True,  u''

=== modified file 'openlp/plugins/custom/lib/mediaitem.py'
--- openlp/plugins/custom/lib/mediaitem.py	2010-04-06 19:16:14 +0000
+++ openlp/plugins/custom/lib/mediaitem.py	2010-04-10 18:18:19 +0000
@@ -149,6 +149,7 @@
             item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
         service_item.add_capability(ItemCapabilities.AllowsEdit)
         service_item.add_capability(ItemCapabilities.AllowsPreview)
+        service_item.add_capability(ItemCapabilities.AllowsLoop)
         customSlide = self.parent.custommanager.get_custom(item_id)
         title = customSlide.title
         credit = customSlide.credits
@@ -169,4 +170,4 @@
         else:
             raw_footer.append(u'')
         service_item.raw_footer = raw_footer
-        return True
\ No newline at end of file
+        return True

=== modified file 'openlp/plugins/images/lib/mediaitem.py'
--- openlp/plugins/images/lib/mediaitem.py	2010-04-07 18:32:54 +0000
+++ openlp/plugins/images/lib/mediaitem.py	2010-04-10 18:18:19 +0000
@@ -139,6 +139,7 @@
             service_item.title = self.trUtf8('Image(s)')
             service_item.add_capability(ItemCapabilities.AllowsMaintain)
             service_item.add_capability(ItemCapabilities.AllowsPreview)
+            service_item.add_capability(ItemCapabilities.AllowsLoop)
             for item in items:
                 bitem = self.ListView.item(item.row())
                 filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString())
@@ -162,4 +163,4 @@
             self.parent.maindisplay.addImageWithText(frame)
 
     def onPreviewClick(self):
-        MediaManagerItem.onPreviewClick(self)
\ No newline at end of file
+        MediaManagerItem.onPreviewClick(self)

=== modified file 'openlp/plugins/songs/lib/mediaitem.py'
--- openlp/plugins/songs/lib/mediaitem.py	2010-04-06 19:16:14 +0000
+++ openlp/plugins/songs/lib/mediaitem.py	2010-04-10 18:18:19 +0000
@@ -306,6 +306,7 @@
             item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
         service_item.add_capability(ItemCapabilities.AllowsEdit)
         service_item.add_capability(ItemCapabilities.AllowsPreview)
+        service_item.add_capability(ItemCapabilities.AllowsLoop)
         song = self.parent.songmanager.get_song(item_id)
         service_item.theme = song.theme_name
         service_item.editId = item_id
@@ -361,4 +362,4 @@
         service_item.audit = [
             song.title, author_audit, song.copyright, song.ccli_number
         ]
-        return True
\ No newline at end of file
+        return True

=== modified file 'resources/forms/editcustomdialog.ui'
--- resources/forms/editcustomdialog.ui	2009-09-11 04:54:22 +0000
+++ resources/forms/editcustomdialog.ui	2010-04-10 18:18:19 +0000
@@ -46,7 +46,7 @@
        <item>
         <widget class="QPushButton" name="UpButton">
          <property name="toolTip">
-          <string extracomment="Move selected slide up one"/>
+          <string extracomment="Move slide up 1"/>
          </property>
          <property name="text">
           <string/>
@@ -73,7 +73,7 @@
        <item>
         <widget class="QPushButton" name="DownButton">
          <property name="toolTip">
-          <string extracomment="Move selected slide down one"/>
+          <string extracomment="Move slide down 1"/>
          </property>
          <property name="text">
           <string/>
@@ -106,7 +106,7 @@
          <item>
           <widget class="QPushButton" name="AddButton">
            <property name="toolTip">
-            <string extracomment="Adds a  new slide at bottom of list"/>
+            <string extracomment="Adds a new slide at bottom"/>
            </property>
            <property name="text">
             <string>Add New</string>
@@ -136,7 +136,7 @@
          <item>
           <widget class="QPushButton" name="SaveButton">
            <property name="toolTip">
-            <string extracomment="Save changed slide"/>
+            <string extracomment="Replace edited slide"/>
            </property>
            <property name="text">
             <string>Save</string>
@@ -164,6 +164,16 @@
           </widget>
          </item>
          <item>
+          <widget class="QPushButton" name="SplitButton">
+           <property name="toolTip">
+            <string extracomment="Add new slide split"/>
+           </property>
+           <property name="text">
+            <string>Split Slide</string>
+           </property>
+          </widget>
+         </item>
+         <item>
           <spacer name="ButtonSpacer">
            <property name="orientation">
             <enum>Qt::Vertical</enum>
@@ -216,8 +226,11 @@
    </item>
    <item row="5" column="0">
     <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="toolTip">
+      <string extracomment="Edit dialog"/>
+     </property>
      <property name="standardButtons">
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
      </property>
     </widget>
    </item>
@@ -236,12 +249,44 @@
   <tabstop>UpButton</tabstop>
   <tabstop>DownButton</tabstop>
   <tabstop>ThemeComboBox</tabstop>
-  <tabstop>buttonBox</tabstop>
  </tabstops>
  <resources>
   <include location="../images/openlp-2.qrc"/>
  </resources>
- <connections/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>customEditDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>294</x>
+     <y>524</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>294</x>
+     <y>270</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>customEditDialog</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>294</x>
+     <y>524</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>294</x>
+     <y>270</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
  <slots>
   <slot>accept()</slot>
   <slot>rejected()</slot>

=== modified file 'setup.py'
--- setup.py	2010-04-09 19:15:26 +0000
+++ setup.py	2010-04-10 18:18:19 +0000
@@ -69,7 +69,7 @@
     license='GNU General Public License',
     packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
     scripts=['openlp.pyw', 'scripts/openlp-1to2-converter.py',
-    'scripts/bible-1to2-converter.py','scripts/openlp-remoteclient.py'],
+        'scripts/bible-1to2-converter.py','scripts/openlp-remoteclient.py'],
     include_package_data=True,
     zip_safe=False,
     install_requires=[


Follow ups