From 659e3719f0c375d621543fac0353e7c6d13fdc2d Mon Sep 17 00:00:00 2001 From: Matthias Hub Date: Thu, 10 Mar 2011 02:45:45 +0100 Subject: [PATCH 001/123] - disabled presentations plugin in the first time wizard when on OS X - converting and bundling translations during the build process - removing presentations plugin from the dmg file during the build process - fixed Info.plist spelling errors reported by typovar - fixed translation in the presentations mediaitem --- openlp/core/ui/firsttimewizard.py | 9 +++++++- openlp/plugins/presentations/lib/mediaitem.py | 2 +- resources/osx/Info.plist.master | 4 ++-- resources/osx/Makefile | 2 +- resources/osx/build.py | 23 +++++++++++++++++++ 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/openlp/core/ui/firsttimewizard.py b/openlp/core/ui/firsttimewizard.py index c6d36d741..4c7ae6880 100644 --- a/openlp/core/ui/firsttimewizard.py +++ b/openlp/core/ui/firsttimewizard.py @@ -26,6 +26,8 @@ from PyQt4 import QtCore, QtGui +import sys + from openlp.core.lib import translate from openlp.core.lib.ui import add_welcome_page @@ -77,7 +79,10 @@ class Ui_FirstTimeWizard(object): self.imageCheckBox.setObjectName(u'imageCheckBox') self.pluginLayout.addWidget(self.imageCheckBox) self.presentationCheckBox = QtGui.QCheckBox(self.pluginPage) - self.presentationCheckBox.setChecked(True) + if sys.platform == "darwin": + self.presentationCheckBox.setChecked(False) + else: + self.presentationCheckBox.setChecked(True) self.presentationCheckBox.setObjectName(u'presentationCheckBox') self.pluginLayout.addWidget(self.presentationCheckBox) self.mediaCheckBox = QtGui.QCheckBox(self.pluginPage) @@ -210,6 +215,8 @@ class Ui_FirstTimeWizard(object): 'Images')) self.presentationCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Presentations')) + if sys.platform == "darwin": + self.presentationCheckBox.setEnabled(False) self.mediaCheckBox.setText(translate('OpenLP.FirstTimeWizard', 'Media (Audio and Video)')) self.remoteCheckBox.setText(translate('OpenLP.FirstTimeWizard', diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index 26229aed6..6009ff906 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -189,7 +189,7 @@ class PresentationMediaItem(MediaManagerItem): icon = build_icon(u':/general/general_delete.png') else: critical_error_message_box( - self, translate('PresentationPlugin.MediaItem', + translate('PresentationPlugin.MediaItem', 'Unsupported File'), translate('PresentationPlugin.MediaItem', 'This type of presentation is not supported.')) diff --git a/resources/osx/Info.plist.master b/resources/osx/Info.plist.master index e97e1faf5..45aab92a5 100755 --- a/resources/osx/Info.plist.master +++ b/resources/osx/Info.plist.master @@ -18,9 +18,9 @@ MacOS/openlp CFBundleName %(openlp_appname)s -CFBundleGetInfoString +CFBundleGetInfoString %(openlp_appname)s %(openlp_version)s -LSHasLocalizedDisplayName +LSHasLocalizedDisplayName NSAppleScriptEnabled diff --git a/resources/osx/Makefile b/resources/osx/Makefile index 422749da5..738a27aaa 100644 --- a/resources/osx/Makefile +++ b/resources/osx/Makefile @@ -25,4 +25,4 @@ clean: rm -rf OpenLP.app rm -f warnopenlp.txt rm -f *dmg - + diff --git a/resources/osx/build.py b/resources/osx/build.py index 4ffae789b..03f934dea 100644 --- a/resources/osx/build.py +++ b/resources/osx/build.py @@ -82,6 +82,7 @@ import ConfigParser import logging import optparse import sys +import glob import platform import re import subprocess as subp @@ -122,6 +123,15 @@ def build_application(settings, app_name_lower, app_dir): script_name) sys.exit(1) + logging.info('[%s] removing the presentations plugin...', script_name) + result = os.system('rm -rf \ + %(application_directory)s/Contents/MacOS/plugins/presentations' \ + % { 'application_directory' : app_dir }) + if (result != 0): + logging.error('[%s] could not remove presentations plugins, dmg creation failed!', + script_name) + sys.exit(1) + logging.info('[%s] copying the icons to the resource directory...', script_name) result = os.system('cp %(icon_file)s \ @@ -151,6 +161,19 @@ def build_application(settings, app_name_lower, app_dir): failed!', script_name) sys.exit(1) + logging.info('[%s] copying the translations...', script_name) + os.mkdir(app_dir + '/Contents/MacOS/i18n') + for ts_file in glob.glob(os.path.join(settings['openlp_basedir'] + + '/resources/i18n/', '*ts')): + result = os.system('lconvert -i %(ts_file)s \ + -o %(target_directory)s/Contents/MacOS/i18n/%(base)s.qm' \ + % { 'ts_file' : ts_file, 'target_directory' : app_dir, + 'base': os.path.splitext(os.path.basename(ts_file))[0] }) + if (result != 0): + logging.error('[%s] could not copy the translations, dmg creation \ + failed!', script_name) + sys.exit(1) + def deploy_qt(settings): logging.info('[%s] running mac deploy qt on %s.app...', script_name, settings['openlp_appname']); From 995b4274c5eca322dfa9b3441c3d439a8184e98f Mon Sep 17 00:00:00 2001 From: Matthias Hub Date: Thu, 10 Mar 2011 02:47:54 +0100 Subject: [PATCH 002/123] fixed line length --- resources/osx/build.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/osx/build.py b/resources/osx/build.py index 03f934dea..93fe453ad 100644 --- a/resources/osx/build.py +++ b/resources/osx/build.py @@ -128,8 +128,8 @@ def build_application(settings, app_name_lower, app_dir): %(application_directory)s/Contents/MacOS/plugins/presentations' \ % { 'application_directory' : app_dir }) if (result != 0): - logging.error('[%s] could not remove presentations plugins, dmg creation failed!', - script_name) + logging.error('[%s] could not remove presentations plugins, dmg \ + creation failed!', script_name) sys.exit(1) logging.info('[%s] copying the icons to the resource directory...', @@ -170,8 +170,8 @@ def build_application(settings, app_name_lower, app_dir): % { 'ts_file' : ts_file, 'target_directory' : app_dir, 'base': os.path.splitext(os.path.basename(ts_file))[0] }) if (result != 0): - logging.error('[%s] could not copy the translations, dmg creation \ - failed!', script_name) + logging.error('[%s] could not copy the translations, dmg \ + creation failed!', script_name) sys.exit(1) def deploy_qt(settings): From eb1dc880cb9d231710cb58a1eee31114f762104b Mon Sep 17 00:00:00 2001 From: Matthias Hub Date: Thu, 10 Mar 2011 03:09:23 +0100 Subject: [PATCH 003/123] using raouls get_version script from http://wiki.openlp.org/Packaging:Version_Script to create the .version file --- resources/osx/build.py | 5 +---- resources/osx/get_version.py | 36 ++++++++++++++++++++++++++++++++++++ resources/osx/openlp.cfg | 1 - resources/osx/version.master | 1 - 4 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 resources/osx/get_version.py delete mode 100755 resources/osx/version.master diff --git a/resources/osx/build.py b/resources/osx/build.py index 93fe453ad..ff7f6bdfd 100644 --- a/resources/osx/build.py +++ b/resources/osx/build.py @@ -394,10 +394,7 @@ if __name__ == '__main__': --template Info.plist.master \ --expandto %(target_directory)s/Info.plist' \ % { 'config_file' : options.config, 'target_directory' : os.getcwd() }) - os.system('python expander.py --config %(config_file)s \ - --template version.master \ - --expandto %(target_directory)s/.version' \ - % { 'config_file' : options.config, 'target_directory' : os.getcwd() }) + os.system('python get_version.py > .version') # prepare variables app_name_lower = settings['openlp_appname'].lower() diff --git a/resources/osx/get_version.py b/resources/osx/get_version.py new file mode 100644 index 000000000..30ebd7886 --- /dev/null +++ b/resources/osx/get_version.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import sys +import os +from bzrlib.branch import Branch + +def get_version(path): + b = Branch.open_containing(path)[0] + b.lock_read() + result = '0.0.0' + try: + # Get the branch's latest revision number. + revno = b.revno() + # Convert said revision number into a bzr revision id. + revision_id = b.dotted_revno_to_revision_id((revno,)) + # Get a dict of tags, with the revision id as the key. + tags = b.tags.get_reverse_tag_dict() + # Check if the latest + if revision_id in tags: + result = tags[revision_id][0] + else: + result = '%s-bzr%s' % (sorted(b.tags.get_tag_dict().keys())[-1], revno) + finally: + b.unlock() + return result + +def get_path(): + if len(sys.argv) > 1: + return os.path.abspath(sys.argv[1]) + else: + return os.path.abspath('.') + +if __name__ == u'__main__': + path = get_path() + print get_version(path) + diff --git a/resources/osx/openlp.cfg b/resources/osx/openlp.cfg index 1f04861b5..3be085dc0 100755 --- a/resources/osx/openlp.cfg +++ b/resources/osx/openlp.cfg @@ -2,7 +2,6 @@ openlp_appname = OpenLP openlp_dmgname = OpenLP-1.9.4-bzrXXXX openlp_version = XXXX -openlp_full_version = 1.9.4-latest openlp_basedir = /Users/openlp/trunk openlp_icon_file = openlp-logo-with-text.icns openlp_dmg_icon_file = openlp-logo-420x420.png diff --git a/resources/osx/version.master b/resources/osx/version.master deleted file mode 100755 index d517a51bc..000000000 --- a/resources/osx/version.master +++ /dev/null @@ -1 +0,0 @@ -%(openlp_full_version)s From 1312e0c913a04e1f4024882315fbb8e9a0856181 Mon Sep 17 00:00:00 2001 From: Matthias Hub Date: Thu, 10 Mar 2011 03:13:05 +0100 Subject: [PATCH 004/123] fixed the language configuration save/load bug on OS X --- openlp/core/utils/languagemanager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/core/utils/languagemanager.py b/openlp/core/utils/languagemanager.py index caea3bfdd..9dbf9a779 100644 --- a/openlp/core/utils/languagemanager.py +++ b/openlp/core/utils/languagemanager.py @@ -91,7 +91,7 @@ class LanguageManager(object): """ Retrieve a saved language to use from settings """ - settings = QtCore.QSettings(u'OpenLP', u'OpenLP') + settings = QtCore.QSettings() language = unicode(settings.value( u'general/language', QtCore.QVariant(u'[en]')).toString()) log.info(u'Language file: \'%s\' Loaded from conf file' % language) From 1ce88e7a2a852446750c61ee1eb460a002fc0880 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20P=C3=B5ldaru?= Date: Tue, 15 Mar 2011 00:29:02 +0200 Subject: [PATCH 005/123] Prevent possible crash, if label field is empty in database. --- openlp/plugins/songs/forms/editsongform.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index 0d9121c45..069e1e4a8 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -269,6 +269,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): if index is None: index = VerseType.Other verse[0][u'type'] = VerseType.Tags[index] + if verse[0][u'label'] == u'': + verse[0][u'label'] = u'1' verse_def = u'%s%s' % (verse[0][u'type'], verse[0][u'label']) item = QtGui.QTableWidgetItem(verse[1]) item.setData(QtCore.Qt.UserRole, QtCore.QVariant(verse_def)) From e5b664663a335666b6b509860b53f4392f10e3c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20P=C3=B5ldaru?= Date: Tue, 15 Mar 2011 01:05:31 +0200 Subject: [PATCH 006/123] Fix tracebacks, if user has no internet connection and he still presses Finish. --- openlp/core/ui/mainwindow.py | 2 ++ openlp/plugins/songs/songsplugin.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 06b809a20..2af6f3e59 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -678,6 +678,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): plugin.firstTime() Receiver.send_message(u'openlp_process_events') temp_dir = os.path.join(unicode(gettempdir()), u'openlp') + if not os.path.isdir(temp_dir): + return for filename in os.listdir(temp_dir): os.remove(os.path.join(temp_dir, filename)) os.removedirs(temp_dir) diff --git a/openlp/plugins/songs/songsplugin.py b/openlp/plugins/songs/songsplugin.py index bd953ffac..1d3f12ede 100644 --- a/openlp/plugins/songs/songsplugin.py +++ b/openlp/plugins/songs/songsplugin.py @@ -255,6 +255,8 @@ class SongsPlugin(Plugin): """ db_dir = unicode(os.path.join(gettempdir(), u'openlp')) song_dbs = [] + if not os.path.isdir(db_dir): + return for sfile in os.listdir(db_dir): if sfile.startswith(u'songs_') and sfile.endswith(u'.sqlite'): song_dbs.append(os.path.join(db_dir, sfile)) From 077337066221ceaec3ce98a753bc753b8f00633b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20P=C3=B5ldaru?= Date: Tue, 15 Mar 2011 16:38:16 +0200 Subject: [PATCH 007/123] Fix for #65 --- openlp/core/ui/servicemanager.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index fa2bc50f5..b43463d32 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -556,6 +556,13 @@ class ServiceManager(QtGui.QWidget): log.exception(u'File contains no service data') except (IOError, NameError): log.exception(u'Problem loading service file %s' % fileName) + except zipfile.BadZipfile: + log.exception(u'Service file is corrupt: %s' % fileName) + QtGui.QMessageBox.information(self, + translate('OpenLP.ServiceManager', 'File Is Corrupt'), + translate('OpenLP.ServiceManager', 'This service file is ' + 'either corrupt or is not an OpenLP 2 service file.')) + return finally: if fileTo: fileTo.close() From b502ad549c022fc66e13f194f7eac0f0431a0b10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20P=C3=B5ldaru?= Date: Wed, 16 Mar 2011 09:55:08 +0200 Subject: [PATCH 008/123] Differentiated error message for zero sized service. --- openlp/core/ui/servicemanager.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index b43463d32..18b9bf8a2 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -557,11 +557,19 @@ class ServiceManager(QtGui.QWidget): except (IOError, NameError): log.exception(u'Problem loading service file %s' % fileName) except zipfile.BadZipfile: - log.exception(u'Service file is corrupt: %s' % fileName) - QtGui.QMessageBox.information(self, - translate('OpenLP.ServiceManager', 'File Is Corrupt'), - translate('OpenLP.ServiceManager', 'This service file is ' - 'either corrupt or is not an OpenLP 2 service file.')) + if os.path.getsize(fileName) == 0: + log.exception(u'Service file is zero sized: %s' % fileName) + QtGui.QMessageBox.information(self, + translate('OpenLP.ServiceManager', 'File Is Empty'), + translate('OpenLP.ServiceManager', 'This service file is ' + 'zero size and does not contain any data.')) + else: + log.exception(u'Service file is cannot be extracted as zip: ' + u'%s' % fileName) + QtGui.QMessageBox.information(self, + translate('OpenLP.ServiceManager', 'File Is Corrupt'), + translate('OpenLP.ServiceManager', 'This service file is ' + 'either corrupt or is not an OpenLP 2 service file.')) return finally: if fileTo: From 38243af7debe5a530a64a9cc9bfa2323289192b6 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 19 Mar 2011 10:08:05 +0000 Subject: [PATCH 009/123] Add destop startup file selection --- openlp.pyw | 2 +- openlp/core/ui/mainwindow.py | 11 ++++++++--- openlp/core/ui/printserviceform.py | 11 ++++++----- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/openlp.pyw b/openlp.pyw index 04f65a5dd..3fbb473fd 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -184,7 +184,7 @@ class OpenLP(QtGui.QApplication): # make sure Qt really display the splash screen self.processEvents() # start the main app window - self.mainWindow = MainWindow(screens, app_version, self.clipboard()) + self.mainWindow = MainWindow(screens, app_version, self) self.mainWindow.show() if show_splash: # now kill the splashscreen diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 294cca49b..85872155f 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -468,7 +468,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): actionList = ActionList() - def __init__(self, screens, applicationVersion, clipboard): + def __init__(self, screens, applicationVersion, application): """ This constructor sets up the interface, the various managers, and the plugins. @@ -476,7 +476,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): QtGui.QMainWindow.__init__(self) self.screens = screens self.applicationVersion = applicationVersion - self.clipboard = clipboard + self.application = application # Set up settings sections for the main application # (not for use by plugins) self.uiSettingsSection = u'user interface' @@ -658,7 +658,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 713e7c27b..da4d6205e 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) @@ -181,13 +181,14 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog): """ 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): """ 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): """ From 5e7fa5940717f36e9b5b240fd1175fce0e493f21 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 19 Mar 2011 11:23:45 +0000 Subject: [PATCH 010/123] Update the Media timer UI --- openlp/core/lib/ui.py | 2 + openlp/core/ui/starttimedialog.py | 75 +++++++++++++++++++++++-------- openlp/core/ui/starttimeform.py | 28 +++++++++--- 3 files changed, 82 insertions(+), 23 deletions(-) diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index eae4f60ca..4e0c59210 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -56,6 +56,7 @@ class UiStrings(object): Export = translate('OpenLP.Ui', 'Export') FontSizePtUnit = translate('OpenLP.Ui', 'pt', 'Abbreviated font pointsize unit') + H = 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')) @@ -63,6 +64,7 @@ class UiStrings(object): LiveBGError = translate('OpenLP.Ui', 'Live Background Error') LivePanel = translate('OpenLP.Ui', 'Live Panel') Load = translate('OpenLP.Ui', 'Load') + M = 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') diff --git a/openlp/core/ui/starttimedialog.py b/openlp/core/ui/starttimedialog.py index 14ef84aac..0ee9ff5e7 100644 --- a/openlp/core/ui/starttimedialog.py +++ b/openlp/core/ui/starttimedialog.py @@ -32,39 +32,78 @@ from openlp.core.lib.ui import UiStrings, create_accept_reject_button_box class Ui_StartTimeDialog(object): def setupUi(self, StartTimeDialog): StartTimeDialog.setObjectName(u'StartTimeDialog') - StartTimeDialog.resize(300, 10) + StartTimeDialog.resize(350, 10) self.dialogLayout = QtGui.QGridLayout(StartTimeDialog) 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.setObjectName("hourLabel") - self.dialogLayout.addWidget(self.hourLabel, 0, 0, 1, 1) + self.hourLabel.setObjectName(u'hourLabel') + self.dialogLayout.addWidget(self.hourLabel, 1, 0, 1, 1) self.hourSpinBox = QtGui.QSpinBox(StartTimeDialog) - self.hourSpinBox.setObjectName("hourSpinBox") - self.dialogLayout.addWidget(self.hourSpinBox, 0, 1, 1, 1) + self.hourSpinBox.setObjectName(u'hourSpinBox') + self.dialogLayout.addWidget(self.hourSpinBox, 1, 1, 1, 1) + self.hourFinishSpinBox = QtGui.QSpinBox(StartTimeDialog) + self.hourFinishSpinBox.setObjectName(u'hourFinishSpinBox') + 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.setObjectName("minuteLabel") - self.dialogLayout.addWidget(self.minuteLabel, 1, 0, 1, 1) + self.minuteLabel.setObjectName(u'minuteLabel') + self.dialogLayout.addWidget(self.minuteLabel, 2, 0, 1, 1) self.minuteSpinBox = QtGui.QSpinBox(StartTimeDialog) - self.minuteSpinBox.setObjectName("minuteSpinBox") - self.dialogLayout.addWidget(self.minuteSpinBox, 1, 1, 1, 1) + self.minuteSpinBox.setObjectName(u'minuteSpinBox') + self.dialogLayout.addWidget(self.minuteSpinBox, 2, 1, 1, 1) + self.minuteFinishSpinBox = QtGui.QSpinBox(StartTimeDialog) + self.minuteFinishSpinBox.setObjectName(u'minuteFinishSpinBox') + 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.setObjectName("secondLabel") - self.dialogLayout.addWidget(self.secondLabel, 2, 0, 1, 1) + self.secondLabel.setObjectName(u'secondLabel') + self.dialogLayout.addWidget(self.secondLabel, 3, 0, 1, 1) self.secondSpinBox = QtGui.QSpinBox(StartTimeDialog) - self.secondSpinBox.setObjectName("secondSpinBox") - self.dialogLayout.addWidget(self.secondSpinBox, 2, 1, 1, 1) + self.secondSpinBox.setObjectName(u'secondSpinBox') + self.secondFinishSpinBox = QtGui.QSpinBox(StartTimeDialog) + self.secondFinishSpinBox.setObjectName(u'secondFinishSpinBox') + 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.dialogLayout.addWidget(self.buttonBox, 4, 0, 1, 2) + self.dialogLayout.addWidget(self.buttonBox, 5, 2, 1, 2) self.retranslateUi(StartTimeDialog) self.setMaximumHeight(self.sizeHint().height()) QtCore.QMetaObject.connectSlotsByName(StartTimeDialog) def retranslateUi(self, StartTimeDialog): self.setWindowTitle(translate('OpenLP.StartTimeForm', - 'Item Start Time')) - self.hourLabel.setText(translate('OpenLP.StartTimeForm', 'Hours:')) - self.hourSpinBox.setSuffix(translate('OpenLP.StartTimeForm', 'h')) - self.minuteSpinBox.setSuffix(translate('OpenLP.StartTimeForm', 'm')) + 'Item Start and Fnish Time')) + self.hourSpinBox.setSuffix(UiStrings.H) + self.minuteSpinBox.setSuffix(UiStrings.M) self.secondSpinBox.setSuffix(UiStrings.S) + self.hourFinishSpinBox.setSuffix(UiStrings.H) + self.minuteFinishSpinBox.setSuffix(UiStrings.M) + self.secondFinishSpinBox.setSuffix(UiStrings.S) + self.hourLabel.setText(translate('OpenLP.StartTimeForm', 'Hours:')) self.minuteLabel.setText(translate('OpenLP.StartTimeForm', 'Minutes:')) 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')) diff --git a/openlp/core/ui/starttimeform.py b/openlp/core/ui/starttimeform.py index 01800602f..42298772d 100644 --- a/openlp/core/ui/starttimeform.py +++ b/openlp/core/ui/starttimeform.py @@ -27,6 +27,7 @@ from PyQt4 import QtGui from starttimedialog import Ui_StartTimeDialog +from openlp.core.lib.ui import UiStrings class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog): """ @@ -40,13 +41,30 @@ class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog): """ 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.H)) + self.minuteFinishLabel.setText(u'%s%s' % + (unicode(minutes), UiStrings.M)) + self.secondFinishLabel.setText(u'%s%s' % + (unicode(seconds), UiStrings.S)) + return QtGui.QDialog.exec_(self) + + def accept(self): + return QtGui.QDialog.accept(self) + + def _time_split(self, seconds): hours = seconds / 3600 seconds -= 3600 * hours minutes = seconds / 60 seconds -= 60 * minutes - self.hourSpinBox.setValue(hours) - self.minuteSpinBox.setValue(minutes) - self.secondSpinBox.setValue(seconds) - return QtGui.QDialog.exec_(self) + return hours, minutes, seconds From 7fc84ad2b2bfc541e276c49b3e2cdd0d07f43ef0 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 19 Mar 2011 11:50:48 +0000 Subject: [PATCH 011/123] Enter and save end times --- openlp/core/lib/serviceitem.py | 6 +++++- openlp/core/ui/servicemanager.py | 6 +----- openlp/core/ui/starttimeform.py | 27 +++++++++++++++++++++++++-- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index b360ab13d..ec0dceb65 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -109,6 +109,7 @@ class ServiceItem(object): self.edit_id = None self.xml_version = None self.start_time = 0 + self.end_time = 0 self.media_length = 0 self._new_item() @@ -260,6 +261,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 = [] @@ -306,6 +308,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: @@ -447,4 +451,4 @@ class ServiceItem(object): elif not start and end: return end else: - return u'%s : %s' % (start, end) \ No newline at end of file + return u'%s : %s' % (start, end) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 56aa1bea1..d6d675e1e 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -652,10 +652,6 @@ class ServiceManager(QtGui.QWidget): item = self.findServiceItem()[0] self.startTimeForm.item = self.serviceItems[item] 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) def onServiceItemEditForm(self): @@ -1256,4 +1252,4 @@ class ServiceManager(QtGui.QWidget): Print a Service Order Sheet. """ settingDialog = PrintServiceForm(self.mainwindow, self) - settingDialog.exec_() \ No newline at end of file + settingDialog.exec_() diff --git a/openlp/core/ui/starttimeform.py b/openlp/core/ui/starttimeform.py index 42298772d..eb70536cb 100644 --- a/openlp/core/ui/starttimeform.py +++ b/openlp/core/ui/starttimeform.py @@ -27,7 +27,9 @@ from PyQt4 import QtGui from starttimedialog import Ui_StartTimeDialog -from openlp.core.lib.ui import UiStrings + +from openlp.core.lib import translate +from openlp.core.lib.ui import UiStrings, critical_error_message_box class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog): """ @@ -59,6 +61,28 @@ class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog): 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 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 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): @@ -67,4 +91,3 @@ class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog): minutes = seconds / 60 seconds -= 60 * minutes return hours, minutes, seconds - From 921163dbcd442a9096b20035fde1c71beef35178 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 19 Mar 2011 12:40:33 +0000 Subject: [PATCH 012/123] Media now has start and end times --- openlp/core/ui/maindisplay.py | 6 +++--- openlp/core/ui/printserviceform.py | 5 ++++- openlp/core/ui/serviceitemeditform.py | 1 - 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 76c891636..193e96c1d 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) @@ -399,9 +399,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): """ diff --git a/openlp/core/ui/printserviceform.py b/openlp/core/ui/printserviceform.py index da4d6205e..37f15b297 100644 --- a/openlp/core/ui/printserviceform.py +++ b/openlp/core/ui/printserviceform.py @@ -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'

%s

%s' % (translate('OpenLP.ServiceManager', u'Custom Service Notes:'), self.footerTextEdit.toPlainText()) diff --git a/openlp/core/ui/serviceitemeditform.py b/openlp/core/ui/serviceitemeditform.py index 588bdbfd6..228484ebf 100644 --- a/openlp/core/ui/serviceitemeditform.py +++ b/openlp/core/ui/serviceitemeditform.py @@ -141,4 +141,3 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog): else: self.upButton.setEnabled(True) self.deleteButton.setEnabled(True) - From 45034c1b8b60d804b50c01493fba35a0ea481e36 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 19 Mar 2011 19:45:22 +0000 Subject: [PATCH 013/123] Force default theme if no theme present --- openlp/core/lib/ui.py | 1 + openlp/core/ui/mainwindow.py | 6 +++--- openlp/core/ui/thememanager.py | 22 ++++++++++++++++++++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index eae4f60ca..987e99bf8 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -49,6 +49,7 @@ class UiStrings(object): Cancel = translate('OpenLP.Ui', 'Cancel') CCLINumberLabel = translate('OpenLP.Ui', 'CCLI number:') CreateService = translate('OpenLP.Ui', 'Create a new service.') + Default = unicode(translate('OpenLP.Ui', 'Default')) Delete = translate('OpenLP.Ui', '&Delete') Edit = translate('OpenLP.Ui', '&Edit') EmptyField = translate('OpenLP.Ui', 'Empty Field') diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 294cca49b..37ff71170 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -619,9 +619,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): # Call the initialise method to setup plugins. log.info(u'initialise plugins') self.pluginManager.initialise_plugins() - # Once all components are initialised load the Themes - log.info(u'Load Themes') - self.themeManagerContents.loadThemes() log.info(u'Load data from Settings') if QtCore.QSettings().value(u'advanced/save current plugin', QtCore.QVariant(False)).toBool(): @@ -630,6 +627,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): if savedPlugin != -1: self.MediaToolBox.setCurrentIndex(savedPlugin) self.settingsForm.postSetUp() + # Once all components are initialised load the Themes + log.info(u'Load Themes') + self.themeManagerContents.loadThemes(True) Receiver.send_message(u'cursor_normal') def setAutoLanguage(self, value): diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 407d0cfa8..a96147f81 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -159,7 +159,7 @@ class ThemeManager(QtGui.QWidget): self.loadThemes() Receiver.send_message(u'cursor_normal') - def configUpdated(self, firstTime=False): + def configUpdated(self): """ Triggered when Config dialog is updated. """ @@ -433,7 +433,7 @@ class ThemeManager(QtGui.QWidget): self.loadThemes() Receiver.send_message(u'cursor_normal') - def loadThemes(self): + def loadThemes(self, firstTime=False): """ Loads the theme lists and triggers updates accross the whole system using direct calls or core functions and events for the plugins. @@ -443,6 +443,24 @@ class ThemeManager(QtGui.QWidget): self.themelist = [] self.themeListWidget.clear() dirList = os.listdir(self.path) + if firstTime: + found = False + for name in dirList: + if name.endswith(u'.png'): + theme = os.path.join(self.path, name) + if os.path.exists(theme): + found = True + break + # No themes have been found so create one + if not found: + theme = ThemeXML() + theme.theme_name = UiStrings.Default + self._writeTheme(theme, None, None) + QtCore.QSettings().setValue( + self.settingsSection + u'/global theme', + QtCore.QVariant(theme.theme_name)) + self.configUpdated() + dirList = os.listdir(self.path) dirList.sort() for name in dirList: if name.endswith(u'.png'): From d26c8fce86a8235fc44345c39f00abbf13cadfe2 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 20 Mar 2011 07:37:44 +0000 Subject: [PATCH 014/123] Clean up initial theme setup --- openlp/core/ui/mainwindow.py | 1 - openlp/core/ui/thememanager.py | 64 +++++++++++++++------------------- 2 files changed, 29 insertions(+), 36 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 37ff71170..c0201bc8b 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -676,7 +676,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): def firstTime(self): # Import themes if first time Receiver.send_message(u'openlp_process_events') - self.themeManagerContents.firstTime() for plugin in self.pluginManager.plugins: if hasattr(plugin, u'firstTime'): Receiver.send_message(u'openlp_process_events') diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index a96147f81..2d0955a0c 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -156,7 +156,6 @@ class ThemeManager(QtGui.QWidget): file = os.path.join(self.path, file).encode(encoding) self.unzipTheme(file, self.path) delete_file(file) - self.loadThemes() Receiver.send_message(u'cursor_normal') def configUpdated(self): @@ -443,16 +442,11 @@ class ThemeManager(QtGui.QWidget): self.themelist = [] self.themeListWidget.clear() dirList = os.listdir(self.path) + files = SettingsManager.get_files(self.settingsSection, u'.png') if firstTime: - found = False - for name in dirList: - if name.endswith(u'.png'): - theme = os.path.join(self.path, name) - if os.path.exists(theme): - found = True - break + self.firstTime() # No themes have been found so create one - if not found: + if len(files) == 0: theme = ThemeXML() theme.theme_name = UiStrings.Default self._writeTheme(theme, None, None) @@ -460,32 +454,32 @@ class ThemeManager(QtGui.QWidget): self.settingsSection + u'/global theme', QtCore.QVariant(theme.theme_name)) self.configUpdated() - dirList = os.listdir(self.path) - dirList.sort() - for name in dirList: - if name.endswith(u'.png'): - # check to see file is in theme root directory - theme = os.path.join(self.path, name) - if os.path.exists(theme): - textName = os.path.splitext(name)[0] - if textName == self.global_theme: - name = unicode(translate('OpenLP.ThemeManager', - '%s (default)')) % textName - else: - name = textName - thumb = os.path.join(self.thumbPath, u'%s.png' % textName) - item_name = QtGui.QListWidgetItem(name) - if os.path.exists(thumb): - icon = build_icon(thumb) - else: - icon = build_icon(theme) - pixmap = icon.pixmap(QtCore.QSize(88, 50)) - pixmap.save(thumb, u'png') - item_name.setIcon(icon) - item_name.setData(QtCore.Qt.UserRole, - QtCore.QVariant(textName)) - self.themeListWidget.addItem(item_name) - self.themelist.append(textName) + files = SettingsManager.get_files(self.settingsSection, u'.png') + files.sort() + # now process the file list of png files + for name in files: + # check to see file is in theme root directory + theme = os.path.join(self.path, name) + if os.path.exists(theme): + textName = os.path.splitext(name)[0] + if textName == self.global_theme: + name = unicode(translate('OpenLP.ThemeManager', + '%s (default)')) % textName + else: + name = textName + thumb = os.path.join(self.thumbPath, u'%s.png' % textName) + item_name = QtGui.QListWidgetItem(name) + if os.path.exists(thumb): + icon = build_icon(thumb) + else: + icon = build_icon(theme) + pixmap = icon.pixmap(QtCore.QSize(88, 50)) + pixmap.save(thumb, u'png') + item_name.setIcon(icon) + item_name.setData(QtCore.Qt.UserRole, + QtCore.QVariant(textName)) + self.themeListWidget.addItem(item_name) + self.themelist.append(textName) self._pushThemes() def _pushThemes(self): From f0f1a5b5e1f0c264bcd0698d6ef1f2939fba4a31 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 20 Mar 2011 08:34:47 +0000 Subject: [PATCH 015/123] Text changes --- openlp/core/ui/starttimeform.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/core/ui/starttimeform.py b/openlp/core/ui/starttimeform.py index eb70536cb..2a1c270b4 100644 --- a/openlp/core/ui/starttimeform.py +++ b/openlp/core/ui/starttimeform.py @@ -72,14 +72,14 @@ class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog): title=translate('OpenLP.StartTimeForm', 'Time Validation Error'), message=translate('OpenLP.StartTimeForm', - 'End time is after the end of the Media Item')) + '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 of the Media Item')) + '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 From caaf004f4c1300021757e28401d7d6b6433557d7 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 20 Mar 2011 18:42:24 +0000 Subject: [PATCH 016/123] theme changes --- openlp/core/lib/rendermanager.py | 3 ++- openlp/core/ui/slidecontroller.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/openlp/core/lib/rendermanager.py b/openlp/core/lib/rendermanager.py index 0c9549ea5..4f84cf27e 100644 --- a/openlp/core/lib/rendermanager.py +++ b/openlp/core/lib/rendermanager.py @@ -145,7 +145,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/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 2f0e789a5..7cb1eb5c4 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -944,6 +944,7 @@ class SlideController(QtGui.QWidget): self.onSlideSelected() def __checkUpdateSelectedSlide(self, row): + print row, self.previewListWidget.rowCount() if row + 1 < self.previewListWidget.rowCount(): self.previewListWidget.scrollToItem( self.previewListWidget.item(row + 1, 0)) From 9836131025ecb47c72a3a1d1c1cf98da5132cb32 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Wed, 23 Mar 2011 21:08:24 +0000 Subject: [PATCH 017/123] Allow Preview Controller to request servicemanger to make the preview item live and add next to preview. Fixes: https://launchpad.net/bugs/730294 --- openlp/core/lib/eventreceiver.py | 4 ++++ openlp/core/lib/serviceitem.py | 1 + openlp/core/ui/servicemanager.py | 24 +++++++++++++++++++++++- openlp/core/ui/slidecontroller.py | 10 +++++++--- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/openlp/core/lib/eventreceiver.py b/openlp/core/lib/eventreceiver.py index 78b0c6324..b17db9823 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/serviceitem.py b/openlp/core/lib/serviceitem.py index 8991c873f..a5e82fb98 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -111,6 +111,7 @@ class ServiceItem(object): self.start_time = 0 self.end_time = 0 self.media_length = 0 + self.from_service = False self._new_item() def _new_item(self): diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index d6d675e1e..eeb18cb46 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -238,6 +238,8 @@ class ServiceManager(QtGui.QWidget): QtCore.SIGNAL(u'itemExpanded(QTreeWidgetItem*)'), self.expanded) QtCore.QObject.connect(Receiver.get_receiver(), 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.SIGNAL(u'servicemanager_next_item'), self.nextItem) QtCore.QObject.connect(Receiver.get_receiver(), @@ -558,6 +560,7 @@ class ServiceManager(QtGui.QWidget): self.newFile() for item in items: serviceItem = ServiceItem() + serviceItem.from_service = True serviceItem.render_manager = self.mainwindow.renderManager serviceItem.set_from_service(item, self.servicePath) self.validateItem(serviceItem) @@ -662,6 +665,19 @@ class ServiceManager(QtGui.QWidget): self.addServiceItem(self.serviceItemEditForm.getServiceItem(), 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): """ Called by the SlideController to select the next service item. @@ -1017,6 +1033,7 @@ class ServiceManager(QtGui.QWidget): if expand is None: expand = self.expandTabs item.render() + item.from_service = True if replace: sitem, child = self.findServiceItem() item.merge(self.serviceItems[sitem][u'service_item']) @@ -1071,11 +1088,16 @@ class ServiceManager(QtGui.QWidget): else: return self.serviceItems[item][u'service_item'] - def makeLive(self): + def makeLive(self, row=-1): """ Send the current item to the Live slide controller + + ``row`` + Row number to be displayed if from preview """ item, child = self.findServiceItem() + if row != -1: + child = row if self.serviceItems[item][u'service_item'].is_valid: self.mainwindow.liveController.addServiceManagerItem( self.serviceItems[item][u'service_item'], child) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index dfffa2e66..72704a2c0 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -655,6 +655,7 @@ class SlideController(QtGui.QWidget): """ Utility method to update the selected slide in the list. """ + print "c", slideno if slideno > self.previewListWidget.rowCount(): self.previewListWidget.selectRow( self.previewListWidget.rowCount() - 1) @@ -944,7 +945,6 @@ class SlideController(QtGui.QWidget): self.onSlideSelected() def __checkUpdateSelectedSlide(self, row): - print row, self.previewListWidget.rowCount() if row + 1 < self.previewListWidget.rowCount(): self.previewListWidget.scrollToItem( self.previewListWidget.item(row + 1, 0)) @@ -1014,8 +1014,12 @@ class SlideController(QtGui.QWidget): """ row = self.previewListWidget.currentRow() if row > -1 and row < self.previewListWidget.rowCount(): - self.parent.liveController.addServiceManagerItem( - self.serviceItem, row) + if self.serviceItem.from_service: + Receiver.send_message('servicemanager_preview_live', + u'%s:%s' % (self.serviceItem._uuid, row)) + else: + self.parent.liveController.addServiceManagerItem( + self.serviceItem, row) def onMediaStart(self, item): """ From 711c24668779963d8a75d5a0c040e70b3f0446be Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Thu, 24 Mar 2011 17:43:08 +0100 Subject: [PATCH 018/123] clean up --- openlp/core/ui/printservicedialog.py | 14 ++++++-------- openlp/core/utils/__init__.py | 8 +++----- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/openlp/core/ui/printservicedialog.py b/openlp/core/ui/printservicedialog.py index 41101e8ff..3d49533dd 100644 --- a/openlp/core/ui/printservicedialog.py +++ b/openlp/core/ui/printservicedialog.py @@ -64,8 +64,7 @@ class Ui_PrintServiceDialog(object): 'Options')) self.optionsButton.setToolButtonStyle( QtCore.Qt.ToolButtonTextBesideIcon) - self.optionsButton.setIcon(QtGui.QIcon( - build_icon(u':/system/system_configure.png'))) + self.optionsButton.setIcon(build_icon(u':/system/system_configure.png')) self.optionsButton.setCheckable(True) self.toolbar.addWidget(self.optionsButton) self.closeButton = self.toolbar.addAction( @@ -80,24 +79,23 @@ class Ui_PrintServiceDialog(object): translate('OpenLP.PrintServiceForm', 'Copy as HTML')) self.toolbar.addSeparator() self.zoomInButton = QtGui.QToolButton(self.toolbar) - self.zoomInButton.setIcon(QtGui.QIcon( - build_icon(u':/general/general_zoom_in.png'))) + self.zoomInButton.setIcon(build_icon(u':/general/general_zoom_in.png')) self.zoomInButton.setToolTip(translate('OpenLP.PrintServiceForm', 'Zoom In')) self.zoomInButton.setObjectName(u'zoomInButton') self.zoomInButton.setIconSize(QtCore.QSize(22, 22)) self.toolbar.addWidget(self.zoomInButton) self.zoomOutButton = QtGui.QToolButton(self.toolbar) - self.zoomOutButton.setIcon(QtGui.QIcon( - build_icon(u':/general/general_zoom_out.png'))) + self.zoomOutButton.setIcon( + build_icon(u':/general/general_zoom_out.png')) self.zoomOutButton.setToolTip(translate('OpenLP.PrintServiceForm', 'Zoom Out')) self.zoomOutButton.setObjectName(u'zoomOutButton') self.zoomOutButton.setIconSize(QtCore.QSize(22, 22)) self.toolbar.addWidget(self.zoomOutButton) self.zoomOriginalButton = QtGui.QToolButton(self.toolbar) - self.zoomOriginalButton.setIcon(QtGui.QIcon( - build_icon(u':/general/general_zoom_original.png'))) + self.zoomOriginalButton.setIcon( + build_icon(u':/general/general_zoom_original.png')) self.zoomOriginalButton.setToolTip(translate('OpenLP.PrintServiceForm', 'Zoom Original')) self.zoomOriginalButton.setObjectName(u'zoomOriginalButton') diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 54b48cdf6..4ee2e84e0 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -44,7 +44,7 @@ if sys.platform != u'win32' and sys.platform != u'darwin': XDG_BASE_AVAILABLE = False import openlp -from openlp.core.lib import Receiver, translate +from openlp.core.lib import Receiver, translate, check_directory_exists log = logging.getLogger(__name__) IMAGES_FILTER = None @@ -146,8 +146,7 @@ class AppLocation(object): Return the path OpenLP stores all its data under. """ path = AppLocation.get_directory(AppLocation.DataDir) - if not os.path.exists(path): - os.makedirs(path) + check_directory_exists(path) return path @staticmethod @@ -157,8 +156,7 @@ class AppLocation(object): """ data_path = AppLocation.get_data_path() path = os.path.join(data_path, section) - if not os.path.exists(path): - os.makedirs(path) + check_directory_exists(path) return path def _get_os_dir_path(dir_type): From 67ee8394c21a5adec83e97aed10444f9270c6131 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Thu, 24 Mar 2011 20:12:27 +0100 Subject: [PATCH 019/123] moved version function --- openlp.pyw | 85 ++------------------------ openlp/.version | 2 +- openlp/core/lib/plugin.py | 6 +- openlp/core/ui/slidecontroller.py | 1 + openlp/core/utils/__init__.py | 87 +++++++++++++++++++++++++++ openlp/plugins/media/lib/mediaitem.py | 4 +- openlp/plugins/songs/lib/xml.py | 5 +- 7 files changed, 103 insertions(+), 87 deletions(-) diff --git a/openlp.pyw b/openlp.pyw index af3908c30..717ea27f9 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -29,7 +29,6 @@ import sys import logging from optparse import OptionParser from traceback import format_exception -from subprocess import Popen, PIPE from PyQt4 import QtCore, QtGui @@ -40,7 +39,8 @@ from openlp.core.ui.firsttimelanguageform import FirstTimeLanguageForm from openlp.core.ui.firsttimeform import FirstTimeForm from openlp.core.ui.exceptionform import ExceptionForm from openlp.core.ui import SplashScreen, ScreenList -from openlp.core.utils import AppLocation, LanguageManager, VersionThread +from openlp.core.utils import AppLocation, LanguageManager, VersionThread, \ + get_application_version log = logging.getLogger() @@ -73,89 +73,12 @@ class OpenLP(QtGui.QApplication): """ log.info(u'OpenLP Application Loaded') - def _get_version(self): - """ - Load and store current Application Version - """ - if u'--dev-version' in sys.argv or u'-d' in sys.argv: - # If we're running the dev version, let's use bzr to get the version - try: - # If bzrlib is availble, use it - from bzrlib.branch import Branch - b = Branch.open_containing('.')[0] - b.lock_read() - try: - # Get the branch's latest revision number. - revno = b.revno() - # Convert said revision number into a bzr revision id. - revision_id = b.dotted_revno_to_revision_id((revno,)) - # Get a dict of tags, with the revision id as the key. - tags = b.tags.get_reverse_tag_dict() - # Check if the latest - if revision_id in tags: - full_version = u'%s' % tags[revision_id][0] - else: - full_version = '%s-bzr%s' % \ - (sorted(b.tags.get_tag_dict().keys())[-1], revno) - finally: - b.unlock() - except: - # Otherwise run the command line bzr client - bzr = Popen((u'bzr', u'tags', u'--sort', u'time'), stdout=PIPE) - output, error = bzr.communicate() - code = bzr.wait() - if code != 0: - raise Exception(u'Error running bzr tags') - lines = output.splitlines() - if len(lines) == 0: - tag = u'0.0.0' - revision = u'0' - else: - tag, revision = lines[-1].split() - bzr = Popen((u'bzr', u'log', u'--line', u'-r', u'-1'), - stdout=PIPE) - output, error = bzr.communicate() - code = bzr.wait() - if code != 0: - raise Exception(u'Error running bzr log') - latest = output.split(u':')[0] - full_version = latest == revision and tag or \ - u'%s-bzr%s' % (tag, latest) - else: - # We're not running the development version, let's use the file - filepath = AppLocation.get_directory(AppLocation.VersionDir) - filepath = os.path.join(filepath, u'.version') - fversion = None - try: - fversion = open(filepath, u'r') - full_version = unicode(fversion.read()).rstrip() - except IOError: - log.exception('Error in version file.') - full_version = u'0.0.0-bzr000' - finally: - if fversion: - fversion.close() - bits = full_version.split(u'-') - app_version = { - u'full': full_version, - u'version': bits[0], - u'build': bits[1] if len(bits) > 1 else None - } - if app_version[u'build']: - log.info( - u'Openlp version %s build %s', - app_version[u'version'], - app_version[u'build'] - ) - else: - log.info(u'Openlp version %s' % app_version[u'version']) - return app_version - def run(self): """ Run the OpenLP application. """ - app_version = self._get_version() + app_version = get_application_version( + u'--dev-version' in sys.argv or u'-d' in sys.argv) # provide a listener for widgets to reqest a screen update. QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'openlp_process_events'), self.processEvents) diff --git a/openlp/.version b/openlp/.version index ae8249b9a..4543cdd14 100644 --- a/openlp/.version +++ b/openlp/.version @@ -1 +1 @@ -1.9.2-bzr987 \ No newline at end of file +1.9.4-bzr1416 \ No newline at end of file diff --git a/openlp/core/lib/plugin.py b/openlp/core/lib/plugin.py index 6195cb248..72d51ca1d 100644 --- a/openlp/core/lib/plugin.py +++ b/openlp/core/lib/plugin.py @@ -32,6 +32,7 @@ from PyQt4 import QtCore from openlp.core.lib import Receiver from openlp.core.lib.ui import UiStrings +from openlp.core.utils import get_application_version log = logging.getLogger(__name__) @@ -145,7 +146,10 @@ class Plugin(QtCore.QObject): self.textStrings = {} self.setPluginTextStrings() self.nameStrings = self.textStrings[StringContent.Name] - self.version = version if version else u'1.9.4' + if version: + self.version = version + else: + self.version = get_application_version()[u'version'] self.settingsSection = self.name.lower() self.icon = None self.mediaItemClass = mediaItemClass diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index ae0c52273..ad6143796 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -46,6 +46,7 @@ class SlideList(QtGui.QTableWidget): QtGui.QTableWidget.__init__(self, parent.controller) self.parent = parent + class SlideController(QtGui.QWidget): """ SlideController is the slide controller widget. This widget is what the diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 4ee2e84e0..60dd4b920 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -33,6 +33,7 @@ import sys import time import urllib2 from datetime import datetime +from subprocess import Popen, PIPE from PyQt4 import QtGui, QtCore @@ -50,6 +51,7 @@ log = logging.getLogger(__name__) IMAGES_FILTER = None UNO_CONNECTION_TYPE = u'pipe' #UNO_CONNECTION_TYPE = u'socket' +APPLICATION_VERSION = u'' class VersionThread(QtCore.QThread): """ @@ -206,6 +208,91 @@ def _get_frozen_path(frozen_option, non_frozen_option): return frozen_option return non_frozen_option +def get_application_version(dev_version=False): + """ + Returns the application version of the running instance of OpenLP:: + + {u'full': u'1.9.4-bzr1249', u'version': u'1.9.4', u'build': u'bzr1249'} + + ``dev_version`` + If ``True``, then it is assumed, that we are running a dev version and + attempt to receive the version number using bzr. **Note**, that this + argument is only important the first time the function is called. + """ + global APPLICATION_VERSION + if APPLICATION_VERSION: + # We already know the version, so just return it. + return APPLICATION_VERSION + if dev_version: + # If we're running the dev version, let's use bzr to get the version. + try: + # If bzrlib is available, use it. + from bzrlib.branch import Branch + b = Branch.open_containing('.')[0] + b.lock_read() + try: + # Get the branch's latest revision number. + revno = b.revno() + # Convert said revision number into a bzr revision id. + revision_id = b.dotted_revno_to_revision_id((revno,)) + # Get a dict of tags, with the revision id as the key. + tags = b.tags.get_reverse_tag_dict() + # Check if the latest + if revision_id in tags: + full_version = u'%s' % tags[revision_id][0] + else: + full_version = '%s-bzr%s' % \ + (sorted(b.tags.get_tag_dict().keys())[-1], revno) + finally: + b.unlock() + except: + # Otherwise run the command line bzr client. + bzr = Popen((u'bzr', u'tags', u'--sort', u'time'), stdout=PIPE) + output, error = bzr.communicate() + code = bzr.wait() + if code != 0: + raise Exception(u'Error running bzr tags') + lines = output.splitlines() + if len(lines) == 0: + tag = u'0.0.0' + revision = u'0' + else: + tag, revision = lines[-1].split() + bzr = Popen((u'bzr', u'log', u'--line', u'-r', u'-1'), stdout=PIPE) + output, error = bzr.communicate() + code = bzr.wait() + if code != 0: + raise Exception(u'Error running bzr log') + latest = output.split(u':')[0] + full_version = latest == revision and tag or \ + u'%s-bzr%s' % (tag, latest) + else: + # We're not running the development version, let's use the file. + filepath = AppLocation.get_directory(AppLocation.VersionDir) + filepath = os.path.join(filepath, u'.version') + fversion = None + try: + fversion = open(filepath, u'r') + full_version = unicode(fversion.read()).rstrip() + except IOError: + log.exception('Error in version file.') + full_version = u'0.0.0-bzr000' + finally: + if fversion: + fversion.close() + bits = full_version.split(u'-') + APPLICATION_VERSION = { + u'full': full_version, + u'version': bits[0], + u'build': bits[1] if len(bits) > 1 else None + } + if APPLICATION_VERSION[u'build']: + log.info(u'Openlp version %s build %s', + APPLICATION_VERSION[u'version'], APPLICATION_VERSION[u'build']) + else: + log.info(u'Openlp version %s' % APPLICATION_VERSION[u'version']) + return APPLICATION_VERSION + def check_latest_version(current_version): """ Check the latest version of OpenLP against the version file on the OpenLP diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index 8a1bc2b76..8118e08d7 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -36,7 +36,7 @@ from openlp.core.lib.ui import UiStrings, critical_error_message_box from PyQt4.phonon import Phonon log = logging.getLogger(__name__) - + class MediaMediaItem(MediaManagerItem): """ This is the custom media manager item for Media Slides. @@ -182,7 +182,7 @@ class MediaMediaItem(MediaManagerItem): if (datetime.now() - start).seconds > 5: return False return True - + def initialise(self): self.listView.clear() self.listView.setIconSize(QtCore.QSize(88, 50)) diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index 0bf64c6fa..f98d50098 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -68,6 +68,7 @@ from lxml import etree, objectify from openlp.plugins.songs.lib import clean_song, VerseType from openlp.plugins.songs.lib.db import Author, Book, Song, Topic +from openlp.core.utils import get_application_version log = logging.getLogger(__name__) @@ -230,8 +231,8 @@ class OpenLyrics(object): # Append the necessary meta data to the song. song_xml.set(u'xmlns', u'http://openlyrics.info/namespace/2009/song') song_xml.set(u'version', OpenLyrics.IMPLEMENTED_VERSION) - song_xml.set(u'createdIn', u'OpenLP 1.9.4') # Use variable - song_xml.set(u'modifiedIn', u'OpenLP 1.9.4') # Use variable + song_xml.set(u'createdIn', get_application_version()[u'version']) + song_xml.set(u'modifiedIn', get_application_version()[u'version']) song_xml.set(u'modifiedDate', datetime.datetime.now().strftime(u'%Y-%m-%dT%H:%M:%S')) properties = etree.SubElement(song_xml, u'properties') From 5a80d5a606eb557813d977d59374d2fac9416cf0 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Thu, 24 Mar 2011 19:50:40 +0000 Subject: [PATCH 020/123] remove print --- openlp/core/ui/slidecontroller.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 72704a2c0..dfeb02964 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -655,7 +655,6 @@ class SlideController(QtGui.QWidget): """ Utility method to update the selected slide in the list. """ - print "c", slideno if slideno > self.previewListWidget.rowCount(): self.previewListWidget.selectRow( self.previewListWidget.rowCount() - 1) From 30de0d9916325cc9339da356f28ab9ecffec94eb Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Thu, 24 Mar 2011 21:37:02 +0100 Subject: [PATCH 021/123] fixed ticket 65 --- openlp/core/ui/servicemanager.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 56aa1bea1..01e64cebf 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -481,16 +481,14 @@ class ServiceManager(QtGui.QWidget): # Usual Zip file cannot exceed 2GiB, file with Zip64 cannot be # extracted using unzip in UNIX. allow_zip_64 = (total_size > 2147483648 + len(service_content)) - log.debug(u'ServiceManager.saveFile - allowZip64 is %s' % - allow_zip_64) + log.debug(u'ServiceManager.saveFile - allowZip64 is %s' % allow_zip_64) zip = None try: zip = zipfile.ZipFile(path_file_name, 'w', zipfile.ZIP_STORED, allow_zip_64) # First we add service contents. # We save ALL filenames into ZIP using UTF-8. - zip.writestr(service_file_name.encode(u'utf-8'), - service_content) + zip.writestr(service_file_name.encode(u'utf-8'), service_content) # Finally add all the listed media files. for path_from in write_list: zip.write(path_from, path_from.encode(u'utf-8')) @@ -566,24 +564,27 @@ class ServiceManager(QtGui.QWidget): Receiver.send_message(u'%s_service_load' % serviceItem.name.lower(), serviceItem) delete_file(p_file) + self.setFileName(fileName) + self.mainwindow.addRecentFile(fileName) + self.setModified(False) + QtCore.QSettings().setValue( + 'service/last file', QtCore.QVariant(fileName)) Receiver.send_message(u'cursor_normal') else: critical_error_message_box( message=translate('OpenLP.ServiceManager', 'File is not a valid service.')) log.exception(u'File contains no service data') - except (IOError, NameError): + except (IOError, NameError, zipfile.BadZipfile): + critical_error_message_box( + message=translate('OpenLP.ServiceManager', + 'File could not be opened because it is corrupt.')) log.exception(u'Problem loading service file %s' % fileName) finally: if fileTo: fileTo.close() if zip: zip.close() - self.setFileName(fileName) - self.mainwindow.addRecentFile(fileName) - self.setModified(False) - QtCore.QSettings(). \ - setValue(u'service/last file', QtCore.QVariant(fileName)) def loadLastFile(self): """ @@ -1256,4 +1257,5 @@ class ServiceManager(QtGui.QWidget): Print a Service Order Sheet. """ settingDialog = PrintServiceForm(self.mainwindow, self) - settingDialog.exec_() \ No newline at end of file + settingDialog.exec_() + From c598a86e592592322576efa0b05246d98f548ba1 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Thu, 24 Mar 2011 21:46:34 +0100 Subject: [PATCH 022/123] workaround for ticket 102 --- openlp.pyw | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openlp.pyw b/openlp.pyw index a03f8e16c..670d9e11a 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -27,6 +27,11 @@ import os import sys import logging +# Import uuid now, to avoid the rare bug described in the support system: +# http://support.openlp.org/issues/102 +# If https://bugs.gentoo.org/show_bug.cgi?id=317557 is fixed, the import can be +# removed. +import uuid from optparse import OptionParser from traceback import format_exception from subprocess import Popen, PIPE From a9cd8db787df4a521cb83b05203a5a533b47f190 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Thu, 24 Mar 2011 22:13:51 +0100 Subject: [PATCH 023/123] do not show error message when file does not exist, fixed return --- openlp/core/ui/servicemanager.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index ae77f8aee..cc6ee2b3b 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -483,6 +483,7 @@ class ServiceManager(QtGui.QWidget): allow_zip_64 = (total_size > 2147483648 + len(service_content)) log.debug(u'ServiceManager.saveFile - allowZip64 is %s' % allow_zip_64) zip = None + success = True try: zip = zipfile.ZipFile(path_file_name, 'w', zipfile.ZIP_STORED, allow_zip_64) @@ -494,13 +495,16 @@ class ServiceManager(QtGui.QWidget): zip.write(path_from, path_from.encode(u'utf-8')) except IOError: log.exception(u'Failed to save service to disk') - return False + success = False finally: if zip: zip.close() - self.mainwindow.addRecentFile(path_file_name) - self.setModified(False) - return True + if success: + self.mainwindow.addRecentFile(path_file_name) + self.setModified(False) + else: + delete_file(path_file_name) + return success def saveFileAs(self): """ @@ -525,8 +529,9 @@ class ServiceManager(QtGui.QWidget): def loadFile(self, fileName): if not fileName: return False - else: - fileName = unicode(fileName) + fileName = unicode(fileName) + if not os.path.exists(fileName): + return False zip = None fileTo = None try: From f83ac13f3f218a86145a117b498a3154aa8d5dd2 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Thu, 24 Mar 2011 21:28:03 +0000 Subject: [PATCH 024/123] Allow slides to automatically unblank when added to live Fixes: https://launchpad.net/bugs/735367 --- openlp/core/ui/generaltab.py | 9 +++++++++ openlp/core/ui/maindisplay.py | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/openlp/core/ui/generaltab.py b/openlp/core/ui/generaltab.py index eabccd301..344f0b702 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 1153917a2..44c0e2b41 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -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 From 2de02a0c76738482c3ab5a17b64932b5e5bb1161 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 25 Mar 2011 06:13:42 +0000 Subject: [PATCH 025/123] Fix up verse selection correctly. --- openlp/core/ui/servicemanager.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index eeb18cb46..8d0f9df9c 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -231,7 +231,7 @@ class ServiceManager(QtGui.QWidget): QtCore.QObject.connect(self.themeComboBox, QtCore.SIGNAL(u'activated(int)'), self.onThemeComboBoxSelected) 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.SIGNAL(u'itemCollapsed(QTreeWidgetItem*)'), self.collapsed) QtCore.QObject.connect(self.serviceManagerList, @@ -1088,12 +1088,20 @@ class ServiceManager(QtGui.QWidget): else: return self.serviceItems[item][u'service_item'] + 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 ``row`` - Row number to be displayed if from preview + Row number to be displayed if from preview. + -1 is passed if the value is not set """ item, child = self.findServiceItem() if row != -1: From 24b58ff518bbd772ab7213d171c3960dce921868 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Fri, 25 Mar 2011 17:29:39 +0100 Subject: [PATCH 026/123] fixed application version --- openlp.pyw | 8 +++----- openlp/core/ui/aboutform.py | 11 ++++++----- openlp/core/ui/mainwindow.py | 10 ++++------ openlp/core/utils/__init__.py | 20 +++++++------------- 4 files changed, 20 insertions(+), 29 deletions(-) diff --git a/openlp.pyw b/openlp.pyw index 96871ad79..f9c92dc44 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -71,7 +71,6 @@ class OpenLP(QtGui.QApplication): The core application class. This class inherits from Qt's QApplication class in order to provide the core of the application. """ - app_version = None def run(self): """ @@ -103,8 +102,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.app_version, - self.clipboard()) + self.mainWindow = MainWindow(screens, self.clipboard()) self.mainWindow.show() if show_splash: # now kill the splashscreen @@ -116,7 +114,7 @@ class OpenLP(QtGui.QApplication): update_check = QtCore.QSettings().value( u'general/update check', QtCore.QVariant(True)).toBool() if update_check: - VersionThread(self.mainWindow, self.app_version).start() + VersionThread(self.mainWindow).start() return self.exec_() def hookException(self, exctype, value, traceback): @@ -194,7 +192,7 @@ def main(): app.setOrganizationName(u'OpenLP') app.setOrganizationDomain(u'openlp.org') app.setApplicationName(u'OpenLP') - app.setApplicationVersion(app.get_version()[u'version']) + app.setApplicationVersion(get_application_version()[u'version']) # First time checks in settings if not QtCore.QSettings().value(u'general/has run wizard', QtCore.QVariant(False)).toBool(): diff --git a/openlp/core/ui/aboutform.py b/openlp/core/ui/aboutform.py index 5c26167e3..4112cfd8f 100644 --- a/openlp/core/ui/aboutform.py +++ b/openlp/core/ui/aboutform.py @@ -28,25 +28,26 @@ from PyQt4 import QtCore, QtGui from aboutdialog import Ui_AboutDialog from openlp.core.lib import translate +from openlp.core.utils import get_application_version class AboutForm(QtGui.QDialog, Ui_AboutDialog): """ The About dialog """ - def __init__(self, parent, applicationVersion): + def __init__(self, parent): """ Do some initialisation stuff """ QtGui.QDialog.__init__(self, parent) - self.applicationVersion = applicationVersion + applicationVersion = get_application_version() self.setupUi(self) about_text = self.aboutTextEdit.toPlainText() about_text = about_text.replace(u'', - self.applicationVersion[u'version']) - if self.applicationVersion[u'build']: + applicationVersion[u'version']) + if applicationVersion[u'build']: build_text = unicode(translate('OpenLP.AboutForm', ' build %s')) % \ - self.applicationVersion[u'build'] + applicationVersion[u'build'] else: build_text = u'' about_text = about_text.replace(u'', build_text) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index e421edd98..b8dfc35f5 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -38,7 +38,7 @@ from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \ ThemeManager, SlideController, PluginForm, MediaDockManager, \ ShortcutListForm, DisplayTagForm from openlp.core.utils import AppLocation, add_actions, LanguageManager, \ - ActionList + ActionList, get_application_version log = logging.getLogger(__name__) @@ -469,14 +469,13 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): actionList = ActionList() - def __init__(self, screens, applicationVersion, clipboard): + def __init__(self, screens, clipboard): """ This constructor sets up the interface, the various managers, and the plugins. """ QtGui.QMainWindow.__init__(self) self.screens = screens - self.applicationVersion = applicationVersion self.clipboard = clipboard # Set up settings sections for the main application # (not for use by plugins) @@ -487,7 +486,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.serviceNotSaved = False self.actionList = ActionList() self.settingsmanager = SettingsManager(screens) - self.aboutForm = AboutForm(self, applicationVersion) + self.aboutForm = AboutForm(self) self.settingsForm = SettingsForm(self.screens, self, self) self.displayTagForm = DisplayTagForm(self) self.shortcutForm = ShortcutListForm(self) @@ -651,7 +650,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): 'version from http://openlp.org/.')) QtGui.QMessageBox.question(self, translate('OpenLP.MainWindow', 'OpenLP Version Updated'), - version_text % (version, self.applicationVersion[u'full'])) + version_text % (version, get_application_version()[u'full'])) def show(self): """ @@ -734,7 +733,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): """ Show the About form """ - self.aboutForm.applicationVersion = self.applicationVersion self.aboutForm.exec_() def onPluginItemClicked(self): diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 22c56e7c1..3c639297e 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -48,19 +48,18 @@ import openlp from openlp.core.lib import Receiver, translate, check_directory_exists log = logging.getLogger(__name__) +APPLICATION_VERSION = {} IMAGES_FILTER = None UNO_CONNECTION_TYPE = u'pipe' #UNO_CONNECTION_TYPE = u'socket' -APPLICATION_VERSION = u'' class VersionThread(QtCore.QThread): """ A special Qt thread class to fetch the version of OpenLP from the website. This is threaded so that it doesn't affect the loading time of OpenLP. """ - def __init__(self, parent, app_version): + def __init__(self, parent): QtCore.QThread.__init__(self, parent) - self.app_version = app_version self.version_splitter = re.compile( r'([0-9]+).([0-9]+).([0-9]+)(?:-bzr([0-9]+))?') @@ -70,7 +69,8 @@ class VersionThread(QtCore.QThread): """ time.sleep(1) Receiver.send_message(u'maindisplay_blank_check') - version = check_latest_version(self.app_version) + app_version = get_application_version() + version = check_latest_version(app_version) remote_version = {} local_version = {} match = self.version_splitter.match(version) @@ -82,7 +82,7 @@ class VersionThread(QtCore.QThread): remote_version[u'revision'] = int(match.group(4)) else: return - match = self.version_splitter.match(self.app_version[u'full']) + match = self.version_splitter.match(app_version[u'full']) if match: local_version[u'major'] = int(match.group(1)) local_version[u'minor'] = int(match.group(2)) @@ -208,22 +208,16 @@ def _get_frozen_path(frozen_option, non_frozen_option): return frozen_option return non_frozen_option -def get_application_version(dev_version=False): +def get_application_version(): """ Returns the application version of the running instance of OpenLP:: {u'full': u'1.9.4-bzr1249', u'version': u'1.9.4', u'build': u'bzr1249'} - - ``dev_version`` - If ``True``, then it is assumed, that we are running a dev version and - attempt to receive the version number using bzr. **Note**, that this - argument is only important the first time the function is called. """ global APPLICATION_VERSION if APPLICATION_VERSION: - # We already know the version, so just return it. return APPLICATION_VERSION - if dev_version: + if u'--dev-version' in sys.argv or u'-d' in sys.argv: # If we're running the dev version, let's use bzr to get the version. try: # If bzrlib is available, use it. From 8aac2f77242895a94f06c1a4edd248d9d180d15b Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Fri, 25 Mar 2011 19:45:39 +0100 Subject: [PATCH 027/123] fixed exception --- openlp/core/lib/__init__.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index 0d56d1ddd..ddb1ae9b1 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -316,8 +316,11 @@ def check_directory_exists(dir): Theme directory to make sure exists """ log.debug(u'check_directory_exists %s' % dir) - if not os.path.exists(dir): - os.makedirs(dir) + try: + if not os.path.exists(dir): + os.makedirs(dir) + except IOError: + pass from listwidgetwithdnd import ListWidgetWithDnD from displaytags import DisplayTags From ad1d57faab933a7d04861462b441c91a6475495e Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Fri, 25 Mar 2011 19:49:53 +0100 Subject: [PATCH 028/123] fixed version file --- openlp/.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/.version b/openlp/.version index 4543cdd14..998994b7f 100644 --- a/openlp/.version +++ b/openlp/.version @@ -1 +1 @@ -1.9.4-bzr1416 \ No newline at end of file +1.9.5-bzr1421 \ No newline at end of file From 731765b82943309f312fc114c17fe8d80c1e1c75 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 25 Mar 2011 18:50:25 +0000 Subject: [PATCH 029/123] missing files --- resources/openlp.desktop | 4 ++-- resources/openlp.xml | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 resources/openlp.xml diff --git a/resources/openlp.desktop b/resources/openlp.desktop index 684119773..07398ede8 100755 --- a/resources/openlp.desktop +++ b/resources/openlp.desktop @@ -3,11 +3,11 @@ Categories=AudioVideo; Comment[de]= Comment= Encoding=UTF-8 -Exec=openlp +Exec=openlp %F GenericName[de]=Church lyrics projection GenericName=Church lyrics projection Icon=openlp -MimeType= +MimeType=application/x-openlp-service; Name[de]=OpenLP Name=OpenLP Path= diff --git a/resources/openlp.xml b/resources/openlp.xml new file mode 100644 index 000000000..215fa2b6e --- /dev/null +++ b/resources/openlp.xml @@ -0,0 +1,26 @@ + + + + + + + OpenLP Service File + + + + + OpenLP Theme File + + + From 2f73bc1dd7c584ad13126296bfc03716e3905a75 Mon Sep 17 00:00:00 2001 From: Wesley Stout Date: Sat, 26 Mar 2011 00:11:45 -0500 Subject: [PATCH 030/123] changes to dual monitor --- documentation/manual/source/dualmonitors.rst | 43 ++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/documentation/manual/source/dualmonitors.rst b/documentation/manual/source/dualmonitors.rst index 5c29e8650..eb9beedeb 100644 --- a/documentation/manual/source/dualmonitors.rst +++ b/documentation/manual/source/dualmonitors.rst @@ -180,3 +180,46 @@ on :guilabel:`Save to X Configuration File`. Click :guilabel:`Save` and you should be set. You may want to restart X or your machine just to make sure all the settings carry over the next time you log in. + +Linux Systems With Intel Video +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Generally systems with Intel video cards work very well. They are well supported +by open source drivers. There are, however, a couple of issues that may require +some work arounds. + +**Resolution Issue** + +There is a limitation with certain cards that limits the total resolution to +2048x2048, so both monitors can not have a total resolution totaling more than +that. To work around this it may be necessary to position your monitor as a top +or bottom monitor as opposed to the typical side by side setup. This can easily +be accomplished through your desktop's control of monitors. Please see the +sections on dual monitors with KDE and GNOME above. + +**Primary Monitor Issues** + +With certain cards your system may get confused on what is the primary display. +For example many users will be using a laptop. You will want your laptop screen +to be the primary screen, and your projector to be the secondary monitor. +Certain Intel cards reverse this. To work around this you will need to know the +name of your monitor. If you are a KDE user this info is given to you in the +display settings. If you are not using KDE enter the following in a terminal +without your projector connected to your computer:: + + user@linux:~ $ xrandr -q + +This will give you a long string of output. Screen names will be something along +the lines of LVDM, VGA-0 or some convention similar to that. Without your +projector connected to your computer only one monitor show as being connected. +That will be the monitor you will need as the primary. Now connect your +projector and enter:: + + user@linux:~ $ xrandr --output LVDM --primary + +**Note** it has been reported that when this issue is occurring you will not +want to connect your projector until your desktop is running. + + + + From 07817bf4523aebe818ee9c7d4025c5acdea5e21b Mon Sep 17 00:00:00 2001 From: Wesley Stout Date: Sat, 26 Mar 2011 07:12:00 -0500 Subject: [PATCH 031/123] corrections to dual monitor --- documentation/manual/source/dualmonitors.rst | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/documentation/manual/source/dualmonitors.rst b/documentation/manual/source/dualmonitors.rst index eb9beedeb..3e1a8d210 100644 --- a/documentation/manual/source/dualmonitors.rst +++ b/documentation/manual/source/dualmonitors.rst @@ -190,7 +190,7 @@ some work arounds. **Resolution Issue** -There is a limitation with certain cards that limits the total resolution to +There is a limitation with certain cards which limits the total resolution to 2048x2048, so both monitors can not have a total resolution totaling more than that. To work around this it may be necessary to position your monitor as a top or bottom monitor as opposed to the typical side by side setup. This can easily @@ -211,15 +211,11 @@ without your projector connected to your computer:: This will give you a long string of output. Screen names will be something along the lines of LVDM, VGA-0 or some convention similar to that. Without your -projector connected to your computer only one monitor show as being connected. -That will be the monitor you will need as the primary. Now connect your -projector and enter:: +projector connected to your computer only one monitor will show as being +connected. That will be the monitor you will need to use as the primary. Now +connect your projector and enter:: user@linux:~ $ xrandr --output LVDM --primary **Note** it has been reported that when this issue is occurring you will not want to connect your projector until your desktop is running. - - - - From f19baafb9c5166460c75b161f887d479eea25c69 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 26 Mar 2011 13:45:24 +0000 Subject: [PATCH 032/123] Block 2 Instances of OpenLp running at the same time. Fixes: https://launchpad.net/bugs/742122 --- openlp.pyw | 22 ++++++++++++++++++++++ openlp/core/lib/ui.py | 1 + 2 files changed, 23 insertions(+) diff --git a/openlp.pyw b/openlp.pyw index 572f46934..7d44deaa6 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -34,6 +34,7 @@ from subprocess import Popen, PIPE 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 @@ -151,6 +152,13 @@ class OpenLP(QtGui.QApplication): log.info(u'Openlp version %s' % app_version[u'version']) return app_version + 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. @@ -201,6 +209,17 @@ class OpenLP(QtGui.QApplication): VersionThread(self.mainWindow, app_version).start() return self.exec_() + def isAlreadyRunning(self): + self.sharedMemory = QtCore.QSharedMemory('OpenLP') + if self.sharedMemory.attach(): + QtGui.QMessageBox.critical(None, + UiStrings.Error, UiStrings.OpenLPStart, + QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) + return True + 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))) @@ -275,6 +294,9 @@ def main(): app = OpenLP(qt_args) # Define the settings environment settings = QtCore.QSettings(u'OpenLP', u'OpenLP') + # Instance check + if app.isAlreadyRunning(): + sys.exit() # First time checks in settings # Use explicit reference as not inside a QT environment yet if not settings.value(u'general/has run wizard', diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index a503d7ef6..ad5b796d7 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -75,6 +75,7 @@ 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') OpenService = translate('OpenLP.Ui', 'Open Service') Preview = translate('OpenLP.Ui', 'Preview') PreviewPanel = translate('OpenLP.Ui', 'Preview Panel') From 2c7ec2978edf4cc6152dcef9bfb4c86f2338b581 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Sat, 26 Mar 2011 19:51:07 +0200 Subject: [PATCH 033/123] Removed a console.log which caused older browsers to choke. --- openlp/plugins/remotes/html/openlp.js | 1 - 1 file changed, 1 deletion(-) diff --git a/openlp/plugins/remotes/html/openlp.js b/openlp/plugins/remotes/html/openlp.js index c4eeb4511..cff36b42c 100644 --- a/openlp/plugins/remotes/html/openlp.js +++ b/openlp/plugins/remotes/html/openlp.js @@ -93,7 +93,6 @@ window.OpenLP = { }, setSlide: function (event) { var slide = OpenLP.getElement(event); - console.log(slide); var id = slide.attr("value"); var text = JSON.stringify({"request": {"id": id}}); $.getJSON( From dce9a73153310b4c863ec16114bb19ca18d45c54 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 26 Mar 2011 19:34:01 +0000 Subject: [PATCH 034/123] Add Yes / No to Error Message --- openlp.pyw | 9 ++++++--- openlp/core/lib/ui.py | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/openlp.pyw b/openlp.pyw index 693b7aa0b..f5cb93ea7 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -133,10 +133,13 @@ class OpenLP(QtGui.QApplication): def isAlreadyRunning(self): self.sharedMemory = QtCore.QSharedMemory('OpenLP') if self.sharedMemory.attach(): - QtGui.QMessageBox.critical(None, + status = QtGui.QMessageBox.critical(None, UiStrings.Error, UiStrings.OpenLPStart, - QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) - return True + 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 diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index 6c9281f11..9f26f4056 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -76,7 +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') + OpenLPStart = translate('OpenLP.Ui', 'OpenLP is already running. Do you ' + 'wish continue.') OpenService = translate('OpenLP.Ui', 'Open Service') Preview = translate('OpenLP.Ui', 'Preview') PreviewPanel = translate('OpenLP.Ui', 'Preview Panel') From 70ca844473ef5d4dd0012519d772ef989364c869 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 26 Mar 2011 19:50:15 +0000 Subject: [PATCH 035/123] Fix comments and errors --- openlp.pyw | 4 ++++ openlp/core/lib/ui.py | 8 ++++---- openlp/core/ui/slidecontroller.py | 2 +- openlp/core/ui/starttimedialog.py | 12 ++++++------ openlp/core/ui/starttimeform.py | 6 +++--- openlp/plugins/alerts/lib/alertstab.py | 2 +- 6 files changed, 19 insertions(+), 15 deletions(-) diff --git a/openlp.pyw b/openlp.pyw index f5cb93ea7..07e987842 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -131,6 +131,10 @@ class OpenLP(QtGui.QApplication): 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, diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index 9f26f4056..6aa610d09 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -57,7 +57,7 @@ class UiStrings(object): Export = translate('OpenLP.Ui', 'Export') FontSizePtUnit = translate('OpenLP.Ui', 'pt', 'Abbreviated font pointsize unit') - H = translate('OpenLP.Ui', 'h', 'The abbreviated unit for hours') + 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')) @@ -65,7 +65,7 @@ class UiStrings(object): LiveBGError = translate('OpenLP.Ui', 'Live Background Error') LivePanel = translate('OpenLP.Ui', 'Live Panel') Load = translate('OpenLP.Ui', 'Load') - M = translate('OpenLP.Ui', 'm', 'The abbreviated unit for minutes') + 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') @@ -77,7 +77,7 @@ class UiStrings(object): 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 continue.') + 'wish to continue.') OpenService = translate('OpenLP.Ui', 'Open Service') Preview = translate('OpenLP.Ui', 'Preview') PreviewPanel = translate('OpenLP.Ui', 'Preview Panel') @@ -86,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/slidecontroller.py b/openlp/core/ui/slidecontroller.py index ccc81e4b3..232653326 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -185,7 +185,7 @@ class SlideController(QtGui.QWidget): self.delaySpinBox.setMinimum(1) self.delaySpinBox.setMaximum(180) self.toolbar.addToolbarWidget(u'Image SpinBox', self.delaySpinBox) - self.delaySpinBox.setSuffix(UiStrings.S) + self.delaySpinBox.setSuffix(UiStrings.Seconds) self.delaySpinBox.setToolTip(translate('OpenLP.SlideController', 'Delay between slides in seconds')) else: diff --git a/openlp/core/ui/starttimedialog.py b/openlp/core/ui/starttimedialog.py index c490a8a33..76690f686 100644 --- a/openlp/core/ui/starttimedialog.py +++ b/openlp/core/ui/starttimedialog.py @@ -95,12 +95,12 @@ class Ui_StartTimeDialog(object): def retranslateUi(self, StartTimeDialog): self.setWindowTitle(translate('OpenLP.StartTimeForm', 'Item Start and Fnish Time')) - self.hourSpinBox.setSuffix(UiStrings.H) - self.minuteSpinBox.setSuffix(UiStrings.M) - self.secondSpinBox.setSuffix(UiStrings.S) - self.hourFinishSpinBox.setSuffix(UiStrings.H) - self.minuteFinishSpinBox.setSuffix(UiStrings.M) - self.secondFinishSpinBox.setSuffix(UiStrings.S) + 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.minuteLabel.setText(translate('OpenLP.StartTimeForm', 'Minutes:')) self.secondLabel.setText(translate('OpenLP.StartTimeForm', 'Seconds:')) diff --git a/openlp/core/ui/starttimeform.py b/openlp/core/ui/starttimeform.py index 89ece34c6..a30dd3b8e 100644 --- a/openlp/core/ui/starttimeform.py +++ b/openlp/core/ui/starttimeform.py @@ -53,11 +53,11 @@ class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog): self.hourFinishSpinBox.setValue(hours) self.minuteFinishSpinBox.setValue(minutes) self.secondFinishSpinBox.setValue(seconds) - self.hourFinishLabel.setText(u'%s%s' % (unicode(hour), UiStrings.H)) + self.hourFinishLabel.setText(u'%s%s' % (unicode(hour), UiStrings.Hours)) self.minuteFinishLabel.setText(u'%s%s' % - (unicode(minutes), UiStrings.M)) + (unicode(minutes), UiStrings.Minutes)) self.secondFinishLabel.setText(u'%s%s' % - (unicode(seconds), UiStrings.S)) + (unicode(seconds), UiStrings.Seconds)) return QtGui.QDialog.exec_(self) def accept(self): diff --git a/openlp/plugins/alerts/lib/alertstab.py b/openlp/plugins/alerts/lib/alertstab.py index 698cbfa2a..64a9801ca 100644 --- a/openlp/plugins/alerts/lib/alertstab.py +++ b/openlp/plugins/alerts/lib/alertstab.py @@ -112,7 +112,7 @@ class AlertsTab(SettingsTab): self.FontSizeSpinBox.setSuffix(UiStrings.FontSizePtUnit) self.TimeoutLabel.setText( translate('AlertsPlugin.AlertsTab', 'Alert timeout:')) - self.TimeoutSpinBox.setSuffix(UiStrings.S) + self.TimeoutSpinBox.setSuffix(UiStrings.Seconds) self.PreviewGroupBox.setTitle(UiStrings.Preview) self.FontPreview.setText(UiStrings.OLPV2) From d83f14f8fb1e92a3ee96787ce1f4b26856a7ff16 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sat, 26 Mar 2011 21:07:19 +0100 Subject: [PATCH 036/123] import topics from usr files, clean ups --- openlp/plugins/songs/lib/cclifileimport.py | 98 ++++++++++++---------- 1 file changed, 53 insertions(+), 45 deletions(-) diff --git a/openlp/plugins/songs/lib/cclifileimport.py b/openlp/plugins/songs/lib/cclifileimport.py index f9e2963d1..2cbaa000d 100644 --- a/openlp/plugins/songs/lib/cclifileimport.py +++ b/openlp/plugins/songs/lib/cclifileimport.py @@ -30,6 +30,7 @@ import chardet import codecs from openlp.core.lib import translate +from openlp.plugins.songs.lib import VerseType from songimport import SongImport log = logging.getLogger(__name__) @@ -67,6 +68,7 @@ class CCLIFileImport(SongImport): (song_count, song_total)) filename = unicode(filename) log.debug(u'Importing CCLI File: %s', filename) + self.set_defaults() lines = [] if os.path.isfile(filename): detect_file = open(filename, u'r') @@ -108,35 +110,46 @@ class CCLIFileImport(SongImport): ``[File]`` USR file format first line + ``Type=`` Indicates the file type e.g. *Type=SongSelect Import File* + ``Version=3.0`` File format version + ``[S A2672885]`` Contains the CCLI Song number e.g. *2672885* + ``Title=`` Contains the song title (e.g. *Title=Above All*) + ``Author=`` Contains a | delimited list of the song authors e.g. *Author=LeBlanc, Lenny | Baloche, Paul* + ``Copyright=`` Contains a | delimited list of the song copyrights e.g. Copyright=1999 Integrity's Hosanna! Music | LenSongs Publishing (Verwaltet von Gerth Medien Musikverlag) + ``Admin=`` Contains the song administrator e.g. *Admin=Gerth Medien Musikverlag* + ``Themes=`` Contains a /t delimited list of the song themes e.g. *Themes=Cross/tKingship/tMajesty/tRedeemer* + ``Keys=`` Contains the keys in which the music is played?? e.g. *Keys=A* + ``Fields=`` Contains a list of the songs fields in order /t delimited e.g. *Fields=Vers 1/tVers 2/tChorus 1/tAndere 1* + ``Words=`` Contains the songs various lyrics in order as shown by the *Fields* description @@ -144,57 +157,60 @@ class CCLIFileImport(SongImport): """ log.debug(u'USR file text: %s', textList) - self.set_defaults() + song_author = u'' + song_topics = u'' for line in textList: if line.startswith(u'Title='): - song_name = line[6:].strip() + self.title = line[6:].strip() elif line.startswith(u'Author='): song_author = line[7:].strip() elif line.startswith(u'Copyright='): - song_copyright = line[10:].strip() + self.copyright = line[10:].strip() + elif line.startswith(u'Themes='): + song_topics = line[7:].strip() elif line.startswith(u'[S A'): - song_ccli = line[4:-3].strip() + self.ccli_number = line[4:-3].strip() elif line.startswith(u'Fields='): - #Fields contain single line indicating verse, chorus, etc, - #/t delimited, same as with words field. store seperately - #and process at end. + #Fields contain single line indicating verse, chorus, etc, + #/t delimited, same as with words field. store seperately + #and process at end. song_fields = line[7:].strip() elif line.startswith(u'Words='): song_words = line[6:].strip() - #Unhandled usr keywords:Type,Version,Admin,Themes,Keys - #Process Fields and words sections + # Unhandled usr keywords: Type, Version, Admin, Keys + # Process Fields and words sections. check_first_verse_line = False field_list = song_fields.split(u'/t') words_list = song_words.split(u'/t') for counter in range(0, len(field_list)): if field_list[counter].startswith(u'Ver'): - verse_type = u'V' + verse_type = VerseType.Tags[VerseType.Verse] elif field_list[counter].startswith(u'Ch'): - verse_type = u'C' + verse_type = VerseType.Tags[VerseType.Chorus] elif field_list[counter].startswith(u'Br'): - verse_type = u'B' - else: #Other - verse_type = u'O' + verse_type = VerseType.Tags[VerseType.Bridge] + else: + verse_type = VerseType.Tags[VerseType.Other] check_first_verse_line = True verse_text = unicode(words_list[counter]) verse_text = verse_text.replace(u'/n', u'\n') verse_lines = verse_text.split(u'\n', 1) if check_first_verse_line: if verse_lines[0].startswith(u'(PRE-CHORUS'): - verse_type = u'P' + verse_type = VerseType.Tags[VerseType.PreChorus] log.debug(u'USR verse PRE-CHORUS: %s', verse_lines[0]) verse_text = verse_lines[1] elif verse_lines[0].startswith(u'(BRIDGE'): - verse_type = u'B' + verse_type = VerseType.Tags[VerseType.Bridge] log.debug(u'USR verse BRIDGE') verse_text = verse_lines[1] elif verse_lines[0].startswith(u'('): - verse_type = u'O' + verse_type = VerseType.Tags[VerseType.Other] verse_text = verse_lines[1] if len(verse_text) > 0: self.add_verse(verse_text, verse_type) check_first_verse_line = False - #Handle multiple authors + # Handle multiple authors author_list = song_author.split(u'/') if len(author_list) < 2: author_list = song_author.split(u'|') @@ -204,9 +220,7 @@ class CCLIFileImport(SongImport): self.add_author(u' '.join(reversed(separated))) else: self.add_author(author) - self.title = song_name - self.copyright = song_copyright - self.ccli_number = song_ccli + self.topics = [topic.strip() for topic in song_topics.split(u'/t')] self.finish() def do_import_txt_file(self, textList): @@ -243,12 +257,11 @@ class CCLIFileImport(SongImport): """ log.debug(u'TXT file text: %s', textList) - self.set_defaults() line_number = 0 check_first_verse_line = False verse_text = u'' - song_comments = u'' - song_copyright = u'' + song_author = u'' + song_topics = u'' verse_start = False for line in textList: clean_line = line.strip() @@ -258,12 +271,12 @@ class CCLIFileImport(SongImport): elif verse_start: if verse_text: self.add_verse(verse_text, verse_type) - verse_text = '' + verse_text = u'' verse_start = False else: #line_number=0, song title if line_number == 0: - song_name = clean_line + self.title = clean_line line_number += 1 #line_number=1, verses elif line_number == 1: @@ -271,37 +284,37 @@ class CCLIFileImport(SongImport): if clean_line.startswith(u'CCLI'): line_number += 1 ccli_parts = clean_line.split(' ') - song_ccli = ccli_parts[len(ccli_parts)-1] + self.ccli_number = ccli_parts[len(ccli_parts)-1] elif not verse_start: # We have the verse descriptor - verse_desc_parts = clean_line.split(' ') + verse_desc_parts = clean_line.split(u' ') if len(verse_desc_parts) == 2: if verse_desc_parts[0].startswith(u'Ver'): - verse_type = u'V' + verse_type = VerseType.Tags[VerseType.Verse] elif verse_desc_parts[0].startswith(u'Ch'): - verse_type = u'C' + verse_type = VerseType.Tags[VerseType.Chorus] elif verse_desc_parts[0].startswith(u'Br'): - verse_type = u'B' + verse_type = VerseType.Tags[VerseType.Bridge] else: #we need to analyse the next line for #verse type, so set flag - verse_type = u'O' + verse_type = VerseType.Tags[VerseType.Other] check_first_verse_line = True verse_number = verse_desc_parts[1] else: - verse_type = u'O' + verse_type = VerseType.Tags[VerseType.Other] verse_number = 1 verse_start = True else: #check first line for verse type if check_first_verse_line: if line.startswith(u'(PRE-CHORUS'): - verse_type = u'P' + verse_type = VerseType.Tags[VerseType.PreChorus] elif line.startswith(u'(BRIDGE'): - verse_type = u'B' + verse_type = VerseType.Tags[VerseType.Bridge] # Handle all other misc types elif line.startswith(u'('): - verse_type = u'O' + verse_type = VerseType.Tags[VerseType.Other] else: verse_text = verse_text + line check_first_verse_line = False @@ -313,24 +326,19 @@ class CCLIFileImport(SongImport): #line_number=2, copyright if line_number == 2: line_number += 1 - song_copyright = clean_line + self.copyright = clean_line #n=3, authors elif line_number == 3: line_number += 1 song_author = clean_line #line_number=4, comments lines before last line - elif (line_number == 4) and \ - (not clean_line.startswith(u'CCL')): - song_comments = song_comments + clean_line + elif line_number == 4 and not clean_line.startswith(u'CCL'): + self.comments += clean_line # split on known separators author_list = song_author.split(u'/') if len(author_list) < 2: author_list = song_author.split(u'|') - #Clean spaces before and after author names + # Clean spaces before and after author names. for author_name in author_list: self.add_author(author_name.strip()) - self.title = song_name - self.copyright = song_copyright - self.ccli_number = song_ccli - self.comments = song_comments self.finish() From fef89e7b8dc01e70ccec59051ed121b35f3e3ae8 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 26 Mar 2011 20:10:12 +0000 Subject: [PATCH 037/123] Add Spinbox limis --- openlp/core/ui/starttimedialog.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/openlp/core/ui/starttimedialog.py b/openlp/core/ui/starttimedialog.py index 76690f686..7597341f1 100644 --- a/openlp/core/ui/starttimedialog.py +++ b/openlp/core/ui/starttimedialog.py @@ -52,9 +52,13 @@ class Ui_StartTimeDialog(object): self.dialogLayout.addWidget(self.hourLabel, 1, 0, 1, 1) self.hourSpinBox = QtGui.QSpinBox(StartTimeDialog) self.hourSpinBox.setObjectName(u'hourSpinBox') + 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') @@ -65,9 +69,13 @@ class Ui_StartTimeDialog(object): self.dialogLayout.addWidget(self.minuteLabel, 2, 0, 1, 1) self.minuteSpinBox = QtGui.QSpinBox(StartTimeDialog) self.minuteSpinBox.setObjectName(u'minuteSpinBox') + 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') @@ -78,8 +86,12 @@ class Ui_StartTimeDialog(object): self.dialogLayout.addWidget(self.secondLabel, 3, 0, 1, 1) self.secondSpinBox = QtGui.QSpinBox(StartTimeDialog) self.secondSpinBox.setObjectName(u'secondSpinBox') + 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') From 7cf329422b1e325fc75c42bb1a19ec6414dec68d Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 26 Mar 2011 20:28:05 +0000 Subject: [PATCH 038/123] Fix minor errors --- openlp.pyw | 2 -- openlp/core/ui/starttimedialog.py | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/openlp.pyw b/openlp.pyw index 07e987842..b8c16c585 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -220,8 +220,6 @@ def main(): qInitResources() # Now create and actually run the application. app = OpenLP(qt_args) - # Define the settings environment - settings = QtCore.QSettings(u'OpenLP', u'OpenLP') # Instance check if app.isAlreadyRunning(): sys.exit() diff --git a/openlp/core/ui/starttimedialog.py b/openlp/core/ui/starttimedialog.py index 7597341f1..be34b765e 100644 --- a/openlp/core/ui/starttimedialog.py +++ b/openlp/core/ui/starttimedialog.py @@ -106,7 +106,7 @@ class Ui_StartTimeDialog(object): def retranslateUi(self, StartTimeDialog): self.setWindowTitle(translate('OpenLP.StartTimeForm', - 'Item Start and Fnish Time')) + 'Item Start and Finish Time')) self.hourSpinBox.setSuffix(UiStrings.Hours) self.minuteSpinBox.setSuffix(UiStrings.Minutes) self.secondSpinBox.setSuffix(UiStrings.Seconds) From 41f0be38fbe4d1c05e424ca8c98abea6772d51f6 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sat, 26 Mar 2011 21:45:11 +0100 Subject: [PATCH 039/123] clean ups --- openlp/plugins/songs/lib/cclifileimport.py | 31 +++++++++------------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/openlp/plugins/songs/lib/cclifileimport.py b/openlp/plugins/songs/lib/cclifileimport.py index 2cbaa000d..0f1c5c063 100644 --- a/openlp/plugins/songs/lib/cclifileimport.py +++ b/openlp/plugins/songs/lib/cclifileimport.py @@ -37,9 +37,9 @@ log = logging.getLogger(__name__) class CCLIFileImport(SongImport): """ - The :class:`CCLIFileImport` class provides OpenLP with the ability to - import CCLI SongSelect song files in both .txt and .usr formats. - See http://www.ccli.com/ for more details. + The :class:`CCLIFileImport` class provides OpenLP with the ability to import + CCLI SongSelect song files in both .txt and .usr formats. See + ``_ for more details. """ def __init__(self, manager, **kwargs): @@ -56,7 +56,7 @@ class CCLIFileImport(SongImport): def do_import(self): """ - Import either a .usr or a .txt SongSelect file + Import either a ``.usr`` or a ``.txt`` SongSelect file. """ log.debug(u'Starting CCLI File Import') song_total = len(self.import_source) @@ -83,12 +83,10 @@ class CCLIFileImport(SongImport): lines = infile.readlines() ext = os.path.splitext(filename)[1] if ext.lower() == u'.usr': - log.info(u'SongSelect .usr format file found %s: ', - filename) + log.info(u'SongSelect .usr format file found: %s', filename) self.do_import_usr_file(lines) elif ext.lower() == u'.txt': - log.info(u'SongSelect .txt format file found %s: ', - filename) + log.info(u'SongSelect .txt format file found: %s', filename) self.do_import_txt_file(lines) else: log.info(u'Extension %s is not valid', filename) @@ -99,9 +97,8 @@ class CCLIFileImport(SongImport): def do_import_usr_file(self, textList): """ - The :func:`do_import_usr_file` method provides OpenLP - with the ability to import CCLI SongSelect songs in - *USR* file format + The :func:`do_import_usr_file` method provides OpenLP with the ability + to import CCLI SongSelect songs in *USR* file format. ``textList`` An array of strings containing the usr file content. @@ -225,9 +222,8 @@ class CCLIFileImport(SongImport): def do_import_txt_file(self, textList): """ - The :func:`do_import_txt_file` method provides OpenLP - with the ability to import CCLI SongSelect songs in - *TXT* file format + The :func:`do_import_txt_file` method provides OpenLP with the ability + to import CCLI SongSelect songs in *TXT* file format. ``textList`` An array of strings containing the txt file content. @@ -261,7 +257,6 @@ class CCLIFileImport(SongImport): check_first_verse_line = False verse_text = u'' song_author = u'' - song_topics = u'' verse_start = False for line in textList: clean_line = line.strip() @@ -296,8 +291,8 @@ class CCLIFileImport(SongImport): elif verse_desc_parts[0].startswith(u'Br'): verse_type = VerseType.Tags[VerseType.Bridge] else: - #we need to analyse the next line for - #verse type, so set flag + # we need to analyse the next line for + # verse type, so set flag verse_type = VerseType.Tags[VerseType.Other] check_first_verse_line = True verse_number = verse_desc_parts[1] @@ -306,7 +301,7 @@ class CCLIFileImport(SongImport): verse_number = 1 verse_start = True else: - #check first line for verse type + # check first line for verse type if check_first_verse_line: if line.startswith(u'(PRE-CHORUS'): verse_type = VerseType.Tags[VerseType.PreChorus] From 252f316e0e6362a4faed2657d440b57417f7b75a Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sat, 26 Mar 2011 21:51:41 +0100 Subject: [PATCH 040/123] missing spaces --- openlp/plugins/songs/lib/cclifileimport.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/plugins/songs/lib/cclifileimport.py b/openlp/plugins/songs/lib/cclifileimport.py index 0f1c5c063..3f66a6855 100644 --- a/openlp/plugins/songs/lib/cclifileimport.py +++ b/openlp/plugins/songs/lib/cclifileimport.py @@ -279,7 +279,7 @@ class CCLIFileImport(SongImport): if clean_line.startswith(u'CCLI'): line_number += 1 ccli_parts = clean_line.split(' ') - self.ccli_number = ccli_parts[len(ccli_parts)-1] + self.ccli_number = ccli_parts[len(ccli_parts) - 1] elif not verse_start: # We have the verse descriptor verse_desc_parts = clean_line.split(u' ') From f2acce4a77a261fcfef4bb9f228a7a220c93abee Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sat, 26 Mar 2011 21:59:44 +0100 Subject: [PATCH 041/123] missing spaces --- openlp/plugins/songs/lib/cclifileimport.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openlp/plugins/songs/lib/cclifileimport.py b/openlp/plugins/songs/lib/cclifileimport.py index 3f66a6855..dcfab0942 100644 --- a/openlp/plugins/songs/lib/cclifileimport.py +++ b/openlp/plugins/songs/lib/cclifileimport.py @@ -27,7 +27,7 @@ import logging import os import chardet -import codecs +import codecsu from openlp.core.lib import translate from openlp.plugins.songs.lib import VerseType @@ -168,9 +168,9 @@ class CCLIFileImport(SongImport): elif line.startswith(u'[S A'): self.ccli_number = line[4:-3].strip() elif line.startswith(u'Fields='): - #Fields contain single line indicating verse, chorus, etc, - #/t delimited, same as with words field. store seperately - #and process at end. + # Fields contain single line indicating verse, chorus, etc, + # /t delimited, same as with words field. store seperately + # and process at end. song_fields = line[7:].strip() elif line.startswith(u'Words='): song_words = line[6:].strip() From dbefa29054e0dfa69c49283bcb021ab4a29cdfd8 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sat, 26 Mar 2011 22:03:28 +0100 Subject: [PATCH 042/123] fixed mistake --- openlp/plugins/songs/lib/cclifileimport.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/plugins/songs/lib/cclifileimport.py b/openlp/plugins/songs/lib/cclifileimport.py index dcfab0942..03a86c455 100644 --- a/openlp/plugins/songs/lib/cclifileimport.py +++ b/openlp/plugins/songs/lib/cclifileimport.py @@ -27,7 +27,7 @@ import logging import os import chardet -import codecsu +import codecs from openlp.core.lib import translate from openlp.plugins.songs.lib import VerseType From fc3f35f0f905a9d6cad02850b0ce4a3c02c07503 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 27 Mar 2011 17:30:40 +0100 Subject: [PATCH 043/123] Question mark --- openlp/core/lib/rendermanager.py | 1 + openlp/core/lib/ui.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/openlp/core/lib/rendermanager.py b/openlp/core/lib/rendermanager.py index 65f2b355c..a93b5d90e 100644 --- a/openlp/core/lib/rendermanager.py +++ b/openlp/core/lib/rendermanager.py @@ -242,6 +242,7 @@ class RenderManager(object): Add line endings after each line of text used for bibles. """ log.debug(u'format slide') + print words return self.renderer.format_slide(words, line_break, self.force_page) def calculate_default(self, screen): diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index 6aa610d09..c1a9f8b35 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -77,7 +77,7 @@ class UiStrings(object): 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.') + 'wish to continue?') OpenService = translate('OpenLP.Ui', 'Open Service') Preview = translate('OpenLP.Ui', 'Preview') PreviewPanel = translate('OpenLP.Ui', 'Preview Panel') From d3e2fe79e9a0506d6be5e3d0aed4136167657a50 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 27 Mar 2011 17:39:04 +0100 Subject: [PATCH 044/123] wot not print --- openlp/core/lib/rendermanager.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openlp/core/lib/rendermanager.py b/openlp/core/lib/rendermanager.py index a93b5d90e..65f2b355c 100644 --- a/openlp/core/lib/rendermanager.py +++ b/openlp/core/lib/rendermanager.py @@ -242,7 +242,6 @@ class RenderManager(object): Add line endings after each line of text used for bibles. """ log.debug(u'format slide') - print words return self.renderer.format_slide(words, line_break, self.force_page) def calculate_default(self, screen): From c0f5191d6cd50ed010ef838d08559b2844e9d15f Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 27 Mar 2011 19:00:34 +0200 Subject: [PATCH 045/123] clicked rather than pressed --- openlp/plugins/custom/forms/editcustomslideform.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/plugins/custom/forms/editcustomslideform.py b/openlp/plugins/custom/forms/editcustomslideform.py index 24ddc3775..7d4e32968 100644 --- a/openlp/plugins/custom/forms/editcustomslideform.py +++ b/openlp/plugins/custom/forms/editcustomslideform.py @@ -45,7 +45,7 @@ class EditCustomSlideForm(QtGui.QDialog, Ui_CustomSlideEditDialog): self.setupUi(self) # Connecting signals and slots QtCore.QObject.connect(self.splitButton, - QtCore.SIGNAL(u'pressed()'), self.onSplitButtonPressed) + QtCore.SIGNAL(u'clicked()'), self.onSplitButtonPressed) def setText(self, text): """ From 26f144e1eca47cf3ddcad1cedb015d87c3ebfe10 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 27 Mar 2011 20:28:03 +0200 Subject: [PATCH 046/123] fix for ticket #142 --- openlp/core/lib/serviceitem.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 48a277633..2305f1102 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -406,24 +406,28 @@ class ServiceItem(object): def get_rendered_frame(self, row): """ - Returns the correct frame for a given list and - renders it if required. + Returns the correct frame for a given list and renders it if required. """ - if self.service_item_type == ServiceItemType.Text: - return self._display_frames[row][u'html'].split(u'\n')[0] - elif self.service_item_type == ServiceItemType.Image: - return self._raw_frames[row][u'title'] - else: - return self._raw_frames[row][u'image'] + try: + if self.service_item_type == ServiceItemType.Text: + frame = self._display_frames[row][u'html'].split(u'\n')[0] + elif self.service_item_type == ServiceItemType.Image: + frame = self._raw_frames[row][u'title'] + else: + frame = self._raw_frames[row][u'image'] + except IndexError: + frame = u'' + return frame def get_frame_title(self, row=0): """ Returns the title of the raw frame """ try: - return self._raw_frames[row][u'title'] + title = self._raw_frames[row][u'title'] except IndexError: - return u'' + title = u'' + return title def get_frame_path(self, row=0): """ From 3efb36c9e389c870dcbf7b506ebf34ea02812d5f Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Sun, 27 Mar 2011 22:25:02 +0200 Subject: [PATCH 047/123] Set the HTML/Qt Help theme when building either one of those, otherwise use the default theme. --- documentation/manual/source/conf.py | 31 ++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/documentation/manual/source/conf.py b/documentation/manual/source/conf.py index 6e9285aed..c10164669 100644 --- a/documentation/manual/source/conf.py +++ b/documentation/manual/source/conf.py @@ -14,6 +14,8 @@ import sys import os +print sys.argv + # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. @@ -42,7 +44,7 @@ master_doc = 'index' # General information about the project. project = u'OpenLP' -copyright = u'2010, Raoul Snyman' +copyright = u'2004 - 2011, Raoul Snyman' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -92,19 +94,30 @@ pygments_style = 'sphinx' # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +if sys.argv[2] == 'qthelp' or sys.argv[2] == 'htmlhelp': + html_theme = 'openlp_qthelp' +else: + html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +if sys.argv[2] == 'html': + html_theme_options = { + 'sidebarbgcolor': '#3a60a9', + 'relbarbgcolor': '#203b6f', + 'footerbgcolor': '#26437c', + 'headtextcolor': '#203b6f', + 'linkcolor': '#26437c', + 'sidebarlinkcolor': '#ceceff' + } # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +html_theme_path = [os.path.join(os.path.abspath('..'), 'themes')] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +html_title = u'OpenLP 2.0 Reference Manual' # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None @@ -125,7 +138,7 @@ html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. @@ -165,7 +178,7 @@ html_static_path = ['_static'] #html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'OpenLPdoc' +htmlhelp_basename = 'OpenLP' # -- Options for LaTeX output -------------------------------------------------- @@ -179,7 +192,7 @@ htmlhelp_basename = 'OpenLPdoc' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'OpenLP.tex', u'OpenLP Documentation', + ('index', 'OpenLP.tex', u'OpenLP Reference Manual', u'Wesley Stout', 'manual'), ] @@ -212,6 +225,6 @@ latex_documents = [ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'openlp', u'OpenLP Documentation', + ('index', 'openlp', u'OpenLP Reference Manual', [u'Wesley Stout'], 1) ] From 63282e71372709695e14fd746e5b9880521aac7e Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Sun, 27 Mar 2011 23:01:29 +0200 Subject: [PATCH 048/123] Removed an unnecessary print statement. --- documentation/manual/source/conf.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/documentation/manual/source/conf.py b/documentation/manual/source/conf.py index c10164669..2e9c0a88f 100644 --- a/documentation/manual/source/conf.py +++ b/documentation/manual/source/conf.py @@ -14,8 +14,6 @@ import sys import os -print sys.argv - # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. From 1e973c6c8db25ed36fb9c71f82425fd759ed1985 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Sun, 27 Mar 2011 23:28:20 +0100 Subject: [PATCH 049/123] Attempt superscript without affecting line spacing --- openlp/core/lib/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index ddb1ae9b1..a9e8e86f1 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -65,8 +65,9 @@ base_html_expands.append({u'desc': u'White', u'start tag': u'{w}', u'start html': u'', u'end tag': u'{/w}', u'end html': u'', u'protected': True}) base_html_expands.append({u'desc': u'Superscript', u'start tag': u'{su}', - u'start html': u'', u'end tag': u'{/su}', u'end html': u'', - u'protected': True}) + u'start html': u'', u'end tag': u'{/su}', + u'end html': u'', u'protected': True}) base_html_expands.append({u'desc': u'Subscript', u'start tag': u'{sb}', u'start html': u'', u'end tag': u'{/sb}', u'end html': u'', u'protected': True}) From 534c17fbf14e82975e1551147c5c4388c400ac71 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Mon, 28 Mar 2011 10:52:37 +0200 Subject: [PATCH 050/123] Changed line endings on make.bat to Windows. --- documentation/manual/make.bat | 224 +++++++++++++++++----------------- 1 file changed, 112 insertions(+), 112 deletions(-) diff --git a/documentation/manual/make.bat b/documentation/manual/make.bat index 8d21b45ce..20bff1ee7 100644 --- a/documentation/manual/make.bat +++ b/documentation/manual/make.bat @@ -1,112 +1,112 @@ -@ECHO OFF - -REM Command file for Sphinx documentation - -set SPHINXBUILD=sphinx-build -set ALLSPHINXOPTS=-d build/doctrees %SPHINXOPTS% source -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% -) - -if "%1" == "" goto help - -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. changes to make an overview over all changed/added/deprecated items - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (build\*) do rmdir /q /s %%i - del /q /s build\* - goto end -) - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% build/html - echo. - echo.Build finished. The HTML pages are in build/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% build/dirhtml - echo. - echo.Build finished. The HTML pages are in build/dirhtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% build/pickle - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% build/json - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% build/htmlhelp - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in build/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% build/qthelp - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in build/qthelp, like this: - echo.^> qcollectiongenerator build\qthelp\OpenLP.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile build\qthelp\OpenLP.ghc - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% build/latex - echo. - echo.Build finished; the LaTeX files are in build/latex. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% build/changes - echo. - echo.The overview file is in build/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% build/linkcheck - echo. - echo.Link check complete; look for any errors in the above output ^ -or in build/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% build/doctest - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in build/doctest/output.txt. - goto end -) - -:end +@ECHO OFF + +REM Command file for Sphinx documentation + +set SPHINXBUILD=sphinx-build +set ALLSPHINXOPTS=-d build/doctrees %SPHINXOPTS% source +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. changes to make an overview over all changed/added/deprecated items + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (build\*) do rmdir /q /s %%i + del /q /s build\* + goto end +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% build/html + echo. + echo.Build finished. The HTML pages are in build/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% build/dirhtml + echo. + echo.Build finished. The HTML pages are in build/dirhtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% build/pickle + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% build/json + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% build/htmlhelp + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in build/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% build/qthelp + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in build/qthelp, like this: + echo.^> qcollectiongenerator build\qthelp\OpenLP.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile build\qthelp\OpenLP.ghc + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% build/latex + echo. + echo.Build finished; the LaTeX files are in build/latex. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% build/changes + echo. + echo.The overview file is in build/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% build/linkcheck + echo. + echo.Link check complete; look for any errors in the above output ^ +or in build/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% build/doctest + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in build/doctest/output.txt. + goto end +) + +:end From 3aaaa8895b5102a3054cfd0f04a915b10db0c96a Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Mon, 28 Mar 2011 19:29:25 +0200 Subject: [PATCH 051/123] fixed a bug in the exception form --- openlp/core/ui/exceptionform.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openlp/core/ui/exceptionform.py b/openlp/core/ui/exceptionform.py index 50cf597ea..0ae9497c9 100644 --- a/openlp/core/ui/exceptionform.py +++ b/openlp/core/ui/exceptionform.py @@ -57,6 +57,7 @@ except ImportError: from openlp.core.lib import translate, SettingsManager from openlp.core.lib.mailto import mailto from openlp.core.lib.ui import UiStrings +from openlp.core.utils import get_application_version from exceptiondialog import Ui_ExceptionDialog @@ -78,7 +79,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog): return QtGui.QDialog.exec_(self) def _createReport(self): - openlp_version = self.parent().applicationVersion[u'full'] + openlp_version = get_application_version() description = unicode(self.descriptionTextEdit.toPlainText()) traceback = unicode(self.exceptionTextEdit.toPlainText()) system = unicode(translate('OpenLP.ExceptionForm', From 2cce748d20b9fd458add0f4f4ece1f3b54a61e7a Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Mon, 28 Mar 2011 21:18:55 +0100 Subject: [PATCH 052/123] Change superscript so it still works in print. Fix problem with openlp not closing --- openlp.pyw | 16 +++++++++------- openlp/core/lib/__init__.py | 5 ++--- openlp/core/lib/htmlbuilder.py | 7 ++++++- openlp/core/ui/mainwindow.py | 10 ++++++---- openlp/core/ui/printserviceform.py | 4 ++-- 5 files changed, 25 insertions(+), 17 deletions(-) diff --git a/openlp.pyw b/openlp.pyw index b8c16c585..c9c5294b5 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -78,12 +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 exec_(self): + #""" + #Override exec method to allow the shared memory to be released on exit + #""" + #return QtGui.QApplication.exec_() + #self.sharedMemory.detach() + #return i def run(self): """ @@ -115,7 +116,8 @@ class OpenLP(QtGui.QApplication): # make sure Qt really display the splash screen self.processEvents() # start the main app window - self.mainWindow = MainWindow(screens, self) + self.mainWindow = MainWindow(screens, self.clipboard(), + self.arguments()) self.mainWindow.show() if show_splash: # now kill the splashscreen diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index a9e8e86f1..ddb1ae9b1 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -65,9 +65,8 @@ base_html_expands.append({u'desc': u'White', u'start tag': u'{w}', u'start html': u'', u'end tag': u'{/w}', u'end html': u'', u'protected': True}) base_html_expands.append({u'desc': u'Superscript', u'start tag': u'{su}', - u'start html': u'', u'end tag': u'{/su}', - u'end html': u'', u'protected': True}) + u'start html': u'', u'end tag': u'{/su}', u'end html': u'', + u'protected': True}) base_html_expands.append({u'desc': u'Subscript', u'start tag': u'{sb}', u'start html': u'', u'end tag': u'{/sb}', u'end html': u'', u'protected': True}) diff --git a/openlp/core/lib/htmlbuilder.py b/openlp/core/lib/htmlbuilder.py index 67a05c6a1..c4361a421 100644 --- a/openlp/core/lib/htmlbuilder.py +++ b/openlp/core/lib/htmlbuilder.py @@ -85,7 +85,12 @@ body { } /* lyric css */ %s - +sup { + font-size:0.6em; + vertical-align:top; + position:relative; + top:-0.3em; +}