This commit is contained in:
Andreas Preikschat 2011-03-26 21:32:10 +01:00
commit baff5451c2
23 changed files with 339 additions and 233 deletions

View File

@ -180,3 +180,42 @@ on :guilabel:`Save to X Configuration File`.
Click :guilabel:`Save` and you should be set. You may want to restart X or 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 your machine just to make sure all the settings carry over the next time you log
in. 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 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
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 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.

View File

@ -27,9 +27,13 @@
import os import os
import sys import sys
import logging 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 optparse import OptionParser
from traceback import format_exception from traceback import format_exception
from subprocess import Popen, PIPE
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
@ -40,7 +44,8 @@ from openlp.core.ui.firsttimelanguageform import FirstTimeLanguageForm
from openlp.core.ui.firsttimeform import FirstTimeForm from openlp.core.ui.firsttimeform import FirstTimeForm
from openlp.core.ui.exceptionform import ExceptionForm from openlp.core.ui.exceptionform import ExceptionForm
from openlp.core.ui import SplashScreen, ScreenList 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() log = logging.getLogger()
@ -71,87 +76,6 @@ class OpenLP(QtGui.QApplication):
The core application class. This class inherits from Qt's QApplication The core application class. This class inherits from Qt's QApplication
class in order to provide the core of the application. class in order to provide the core of the application.
""" """
app_version = None
def get_version(self):
"""
Load and store current Application Version
"""
if self.app_version:
return self.app_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'-')
self.app_version = {
u'full': full_version,
u'version': bits[0],
u'build': bits[1] if len(bits) > 1 else None
}
if self.app_version[u'build']:
log.info(
u'Openlp version %s build %s',
self.app_version[u'version'],
self.app_version[u'build']
)
else:
log.info(u'Openlp version %s' % self.app_version[u'version'])
return self.app_version
def run(self): def run(self):
""" """
@ -183,8 +107,7 @@ class OpenLP(QtGui.QApplication):
# make sure Qt really display the splash screen # make sure Qt really display the splash screen
self.processEvents() self.processEvents()
# start the main app window # start the main app window
self.mainWindow = MainWindow(screens, self.app_version, self.mainWindow = MainWindow(screens, self.clipboard())
self.clipboard())
self.mainWindow.show() self.mainWindow.show()
if show_splash: if show_splash:
# now kill the splashscreen # now kill the splashscreen
@ -196,7 +119,7 @@ class OpenLP(QtGui.QApplication):
update_check = QtCore.QSettings().value( update_check = QtCore.QSettings().value(
u'general/update check', QtCore.QVariant(True)).toBool() u'general/update check', QtCore.QVariant(True)).toBool()
if update_check: if update_check:
VersionThread(self.mainWindow, self.app_version).start() VersionThread(self.mainWindow).start()
return self.exec_() return self.exec_()
def hookException(self, exctype, value, traceback): def hookException(self, exctype, value, traceback):
@ -274,7 +197,7 @@ def main():
app.setOrganizationName(u'OpenLP') app.setOrganizationName(u'OpenLP')
app.setOrganizationDomain(u'openlp.org') app.setOrganizationDomain(u'openlp.org')
app.setApplicationName(u'OpenLP') app.setApplicationName(u'OpenLP')
app.setApplicationVersion(app.get_version()[u'version']) app.setApplicationVersion(get_application_version()[u'version'])
# First time checks in settings # First time checks in settings
if not QtCore.QSettings().value(u'general/has run wizard', if not QtCore.QSettings().value(u'general/has run wizard',
QtCore.QVariant(False)).toBool(): QtCore.QVariant(False)).toBool():

View File

@ -1 +1 @@
1.9.2-bzr987 1.9.5-bzr1421

View File

@ -316,8 +316,11 @@ def check_directory_exists(dir):
Theme directory to make sure exists Theme directory to make sure exists
""" """
log.debug(u'check_directory_exists %s' % dir) log.debug(u'check_directory_exists %s' % dir)
if not os.path.exists(dir): try:
os.makedirs(dir) if not os.path.exists(dir):
os.makedirs(dir)
except IOError:
pass
from listwidgetwithdnd import ListWidgetWithDnD from listwidgetwithdnd import ListWidgetWithDnD
from displaytags import DisplayTags from displaytags import DisplayTags

View File

@ -32,6 +32,7 @@ from PyQt4 import QtCore
from openlp.core.lib import Receiver from openlp.core.lib import Receiver
from openlp.core.lib.ui import UiStrings from openlp.core.lib.ui import UiStrings
from openlp.core.utils import get_application_version
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -145,7 +146,10 @@ class Plugin(QtCore.QObject):
self.textStrings = {} self.textStrings = {}
self.setPluginTextStrings() self.setPluginTextStrings()
self.nameStrings = self.textStrings[StringContent.Name] self.nameStrings = self.textStrings[StringContent.Name]
self.version = version if version else u'1.9.5' if version:
self.version = version
else:
self.version = get_application_version()[u'version']
self.settingsSection = self.name.lower() self.settingsSection = self.name.lower()
self.icon = None self.icon = None
self.mediaItemClass = mediaItemClass self.mediaItemClass = mediaItemClass

