diff --git a/OpenLP.spec b/OpenLP.spec index 366bdf31d..9569af6c1 100644 --- a/OpenLP.spec +++ b/OpenLP.spec @@ -1,6 +1,6 @@ # -*- mode: python -*- a = Analysis([os.path.join(HOMEPATH,'support\\_mountzlib.py'), os.path.join(HOMEPATH,'support\\useUnicode.py'), 'openlp.pyw'], - pathex=['c:\\Documents and Settings\\raoul\\My Documents\\My Projects\\openlp\\pyinstaller']) + pathex=[os.path.abspath('.')]) pyz = PYZ(a.pure) exe = EXE(pyz, a.scripts, diff --git a/openlp/.version b/openlp/.version index f8e233b27..2007f03af 100644 --- a/openlp/.version +++ b/openlp/.version @@ -1 +1 @@ -1.9.0 +1.9.1-bzr821 diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 92c8fed94..48f0f6894 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -25,6 +25,7 @@ import logging import time +import re from PyQt4 import QtCore, QtGui @@ -60,6 +61,7 @@ class VersionThread(QtCore.QThread): QtCore.QThread.__init__(self, parent) self.parent = parent self.app_version = app_version + self.version_splitter = re.compile(r'([0-9]+).([0-9]+).([0-9]+)(?:-bzr([0-9]+))') def run(self): """ @@ -68,8 +70,29 @@ class VersionThread(QtCore.QThread): time.sleep(1) Receiver.send_message(u'maindisplay_blank_check') version = check_latest_version(self.app_version) - #new version has arrived - if version != self.app_version[u'full']: + remote_version = {} + local_version = {} + match = self.version_splitter.match(version) + if match: + remote_version[u'major'] = int(match.group(1)) + remote_version[u'minor'] = int(match.group(2)) + remote_version[u'release'] = int(match.group(3)) + if len(match.groups()) > 3: + remote_version[u'revision'] = int(match.group(4)) + match = self.version_splitter.match(self.app_version[u'full']) + if match: + local_version[u'major'] = int(match.group(1)) + local_version[u'minor'] = int(match.group(2)) + local_version[u'release'] = int(match.group(3)) + if len(match.groups()) > 3: + local_version[u'revision'] = int(match.group(4)) + if remote_version[u'major'] > local_version[u'major'] or \ + remote_version[u'minor'] > local_version[u'minor'] or \ + remote_version[u'release'] > local_version[u'release']: + Receiver.send_message(u'openlp_version_check', u'%s' % version) + elif remote_version.get(u'revision') and \ + local_version.get(u'revision') and \ + remote_version[u'revision'] > local_version[u'revision']: Receiver.send_message(u'openlp_version_check', u'%s' % version) class Ui_MainWindow(object): diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index c5fa0b73c..df127c85c 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -711,6 +711,10 @@ class ServiceManager(QtGui.QWidget): self.regenerateServiceItems() def regenerateServiceItems(self): + """ + Rebuild the service list as things have changed and a + repaint is the easiest way to do this. + """ #force reset of renderer as theme data has changed self.parent.RenderManager.themedata = None if self.serviceItems: @@ -963,4 +967,4 @@ class ServiceManager(QtGui.QWidget): data_item[u'notes'] = unicode(service_item.notes) data_item[u'selected'] = (item == curitem) data.append(data_item) - Receiver.send_message(u'servicemanager_list_response', data) \ No newline at end of file + Receiver.send_message(u'servicemanager_list_response', data) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index e614205fe..a2bd68e13 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -516,6 +516,9 @@ class SlideController(QtGui.QWidget): #Set pointing cursor when we have somthing to point at self.PreviewListWidget.setCursor(QtCore.Qt.PointingHandCursor) before = time.time() + #Clear the old serviceItem cache to release memory + if self.serviceItem: + self.serviceItem.cache = [] self.serviceItem = serviceItem self.PreviewListWidget.clear() self.PreviewListWidget.setRowCount(0) @@ -531,8 +534,7 @@ class SlideController(QtGui.QWidget): slideHeight = 0 #It is a based Text Render if self.serviceItem.is_text(): - if frame[u'verseTag'] is not None: - #only load the slot once + if frame[u'verseTag']: bits = frame[u'verseTag'].split(u':') tag = None #If verse handle verse number else tag only @@ -545,13 +547,13 @@ class SlideController(QtGui.QWidget): tag = bits[0] tag1 = tag row = bits[0][0:1] - if self.isLive: - if tag1 not in self.slideList: - self.slideList[tag1] = framenumber - self.SongMenu.menu().addAction(self.trUtf8(u'%s'%tag1), - self.onSongBarHandler) else: row += 1 + if self.isLive and frame[u'verseTag'] is not None: + if tag1 not in self.slideList: + self.slideList[tag1] = framenumber + self.SongMenu.menu().addAction(self.trUtf8(u'%s'%tag1), + self.onSongBarHandler) item.setText(frame[u'text']) else: label = QtGui.QLabel() diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 0a2d29b14..2bf72e9b9 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -323,7 +323,9 @@ class SongMediaItem(MediaManagerItem): #no verse list or only 1 space (in error) if not song.verse_order or not song.verse_order.strip(): for verse in verseList: - service_item.add_from_text(verse[1][:30], unicode(verse[1])) + verseTag = u'%s:%s' % (verse[0][u'type'], verse[0][u'label']) + service_item.add_from_text(\ + verse[1][:30], unicode(verse[1]), verseTag) else: #Loop through the verse list and expand the song accordingly. for order in song.verse_order.upper().split(u' '): diff --git a/resources/innosetup/OpenLP-2.0.iss b/resources/innosetup/OpenLP-2.0.iss index b826fa76f..e75f1076f 100644 --- a/resources/innosetup/OpenLP-2.0.iss +++ b/resources/innosetup/OpenLP-2.0.iss @@ -1,28 +1,33 @@ ; Script generated by the Inno Setup Script Wizard. ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! -#define MyAppName "OpenLP" -#define MyAppVerName "OpenLP 2.0" -#define MyAppPublisher "OpenLP Developers" -#define MyAppURL "http://openlp.org/" -#define MyAppExeName "OpenLP.exe" +#define AppName "OpenLP" +#define AppVerName "OpenLP 2.0" +#define AppPublisher "OpenLP Developers" +#define AppURL "http://openlp.org/" +#define AppExeName "OpenLP.exe" + +#define FileHandle FileOpen("..\..\dist\OpenLP\.version") +#define FileLine FileRead(FileHandle) +#define RealVersion FileLine +#expr FileClose(FileHandle) [Setup] ; NOTE: The value of AppId uniquely identifies this application. ; Do not use the same AppId value in installers for other applications. ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) AppId={{AA7699FA-B2D2-43F4-8A70-D497D03C9485} -AppName={#MyAppName} -AppVerName={#MyAppVerName} -AppPublisher={#MyAppPublisher} -AppPublisherURL={#MyAppURL} -AppSupportURL={#MyAppURL} -AppUpdatesURL={#MyAppURL} -DefaultDirName={pf}\{#MyAppName} -DefaultGroupName=OpenLP 2.0 +AppName={#AppName} +AppVerName={#AppVerName} +AppPublisher={#AppPublisher} +AppPublisherURL={#AppURL} +AppSupportURL={#AppURL} +AppUpdatesURL={#AppURL} +DefaultDirName={pf}\{#AppName} +DefaultGroupName={#AppVerName} AllowNoIcons=true LicenseFile=LICENSE.txt -OutputBaseFilename=OpenLP-1.9.0-bzr739-setup +OutputBaseFilename=OpenLP-{#RealVersion}-setup Compression=lzma SolidCompression=true SetupIconFile=C:\Program Files\Inno Setup 5\Examples\Setup.ico @@ -57,20 +62,26 @@ Name: desktopicon; Description: {cm:CreateDesktopIcon}; GroupDescription: {cm:Ad Name: quicklaunchicon; Description: {cm:CreateQuickLaunchIcon}; GroupDescription: {cm:AdditionalIcons} [Files] -Source: ..\..\dist\OpenLP\*; DestDir: {app}; Flags: ignoreversion -Source: ..\..\dist\OpenLP\plugins\*; DestDir: {app}\plugins; Flags: ignoreversion recursesubdirs createallsubdirs -Source: ..\..\dist\OpenLP\Microsoft.VC90.CRT\*; DestDir: {app}\Microsoft.VC90.CRT; Flags: ignoreversion recursesubdirs createallsubdirs -Source: ..\..\dist\OpenLP\qt4_plugins\*; DestDir: {app}\qt4_plugins; Flags: ignoreversion recursesubdirs createallsubdirs -Source: ..\..\dist\OpenLP\eggs\*; DestDir: {app}\eggs; Flags: ignoreversion recursesubdirs createallsubdirs -Source: openlp.conf; DestDir: {userappdata}\openlp; Flags: ignoreversion onlyifdoesntexist +Source: ..\..\dist\OpenLP\*; DestDir: {app}; Flags: ignoreversion recursesubdirs createallsubdirs ; NOTE: Don't use "Flags: ignoreversion" on any shared system files [Icons] -Name: {group}\{#MyAppName}; Filename: {app}\{#MyAppExeName} -Name: {group}\{cm:ProgramOnTheWeb,{#MyAppName}}; Filename: {#MyAppURL} -Name: {group}\{cm:UninstallProgram,{#MyAppName}}; Filename: {uninstallexe} -Name: {commondesktop}\{#MyAppName}; Filename: {app}\{#MyAppExeName}; Tasks: desktopicon -Name: {userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName}; Filename: {app}\{#MyAppExeName}; Tasks: quicklaunchicon +Name: {group}\{#AppName}; Filename: {app}\{#AppExeName} +Name: {group}\{cm:ProgramOnTheWeb,{#AppName}}; Filename: {#AppURL} +Name: {group}\{cm:UninstallProgram,{#AppName}}; Filename: {uninstallexe} +Name: {commondesktop}\{#AppName}; Filename: {app}\{#AppExeName}; Tasks: desktopicon +Name: {userappdata}\Microsoft\Internet Explorer\Quick Launch\{#AppName}; Filename: {app}\{#AppExeName}; Tasks: quicklaunchicon [Run] -Filename: {app}\{#MyAppExeName}; Description: {cm:LaunchProgram,{#MyAppName}}; Flags: nowait postinstall skipifsilent +Filename: {app}\{#AppExeName}; Description: {cm:LaunchProgram,{#AppName}}; Flags: nowait postinstall skipifsilent + +[Registry] +Root: HKCU; SubKey: Software\OpenLP\OpenLP\alerts; ValueType: dword; ValueName: status; ValueData: $00000001 +Root: HKCU; SubKey: Software\OpenLP\OpenLP\bibles; ValueType: dword; ValueName: status; ValueData: $00000001 +Root: HKCU; SubKey: Software\OpenLP\OpenLP\custom; ValueType: dword; ValueName: status; ValueData: $00000001 +Root: HKCU; SubKey: Software\OpenLP\OpenLP\images; ValueType: dword; ValueName: status; ValueData: $00000001 +Root: HKCU; SubKey: Software\OpenLP\OpenLP\media; ValueType: dword; ValueName: status; ValueData: $00000001 +Root: HKCU; SubKey: Software\OpenLP\OpenLP\presentations; ValueType: dword; ValueName: status; ValueData: $00000001 +Root: HKCU; SubKey: Software\OpenLP\OpenLP\remotes; ValueType: dword; ValueName: status; ValueData: $00000001 +Root: HKCU; SubKey: Software\OpenLP\OpenLP\songs; ValueType: dword; ValueName: status; ValueData: $00000001 +Root: HKCU; SubKey: Software\OpenLP\OpenLP\songusage; ValueType: dword; ValueName: status; ValueData: $00000001 diff --git a/resources/innosetup/OpenLP.reg b/resources/innosetup/OpenLP.reg new file mode 100644 index 000000000..503e718a2 Binary files /dev/null and b/resources/innosetup/OpenLP.reg differ diff --git a/resources/pyinstaller/windows-builder.py b/resources/pyinstaller/windows-builder.py new file mode 100644 index 000000000..42592768a --- /dev/null +++ b/resources/pyinstaller/windows-builder.py @@ -0,0 +1,130 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2010 Raoul Snyman # +# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael # +# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin # +# Thompson, Jon Tibble, Carsten Tinggaard # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### + +""" +Windows Build Script +-------------------- + +This script is used to build the Windows binary and the accompanying installer. + +For this script to work out of the box, it depends on being inside the +"resources/pyinstaller" directory in the OpenLP source tree, it depends on +OpenLP having it's own project directory which all the branches live in, and it +depends on PyInstaller being +""" + +import os +from shutil import copy +from subprocess import Popen, PIPE + +script_path = os.path.split(os.path.abspath(__file__))[0] +pyinstaller_path = os.path.abspath(os.path.join(script_path, u'..', u'..', u'..', u'..', u'pyinstaller')) +innosetup_path = os.path.join(os.getenv(u'PROGRAMFILES'), 'Inno Setup 5') +iss_path = os.path.abspath(os.path.join(script_path, u'..', u'innosetup')) +branch_path = os.path.abspath(os.path.join(script_path, u'..', u'..')) +source_path = os.path.join(branch_path, u'openlp') +dist_path = os.path.join(branch_path, u'dist', u'OpenLP') + + +def run_pyinstaller(): + print u'Running PyInstaller...' + os.chdir(branch_path) + pyinstaller = Popen((u'python', os.path.join(pyinstaller_path, u'Build.py'), + u'OpenLP.spec')) + code = pyinstaller.wait() + if code != 0: + raise Exception(u'Error running PyInstaller Build.py') + +def write_version_file(): + print u'Writing version file...' + os.chdir(branch_path) + 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] + versionstring = latest == revision and tag or u'%s-bzr%s' % (tag, latest) + f = open(os.path.join(dist_path, u'.version'), u'w') + f.write(versionstring) + f.close() + +def copy_plugins(): + print u'Copying plugins...' + source = os.path.join(source_path, u'plugins') + dest = os.path.join(dist_path, u'plugins') + for root, dirs, files in os.walk(source): + for filename in files: + if not filename.endswith(u'.pyc'): + dest_path = os.path.join(dest, root[len(source)+1:]) + if not os.path.exists(dest_path): + os.makedirs(dest_path) + copy(os.path.join(root, filename), + os.path.join(dest_path, filename)) + +def copy_windows_files(): + print u'Copying extra files for Windows...' + copy(os.path.join(iss_path, u'OpenLP.ico'), os.path.join(dist_path, u'OpenLP.ico')) + copy(os.path.join(iss_path, u'LICENSE.txt'), os.path.join(dist_path, u'LICENSE.txt')) + +def run_innosetup(): + print u'Running Inno Setup...' + os.chdir(iss_path) + run_command = u'"%s" "%s"' % (os.path.join(innosetup_path, u'ISCC.exe'), + os.path.join(iss_path, u'OpenLP-2.0.iss')) + print run_command + innosetup = Popen(run_command) + code = innosetup.wait() + if code != 0: + raise Exception(u'Error running Inno Setup') + +def main(): + print "Script path:", script_path + print "PyInstaller path:", pyinstaller_path + print "Inno Setup path:", innosetup_path + print "ISS file path:", iss_path + print "Branch path:", branch_path + print "Source path:", source_path + print "\"dist\" path:", dist_path + run_pyinstaller() + write_version_file() + copy_plugins() + copy_windows_files() + run_innosetup() + print "Done." + +if __name__ == u'__main__': + main() diff --git a/scripts/openlp-1to2-converter.py b/scripts/openlp-1to2-converter.py index 8645fc2a4..f0c5a0975 100755 --- a/scripts/openlp-1to2-converter.py +++ b/scripts/openlp-1to2-converter.py @@ -97,7 +97,7 @@ create_statements = [ ] def prepare_string(dirty): - return dirty_chars.sub(u'', dirty.replace(u'\r\n', ' ').replace(u'\n', ' ')) + return dirty_chars.sub(u'', dirty.replace(u'\r\n', u' ').replace(u'\n', u' ')) def display_sql(sql, params): prepared_params = []