diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py
index e104f4022..a687ded64 100644
--- a/openlp/core/lib/__init__.py
+++ b/openlp/core/lib/__init__.py
@@ -80,6 +80,9 @@ def get_text_file_string(text_file):
content_string = None
try:
file_handle = open(text_file, u'r')
+ if not file_handle.read(3) == '\xEF\xBB\xBF':
+ # no BOM was found
+ file_handle.seek(0)
content = file_handle.read()
content_string = content.decode(u'utf-8')
except (IOError, UnicodeError):
@@ -191,10 +194,10 @@ def validate_thumb(file_path, thumb_path):
``thumb_path``
The path to the thumb.
"""
- if not os.path.exists(unicode(thumb_path)):
+ if not os.path.exists(thumb_path):
return False
- image_date = os.stat(unicode(file_path)).st_mtime
- thumb_date = os.stat(unicode(thumb_path)).st_mtime
+ image_date = os.stat(file_path).st_mtime
+ thumb_date = os.stat(thumb_path).st_mtime
return image_date <= thumb_date
def resize_image(image_path, width, height, background=u'#000000'):
diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py
index 86e0a0a30..b6f12d180 100644
--- a/openlp/core/lib/db.py
+++ b/openlp/core/lib/db.py
@@ -358,10 +358,17 @@ class Manager(object):
def delete_all_objects(self, object_class, filter_clause=None):
"""
- Delete all object records
+ Delete all object records.
+ This method should only be used for simple tables and not ones with
+ relationships. The relationships are not deleted from the database and
+ this will lead to database corruptions.
``object_class``
The type of object to delete
+
+ ``filter_clause``
+ The filter governing selection of objects to return. Defaults to
+ None.
"""
try:
query = self.session.query(object_class)
diff --git a/openlp/core/lib/eventreceiver.py b/openlp/core/lib/eventreceiver.py
index 14b6126bc..40cac8e35 100644
--- a/openlp/core/lib/eventreceiver.py
+++ b/openlp/core/lib/eventreceiver.py
@@ -115,8 +115,12 @@ class EventReceiver(QtCore.QObject):
``slidecontroller_live_stop_loop``
Stop the loop on the main display.
+
**Servicemanager related signals**
+ ``servicemanager_new_service``
+ A new service is being loaded or created.
+
``servicemanager_previous_item``
Display the previous item in the service.
diff --git a/openlp/core/lib/formattingtags.py b/openlp/core/lib/formattingtags.py
index ea5547f27..bc0055325 100644
--- a/openlp/core/lib/formattingtags.py
+++ b/openlp/core/lib/formattingtags.py
@@ -149,11 +149,17 @@ class FormattingTags(object):
tags = []
for tag in FormattingTags.html_expands:
if not tag[u'protected'] and not tag.get(u'temporary'):
- tags.append(tag)
- # Remove key 'temporary' from tags. It is not needed to be saved.
- for tag in tags:
- if u'temporary' in tag:
- del tag[u'temporary']
+ # Using dict ensures that copy is made and encoding of values
+ # a little later does not affect tags in the original list
+ tags.append(dict(tag))
+ tag = tags[-1]
+ # Remove key 'temporary' from tags.
+ # It is not needed to be saved.
+ if u'temporary' in tag:
+ del tag[u'temporary']
+ for element in tag:
+ if isinstance(tag[element], unicode):
+ tag[element] = tag[element].encode('utf8')
# Formatting Tags were also known as display tags.
QtCore.QSettings().setValue(u'displayTags/html_tags',
QtCore.QVariant(cPickle.dumps(tags) if tags else u''))
@@ -171,9 +177,13 @@ class FormattingTags(object):
user_expands = QtCore.QSettings().value(u'displayTags/html_tags',
QtCore.QVariant(u'')).toString()
# cPickle only accepts str not unicode strings
- user_expands_string = str(unicode(user_expands).encode(u'utf8'))
+ user_expands_string = str(user_expands)
if user_expands_string:
user_tags = cPickle.loads(user_expands_string)
+ for tag in user_tags:
+ for element in tag:
+ if isinstance(tag[element], str):
+ tag[element] = tag[element].decode('utf8')
# If we have some user ones added them as well
FormattingTags.add_html_tags(user_tags)
diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py
index b12a27f1d..62418f49e 100644
--- a/openlp/core/lib/serviceitem.py
+++ b/openlp/core/lib/serviceitem.py
@@ -119,6 +119,7 @@ class ServiceItem(object):
self.image_border = u'#000000'
self.background_audio = []
self.theme_overwritten = False
+ self.temporary_edit = False
self._new_item()
def _new_item(self):
@@ -365,6 +366,7 @@ class ServiceItem(object):
"""
self._uuid = other._uuid
self.notes = other.notes
+ self.temporary_edit = other.temporary_edit
# Copy theme over if present.
if other.theme is not None:
self.theme = other.theme
diff --git a/openlp/core/lib/settingstab.py b/openlp/core/lib/settingstab.py
index 46263efca..f36f9f561 100644
--- a/openlp/core/lib/settingstab.py
+++ b/openlp/core/lib/settingstab.py
@@ -125,3 +125,9 @@ class SettingsTab(QtGui.QWidget):
"""
pass
+
+ def tabVisible(self):
+ """
+ Tab has just been made visible to the user
+ """
+ pass
diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py
index e439b1db1..328970d45 100644
--- a/openlp/core/ui/maindisplay.py
+++ b/openlp/core/ui/maindisplay.py
@@ -45,7 +45,7 @@ log = logging.getLogger(__name__)
class Display(QtGui.QGraphicsView):
"""
- This is a general display screen class. Here the general display settings
+ This is a general display screen class. Here the general display settings
will done. It will be used as specialized classes by Main Display and
Preview display.
"""
@@ -66,7 +66,7 @@ class Display(QtGui.QGraphicsView):
"""
Set up and build the screen base
"""
- log.debug(u'Start Display base setup (live = %s)' % self.isLive)
+ log.debug(u'Start Display base setup (live = %s)' % self.isLive)
self.setGeometry(self.screen[u'size'])
log.debug(u'Setup webView')
self.webView = QtWebKit.QWebView(self)
diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py
index ab21a9c19..07c90e62f 100644
--- a/openlp/core/ui/mainwindow.py
+++ b/openlp/core/ui/mainwindow.py
@@ -176,92 +176,100 @@ class Ui_MainWindow(object):
self.themeManagerDock)
# Create the menu items
action_list = ActionList.get_instance()
- action_list.add_category(UiStrings().File, CategoryOrder.standardMenu)
+ action_list.add_category(unicode(UiStrings().File),
+ CategoryOrder.standardMenu)
self.fileNewItem = shortcut_action(mainWindow, u'fileNewItem',
[QtGui.QKeySequence(u'Ctrl+N')],
self.serviceManagerContents.onNewServiceClicked,
- u':/general/general_new.png', category=UiStrings().File)
+ u':/general/general_new.png', category=unicode(UiStrings().File))
self.fileOpenItem = shortcut_action(mainWindow, u'fileOpenItem',
[QtGui.QKeySequence(u'Ctrl+O')],
self.serviceManagerContents.onLoadServiceClicked,
- u':/general/general_open.png', category=UiStrings().File)
+ u':/general/general_open.png', category=unicode(UiStrings().File))
self.fileSaveItem = shortcut_action(mainWindow, u'fileSaveItem',
[QtGui.QKeySequence(u'Ctrl+S')],
self.serviceManagerContents.saveFile,
- u':/general/general_save.png', category=UiStrings().File)
+ u':/general/general_save.png', category=unicode(UiStrings().File))
self.fileSaveAsItem = shortcut_action(mainWindow, u'fileSaveAsItem',
[QtGui.QKeySequence(u'Ctrl+Shift+S')],
- self.serviceManagerContents.saveFileAs, category=UiStrings().File)
+ self.serviceManagerContents.saveFileAs,
+ category=unicode(UiStrings().File))
self.printServiceOrderItem = shortcut_action(mainWindow,
u'printServiceItem', [QtGui.QKeySequence(u'Ctrl+P')],
self.serviceManagerContents.printServiceOrder,
- category=UiStrings().File)
+ category=unicode(UiStrings().File))
self.fileExitItem = shortcut_action(mainWindow, u'fileExitItem',
[QtGui.QKeySequence(u'Alt+F4')], mainWindow.close,
- u':/system/system_exit.png', category=UiStrings().File)
- action_list.add_category(UiStrings().Import, CategoryOrder.standardMenu)
+ u':/system/system_exit.png', category=unicode(UiStrings().File))
+ action_list.add_category(unicode(UiStrings().Import),
+ CategoryOrder.standardMenu)
self.importThemeItem = base_action(
- mainWindow, u'importThemeItem', UiStrings().Import)
+ mainWindow, u'importThemeItem', unicode(UiStrings().Import))
self.importLanguageItem = base_action(
- mainWindow, u'importLanguageItem')#, UiStrings().Import)
- action_list.add_category(UiStrings().Export, CategoryOrder.standardMenu)
+ mainWindow, u'importLanguageItem')#, unicode(UiStrings().Import))
+ action_list.add_category(unicode(UiStrings().Export),
+ CategoryOrder.standardMenu)
self.exportThemeItem = base_action(
- mainWindow, u'exportThemeItem', UiStrings().Export)
+ mainWindow, u'exportThemeItem', unicode(UiStrings().Export))
self.exportLanguageItem = base_action(
- mainWindow, u'exportLanguageItem')#, UiStrings().Export)
- action_list.add_category(UiStrings().View, CategoryOrder.standardMenu)
+ mainWindow, u'exportLanguageItem')#, unicode(UiStrings().Export))
+ action_list.add_category(unicode(UiStrings().View),
+ CategoryOrder.standardMenu)
self.viewMediaManagerItem = shortcut_action(mainWindow,
u'viewMediaManagerItem', [QtGui.QKeySequence(u'F8')],
self.toggleMediaManager, u':/system/system_mediamanager.png',
- self.mediaManagerDock.isVisible(), UiStrings().View)
+ self.mediaManagerDock.isVisible(), unicode(UiStrings().View))
self.viewThemeManagerItem = shortcut_action(mainWindow,
u'viewThemeManagerItem', [QtGui.QKeySequence(u'F10')],
self.toggleThemeManager, u':/system/system_thememanager.png',
- self.themeManagerDock.isVisible(), UiStrings().View)
+ self.themeManagerDock.isVisible(), unicode(UiStrings().View))
self.viewServiceManagerItem = shortcut_action(mainWindow,
u'viewServiceManagerItem', [QtGui.QKeySequence(u'F9')],
self.toggleServiceManager, u':/system/system_servicemanager.png',
- self.serviceManagerDock.isVisible(), UiStrings().View)
+ self.serviceManagerDock.isVisible(), unicode(UiStrings().View))
self.viewPreviewPanel = shortcut_action(mainWindow,
u'viewPreviewPanel', [QtGui.QKeySequence(u'F11')],
self.setPreviewPanelVisibility, checked=previewVisible,
- category=UiStrings().View)
+ category=unicode(UiStrings().View))
self.viewLivePanel = shortcut_action(mainWindow, u'viewLivePanel',
[QtGui.QKeySequence(u'F12')], self.setLivePanelVisibility,
- checked=liveVisible, category=UiStrings().View)
+ checked=liveVisible, category=unicode(UiStrings().View))
self.lockPanel = shortcut_action(mainWindow, u'lockPanel',
None, self.setLockPanel,
checked=panelLocked, category=None)
- action_list.add_category(UiStrings().ViewMode,
+ action_list.add_category(unicode(UiStrings().ViewMode),
CategoryOrder.standardMenu)
self.modeDefaultItem = checkable_action(
- mainWindow, u'modeDefaultItem', category=UiStrings().ViewMode)
+ mainWindow, u'modeDefaultItem',
+ category=unicode(UiStrings().ViewMode))
self.modeSetupItem = checkable_action(
- mainWindow, u'modeSetupItem', category=UiStrings().ViewMode)
+ mainWindow, u'modeSetupItem',
+ category=unicode(UiStrings().ViewMode))
self.modeLiveItem = checkable_action(
- mainWindow, u'modeLiveItem', True, UiStrings().ViewMode)
+ mainWindow, u'modeLiveItem', True, unicode(UiStrings().ViewMode))
self.modeGroup = QtGui.QActionGroup(mainWindow)
self.modeGroup.addAction(self.modeDefaultItem)
self.modeGroup.addAction(self.modeSetupItem)
self.modeGroup.addAction(self.modeLiveItem)
self.modeDefaultItem.setChecked(True)
- action_list.add_category(UiStrings().Tools, CategoryOrder.standardMenu)
+ action_list.add_category(unicode(UiStrings().Tools),
+ CategoryOrder.standardMenu)
self.toolsAddToolItem = icon_action(mainWindow, u'toolsAddToolItem',
- u':/tools/tools_add.png', category=UiStrings().Tools)
+ u':/tools/tools_add.png', category=unicode(UiStrings().Tools))
self.toolsOpenDataFolder = icon_action(mainWindow,
u'toolsOpenDataFolder', u':/general/general_open.png',
- category=UiStrings().Tools)
+ category=unicode(UiStrings().Tools))
self.toolsFirstTimeWizard = icon_action(mainWindow,
u'toolsFirstTimeWizard', u':/general/general_revert.png',
- category=UiStrings().Tools)
+ category=unicode(UiStrings().Tools))
self.updateThemeImages = base_action(mainWindow,
- u'updateThemeImages', category=UiStrings().Tools)
- action_list.add_category(UiStrings().Settings,
+ u'updateThemeImages', category=unicode(UiStrings().Tools))
+ action_list.add_category(unicode(UiStrings().Settings),
CategoryOrder.standardMenu)
self.settingsPluginListItem = shortcut_action(mainWindow,
u'settingsPluginListItem', [QtGui.QKeySequence(u'Alt+F7')],
self.onPluginItemClicked, u':/system/settings_plugin_list.png',
- category=UiStrings().Settings)
+ category=unicode(UiStrings().Settings))
# i18n Language Items
self.autoLanguageItem = checkable_action(mainWindow,
u'autoLanguageItem', LanguageManager.auto_language)
@@ -278,35 +286,38 @@ class Ui_MainWindow(object):
self.settingsShortcutsItem = icon_action(mainWindow,
u'settingsShortcutsItem',
u':/system/system_configure_shortcuts.png',
- category=UiStrings().Settings)
+ category=unicode(UiStrings().Settings))
# Formatting Tags were also known as display tags.
self.formattingTagItem = icon_action(mainWindow,
u'displayTagItem', u':/system/tag_editor.png',
- category=UiStrings().Settings)
+ category=unicode(UiStrings().Settings))
self.settingsConfigureItem = icon_action(mainWindow,
u'settingsConfigureItem', u':/system/system_settings.png',
- category=UiStrings().Settings)
+ category=unicode(UiStrings().Settings))
self.settingsImportItem = base_action(mainWindow,
- u'settingsImportItem', category=UiStrings().Settings)
+ u'settingsImportItem', category=unicode(UiStrings().Settings))
self.settingsExportItem = base_action(mainWindow,
- u'settingsExportItem', category=UiStrings().Settings)
- action_list.add_category(UiStrings().Help, CategoryOrder.standardMenu)
+ u'settingsExportItem', category=unicode(UiStrings().Settings))
+ action_list.add_category(unicode(UiStrings().Help),
+ CategoryOrder.standardMenu)
self.aboutItem = shortcut_action(mainWindow, u'aboutItem',
[QtGui.QKeySequence(u'Ctrl+F1')], self.onAboutItemClicked,
- u':/system/system_about.png', category=UiStrings().Help)
+ u':/system/system_about.png', category=unicode(UiStrings().Help))
if os.name == u'nt':
self.localHelpFile = os.path.join(
AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm')
self.offlineHelpItem = shortcut_action(
mainWindow, u'offlineHelpItem', [QtGui.QKeySequence(u'F1')],
self.onOfflineHelpClicked,
- u':/system/system_help_contents.png', category=UiStrings().Help)
+ u':/system/system_help_contents.png',
+ category=unicode(UiStrings().Help))
self.onlineHelpItem = shortcut_action(
mainWindow, u'onlineHelpItem',
[QtGui.QKeySequence(u'Alt+F1')], self.onOnlineHelpClicked,
- u':/system/system_online_help.png', category=UiStrings().Help)
+ u':/system/system_online_help.png',
+ category=unicode(UiStrings().Help))
self.webSiteItem = base_action(
- mainWindow, u'webSiteItem', category=UiStrings().Help)
+ mainWindow, u'webSiteItem', category=unicode(UiStrings().Help))
add_actions(self.fileImportMenu, (self.settingsImportItem, None,
self.importThemeItem, self.importLanguageItem))
add_actions(self.fileExportMenu, (self.settingsExportItem, None,
diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py
index 8ad2db9c2..0eb1e77c5 100644
--- a/openlp/core/ui/servicemanager.py
+++ b/openlp/core/ui/servicemanager.py
@@ -37,7 +37,7 @@ log = logging.getLogger(__name__)
from PyQt4 import QtCore, QtGui
from openlp.core.lib import OpenLPToolbar, ServiceItem, Receiver, build_icon, \
- ItemCapabilities, SettingsManager, translate
+ ItemCapabilities, SettingsManager, translate, str_to_bool
from openlp.core.lib.theme import ThemeLevel
from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
context_menu_action, context_menu_separator, find_and_set_in_combo_box
@@ -177,9 +177,9 @@ class ServiceManager(QtGui.QWidget):
self.serviceManagerList.moveTop.setObjectName(u'moveTop')
action_list = ActionList.get_instance()
action_list.add_category(
- UiStrings().Service, CategoryOrder.standardToolbar)
+ unicode(UiStrings().Service), CategoryOrder.standardToolbar)
action_list.add_action(
- self.serviceManagerList.moveTop, UiStrings().Service)
+ self.serviceManagerList.moveTop, unicode(UiStrings().Service))
self.serviceManagerList.moveUp = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move &up'),
u':/services/service_up.png',
@@ -188,7 +188,7 @@ class ServiceManager(QtGui.QWidget):
self.onServiceUp, shortcuts=[QtCore.Qt.Key_PageUp])
self.serviceManagerList.moveUp.setObjectName(u'moveUp')
action_list.add_action(
- self.serviceManagerList.moveUp, UiStrings().Service)
+ self.serviceManagerList.moveUp, unicode(UiStrings().Service))
self.serviceManagerList.moveDown = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move &down'),
u':/services/service_down.png',
@@ -197,7 +197,7 @@ class ServiceManager(QtGui.QWidget):
self.onServiceDown, shortcuts=[QtCore.Qt.Key_PageDown])
self.serviceManagerList.moveDown.setObjectName(u'moveDown')
action_list.add_action(
- self.serviceManagerList.moveDown, UiStrings().Service)
+ self.serviceManagerList.moveDown, unicode(UiStrings().Service))
self.serviceManagerList.moveBottom = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move to &bottom'),
u':/services/service_bottom.png',
@@ -206,7 +206,7 @@ class ServiceManager(QtGui.QWidget):
self.onServiceEnd, shortcuts=[QtCore.Qt.Key_End])
self.serviceManagerList.moveBottom.setObjectName(u'moveBottom')
action_list.add_action(
- self.serviceManagerList.moveBottom, UiStrings().Service)
+ self.serviceManagerList.moveBottom, unicode(UiStrings().Service))
self.serviceManagerList.down = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Move &down'),
None,
@@ -241,7 +241,7 @@ class ServiceManager(QtGui.QWidget):
self.onExpandAll, shortcuts=[QtCore.Qt.Key_Plus])
self.serviceManagerList.expand.setObjectName(u'expand')
action_list.add_action(
- self.serviceManagerList.expand, UiStrings().Service)
+ self.serviceManagerList.expand, unicode(UiStrings().Service))
self.serviceManagerList.collapse = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', '&Collapse all'),
u':/services/service_collapse_all.png',
@@ -250,7 +250,7 @@ class ServiceManager(QtGui.QWidget):
self.onCollapseAll, shortcuts=[QtCore.Qt.Key_Minus])
self.serviceManagerList.collapse.setObjectName(u'collapse')
action_list.add_action(
- self.serviceManagerList.collapse, UiStrings().Service)
+ self.serviceManagerList.collapse, unicode(UiStrings().Service))
self.orderToolbar.addSeparator()
self.serviceManagerList.makeLive = self.orderToolbar.addToolbarButton(
translate('OpenLP.ServiceManager', 'Go Live'),
@@ -260,7 +260,7 @@ class ServiceManager(QtGui.QWidget):
shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return])
self.serviceManagerList.makeLive.setObjectName(u'orderToolbar')
action_list.add_action(
- self.serviceManagerList.makeLive, UiStrings().Service)
+ self.serviceManagerList.makeLive, unicode(UiStrings().Service))
self.layout.addWidget(self.orderToolbar)
# Connect up our signals and slots
QtCore.QObject.connect(self.themeComboBox,
@@ -465,6 +465,7 @@ class ServiceManager(QtGui.QWidget):
self.setModified(False)
QtCore.QSettings(). \
setValue(u'servicemanager/last file',QtCore.QVariant(u''))
+ Receiver.send_message(u'servicemanager_new_service')
def saveFile(self):
"""
@@ -663,13 +664,14 @@ class ServiceManager(QtGui.QWidget):
serviceItem.renderer = self.mainwindow.renderer
serviceItem.set_from_service(item, self.servicePath)
self.validateItem(serviceItem)
- self.loadItem_uuid = 0
+ self.load_item_uuid = 0
if serviceItem.is_capable(ItemCapabilities.OnLoadUpdate):
Receiver.send_message(u'%s_service_load' %
serviceItem.name.lower(), serviceItem)
# if the item has been processed
- if serviceItem._uuid == self.loadItem_uuid:
- serviceItem.edit_id = int(self.loadItem_editId)
+ if serviceItem._uuid == self.load_item_uuid:
+ serviceItem.edit_id = int(self.load_item_edit_id)
+ serviceItem.temporary_edit = self.load_item_temporary
self.addServiceItem(serviceItem, repaint=False)
delete_file(p_file)
self.setFileName(fileName)
@@ -999,6 +1001,17 @@ class ServiceManager(QtGui.QWidget):
painter.drawImage(0, 0, overlay)
painter.end()
treewidgetitem.setIcon(0, build_icon(icon))
+ elif serviceitem.temporary_edit:
+ icon = QtGui.QImage(serviceitem.icon)
+ icon = icon.scaled(80, 80, QtCore.Qt.KeepAspectRatio,
+ QtCore.Qt.SmoothTransformation)
+ overlay = QtGui.QImage(':/general/general_export.png')
+ overlay = overlay.scaled(40, 40, QtCore.Qt.KeepAspectRatio,
+ QtCore.Qt.SmoothTransformation)
+ painter = QtGui.QPainter(icon)
+ painter.drawImage(40, 0, overlay)
+ painter.end()
+ treewidgetitem.setIcon(0, build_icon(icon))
else:
treewidgetitem.setIcon(0, serviceitem.iconic_representation)
else:
@@ -1006,6 +1019,11 @@ class ServiceManager(QtGui.QWidget):
build_icon(u':/general/general_delete.png'))
treewidgetitem.setText(0, serviceitem.get_display_title())
tips = []
+ if serviceitem.temporary_edit:
+ tips.append(u'%s: %s' %
+ (unicode(translate('OpenLP.ServiceManager', 'Edit')),
+ (unicode(translate('OpenLP.ServiceManager',
+ 'Service copy only')))))
if serviceitem.theme and serviceitem.theme != -1:
tips.append(u'%s: %s' %
(unicode(translate('OpenLP.ServiceManager', 'Slide theme')),
@@ -1127,8 +1145,9 @@ class ServiceManager(QtGui.QWidget):
Triggered from plugins to update service items.
Save the values as they will be used as part of the service load
"""
- editId, self.loadItem_uuid = message.split(u':')
- self.loadItem_editId = int(editId)
+ edit_id, self.load_item_uuid, temporary = message.split(u':')
+ self.load_item_edit_id = int(edit_id)
+ self.load_item_temporary = str_to_bool(temporary)
def replaceServiceItem(self, newItem):
"""
diff --git a/openlp/core/ui/settingsdialog.py b/openlp/core/ui/settingsdialog.py
index 296337f0f..643ab0a6e 100644
--- a/openlp/core/ui/settingsdialog.py
+++ b/openlp/core/ui/settingsdialog.py
@@ -55,7 +55,7 @@ class Ui_SettingsDialog(object):
QtCore.QMetaObject.connectSlotsByName(settingsDialog)
QtCore.QObject.connect(self.settingListWidget,
QtCore.SIGNAL(u'currentRowChanged(int)'),
- self.stackedLayout.setCurrentIndex)
+ self.tabChanged)
def retranslateUi(self, settingsDialog):
settingsDialog.setWindowTitle(translate('OpenLP.SettingsForm',
diff --git a/openlp/core/ui/settingsform.py b/openlp/core/ui/settingsform.py
index 37da93b5b..b25a3a856 100644
--- a/openlp/core/ui/settingsform.py
+++ b/openlp/core/ui/settingsform.py
@@ -116,3 +116,10 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
for plugin in self.plugins:
if plugin.settings_tab:
plugin.settings_tab.postSetUp()
+
+ def tabChanged(self, tabIndex):
+ """
+ A different settings tab is selected
+ """
+ self.stackedLayout.setCurrentIndex(tabIndex)
+ self.stackedLayout.currentWidget().tabVisible()
diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py
index 92eb7971e..cd4663297 100644
--- a/openlp/core/ui/slidecontroller.py
+++ b/openlp/core/ui/slidecontroller.py
@@ -187,18 +187,20 @@ class SlideController(Controller):
translate('OpenLP.SlideController', 'Hide'), self.toolbar))
self.blankScreen = shortcut_action(self.hideMenu, u'blankScreen',
[QtCore.Qt.Key_Period], self.onBlankDisplay,
- u':/slides/slide_blank.png', False, UiStrings().LiveToolbar)
+ u':/slides/slide_blank.png', False,
+ unicode(UiStrings().LiveToolbar))
self.blankScreen.setText(
translate('OpenLP.SlideController', 'Blank Screen'))
self.themeScreen = shortcut_action(self.hideMenu, u'themeScreen',
[QtGui.QKeySequence(u'T')], self.onThemeDisplay,
- u':/slides/slide_theme.png', False, UiStrings().LiveToolbar)
+ u':/slides/slide_theme.png', False,
+ unicode(UiStrings().LiveToolbar))
self.themeScreen.setText(
translate('OpenLP.SlideController', 'Blank to Theme'))
self.desktopScreen = shortcut_action(self.hideMenu,
u'desktopScreen', [QtGui.QKeySequence(u'D')],
self.onHideDisplay, u':/slides/slide_desktop.png', False,
- UiStrings().LiveToolbar)
+ unicode(UiStrings().LiveToolbar))
self.desktopScreen.setText(
translate('OpenLP.SlideController', 'Show Desktop'))
self.hideMenu.setDefaultAction(self.blankScreen)
@@ -218,11 +220,13 @@ class SlideController(Controller):
self.toolbar))
self.playSlidesLoop = shortcut_action(self.playSlidesMenu,
u'playSlidesLoop', [], self.onPlaySlidesLoop,
- u':/media/media_time.png', False, UiStrings().LiveToolbar)
+ u':/media/media_time.png', False,
+ unicode(UiStrings().LiveToolbar))
self.playSlidesLoop.setText(UiStrings().PlaySlidesInLoop)
self.playSlidesOnce = shortcut_action(self.playSlidesMenu,
u'playSlidesOnce', [], self.onPlaySlidesOnce,
- u':/media/media_time.png', False, UiStrings().LiveToolbar)
+ u':/media/media_time.png', False,
+ unicode(UiStrings().LiveToolbar))
self.playSlidesOnce.setText(UiStrings().PlaySlidesToEnd)
if QtCore.QSettings().value(self.parent().generalSettingsSection +
u'/enable slide loop', QtCore.QVariant(True)).toBool():
@@ -320,7 +324,7 @@ class SlideController(Controller):
self.shortcutTimer.setSingleShot(True)
self.verseShortcut = shortcut_action(self, u'verseShortcut',
[QtGui.QKeySequence(u'V')], self.slideShortcutActivated,
- category=UiStrings().LiveToolbar,
+ category=unicode(UiStrings().LiveToolbar),
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.verseShortcut.setText(translate(
'OpenLP.SlideController', 'Go to "Verse"'))
@@ -356,37 +360,37 @@ class SlideController(Controller):
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.chorusShortcut = shortcut_action(self, u'chorusShortcut',
[QtGui.QKeySequence(u'C')], self.slideShortcutActivated,
- category=UiStrings().LiveToolbar,
+ category=unicode(UiStrings().LiveToolbar),
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.chorusShortcut.setText(translate(
'OpenLP.SlideController', 'Go to "Chorus"'))
self.bridgeShortcut = shortcut_action(self, u'bridgeShortcut',
[QtGui.QKeySequence(u'B')], self.slideShortcutActivated,
- category=UiStrings().LiveToolbar,
+ category=unicode(UiStrings().LiveToolbar),
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.bridgeShortcut.setText(translate(
'OpenLP.SlideController', 'Go to "Bridge"'))
self.preChorusShortcut = shortcut_action(self, u'preChorusShortcut',
[QtGui.QKeySequence(u'P')], self.slideShortcutActivated,
- category=UiStrings().LiveToolbar,
+ category=unicode(UiStrings().LiveToolbar),
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.preChorusShortcut.setText(translate(
'OpenLP.SlideController', 'Go to "Pre-Chorus"'))
self.introShortcut = shortcut_action(self, u'introShortcut',
[QtGui.QKeySequence(u'I')], self.slideShortcutActivated,
- category=UiStrings().LiveToolbar,
+ category=unicode(UiStrings().LiveToolbar),
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.introShortcut.setText(translate(
'OpenLP.SlideController', 'Go to "Intro"'))
self.endingShortcut = shortcut_action(self, u'endingShortcut',
[QtGui.QKeySequence(u'E')], self.slideShortcutActivated,
- category=UiStrings().LiveToolbar,
+ category=unicode(UiStrings().LiveToolbar),
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.endingShortcut.setText(translate(
'OpenLP.SlideController', 'Go to "Ending"'))
self.otherShortcut = shortcut_action(self, u'otherShortcut',
[QtGui.QKeySequence(u'O')], self.slideShortcutActivated,
- category=UiStrings().LiveToolbar,
+ category=unicode(UiStrings().LiveToolbar),
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.otherShortcut.setText(translate(
'OpenLP.SlideController', 'Go to "Other"'))
@@ -540,24 +544,24 @@ class SlideController(Controller):
self.nextItem.setObjectName(u'nextItemLive')
action_list = ActionList.get_instance()
action_list.add_category(
- UiStrings().LiveToolbar, CategoryOrder.standardToolbar)
+ unicode(UiStrings().LiveToolbar), CategoryOrder.standardToolbar)
action_list.add_action(self.previousItem)
action_list.add_action(self.nextItem)
self.previousService = shortcut_action(parent, u'previousService',
[QtCore.Qt.Key_Left], self.servicePrevious,
- category=UiStrings().LiveToolbar,
+ category=unicode(UiStrings().LiveToolbar),
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.previousService.setText(
translate('OpenLP.SlideController', 'Previous Service'))
self.nextService = shortcut_action(parent, 'nextService',
[QtCore.Qt.Key_Right], self.serviceNext,
- category=UiStrings().LiveToolbar,
+ category=unicode(UiStrings().LiveToolbar),
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.nextService.setText(
translate('OpenLP.SlideController', 'Next Service'))
self.escapeItem = shortcut_action(parent, 'escapeItem',
[QtCore.Qt.Key_Escape], self.liveEscape,
- category=UiStrings().LiveToolbar,
+ category=unicode(UiStrings().LiveToolbar),
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.escapeItem.setText(
translate('OpenLP.SlideController', 'Escape Item'))
diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py
index 596bce5d9..b8767d736 100644
--- a/openlp/core/ui/thememanager.py
+++ b/openlp/core/ui/thememanager.py
@@ -526,13 +526,11 @@ class ThemeManager(QtGui.QWidget):
zip = zipfile.ZipFile(filename)
themename = None
for file in zip.namelist():
+ # Handle UTF-8 files
ucsfile = file_is_unicode(file)
if not ucsfile:
- critical_error_message_box(
- message=translate('OpenLP.ThemeManager',
- 'File is not a valid theme.\n'
- 'The content encoding is not UTF-8.'))
- continue
+ # Handle native Unicode files from Windows
+ ucsfile = file
osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile))
theme_dir = None
if osfile.endswith(os.path.sep):
@@ -620,7 +618,7 @@ class ThemeManager(QtGui.QWidget):
"""
name = theme.theme_name
theme_pretty_xml = theme.extract_formatted_xml()
- log.debug(u'saveTheme %s %s', name, theme_pretty_xml)
+ log.debug(u'saveTheme %s %s', name, theme_pretty_xml.decode(u'utf-8'))
theme_dir = os.path.join(self.path, name)
check_directory_exists(theme_dir)
theme_file = os.path.join(theme_dir, name + u'.xml')
diff --git a/openlp/core/utils/actions.py b/openlp/core/utils/actions.py
index 86ee69a48..8b807bf9e 100644
--- a/openlp/core/utils/actions.py
+++ b/openlp/core/utils/actions.py
@@ -217,8 +217,6 @@ class ActionList(object):
The weight specifies how important a category is. However, this only
has an impact on the order the categories are displayed.
"""
- if category is not None:
- category = unicode(category)
if category not in self.categories:
self.categories.append(category)
action.defaultShortcuts = action.shortcuts()
@@ -226,7 +224,7 @@ class ActionList(object):
self.categories[category].actions.append(action)
else:
self.categories[category].actions.add(action, weight)
- if category is None:
+ if not category:
# Stop here, as this action is not configurable.
return
# Load the shortcut from the config.
@@ -250,8 +248,6 @@ class ActionList(object):
The name (unicode string) of the category, which contains the
action. Defaults to None.
"""
- if category is not None:
- category = unicode(category)
if category not in self.categories:
return
self.categories[category].actions.remove(action)
diff --git a/openlp/plugins/alerts/alertsplugin.py b/openlp/plugins/alerts/alertsplugin.py
index 493f08ba0..ba2af74e8 100644
--- a/openlp/plugins/alerts/alertsplugin.py
+++ b/openlp/plugins/alerts/alertsplugin.py
@@ -149,7 +149,7 @@ class AlertsPlugin(Plugin):
Plugin.initialise(self)
self.toolsAlertItem.setVisible(True)
action_list = ActionList.get_instance()
- action_list.add_action(self.toolsAlertItem, UiStrings().Tools)
+ action_list.add_action(self.toolsAlertItem, unicode(UiStrings().Tools))
def finalise(self):
"""
diff --git a/openlp/plugins/bibles/bibleplugin.py b/openlp/plugins/bibles/bibleplugin.py
index 619581b17..68b4d1ce8 100644
--- a/openlp/plugins/bibles/bibleplugin.py
+++ b/openlp/plugins/bibles/bibleplugin.py
@@ -55,9 +55,11 @@ class BiblePlugin(Plugin):
Plugin.initialise(self)
self.importBibleItem.setVisible(True)
action_list = ActionList.get_instance()
- action_list.add_action(self.importBibleItem, UiStrings().Import)
+ action_list.add_action(self.importBibleItem,
+ unicode(UiStrings().Import))
# Do not add the action to the list yet.
- #action_list.add_action(self.exportBibleItem, UiStrings().Export)
+ #action_list.add_action(self.exportBibleItem,
+ # unicode(UiStrings().Export))
# Set to invisible until we can export bibles
self.exportBibleItem.setVisible(False)
if len(self.manager.old_bible_databases):
@@ -71,7 +73,8 @@ class BiblePlugin(Plugin):
self.manager.finalise()
Plugin.finalise(self)
action_list = ActionList.get_instance()
- action_list.remove_action(self.importBibleItem, UiStrings().Import)
+ action_list.remove_action(self.importBibleItem,
+ unicode(UiStrings().Import))
self.importBibleItem.setVisible(False)
#action_list.remove_action(self.exportBibleItem, UiStrings().Export)
self.exportBibleItem.setVisible(False)
diff --git a/openlp/plugins/bibles/lib/csvbible.py b/openlp/plugins/bibles/lib/csvbible.py
index 6735a7344..55feae7d4 100644
--- a/openlp/plugins/bibles/lib/csvbible.py
+++ b/openlp/plugins/bibles/lib/csvbible.py
@@ -28,17 +28,7 @@
The :mod:`cvsbible` modules provides a facility to import bibles from a set of
CSV files.
-The module expects two mandatory files containing the books and the verses and
-will accept an optional third file containing the testaments.
-
-The format of the testament file is:
-
- ,
-
- For example:
-
- 1,Old Testament
- 2,New Testament
+The module expects two mandatory files containing the books and the verses.
The format of the books file is:
@@ -110,6 +100,9 @@ class CSVBible(BibleDB):
try:
details = get_file_encoding(self.booksfile)
books_file = open(self.booksfile, 'r')
+ if not books_file.read(3) == '\xEF\xBB\xBF':
+ # no BOM was found
+ books_file.seek(0)
books_reader = csv.reader(books_file, delimiter=',', quotechar='"')
for line in books_reader:
if self.stop_import_flag:
@@ -144,6 +137,9 @@ class CSVBible(BibleDB):
book_ptr = None
details = get_file_encoding(self.versesfile)
verse_file = open(self.versesfile, 'rb')
+ if not verse_file.read(3) == '\xEF\xBB\xBF':
+ # no BOM was found
+ verse_file.seek(0)
verse_reader = csv.reader(verse_file, delimiter=',', quotechar='"')
for line in verse_reader:
if self.stop_import_flag:
diff --git a/openlp/plugins/bibles/lib/osis.py b/openlp/plugins/bibles/lib/osis.py
index b802cda85..d4d797513 100644
--- a/openlp/plugins/bibles/lib/osis.py
+++ b/openlp/plugins/bibles/lib/osis.py
@@ -78,8 +78,7 @@ class OSISBible(BibleDB):
fbibles = open(filepath, u'r')
for line in fbibles:
book = line.split(u',')
- self.books[book[0]] = (book[1].lstrip().rstrip(),
- book[2].lstrip().rstrip())
+ self.books[book[0]] = (book[1].strip(), book[2].strip())
except IOError:
log.exception(u'OSIS bible import failed')
finally:
diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py
index 049e2da18..b1e815a3a 100644
--- a/openlp/plugins/images/lib/mediaitem.py
+++ b/openlp/plugins/images/lib/mediaitem.py
@@ -127,13 +127,13 @@ class ImageMediaItem(MediaManagerItem):
self.plugin.formparent.incrementProgressBar()
filename = os.path.split(unicode(imageFile))[1]
thumb = os.path.join(self.servicePath, filename)
- if not os.path.exists(imageFile):
+ if not os.path.exists(unicode(imageFile)):
icon = build_icon(u':/general/general_delete.png')
else:
- if validate_thumb(imageFile, thumb):
+ if validate_thumb(unicode(imageFile), thumb):
icon = build_icon(thumb)
else:
- icon = create_thumb(imageFile, thumb)
+ icon = create_thumb(unicode(imageFile), thumb)
item_name = QtGui.QListWidgetItem(filename)
item_name.setIcon(icon)
item_name.setToolTip(imageFile)
diff --git a/openlp/plugins/presentations/lib/impresscontroller.py b/openlp/plugins/presentations/lib/impresscontroller.py
index 36f684ad4..8355da5a8 100644
--- a/openlp/plugins/presentations/lib/impresscontroller.py
+++ b/openlp/plugins/presentations/lib/impresscontroller.py
@@ -184,7 +184,15 @@ class ImpressController(PresentationController):
if not desktop:
return
docs = desktop.getComponents()
+ cnt = 0
if docs.hasElements():
+ list = docs.createEnumeration()
+ while list.hasMoreElements():
+ doc = list.nextElement()
+ if doc.getImplementationName() != \
+ u'com.sun.star.comp.framework.BackingComp':
+ cnt = cnt + 1
+ if cnt > 0:
log.debug(u'OpenOffice not terminated as docs are still open')
else:
try:
diff --git a/openlp/plugins/presentations/lib/presentationcontroller.py b/openlp/plugins/presentations/lib/presentationcontroller.py
index a9d384c81..7ff04179f 100644
--- a/openlp/plugins/presentations/lib/presentationcontroller.py
+++ b/openlp/plugins/presentations/lib/presentationcontroller.py
@@ -378,7 +378,7 @@ class PresentationController(object):
self.name = name
self.document_class = document_class
self.settings_section = self.plugin.settingsSection
- self.available = self.check_available()
+ self.available = None
self.temp_folder = os.path.join(
AppLocation.get_section_data_path(self.settings_section), name)
self.thumbnail_folder = os.path.join(
@@ -392,14 +392,19 @@ class PresentationController(object):
"""
Return whether the controller is currently enabled
"""
- if self.available:
- return QtCore.QSettings().value(
- self.settings_section + u'/' + self.name,
- QtCore.QVariant(QtCore.Qt.Checked)).toInt()[0] == \
- QtCore.Qt.Checked
+ if QtCore.QSettings().value(
+ self.settings_section + u'/' + self.name,
+ QtCore.QVariant(QtCore.Qt.Checked)).toInt()[0] == \
+ QtCore.Qt.Checked:
+ return self.is_available()
else:
return False
+ def is_available(self):
+ if self.available is None:
+ self.available = self.check_available()
+ return self.available
+
def check_available(self):
"""
Presentation app is able to run on this machine
diff --git a/openlp/plugins/presentations/lib/presentationtab.py b/openlp/plugins/presentations/lib/presentationtab.py
index b0c3de7a8..c11f36c20 100644
--- a/openlp/plugins/presentations/lib/presentationtab.py
+++ b/openlp/plugins/presentations/lib/presentationtab.py
@@ -55,7 +55,6 @@ class PresentationTab(SettingsTab):
for key in self.controllers:
controller = self.controllers[key]
checkbox = QtGui.QCheckBox(self.ControllersGroupBox)
- checkbox.setEnabled(controller.available)
checkbox.setObjectName(controller.name + u'CheckBox')
self.PresenterCheckboxes[controller.name] = checkbox
self.ControllersLayout.addWidget(checkbox)
@@ -81,17 +80,20 @@ class PresentationTab(SettingsTab):
for key in self.controllers:
controller = self.controllers[key]
checkbox = self.PresenterCheckboxes[controller.name]
- if controller.available:
- checkbox.setText(controller.name)
- else:
- checkbox.setText(
- unicode(translate('PresentationPlugin.PresentationTab',
- '%s (unavailable)')) % controller.name)
+ self.setControllerText(checkbox, controller)
self.AdvancedGroupBox.setTitle(UiStrings().Advanced)
self.OverrideAppCheckBox.setText(
translate('PresentationPlugin.PresentationTab',
'Allow presentation application to be overriden'))
+ def setControllerText(self, checkbox, controller):
+ if checkbox.isEnabled():
+ checkbox.setText(controller.name)
+ else:
+ checkbox.setText(
+ unicode(translate('PresentationPlugin.PresentationTab',
+ '%s (unavailable)')) % controller.name)
+
def load(self):
"""
Load the settings.
@@ -113,7 +115,7 @@ class PresentationTab(SettingsTab):
changed = False
for key in self.controllers:
controller = self.controllers[key]
- if controller.available:
+ if controller.is_available():
checkbox = self.PresenterCheckboxes[controller.name]
setting_key = self.settingsSection + u'/' + controller.name
if QtCore.QSettings().value(setting_key) != \
@@ -133,3 +135,13 @@ class PresentationTab(SettingsTab):
changed = True
if changed:
Receiver.send_message(u'mediaitem_presentation_rebuild')
+
+ def tabVisible(self):
+ """
+ Tab has just been made visible to the user
+ """
+ for key in self.controllers:
+ controller = self.controllers[key]
+ checkbox = self.PresenterCheckboxes[controller.name]
+ checkbox.setEnabled(controller.is_available())
+ self.setControllerText(checkbox, controller)
diff --git a/openlp/plugins/songs/forms/songexportform.py b/openlp/plugins/songs/forms/songexportform.py
index 22020a401..20a52c82d 100644
--- a/openlp/plugins/songs/forms/songexportform.py
+++ b/openlp/plugins/songs/forms/songexportform.py
@@ -252,6 +252,9 @@ class SongExportForm(OpenLPWizard):
songs = self.plugin.manager.get_all_objects(Song)
songs.sort(cmp=locale.strcoll, key=lambda song: song.title.lower())
for song in songs:
+ # No need to export temporary songs.
+ if song.temporary:
+ continue
authors = u', '.join([author.display_name
for author in song.authors])
title = u'%s (%s)' % (unicode(song.title), authors)
diff --git a/openlp/plugins/songs/forms/songimportform.py b/openlp/plugins/songs/forms/songimportform.py
index b79e56f7b..53e70cde6 100644
--- a/openlp/plugins/songs/forms/songimportform.py
+++ b/openlp/plugins/songs/forms/songimportform.py
@@ -191,32 +191,32 @@ class SongImportForm(OpenLPWizard):
QtGui.QSizePolicy.Expanding)
self.formatStack = QtGui.QStackedLayout()
self.formatStack.setObjectName(u'FormatStack')
+ # OpenLyrics
+ self.addFileSelectItem(u'openLyrics', u'OpenLyrics', True)
# OpenLP 2.0
self.addFileSelectItem(u'openLP2', single_select=True)
# openlp.org 1.x
self.addFileSelectItem(u'openLP1', None, True, True)
- # OpenLyrics
- self.addFileSelectItem(u'openLyrics', u'OpenLyrics', True)
- # Open Song
- self.addFileSelectItem(u'openSong', u'OpenSong')
- # Words of Worship
- self.addFileSelectItem(u'wordsOfWorship')
- # CCLI File import
- self.addFileSelectItem(u'ccli')
- # Songs of Fellowship
- self.addFileSelectItem(u'songsOfFellowship', None, True)
# Generic Document/Presentation import
self.addFileSelectItem(u'generic', None, True)
- # EasySlides
+ # CCLI File import
+ self.addFileSelectItem(u'ccli')
+ # EasiSlides
self.addFileSelectItem(u'easiSlides', single_select=True)
# EasyWorship
self.addFileSelectItem(u'ew', single_select=True)
- # Words of Worship
+ # Foilpresenter
+ self.addFileSelectItem(u'foilPresenter')
+ # Open Song
+ self.addFileSelectItem(u'openSong', u'OpenSong')
+ # SongBeamer
self.addFileSelectItem(u'songBeamer')
# Song Show Plus
self.addFileSelectItem(u'songShowPlus')
- # Foilpresenter
- self.addFileSelectItem(u'foilPresenter')
+ # Songs of Fellowship
+ self.addFileSelectItem(u'songsOfFellowship', None, True)
+ # Words of Worship
+ self.addFileSelectItem(u'wordsOfWorship')
# Commented out for future use.
# self.addFileSelectItem(u'csv', u'CSV', single_select=True)
self.sourceLayout.addLayout(self.formatStack)
@@ -238,30 +238,30 @@ class SongImportForm(OpenLPWizard):
self.sourcePage.setTitle(WizardStrings.ImportSelect)
self.sourcePage.setSubTitle(WizardStrings.ImportSelectLong)
self.formatLabel.setText(WizardStrings.FormatLabel)
- self.formatComboBox.setItemText(SongFormat.OpenLP2, UiStrings().OLPV2)
- self.formatComboBox.setItemText(SongFormat.OpenLP1, UiStrings().OLPV1)
self.formatComboBox.setItemText(SongFormat.OpenLyrics,
translate('SongsPlugin.ImportWizardForm',
'OpenLyrics or OpenLP 2.0 Exported Song'))
- self.formatComboBox.setItemText(SongFormat.OpenSong, WizardStrings.OS)
- self.formatComboBox.setItemText(
- SongFormat.WordsOfWorship, WizardStrings.WoW)
- self.formatComboBox.setItemText(SongFormat.CCLI, WizardStrings.CCLI)
- self.formatComboBox.setItemText(
- SongFormat.SongsOfFellowship, WizardStrings.SoF)
+ self.formatComboBox.setItemText(SongFormat.OpenLP2, UiStrings().OLPV2)
+ self.formatComboBox.setItemText(SongFormat.OpenLP1, UiStrings().OLPV1)
self.formatComboBox.setItemText(SongFormat.Generic,
translate('SongsPlugin.ImportWizardForm',
'Generic Document/Presentation'))
+ self.formatComboBox.setItemText(SongFormat.CCLI, WizardStrings.CCLI)
self.formatComboBox.setItemText(
SongFormat.EasiSlides, WizardStrings.ES)
self.formatComboBox.setItemText(
SongFormat.EasyWorship, WizardStrings.EW)
+ self.formatComboBox.setItemText(
+ SongFormat.FoilPresenter, WizardStrings.FP)
+ self.formatComboBox.setItemText(SongFormat.OpenSong, WizardStrings.OS)
self.formatComboBox.setItemText(
SongFormat.SongBeamer, WizardStrings.SB)
self.formatComboBox.setItemText(
SongFormat.SongShowPlus, WizardStrings.SSP)
self.formatComboBox.setItemText(
- SongFormat.FoilPresenter, WizardStrings.FP)
+ SongFormat.SongsOfFellowship, WizardStrings.SoF)
+ self.formatComboBox.setItemText(
+ SongFormat.WordsOfWorship, WizardStrings.WoW)
# self.formatComboBox.setItemText(SongFormat.CSV, WizardStrings.CSV)
self.openLP2FilenameLabel.setText(
translate('SongsPlugin.ImportWizardForm', 'Filename:'))
@@ -359,6 +359,8 @@ class SongImportForm(OpenLPWizard):
return True
elif self.currentPage() == self.sourcePage:
source_format = self.formatComboBox.currentIndex()
+ QtCore.QSettings().setValue(u'songs/last import type',
+ source_format)
if source_format == SongFormat.OpenLP2:
if self.openLP2FilenameEdit.text().isEmpty():
critical_error_message_box(UiStrings().NFSs,
@@ -657,7 +659,12 @@ class SongImportForm(OpenLPWizard):
self.restart()
self.finishButton.setVisible(False)
self.cancelButton.setVisible(True)
- self.formatComboBox.setCurrentIndex(0)
+ last_import_type = QtCore.QSettings().value(
+ u'songs/last import type').toInt()[0]
+ if last_import_type < 0 or \
+ last_import_type >= self.formatComboBox.count():
+ last_import_type = 0
+ self.formatComboBox.setCurrentIndex(last_import_type)
self.openLP2FilenameEdit.setText(u'')
self.openLP1FilenameEdit.setText(u'')
self.openLyricsFileListWidget.clear()
diff --git a/openlp/plugins/songs/lib/cclifileimport.py b/openlp/plugins/songs/lib/cclifileimport.py
index 624256290..e9b1aa925 100644
--- a/openlp/plugins/songs/lib/cclifileimport.py
+++ b/openlp/plugins/songs/lib/cclifileimport.py
@@ -75,6 +75,9 @@ class CCLIFileImport(SongImport):
details = chardet.detect(detect_content)
detect_file.close()
infile = codecs.open(filename, u'r', details['encoding'])
+ if not infile.read(3) == '\xEF\xBB\xBF':
+ # not UTF or no BOM was found
+ infile.seek(0)
lines = infile.readlines()
infile.close()
ext = os.path.splitext(filename)[1]
diff --git a/openlp/plugins/songs/lib/db.py b/openlp/plugins/songs/lib/db.py
index 37ee42451..ce228e5f8 100644
--- a/openlp/plugins/songs/lib/db.py
+++ b/openlp/plugins/songs/lib/db.py
@@ -199,7 +199,8 @@ def init_schema(url):
Column(u'search_lyrics', types.UnicodeText, nullable=False),
Column(u'create_date', types.DateTime(), default=func.now()),
Column(u'last_modified', types.DateTime(), default=func.now(),
- onupdate=func.now())
+ onupdate=func.now()),
+ Column(u'temporary', types.Boolean(), default=False)
)
# Definition of the "topics" table
diff --git a/openlp/plugins/songs/lib/importer.py b/openlp/plugins/songs/lib/importer.py
index d8432f668..c24313be1 100644
--- a/openlp/plugins/songs/lib/importer.py
+++ b/openlp/plugins/songs/lib/importer.py
@@ -68,19 +68,19 @@ class SongFormat(object):
"""
_format_availability = {}
Unknown = -1
- OpenLP2 = 0
- OpenLP1 = 1
- OpenLyrics = 2
- OpenSong = 3
- WordsOfWorship = 4
- CCLI = 5
- SongsOfFellowship = 6
- Generic = 7
- EasiSlides = 8
- EasyWorship = 9
- SongBeamer = 10
- SongShowPlus = 11
- FoilPresenter = 12
+ OpenLyrics = 0
+ OpenLP2 = 1
+ OpenLP1 = 2
+ Generic = 3
+ CCLI = 4
+ EasiSlides = 5
+ EasyWorship = 6
+ FoilPresenter = 7
+ OpenSong = 8
+ SongBeamer = 9
+ SongShowPlus = 10
+ SongsOfFellowship = 11
+ WordsOfWorship = 12
#CSV = 13
@staticmethod
@@ -125,19 +125,19 @@ class SongFormat(object):
Return a list of the supported song formats.
"""
return [
+ SongFormat.OpenLyrics,
SongFormat.OpenLP2,
SongFormat.OpenLP1,
- SongFormat.OpenLyrics,
- SongFormat.OpenSong,
- SongFormat.WordsOfWorship,
- SongFormat.CCLI,
- SongFormat.SongsOfFellowship,
SongFormat.Generic,
+ SongFormat.CCLI,
SongFormat.EasiSlides,
- SongFormat.EasyWorship,
+ SongFormat.EasyWorship,
+ SongFormat.FoilPresenter,
+ SongFormat.OpenSong,
SongFormat.SongBeamer,
SongFormat.SongShowPlus,
- SongFormat.FoilPresenter
+ SongFormat.SongsOfFellowship,
+ SongFormat.WordsOfWorship
]
@staticmethod
diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py
index dad95c61b..052fb5b7b 100644
--- a/openlp/plugins/songs/lib/mediaitem.py
+++ b/openlp/plugins/songs/lib/mediaitem.py
@@ -270,6 +270,9 @@ class SongMediaItem(MediaManagerItem):
searchresults.sort(
cmp=locale.strcoll, key=lambda song: song.title.lower())
for song in searchresults:
+ # Do not display temporary songs
+ if song.temporary:
+ continue
author_list = [author.display_name for author in song.authors]
song_title = unicode(song.title)
song_detail = u'%s (%s)' % (song_title, u', '.join(author_list))
@@ -286,6 +289,9 @@ class SongMediaItem(MediaManagerItem):
self.listView.clear()
for author in searchresults:
for song in author.songs:
+ # Do not display temporary songs
+ if song.temporary:
+ continue
song_detail = u'%s (%s)' % (author.display_name, song.title)
song_name = QtGui.QListWidgetItem(song_detail)
song_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(song.id))
@@ -534,6 +540,7 @@ class SongMediaItem(MediaManagerItem):
Song.search_title.asc())
editId = 0
add_song = True
+ temporary = False
if search_results:
for song in search_results:
author_list = item.data_string[u'authors']
@@ -559,13 +566,18 @@ class SongMediaItem(MediaManagerItem):
self._updateBackgroundAudio(song, item)
editId = song.id
self.onSearchTextButtonClick()
- else:
+ elif add_song and not self.addSongFromService:
# Make sure we temporary import formatting tags.
- self.openLyrics.xml_to_song(item.xml_version, True)
+ song = self.openLyrics.xml_to_song(item.xml_version, True)
+ # If there's any backing tracks, copy them over.
+ if len(item.background_audio) > 0:
+ self._updateBackgroundAudio(song, item)
+ editId = song.id
+ temporary = True
# Update service with correct song id.
if editId:
Receiver.send_message(u'service_item_update',
- u'%s:%s' % (editId, item._uuid))
+ u'%s:%s:%s' % (editId, item._uuid, temporary))
def search(self, string):
"""
diff --git a/openlp/plugins/songs/lib/sofimport.py b/openlp/plugins/songs/lib/sofimport.py
index 4bb91f58a..7bd0a50d6 100644
--- a/openlp/plugins/songs/lib/sofimport.py
+++ b/openlp/plugins/songs/lib/sofimport.py
@@ -345,7 +345,8 @@ class SofImport(OooImport):
u'I\'M', u'I\'LL', u'SAVIOUR', u'O', u'YOU\'RE', u'HE', u'HIS',
u'HIM', u'ZION', u'EMMANUEL', u'MAJESTY', u'JESUS\'', u'JIREH',
u'JUDAH', u'LION', u'LORD\'S', u'ABRAHAM', u'GOD\'S',
- u'FATHER\'S', u'ELIJAH'):
+ u'FATHER\'S', u'ELIJAH' u'MARTHA', u'CHRISTMAS', u'ALPHA',
+ u'OMEGA'):
textarr[i] = textarr[i].capitalize()
else:
textarr[i] = textarr[i].lower()
diff --git a/openlp/plugins/songs/lib/upgrade.py b/openlp/plugins/songs/lib/upgrade.py
index f97fdff42..25f90e860 100644
--- a/openlp/plugins/songs/lib/upgrade.py
+++ b/openlp/plugins/songs/lib/upgrade.py
@@ -33,7 +33,9 @@ from sqlalchemy import Column, Table, types
from sqlalchemy.sql.expression import func
from migrate.changeset.constraint import ForeignKeyConstraint
-__version__ = 2
+from openlp.plugins.songs.lib.db import Song
+
+__version__ = 3
def upgrade_setup(metadata):
"""
@@ -86,3 +88,12 @@ def upgrade_2(session, metadata, tables):
Column(u'last_modified', types.DateTime(), default=func.now())\
.create(table=tables[u'songs'])
+def upgrade_3(session, metadata, tables):
+ """
+ Version 3 upgrade.
+
+ This upgrade adds a temporary song flag to the songs table
+ """
+ Column(u'temporary', types.Boolean(), default=False)\
+ .create(table=tables[u'songs'])
+
diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py
index aaf82b395..b16db7e94 100644
--- a/openlp/plugins/songs/lib/xml.py
+++ b/openlp/plugins/songs/lib/xml.py
@@ -346,7 +346,7 @@ class OpenLyrics(object):
lines_element.set(u'break', u'optional')
return self._extract_xml(song_xml)
- def xml_to_song(self, xml, parse_and_not_save=False):
+ def xml_to_song(self, xml, parse_and_temporary_save=False):
"""
Create and save a song from OpenLyrics format xml to the database. Since
we also export XML from external sources (e. g. OpenLyrics import), we
@@ -355,9 +355,9 @@ class OpenLyrics(object):
``xml``
The XML to parse (unicode).
- ``parse_and_not_save``
- Switch to skip processing the whole song and to prevent storing the
- songs to the database. Defaults to ``False``.
+ ``parse_and_temporary_save``
+ Switch to skip processing the whole song and storing the songs in
+ the database with a temporary flag. Defaults to ``False``.
"""
# No xml get out of here.
if not xml:
@@ -371,14 +371,13 @@ class OpenLyrics(object):
return None
# Formatting tags are new in OpenLyrics 0.8
if float(song_xml.get(u'version')) > 0.7:
- self._process_formatting_tags(song_xml, parse_and_not_save)
- if parse_and_not_save:
- return
+ self._process_formatting_tags(song_xml, parse_and_temporary_save)
song = Song()
# Values will be set when cleaning the song.
song.search_lyrics = u''
song.verse_order = u''
song.search_title = u''
+ song.temporary = parse_and_temporary_save
self._process_copyright(properties, song)
self._process_cclinumber(properties, song)
self._process_titles(properties, song)
diff --git a/openlp/plugins/songs/songsplugin.py b/openlp/plugins/songs/songsplugin.py
index a5f194f7b..5402ec1fa 100644
--- a/openlp/plugins/songs/songsplugin.py
+++ b/openlp/plugins/songs/songsplugin.py
@@ -74,9 +74,14 @@ class SongsPlugin(Plugin):
self.songExportItem.setVisible(True)
self.toolsReindexItem.setVisible(True)
action_list = ActionList.get_instance()
- action_list.add_action(self.songImportItem, UiStrings().Import)
- action_list.add_action(self.songExportItem, UiStrings().Export)
- action_list.add_action(self.toolsReindexItem, UiStrings().Tools)
+ action_list.add_action(self.songImportItem, unicode(UiStrings().Import))
+ action_list.add_action(self.songExportItem, unicode(UiStrings().Export))
+ action_list.add_action(self.toolsReindexItem,
+ unicode(UiStrings().Tools))
+ QtCore.QObject.connect(Receiver.get_receiver(),
+ QtCore.SIGNAL(u'servicemanager_new_service'),
+ self.clearTemporarySongs)
+
def addImportMenuItem(self, import_menu):
"""
@@ -264,12 +269,23 @@ class SongsPlugin(Plugin):
Time to tidy up on exit
"""
log.info(u'Songs Finalising')
+ self.clearTemporarySongs()
+ # Clean up files and connections
self.manager.finalise()
self.songImportItem.setVisible(False)
self.songExportItem.setVisible(False)
self.toolsReindexItem.setVisible(False)
action_list = ActionList.get_instance()
- action_list.remove_action(self.songImportItem, UiStrings().Import)
- action_list.remove_action(self.songExportItem, UiStrings().Export)
- action_list.remove_action(self.toolsReindexItem, UiStrings().Tools)
+ action_list.remove_action(self.songImportItem,
+ unicode(UiStrings().Import))
+ action_list.remove_action(self.songExportItem,
+ unicode(UiStrings().Export))
+ action_list.remove_action(self.toolsReindexItem,
+ unicode(UiStrings().Tools))
Plugin.finalise(self)
+
+ def clearTemporarySongs(self):
+ # Remove temporary songs
+ songs = self.manager.get_all_objects(Song, Song.temporary == True)
+ for song in songs:
+ self.manager.delete_object(Song, song.id)
diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py
index d09831052..29c5c4927 100644
--- a/openlp/plugins/songusage/songusageplugin.py
+++ b/openlp/plugins/songusage/songusageplugin.py
@@ -136,11 +136,11 @@ class SongUsagePlugin(Plugin):
self.setButtonState()
action_list = ActionList.get_instance()
action_list.add_action(self.songUsageStatus,
- translate('SongUsagePlugin', 'Song Usage'))
+ unicode(translate('SongUsagePlugin', 'Song Usage')))
action_list.add_action(self.songUsageDelete,
- translate('SongUsagePlugin', 'Song Usage'))
+ unicode(translate('SongUsagePlugin', 'Song Usage')))
action_list.add_action(self.songUsageReport,
- translate('SongUsagePlugin', 'Song Usage'))
+ unicode(translate('SongUsagePlugin', 'Song Usage')))
self.songUsageDeleteForm = SongUsageDeleteForm(self.manager,
self.formparent)
self.songUsageDetailForm = SongUsageDetailForm(self, self.formparent)
@@ -157,11 +157,11 @@ class SongUsagePlugin(Plugin):
self.songUsageMenu.menuAction().setVisible(False)
action_list = ActionList.get_instance()
action_list.remove_action(self.songUsageStatus,
- translate('SongUsagePlugin', 'Song Usage'))
+ unicode(translate('SongUsagePlugin', 'Song Usage')))
action_list.remove_action(self.songUsageDelete,
- translate('SongUsagePlugin', 'Song Usage'))
+ unicode(translate('SongUsagePlugin', 'Song Usage')))
action_list.remove_action(self.songUsageReport,
- translate('SongUsagePlugin', 'Song Usage'))
+ unicode(translate('SongUsagePlugin', 'Song Usage')))
self.songUsageActiveButton.hide()
# stop any events being processed
self.songUsageActive = False