This commit is contained in:
Andreas Preikschat 2011-12-18 09:20:02 +01:00
commit 42099861ce
66 changed files with 21834 additions and 7856 deletions

View File

@ -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'):

View File

@ -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)

View File

@ -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.

View File

@ -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)

View File

@ -113,10 +113,10 @@ sup {
document.getElementById('lyricsmain').style.visibility = lyrics;
document.getElementById('image').style.visibility = lyrics;
outline = document.getElementById('lyricsoutline')
if(outline!=null)
if(outline != null)
outline.style.visibility = lyrics;
shadow = document.getElementById('lyricsshadow')
if(shadow!=null)
if(shadow != null)
shadow.style.visibility = lyrics;
document.getElementById('footer').style.visibility = lyrics;
}
@ -129,10 +129,28 @@ sup {
var match = /-webkit-text-fill-color:[^;\"]+/gi;
if(timer != null)
clearTimeout(timer);
/*
QtWebkit bug with outlines and justify causing outline alignment
problems. (Bug 859950) Surround each word with a <span> to workaround,
but only in this scenario.
*/
var txt = document.getElementById('lyricsmain');
if(window.getComputedStyle(txt).textAlign == 'justify'){
var outline = document.getElementById('lyricsoutline');
if(outline != null)
txt = outline;
if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){
newtext = newtext.replace(/(\s|&nbsp;)+(?![^<]*>)/g,
function(match) {
return '</span>' + match + '<span>';
});
newtext = '<span>' + newtext + '</span>';
}
}
text_fade('lyricsmain', newtext);
text_fade('lyricsoutline', newtext);
text_fade('lyricsshadow', newtext.replace(match, ""));
if(text_opacity()==1) return;
text_fade('lyricsshadow', newtext.replace(match, ''));
if(text_opacity() == 1) return;
timer = setTimeout(function(){
show_text(newtext);
}, 100);
@ -149,18 +167,18 @@ sup {
slides) still looks pretty and is zippy.
*/
var text = document.getElementById(id);
if(text==null) return;
if(text == null) return;
if(!transition){
text.innerHTML = newtext;
return;
}
if(newtext==text.innerHTML){
if(newtext == text.innerHTML){
text.style.opacity = parseFloat(text.style.opacity) + 0.3;
if(text.style.opacity>0.7)
if(text.style.opacity > 0.7)
text.style.opacity = 1;
} else {
text.style.opacity = parseFloat(text.style.opacity) - 0.3;
if(text.style.opacity<=0.1){
if(text.style.opacity <= 0.1){
text.innerHTML = newtext;
}
}
@ -172,7 +190,7 @@ sup {
}
function show_text_complete(){
return (text_opacity()==1);
return (text_opacity() == 1);
}
</script>
</head>

View File

@ -91,8 +91,9 @@ class Plugin(QtCore.QObject):
``checkPreConditions()``
Provides the Plugin with a handle to check if it can be loaded.
``getMediaManagerItem()``
Returns an instance of MediaManagerItem to be used in the Media Manager.
``createMediaManagerItem()``
Creates a new instance of MediaManagerItem to be used in the Media
Manager.
``addImportMenuItem(import_menu)``
Add an item to the Import menu.
@ -100,8 +101,8 @@ class Plugin(QtCore.QObject):
``addExportMenuItem(export_menu)``
Add an item to the Export menu.
``getSettingsTab()``
Returns an instance of SettingsTabItem to be used in the Settings
``createSettingsTab()``
Creates a new instance of SettingsTabItem to be used in the Settings
dialog.
``addToMenu(menubar)``
@ -156,10 +157,10 @@ class Plugin(QtCore.QObject):
self.icon = None
self.media_item_class = media_item_class
self.settings_tab_class = settings_tab_class
self.settings_tab = None
self.mediaItem = None
self.weight = 0
self.status = PluginStatus.Inactive
# Set up logging
self.log = logging.getLogger(self.name)
self.previewController = plugin_helpers[u'preview']
self.liveController = plugin_helpers[u'live']
self.renderer = plugin_helpers[u'renderer']
@ -178,7 +179,7 @@ class Plugin(QtCore.QObject):
Provides the Plugin with a handle to check if it can be loaded.
Failing Preconditions does not stop a settings Tab being created
Returns True or False.
Returns ``True`` or ``False``.
"""
return True
@ -210,15 +211,14 @@ class Plugin(QtCore.QObject):
"""
return self.status == PluginStatus.Active
def getMediaManagerItem(self):
def createMediaManagerItem(self):
"""
Construct a MediaManagerItem object with all the buttons and things
you need, and return it for integration into openlp.org.
you need, and return it for integration into OpenLP.
"""
if self.media_item_class:
return self.media_item_class(self.mediadock.media_dock, self,
self.icon)
return None
self.mediaItem = self.media_item_class(self.mediadock.media_dock,
self, self.icon)
def addImportMenuItem(self, importMenu):
"""
@ -247,16 +247,15 @@ class Plugin(QtCore.QObject):
"""
pass
def getSettingsTab(self, parent):
def createSettingsTab(self, parent):
"""
Create a tab for the settings window to display the configurable
options for this plugin to the user.
Create a tab for the settings window to display the configurable options
for this plugin to the user.
"""
if self.settings_tab_class:
return self.settings_tab_class(parent, self.name,
self.settings_tab = self.settings_tab_class(parent, self.name,
self.getString(StringContent.VisibleName)[u'title'],
self.icon_path)
return None
def addToMenu(self, menubar):
"""

View File

@ -90,7 +90,7 @@ class PluginManager(object):
thisdepth = len(path.split(os.sep))
if thisdepth - startdepth > 2:
# skip anything lower down
continue
break
modulename = os.path.splitext(path)[0]
prefix = os.path.commonprefix([self.basepath, path])
# hack off the plugin base path
@ -113,7 +113,7 @@ class PluginManager(object):
plugin_objects.append(plugin)
except TypeError:
log.exception(u'Failed to load plugin %s', unicode(p))
plugins_list = sorted(plugin_objects, self.order_by_weight)
plugins_list = sorted(plugin_objects, key=lambda plugin: plugin.weight)
for plugin in plugins_list:
if plugin.checkPreConditions():
log.debug(u'Plugin %s active', unicode(plugin.name))
@ -122,29 +122,13 @@ class PluginManager(object):
plugin.status = PluginStatus.Disabled
self.plugins.append(plugin)
def order_by_weight(self, x, y):
def hook_media_manager(self):
"""
Sort two plugins and order them by their weight.
``x``
The first plugin.
``y``
The second plugin.
"""
return cmp(x.weight, y.weight)
def hook_media_manager(self, mediadock):
"""
Loop through all the plugins. If a plugin has a valid media manager
item, add it to the media manager.
``mediatoolbox``
The Media Manager itself.
Create the plugins' media manager items.
"""
for plugin in self.plugins:
if plugin.status is not PluginStatus.Disabled:
plugin.mediaItem = plugin.getMediaManagerItem()
plugin.createMediaManagerItem()
def hook_settings_tabs(self, settings_form=None):
"""
@ -152,14 +136,12 @@ class PluginManager(object):
item, add it to the settings tab.
Tabs are set for all plugins not just Active ones
``settingsform``
``settings_form``
Defaults to *None*. The settings form to add tabs to.
"""
for plugin in self.plugins:
if plugin.status is not PluginStatus.Disabled:
plugin.settings_tab = plugin.getSettingsTab(settings_form)
else:
plugin.settings_tab = None
plugin.createSettingsTab(settings_form)
settings_form.plugins = self.plugins
def hook_import_menu(self, import_menu):
@ -225,7 +207,7 @@ class PluginManager(object):
def get_plugin_by_name(self, name):
"""
Return the plugin which has a name with value ``name``
Return the plugin which has a name with value ``name``.
"""
for plugin in self.plugins:
if plugin.name == name:

View File

@ -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

View File

@ -125,3 +125,9 @@ class SettingsTab(QtGui.QWidget):
"""
pass
def tabVisible(self):
"""
Tab has just been made visible to the user
"""
pass

View File

@ -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)

View File

@ -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,
@ -655,7 +666,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.pluginManager.hook_settings_tabs(self.settingsForm)
# Find and insert media manager items
log.info(u'hook media')
self.pluginManager.hook_media_manager(self.mediaDockManager)
self.pluginManager.hook_media_manager()
# Call the hook method to pull in import menus.
log.info(u'hook menus')
self.pluginManager.hook_import_menu(self.fileImportMenu)
@ -720,7 +731,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
args = []
for a in self.arguments:
args.extend([a])
self.serviceManagerContents.loadFile(unicode(args[0]))
filename = args[0]
if not isinstance(filename, unicode):
filename = unicode(filename, sys.getfilesystemencoding())
self.serviceManagerContents.loadFile(filename)
elif QtCore.QSettings().value(
self.generalSettingsSection + u'/auto open',
QtCore.QVariant(False)).toBool():
@ -1312,7 +1326,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
settings.value(u'preview splitter geometry').toByteArray())
self.controlSplitter.restoreState(
settings.value(u'mainwindow splitter geometry').toByteArray())
settings.endGroup()
def saveSettings(self):
@ -1388,6 +1401,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
maxRecentFiles = QtCore.QSettings().value(u'advanced/max recent files',
QtCore.QVariant(20)).toInt()[0]
if filename:
# Add some cleanup to reduce duplication in the recent file list
filename = os.path.abspath(filename)
# abspath() only capitalises the drive letter if it wasn't provided
# in the given filename which then causes duplication.
if filename[1:3] == ':\\':
filename = filename[0].upper() + filename[1:]
position = self.recentFiles.indexOf(filename)
if position != -1:
self.recentFiles.removeAt(position)

View File

@ -311,8 +311,13 @@ class MediaController(object):
isValid = self.check_file_type(controller, display)
display.override[u'theme'] = u''
display.override[u'video'] = True
controller.media_info.start_time = display.serviceItem.start_time
controller.media_info.end_time = display.serviceItem.end_time
if controller.media_info.is_background:
# ignore start/end time
controller.media_info.start_time = 0
controller.media_info.end_time = 0
else:
controller.media_info.start_time = display.serviceItem.start_time
controller.media_info.end_time = display.serviceItem.end_time
elif controller.previewDisplay:
display = controller.previewDisplay
isValid = self.check_file_type(controller, display)

View File

@ -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'<strong>%s:</strong> <em>%s</em>' %
(unicode(translate('OpenLP.ServiceManager', 'Edit')),
(unicode(translate('OpenLP.ServiceManager',
'Service copy only')))))
if serviceitem.theme and serviceitem.theme != -1:
tips.append(u'<strong>%s:</strong> <em>%s</em>' %
(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):
"""

View File

@ -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',

View File

@ -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()

View File

@ -344,8 +344,11 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
if category.name is None:
continue
for action in category.actions:
if self.changedActions .has_key(action):
if action in self.changedActions:
old_shortcuts = map(unicode,
map(QtGui.QKeySequence.toString, action.shortcuts()))
action.setShortcuts(self.changedActions[action])
self.action_list.update_shortcut_map(action, old_shortcuts)
settings.setValue(
action.objectName(), QtCore.QVariant(action.shortcuts()))
settings.endGroup()
@ -452,7 +455,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
those shortcuts which are not saved yet but already assigned (as changes
are applied when closing the dialog).
"""
if self.changedActions.has_key(action):
if action in self.changedActions:
return self.changedActions[action]
return action.shortcuts()

View File

@ -95,7 +95,7 @@ class SlideController(Controller):
u'Edit Song',
]
self.nextPreviousList = [
u'Previous Slide',
u'Previous Slide',
u'Next Slide'
]
self.timer_id = 0
@ -114,8 +114,8 @@ class SlideController(Controller):
self.typeLabel.setText(UiStrings().Live)
self.split = 1
self.typePrefix = u'live'
self.keypress_queue = deque()
self.keypress_loop = False
self.keypress_queue = deque()
self.keypress_loop = False
else:
self.typeLabel.setText(UiStrings().Preview)
self.split = 0
@ -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"'))
@ -408,6 +412,9 @@ class SlideController(Controller):
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_live_spin_delay'),
self.receiveSpinDelay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'slidecontroller_toggle_display'),
self.toggleDisplay)
self.toolbar.makeWidgetsInvisible(self.loopList)
else:
QtCore.QObject.connect(self.previewListWidget,
@ -540,24 +547,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'))
@ -566,6 +573,21 @@ class SlideController(Controller):
self.display.setVisible(False)
self.mediaController.video_stop([self])
def toggleDisplay(self, action):
"""
Toggle the display settings triggered from remote messages.
"""
if action == u'blank' or action == u'hide':
self.onBlankDisplay(True)
elif action == u'theme':
self.onThemeDisplay(True)
elif action == u'desktop':
self.onHideDisplay(True)
elif action == u'show':
self.onBlankDisplay(False)
self.onThemeDisplay(False)
self.onHideDisplay(False)
def servicePrevious(self):
"""
Live event to select the previous service item from the service manager.
@ -614,8 +636,8 @@ class SlideController(Controller):
self.previewSizeChanged()
self.previewDisplay.setup()
serviceItem = ServiceItem()
self.previewDisplay.webView.setHtml(build_html(serviceItem,
self.previewDisplay.screen, None, self.isLive, None,
self.previewDisplay.webView.setHtml(build_html(serviceItem,
self.previewDisplay.screen, None, self.isLive, None,
plugins=PluginManager.get_instance().plugins))
self.mediaController.setup_display(self.previewDisplay)
if self.serviceItem:

View File

@ -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')

View File

@ -218,8 +218,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()
@ -236,15 +234,19 @@ class ActionList(object):
if not shortcuts:
action.setShortcuts([])
return
shortcuts = map(unicode, shortcuts)
# We have to do this to ensure that the loaded shortcut list e. g.
# STRG+O (German) is converted to CTRL+O, which is only done when we
# convert the strings in this way (QKeySequence -> QString -> unicode).
shortcuts = map(QtGui.QKeySequence, shortcuts)
shortcuts = map(unicode, map(QtGui.QKeySequence.toString, shortcuts))
# Check the alternate shortcut first, to avoid problems when the
# alternate shortcut becomes the primary shortcut after removing the
# (initial) primary shortcut due to confllicts.
# (initial) primary shortcut due to conflicts.
if len(shortcuts) == 2:
existing_actions = ActionList.shortcut_map.get(shortcuts[1], [])
# Check for conflicts with other actions considering the shortcut
# context.
if self._shortcut_available(existing_actions, action):
if self._is_shortcut_available(existing_actions, action):
actions = ActionList.shortcut_map.get(shortcuts[1], [])
actions.append(action)
ActionList.shortcut_map[shortcuts[1]] = actions
@ -254,7 +256,7 @@ class ActionList(object):
existing_actions = ActionList.shortcut_map.get(shortcuts[0], [])
# Check for conflicts with other actions considering the shortcut
# context.
if self._shortcut_available(existing_actions, action):
if self._is_shortcut_available(existing_actions, action):
actions = ActionList.shortcut_map.get(shortcuts[0], [])
actions.append(action)
ActionList.shortcut_map[shortcuts[0]] = actions
@ -275,14 +277,21 @@ 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)
# Remove empty categories.
if len(self.categories[category].actions) == 0:
self.categories.remove(category)
shortcuts = map(unicode,
map(QtGui.QKeySequence.toString, action.shortcuts()))
for shortcut in shortcuts:
# Remove action from the list of actions which are using this
# shortcut.
ActionList.shortcut_map[shortcut].remove(action)
# Remove empty entries.
if not ActionList.shortcut_map[shortcut]:
del ActionList.shortcut_map[shortcut]
def add_category(self, name, weight):
"""
@ -304,7 +313,37 @@ class ActionList(object):
return
self.categories.add(name, weight)
def _shortcut_available(self, existing_actions, action):
def update_shortcut_map(self, action, old_shortcuts):
"""
Remove the action for the given ``old_shortcuts`` from the
``shortcut_map`` to ensure its up-to-dateness.
**Note**: The new action's shortcuts **must** be assigned to the given
``action`` **before** calling this method.
``action``
The action whose shortcuts are supposed to be updated in the
``shortcut_map``.
``old_shortcuts``
A list of unicode keysequences.
"""
for old_shortcut in old_shortcuts:
# Remove action from the list of actions which are using this
# shortcut.
ActionList.shortcut_map[old_shortcut].remove(action)
# Remove empty entries.
if not ActionList.shortcut_map[old_shortcut]:
del ActionList.shortcut_map[old_shortcut]
new_shortcuts = map(unicode,
map(QtGui.QKeySequence.toString, action.shortcuts()))
# Add the new shortcuts to the map.
for new_shortcut in new_shortcuts:
existing_actions = ActionList.shortcut_map.get(new_shortcut, [])
existing_actions.append(action)
ActionList.shortcut_map[new_shortcut] = existing_actions
def _is_shortcut_available(self, existing_actions, action):
"""
Checks if the given ``action`` may use its assigned shortcut(s) or not.
Returns ``True`` or ``False.

View File

@ -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):
"""

View File

@ -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)

