diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index abf035d65..60a6ae2b7 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -250,7 +250,7 @@ class Ui_MainWindow(object): self.LanguageGroup = QtGui.QActionGroup(MainWindow) qmList = LanguageManager.get_qm_list() savedLanguage = LanguageManager.get_language() - self.AutoLanguageItem.setChecked(LanguageManager.AutoLanguage) + self.AutoLanguageItem.setChecked(LanguageManager.auto_language) for key in sorted(qmList.keys()): languageItem = QtGui.QAction(MainWindow) languageItem.setObjectName(key) @@ -258,7 +258,7 @@ class Ui_MainWindow(object): if qmList[key] == savedLanguage: languageItem.setChecked(True) add_actions(self.LanguageGroup, [languageItem]) - self.LanguageGroup.setDisabled(LanguageManager.AutoLanguage) + self.LanguageGroup.setDisabled(LanguageManager.auto_language) self.ToolsAddToolItem = QtGui.QAction(MainWindow) self.ToolsAddToolItem.setIcon(build_icon(u':/tools/tools_add.png')) self.ToolsAddToolItem.setObjectName(u'ToolsAddToolItem') @@ -640,7 +640,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): def setAutoLanguage(self, value): self.LanguageGroup.setDisabled(value) - LanguageManager.AutoLanguage = value + LanguageManager.auto_language = value LanguageManager.set_language(self.LanguageGroup.checkedAction()) def versionNotice(self, version): diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index ea14b2259..119bf6b55 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -102,6 +102,7 @@ class AppLocation(object): PluginsDir = 4 VersionDir = 5 CacheDir = 6 + LanguageDir = 7 @staticmethod def get_directory(dir_type=1): @@ -173,6 +174,13 @@ class AppLocation(object): except ImportError: path = os.path.join(os.getenv(u'HOME'), u'.openlp') return path + if dir_type == AppLocation.LanguageDir: + if hasattr(sys, u'frozen') and sys.frozen == 1: + app_path = os.path.abspath(os.path.split(sys.argv[0])[0]) + else: + app_path = os.path.split(openlp.__file__)[0] + return os.path.join(app_path, u'i18n') + @staticmethod def get_data_path(): diff --git a/openlp/core/utils/languagemanager.py b/openlp/core/utils/languagemanager.py index a264e15a9..36e6330a6 100644 --- a/openlp/core/utils/languagemanager.py +++ b/openlp/core/utils/languagemanager.py @@ -35,14 +35,14 @@ from PyQt4 import QtCore, QtGui from openlp.core.utils import AppLocation from openlp.core.lib import translate -log = logging.getLogger() +log = logging.getLogger(__name__) class LanguageManager(object): """ Helper for Language selection """ - __qmList__ = None - AutoLanguage = False + __qm_list__ = {} + auto_language = False @staticmethod def get_translator(language): @@ -52,12 +52,11 @@ class LanguageManager(object): ``language`` The language to load into the translator """ - if LanguageManager.AutoLanguage: + if LanguageManager.auto_language: language = QtCore.QLocale.system().name() - lang_path = AppLocation.get_directory(AppLocation.AppDir) - lang_path = os.path.join(lang_path, u'i18n') + lang_path = AppLocation.get_directory(AppLocation.LanguageDir) app_translator = QtCore.QTranslator() - if app_translator.load("openlp_" + language, lang_path): + if app_translator.load(language, lang_path): return app_translator @staticmethod @@ -65,8 +64,8 @@ class LanguageManager(object): """ Find all available language files in this OpenLP install """ - trans_dir = AppLocation.get_directory(AppLocation.AppDir) - trans_dir = QtCore.QDir(os.path.join(trans_dir, u'i18n')) + trans_dir = QtCore.QDir(AppLocation.get_directory( + AppLocation.LanguageDir)) file_names = trans_dir.entryList(QtCore.QStringList("*.qm"), QtCore.QDir.Files, QtCore.QDir.Name) for name in file_names: @@ -96,7 +95,7 @@ class LanguageManager(object): log.info(u'Language file: \'%s\' Loaded from conf file' % language) reg_ex = QtCore.QRegExp("^\[(.*)\]") if reg_ex.exactMatch(language): - LanguageManager.AutoLanguage = True + LanguageManager.auto_language = True language = reg_ex.cap(1) return language @@ -110,7 +109,7 @@ class LanguageManager(object): """ action_name = u'%s' % action.objectName() qm_list = LanguageManager.get_qm_list() - if LanguageManager.AutoLanguage: + if LanguageManager.auto_language: language = u'[%s]' % qm_list[action_name] else: language = u'%s' % qm_list[action_name] @@ -127,20 +126,18 @@ class LanguageManager(object): """ Initialise the list of available translations """ - LanguageManager.__qmList__ = {} + LanguageManager.__qm_list__ = {} qm_files = LanguageManager.find_qm_files() - for i, qmf in enumerate(qm_files): - reg_ex = QtCore.QRegExp("^.*openlp_(.*).qm") - if reg_ex.exactMatch(qmf): - lang_name = reg_ex.cap(1) - LanguageManager.__qmList__[u'%#2i %s' % (i+1, - LanguageManager.language_name(qmf))] = lang_name + for counter, qmf in enumerate(qm_files): + name = unicode(qmf).split(u'.')[0] + LanguageManager.__qm_list__[u'%#2i %s' % (counter + 1, + LanguageManager.language_name(qmf))] = name @staticmethod def get_qm_list(): """ Return the list of available translations """ - if LanguageManager.__qmList__ is None: + if not LanguageManager.__qm_list__: LanguageManager.init_qm_list() - return LanguageManager.__qmList__ + return LanguageManager.__qm_list__ diff --git a/scripts/windows-builder.py b/scripts/windows-builder.py index 9ef073729..a100dfd5a 100644 --- a/scripts/windows-builder.py +++ b/scripts/windows-builder.py @@ -31,6 +31,18 @@ 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 a number of things: +Python 2.6 + This build script only works with Python 2.6. + +PyQt4 + You should already have this installed, OpenLP doesn't work without it. The + version the script expects is the packaged one available from River Bank + Computing. + +PyEnchant + This script expects the precompiled, installable version of PyEnchant to be + installed. You can find this on the PyEnchant site. + Inno Setup 5 Inno Setup should be installed into "C:\%PROGRAMFILES%\Inno Setup 5" @@ -41,9 +53,10 @@ UPX add that directory to your PATH environment variable. PyInstaller - PyInstaller should be a checkout of trunk, and in a directory called, - "pyinstaller" on the same level as OpenLP's Bazaar shared repository - directory. + PyInstaller should be a checkout of revision 844 of trunk, and in a + directory called, "pyinstaller" on the same level as OpenLP's Bazaar shared + repository directory. The revision is very important as there is currently + a major regression in HEAD. To install PyInstaller, first checkout trunk from Subversion. The easiest way is to install TortoiseSVN and then checkout the following URL to a @@ -80,17 +93,32 @@ from subprocess import Popen, PIPE script_path = os.path.split(os.path.abspath(__file__))[0] branch_path = os.path.abspath(os.path.join(script_path, u'..')) source_path = os.path.join(branch_path, u'openlp') +i18n_path = os.path.join(branch_path, u'resources', u'i18n') +build_path = os.path.join(branch_path, u'build', u'pyi.win32', u'OpenLP') dist_path = os.path.join(branch_path, u'dist', u'OpenLP') pyinstaller_path = os.path.abspath(os.path.join(branch_path, u'..', u'..', u'pyinstaller')) innosetup_path = os.path.join(os.getenv(u'PROGRAMFILES'), 'Inno Setup 5') iss_path = os.path.join(branch_path, u'resources', u'innosetup') +lrelease_path = u'C:\\Python26\\Lib\\site-packages\\PyQt4\\bin\\lrelease.exe' +enchant_path = u'C:\\Python26\\Lib\\site-packages\\enchant' +def clean_build_directories(): + #if not os.path.exists(build_path) + for root, dirs, files in os.walk(build_path, topdown=False): + print root + for file in files: + os.remove(os.path.join(root, file)) + #os.removedirs(build_path) + for root, dirs, files in os.walk(dist_path, topdown=False): + for file in files: + os.remove(os.path.join(root, file)) + #os.removedirs(dist_path) 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')) + u'-y', u'OpenLP.spec')) code = pyinstaller.wait() if code != 0: raise Exception(u'Error running PyInstaller Build.py') @@ -120,6 +148,19 @@ def write_version_file(): f.write(versionstring) f.close() +def copy_enchant(): + print u'Copying enchant/pyenchant...' + source = enchant_path + dest = os.path.join(dist_path, u'enchant') + for root, dirs, files in os.walk(source): + for filename in files: + if not filename.endswith(u'.pyc') and not filename.endswith(u'.pyo'): + 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_plugins(): print u'Copying plugins...' source = os.path.join(source_path, u'plugins') @@ -138,6 +179,21 @@ def copy_windows_files(): 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 compile_translations(): + files = os.listdir(i18n_path) + if not os.path.exists(os.path.join(dist_path, u'i18n')): + os.makedirs(os.path.join(dist_path, u'i18n')) + for file in files: + if file.endswith(u'.ts'): + source_path = os.path.join(i18n_path, file) + dest_path = os.path.join(dist_path, u'i18n', + file.replace(u'.ts', u'.qm')) + lconvert = Popen(u'"%s" "%s" -qm "%s"' % (lrelease_path, \ + source_path, dest_path)) + code = lconvert.wait() + if code != 0: + print 'Error running lconvert on %s' % source_path + def run_innosetup(): print u'Running Inno Setup...' os.chdir(iss_path) @@ -150,17 +206,22 @@ def run_innosetup(): raise Exception(u'Error running Inno Setup') def main(): - print "Script path:", script_path - print "Branch path:", branch_path - print "Source path:", source_path - print "\"dist\" path:", dist_path - print "PyInstaller path:", pyinstaller_path - print "Inno Setup path:", innosetup_path - print "ISS file path:", iss_path + import sys + if len(sys.argv) > 1 and (sys.argv[1] == u'-v' or sys.argv[1] == u'--verbose'): + print "Script path:", script_path + print "Branch path:", branch_path + print "Source path:", source_path + print "\"dist\" path:", dist_path + print "PyInstaller path:", pyinstaller_path + print "Inno Setup path:", innosetup_path + print "ISS file path:", iss_path + #clean_build_directories() run_pyinstaller() write_version_file() + copy_enchant() copy_plugins() copy_windows_files() + compile_translations() run_innosetup() print "Done."