Bug #730294: Auto-preview, not previewing next item if go live from preview

Bug #735367: Blank to theme won't unblank
Bug #742122: Prevent multiple instances

Also add ability to stop media in the middle.

Add ability to use command line or double click from desktop to pass service file.
(Needs build script changes)

bzr-revno: 1430
Fixes: https://launchpad.net/bugs/742122, https://launchpad.net/bugs/735367, https://launchpad.net/bugs/742122
This commit is contained in:
Tim Bentley 2011-03-27 18:00:30 +01:00
commit 406b07b63f
15 changed files with 238 additions and 52 deletions

View File

@ -38,6 +38,7 @@ from traceback import format_exception
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, check_directory_exists from openlp.core.lib import Receiver, check_directory_exists
from openlp.core.lib.ui import UiStrings
from openlp.core.resources import qInitResources from openlp.core.resources import qInitResources
from openlp.core.ui.mainwindow import MainWindow from openlp.core.ui.mainwindow import MainWindow
from openlp.core.ui.firsttimelanguageform import FirstTimeLanguageForm from openlp.core.ui.firsttimelanguageform import FirstTimeLanguageForm
@ -77,6 +78,13 @@ class OpenLP(QtGui.QApplication):
class in order to provide the core of the application. class in order to provide the core of the application.
""" """
def exec_(self):
"""
Override exec method to allow the shared memory to be released on exit
"""
QtGui.QApplication.exec_()
self.sharedMemory.detach()
def run(self): def run(self):
""" """
Run the OpenLP application. Run the OpenLP application.
@ -107,7 +115,7 @@ class OpenLP(QtGui.QApplication):
# make sure Qt really display the splash screen # make sure Qt really display the splash screen
self.processEvents() self.processEvents()
# start the main app window # start the main app window
self.mainWindow = MainWindow(screens, self.clipboard()) self.mainWindow = MainWindow(screens, self)
self.mainWindow.show() self.mainWindow.show()
if show_splash: if show_splash:
# now kill the splashscreen # now kill the splashscreen
@ -122,6 +130,24 @@ class OpenLP(QtGui.QApplication):
VersionThread(self.mainWindow).start() VersionThread(self.mainWindow).start()
return self.exec_() return self.exec_()
def isAlreadyRunning(self):
"""
Look to see if OpenLP is already running and ask if a 2nd copy
is to be started.
"""
self.sharedMemory = QtCore.QSharedMemory('OpenLP')
if self.sharedMemory.attach():
status = QtGui.QMessageBox.critical(None,
UiStrings.Error, UiStrings.OpenLPStart,
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No))
if status == QtGui.QMessageBox.No:
return True
return False
else:
self.sharedMemory.create(1)
return False
def hookException(self, exctype, value, traceback): def hookException(self, exctype, value, traceback):
if not hasattr(self, u'mainWindow'): if not hasattr(self, u'mainWindow'):
log.exception(''.join(format_exception(exctype, value, traceback))) log.exception(''.join(format_exception(exctype, value, traceback)))
@ -194,6 +220,9 @@ def main():
qInitResources() qInitResources()
# Now create and actually run the application. # Now create and actually run the application.
app = OpenLP(qt_args) app = OpenLP(qt_args)
# Instance check
if app.isAlreadyRunning():
sys.exit()
app.setOrganizationName(u'OpenLP') app.setOrganizationName(u'OpenLP')
app.setOrganizationDomain(u'openlp.org') app.setOrganizationDomain(u'openlp.org')
app.setApplicationName(u'OpenLP') app.setApplicationName(u'OpenLP')

View File

@ -101,6 +101,10 @@ class EventReceiver(QtCore.QObject):
``servicemanager_previous_item`` ``servicemanager_previous_item``
Display the previous item in the service Display the previous item in the service
``servicemanager_preview_live``
Requests a Preview item from the Service Manager to update live and
add a new item to the preview panel
``servicemanager_next_item`` ``servicemanager_next_item``
Display the next item in the service Display the next item in the service

View File

@ -145,7 +145,8 @@ class RenderManager(object):
else: else:
self.theme = self.service_theme self.theme = self.service_theme
else: else:
if theme: # Images have a theme of -1
if theme and theme != -1:
self.theme = theme self.theme = theme
elif theme_level == ThemeLevel.Song or \ elif theme_level == ThemeLevel.Song or \
theme_level == ThemeLevel.Service: theme_level == ThemeLevel.Service:

View File

@ -109,7 +109,9 @@ class ServiceItem(object):
self.edit_id = None self.edit_id = None
self.xml_version = None self.xml_version = None
self.start_time = 0 self.start_time = 0
self.end_time = 0
self.media_length = 0 self.media_length = 0
self.from_service = False
self._new_item() self._new_item()
def _new_item(self): def _new_item(self):
@ -261,6 +263,7 @@ class ServiceItem(object):
u'data': self.data_string, u'data': self.data_string,
u'xml_version': self.xml_version, u'xml_version': self.xml_version,
u'start_time': self.start_time, u'start_time': self.start_time,
u'end_time': self.end_time,
u'media_length': self.media_length u'media_length': self.media_length
} }
service_data = [] service_data = []
@ -307,6 +310,8 @@ class ServiceItem(object):
self.xml_version = header[u'xml_version'] self.xml_version = header[u'xml_version']
if u'start_time' in header: if u'start_time' in header:
self.start_time = header[u'start_time'] self.start_time = header[u'start_time']
if u'end_time' in header:
self.end_time = header[u'end_time']
if u'media_length' in header: if u'media_length' in header:
self.media_length = header[u'media_length'] self.media_length = header[u'media_length']
if self.service_item_type == ServiceItemType.Text: if self.service_item_type == ServiceItemType.Text:
@ -449,4 +454,3 @@ class ServiceItem(object):
return end return end
else: else:
return u'%s : %s' % (start, end) return u'%s : %s' % (start, end)

View File

@ -57,6 +57,7 @@ class UiStrings(object):
Export = translate('OpenLP.Ui', 'Export') Export = translate('OpenLP.Ui', 'Export')
FontSizePtUnit = translate('OpenLP.Ui', 'pt', FontSizePtUnit = translate('OpenLP.Ui', 'pt',
'Abbreviated font pointsize unit') 'Abbreviated font pointsize unit')
Hours = translate('OpenLP.Ui', 'h', 'The abbreviated unit for hours')
Image = translate('OpenLP.Ui', 'Image') Image = translate('OpenLP.Ui', 'Image')
Import = translate('OpenLP.Ui', 'Import') Import = translate('OpenLP.Ui', 'Import')
LengthTime = unicode(translate('OpenLP.Ui', 'Length %s')) LengthTime = unicode(translate('OpenLP.Ui', 'Length %s'))
@ -64,6 +65,7 @@ class UiStrings(object):
LiveBGError = translate('OpenLP.Ui', 'Live Background Error') LiveBGError = translate('OpenLP.Ui', 'Live Background Error')
LivePanel = translate('OpenLP.Ui', 'Live Panel') LivePanel = translate('OpenLP.Ui', 'Live Panel')
Load = translate('OpenLP.Ui', 'Load') Load = translate('OpenLP.Ui', 'Load')
Minutes = translate('OpenLP.Ui', 'm', 'The abbreviated unit for minutes')
Middle = translate('OpenLP.Ui', 'Middle') Middle = translate('OpenLP.Ui', 'Middle')
New = translate('OpenLP.Ui', 'New') New = translate('OpenLP.Ui', 'New')
NewService = translate('OpenLP.Ui', 'New Service') NewService = translate('OpenLP.Ui', 'New Service')
@ -74,6 +76,8 @@ class UiStrings(object):
NISp = translate('OpenLP.Ui', 'No Items Selected', 'Plural') NISp = translate('OpenLP.Ui', 'No Items Selected', 'Plural')
OLPV1 = translate('OpenLP.Ui', 'openlp.org 1.x') OLPV1 = translate('OpenLP.Ui', 'openlp.org 1.x')
OLPV2 = translate('OpenLP.Ui', 'OpenLP 2.0') OLPV2 = translate('OpenLP.Ui', 'OpenLP 2.0')
OpenLPStart = translate('OpenLP.Ui', 'OpenLP is already running. Do you '
'wish to continue?')
OpenService = translate('OpenLP.Ui', 'Open Service') OpenService = translate('OpenLP.Ui', 'Open Service')
Preview = translate('OpenLP.Ui', 'Preview') Preview = translate('OpenLP.Ui', 'Preview')
PreviewPanel = translate('OpenLP.Ui', 'Preview Panel') PreviewPanel = translate('OpenLP.Ui', 'Preview Panel')
@ -82,7 +86,7 @@ class UiStrings(object):
ReplaceLiveBG = translate('OpenLP.Ui', 'Replace Live Background') ReplaceLiveBG = translate('OpenLP.Ui', 'Replace Live Background')
ResetBG = translate('OpenLP.Ui', 'Reset Background') ResetBG = translate('OpenLP.Ui', 'Reset Background')
ResetLiveBG = translate('OpenLP.Ui', 'Reset Live Background') ResetLiveBG = translate('OpenLP.Ui', 'Reset Live Background')
S = translate('OpenLP.Ui', 's', 'The abbreviated unit for seconds') Seconds = translate('OpenLP.Ui', 's', 'The abbreviated unit for seconds')
SaveAndPreview = translate('OpenLP.Ui', 'Save && Preview') SaveAndPreview = translate('OpenLP.Ui', 'Save && Preview')
Search = translate('OpenLP.Ui', 'Search') Search = translate('OpenLP.Ui', 'Search')
SelectDelete = translate('OpenLP.Ui', 'You must select an item to delete.') SelectDelete = translate('OpenLP.Ui', 'You must select an item to delete.')