View File

@ -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:
<testament_id>,<testament_name>
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:

View File

@ -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:

View File

@ -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)

View File

@ -54,7 +54,7 @@ class MediaMediaItem(MediaManagerItem):
self.iconPath = u'images/image'
self.background = False
self.previewFunction = CLAPPERBOARD
self.Automatic = u''
self.automatic = u''
MediaManagerItem.__init__(self, parent, plugin, icon)
self.singleServiceItem = False
self.hasSearch = True
@ -101,7 +101,7 @@ class MediaMediaItem(MediaManagerItem):
self.replaceAction.setToolTip(UiStrings().ReplaceLiveBG)
self.resetAction.setText(UiStrings().ResetBG)
self.resetAction.setToolTip(UiStrings().ResetLiveBG)
self.Automatic = translate('MediaPlugin.MediaItem',
self.automatic = translate('MediaPlugin.MediaItem',
'Automatic')
self.displayTypeLabel.setText(
translate('MediaPlugin.MediaItem', 'Use Player:'))
@ -253,7 +253,7 @@ class MediaMediaItem(MediaManagerItem):
# load the drop down selection
self.displayTypeComboBox.addItem(title)
if self.displayTypeComboBox.count() > 1:
self.displayTypeComboBox.insertItem(0, self.Automatic)
self.displayTypeComboBox.insertItem(0, self.automatic)
self.displayTypeComboBox.setCurrentIndex(0)
if QtCore.QSettings().value(self.settingsSection + u'/override player',
QtCore.QVariant(QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:

View File

@ -35,7 +35,7 @@ class MediaTab(SettingsTab):
MediaTab is the Media settings tab in the settings dialog.
"""
def __init__(self, parent, title, visible_title, media_players, icon_path):
self.media_players = media_players
self.mediaPlayers = media_players
SettingsTab.__init__(self, parent, title, visible_title, icon_path)
def setupUi(self):
@ -45,13 +45,13 @@ class MediaTab(SettingsTab):
self.mediaPlayerGroupBox.setObjectName(u'mediaPlayerGroupBox')
self.mediaPlayerLayout = QtGui.QVBoxLayout(self.mediaPlayerGroupBox)
self.mediaPlayerLayout.setObjectName(u'mediaPlayerLayout')
self.PlayerCheckBoxes = {}
for key in self.media_players:
player = self.media_players[key]
self.playerCheckBoxes = {}
for key, player in self.mediaPlayers.iteritems():
player = self.mediaPlayers[key]
checkbox = QtGui.QCheckBox(self.mediaPlayerGroupBox)
checkbox.setEnabled(player.available)
checkbox.setObjectName(player.name + u'CheckBox')
self.PlayerCheckBoxes[player.name] = checkbox
self.playerCheckBoxes[player.name] = checkbox
self.mediaPlayerLayout.addWidget(checkbox)
self.leftLayout.addWidget(self.mediaPlayerGroupBox)
self.playerOrderGroupBox = QtGui.QGroupBox(self.leftColumn)
@ -88,19 +88,19 @@ class MediaTab(SettingsTab):
self.orderingButtonLayout.addWidget(self.orderingUpButton)
self.playerOrderLayout.addWidget(self.orderingButtonsWidget)
self.leftLayout.addWidget(self.playerOrderGroupBox)
self.AdvancedGroupBox = QtGui.QGroupBox(self.leftColumn)
self.AdvancedGroupBox.setObjectName(u'AdvancedGroupBox')
self.AdvancedLayout = QtGui.QVBoxLayout(self.AdvancedGroupBox)
self.AdvancedLayout.setObjectName(u'AdvancedLayout')
self.OverridePlayerCheckBox = QtGui.QCheckBox(self.AdvancedGroupBox)
self.OverridePlayerCheckBox.setObjectName(u'OverridePlayerCheckBox')
self.AdvancedLayout.addWidget(self.OverridePlayerCheckBox)
self.leftLayout.addWidget(self.AdvancedGroupBox)
self.advancedGroupBox = QtGui.QGroupBox(self.leftColumn)
self.advancedGroupBox.setObjectName(u'advancedGroupBox')
self.advancedLayout = QtGui.QVBoxLayout(self.advancedGroupBox)
self.advancedLayout.setObjectName(u'advancedLayout')
self.overridePlayerCheckBox = QtGui.QCheckBox(self.advancedGroupBox)
self.overridePlayerCheckBox.setObjectName(u'overridePlayerCheckBox')
self.advancedLayout.addWidget(self.overridePlayerCheckBox)
self.leftLayout.addWidget(self.advancedGroupBox)
self.leftLayout.addStretch()
self.rightLayout.addStretch()
for key in self.media_players:
player = self.media_players[key]
checkbox = self.PlayerCheckBoxes[player.name]
for key in self.mediaPlayers:
player = self.mediaPlayers[key]
checkbox = self.playerCheckBoxes[player.name]
QtCore.QObject.connect(checkbox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onPlayerCheckBoxChanged)
@ -112,9 +112,9 @@ class MediaTab(SettingsTab):
def retranslateUi(self):
self.mediaPlayerGroupBox.setTitle(
translate('MediaPlugin.MediaTab', 'Available Media Players'))
for key in self.media_players:
player = self.media_players[key]
checkbox = self.PlayerCheckBoxes[player.name]
for key in self.mediaPlayers:
player = self.mediaPlayers[key]
checkbox = self.playerCheckBoxes[player.name]
if player.available:
checkbox.setText(player.name)
else:
@ -127,8 +127,8 @@ class MediaTab(SettingsTab):
translate('MediaPlugin.MediaTab', 'Down'))
self.orderingUpButton.setText(
translate('MediaPlugin.MediaTab', 'Up'))
self.AdvancedGroupBox.setTitle(UiStrings().Advanced)
self.OverridePlayerCheckBox.setText(
self.advancedGroupBox.setTitle(UiStrings().Advanced)
self.overridePlayerCheckBox.setText(
translate('MediaPlugin.MediaTab',
'Allow media player to be overriden'))
@ -144,12 +144,12 @@ class MediaTab(SettingsTab):
def updatePlayerList(self):
self.playerOrderlistWidget.clear()
for player in self.usedPlayers:
if player in self.PlayerCheckBoxes.keys():
if player in self.playerCheckBoxes.keys():
if len(self.usedPlayers) == 1:
# at least one media player have to stay active
self.PlayerCheckBoxes[u'%s' % player].setEnabled(False)
self.playerCheckBoxes[u'%s' % player].setEnabled(False)
else:
self.PlayerCheckBoxes[u'%s' % player].setEnabled(True)
self.playerCheckBoxes[u'%s' % player].setEnabled(True)
self.playerOrderlistWidget.addItem(player)
def onOrderingUpButtonPressed(self):
@ -172,34 +172,34 @@ class MediaTab(SettingsTab):
self.usedPlayers = QtCore.QSettings().value(
self.settingsSection + u'/players',
QtCore.QVariant(u'webkit')).toString().split(u',')
for key in self.media_players:
player = self.media_players[key]
checkbox = self.PlayerCheckBoxes[player.name]
for key in self.mediaPlayers:
player = self.mediaPlayers[key]
checkbox = self.playerCheckBoxes[player.name]
if player.available and player.name in self.usedPlayers:
checkbox.setChecked(True)
self.updatePlayerList()
self.OverridePlayerCheckBox.setChecked(QtCore.QSettings().value(
self.overridePlayerCheckBox.setChecked(QtCore.QSettings().value(
self.settingsSection + u'/override player',
QtCore.QVariant(QtCore.Qt.Unchecked)).toInt()[0])
def save(self):
override_changed = False
player_string_changed = False
oldPlayerString = QtCore.QSettings().value(
old_players = QtCore.QSettings().value(
self.settingsSection + u'/players',
QtCore.QVariant(u'webkit')).toString()
newPlayerString = self.usedPlayers.join(u',')
if oldPlayerString != newPlayerString:
new_players = self.usedPlayers.join(u',')
if old_players != new_players:
# clean old Media stuff
QtCore.QSettings().setValue(self.settingsSection + u'/players',
QtCore.QVariant(newPlayerString))
QtCore.QVariant(new_players))
player_string_changed = True
override_changed = True
setting_key = self.settingsSection + u'/override player'
if QtCore.QSettings().value(setting_key) != \
self.OverridePlayerCheckBox.checkState():
self.overridePlayerCheckBox.checkState():
QtCore.QSettings().setValue(setting_key,
QtCore.QVariant(self.OverridePlayerCheckBox.checkState()))
QtCore.QVariant(self.overridePlayerCheckBox.checkState()))
override_changed = True
if override_changed:
Receiver.send_message(u'mediaitem_media_rebuild')

View File

@ -27,6 +27,8 @@
import logging
from PyQt4 import QtCore
from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.plugins.media.lib import MediaMediaItem, MediaTab
@ -52,12 +54,12 @@ class MediaPlugin(Plugin):
for ext in self.video_extensions_list:
self.serviceManager.supportedSuffixes(ext[2:])
def getSettingsTab(self, parent):
def createSettingsTab(self, parent):
"""
Create the settings Tab
"""
visible_name = self.getString(StringContent.VisibleName)
return MediaTab(parent, self.name, visible_name[u'title'],
self.settings_tab = MediaTab(parent, self.name, visible_name[u'title'],
self.mediaController.mediaPlayers, self.icon_path)
def about(self):
@ -117,3 +119,29 @@ class MediaPlugin(Plugin):
Add html code to htmlbuilder
"""
return self.mediaController.get_media_display_html()
def appStartup(self):
"""
Do a couple of things when the app starts up. In this particular case
we want to check if we have the old "Use Phonon" setting, and convert
it to "enable Phonon" and "make it the first one in the list".
"""
settings = QtCore.QSettings()
settings.beginGroup(self.settingsSection)
if settings.contains(u'use phonon'):
log.info(u'Found old Phonon setting')
players = self.mediaController.mediaPlayers.keys()
has_phonon = u'phonon' in players
if settings.value(u'use phonon').toBool() and has_phonon:
log.debug(u'Converting old setting to new setting')
new_players = []
if players:
new_players = [player for player in players \
if player != u'phonon']
new_players.insert(0, u'phonon')
self.mediaController.mediaPlayers[u'phonon'].isActive = True
settings.setValue(u'players', \
QtCore.QVariant(u','.join(new_players)))
self.settings_tab.load()
settings.remove(u'use phonon')
settings.endGroup()

View File

@ -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:

View File

@ -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

View File

@ -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)

View File

@ -57,13 +57,13 @@ class PresentationPlugin(Plugin):
self.icon_path = u':/plugins/plugin_presentations.png'
self.icon = build_icon(self.icon_path)
def getSettingsTab(self, parent):
def createSettingsTab(self, parent):
"""
Create the settings Tab
"""
visible_name = self.getString(StringContent.VisibleName)
return PresentationTab(parent, self.name, visible_name[u'title'],
self.controllers, self.icon_path)
self.settings_tab = PresentationTab(parent, self.name,
visible_name[u'title'], self.controllers, self.icon_path)
def initialise(self):
"""
@ -94,11 +94,11 @@ class PresentationPlugin(Plugin):
controller.kill()
Plugin.finalise(self)
def getMediaManagerItem(self):
def createMediaManagerItem(self):
"""
Create the Media Manager List
"""
return PresentationMediaItem(
self.mediaItem = PresentationMediaItem(
self.mediadock.media_dock, self, self.icon, self.controllers)
def registerControllers(self, controller):

View File

@ -249,7 +249,7 @@ class HttpConnection(object):
(r'^/api/poll$', self.poll),
(r'^/api/controller/(live|preview)/(.*)$', self.controller),
(r'^/api/service/(.*)$', self.service),
(r'^/api/display/(hide|show)$', self.display),
(r'^/api/display/(hide|show|blank|theme|desktop)$', self.display),
(r'^/api/alert$', self.alert),
(r'^/api/plugin/(search)$', self.pluginInfo),
(r'^/api/(.*)/search$', self.search),
@ -315,7 +315,9 @@ class HttpConnection(object):
"""
log.debug(u'ready to read socket')
if self.socket.canReadLine():
data = unicode(self.socket.readLine()).encode(u'utf-8')
data = self.socket.readLine()
data = QtCore.QByteArray.fromPercentEncoding(data)
data = unicode(data, 'utf8')
log.debug(u'received: ' + data)
words = data.split(u' ')
response = None
@ -399,7 +401,13 @@ class HttpConnection(object):
u'item': self.parent.current_item._uuid \
if self.parent.current_item else u'',
u'twelve':QtCore.QSettings().value(
u'remotes/twelve hour', QtCore.QVariant(True)).toBool()
u'remotes/twelve hour', QtCore.QVariant(True)).toBool(),
u'blank': self.parent.plugin.liveController.blankScreen.\
isChecked(),
u'theme': self.parent.plugin.liveController.themeScreen.\
isChecked(),
u'display': self.parent.plugin.liveController.desktopScreen.\
isChecked()
}
return HttpResponse(json.dumps({u'results': result}),
{u'Content-Type': u'application/json'})
@ -411,8 +419,7 @@ class HttpConnection(object):
``action``
This is the action, either ``hide`` or ``show``.
"""
event = u'live_display_%s' % action
Receiver.send_message(event, HideMode.Blank)
Receiver.send_message(u'slidecontroller_toggle_display', action)
return HttpResponse(json.dumps({u'results': {u'success': True}}),
{u'Content-Type': u'application/json'})

View File

@ -181,7 +181,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
plugin.status == PluginStatus.Active:
self.audioAddFromMediaButton.setVisible(True)
self.mediaForm.populateFiles(
plugin.getMediaManagerItem().getList(MediaType.Audio))
plugin.mediaItem.getList(MediaType.Audio))
break
def newSong(self):

View File

@ -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)

View File

@ -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()

View File

@ -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]

View File

@ -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

View File

@ -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

View File

@ -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):
"""