View File

@ -49,6 +49,7 @@ class UiStrings(object):
Cancel = translate('OpenLP.Ui', 'Cancel') Cancel = translate('OpenLP.Ui', 'Cancel')
CCLINumberLabel = translate('OpenLP.Ui', 'CCLI number:') CCLINumberLabel = translate('OpenLP.Ui', 'CCLI number:')
CreateService = translate('OpenLP.Ui', 'Create a new service.') CreateService = translate('OpenLP.Ui', 'Create a new service.')
Default = unicode(translate('OpenLP.Ui', 'Default'))
Delete = translate('OpenLP.Ui', '&Delete') Delete = translate('OpenLP.Ui', '&Delete')
Edit = translate('OpenLP.Ui', '&Edit') Edit = translate('OpenLP.Ui', '&Edit')
EmptyField = translate('OpenLP.Ui', 'Empty Field') EmptyField = translate('OpenLP.Ui', 'Empty Field')

View File

@ -28,25 +28,26 @@ from PyQt4 import QtCore, QtGui
from aboutdialog import Ui_AboutDialog from aboutdialog import Ui_AboutDialog
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.core.utils import get_application_version
class AboutForm(QtGui.QDialog, Ui_AboutDialog): class AboutForm(QtGui.QDialog, Ui_AboutDialog):
""" """
The About dialog The About dialog
""" """
def __init__(self, parent, applicationVersion): def __init__(self, parent):
""" """
Do some initialisation stuff Do some initialisation stuff
""" """
QtGui.QDialog.__init__(self, parent) QtGui.QDialog.__init__(self, parent)
self.applicationVersion = applicationVersion applicationVersion = get_application_version()
self.setupUi(self) self.setupUi(self)
about_text = self.aboutTextEdit.toPlainText() about_text = self.aboutTextEdit.toPlainText()
about_text = about_text.replace(u'<version>', about_text = about_text.replace(u'<version>',
self.applicationVersion[u'version']) applicationVersion[u'version'])
if self.applicationVersion[u'build']: if applicationVersion[u'build']:
build_text = unicode(translate('OpenLP.AboutForm', ' build %s')) % \ build_text = unicode(translate('OpenLP.AboutForm', ' build %s')) % \
self.applicationVersion[u'build'] applicationVersion[u'build']
else: else:
build_text = u'' build_text = u''
about_text = about_text.replace(u'<revision>', build_text) about_text = about_text.replace(u'<revision>', build_text)

View File

@ -26,6 +26,8 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
import sys
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.core.lib.ui import add_welcome_page from openlp.core.lib.ui import add_welcome_page
@ -77,7 +79,10 @@ class Ui_FirstTimeWizard(object):
self.imageCheckBox.setObjectName(u'imageCheckBox') self.imageCheckBox.setObjectName(u'imageCheckBox')
self.pluginLayout.addWidget(self.imageCheckBox) self.pluginLayout.addWidget(self.imageCheckBox)
self.presentationCheckBox = QtGui.QCheckBox(self.pluginPage) 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.presentationCheckBox.setObjectName(u'presentationCheckBox')
self.pluginLayout.addWidget(self.presentationCheckBox) self.pluginLayout.addWidget(self.presentationCheckBox)
self.mediaCheckBox = QtGui.QCheckBox(self.pluginPage) self.mediaCheckBox = QtGui.QCheckBox(self.pluginPage)
@ -210,6 +215,8 @@ class Ui_FirstTimeWizard(object):
'Images')) 'Images'))
self.presentationCheckBox.setText(translate('OpenLP.FirstTimeWizard', self.presentationCheckBox.setText(translate('OpenLP.FirstTimeWizard',
'Presentations')) 'Presentations'))
if sys.platform == "darwin":
self.presentationCheckBox.setEnabled(False)
self.mediaCheckBox.setText(translate('OpenLP.FirstTimeWizard', self.mediaCheckBox.setText(translate('OpenLP.FirstTimeWizard',
'Media (Audio and Video)')) 'Media (Audio and Video)'))
self.remoteCheckBox.setText(translate('OpenLP.FirstTimeWizard', self.remoteCheckBox.setText(translate('OpenLP.FirstTimeWizard',

View File

@ -38,7 +38,7 @@ from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \
ThemeManager, SlideController, PluginForm, MediaDockManager, \ ThemeManager, SlideController, PluginForm, MediaDockManager, \
ShortcutListForm, DisplayTagForm ShortcutListForm, DisplayTagForm
from openlp.core.utils import AppLocation, add_actions, LanguageManager, \ from openlp.core.utils import AppLocation, add_actions, LanguageManager, \
ActionList ActionList, get_application_version
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -469,14 +469,13 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
actionList = ActionList() actionList = ActionList()
def __init__(self, screens, applicationVersion, clipboard): def __init__(self, screens, clipboard):
""" """
This constructor sets up the interface, the various managers, and the This constructor sets up the interface, the various managers, and the
plugins. plugins.
""" """
QtGui.QMainWindow.__init__(self) QtGui.QMainWindow.__init__(self)
self.screens = screens self.screens = screens
self.applicationVersion = applicationVersion
self.clipboard = clipboard self.clipboard = clipboard
# Set up settings sections for the main application # Set up settings sections for the main application
# (not for use by plugins) # (not for use by plugins)
@ -487,7 +486,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.serviceNotSaved = False self.serviceNotSaved = False
self.actionList = ActionList() self.actionList = ActionList()
self.settingsmanager = SettingsManager(screens) self.settingsmanager = SettingsManager(screens)
self.aboutForm = AboutForm(self, applicationVersion) self.aboutForm = AboutForm(self)
self.settingsForm = SettingsForm(self.screens, self, self) self.settingsForm = SettingsForm(self.screens, self, self)
self.displayTagForm = DisplayTagForm(self) self.displayTagForm = DisplayTagForm(self)
self.shortcutForm = ShortcutListForm(self) self.shortcutForm = ShortcutListForm(self)
@ -622,9 +621,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
# Call the initialise method to setup plugins. # Call the initialise method to setup plugins.
log.info(u'initialise plugins') log.info(u'initialise plugins')
self.pluginManager.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') log.info(u'Load data from Settings')
if QtCore.QSettings().value(u'advanced/save current plugin', if QtCore.QSettings().value(u'advanced/save current plugin',
QtCore.QVariant(False)).toBool(): QtCore.QVariant(False)).toBool():
@ -633,6 +629,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
if savedPlugin != -1: if savedPlugin != -1:
self.MediaToolBox.setCurrentIndex(savedPlugin) self.MediaToolBox.setCurrentIndex(savedPlugin)
self.settingsForm.postSetUp() 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') Receiver.send_message(u'cursor_normal')
def setAutoLanguage(self, value): def setAutoLanguage(self, value):
@ -651,7 +650,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
'version from http://openlp.org/.')) 'version from http://openlp.org/.'))
QtGui.QMessageBox.question(self, QtGui.QMessageBox.question(self,
translate('OpenLP.MainWindow', 'OpenLP Version Updated'), translate('OpenLP.MainWindow', 'OpenLP Version Updated'),
version_text % (version, self.applicationVersion[u'full'])) version_text % (version, get_application_version()[u'full']))
def show(self): def show(self):
""" """
@ -679,7 +678,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
def firstTime(self): def firstTime(self):
# Import themes if first time # Import themes if first time
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
self.themeManagerContents.firstTime()
for plugin in self.pluginManager.plugins: for plugin in self.pluginManager.plugins:
if hasattr(plugin, u'firstTime'): if hasattr(plugin, u'firstTime'):
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
@ -734,7 +732,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
""" """
Show the About form Show the About form
""" """
self.aboutForm.applicationVersion = self.applicationVersion
self.aboutForm.exec_() self.aboutForm.exec_()
def onPluginItemClicked(self): def onPluginItemClicked(self):

View File

@ -64,8 +64,7 @@ class Ui_PrintServiceDialog(object):
'Options')) 'Options'))
self.optionsButton.setToolButtonStyle( self.optionsButton.setToolButtonStyle(
QtCore.Qt.ToolButtonTextBesideIcon) QtCore.Qt.ToolButtonTextBesideIcon)
self.optionsButton.setIcon(QtGui.QIcon( self.optionsButton.setIcon(build_icon(u':/system/system_configure.png'))
build_icon(u':/system/system_configure.png')))
self.optionsButton.setCheckable(True) self.optionsButton.setCheckable(True)
self.toolbar.addWidget(self.optionsButton) self.toolbar.addWidget(self.optionsButton)
self.closeButton = self.toolbar.addAction( self.closeButton = self.toolbar.addAction(
@ -80,24 +79,23 @@ class Ui_PrintServiceDialog(object):
translate('OpenLP.PrintServiceForm', 'Copy as HTML')) translate('OpenLP.PrintServiceForm', 'Copy as HTML'))
self.toolbar.addSeparator() self.toolbar.addSeparator()
self.zoomInButton = QtGui.QToolButton(self.toolbar) self.zoomInButton = QtGui.QToolButton(self.toolbar)
self.zoomInButton.setIcon(QtGui.QIcon( self.zoomInButton.setIcon(build_icon(u':/general/general_zoom_in.png'))
build_icon(u':/general/general_zoom_in.png')))
self.zoomInButton.setToolTip(translate('OpenLP.PrintServiceForm', self.zoomInButton.setToolTip(translate('OpenLP.PrintServiceForm',
'Zoom In')) 'Zoom In'))
self.zoomInButton.setObjectName(u'zoomInButton') self.zoomInButton.setObjectName(u'zoomInButton')
self.zoomInButton.setIconSize(QtCore.QSize(22, 22)) self.zoomInButton.setIconSize(QtCore.QSize(22, 22))
self.toolbar.addWidget(self.zoomInButton) self.toolbar.addWidget(self.zoomInButton)
self.zoomOutButton = QtGui.QToolButton(self.toolbar) self.zoomOutButton = QtGui.QToolButton(self.toolbar)
self.zoomOutButton.setIcon(QtGui.QIcon( self.zoomOutButton.setIcon(
build_icon(u':/general/general_zoom_out.png'))) build_icon(u':/general/general_zoom_out.png'))
self.zoomOutButton.setToolTip(translate('OpenLP.PrintServiceForm', self.zoomOutButton.setToolTip(translate('OpenLP.PrintServiceForm',
'Zoom Out')) 'Zoom Out'))
self.zoomOutButton.setObjectName(u'zoomOutButton') self.zoomOutButton.setObjectName(u'zoomOutButton')
self.zoomOutButton.setIconSize(QtCore.QSize(22, 22)) self.zoomOutButton.setIconSize(QtCore.QSize(22, 22))
self.toolbar.addWidget(self.zoomOutButton) self.toolbar.addWidget(self.zoomOutButton)
self.zoomOriginalButton = QtGui.QToolButton(self.toolbar) self.zoomOriginalButton = QtGui.QToolButton(self.toolbar)
self.zoomOriginalButton.setIcon(QtGui.QIcon( self.zoomOriginalButton.setIcon(
build_icon(u':/general/general_zoom_original.png'))) build_icon(u':/general/general_zoom_original.png'))
self.zoomOriginalButton.setToolTip(translate('OpenLP.PrintServiceForm', self.zoomOriginalButton.setToolTip(translate('OpenLP.PrintServiceForm',
'Zoom Original')) 'Zoom Original'))
self.zoomOriginalButton.setObjectName(u'zoomOriginalButton') self.zoomOriginalButton.setObjectName(u'zoomOriginalButton')

View File

@ -481,28 +481,30 @@ class ServiceManager(QtGui.QWidget):
# Usual Zip file cannot exceed 2GiB, file with Zip64 cannot be # Usual Zip file cannot exceed 2GiB, file with Zip64 cannot be
# extracted using unzip in UNIX. # extracted using unzip in UNIX.
allow_zip_64 = (total_size > 2147483648 + len(service_content)) allow_zip_64 = (total_size > 2147483648 + len(service_content))
log.debug(u'ServiceManager.saveFile - allowZip64 is %s' % log.debug(u'ServiceManager.saveFile - allowZip64 is %s' % allow_zip_64)
allow_zip_64)
zip = None zip = None
success = True
try: try:
zip = zipfile.ZipFile(path_file_name, 'w', zipfile.ZIP_STORED, zip = zipfile.ZipFile(path_file_name, 'w', zipfile.ZIP_STORED,
allow_zip_64) allow_zip_64)
# First we add service contents. # First we add service contents.
# We save ALL filenames into ZIP using UTF-8. # We save ALL filenames into ZIP using UTF-8.
zip.writestr(service_file_name.encode(u'utf-8'), zip.writestr(service_file_name.encode(u'utf-8'), service_content)
service_content)
# Finally add all the listed media files. # Finally add all the listed media files.
for path_from in write_list: for path_from in write_list:
zip.write(path_from, path_from.encode(u'utf-8')) zip.write(path_from, path_from.encode(u'utf-8'))
except IOError: except IOError:
log.exception(u'Failed to save service to disk') log.exception(u'Failed to save service to disk')
return False success = False
finally: finally:
if zip: if zip:
zip.close() zip.close()
self.mainwindow.addRecentFile(path_file_name) if success:
self.setModified(False) self.mainwindow.addRecentFile(path_file_name)
return True self.setModified(False)
else:
delete_file(path_file_name)
return success
def saveFileAs(self): def saveFileAs(self):
""" """
@ -527,8 +529,9 @@ class ServiceManager(QtGui.QWidget):
def loadFile(self, fileName): def loadFile(self, fileName):
if not fileName: if not fileName:
return False return False
else: fileName = unicode(fileName)
fileName = unicode(fileName) if not os.path.exists(fileName):
return False
zip = None zip = None
fileTo = None fileTo = None
try: try:
@ -566,24 +569,27 @@ class ServiceManager(QtGui.QWidget):
Receiver.send_message(u'%s_service_load' % Receiver.send_message(u'%s_service_load' %
serviceItem.name.lower(), serviceItem) serviceItem.name.lower(), serviceItem)
delete_file(p_file) 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') Receiver.send_message(u'cursor_normal')
else: else:
critical_error_message_box( critical_error_message_box(
message=translate('OpenLP.ServiceManager', message=translate('OpenLP.ServiceManager',
'File is not a valid service.')) 'File is not a valid service.'))
log.exception(u'File contains no service data') 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) log.exception(u'Problem loading service file %s' % fileName)
finally: finally:
if fileTo: if fileTo:
fileTo.close() fileTo.close()
if zip: if zip:
zip.close() 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): def loadLastFile(self):
""" """

View File

@ -46,6 +46,7 @@ class SlideList(QtGui.QTableWidget):
QtGui.QTableWidget.__init__(self, parent.controller) QtGui.QTableWidget.__init__(self, parent.controller)
self.parent = parent self.parent = parent
class SlideController(QtGui.QWidget): class SlideController(QtGui.QWidget):
""" """
SlideController is the slide controller widget. This widget is what the SlideController is the slide controller widget. This widget is what the

View File

@ -156,10 +156,9 @@ class ThemeManager(QtGui.QWidget):
file = os.path.join(self.path, file).encode(encoding) file = os.path.join(self.path, file).encode(encoding)
self.unzipTheme(file, self.path) self.unzipTheme(file, self.path)
delete_file(file) delete_file(file)
self.loadThemes()
Receiver.send_message(u'cursor_normal') Receiver.send_message(u'cursor_normal')
def configUpdated(self, firstTime=False): def configUpdated(self):
""" """
Triggered when Config dialog is updated. Triggered when Config dialog is updated.
""" """
@ -433,7 +432,7 @@ class ThemeManager(QtGui.QWidget):
self.loadThemes() self.loadThemes()
Receiver.send_message(u'cursor_normal') 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 Loads the theme lists and triggers updates accross the whole system
using direct calls or core functions and events for the plugins. using direct calls or core functions and events for the plugins.
@ -443,31 +442,44 @@ class ThemeManager(QtGui.QWidget):
self.themelist = [] self.themelist = []
self.themeListWidget.clear() self.themeListWidget.clear()
dirList = os.listdir(self.path) dirList = os.listdir(self.path)
dirList.sort() files = SettingsManager.get_files(self.settingsSection, u'.png')
for name in dirList: if firstTime:
if name.endswith(u'.png'): self.firstTime()
# check to see file is in theme root directory # No themes have been found so create one
theme = os.path.join(self.path, name) if len(files) == 0:
if os.path.exists(theme): theme = ThemeXML()
textName = os.path.splitext(name)[0] theme.theme_name = UiStrings.Default
if textName == self.global_theme: self._writeTheme(theme, None, None)
name = unicode(translate('OpenLP.ThemeManager', QtCore.QSettings().setValue(
'%s (default)')) % textName self.settingsSection + u'/global theme',
else: QtCore.QVariant(theme.theme_name))
name = textName self.configUpdated()
thumb = os.path.join(self.thumbPath, u'%s.png' % textName) files = SettingsManager.get_files(self.settingsSection, u'.png')
item_name = QtGui.QListWidgetItem(name) files.sort()
if os.path.exists(thumb): # now process the file list of png files
icon = build_icon(thumb) for name in files:
else: # check to see file is in theme root directory
icon = build_icon(theme) theme = os.path.join(self.path, name)
pixmap = icon.pixmap(QtCore.QSize(88, 50)) if os.path.exists(theme):
pixmap.save(thumb, u'png') textName = os.path.splitext(name)[0]
item_name.setIcon(icon) if textName == self.global_theme:
item_name.setData(QtCore.Qt.UserRole, name = unicode(translate('OpenLP.ThemeManager',
QtCore.QVariant(textName)) '%s (default)')) % textName
self.themeListWidget.addItem(item_name) else:
self.themelist.append(textName) 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() self._pushThemes()
def _pushThemes(self): def _pushThemes(self):

View File