View File

@ -105,6 +105,9 @@ class GeneralTab(SettingsTab):
self.saveCheckServiceCheckBox = QtGui.QCheckBox(self.settingsGroupBox) self.saveCheckServiceCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
self.saveCheckServiceCheckBox.setObjectName(u'saveCheckServiceCheckBox') self.saveCheckServiceCheckBox.setObjectName(u'saveCheckServiceCheckBox')
self.settingsLayout.addRow(self.saveCheckServiceCheckBox) self.settingsLayout.addRow(self.saveCheckServiceCheckBox)
self.autoUnblankCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
self.autoUnblankCheckBox.setObjectName(u'autoUnblankCheckBox')
self.settingsLayout.addRow(self.autoUnblankCheckBox)
self.autoPreviewCheckBox = QtGui.QCheckBox(self.settingsGroupBox) self.autoPreviewCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
self.autoPreviewCheckBox.setObjectName(u'autoPreviewCheckBox') self.autoPreviewCheckBox.setObjectName(u'autoPreviewCheckBox')
self.settingsLayout.addRow(self.autoPreviewCheckBox) self.settingsLayout.addRow(self.autoPreviewCheckBox)
@ -224,6 +227,8 @@ class GeneralTab(SettingsTab):
translate('OpenLP.GeneralTab', 'Application Settings')) translate('OpenLP.GeneralTab', 'Application Settings'))
self.saveCheckServiceCheckBox.setText(translate('OpenLP.GeneralTab', self.saveCheckServiceCheckBox.setText(translate('OpenLP.GeneralTab',
'Prompt to save before starting a new service')) 'Prompt to save before starting a new service'))
self.autoUnblankCheckBox.setText(translate('OpenLP.GeneralTab',
'Unblank display when adding new live item'))
self.autoPreviewCheckBox.setText(translate('OpenLP.GeneralTab', self.autoPreviewCheckBox.setText(translate('OpenLP.GeneralTab',
'Automatically preview next item in service')) 'Automatically preview next item in service'))
self.timeoutLabel.setText(translate('OpenLP.GeneralTab', self.timeoutLabel.setText(translate('OpenLP.GeneralTab',
@ -262,6 +267,8 @@ class GeneralTab(SettingsTab):
u'songselect password', QtCore.QVariant(u'')).toString())) u'songselect password', QtCore.QVariant(u'')).toString()))
self.saveCheckServiceCheckBox.setChecked(settings.value(u'save prompt', self.saveCheckServiceCheckBox.setChecked(settings.value(u'save prompt',
QtCore.QVariant(False)).toBool()) QtCore.QVariant(False)).toBool())
self.autoUnblankCheckBox.setChecked(settings.value(u'auto unblank',
QtCore.QVariant(False)).toBool())
self.monitorComboBox.setCurrentIndex(self.monitorNumber) self.monitorComboBox.setCurrentIndex(self.monitorNumber)
self.displayOnMonitorCheck.setChecked(self.screens.display) self.displayOnMonitorCheck.setChecked(self.screens.display)
self.warningCheckBox.setChecked(settings.value(u'blank warning', self.warningCheckBox.setChecked(settings.value(u'blank warning',
@ -312,6 +319,8 @@ class GeneralTab(SettingsTab):
QtCore.QVariant(self.checkForUpdatesCheckBox.isChecked())) QtCore.QVariant(self.checkForUpdatesCheckBox.isChecked()))
settings.setValue(u'save prompt', settings.setValue(u'save prompt',
QtCore.QVariant(self.saveCheckServiceCheckBox.isChecked())) QtCore.QVariant(self.saveCheckServiceCheckBox.isChecked()))
settings.setValue(u'auto unblank',
QtCore.QVariant(self.autoUnblankCheckBox.isChecked()))
settings.setValue(u'auto preview', settings.setValue(u'auto preview',
QtCore.QVariant(self.autoPreviewCheckBox.isChecked())) QtCore.QVariant(self.autoPreviewCheckBox.isChecked()))
settings.setValue(u'loop delay', settings.setValue(u'loop delay',

View File

@ -367,7 +367,7 @@ class MainDisplay(DisplayWidget):
self.mediaObject.setCurrentSource(Phonon.MediaSource(videoPath)) self.mediaObject.setCurrentSource(Phonon.MediaSource(videoPath))
# Need the timer to trigger set the trigger to 200ms # Need the timer to trigger set the trigger to 200ms
# Value taken from web documentation. # Value taken from web documentation.
if self.serviceItem.start_time != 0: if self.serviceItem.end_time != 0:
self.mediaObject.setTickInterval(200) self.mediaObject.setTickInterval(200)
self.mediaObject.play() self.mediaObject.play()
self.webView.setVisible(False) self.webView.setVisible(False)
@ -401,9 +401,9 @@ class MainDisplay(DisplayWidget):
def videoTick(self, tick): def videoTick(self, tick):
""" """
Triggered on video tick every 200 milli seconds Triggered on video tick every 200 milli seconds
Will be used to manage stop time later
""" """
pass if tick > self.serviceItem.end_time * 1000:
self.videoFinished()
def isWebLoaded(self): def isWebLoaded(self):
""" """
@ -489,6 +489,10 @@ class MainDisplay(DisplayWidget):
self.footer(serviceItem.foot_text) self.footer(serviceItem.foot_text)
# if was hidden keep it hidden # if was hidden keep it hidden
if self.hideMode and self.isLive: if self.hideMode and self.isLive:
if QtCore.QSettings().value(u'general/auto unblank',
QtCore.QVariant(False)).toBool():
Receiver.send_message(u'slidecontroller_live_unblank')
else:
self.hideDisplay(self.hideMode) self.hideDisplay(self.hideMode)
# display hidden for video end we have a new item so must be shown # display hidden for video end we have a new item so must be shown
if self.videoHide and self.isLive: if self.videoHide and self.isLive:

View File

@ -469,14 +469,15 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
actionList = ActionList() actionList = ActionList()
def __init__(self, screens, clipboard): def __init__(self, screens, application):
""" """
This constructor sets up the interface, the various managers, and the This constructor sets up the interface, the various managers, and the
plugins. plugins.
""" """
QtGui.QMainWindow.__init__(self) QtGui.QMainWindow.__init__(self)
self.screens = screens self.screens = screens
self.clipboard = clipboard
self.application = application
# Set up settings sections for the main application # Set up settings sections for the main application
# (not for use by plugins) # (not for use by plugins)
self.uiSettingsSection = u'user interface' self.uiSettingsSection = u'user interface'
@ -660,7 +661,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
if self.liveController.display.isVisible(): if self.liveController.display.isVisible():
self.liveController.display.setFocus() self.liveController.display.setFocus()
self.activateWindow() self.activateWindow()
if QtCore.QSettings().value( if len(self.application.arguments()) > 0:
args = []
for a in self.application.arguments():
args.extend([a])
self.ServiceManagerContents.loadFile(unicode(args[0]))
elif QtCore.QSettings().value(
self.generalSettingsSection + u'/auto open', self.generalSettingsSection + u'/auto open',
QtCore.QVariant(False)).toBool(): QtCore.QVariant(False)).toBool():
self.ServiceManagerContents.loadLastFile() self.ServiceManagerContents.loadLastFile()

View File

@ -33,12 +33,12 @@ from openlp.core.ui.printservicedialog import Ui_PrintServiceDialog, ZoomSize
class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog): class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
def __init__(self, parent, serviceManager): def __init__(self, mainWindow, serviceManager):
""" """
Constructor Constructor
""" """
QtGui.QDialog.__init__(self, parent) QtGui.QDialog.__init__(self, mainWindow)
self.parent = parent self.mainWindow = mainWindow
self.serviceManager = serviceManager self.serviceManager = serviceManager
self.printer = QtGui.QPrinter() self.printer = QtGui.QPrinter()
self.printDialog = QtGui.QPrintDialog(self.printer, self) self.printDialog = QtGui.QPrintDialog(self.printer, self)
@ -134,9 +134,12 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
item.notes.replace(u'\n', u'<br />')) item.notes.replace(u'\n', u'<br />'))
# Add play length of media files. # Add play length of media files.
if item.is_media() and self.metaDataCheckBox.isChecked(): if item.is_media() and self.metaDataCheckBox.isChecked():
tme = item.media_length
if item.end_time > 0:
tme = item.end_time - item.start_time
text += u'<p><strong>%s</strong> %s</p>' % (translate( text += u'<p><strong>%s</strong> %s</p>' % (translate(
'OpenLP.ServiceManager', u'Playing time:'), 'OpenLP.ServiceManager', u'Playing time:'),
unicode(datetime.timedelta(seconds=item.media_length))) unicode(datetime.timedelta(seconds=tme)))
if self.footerTextEdit.toPlainText(): if self.footerTextEdit.toPlainText():
text += u'<h4>%s</h4>%s' % (translate('OpenLP.ServiceManager', text += u'<h4>%s</h4>%s' % (translate('OpenLP.ServiceManager',
u'Custom Service Notes:'), self.footerTextEdit.toPlainText()) u'Custom Service Notes:'), self.footerTextEdit.toPlainText())
@ -181,13 +184,14 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
""" """
Copies the display text to the clipboard as plain text Copies the display text to the clipboard as plain text
""" """
self.parent.clipboard.setText(self.document.toPlainText()) self.mainWindow.application.clipboard.setText(
self.document.toPlainText())
def copyHtmlText(self): def copyHtmlText(self):
""" """
Copies the display text to the clipboard as Html Copies the display text to the clipboard as Html
""" """
self.parent.clipboard.setText(self.document.toHtml()) self.mainWindow.application.clipboard.setText(self.document.toHtml())
def printServiceOrder(self): def printServiceOrder(self):
""" """

View File

@ -141,4 +141,3 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
else: else:
self.upButton.setEnabled(True) self.upButton.setEnabled(True)
self.deleteButton.setEnabled(True) self.deleteButton.setEnabled(True)

View File

@ -231,13 +231,15 @@ class ServiceManager(QtGui.QWidget):
QtCore.QObject.connect(self.themeComboBox, QtCore.QObject.connect(self.themeComboBox,
QtCore.SIGNAL(u'activated(int)'), self.onThemeComboBoxSelected) QtCore.SIGNAL(u'activated(int)'), self.onThemeComboBoxSelected)
QtCore.QObject.connect(self.serviceManagerList, QtCore.QObject.connect(self.serviceManagerList,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.makeLive) QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onMakeLive)
QtCore.QObject.connect(self.serviceManagerList, QtCore.QObject.connect(self.serviceManagerList,
QtCore.SIGNAL(u'itemCollapsed(QTreeWidgetItem*)'), self.collapsed) QtCore.SIGNAL(u'itemCollapsed(QTreeWidgetItem*)'), self.collapsed)
QtCore.QObject.connect(self.serviceManagerList, QtCore.QObject.connect(self.serviceManagerList,
QtCore.SIGNAL(u'itemExpanded(QTreeWidgetItem*)'), self.expanded) QtCore.SIGNAL(u'itemExpanded(QTreeWidgetItem*)'), self.expanded)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList) QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'servicemanager_preview_live'), self.previewLive)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'servicemanager_next_item'), self.nextItem) QtCore.SIGNAL(u'servicemanager_next_item'), self.nextItem)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
@ -561,6 +563,7 @@ class ServiceManager(QtGui.QWidget):
self.newFile() self.newFile()
for item in items: for item in items:
serviceItem = ServiceItem() serviceItem = ServiceItem()
serviceItem.from_service = True
serviceItem.render_manager = self.mainwindow.renderManager serviceItem.render_manager = self.mainwindow.renderManager
serviceItem.set_from_service(item, self.servicePath) serviceItem.set_from_service(item, self.servicePath)
self.validateItem(serviceItem) self.validateItem(serviceItem)
@ -658,10 +661,6 @@ class ServiceManager(QtGui.QWidget):
item = self.findServiceItem()[0] item = self.findServiceItem()[0]
self.startTimeForm.item = self.serviceItems[item] self.startTimeForm.item = self.serviceItems[item]
if self.startTimeForm.exec_(): if self.startTimeForm.exec_():
self.serviceItems[item][u'service_item'].start_time = \
self.startTimeForm.hourSpinBox.value() * 3600 + \
self.startTimeForm.minuteSpinBox.value() * 60 + \
self.startTimeForm.secondSpinBox.value()
self.repaintServiceList(item, -1) self.repaintServiceList(item, -1)
def onServiceItemEditForm(self): def onServiceItemEditForm(self):
@ -672,6 +671,19 @@ class ServiceManager(QtGui.QWidget):
self.addServiceItem(self.serviceItemEditForm.getServiceItem(), self.addServiceItem(self.serviceItemEditForm.getServiceItem(),
replace=True, expand=self.serviceItems[item][u'expanded']) replace=True, expand=self.serviceItems[item][u'expanded'])
def previewLive(self, message):
"""
Called by the SlideController to request a preview item be made live
and allows the next preview to be updated if relevent.
"""
id, row = message.split(u':')
for sitem in self.serviceItems:
if sitem[u'service_item']._uuid == id:
item = self.serviceManagerList.topLevelItem(sitem[u'order'] - 1)
self.serviceManagerList.setCurrentItem(item)
self.makeLive(int(row))
return
def nextItem(self): def nextItem(self):
""" """
Called by the SlideController to select the next service item. Called by the SlideController to select the next service item.
@ -1027,6 +1039,7 @@ class ServiceManager(QtGui.QWidget):
if expand is None: if expand is None:
expand = self.expandTabs expand = self.expandTabs
item.render() item.render()
item.from_service = True
if replace: if replace:
sitem, child = self.findServiceItem() sitem, child = self.findServiceItem()
item.merge(self.serviceItems[sitem][u'service_item']) item.merge(self.serviceItems[sitem][u'service_item'])
@ -1081,11 +1094,24 @@ class ServiceManager(QtGui.QWidget):
else: else:
return self.serviceItems[item][u'service_item'] return self.serviceItems[item][u'service_item']
def makeLive(self): def onMakeLive(self):
"""
Send the current item to the Live slide controller but triggered
by a tablewidget click event.
"""
self.makeLive()
def makeLive(self, row=-1):
""" """
Send the current item to the Live slide controller Send the current item to the Live slide controller
``row``
Row number to be displayed if from preview.
-1 is passed if the value is not set
""" """
item, child = self.findServiceItem() item, child = self.findServiceItem()
if row != -1:
child = row
if self.serviceItems[item][u'service_item'].is_valid: if self.serviceItems[item][u'service_item'].is_valid:
self.mainwindow.liveController.addServiceManagerItem( self.mainwindow.liveController.addServiceManagerItem(
self.serviceItems[item][u'service_item'], child) self.serviceItems[item][u'service_item'], child)