View File

@ -30,7 +30,7 @@ song databases into the current installation database.
"""
import logging
from sqlalchemy import create_engine, MetaData
from sqlalchemy import create_engine, MetaData, Table
from sqlalchemy.orm import class_mapper, mapper, relation, scoped_session, \
sessionmaker
from sqlalchemy.orm.exc import UnmappedClassError
@ -44,41 +44,6 @@ from songimport import SongImport
log = logging.getLogger(__name__)
class OldAuthor(BaseModel):
"""
Author model
"""
pass
class OldBook(BaseModel):
"""
Book model
"""
pass
class OldMediaFile(BaseModel):
"""
MediaFile model
"""
pass
class OldSong(BaseModel):
"""
Song model
"""
pass
class OldTopic(BaseModel):
"""
Topic model
"""
pass
class OpenLPSongImport(SongImport):
"""
The :class:`OpenLPSongImport` class provides OpenLP with the ability to
@ -101,6 +66,41 @@ class OpenLPSongImport(SongImport):
"""
Run the import for an OpenLP version 2 song database.
"""
class OldAuthor(BaseModel):
"""
Author model
"""
pass
class OldBook(BaseModel):
"""
Book model
"""
pass
class OldMediaFile(BaseModel):
"""
MediaFile model
"""
pass
class OldSong(BaseModel):
"""
Song model
"""
pass
class OldTopic(BaseModel):
"""
Topic model
"""
pass
if not self.importSource.endswith(u'.sqlite'):
self.logError(self.importSource,
translate('SongsPlugin.OpenLPSongImport',
@ -138,13 +138,14 @@ class OpenLPSongImport(SongImport):
secondary=source_songs_topics_table)
}
if has_media_files:
if source_media_files_songs_table is not None:
if isinstance(source_media_files_songs_table, Table):
song_props['media_files'] = relation(OldMediaFile,
backref='songs',
secondary=source_media_files_songs_table)
else:
song_props['media_files'] = relation(OldMediaFile,
backref='songs',
foreign_keys=[source_media_files_table.c.song_id],
primaryjoin=source_songs_table.c.id == \
source_media_files_table.c.song_id)
try:

View File

@ -127,7 +127,7 @@ class SofImport(OooImport):
self.processParagraphText(text)
self.newSong()
text = u''
text += self.process_textportion(textportion)
text += self.processTextPortion(textportion)
if textportion.BreakType in (PAGE_AFTER, PAGE_BOTH):
self.processParagraphText(text)
self.newSong()
@ -202,8 +202,8 @@ class SofImport(OooImport):
if boldtext.isdigit() and self.songNumber == '':
self.addSongNumber(boldtext)
return u''
text = self.uncapText(text)
if self.title == u'':
text = self.uncap_text(text)
self.addTitle(text)
return text
if text.strip().startswith(u'('):
@ -242,8 +242,12 @@ class SofImport(OooImport):
self.songBook = u'Songs of Fellowship 2'
elif int(song_no) <= 1690:
self.songBook = u'Songs of Fellowship 3'
else:
elif int(song_no) <= 2200:
self.songBook = u'Songs of Fellowship 4'
elif int(song_no) <= 2710:
self.songBook = u'Songs of Fellowship 5'
else:
self.songBook = u'Songs of Fellowship Other'
def addTitle(self, text):
"""
@ -341,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()

View File

@ -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'])

View File

@ -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)

View File

@ -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)

View File

@ -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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

6196
resources/i18n/el.ts Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

6059
resources/i18n/sq.ts Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff