Some more fixes for the Windows World:

- Fixed location of .qm files, so that they can be found in a Windows build
- Added PyEnchant to the build process
- Fixed up langaugemanager.py so that it conforms to coding standards

bzr-revno: 1036
This commit is contained in:
Raoul Snyman 2010-09-17 16:30:26 +02:00
commit 9fb2bb1458
4 changed files with 100 additions and 34 deletions

View File

@ -250,7 +250,7 @@ class Ui_MainWindow(object):
self.LanguageGroup = QtGui.QActionGroup(MainWindow) self.LanguageGroup = QtGui.QActionGroup(MainWindow)
qmList = LanguageManager.get_qm_list() qmList = LanguageManager.get_qm_list()
savedLanguage = LanguageManager.get_language() savedLanguage = LanguageManager.get_language()
self.AutoLanguageItem.setChecked(LanguageManager.AutoLanguage) self.AutoLanguageItem.setChecked(LanguageManager.auto_language)
for key in sorted(qmList.keys()): for key in sorted(qmList.keys()):
languageItem = QtGui.QAction(MainWindow) languageItem = QtGui.QAction(MainWindow)
languageItem.setObjectName(key) languageItem.setObjectName(key)
@ -258,7 +258,7 @@ class Ui_MainWindow(object):
if qmList[key] == savedLanguage: if qmList[key] == savedLanguage:
languageItem.setChecked(True) languageItem.setChecked(True)
add_actions(self.LanguageGroup, [languageItem]) add_actions(self.LanguageGroup, [languageItem])
self.LanguageGroup.setDisabled(LanguageManager.AutoLanguage) self.LanguageGroup.setDisabled(LanguageManager.auto_language)
self.ToolsAddToolItem = QtGui.QAction(MainWindow) self.ToolsAddToolItem = QtGui.QAction(MainWindow)
self.ToolsAddToolItem.setIcon(build_icon(u':/tools/tools_add.png')) self.ToolsAddToolItem.setIcon(build_icon(u':/tools/tools_add.png'))
self.ToolsAddToolItem.setObjectName(u'ToolsAddToolItem') self.ToolsAddToolItem.setObjectName(u'ToolsAddToolItem')
@ -640,7 +640,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
def setAutoLanguage(self, value): def setAutoLanguage(self, value):
self.LanguageGroup.setDisabled(value) self.LanguageGroup.setDisabled(value)
LanguageManager.AutoLanguage = value LanguageManager.auto_language = value
LanguageManager.set_language(self.LanguageGroup.checkedAction()) LanguageManager.set_language(self.LanguageGroup.checkedAction())
def versionNotice(self, version): def versionNotice(self, version):

View File

@ -102,6 +102,7 @@ class AppLocation(object):
PluginsDir = 4 PluginsDir = 4
VersionDir = 5 VersionDir = 5
CacheDir = 6 CacheDir = 6
LanguageDir = 7
@staticmethod @staticmethod
def get_directory(dir_type=1): def get_directory(dir_type=1):
@ -173,6 +174,13 @@ class AppLocation(object):
except ImportError: except ImportError:
path = os.path.join(os.getenv(u'HOME'), u'.openlp') path = os.path.join(os.getenv(u'HOME'), u'.openlp')
return path 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 @staticmethod
def get_data_path(): def get_data_path():

View File

@ -35,14 +35,14 @@ from PyQt4 import QtCore, QtGui
from openlp.core.utils import AppLocation from openlp.core.utils import AppLocation
from openlp.core.lib import translate from openlp.core.lib import translate
log = logging.getLogger() log = logging.getLogger(__name__)
class LanguageManager(object): class LanguageManager(object):
""" """
Helper for Language selection Helper for Language selection
""" """
__qmList__ = None __qm_list__ = {}
AutoLanguage = False auto_language = False
@staticmethod @staticmethod
def get_translator(language): def get_translator(language):
@ -52,12 +52,11 @@ class LanguageManager(object):
``language`` ``language``
The language to load into the translator The language to load into the translator
""" """
if LanguageManager.AutoLanguage: if LanguageManager.auto_language:
language = QtCore.QLocale.system().name() language = QtCore.QLocale.system().name()
lang_path = AppLocation.get_directory(AppLocation.AppDir) lang_path = AppLocation.get_directory(AppLocation.LanguageDir)
lang_path = os.path.join(lang_path, u'i18n')
app_translator = QtCore.QTranslator() app_translator = QtCore.QTranslator()
if app_translator.load("openlp_" + language, lang_path): if app_translator.load(language, lang_path):
return app_translator return app_translator
@staticmethod @staticmethod
@ -65,8 +64,8 @@ class LanguageManager(object):
""" """
Find all available language files in this OpenLP install Find all available language files in this OpenLP install
""" """
trans_dir = AppLocation.get_directory(AppLocation.AppDir) trans_dir = QtCore.QDir(AppLocation.get_directory(
trans_dir = QtCore.QDir(os.path.join(trans_dir, u'i18n')) AppLocation.LanguageDir))
file_names = trans_dir.entryList(QtCore.QStringList("*.qm"), file_names = trans_dir.entryList(QtCore.QStringList("*.qm"),
QtCore.QDir.Files, QtCore.QDir.Name) QtCore.QDir.Files, QtCore.QDir.Name)
for name in file_names: for name in file_names:
@ -96,7 +95,7 @@ class LanguageManager(object):
log.info(u'Language file: \'%s\' Loaded from conf file' % language) log.info(u'Language file: \'%s\' Loaded from conf file' % language)
reg_ex = QtCore.QRegExp("^\[(.*)\]") reg_ex = QtCore.QRegExp("^\[(.*)\]")
if reg_ex.exactMatch(language): if reg_ex.exactMatch(language):
LanguageManager.AutoLanguage = True LanguageManager.auto_language = True
language = reg_ex.cap(1) language = reg_ex.cap(1)
return language return language
@ -110,7 +109,7 @@ class LanguageManager(object):
""" """
action_name = u'%s' % action.objectName() action_name = u'%s' % action.objectName()
qm_list = LanguageManager.get_qm_list() qm_list = LanguageManager.get_qm_list()
if LanguageManager.AutoLanguage: if LanguageManager.auto_language:
language = u'[%s]' % qm_list[action_name] language = u'[%s]' % qm_list[action_name]
else: else:
language = u'%s' % qm_list[action_name] language = u'%s' % qm_list[action_name]
@ -127,20 +126,18 @@ class LanguageManager(object):
""" """
Initialise the list of available translations Initialise the list of available translations
""" """
LanguageManager.__qmList__ = {} LanguageManager.__qm_list__ = {}
qm_files = LanguageManager.find_qm_files() qm_files = LanguageManager.find_qm_files()
for i, qmf in enumerate(qm_files): for counter, qmf in enumerate(qm_files):
reg_ex = QtCore.QRegExp("^.*openlp_(.*).qm") name = unicode(qmf).split(u'.')[0]
if reg_ex.exactMatch(qmf): LanguageManager.__qm_list__[u'%#2i %s' % (counter + 1,
lang_name = reg_ex.cap(1) LanguageManager.language_name(qmf))] = name
LanguageManager.__qmList__[u'%#2i %s' % (i+1,
LanguageManager.language_name(qmf))] = lang_name
@staticmethod @staticmethod
def get_qm_list(): def get_qm_list():
""" """
Return the list of available translations Return the list of available translations
""" """
if LanguageManager.__qmList__ is None: if not LanguageManager.__qm_list__:
LanguageManager.init_qm_list() LanguageManager.init_qm_list()
return LanguageManager.__qmList__ return LanguageManager.__qm_list__

