diff --git a/openlp.pyw b/openlp.pyw
index 8d5a17a28..b8c16c585 100755
--- a/openlp.pyw
+++ b/openlp.pyw
@@ -38,6 +38,7 @@ from traceback import format_exception
from PyQt4 import QtCore, QtGui
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.ui.mainwindow import MainWindow
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.
"""
+ 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):
"""
Run the OpenLP application.
@@ -107,7 +115,7 @@ class OpenLP(QtGui.QApplication):
# make sure Qt really display the splash screen
self.processEvents()
# start the main app window
- self.mainWindow = MainWindow(screens, self.clipboard())
+ self.mainWindow = MainWindow(screens, self)
self.mainWindow.show()
if show_splash:
# now kill the splashscreen
@@ -122,6 +130,24 @@ class OpenLP(QtGui.QApplication):
VersionThread(self.mainWindow).start()
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):
if not hasattr(self, u'mainWindow'):
log.exception(''.join(format_exception(exctype, value, traceback)))
@@ -194,6 +220,9 @@ def main():
qInitResources()
# Now create and actually run the application.
app = OpenLP(qt_args)
+ # Instance check
+ if app.isAlreadyRunning():
+ sys.exit()
app.setOrganizationName(u'OpenLP')
app.setOrganizationDomain(u'openlp.org')
app.setApplicationName(u'OpenLP')
diff --git a/openlp/core/lib/eventreceiver.py b/openlp/core/lib/eventreceiver.py
index a8034fbb6..bee195b0f 100644
--- a/openlp/core/lib/eventreceiver.py
+++ b/openlp/core/lib/eventreceiver.py
@@ -101,6 +101,10 @@ class EventReceiver(QtCore.QObject):
``servicemanager_previous_item``
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``
Display the next item in the service
diff --git a/openlp/core/lib/rendermanager.py b/openlp/core/lib/rendermanager.py
index a88bd6e39..d866fd115 100644
--- a/openlp/core/lib/rendermanager.py
+++ b/openlp/core/lib/rendermanager.py
@@ -146,7 +146,8 @@ class RenderManager(object):
else:
self.theme = self.service_theme
else:
- if theme:
+ # Images have a theme of -1
+ if theme and theme != -1:
self.theme = theme
elif theme_level == ThemeLevel.Song or \
theme_level == ThemeLevel.Service:
diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py
index 249236f98..7496bc6b0 100644
--- a/openlp/core/lib/serviceitem.py
+++ b/openlp/core/lib/serviceitem.py
@@ -109,7 +109,9 @@ class ServiceItem(object):
self.edit_id = None
self.xml_version = None
self.start_time = 0
+ self.end_time = 0
self.media_length = 0
+ self.from_service = False
self._new_item()
def _new_item(self):
@@ -261,6 +263,7 @@ class ServiceItem(object):
u'data': self.data_string,
u'xml_version': self.xml_version,
u'start_time': self.start_time,
+ u'end_time': self.end_time,
u'media_length': self.media_length
}
service_data = []
@@ -307,6 +310,8 @@ class ServiceItem(object):
self.xml_version = header[u'xml_version']
if u'start_time' in header:
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:
self.media_length = header[u'media_length']
if self.service_item_type == ServiceItemType.Text:
@@ -449,4 +454,3 @@ class ServiceItem(object):
return end
else:
return u'%s : %s' % (start, end)
-
diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py
index 776b8e349..c1a9f8b35 100644
--- a/openlp/core/lib/ui.py
+++ b/openlp/core/lib/ui.py
@@ -57,6 +57,7 @@ class UiStrings(object):
Export = translate('OpenLP.Ui', 'Export')
FontSizePtUnit = translate('OpenLP.Ui', 'pt',
'Abbreviated font pointsize unit')
+ Hours = translate('OpenLP.Ui', 'h', 'The abbreviated unit for hours')
Image = translate('OpenLP.Ui', 'Image')
Import = translate('OpenLP.Ui', 'Import')
LengthTime = unicode(translate('OpenLP.Ui', 'Length %s'))
@@ -64,6 +65,7 @@ class UiStrings(object):
LiveBGError = translate('OpenLP.Ui', 'Live Background Error')
LivePanel = translate('OpenLP.Ui', 'Live Panel')
Load = translate('OpenLP.Ui', 'Load')
+ Minutes = translate('OpenLP.Ui', 'm', 'The abbreviated unit for minutes')
Middle = translate('OpenLP.Ui', 'Middle')
New = translate('OpenLP.Ui', 'New')
NewService = translate('OpenLP.Ui', 'New Service')
@@ -74,6 +76,8 @@ class UiStrings(object):
NISp = translate('OpenLP.Ui', 'No Items Selected', 'Plural')
OLPV1 = translate('OpenLP.Ui', 'openlp.org 1.x')
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')
Preview = translate('OpenLP.Ui', 'Preview')
PreviewPanel = translate('OpenLP.Ui', 'Preview Panel')
@@ -82,7 +86,7 @@ class UiStrings(object):
ReplaceLiveBG = translate('OpenLP.Ui', 'Replace Live Background')
ResetBG = translate('OpenLP.Ui', 'Reset 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')
Search = translate('OpenLP.Ui', 'Search')
SelectDelete = translate('OpenLP.Ui', 'You must select an item to delete.')
diff --git a/openlp/core/ui/generaltab.py b/openlp/core/ui/generaltab.py
index 29d6f8aad..d249dd4e0 100644
--- a/openlp/core/ui/generaltab.py
+++ b/openlp/core/ui/generaltab.py
@@ -105,6 +105,9 @@ class GeneralTab(SettingsTab):
self.saveCheckServiceCheckBox = QtGui.QCheckBox(self.settingsGroupBox)
self.saveCheckServiceCheckBox.setObjectName(u'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.setObjectName(u'autoPreviewCheckBox')
self.settingsLayout.addRow(self.autoPreviewCheckBox)
@@ -224,6 +227,8 @@ class GeneralTab(SettingsTab):
translate('OpenLP.GeneralTab', 'Application Settings'))
self.saveCheckServiceCheckBox.setText(translate('OpenLP.GeneralTab',
'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',
'Automatically preview next item in service'))
self.timeoutLabel.setText(translate('OpenLP.GeneralTab',
@@ -262,6 +267,8 @@ class GeneralTab(SettingsTab):
u'songselect password', QtCore.QVariant(u'')).toString()))
self.saveCheckServiceCheckBox.setChecked(settings.value(u'save prompt',
QtCore.QVariant(False)).toBool())
+ self.autoUnblankCheckBox.setChecked(settings.value(u'auto unblank',
+ QtCore.QVariant(False)).toBool())
self.monitorComboBox.setCurrentIndex(self.monitorNumber)
self.displayOnMonitorCheck.setChecked(self.screens.display)
self.warningCheckBox.setChecked(settings.value(u'blank warning',
@@ -312,6 +319,8 @@ class GeneralTab(SettingsTab):
QtCore.QVariant(self.checkForUpdatesCheckBox.isChecked()))
settings.setValue(u'save prompt',
QtCore.QVariant(self.saveCheckServiceCheckBox.isChecked()))
+ settings.setValue(u'auto unblank',
+ QtCore.QVariant(self.autoUnblankCheckBox.isChecked()))
settings.setValue(u'auto preview',
QtCore.QVariant(self.autoPreviewCheckBox.isChecked()))
settings.setValue(u'loop delay',
diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py
index 7e7a6eb8b..5a864957e 100644
--- a/openlp/core/ui/maindisplay.py
+++ b/openlp/core/ui/maindisplay.py
@@ -367,7 +367,7 @@ class MainDisplay(DisplayWidget):
self.mediaObject.setCurrentSource(Phonon.MediaSource(videoPath))
# Need the timer to trigger set the trigger to 200ms
# Value taken from web documentation.
- if self.serviceItem.start_time != 0:
+ if self.serviceItem.end_time != 0:
self.mediaObject.setTickInterval(200)
self.mediaObject.play()
self.webView.setVisible(False)
@@ -401,9 +401,9 @@ class MainDisplay(DisplayWidget):
def videoTick(self, tick):
"""
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):
"""
@@ -489,7 +489,11 @@ class MainDisplay(DisplayWidget):
self.footer(serviceItem.foot_text)
# if was hidden keep it hidden
if self.hideMode and self.isLive:
- self.hideDisplay(self.hideMode)
+ if QtCore.QSettings().value(u'general/auto unblank',
+ QtCore.QVariant(False)).toBool():
+ Receiver.send_message(u'slidecontroller_live_unblank')
+ else:
+ self.hideDisplay(self.hideMode)
# display hidden for video end we have a new item so must be shown
if self.videoHide and self.isLive:
self.videoHide = False
diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py
index e6ace21cd..594c6cc91 100644
--- a/openlp/core/ui/mainwindow.py
+++ b/openlp/core/ui/mainwindow.py
@@ -469,14 +469,15 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
actionList = ActionList()
- def __init__(self, screens, clipboard):
+ def __init__(self, screens, application):
"""
This constructor sets up the interface, the various managers, and the
plugins.
"""
QtGui.QMainWindow.__init__(self)
self.screens = screens
- self.clipboard = clipboard
+
+ self.application = application
# Set up settings sections for the main application
# (not for use by plugins)
self.uiSettingsSection = u'user interface'
@@ -660,7 +661,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
if self.liveController.display.isVisible():
self.liveController.display.setFocus()
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',
QtCore.QVariant(False)).toBool():
self.ServiceManagerContents.loadLastFile()
diff --git a/openlp/core/ui/printserviceform.py b/openlp/core/ui/printserviceform.py
index cd4b155f8..8dda6a9f6 100644
--- a/openlp/core/ui/printserviceform.py
+++ b/openlp/core/ui/printserviceform.py
@@ -33,12 +33,12 @@ from openlp.core.ui.printservicedialog import Ui_PrintServiceDialog, ZoomSize
class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
- def __init__(self, parent, serviceManager):
+ def __init__(self, mainWindow, serviceManager):
"""
Constructor
"""
- QtGui.QDialog.__init__(self, parent)
- self.parent = parent
+ QtGui.QDialog.__init__(self, mainWindow)
+ self.mainWindow = mainWindow
self.serviceManager = serviceManager
self.printer = QtGui.QPrinter()
self.printDialog = QtGui.QPrintDialog(self.printer, self)
@@ -134,9 +134,12 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
item.notes.replace(u'\n', u'
'))
# Add play length of media files.
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'
%s %s
' % (translate( 'OpenLP.ServiceManager', u'Playing time:'), - unicode(datetime.timedelta(seconds=item.media_length))) + unicode(datetime.timedelta(seconds=tme))) if self.footerTextEdit.toPlainText(): text += u'