View File

@ -185,7 +185,7 @@ class SlideController(QtGui.QWidget):
self.delaySpinBox.setMinimum(1) self.delaySpinBox.setMinimum(1)
self.delaySpinBox.setMaximum(180) self.delaySpinBox.setMaximum(180)
self.toolbar.addToolbarWidget(u'Image SpinBox', self.delaySpinBox) self.toolbar.addToolbarWidget(u'Image SpinBox', self.delaySpinBox)
self.delaySpinBox.setSuffix(UiStrings.S) self.delaySpinBox.setSuffix(UiStrings.Seconds)
self.delaySpinBox.setToolTip(translate('OpenLP.SlideController', self.delaySpinBox.setToolTip(translate('OpenLP.SlideController',
'Delay between slides in seconds')) 'Delay between slides in seconds'))
else: else:
@ -1014,6 +1014,10 @@ class SlideController(QtGui.QWidget):
""" """
row = self.previewListWidget.currentRow() row = self.previewListWidget.currentRow()
if row > -1 and row < self.previewListWidget.rowCount(): if row > -1 and row < self.previewListWidget.rowCount():
if self.serviceItem.from_service:
Receiver.send_message('servicemanager_preview_live',
u'%s:%s' % (self.serviceItem._uuid, row))
else:
self.parent.liveController.addServiceManagerItem( self.parent.liveController.addServiceManagerItem(
self.serviceItem, row) self.serviceItem, row)

View File

@ -32,39 +32,90 @@ from openlp.core.lib.ui import UiStrings, create_accept_reject_button_box
class Ui_StartTimeDialog(object): class Ui_StartTimeDialog(object):
def setupUi(self, StartTimeDialog): def setupUi(self, StartTimeDialog):
StartTimeDialog.setObjectName(u'StartTimeDialog') StartTimeDialog.setObjectName(u'StartTimeDialog')
StartTimeDialog.resize(300, 10) StartTimeDialog.resize(350, 10)
self.dialogLayout = QtGui.QGridLayout(StartTimeDialog) self.dialogLayout = QtGui.QGridLayout(StartTimeDialog)
self.dialogLayout.setObjectName(u'dialogLayout') self.dialogLayout.setObjectName(u'dialogLayout')
self.startLabel = QtGui.QLabel(StartTimeDialog)
self.startLabel.setObjectName(u'startLabel')
self.startLabel.setAlignment(QtCore.Qt.AlignHCenter)
self.dialogLayout.addWidget(self.startLabel, 0, 1, 1, 1)
self.finishLabel = QtGui.QLabel(StartTimeDialog)
self.finishLabel.setObjectName(u'finishLabel')
self.finishLabel.setAlignment(QtCore.Qt.AlignHCenter)
self.dialogLayout.addWidget(self.finishLabel, 0, 2, 1, 1)
self.lengthLabel = QtGui.QLabel(StartTimeDialog)
self.lengthLabel.setObjectName(u'startLabel')
self.lengthLabel.setAlignment(QtCore.Qt.AlignHCenter)
self.dialogLayout.addWidget(self.lengthLabel, 0, 3, 1, 1)
self.hourLabel = QtGui.QLabel(StartTimeDialog) self.hourLabel = QtGui.QLabel(StartTimeDialog)
self.hourLabel.setObjectName("hourLabel") self.hourLabel.setObjectName(u'hourLabel')
self.dialogLayout.addWidget(self.hourLabel, 0, 0, 1, 1) self.dialogLayout.addWidget(self.hourLabel, 1, 0, 1, 1)
self.hourSpinBox = QtGui.QSpinBox(StartTimeDialog) self.hourSpinBox = QtGui.QSpinBox(StartTimeDialog)
self.hourSpinBox.setObjectName("hourSpinBox") self.hourSpinBox.setObjectName(u'hourSpinBox')
self.dialogLayout.addWidget(self.hourSpinBox, 0, 1, 1, 1) self.hourSpinBox.setMinimum(0)
self.hourSpinBox.setMaximum(4)
self.dialogLayout.addWidget(self.hourSpinBox, 1, 1, 1, 1)
self.hourFinishSpinBox = QtGui.QSpinBox(StartTimeDialog)
self.hourFinishSpinBox.setObjectName(u'hourFinishSpinBox')
self.hourFinishSpinBox.setMinimum(0)
self.hourFinishSpinBox.setMaximum(4)
self.dialogLayout.addWidget(self.hourFinishSpinBox, 1, 2, 1, 1)
self.hourFinishLabel = QtGui.QLabel(StartTimeDialog)
self.hourFinishLabel.setObjectName(u'hourLabel')
self.hourFinishLabel.setAlignment(QtCore.Qt.AlignRight)
self.dialogLayout.addWidget(self.hourFinishLabel, 1, 3, 1, 1)
self.minuteLabel = QtGui.QLabel(StartTimeDialog) self.minuteLabel = QtGui.QLabel(StartTimeDialog)
self.minuteLabel.setObjectName("minuteLabel") self.minuteLabel.setObjectName(u'minuteLabel')
self.dialogLayout.addWidget(self.minuteLabel, 1, 0, 1, 1) self.dialogLayout.addWidget(self.minuteLabel, 2, 0, 1, 1)
self.minuteSpinBox = QtGui.QSpinBox(StartTimeDialog) self.minuteSpinBox = QtGui.QSpinBox(StartTimeDialog)
self.minuteSpinBox.setObjectName("minuteSpinBox") self.minuteSpinBox.setObjectName(u'minuteSpinBox')
self.dialogLayout.addWidget(self.minuteSpinBox, 1, 1, 1, 1) self.minuteSpinBox.setMinimum(0)
self.minuteSpinBox.setMaximum(59)
self.dialogLayout.addWidget(self.minuteSpinBox, 2, 1, 1, 1)
self.minuteFinishSpinBox = QtGui.QSpinBox(StartTimeDialog)
self.minuteFinishSpinBox.setObjectName(u'minuteFinishSpinBox')
self.minuteFinishSpinBox.setMinimum(0)
self.minuteFinishSpinBox.setMaximum(59)
self.dialogLayout.addWidget(self.minuteFinishSpinBox, 2, 2, 1, 1)
self.minuteFinishLabel = QtGui.QLabel(StartTimeDialog)
self.minuteFinishLabel.setObjectName(u'minuteLabel')
self.minuteFinishLabel.setAlignment(QtCore.Qt.AlignRight)
self.dialogLayout.addWidget(self.minuteFinishLabel, 2, 3, 1, 1)
self.secondLabel = QtGui.QLabel(StartTimeDialog) self.secondLabel = QtGui.QLabel(StartTimeDialog)
self.secondLabel.setObjectName("secondLabel") self.secondLabel.setObjectName(u'secondLabel')
self.dialogLayout.addWidget(self.secondLabel, 2, 0, 1, 1) self.dialogLayout.addWidget(self.secondLabel, 3, 0, 1, 1)
self.secondSpinBox = QtGui.QSpinBox(StartTimeDialog) self.secondSpinBox = QtGui.QSpinBox(StartTimeDialog)
self.secondSpinBox.setObjectName("secondSpinBox") self.secondSpinBox.setObjectName(u'secondSpinBox')
self.dialogLayout.addWidget(self.secondSpinBox, 2, 1, 1, 1) self.secondSpinBox.setMinimum(0)
self.secondSpinBox.setMaximum(59)
self.secondFinishSpinBox = QtGui.QSpinBox(StartTimeDialog)
self.secondFinishSpinBox.setObjectName(u'secondFinishSpinBox')
self.secondFinishSpinBox.setMinimum(0)
self.secondFinishSpinBox.setMaximum(59)
self.dialogLayout.addWidget(self.secondFinishSpinBox, 3, 2, 1, 1)
self.secondFinishLabel = QtGui.QLabel(StartTimeDialog)
self.secondFinishLabel.setObjectName(u'secondLabel')
self.secondFinishLabel.setAlignment(QtCore.Qt.AlignRight)
self.dialogLayout.addWidget(self.secondFinishLabel, 3, 3, 1, 1)
self.dialogLayout.addWidget(self.secondSpinBox, 3, 1, 1, 1)
self.buttonBox = create_accept_reject_button_box(StartTimeDialog, True) self.buttonBox = create_accept_reject_button_box(StartTimeDialog, True)
self.dialogLayout.addWidget(self.buttonBox, 4, 0, 1, 2) self.dialogLayout.addWidget(self.buttonBox, 5, 2, 1, 2)
self.retranslateUi(StartTimeDialog) self.retranslateUi(StartTimeDialog)
self.setMaximumHeight(self.sizeHint().height()) self.setMaximumHeight(self.sizeHint().height())
QtCore.QMetaObject.connectSlotsByName(StartTimeDialog) QtCore.QMetaObject.connectSlotsByName(StartTimeDialog)
def retranslateUi(self, StartTimeDialog): def retranslateUi(self, StartTimeDialog):
self.setWindowTitle(translate('OpenLP.StartTimeForm', self.setWindowTitle(translate('OpenLP.StartTimeForm',
'Item Start Time')) 'Item Start and Finish Time'))
self.hourSpinBox.setSuffix(UiStrings.Hours)
self.minuteSpinBox.setSuffix(UiStrings.Minutes)
self.secondSpinBox.setSuffix(UiStrings.Seconds)
self.hourFinishSpinBox.setSuffix(UiStrings.Hours)
self.minuteFinishSpinBox.setSuffix(UiStrings.Minutes)
self.secondFinishSpinBox.setSuffix(UiStrings.Seconds)
self.hourLabel.setText(translate('OpenLP.StartTimeForm', 'Hours:')) self.hourLabel.setText(translate('OpenLP.StartTimeForm', 'Hours:'))
self.hourSpinBox.setSuffix(translate('OpenLP.StartTimeForm', 'h'))
self.minuteSpinBox.setSuffix(translate('OpenLP.StartTimeForm', 'm'))
self.secondSpinBox.setSuffix(UiStrings.S)
self.minuteLabel.setText(translate('OpenLP.StartTimeForm', 'Minutes:')) self.minuteLabel.setText(translate('OpenLP.StartTimeForm', 'Minutes:'))
self.secondLabel.setText(translate('OpenLP.StartTimeForm', 'Seconds:')) self.secondLabel.setText(translate('OpenLP.StartTimeForm', 'Seconds:'))
self.startLabel.setText(translate('OpenLP.StartTimeForm', 'Start'))
self.finishLabel.setText(translate('OpenLP.StartTimeForm', 'Finish'))
self.lengthLabel.setText(translate('OpenLP.StartTimeForm', 'Length'))