View File

@ -31,6 +31,18 @@ Windows Build Script
This script is used to build the Windows binary and the accompanying installer. 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: 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 5
Inno Setup should be installed into "C:\%PROGRAMFILES%\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. add that directory to your PATH environment variable.
PyInstaller PyInstaller
PyInstaller should be a checkout of trunk, and in a directory called, PyInstaller should be a checkout of revision 844 of trunk, and in a
"pyinstaller" on the same level as OpenLP's Bazaar shared repository directory called, "pyinstaller" on the same level as OpenLP's Bazaar shared
directory. 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 To install PyInstaller, first checkout trunk from Subversion. The easiest
way is to install TortoiseSVN and then checkout the following URL to a 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] script_path = os.path.split(os.path.abspath(__file__))[0]
branch_path = os.path.abspath(os.path.join(script_path, u'..')) branch_path = os.path.abspath(os.path.join(script_path, u'..'))
source_path = os.path.join(branch_path, u'openlp') 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') 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')) 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') innosetup_path = os.path.join(os.getenv(u'PROGRAMFILES'), 'Inno Setup 5')
iss_path = os.path.join(branch_path, u'resources', u'innosetup') 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(): def run_pyinstaller():
print u'Running PyInstaller...' print u'Running PyInstaller...'
os.chdir(branch_path) os.chdir(branch_path)
pyinstaller = Popen((u'python', os.path.join(pyinstaller_path, u'Build.py'), pyinstaller = Popen((u'python', os.path.join(pyinstaller_path, u'Build.py'),
u'OpenLP.spec')) u'-y', u'OpenLP.spec'))
code = pyinstaller.wait() code = pyinstaller.wait()
if code != 0: if code != 0:
raise Exception(u'Error running PyInstaller Build.py') raise Exception(u'Error running PyInstaller Build.py')
@ -120,6 +148,19 @@ def write_version_file():
f.write(versionstring) f.write(versionstring)
f.close() 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(): def copy_plugins():
print u'Copying plugins...' print u'Copying plugins...'
source = os.path.join(source_path, u'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'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')) 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(): def run_innosetup():
print u'Running Inno Setup...' print u'Running Inno Setup...'
os.chdir(iss_path) os.chdir(iss_path)
@ -150,17 +206,22 @@ def run_innosetup():
raise Exception(u'Error running Inno Setup') raise Exception(u'Error running Inno Setup')
def main(): def main():
print "Script path:", script_path import sys
print "Branch path:", branch_path if len(sys.argv) > 1 and (sys.argv[1] == u'-v' or sys.argv[1] == u'--verbose'):
print "Source path:", source_path print "Script path:", script_path
print "\"dist\" path:", dist_path print "Branch path:", branch_path
print "PyInstaller path:", pyinstaller_path print "Source path:", source_path
print "Inno Setup path:", innosetup_path print "\"dist\" path:", dist_path
print "ISS file path:", iss_path print "PyInstaller path:", pyinstaller_path
print "Inno Setup path:", innosetup_path
print "ISS file path:", iss_path
#clean_build_directories()
run_pyinstaller() run_pyinstaller()
write_version_file() write_version_file()
copy_enchant()
copy_plugins() copy_plugins()
copy_windows_files() copy_windows_files()
compile_translations()
run_innosetup() run_innosetup()
print "Done." print "Done."