@ -33,6 +33,7 @@ import sys
import time import time
import urllib2 import urllib2
from datetime import datetime from datetime import datetime
from subprocess import Popen, PIPE
from PyQt4 import QtGui, QtCore from PyQt4 import QtGui, QtCore
@ -44,9 +45,10 @@ if sys.platform != u'win32' and sys.platform != u'darwin':
XDG_BASE_AVAILABLE = False XDG_BASE_AVAILABLE = False
import openlp import openlp
from openlp.core.lib import Receiver, translate from openlp.core.lib import Receiver, translate, check_directory_exists
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
APPLICATION_VERSION = {}
IMAGES_FILTER = None IMAGES_FILTER = None
UNO_CONNECTION_TYPE = u'pipe' UNO_CONNECTION_TYPE = u'pipe'
#UNO_CONNECTION_TYPE = u'socket' #UNO_CONNECTION_TYPE = u'socket'
@ -56,9 +58,8 @@ class VersionThread(QtCore.QThread):
A special Qt thread class to fetch the version of OpenLP from the website. 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. 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) QtCore.QThread.__init__(self, parent)
self.app_version = app_version
self.version_splitter = re.compile( self.version_splitter = re.compile(
r'([0-9]+).([0-9]+).([0-9]+)(?:-bzr([0-9]+))?') r'([0-9]+).([0-9]+).([0-9]+)(?:-bzr([0-9]+))?')
@ -68,7 +69,8 @@ class VersionThread(QtCore.QThread):
""" """
time.sleep(1) time.sleep(1)
Receiver.send_message(u'maindisplay_blank_check') 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 = {} remote_version = {}
local_version = {} local_version = {}
match = self.version_splitter.match(version) match = self.version_splitter.match(version)
@ -80,7 +82,7 @@ class VersionThread(QtCore.QThread):
remote_version[u'revision'] = int(match.group(4)) remote_version[u'revision'] = int(match.group(4))
else: else:
return return
match = self.version_splitter.match(self.app_version[u'full']) match = self.version_splitter.match(app_version[u'full'])
if match: if match:
local_version[u'major'] = int(match.group(1)) local_version[u'major'] = int(match.group(1))
local_version[u'minor'] = int(match.group(2)) local_version[u'minor'] = int(match.group(2))
@ -146,8 +148,7 @@ class AppLocation(object):
Return the path OpenLP stores all its data under. Return the path OpenLP stores all its data under.
""" """
path = AppLocation.get_directory(AppLocation.DataDir) path = AppLocation.get_directory(AppLocation.DataDir)
if not os.path.exists(path): check_directory_exists(path)
os.makedirs(path)
return path return path
@staticmethod @staticmethod
@ -157,8 +158,7 @@ class AppLocation(object):
""" """
data_path = AppLocation.get_data_path() data_path = AppLocation.get_data_path()
path = os.path.join(data_path, section) path = os.path.join(data_path, section)
if not os.path.exists(path): check_directory_exists(path)
os.makedirs(path)
return path return path
def _get_os_dir_path(dir_type): def _get_os_dir_path(dir_type):
@ -208,6 +208,85 @@ def _get_frozen_path(frozen_option, non_frozen_option):
return frozen_option return frozen_option
return non_frozen_option return non_frozen_option
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'}
"""
global APPLICATION_VERSION
if APPLICATION_VERSION:
return 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 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): def check_latest_version(current_version):
""" """
Check the latest version of OpenLP against the version file on the OpenLP Check the latest version of OpenLP against the version file on the OpenLP

View File

@ -551,64 +551,52 @@ class BibleMediaItem(MediaManagerItem):
further action is saved for/in each row. further action is saved for/in each row.
""" """
verse_separator = get_reference_match(u'sep_v_display') verse_separator = get_reference_match(u'sep_v_display')
version = self.parent.manager.get_meta_data(bible, u'Version') version = self.parent.manager.get_meta_data(bible, u'Version').value
copyright = self.parent.manager.get_meta_data(bible, u'Copyright') copyright = self.parent.manager.get_meta_data(bible, u'Copyright').value
permissions = self.parent.manager.get_meta_data(bible, u'Permissions') permissions = \
self.parent.manager.get_meta_data(bible, u'Permissions').value
second_version = u''
second_copyright = u''
second_permissions = u''
if second_bible: if second_bible:
second_version = self.parent.manager.get_meta_data(second_bible, second_version = self.parent.manager.get_meta_data(
u'Version') second_bible, u'Version').value
second_copyright = self.parent.manager.get_meta_data(second_bible, second_copyright = self.parent.manager.get_meta_data(
u'Copyright') second_bible, u'Copyright').value
second_permissions = self.parent.manager.get_meta_data(second_bible, second_permissions = self.parent.manager.get_meta_data(
u'Permissions') second_bible, u'Permissions').value
if not second_permissions:
second_permissions = u''
for count, verse in enumerate(self.search_results): for count, verse in enumerate(self.search_results):
data = {
'book': QtCore.QVariant(verse.book.name),
'chapter': QtCore.QVariant(verse.chapter),
'verse': QtCore.QVariant(verse.verse),
'bible': QtCore.QVariant(bible),
'version': QtCore.QVariant(version),
'copyright': QtCore.QVariant(copyright),
'permissions': QtCore.QVariant(permissions),
'text': QtCore.QVariant(verse.text),
'second_bible': QtCore.QVariant(second_bible),
'second_version': QtCore.QVariant(second_version),
'second_copyright': QtCore.QVariant(second_copyright),
'second_permissions': QtCore.QVariant(second_permissions),
'second_text': QtCore.QVariant(u'')
}
if second_bible: if second_bible:
try: try:
vdict = { data[u'second_text'] = QtCore.QVariant(
'book': QtCore.QVariant(verse.book.name), self.second_search_results[count].text)
'chapter': QtCore.QVariant(verse.chapter),
'verse': QtCore.QVariant(verse.verse),
'bible': QtCore.QVariant(bible),
'version': QtCore.QVariant(version.value),
'copyright': QtCore.QVariant(copyright.value),
'permissions': QtCore.QVariant(permissions.value),
'text': QtCore.QVariant(verse.text),
'second_bible': QtCore.QVariant(second_bible),
'second_version': QtCore.QVariant(second_version.value),
'second_copyright': QtCore.QVariant(
second_copyright.value),
'second_permissions': QtCore.QVariant(
second_permissions.value),
'second_text': QtCore.QVariant(
self.second_search_results[count].text)
}
except IndexError: except IndexError:
log.exception(u'The second_search_results does not have as '
'many verses as the search_results.')
break break
bible_text = u' %s %d%s%d (%s, %s)' % (verse.book.name, bible_text = u' %s %d%s%d (%s, %s)' % (verse.book.name,
verse.chapter, verse_separator, verse.verse, version.value, verse.chapter, verse_separator, verse.verse, version,
second_version.value) second_version)
else: else:
vdict = {
'book': QtCore.QVariant(verse.book.name),
'chapter': QtCore.QVariant(verse.chapter),
'verse': QtCore.QVariant(verse.verse),
'bible': QtCore.QVariant(bible),
'version': QtCore.QVariant(version.value),
'copyright': QtCore.QVariant(copyright.value),
'permissions': QtCore.QVariant(permissions.value),
'text': QtCore.QVariant(verse.text),
'second_bible': QtCore.QVariant(u''),
'second_version': QtCore.QVariant(u''),
'second_copyright': QtCore.QVariant(u''),
'second_permissions': QtCore.QVariant(u''),
'second_text': QtCore.QVariant(u'')
}
bible_text = u'%s %d%s%d (%s)' % (verse.book.name, bible_text = u'%s %d%s%d (%s)' % (verse.book.name,
verse.chapter, verse_separator, verse.verse, version.value) verse.chapter, verse_separator, verse.verse, version)
bible_verse = QtGui.QListWidgetItem(bible_text) bible_verse = QtGui.QListWidgetItem(bible_text)
bible_verse.setData(QtCore.Qt.UserRole, QtCore.QVariant(vdict)) bible_verse.setData(QtCore.Qt.UserRole, QtCore.QVariant(data))
self.listView.addItem(bible_verse) self.listView.addItem(bible_verse)
self.listView.selectAll() self.listView.selectAll()
self.search_results = {} self.search_results = {}
@ -810,11 +798,9 @@ class BibleMediaItem(MediaManagerItem):
else: else:
verse_text = unicode(verse) verse_text = unicode(verse)
if self.settings.display_style == DisplayStyle.Round: if self.settings.display_style == DisplayStyle.Round:
verse_text = u'{su}(' + verse_text + u'){/su}' return u'{su}(%s){/su}' % verse_text
elif self.settings.display_style == DisplayStyle.Curly: if self.settings.display_style == DisplayStyle.Curly:
verse_text = u'{su}{' + verse_text + u'}{/su}' return u'{su}{%s}{/su}' % verse_text
elif self.settings.display_style == DisplayStyle.Square: if self.settings.display_style == DisplayStyle.Square:
verse_text = u'{su}[' + verse_text + u']{/su}' return u'{su}[%s]{/su}' % verse_text
else: return u'{su}%s{/su}' % verse_text
verse_text = u'{su}' + verse_text + u'{/su}'
return verse_text

View File

@ -189,7 +189,7 @@ class PresentationMediaItem(MediaManagerItem):
icon = build_icon(u':/general/general_delete.png') icon = build_icon(u':/general/general_delete.png')
else: else:
critical_error_message_box( critical_error_message_box(
self, translate('PresentationPlugin.MediaItem', translate('PresentationPlugin.MediaItem',
'Unsupported File'), 'Unsupported File'),
translate('PresentationPlugin.MediaItem', translate('PresentationPlugin.MediaItem',
'This type of presentation is not supported.')) 'This type of presentation is not supported.'))

View File

@ -93,7 +93,6 @@ window.OpenLP = {
}, },
setSlide: function (event) { setSlide: function (event) {
var slide = OpenLP.getElement(event); var slide = OpenLP.getElement(event);
console.log(slide);
var id = slide.attr("value"); var id = slide.attr("value");
var text = JSON.stringify({"request": {"id": id}}); var text = JSON.stringify({"request": {"id": id}});
$.getJSON( $.getJSON(

View File

@ -68,6 +68,7 @@ from lxml import etree, objectify
from openlp.plugins.songs.lib import clean_song, VerseType from openlp.plugins.songs.lib import clean_song, VerseType
from openlp.plugins.songs.lib.db import Author, Book, Song, Topic from openlp.plugins.songs.lib.db import Author, Book, Song, Topic
from openlp.core.utils import get_application_version
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -230,8 +231,8 @@ class OpenLyrics(object):
# Append the necessary meta data to the song. # Append the necessary meta data to the song.
song_xml.set(u'xmlns', u'http://openlyrics.info/namespace/2009/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'version', OpenLyrics.IMPLEMENTED_VERSION)
song_xml.set(u'createdIn', u'OpenLP 1.9.5') # Use variable song_xml.set(u'createdIn', get_application_version()[u'version'])
song_xml.set(u'modifiedIn', u'OpenLP 1.9.5') # Use variable song_xml.set(u'modifiedIn', get_application_version()[u'version'])
song_xml.set(u'modifiedDate', song_xml.set(u'modifiedDate',
datetime.datetime.now().strftime(u'%Y-%m-%dT%H:%M:%S')) datetime.datetime.now().strftime(u'%Y-%m-%dT%H:%M:%S'))
properties = etree.SubElement(song_xml, u'properties') properties = etree.SubElement(song_xml, u'properties')

View File

@ -3,11 +3,11 @@ Categories=AudioVideo;
Comment[de]= Comment[de]=
Comment= Comment=
Encoding=UTF-8 Encoding=UTF-8
Exec=openlp Exec=openlp %F
GenericName[de]=Church lyrics projection GenericName[de]=Church lyrics projection
GenericName=Church lyrics projection GenericName=Church lyrics projection
Icon=openlp Icon=openlp
MimeType= MimeType=application/x-openlp-service;
Name[de]=OpenLP Name[de]=OpenLP
Name=OpenLP Name=OpenLP
Path= Path=

26
resources/openlp.xml Normal file
View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
It comes with ABSOLUTELY NO WARRANTY, to the extent permitted by law. You may
redistribute copies of update-mime-database under the terms of the GNU General
Public License. For more information about these matters, see the file named
COPYING.
-->
<!--
Notes:
- the mime types in this file are valid with the version 0.30 of the
shared-mime-info package.
- the "fdo #xxxxx" are the wish in the freedesktop.org bug database to include
the mime type there.
-->
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="application/x-openlp-service">
<sub-class-of type="application/zip"/>
<comment>OpenLP Service File</comment>
<glob pattern="*.osz"/>
</mime-type>
<mime-type type="application/x-openlp-theme">
<sub-class-of type="application/zip"/>
<comment>OpenLP Theme File</comment>
<glob pattern="*.otz"/>
</mime-type>
</mime-info>

View File

@ -18,9 +18,9 @@
<string>MacOS/openlp</string> <string>MacOS/openlp</string>
<key>CFBundleName</key> <key>CFBundleName</key>
<string>%(openlp_appname)s</string> <string>%(openlp_appname)s</string>
<key>CFBundleGetInfoString</string> <key>CFBundleGetInfoString</key>
<string>%(openlp_appname)s %(openlp_version)s</string> <string>%(openlp_appname)s %(openlp_version)s</string>
<key>LSHasLocalizedDisplayName</string> <key>LSHasLocalizedDisplayName</key>
<false/> <false/>
<key>NSAppleScriptEnabled</key> <key>NSAppleScriptEnabled</key>
<false/> <false/>

View File

@ -25,4 +25,4 @@ clean:
rm -rf OpenLP.app rm -rf OpenLP.app
rm -f warnopenlp.txt rm -f warnopenlp.txt
rm -f *dmg rm -f *dmg

View File

@ -82,6 +82,7 @@ import ConfigParser
import logging import logging
import optparse import optparse
import sys import sys
import glob
import platform import platform
import re import re
import subprocess as subp import subprocess as subp
@ -122,6 +123,15 @@ def build_application(settings, app_name_lower, app_dir):
script_name) script_name)
sys.exit(1) 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...', logging.info('[%s] copying the icons to the resource directory...',
script_name) script_name)
result = os.system('cp %(icon_file)s \ result = os.system('cp %(icon_file)s \
@ -151,6 +161,19 @@ def build_application(settings, app_name_lower, app_dir):
failed!', script_name) failed!', script_name)
sys.exit(1) 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): def deploy_qt(settings):
logging.info('[%s] running mac deploy qt on %s.app...', script_name, logging.info('[%s] running mac deploy qt on %s.app...', script_name,
settings['openlp_appname']); settings['openlp_appname']);