View File

@ -28,6 +28,9 @@ from PyQt4 import QtGui
from starttimedialog import Ui_StartTimeDialog from starttimedialog import Ui_StartTimeDialog
from openlp.core.lib import translate
from openlp.core.lib.ui import UiStrings, critical_error_message_box
class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog): class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog):
""" """
The exception dialog The exception dialog
@ -40,13 +43,51 @@ class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog):
""" """
Run the Dialog with correct heading. Run the Dialog with correct heading.
""" """
seconds = self.item[u'service_item'].start_time hour, minutes, seconds = self._time_split(
self.item[u'service_item'].start_time)
self.hourSpinBox.setValue(hour)
self.minuteSpinBox.setValue(minutes)
self.secondSpinBox.setValue(seconds)
hours, minutes, seconds = self._time_split(
self.item[u'service_item'].media_length)
self.hourFinishSpinBox.setValue(hours)
self.minuteFinishSpinBox.setValue(minutes)
self.secondFinishSpinBox.setValue(seconds)
self.hourFinishLabel.setText(u'%s%s' % (unicode(hour), UiStrings.Hours))
self.minuteFinishLabel.setText(u'%s%s' %
(unicode(minutes), UiStrings.Minutes))
self.secondFinishLabel.setText(u'%s%s' %
(unicode(seconds), UiStrings.Seconds))
return QtGui.QDialog.exec_(self)
def accept(self):
start = self.hourSpinBox.value() * 3600 + \
self.minuteSpinBox.value() * 60 + \
self.secondSpinBox.value()
end = self.hourFinishSpinBox.value() * 3600 + \
self.minuteFinishSpinBox.value() * 60 + \
self.secondFinishSpinBox.value()
if end > self.item[u'service_item'].media_length:
critical_error_message_box(
title=translate('OpenLP.StartTimeForm',
'Time Validation Error'),
message=translate('OpenLP.StartTimeForm',
'End time is set after the end of the media item'))
return
elif start > end:
critical_error_message_box(
title=translate('OpenLP.StartTimeForm',
'Time Validation Error'),
message=translate('OpenLP.StartTimeForm',
'Start time is after the End Time of the media item'))
return
self.item[u'service_item'].start_time = start
self.item[u'service_item'].end_time = end
return QtGui.QDialog.accept(self)
def _time_split(self, seconds):
hours = seconds / 3600 hours = seconds / 3600
seconds -= 3600 * hours seconds -= 3600 * hours
minutes = seconds / 60 minutes = seconds / 60
seconds -= 60 * minutes seconds -= 60 * minutes
self.hourSpinBox.setValue(hours) return hours, minutes, seconds
self.minuteSpinBox.setValue(minutes)
self.secondSpinBox.setValue(seconds)
return QtGui.QDialog.exec_(self)

View File

@ -112,7 +112,7 @@ class AlertsTab(SettingsTab):
self.FontSizeSpinBox.setSuffix(UiStrings.FontSizePtUnit) self.FontSizeSpinBox.setSuffix(UiStrings.FontSizePtUnit)
self.TimeoutLabel.setText( self.TimeoutLabel.setText(
translate('AlertsPlugin.AlertsTab', 'Alert timeout:')) translate('AlertsPlugin.AlertsTab', 'Alert timeout:'))
self.TimeoutSpinBox.setSuffix(UiStrings.S) self.TimeoutSpinBox.setSuffix(UiStrings.Seconds)
self.PreviewGroupBox.setTitle(UiStrings.Preview) self.PreviewGroupBox.setTitle(UiStrings.Preview)
self.FontPreview.setText(UiStrings.OLPV2) self.FontPreview.setText(UiStrings.OLPV2)