forked from openlp/openlp
Head + conflicts
This commit is contained in:
commit
2464bef944
@ -136,6 +136,8 @@ class OpenLP(QtGui.QApplication):
|
|||||||
self.processEvents()
|
self.processEvents()
|
||||||
# start the main app window
|
# start the main app window
|
||||||
self.main_window = MainWindow()
|
self.main_window = MainWindow()
|
||||||
|
Registry().execute(u'bootstrap_initialise')
|
||||||
|
Registry().execute(u'bootstrap_post_set_up')
|
||||||
self.main_window.show()
|
self.main_window.show()
|
||||||
if show_splash:
|
if show_splash:
|
||||||
# now kill the splashscreen
|
# now kill the splashscreen
|
||||||
@ -184,10 +186,8 @@ class OpenLP(QtGui.QApplication):
|
|||||||
``traceback``
|
``traceback``
|
||||||
A traceback object with the details of where the exception occurred.
|
A traceback object with the details of where the exception occurred.
|
||||||
"""
|
"""
|
||||||
if not hasattr(self, u'mainWindow'):
|
|
||||||
log.exception(''.join(format_exception(exctype, value, traceback)))
|
log.exception(''.join(format_exception(exctype, value, traceback)))
|
||||||
return
|
if not hasattr(self, u'exception_form'):
|
||||||
if not hasattr(self, u'exceptionForm'):
|
|
||||||
self.exception_form = ExceptionForm(self.main_window)
|
self.exception_form = ExceptionForm(self.main_window)
|
||||||
self.exception_form.exceptionTextEdit.setPlainText(''.join(format_exception(exctype, value, traceback)))
|
self.exception_form.exceptionTextEdit.setPlainText(''.join(format_exception(exctype, value, traceback)))
|
||||||
self.set_normal_cursor()
|
self.set_normal_cursor()
|
||||||
|
@ -393,7 +393,6 @@ from settings import Settings
|
|||||||
from listwidgetwithdnd import ListWidgetWithDnD
|
from listwidgetwithdnd import ListWidgetWithDnD
|
||||||
from formattingtags import FormattingTags
|
from formattingtags import FormattingTags
|
||||||
from spelltextedit import SpellTextEdit
|
from spelltextedit import SpellTextEdit
|
||||||
from settingsmanager import SettingsManager
|
|
||||||
from plugin import PluginStatus, StringContent, Plugin
|
from plugin import PluginStatus, StringContent, Plugin
|
||||||
from pluginmanager import PluginManager
|
from pluginmanager import PluginManager
|
||||||
from settingstab import SettingsTab
|
from settingstab import SettingsTab
|
||||||
|
@ -127,7 +127,7 @@ sup {
|
|||||||
document.getElementById('footer').innerHTML = footertext;
|
document.getElementById('footer').innerHTML = footertext;
|
||||||
}
|
}
|
||||||
|
|
||||||
function show_text(newtext){
|
function show_text(new_text){
|
||||||
var match = /-webkit-text-fill-color:[^;\"]+/gi;
|
var match = /-webkit-text-fill-color:[^;\"]+/gi;
|
||||||
if(timer != null)
|
if(timer != null)
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
@ -142,57 +142,47 @@ sup {
|
|||||||
if(outline != null)
|
if(outline != null)
|
||||||
txt = outline;
|
txt = outline;
|
||||||
if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){
|
if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){
|
||||||
newtext = newtext.replace(/(\s| )+(?![^<]*>)/g,
|
new_text = new_text.replace(/(\s| )+(?![^<]*>)/g,
|
||||||
function(match) {
|
function(match) {
|
||||||
return '</span>' + match + '<span>';
|
return '</span>' + match + '<span>';
|
||||||
});
|
});
|
||||||
newtext = '<span>' + newtext + '</span>';
|
new_text = '<span>' + new_text + '</span>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
text_fade('lyricsmain', newtext);
|
text_fade('lyricsmain', new_text);
|
||||||
text_fade('lyricsoutline', newtext);
|
text_fade('lyricsoutline', new_text);
|
||||||
text_fade('lyricsshadow', newtext.replace(match, ''));
|
text_fade('lyricsshadow', new_text.replace(match, ''));
|
||||||
if(text_opacity() == 1) return;
|
|
||||||
timer = setTimeout(function(){
|
|
||||||
show_text(newtext);
|
|
||||||
}, 100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function text_fade(id, newtext){
|
function text_fade(id, new_text){
|
||||||
/*
|
/*
|
||||||
Using -webkit-transition: opacity 1s linear; would have been preferred
|
Show the text.
|
||||||
but it isn't currently quick enough when animating multiple layers of
|
|
||||||
large areas of large text. Therefore do it manually as best we can.
|
|
||||||
Hopefully in the future we can revisit and do more interesting
|
|
||||||
transitions using -webkit-transition and -webkit-transform.
|
|
||||||
However we need to ensure interrupted transitions (quickly change 2
|
|
||||||
slides) still looks pretty and is zippy.
|
|
||||||
*/
|
*/
|
||||||
var text = document.getElementById(id);
|
var text = document.getElementById(id);
|
||||||
if(text == null) return;
|
if(text == null) return;
|
||||||
if(!transition){
|
if(!transition){
|
||||||
text.innerHTML = newtext;
|
text.innerHTML = new_text;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(newtext == text.innerHTML){
|
// Fade text out. 0.2 to minimize the time "nothing" is shown on the screen.
|
||||||
text.style.opacity = parseFloat(text.style.opacity) + 0.3;
|
text.style.opacity = '0.2';
|
||||||
if(text.style.opacity > 0.7)
|
// Fade new text in after the old text has finished fading out.
|
||||||
text.style.opacity = 1;
|
timer = window.setTimeout(function(){_show_text(text, new_text)}, 400);
|
||||||
} else {
|
|
||||||
text.style.opacity = parseFloat(text.style.opacity) - 0.3;
|
|
||||||
if(text.style.opacity <= 0.1){
|
|
||||||
text.innerHTML = newtext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function text_opacity(){
|
function _show_text(text, new_text) {
|
||||||
var text = document.getElementById('lyricsmain');
|
/*
|
||||||
return getComputedStyle(text, '').opacity;
|
Helper function to show the new_text delayed.
|
||||||
|
*/
|
||||||
|
text.innerHTML = new_text;
|
||||||
|
text.style.opacity = '1';
|
||||||
|
// Wait until the text is completely visible. We want to save the timer id, to be able to call
|
||||||
|
// clearTimeout(timer) when the text has changed before finishing fading.
|
||||||
|
timer = window.setTimeout(function(){timer = null;}, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
function show_text_complete(){
|
function show_text_completed(){
|
||||||
return (text_opacity() == 1);
|
return (timer == null);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
@ -218,7 +208,7 @@ def build_html(item, screen, is_live, background, image=None, plugins=None):
|
|||||||
``screen``
|
``screen``
|
||||||
Current display information
|
Current display information
|
||||||
|
|
||||||
``islive``
|
``is_live``
|
||||||
Item is going live, rather than preview/theme building
|
Item is going live, rather than preview/theme building
|
||||||
|
|
||||||
``background``
|
``background``
|
||||||
@ -336,6 +326,7 @@ def build_lyrics_css(item, webkit_ver):
|
|||||||
.lyricscell {
|
.lyricscell {
|
||||||
display: table-cell;
|
display: table-cell;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
|
-webkit-transition: opacity 0.4s ease;
|
||||||
%s
|
%s
|
||||||
}
|
}
|
||||||
.lyricsmain {
|
.lyricsmain {
|
||||||
|
@ -229,25 +229,28 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
create_widget_action(self.listView, separator=True)
|
create_widget_action(self.listView, separator=True)
|
||||||
if self.hasDeleteIcon:
|
if self.hasDeleteIcon:
|
||||||
create_widget_action(self.listView,
|
create_widget_action(self.listView,
|
||||||
|
u'listView%s%sItem' % (self.plugin.name.title(), StringContent.Delete.title()),
|
||||||
text=self.plugin.getString(StringContent.Delete)[u'title'],
|
text=self.plugin.getString(StringContent.Delete)[u'title'],
|
||||||
icon=u':/general/general_delete.png',
|
icon=u':/general/general_delete.png',
|
||||||
shortcuts=[QtCore.Qt.Key_Delete], triggers=self.onDeleteClick)
|
can_shortcuts=True, triggers=self.onDeleteClick)
|
||||||
create_widget_action(self.listView, separator=True)
|
create_widget_action(self.listView, separator=True)
|
||||||
create_widget_action(self.listView,
|
create_widget_action(self.listView,
|
||||||
|
u'listView%s%sItem' % (self.plugin.name.title(), StringContent.Preview.title()),
|
||||||
text=self.plugin.getString(StringContent.Preview)[u'title'],
|
text=self.plugin.getString(StringContent.Preview)[u'title'],
|
||||||
icon=u':/general/general_preview.png',
|
icon=u':/general/general_preview.png',
|
||||||
shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return],
|
can_shortcuts=True,
|
||||||
triggers=self.onPreviewClick)
|
triggers=self.onPreviewClick)
|
||||||
create_widget_action(self.listView,
|
create_widget_action(self.listView,
|
||||||
|
u'listView%s%sItem' % (self.plugin.name.title(), StringContent.Live.title()),
|
||||||
text=self.plugin.getString(StringContent.Live)[u'title'],
|
text=self.plugin.getString(StringContent.Live)[u'title'],
|
||||||
icon=u':/general/general_live.png',
|
icon=u':/general/general_live.png',
|
||||||
shortcuts=[QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter,
|
can_shortcuts=True,
|
||||||
QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return],
|
|
||||||
triggers=self.onLiveClick)
|
triggers=self.onLiveClick)
|
||||||
create_widget_action(self.listView,
|
create_widget_action(self.listView,
|
||||||
|
u'listView%s%sItem' % (self.plugin.name.title(), StringContent.Service.title()),
|
||||||
|
can_shortcuts=True,
|
||||||
text=self.plugin.getString(StringContent.Service)[u'title'],
|
text=self.plugin.getString(StringContent.Service)[u'title'],
|
||||||
icon=u':/general/general_add.png',
|
icon=u':/general/general_add.png',
|
||||||
shortcuts=[QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal],
|
|
||||||
triggers=self.onAddClick)
|
triggers=self.onAddClick)
|
||||||
if self.addToServiceItem:
|
if self.addToServiceItem:
|
||||||
create_widget_action(self.listView, separator=True)
|
create_widget_action(self.listView, separator=True)
|
||||||
|
@ -148,7 +148,7 @@ class Plugin(QtCore.QObject):
|
|||||||
QtCore.QObject.__init__(self)
|
QtCore.QObject.__init__(self)
|
||||||
self.name = name
|
self.name = name
|
||||||
self.textStrings = {}
|
self.textStrings = {}
|
||||||
self.setPluginTextStrings()
|
self.set_plugin_text_strings()
|
||||||
self.nameStrings = self.textStrings[StringContent.Name]
|
self.nameStrings = self.textStrings[StringContent.Name]
|
||||||
if version:
|
if version:
|
||||||
self.version = version
|
self.version = version
|
||||||
@ -319,7 +319,7 @@ class Plugin(QtCore.QObject):
|
|||||||
Settings().setValue(u'%s/%s files' % (self.settingsSection, self.name), loaded_list)
|
Settings().setValue(u'%s/%s files' % (self.settingsSection, self.name), loaded_list)
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
|
|
||||||
def usesTheme(self, theme):
|
def uses_theme(self, theme):
|
||||||
"""
|
"""
|
||||||
Called to find out if a plugin is currently using a theme.
|
Called to find out if a plugin is currently using a theme.
|
||||||
|
|
||||||
@ -327,7 +327,7 @@ class Plugin(QtCore.QObject):
|
|||||||
"""
|
"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def renameTheme(self, oldTheme, newTheme):
|
def rename_theme(self, oldTheme, newTheme):
|
||||||
"""
|
"""
|
||||||
Renames a theme a plugin is using making the plugin use the new name.
|
Renames a theme a plugin is using making the plugin use the new name.
|
||||||
|
|
||||||
|
@ -54,11 +54,37 @@ class PluginManager(object):
|
|||||||
"""
|
"""
|
||||||
log.info(u'Plugin manager Initialising')
|
log.info(u'Plugin manager Initialising')
|
||||||
Registry().register(u'plugin_manager', self)
|
Registry().register(u'plugin_manager', self)
|
||||||
|
Registry().register_function(u'bootstrap_initialise', self.bootstrap_initialise)
|
||||||
self.base_path = os.path.abspath(AppLocation.get_directory(AppLocation.PluginsDir))
|
self.base_path = os.path.abspath(AppLocation.get_directory(AppLocation.PluginsDir))
|
||||||
log.debug(u'Base path %s ', self.base_path)
|
log.debug(u'Base path %s ', self.base_path)
|
||||||
self.plugins = []
|
self.plugins = []
|
||||||
log.info(u'Plugin manager Initialised')
|
log.info(u'Plugin manager Initialised')
|
||||||
|
|
||||||
|
def bootstrap_initialise(self):
|
||||||
|
"""
|
||||||
|
Bootstrap all the plugin manager functions
|
||||||
|
"""
|
||||||
|
log.info(u'bootstrap_initialise')
|
||||||
|
self.find_plugins()
|
||||||
|
# hook methods have to happen after find_plugins. Find plugins needs
|
||||||
|
# the controllers hence the hooks have moved from setupUI() to here
|
||||||
|
# Find and insert settings tabs
|
||||||
|
log.info(u'hook settings')
|
||||||
|
self.hook_settings_tabs()
|
||||||
|
# Find and insert media manager items
|
||||||
|
log.info(u'hook media')
|
||||||
|
self.hook_media_manager()
|
||||||
|
# Call the hook method to pull in import menus.
|
||||||
|
log.info(u'hook menus')
|
||||||
|
self.hook_import_menu()
|
||||||
|
# Call the hook method to pull in export menus.
|
||||||
|
self.hook_export_menu()
|
||||||
|
# Call the hook method to pull in tools menus.
|
||||||
|
self.hook_tools_menu()
|
||||||
|
# Call the initialise method to setup plugins.
|
||||||
|
log.info(u'initialise plugins')
|
||||||
|
self.initialise_plugins()
|
||||||
|
|
||||||
def find_plugins(self):
|
def find_plugins(self):
|
||||||
"""
|
"""
|
||||||
Scan a directory for objects inheriting from the ``Plugin`` class.
|
Scan a directory for objects inheriting from the ``Plugin`` class.
|
||||||
@ -118,56 +144,44 @@ class PluginManager(object):
|
|||||||
if plugin.status is not PluginStatus.Disabled:
|
if plugin.status is not PluginStatus.Disabled:
|
||||||
plugin.createMediaManagerItem()
|
plugin.createMediaManagerItem()
|
||||||
|
|
||||||
def hook_settings_tabs(self, settings_form=None):
|
def hook_settings_tabs(self):
|
||||||
"""
|
"""
|
||||||
Loop through all the plugins. If a plugin has a valid settings tab
|
Loop through all the plugins. If a plugin has a valid settings tab
|
||||||
item, add it to the settings tab.
|
item, add it to the settings tab.
|
||||||
Tabs are set for all plugins not just Active ones
|
Tabs are set for all plugins not just Active ones
|
||||||
|
|
||||||
``settings_form``
|
|
||||||
Defaults to *None*. The settings form to add tabs to.
|
|
||||||
"""
|
"""
|
||||||
for plugin in self.plugins:
|
for plugin in self.plugins:
|
||||||
if plugin.status is not PluginStatus.Disabled:
|
if plugin.status is not PluginStatus.Disabled:
|
||||||
plugin.createSettingsTab(settings_form)
|
plugin.createSettingsTab(self.settings_form)
|
||||||
if settings_form:
|
|
||||||
settings_form.plugins = self.plugins
|
|
||||||
|
|
||||||
def hook_import_menu(self, import_menu):
|
def hook_import_menu(self):
|
||||||
"""
|
"""
|
||||||
Loop through all the plugins and give them an opportunity to add an
|
Loop through all the plugins and give them an opportunity to add an
|
||||||
item to the import menu.
|
item to the import menu.
|
||||||
|
|
||||||
``import_menu``
|
|
||||||
The Import menu.
|
|
||||||
"""
|
"""
|
||||||
for plugin in self.plugins:
|
for plugin in self.plugins:
|
||||||
if plugin.status is not PluginStatus.Disabled:
|
if plugin.status is not PluginStatus.Disabled:
|
||||||
plugin.addImportMenuItem(import_menu)
|
plugin.addImportMenuItem(self.main_window.file_import_menu)
|
||||||
|
|
||||||
def hook_export_menu(self, export_menu):
|
def hook_export_menu(self):
|
||||||
"""
|
"""
|
||||||
Loop through all the plugins and give them an opportunity to add an
|
Loop through all the plugins and give them an opportunity to add an
|
||||||
item to the export menu.
|
item to the export menu.
|
||||||
|
|
||||||
``export_menu``
|
|
||||||
The Export menu.
|
|
||||||
"""
|
"""
|
||||||
for plugin in self.plugins:
|
for plugin in self.plugins:
|
||||||
if plugin.status is not PluginStatus.Disabled:
|
if plugin.status is not PluginStatus.Disabled:
|
||||||
plugin.addExportMenuItem(export_menu)
|
plugin.addExportMenuItem(self.main_window.file_export_menu)
|
||||||
|
|
||||||
def hook_tools_menu(self, tools_menu):
|
def hook_tools_menu(self):
|
||||||
"""
|
"""
|
||||||
Loop through all the plugins and give them an opportunity to add an
|
Loop through all the plugins and give them an opportunity to add an
|
||||||
item to the tools menu.
|
item to the tools menu.
|
||||||
|
|
||||||
``tools_menu``
|
|
||||||
The Tools menu.
|
|
||||||
"""
|
"""
|
||||||
for plugin in self.plugins:
|
for plugin in self.plugins:
|
||||||
if plugin.status is not PluginStatus.Disabled:
|
if plugin.status is not PluginStatus.Disabled:
|
||||||
plugin.addToolsMenuItem(tools_menu)
|
plugin.addToolsMenuItem(self.main_window.tools_menu)
|
||||||
|
|
||||||
def initialise_plugins(self):
|
def initialise_plugins(self):
|
||||||
"""
|
"""
|
||||||
@ -211,3 +225,23 @@ class PluginManager(object):
|
|||||||
if plugin.isActive():
|
if plugin.isActive():
|
||||||
plugin.new_service_created()
|
plugin.new_service_created()
|
||||||
|
|
||||||
|
def _get_settings_form(self):
|
||||||
|
"""
|
||||||
|
Adds the plugin manager to the class dynamically
|
||||||
|
"""
|
||||||
|
if not hasattr(self, u'_settings_form'):
|
||||||
|
self._settings_form = Registry().get(u'settings_form')
|
||||||
|
return self._settings_form
|
||||||
|
|
||||||
|
settings_form = property(_get_settings_form)
|
||||||
|
|
||||||
|
def _get_main_window(self):
|
||||||
|
"""
|
||||||
|
Adds the main window to the class dynamically
|
||||||
|
"""
|
||||||
|
if not hasattr(self, u'_main_window'):
|
||||||
|
self._main_window = Registry().get(u'main_window')
|
||||||
|
return self._main_window
|
||||||
|
|
||||||
|
main_window = property(_get_main_window)
|
||||||
|
|
||||||
|
@ -247,7 +247,7 @@ class Renderer(object):
|
|||||||
serviceItem.footer = footer
|
serviceItem.footer = footer
|
||||||
serviceItem.render(True)
|
serviceItem.render(True)
|
||||||
if not self.force_page:
|
if not self.force_page:
|
||||||
self.display.buildHtml(serviceItem)
|
self.display.build_html(serviceItem)
|
||||||
raw_html = serviceItem.get_rendered_frame(0)
|
raw_html = serviceItem.get_rendered_frame(0)
|
||||||
self.display.text(raw_html, False)
|
self.display.text(raw_html, False)
|
||||||
preview = self.display.preview()
|
preview = self.display.preview()
|
||||||
@ -662,4 +662,3 @@ class Renderer(object):
|
|||||||
return self._theme_manager
|
return self._theme_manager
|
||||||
|
|
||||||
theme_manager = property(_get_theme_manager)
|
theme_manager = property(_get_theme_manager)
|
||||||
|
|
||||||
|
@ -152,42 +152,99 @@ class Settings(QtCore.QSettings):
|
|||||||
u'SettingsImport/type': u'OpenLP_settings_export',
|
u'SettingsImport/type': u'OpenLP_settings_export',
|
||||||
u'SettingsImport/version': u'',
|
u'SettingsImport/version': u'',
|
||||||
u'shortcuts/aboutItem': [QtGui.QKeySequence(u'Ctrl+F1')],
|
u'shortcuts/aboutItem': [QtGui.QKeySequence(u'Ctrl+F1')],
|
||||||
|
u'shortcuts/addToService': [],
|
||||||
u'shortcuts/audioPauseItem': [],
|
u'shortcuts/audioPauseItem': [],
|
||||||
u'shortcuts/displayTagItem': [],
|
u'shortcuts/displayTagItem': [],
|
||||||
u'shortcuts/blankScreen': [QtCore.Qt.Key_Period],
|
u'shortcuts/blankScreen': [QtGui.QKeySequence(QtCore.Qt.Key_Period)],
|
||||||
u'shortcuts/collapse': [QtCore.Qt.Key_Minus],
|
u'shortcuts/collapse': [QtGui.QKeySequence(QtCore.Qt.Key_Minus)],
|
||||||
u'shortcuts/desktopScreen': [QtGui.QKeySequence(u'D')],
|
u'shortcuts/desktopScreen': [QtGui.QKeySequence(u'D')],
|
||||||
u'shortcuts/down': [QtCore.Qt.Key_Down],
|
u'shortcuts/delete': [],
|
||||||
u'shortcuts/escapeItem': [QtCore.Qt.Key_Escape],
|
u'shortcuts/down': [QtGui.QKeySequence(QtCore.Qt.Key_Down)],
|
||||||
u'shortcuts/expand': [QtCore.Qt.Key_Plus],
|
u'shortcuts/editSong': [],
|
||||||
|
u'shortcuts/escapeItem': [QtGui.QKeySequence(QtCore.Qt.Key_Escape)],
|
||||||
|
u'shortcuts/expand': [QtGui.QKeySequence(QtCore.Qt.Key_Plus)],
|
||||||
u'shortcuts/exportThemeItem': [],
|
u'shortcuts/exportThemeItem': [],
|
||||||
u'shortcuts/fileNewItem': [QtGui.QKeySequence(u'Ctrl+N')],
|
u'shortcuts/fileNewItem': [QtGui.QKeySequence(u'Ctrl+N')],
|
||||||
u'shortcuts/fileSaveAsItem': [QtGui.QKeySequence(u'Ctrl+Shift+S')],
|
u'shortcuts/fileSaveAsItem': [QtGui.QKeySequence(u'Ctrl+Shift+S')],
|
||||||
u'shortcuts/fileExitItem': [QtGui.QKeySequence(u'Alt+F4')],
|
u'shortcuts/fileExitItem': [QtGui.QKeySequence(u'Alt+F4')],
|
||||||
u'shortcuts/fileSaveItem': [QtGui.QKeySequence(u'Ctrl+S')],
|
u'shortcuts/fileSaveItem': [QtGui.QKeySequence(u'Ctrl+S')],
|
||||||
u'shortcuts/fileOpenItem': [QtGui.QKeySequence(u'Ctrl+O')],
|
u'shortcuts/fileOpenItem': [QtGui.QKeySequence(u'Ctrl+O')],
|
||||||
|
u'shortcuts/goLive': [],
|
||||||
u'shortcuts/importThemeItem': [],
|
u'shortcuts/importThemeItem': [],
|
||||||
u'shortcuts/importBibleItem': [],
|
u'shortcuts/importBibleItem': [],
|
||||||
|
u'shortcuts/listViewBiblesDeleteItem': [QtGui.QKeySequence(QtCore.Qt.Key_Delete)],
|
||||||
|
u'shortcuts/listViewBiblesPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Enter),
|
||||||
|
QtGui.QKeySequence(QtCore.Qt.Key_Return)],
|
||||||
|
u'shortcuts/listViewBiblesLiveItem': [QtGui.QKeySequence(QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter),
|
||||||
|
QtGui.QKeySequence(QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return)],
|
||||||
|
u'shortcuts/listViewBiblesServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
|
||||||
|
QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
|
||||||
|
u'shortcuts/listViewCustomDeleteItem': [QtGui.QKeySequence(QtCore.Qt.Key_Delete)],
|
||||||
|
u'shortcuts/listViewCustomPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Enter),
|
||||||
|
QtGui.QKeySequence(QtCore.Qt.Key_Return)],
|
||||||
|
u'shortcuts/listViewCustomLiveItem': [QtGui.QKeySequence(QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter),
|
||||||
|
QtGui.QKeySequence(QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return)],
|
||||||
|
u'shortcuts/listViewCustomServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
|
||||||
|
QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
|
||||||
|
u'shortcuts/listViewImagesDeleteItem': [QtGui.QKeySequence(QtCore.Qt.Key_Delete)],
|
||||||
|
u'shortcuts/listViewImagesPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Enter),
|
||||||
|
QtGui.QKeySequence(QtCore.Qt.Key_Return)],
|
||||||
|
u'shortcuts/listViewImagesLiveItem': [QtGui.QKeySequence(QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter),
|
||||||
|
QtGui.QKeySequence(QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return)],
|
||||||
|
u'shortcuts/listViewImagesServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
|
||||||
|
QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
|
||||||
|
u'shortcuts/listViewMediaDeleteItem': [QtGui.QKeySequence(QtCore.Qt.Key_Delete)],
|
||||||
|
u'shortcuts/listViewMediaPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Enter),
|
||||||
|
QtGui.QKeySequence(QtCore.Qt.Key_Return)],
|
||||||
|
u'shortcuts/listViewMediaLiveItem': [QtGui.QKeySequence(QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter),
|
||||||
|
QtGui.QKeySequence(QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return)],
|
||||||
|
u'shortcuts/listViewMediaServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
|
||||||
|
QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
|
||||||
|
u'shortcuts/listViewPresentationsDeleteItem': [QtGui.QKeySequence(QtCore.Qt.Key_Delete)],
|
||||||
|
u'shortcuts/listViewPresentationsPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Enter),
|
||||||
|
QtGui.QKeySequence(QtCore.Qt.Key_Return)],
|
||||||
|
u'shortcuts/listViewPresentationsLiveItem': [QtGui.QKeySequence(QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter),
|
||||||
|
QtGui.QKeySequence(QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return)],
|
||||||
|
u'shortcuts/listViewPresentationsServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
|
||||||
|
QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
|
||||||
|
u'shortcuts/listViewSongsDeleteItem': [QtGui.QKeySequence(QtCore.Qt.Key_Delete)],
|
||||||
|
u'shortcuts/listViewSongsPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Enter),
|
||||||
|
QtGui.QKeySequence(QtCore.Qt.Key_Return)],
|
||||||
|
u'shortcuts/listViewSongsLiveItem': [QtGui.QKeySequence(QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter),
|
||||||
|
QtGui.QKeySequence(QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return)],
|
||||||
|
u'shortcuts/listViewSongsServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
|
||||||
|
QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
|
||||||
|
u'shortcuts/lockPanel': [],
|
||||||
u'shortcuts/modeDefaultItem': [],
|
u'shortcuts/modeDefaultItem': [],
|
||||||
u'shortcuts/modeLiveItem': [],
|
u'shortcuts/modeLiveItem': [],
|
||||||
u'shortcuts/make_live': [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return],
|
u'shortcuts/make_live': [QtGui.QKeySequence(QtCore.Qt.Key_Enter), QtGui.QKeySequence(QtCore.Qt.Key_Return)],
|
||||||
u'shortcuts/moveUp': [QtCore.Qt.Key_PageUp],
|
u'shortcuts/moveUp': [QtGui.QKeySequence(QtCore.Qt.Key_PageUp)],
|
||||||
u'shortcuts/moveTop': [QtCore.Qt.Key_Home],
|
u'shortcuts/moveTop': [QtGui.QKeySequence(QtCore.Qt.Key_Home)],
|
||||||
u'shortcuts/modeSetupItem': [],
|
u'shortcuts/modeSetupItem': [],
|
||||||
u'shortcuts/moveBottom': [QtCore.Qt.Key_End],
|
u'shortcuts/moveBottom': [QtGui.QKeySequence(QtCore.Qt.Key_End)],
|
||||||
u'shortcuts/moveDown': [QtCore.Qt.Key_PageDown],
|
u'shortcuts/moveDown': [QtGui.QKeySequence(QtCore.Qt.Key_PageDown)],
|
||||||
u'shortcuts/nextTrackItem': [],
|
u'shortcuts/nextTrackItem': [],
|
||||||
u'shortcuts/nextItem_live': [QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown],
|
u'shortcuts/nextItem_live': [QtGui.QKeySequence(QtCore.Qt.Key_Down),
|
||||||
u'shortcuts/nextService': [QtCore.Qt.Key_Right],
|
QtGui.QKeySequence(QtCore.Qt.Key_PageDown)],
|
||||||
|
u'shortcuts/nextItem_preview': [],
|
||||||
|
u'shortcuts/nextService': [QtGui.QKeySequence(QtCore.Qt.Key_Right)],
|
||||||
|
u'shortcuts/newService': [],
|
||||||
u'shortcuts/offlineHelpItem': [],
|
u'shortcuts/offlineHelpItem': [],
|
||||||
u'shortcuts/onlineHelpItem': [QtGui.QKeySequence(u'Alt+F1')],
|
u'shortcuts/onlineHelpItem': [QtGui.QKeySequence(u'Alt+F1')],
|
||||||
u'shortcuts/previousItem_live': [QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp],
|
u'shortcuts/openService': [],
|
||||||
|
u'shortcuts/saveService': [],
|
||||||
|
u'shortcuts/previousItem_live': [QtGui.QKeySequence(QtCore.Qt.Key_Up),
|
||||||
|
QtGui.QKeySequence(QtCore.Qt.Key_PageUp)],
|
||||||
|
u'shortcuts/playbackPause': [],
|
||||||
|
u'shortcuts/playbackPlay': [],
|
||||||
|
u'shortcuts/playbackStop': [],
|
||||||
u'shortcuts/playSlidesLoop': [],
|
u'shortcuts/playSlidesLoop': [],
|
||||||
u'shortcuts/playSlidesOnce': [],
|
u'shortcuts/playSlidesOnce': [],
|
||||||
u'shortcuts/previousService': [QtCore.Qt.Key_Left],
|
u'shortcuts/previousService': [QtGui.QKeySequence(QtCore.Qt.Key_Left)],
|
||||||
|
u'shortcuts/previousItem_preview': [],
|
||||||
u'shortcuts/printServiceItem': [QtGui.QKeySequence(u'Ctrl+P')],
|
u'shortcuts/printServiceItem': [QtGui.QKeySequence(u'Ctrl+P')],
|
||||||
u'shortcuts/songExportItem': [],
|
u'shortcuts/songExportItem': [],
|
||||||
u'shortcuts/songUsageStatus': [QtCore.Qt.Key_F4],
|
u'shortcuts/songUsageStatus': [QtGui.QKeySequence(QtCore.Qt.Key_F4)],
|
||||||
u'shortcuts/settingsShortcutsItem': [],
|
u'shortcuts/settingsShortcutsItem': [],
|
||||||
u'shortcuts/settingsImportItem': [],
|
u'shortcuts/settingsImportItem': [],
|
||||||
u'shortcuts/settingsPluginListItem': [QtGui.QKeySequence(u'Alt+F7')],
|
u'shortcuts/settingsPluginListItem': [QtGui.QKeySequence(u'Alt+F7')],
|
||||||
@ -200,17 +257,27 @@ class Settings(QtCore.QSettings):
|
|||||||
u'shortcuts/shortcutAction_O': [QtGui.QKeySequence(u'O')],
|
u'shortcuts/shortcutAction_O': [QtGui.QKeySequence(u'O')],
|
||||||
u'shortcuts/shortcutAction_P': [QtGui.QKeySequence(u'P')],
|
u'shortcuts/shortcutAction_P': [QtGui.QKeySequence(u'P')],
|
||||||
u'shortcuts/shortcutAction_V': [QtGui.QKeySequence(u'V')],
|
u'shortcuts/shortcutAction_V': [QtGui.QKeySequence(u'V')],
|
||||||
|
u'shortcuts/shortcutAction_0': [QtGui.QKeySequence(u'0')],
|
||||||
|
u'shortcuts/shortcutAction_1': [QtGui.QKeySequence(u'1')],
|
||||||
|
u'shortcuts/shortcutAction_2': [QtGui.QKeySequence(u'2')],
|
||||||
|
u'shortcuts/shortcutAction_3': [QtGui.QKeySequence(u'3')],
|
||||||
|
u'shortcuts/shortcutAction_4': [QtGui.QKeySequence(u'4')],
|
||||||
|
u'shortcuts/shortcutAction_5': [QtGui.QKeySequence(u'5')],
|
||||||
|
u'shortcuts/shortcutAction_6': [QtGui.QKeySequence(u'6')],
|
||||||
|
u'shortcuts/shortcutAction_7': [QtGui.QKeySequence(u'7')],
|
||||||
|
u'shortcuts/shortcutAction_8': [QtGui.QKeySequence(u'8')],
|
||||||
|
u'shortcuts/shortcutAction_9': [QtGui.QKeySequence(u'9')],
|
||||||
u'shortcuts/settingsExportItem': [],
|
u'shortcuts/settingsExportItem': [],
|
||||||
u'shortcuts/songUsageReport': [],
|
u'shortcuts/songUsageReport': [],
|
||||||
u'shortcuts/songImportItem': [],
|
u'shortcuts/songImportItem': [],
|
||||||
u'shortcuts/themeScreen': [QtGui.QKeySequence(u'T')],
|
u'shortcuts/themeScreen': [QtGui.QKeySequence(u'T')],
|
||||||
u'shortcuts/toolsReindexItem': [],
|
u'shortcuts/toolsReindexItem': [],
|
||||||
u'shortcuts/toolsAlertItem': [u'F7'],
|
u'shortcuts/toolsAlertItem': [QtGui.QKeySequence(u'F7')],
|
||||||
u'shortcuts/toolsFirstTimeWizard': [],
|
u'shortcuts/toolsFirstTimeWizard': [],
|
||||||
u'shortcuts/toolsOpenDataFolder': [],
|
u'shortcuts/toolsOpenDataFolder': [],
|
||||||
u'shortcuts/toolsAddToolItem': [],
|
u'shortcuts/toolsAddToolItem': [],
|
||||||
u'shortcuts/updateThemeImages': [],
|
u'shortcuts/updateThemeImages': [],
|
||||||
u'shortcuts/up': [QtCore.Qt.Key_Up],
|
u'shortcuts/up': [QtGui.QKeySequence(QtCore.Qt.Key_Up)],
|
||||||
u'shortcuts/viewThemeManagerItem': [QtGui.QKeySequence(u'F10')],
|
u'shortcuts/viewThemeManagerItem': [QtGui.QKeySequence(u'F10')],
|
||||||
u'shortcuts/viewMediaManagerItem': [QtGui.QKeySequence(u'F8')],
|
u'shortcuts/viewMediaManagerItem': [QtGui.QKeySequence(u'F8')],
|
||||||
u'shortcuts/viewPreviewPanel': [QtGui.QKeySequence(u'F11')],
|
u'shortcuts/viewPreviewPanel': [QtGui.QKeySequence(u'F11')],
|
||||||
@ -287,6 +354,14 @@ class Settings(QtCore.QSettings):
|
|||||||
else:
|
else:
|
||||||
QtCore.QSettings.__init__(self, *args)
|
QtCore.QSettings.__init__(self, *args)
|
||||||
|
|
||||||
|
def get_default_value(self, key):
|
||||||
|
"""
|
||||||
|
Get the default value of the given key
|
||||||
|
"""
|
||||||
|
if self.group():
|
||||||
|
key = self.group() + u'/' + key
|
||||||
|
return Settings.__default_settings__[key]
|
||||||
|
|
||||||
def remove_obsolete_settings(self):
|
def remove_obsolete_settings(self):
|
||||||
"""
|
"""
|
||||||
This method is only called to clean up the config. It removes old settings and it renames settings. See
|
This method is only called to clean up the config. It removes old settings and it renames settings. See
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# OpenLP - Open Source Lyrics Projection #
|
|
||||||
# --------------------------------------------------------------------------- #
|
|
||||||
# Copyright (c) 2008-2013 Raoul Snyman #
|
|
||||||
# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan #
|
|
||||||
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
|
|
||||||
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
|
|
||||||
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
|
|
||||||
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
|
|
||||||
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
|
|
||||||
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
|
|
||||||
# --------------------------------------------------------------------------- #
|
|
||||||
# This program is free software; you can redistribute it and/or modify it #
|
|
||||||
# under the terms of the GNU General Public License as published by the Free #
|
|
||||||
# Software Foundation; version 2 of the License. #
|
|
||||||
# #
|
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
|
||||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
|
||||||
# more details. #
|
|
||||||
# #
|
|
||||||
# You should have received a copy of the GNU General Public License along #
|
|
||||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
|
||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
|
||||||
###############################################################################
|
|
||||||
"""
|
|
||||||
Provide handling for persisting OpenLP settings. OpenLP uses QSettings to manage settings persistence. QSettings
|
|
||||||
provides a single API for saving and retrieving settings from the application but writes to disk in an OS dependant
|
|
||||||
format.
|
|
||||||
"""
|
|
||||||
import os
|
|
||||||
|
|
||||||
from openlp.core.utils import AppLocation
|
|
||||||
|
|
||||||
|
|
||||||
class SettingsManager(object):
|
|
||||||
"""
|
|
||||||
Class to provide helper functions for the loading and saving of application settings.
|
|
||||||
"""
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_files(section=None, extension=None):
|
|
||||||
"""
|
|
||||||
Get a list of files from the data files path.
|
|
||||||
|
|
||||||
``section``
|
|
||||||
Defaults to *None*. The section of code getting the files - used to load from a section's data subdirectory.
|
|
||||||
|
|
||||||
``extension``
|
|
||||||
Defaults to *None*. The extension to search for.
|
|
||||||
"""
|
|
||||||
path = AppLocation.get_data_path()
|
|
||||||
if section:
|
|
||||||
path = os.path.join(path, section)
|
|
||||||
try:
|
|
||||||
files = os.listdir(path)
|
|
||||||
except OSError:
|
|
||||||
return []
|
|
||||||
if extension:
|
|
||||||
return [filename for filename in files if extension == os.path.splitext(filename)[1]]
|
|
||||||
else:
|
|
||||||
# no filtering required
|
|
||||||
return files
|
|
@ -123,7 +123,7 @@ class SettingsTab(QtGui.QWidget):
|
|||||||
"""
|
"""
|
||||||
self.load()
|
self.load()
|
||||||
|
|
||||||
def postSetUp(self, postUpdate=False):
|
def post_set_up(self, postUpdate=False):
|
||||||
"""
|
"""
|
||||||
Changes which need to be made after setup of application
|
Changes which need to be made after setup of application
|
||||||
|
|
||||||
|
@ -69,9 +69,8 @@ def add_welcome_page(parent, image):
|
|||||||
|
|
||||||
def create_button_box(dialog, name, standard_buttons, custom_buttons=None):
|
def create_button_box(dialog, name, standard_buttons, custom_buttons=None):
|
||||||
"""
|
"""
|
||||||
Creates a QDialogButtonBox with the given buttons. The ``accepted()`` and
|
Creates a QDialogButtonBox with the given buttons. The ``accepted()`` and ``rejected()`` signals of the button box
|
||||||
``rejected()`` signals of the button box are connected with the dialogs
|
are connected with the dialogs ``accept()`` and ``reject()`` slots.
|
||||||
``accept()`` and ``reject()`` slots.
|
|
||||||
|
|
||||||
``dialog``
|
``dialog``
|
||||||
The parent object. This has to be a ``QDialog`` descendant.
|
The parent object. This has to be a ``QDialog`` descendant.
|
||||||
@ -80,13 +79,12 @@ def create_button_box(dialog, name, standard_buttons, custom_buttons=None):
|
|||||||
A string which is set as object name.
|
A string which is set as object name.
|
||||||
|
|
||||||
``standard_buttons``
|
``standard_buttons``
|
||||||
A list of strings for the used buttons. It might contain: ``ok``,
|
A list of strings for the used buttons. It might contain: ``ok``, ``save``, ``cancel``, ``close``, and
|
||||||
``save``, ``cancel``, ``close``, and ``defaults``.
|
``defaults``.
|
||||||
|
|
||||||
``custom_buttons``
|
``custom_buttons``
|
||||||
A list of additional buttons. If a item is a instance of
|
A list of additional buttons. If a item is a instance of QtGui.QAbstractButton it is added with
|
||||||
QtGui.QAbstractButton it is added with QDialogButtonBox.ActionRole.
|
QDialogButtonBox.ActionRole. Otherwhise the item has to be a tuple of a button and a ButtonRole.
|
||||||
Otherwhise the item has to be a tuple of a button and a ButtonRole.
|
|
||||||
"""
|
"""
|
||||||
if custom_buttons is None:
|
if custom_buttons is None:
|
||||||
custom_buttons = []
|
custom_buttons = []
|
||||||
@ -116,8 +114,7 @@ def create_button_box(dialog, name, standard_buttons, custom_buttons=None):
|
|||||||
|
|
||||||
def critical_error_message_box(title=None, message=None, parent=None, question=False):
|
def critical_error_message_box(title=None, message=None, parent=None, question=False):
|
||||||
"""
|
"""
|
||||||
Provides a standard critical message box for errors that OpenLP displays
|
Provides a standard critical message box for errors that OpenLP displays to users.
|
||||||
to users.
|
|
||||||
|
|
||||||
``title``
|
``title``
|
||||||
The title for the message box.
|
The title for the message box.
|
||||||
@ -134,7 +131,6 @@ def critical_error_message_box(title=None, message=None, parent=None, question=F
|
|||||||
if question:
|
if question:
|
||||||
return QtGui.QMessageBox.critical(parent, UiStrings().Error, message,
|
return QtGui.QMessageBox.critical(parent, UiStrings().Error, message,
|
||||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No))
|
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No))
|
||||||
data = {u'message': message}
|
|
||||||
return Registry().get(u'main_window').error_message(title if title else UiStrings().Error, message)
|
return Registry().get(u'main_window').error_message(title if title else UiStrings().Error, message)
|
||||||
|
|
||||||
|
|
||||||
@ -166,16 +162,14 @@ def create_button(parent, name, **kwargs):
|
|||||||
A string which is set as object name (required).
|
A string which is set as object name (required).
|
||||||
|
|
||||||
``role``
|
``role``
|
||||||
A string which can have one value out of ``delete``, ``up``, and
|
A string which can have one value out of ``delete``, ``up``, and ``down``. This decides about default values
|
||||||
``down``. This decides about default values for properties like text,
|
for properties like text, icon, or tooltip.
|
||||||
icon, or tooltip.
|
|
||||||
|
|
||||||
``text``
|
``text``
|
||||||
A string for the action text.
|
A string for the action text.
|
||||||
|
|
||||||
``icon``
|
``icon``
|
||||||
Either a QIcon, a resource string, or a file location string for the
|
Either a QIcon, a resource string, or a file location string for the action icon.
|
||||||
action icon.
|
|
||||||
|
|
||||||
``tooltip``
|
``tooltip``
|
||||||
A string for the action tool tip.
|
A string for the action tool tip.
|
||||||
@ -195,8 +189,7 @@ def create_button(parent, name, **kwargs):
|
|||||||
kwargs.setdefault(u'icon', u':/services/service_down.png')
|
kwargs.setdefault(u'icon', u':/services/service_down.png')
|
||||||
kwargs.setdefault(u'tooltip', translate('OpenLP.Ui', 'Move selection down one position.'))
|
kwargs.setdefault(u'tooltip', translate('OpenLP.Ui', 'Move selection down one position.'))
|
||||||
else:
|
else:
|
||||||
log.warn(u'The role "%s" is not defined in create_push_button().',
|
log.warn(u'The role "%s" is not defined in create_push_button().', role)
|
||||||
role)
|
|
||||||
if kwargs.pop(u'class', u'') == u'toolbutton':
|
if kwargs.pop(u'class', u'') == u'toolbutton':
|
||||||
button = QtGui.QToolButton(parent)
|
button = QtGui.QToolButton(parent)
|
||||||
else:
|
else:
|
||||||
@ -256,8 +249,10 @@ def create_action(parent, name, **kwargs):
|
|||||||
``data``
|
``data``
|
||||||
The action's data.
|
The action's data.
|
||||||
|
|
||||||
``shortcuts``
|
``can_shortcuts``
|
||||||
A QList<QKeySequence> (or a list of strings) which are set as shortcuts.
|
Capability stating if this action can have shortcuts. If ``True`` the action is added to shortcut dialog
|
||||||
|
otherwise it it not. Define your shortcut in the :class:`~openlp.core.lib.Settings` class. *Note*: When *not*
|
||||||
|
``True`` you *must not* set a shortcuts at all.
|
||||||
|
|
||||||
``context``
|
``context``
|
||||||
A context for the shortcut execution.
|
A context for the shortcut execution.
|
||||||
@ -289,26 +284,24 @@ def create_action(parent, name, **kwargs):
|
|||||||
action.setSeparator(True)
|
action.setSeparator(True)
|
||||||
if u'data' in kwargs:
|
if u'data' in kwargs:
|
||||||
action.setData(kwargs.pop(u'data'))
|
action.setData(kwargs.pop(u'data'))
|
||||||
if kwargs.get(u'shortcuts'):
|
if kwargs.pop(u'can_shortcuts', False):
|
||||||
action.setShortcuts(kwargs.pop(u'shortcuts'))
|
action_list = ActionList.get_instance()
|
||||||
|
action_list.add_action(action, kwargs.pop(u'category', None))
|
||||||
if u'context' in kwargs:
|
if u'context' in kwargs:
|
||||||
action.setShortcutContext(kwargs.pop(u'context'))
|
action.setShortcutContext(kwargs.pop(u'context'))
|
||||||
if kwargs.get(u'category'):
|
|
||||||
action_list = ActionList.get_instance()
|
|
||||||
action_list.add_action(action, unicode(kwargs.pop(u'category')))
|
|
||||||
if kwargs.get(u'triggers'):
|
if kwargs.get(u'triggers'):
|
||||||
action.triggered.connect(kwargs.pop(u'triggers'))
|
action.triggered.connect(kwargs.pop(u'triggers'))
|
||||||
for key in kwargs.keys():
|
for key in kwargs.keys():
|
||||||
if key not in [u'text', u'icon', u'tooltip', u'statustip', u'checked', u'shortcuts', u'category', u'triggers']:
|
if key not in [u'text', u'icon', u'tooltip', u'statustip', u'checked', u'can_shortcuts',
|
||||||
|
u'category', u'triggers']:
|
||||||
log.warn(u'Parameter %s was not consumed in create_action().', key)
|
log.warn(u'Parameter %s was not consumed in create_action().', key)
|
||||||
return action
|
return action
|
||||||
|
|
||||||
|
|
||||||
def create_widget_action(parent, name=u'', **kwargs):
|
def create_widget_action(parent, name=u'', **kwargs):
|
||||||
"""
|
"""
|
||||||
Return a new QAction by calling ``create_action(parent, name, **kwargs)``.
|
Return a new QAction by calling ``create_action(parent, name, **kwargs)``. The shortcut context defaults to
|
||||||
The shortcut context defaults to ``QtCore.Qt.WidgetShortcut`` and the action
|
``QtCore.Qt.WidgetShortcut`` and the action is added to the parents action list.
|
||||||
is added to the parents action list.
|
|
||||||
"""
|
"""
|
||||||
kwargs.setdefault(u'context', QtCore.Qt.WidgetShortcut)
|
kwargs.setdefault(u'context', QtCore.Qt.WidgetShortcut)
|
||||||
action = create_action(parent, name, **kwargs)
|
action = create_action(parent, name, **kwargs)
|
||||||
@ -333,8 +326,7 @@ def set_case_insensitive_completer(cache, widget):
|
|||||||
|
|
||||||
def create_valign_selection_widgets(parent):
|
def create_valign_selection_widgets(parent):
|
||||||
"""
|
"""
|
||||||
Creates a standard label and combo box for asking users to select a
|
Creates a standard label and combo box for asking users to select a vertical alignment.
|
||||||
vertical alignment.
|
|
||||||
|
|
||||||
``parent``
|
``parent``
|
||||||
The parent object. This should be a ``QWidget`` descendant.
|
The parent object. This should be a ``QWidget`` descendant.
|
||||||
|
@ -308,9 +308,9 @@ class GeneralTab(SettingsTab):
|
|||||||
settings.setValue(u'audio repeat list', self.repeatListCheckBox.isChecked())
|
settings.setValue(u'audio repeat list', self.repeatListCheckBox.isChecked())
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
# On save update the screens as well
|
# On save update the screens as well
|
||||||
self.postSetUp(True)
|
self.post_set_up(True)
|
||||||
|
|
||||||
def postSetUp(self, postUpdate=False):
|
def post_set_up(self, postUpdate=False):
|
||||||
"""
|
"""
|
||||||
Apply settings after settings tab has loaded and most of the
|
Apply settings after settings tab has loaded and most of the
|
||||||
system so must be delayed
|
system so must be delayed
|
||||||
|
@ -68,7 +68,7 @@ class Display(QtGui.QGraphicsView):
|
|||||||
self.parent = lambda: parent
|
self.parent = lambda: parent
|
||||||
else:
|
else:
|
||||||
QtGui.QGraphicsView.__init__(self, parent)
|
QtGui.QGraphicsView.__init__(self, parent)
|
||||||
self.isLive = live
|
self.is_live = live
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.screen = {}
|
self.screen = {}
|
||||||
# FIXME: On Mac OS X (tested on 10.7) the display screen is corrupt with
|
# FIXME: On Mac OS X (tested on 10.7) the display screen is corrupt with
|
||||||
@ -82,40 +82,37 @@ class Display(QtGui.QGraphicsView):
|
|||||||
"""
|
"""
|
||||||
Set up and build the screen base
|
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.is_live)
|
||||||
self.setGeometry(self.screen[u'size'])
|
self.setGeometry(self.screen[u'size'])
|
||||||
log.debug(u'Setup webView')
|
log.debug(u'Setup webView')
|
||||||
self.webView = QtWebKit.QWebView(self)
|
self.web_view = QtWebKit.QWebView(self)
|
||||||
self.webView.setGeometry(0, 0, self.screen[u'size'].width(), self.screen[u'size'].height())
|
self.web_view.setGeometry(0, 0, self.screen[u'size'].width(), self.screen[u'size'].height())
|
||||||
self.webView.settings().setAttribute(QtWebKit.QWebSettings.PluginsEnabled, True)
|
self.web_view.settings().setAttribute(QtWebKit.QWebSettings.PluginsEnabled, True)
|
||||||
palette = self.webView.palette()
|
palette = self.web_view.palette()
|
||||||
palette.setBrush(QtGui.QPalette.Base, QtCore.Qt.transparent)
|
palette.setBrush(QtGui.QPalette.Base, QtCore.Qt.transparent)
|
||||||
self.webView.page().setPalette(palette)
|
self.web_view.page().setPalette(palette)
|
||||||
self.webView.setAttribute(QtCore.Qt.WA_OpaquePaintEvent, False)
|
self.web_view.setAttribute(QtCore.Qt.WA_OpaquePaintEvent, False)
|
||||||
self.page = self.webView.page()
|
self.page = self.web_view.page()
|
||||||
self.frame = self.page.mainFrame()
|
self.frame = self.page.mainFrame()
|
||||||
if self.isLive and log.getEffectiveLevel() == logging.DEBUG:
|
if self.is_live and log.getEffectiveLevel() == logging.DEBUG:
|
||||||
self.webView.settings().setAttribute(QtWebKit.QWebSettings.DeveloperExtrasEnabled, True)
|
self.web_view.settings().setAttribute(QtWebKit.QWebSettings.DeveloperExtrasEnabled, True)
|
||||||
QtCore.QObject.connect(self.webView,
|
self.web_view.loadFinished.connect(self.is_web_loaded)
|
||||||
QtCore.SIGNAL(u'loadFinished(bool)'), self.isWebLoaded)
|
|
||||||
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
|
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
|
||||||
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
|
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
|
||||||
self.frame.setScrollBarPolicy(QtCore.Qt.Vertical,
|
self.frame.setScrollBarPolicy(QtCore.Qt.Vertical, QtCore.Qt.ScrollBarAlwaysOff)
|
||||||
QtCore.Qt.ScrollBarAlwaysOff)
|
self.frame.setScrollBarPolicy(QtCore.Qt.Horizontal, QtCore.Qt.ScrollBarAlwaysOff)
|
||||||
self.frame.setScrollBarPolicy(QtCore.Qt.Horizontal,
|
|
||||||
QtCore.Qt.ScrollBarAlwaysOff)
|
|
||||||
|
|
||||||
def resizeEvent(self, event):
|
def resizeEvent(self, event):
|
||||||
"""
|
"""
|
||||||
React to resizing of this display
|
React to resizing of this display
|
||||||
"""
|
"""
|
||||||
self.webView.setGeometry(0, 0, self.width(), self.height())
|
self.web_view.setGeometry(0, 0, self.width(), self.height())
|
||||||
|
|
||||||
def isWebLoaded(self):
|
def is_web_loaded(self):
|
||||||
"""
|
"""
|
||||||
Called by webView event to show display is fully loaded
|
Called by webView event to show display is fully loaded
|
||||||
"""
|
"""
|
||||||
log.debug(u'Webloaded')
|
log.debug(u'is web loaded')
|
||||||
self.webLoaded = True
|
self.webLoaded = True
|
||||||
|
|
||||||
|
|
||||||
@ -129,11 +126,11 @@ class MainDisplay(Display):
|
|||||||
"""
|
"""
|
||||||
Display.__init__(self, parent, live, controller)
|
Display.__init__(self, parent, live, controller)
|
||||||
self.screens = ScreenList()
|
self.screens = ScreenList()
|
||||||
self.rebuildCSS = False
|
self.rebuild_css = False
|
||||||
self.hideMode = None
|
self.hide_mode = None
|
||||||
self.override = {}
|
self.override = {}
|
||||||
self.retranslateUi()
|
self.retranslateUi()
|
||||||
self.mediaObject = None
|
self.media_object = None
|
||||||
if live:
|
if live:
|
||||||
self.audioPlayer = AudioPlayer(self)
|
self.audioPlayer = AudioPlayer(self)
|
||||||
else:
|
else:
|
||||||
@ -156,14 +153,14 @@ class MainDisplay(Display):
|
|||||||
self.setWindowState(QtCore.Qt.WindowFullScreen)
|
self.setWindowState(QtCore.Qt.WindowFullScreen)
|
||||||
self.setWindowFlags(windowFlags)
|
self.setWindowFlags(windowFlags)
|
||||||
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
|
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
|
||||||
self.setTransparency(False)
|
self.set_transparency(False)
|
||||||
if self.isLive:
|
if self.is_live:
|
||||||
Registry().register_function(u'live_display_hide', self.hide_display)
|
Registry().register_function(u'live_display_hide', self.hide_display)
|
||||||
Registry().register_function(u'live_display_show', self.show_display)
|
Registry().register_function(u'live_display_show', self.show_display)
|
||||||
Registry().register_function(u'update_display_css', self.css_changed)
|
Registry().register_function(u'update_display_css', self.css_changed)
|
||||||
Registry().register_function(u'config_updated', self.config_changed)
|
Registry().register_function(u'config_updated', self.config_changed)
|
||||||
|
|
||||||
def setTransparency(self, enabled):
|
def set_transparency(self, enabled):
|
||||||
"""
|
"""
|
||||||
Set the transparency of the window
|
Set the transparency of the window
|
||||||
"""
|
"""
|
||||||
@ -178,17 +175,17 @@ class MainDisplay(Display):
|
|||||||
"""
|
"""
|
||||||
We may need to rebuild the CSS on the live display.
|
We may need to rebuild the CSS on the live display.
|
||||||
"""
|
"""
|
||||||
self.rebuildCSS = True
|
self.rebuild_css = True
|
||||||
|
|
||||||
def config_changed(self):
|
def config_changed(self):
|
||||||
"""
|
"""
|
||||||
Call the plugins to rebuild the Live display CSS as the screen has
|
Call the plugins to rebuild the Live display CSS as the screen has
|
||||||
not been rebuild on exit of config.
|
not been rebuild on exit of config.
|
||||||
"""
|
"""
|
||||||
if self.rebuildCSS and self.plugin_manager.plugins:
|
if self.rebuild_css and self.plugin_manager.plugins:
|
||||||
for plugin in self.plugin_manager.plugins:
|
for plugin in self.plugin_manager.plugins:
|
||||||
plugin.refreshCss(self.frame)
|
plugin.refreshCss(self.frame)
|
||||||
self.rebuildCSS = False
|
self.rebuild_css = False
|
||||||
|
|
||||||
def retranslateUi(self):
|
def retranslateUi(self):
|
||||||
"""
|
"""
|
||||||
@ -200,11 +197,11 @@ class MainDisplay(Display):
|
|||||||
"""
|
"""
|
||||||
Set up and build the output screen
|
Set up and build the output screen
|
||||||
"""
|
"""
|
||||||
log.debug(u'Start MainDisplay setup (live = %s)' % self.isLive)
|
log.debug(u'Start MainDisplay setup (live = %s)' % self.is_live)
|
||||||
self.screen = self.screens.current
|
self.screen = self.screens.current
|
||||||
self.setVisible(False)
|
self.setVisible(False)
|
||||||
Display.setup(self)
|
Display.setup(self)
|
||||||
if self.isLive:
|
if self.is_live:
|
||||||
# Build the initial frame.
|
# Build the initial frame.
|
||||||
background_color = QtGui.QColor()
|
background_color = QtGui.QColor()
|
||||||
background_color.setNamedColor(Settings().value(u'advanced/default color'))
|
background_color.setNamedColor(Settings().value(u'advanced/default color'))
|
||||||
@ -225,7 +222,7 @@ class MainDisplay(Display):
|
|||||||
splash_image)
|
splash_image)
|
||||||
serviceItem = ServiceItem()
|
serviceItem = ServiceItem()
|
||||||
serviceItem.bg_image_bytes = image_to_byte(self.initialFrame)
|
serviceItem.bg_image_bytes = image_to_byte(self.initialFrame)
|
||||||
self.webView.setHtml(build_html(serviceItem, self.screen, self.isLive, None,
|
self.web_view.setHtml(build_html(serviceItem, self.screen, self.is_live, None,
|
||||||
plugins=self.plugin_manager.plugins))
|
plugins=self.plugin_manager.plugins))
|
||||||
self.__hideMouse()
|
self.__hideMouse()
|
||||||
log.debug(u'Finished MainDisplay setup')
|
log.debug(u'Finished MainDisplay setup')
|
||||||
@ -288,7 +285,7 @@ class MainDisplay(Display):
|
|||||||
self.setVisible(False)
|
self.setVisible(False)
|
||||||
self.setGeometry(self.screen[u'size'])
|
self.setGeometry(self.screen[u'size'])
|
||||||
|
|
||||||
def directImage(self, path, background):
|
def direct_image(self, path, background):
|
||||||
"""
|
"""
|
||||||
API for replacement backgrounds so Images are added directly to cache.
|
API for replacement backgrounds so Images are added directly to cache.
|
||||||
"""
|
"""
|
||||||
@ -299,7 +296,7 @@ class MainDisplay(Display):
|
|||||||
self.override[u'theme'] = self.serviceItem.themedata.background_filename
|
self.override[u'theme'] = self.serviceItem.themedata.background_filename
|
||||||
self.image(path)
|
self.image(path)
|
||||||
# Update the preview frame.
|
# Update the preview frame.
|
||||||
if self.isLive:
|
if self.is_live:
|
||||||
self.live_controller.updatePreview()
|
self.live_controller.updatePreview()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -316,9 +313,9 @@ class MainDisplay(Display):
|
|||||||
log.debug(u'image to display')
|
log.debug(u'image to display')
|
||||||
image = self.image_manager.get_image_bytes(path, ImageSource.ImagePlugin)
|
image = self.image_manager.get_image_bytes(path, ImageSource.ImagePlugin)
|
||||||
self.controller.media_controller.media_reset(self.controller)
|
self.controller.media_controller.media_reset(self.controller)
|
||||||
self.displayImage(image)
|
self.display_image(image)
|
||||||
|
|
||||||
def displayImage(self, image):
|
def display_image(self, image):
|
||||||
"""
|
"""
|
||||||
Display an image, as is.
|
Display an image, as is.
|
||||||
"""
|
"""
|
||||||
@ -329,16 +326,16 @@ class MainDisplay(Display):
|
|||||||
js = u'show_image("");'
|
js = u'show_image("");'
|
||||||
self.frame.evaluateJavaScript(js)
|
self.frame.evaluateJavaScript(js)
|
||||||
|
|
||||||
def resetImage(self):
|
def reset_image(self):
|
||||||
"""
|
"""
|
||||||
Reset the backgound image to the service item image. Used after the
|
Reset the background image to the service item image. Used after the
|
||||||
image plugin has changed the background.
|
image plugin has changed the background.
|
||||||
"""
|
"""
|
||||||
log.debug(u'resetImage')
|
log.debug(u'reset_image')
|
||||||
if hasattr(self, u'serviceItem'):
|
if hasattr(self, u'serviceItem'):
|
||||||
self.displayImage(self.serviceItem.bg_image_bytes)
|
self.display_image(self.serviceItem.bg_image_bytes)
|
||||||
else:
|
else:
|
||||||
self.displayImage(None)
|
self.display_image(None)
|
||||||
# clear the cache
|
# clear the cache
|
||||||
self.override = {}
|
self.override = {}
|
||||||
|
|
||||||
@ -346,24 +343,27 @@ class MainDisplay(Display):
|
|||||||
"""
|
"""
|
||||||
Generates a preview of the image displayed.
|
Generates a preview of the image displayed.
|
||||||
"""
|
"""
|
||||||
log.debug(u'preview for %s', self.isLive)
|
log.debug(u'preview for %s', self.is_live)
|
||||||
|
was_visible = self.isVisible()
|
||||||
self.application.process_events()
|
self.application.process_events()
|
||||||
# We must have a service item to preview.
|
# We must have a service item to preview.
|
||||||
if self.isLive and hasattr(self, u'serviceItem'):
|
if self.is_live and hasattr(self, u'serviceItem'):
|
||||||
# Wait for the fade to finish before geting the preview.
|
# Wait for the fade to finish before geting the preview.
|
||||||
# Important otherwise preview will have incorrect text if at all!
|
# Important otherwise preview will have incorrect text if at all!
|
||||||
if self.serviceItem.themedata and self.serviceItem.themedata.display_slide_transition:
|
if self.serviceItem.themedata and self.serviceItem.themedata.display_slide_transition:
|
||||||
while self.frame.evaluateJavaScript(u'show_text_complete()') == u'false':
|
while not self.frame.evaluateJavaScript(u'show_text_completed()'):
|
||||||
self.application.process_events()
|
self.application.process_events()
|
||||||
# Wait for the webview to update before getting the preview.
|
# Wait for the webview to update before getting the preview.
|
||||||
# Important otherwise first preview will miss the background !
|
# Important otherwise first preview will miss the background !
|
||||||
while not self.webLoaded:
|
while not self.webLoaded:
|
||||||
self.application.process_events()
|
self.application.process_events()
|
||||||
# if was hidden keep it hidden
|
# if was hidden keep it hidden
|
||||||
if self.isLive:
|
if self.is_live:
|
||||||
if self.hideMode:
|
if self.hide_mode:
|
||||||
self.hide_display(self.hideMode)
|
self.hide_display(self.hide_mode)
|
||||||
else:
|
# Only continue if the visibility wasn't changed during method call.
|
||||||
|
elif was_visible == self.isVisible():
|
||||||
|
|
||||||
# Single screen active
|
# Single screen active
|
||||||
if self.screens.display_count == 1:
|
if self.screens.display_count == 1:
|
||||||
# Only make visible if setting enabled.
|
# Only make visible if setting enabled.
|
||||||
@ -373,12 +373,12 @@ class MainDisplay(Display):
|
|||||||
self.setVisible(True)
|
self.setVisible(True)
|
||||||
return QtGui.QPixmap.grabWidget(self)
|
return QtGui.QPixmap.grabWidget(self)
|
||||||
|
|
||||||
def buildHtml(self, serviceItem, image_path=u''):
|
def build_html(self, serviceItem, image_path=u''):
|
||||||
"""
|
"""
|
||||||
Store the serviceItem and build the new HTML from it. Add the
|
Store the serviceItem and build the new HTML from it. Add the
|
||||||
HTML to the display
|
HTML to the display
|
||||||
"""
|
"""
|
||||||
log.debug(u'buildHtml')
|
log.debug(u'build_html')
|
||||||
self.webLoaded = False
|
self.webLoaded = False
|
||||||
self.initialFrame = None
|
self.initialFrame = None
|
||||||
self.serviceItem = serviceItem
|
self.serviceItem = serviceItem
|
||||||
@ -396,30 +396,29 @@ class MainDisplay(Display):
|
|||||||
else:
|
else:
|
||||||
# replace the background
|
# replace the background
|
||||||
background = self.image_manager.get_image_bytes(self.override[u'image'], ImageSource.ImagePlugin)
|
background = self.image_manager.get_image_bytes(self.override[u'image'], ImageSource.ImagePlugin)
|
||||||
self.setTransparency(self.serviceItem.themedata.background_type ==
|
self.set_transparency(self.serviceItem.themedata.background_type ==
|
||||||
BackgroundType.to_string(BackgroundType.Transparent))
|
BackgroundType.to_string(BackgroundType.Transparent))
|
||||||
if self.serviceItem.themedata.background_filename:
|
if self.serviceItem.themedata.background_filename:
|
||||||
self.serviceItem.bg_image_bytes = self.image_manager.get_image_bytes(
|
self.serviceItem.bg_image_bytes = self.image_manager.get_image_bytes(
|
||||||
self.serviceItem.themedata.background_filename,
|
self.serviceItem.themedata.background_filename, ImageSource.Theme
|
||||||
ImageSource.Theme
|
|
||||||
)
|
)
|
||||||
if image_path:
|
if image_path:
|
||||||
image_bytes = self.image_manager.get_image_bytes(image_path, ImageSource.ImagePlugin)
|
image_bytes = self.image_manager.get_image_bytes(image_path, ImageSource.ImagePlugin)
|
||||||
else:
|
else:
|
||||||
image_bytes = None
|
image_bytes = None
|
||||||
html = build_html(self.serviceItem, self.screen, self.isLive, background, image_bytes,
|
html = build_html(self.serviceItem, self.screen, self.is_live, background, image_bytes,
|
||||||
plugins=self.plugin_manager.plugins)
|
plugins=self.plugin_manager.plugins)
|
||||||
log.debug(u'buildHtml - pre setHtml')
|
log.debug(u'buildHtml - pre setHtml')
|
||||||
self.webView.setHtml(html)
|
self.web_view.setHtml(html)
|
||||||
log.debug(u'buildHtml - post setHtml')
|
log.debug(u'buildHtml - post setHtml')
|
||||||
if serviceItem.foot_text:
|
if serviceItem.foot_text:
|
||||||
self.footer(serviceItem.foot_text)
|
self.footer(serviceItem.foot_text)
|
||||||
# if was hidden keep it hidden
|
# if was hidden keep it hidden
|
||||||
if self.hideMode and self.isLive and not serviceItem.is_media():
|
if self.hide_mode and self.is_live and not serviceItem.is_media():
|
||||||
if Settings().value(u'general/auto unblank'):
|
if Settings().value(u'general/auto unblank'):
|
||||||
Registry().execute(u'slidecontroller_live_unblank')
|
Registry().execute(u'slidecontroller_live_unblank')
|
||||||
else:
|
else:
|
||||||
self.hide_display(self.hideMode)
|
self.hide_display(self.hide_mode)
|
||||||
self.__hideMouse()
|
self.__hideMouse()
|
||||||
|
|
||||||
def footer(self, text):
|
def footer(self, text):
|
||||||
@ -450,13 +449,12 @@ class MainDisplay(Display):
|
|||||||
if mode != HideMode.Screen:
|
if mode != HideMode.Screen:
|
||||||
if self.isHidden():
|
if self.isHidden():
|
||||||
self.setVisible(True)
|
self.setVisible(True)
|
||||||
self.webView.setVisible(True)
|
self.web_view.setVisible(True)
|
||||||
self.hideMode = mode
|
self.hide_mode = mode
|
||||||
|
|
||||||
def show_display(self):
|
def show_display(self):
|
||||||
"""
|
"""
|
||||||
Show the stored layers so the screen reappears as it was
|
Show the stored layers so the screen reappears as it was originally.
|
||||||
originally.
|
|
||||||
Make the stored images None to release memory.
|
Make the stored images None to release memory.
|
||||||
"""
|
"""
|
||||||
log.debug(u'show_display')
|
log.debug(u'show_display')
|
||||||
@ -467,9 +465,9 @@ class MainDisplay(Display):
|
|||||||
self.frame.evaluateJavaScript('show_blank("show");')
|
self.frame.evaluateJavaScript('show_blank("show");')
|
||||||
if self.isHidden():
|
if self.isHidden():
|
||||||
self.setVisible(True)
|
self.setVisible(True)
|
||||||
self.hideMode = None
|
self.hide_mode = None
|
||||||
# Trigger actions when display is active again.
|
# Trigger actions when display is active again.
|
||||||
if self.isLive:
|
if self.is_live:
|
||||||
Registry().execute(u'live_display_active')
|
Registry().execute(u'live_display_active')
|
||||||
|
|
||||||
def __hideMouse(self):
|
def __hideMouse(self):
|
||||||
@ -543,38 +541,38 @@ class AudioPlayer(QtCore.QObject):
|
|||||||
self.currentIndex = -1
|
self.currentIndex = -1
|
||||||
self.playlist = []
|
self.playlist = []
|
||||||
self.repeat = False
|
self.repeat = False
|
||||||
self.mediaObject = Phonon.MediaObject()
|
self.media_object = Phonon.MediaObject()
|
||||||
self.mediaObject.setTickInterval(100)
|
self.media_object.setTickInterval(100)
|
||||||
self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory)
|
self.audio_object = Phonon.AudioOutput(Phonon.VideoCategory)
|
||||||
Phonon.createPath(self.mediaObject, self.audioObject)
|
Phonon.createPath(self.media_object, self.audio_object)
|
||||||
QtCore.QObject.connect(self.mediaObject, QtCore.SIGNAL(u'aboutToFinish()'), self.onAboutToFinish)
|
self.media_object.aboutToFinish.connect(self.on_about_to_finish)
|
||||||
QtCore.QObject.connect(self.mediaObject, QtCore.SIGNAL(u'finished()'), self.onFinished)
|
self.media_object.finished.connect(self.on_finished)
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
"""
|
"""
|
||||||
Shutting down so clean up connections
|
Shutting down so clean up connections
|
||||||
"""
|
"""
|
||||||
self.stop()
|
self.stop()
|
||||||
for path in self.mediaObject.outputPaths():
|
for path in self.media_object.outputPaths():
|
||||||
path.disconnect()
|
path.disconnect()
|
||||||
|
|
||||||
def onAboutToFinish(self):
|
def on_about_to_finish(self):
|
||||||
"""
|
"""
|
||||||
Just before the audio player finishes the current track, queue the next
|
Just before the audio player finishes the current track, queue the next
|
||||||
item in the playlist, if there is one.
|
item in the playlist, if there is one.
|
||||||
"""
|
"""
|
||||||
self.currentIndex += 1
|
self.currentIndex += 1
|
||||||
if len(self.playlist) > self.currentIndex:
|
if len(self.playlist) > self.currentIndex:
|
||||||
self.mediaObject.enqueue(self.playlist[self.currentIndex])
|
self.media_object.enqueue(self.playlist[self.currentIndex])
|
||||||
|
|
||||||
def onFinished(self):
|
def on_finished(self):
|
||||||
"""
|
"""
|
||||||
When the audio track finishes.
|
When the audio track finishes.
|
||||||
"""
|
"""
|
||||||
if self.repeat:
|
if self.repeat:
|
||||||
log.debug(u'Repeat is enabled... here we go again!')
|
log.debug(u'Repeat is enabled... here we go again!')
|
||||||
self.mediaObject.clearQueue()
|
self.media_object.clearQueue()
|
||||||
self.mediaObject.clear()
|
self.media_object.clear()
|
||||||
self.currentIndex = -1
|
self.currentIndex = -1
|
||||||
self.play()
|
self.play()
|
||||||
|
|
||||||
@ -582,7 +580,7 @@ class AudioPlayer(QtCore.QObject):
|
|||||||
"""
|
"""
|
||||||
Connect the volume slider to the output channel.
|
Connect the volume slider to the output channel.
|
||||||
"""
|
"""
|
||||||
slider.setAudioOutput(self.audioObject)
|
slider.setAudioOutput(self.audio_object)
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
"""
|
"""
|
||||||
@ -591,7 +589,7 @@ class AudioPlayer(QtCore.QObject):
|
|||||||
self.currentIndex = -1
|
self.currentIndex = -1
|
||||||
self.playlist = []
|
self.playlist = []
|
||||||
self.stop()
|
self.stop()
|
||||||
self.mediaObject.clear()
|
self.media_object.clear()
|
||||||
|
|
||||||
def play(self):
|
def play(self):
|
||||||
"""
|
"""
|
||||||
@ -599,24 +597,24 @@ class AudioPlayer(QtCore.QObject):
|
|||||||
"""
|
"""
|
||||||
log.debug(u'AudioPlayer.play() called')
|
log.debug(u'AudioPlayer.play() called')
|
||||||
if self.currentIndex == -1:
|
if self.currentIndex == -1:
|
||||||
self.onAboutToFinish()
|
self.on_about_to_finish()
|
||||||
self.mediaObject.play()
|
self.media_object.play()
|
||||||
|
|
||||||
def pause(self):
|
def pause(self):
|
||||||
"""
|
"""
|
||||||
Pause the Audio
|
Pause the Audio
|
||||||
"""
|
"""
|
||||||
log.debug(u'AudioPlayer.pause() called')
|
log.debug(u'AudioPlayer.pause() called')
|
||||||
self.mediaObject.pause()
|
self.media_object.pause()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
"""
|
"""
|
||||||
Stop the Audio and clean up
|
Stop the Audio and clean up
|
||||||
"""
|
"""
|
||||||
log.debug(u'AudioPlayer.stop() called')
|
log.debug(u'AudioPlayer.stop() called')
|
||||||
self.mediaObject.stop()
|
self.media_object.stop()
|
||||||
|
|
||||||
def addToPlaylist(self, filenames):
|
def add_to_playlist(self, filenames):
|
||||||
"""
|
"""
|
||||||
Add another file to the playlist.
|
Add another file to the playlist.
|
||||||
|
|
||||||
@ -633,31 +631,30 @@ class AudioPlayer(QtCore.QObject):
|
|||||||
"""
|
"""
|
||||||
if not self.repeat and self.currentIndex + 1 >= len(self.playlist):
|
if not self.repeat and self.currentIndex + 1 >= len(self.playlist):
|
||||||
return
|
return
|
||||||
isPlaying = self.mediaObject.state() == Phonon.PlayingState
|
isPlaying = self.media_object.state() == Phonon.PlayingState
|
||||||
self.currentIndex += 1
|
self.currentIndex += 1
|
||||||
if self.repeat and self.currentIndex == len(self.playlist):
|
if self.repeat and self.currentIndex == len(self.playlist):
|
||||||
self.currentIndex = 0
|
self.currentIndex = 0
|
||||||
self.mediaObject.clearQueue()
|
self.media_object.clearQueue()
|
||||||
self.mediaObject.clear()
|
self.media_object.clear()
|
||||||
self.mediaObject.enqueue(self.playlist[self.currentIndex])
|
self.media_object.enqueue(self.playlist[self.currentIndex])
|
||||||
if isPlaying:
|
if isPlaying:
|
||||||
self.mediaObject.play()
|
self.media_object.play()
|
||||||
|
|
||||||
def goTo(self, index):
|
def go_to(self, index):
|
||||||
"""
|
"""
|
||||||
Go to a particular track in the list
|
Go to a particular track in the list
|
||||||
"""
|
"""
|
||||||
isPlaying = self.mediaObject.state() == Phonon.PlayingState
|
isPlaying = self.media_object.state() == Phonon.PlayingState
|
||||||
self.mediaObject.clearQueue()
|
self.media_object.clearQueue()
|
||||||
self.mediaObject.clear()
|
self.media_object.clear()
|
||||||
self.currentIndex = index
|
self.currentIndex = index
|
||||||
self.mediaObject.enqueue(self.playlist[self.currentIndex])
|
self.media_object.enqueue(self.playlist[self.currentIndex])
|
||||||
if isPlaying:
|
if isPlaying:
|
||||||
self.mediaObject.play()
|
self.media_object.play()
|
||||||
|
|
||||||
#@todo is this used?
|
|
||||||
def connectSlot(self, signal, slot):
|
def connectSlot(self, signal, slot):
|
||||||
"""
|
"""
|
||||||
Connect a slot to a signal on the media object
|
Connect a slot to a signal on the media object. Used by slidecontroller to connect to audio object.
|
||||||
"""
|
"""
|
||||||
QtCore.QObject.connect(self.mediaObject, signal, slot)
|
QtCore.QObject.connect(self.media_object, signal, slot)
|
@ -105,13 +105,13 @@ class Ui_MainWindow(object):
|
|||||||
self.controlSplitter.setObjectName(u'controlSplitter')
|
self.controlSplitter.setObjectName(u'controlSplitter')
|
||||||
self.mainContentLayout.addWidget(self.controlSplitter)
|
self.mainContentLayout.addWidget(self.controlSplitter)
|
||||||
# Create slide controllers
|
# Create slide controllers
|
||||||
self.previewController = SlideController(self)
|
self.preview_controller = SlideController(self)
|
||||||
self.liveController = SlideController(self, True)
|
self.live_controller = SlideController(self, True)
|
||||||
previewVisible = Settings().value(u'user interface/preview panel')
|
previewVisible = Settings().value(u'user interface/preview panel')
|
||||||
self.previewController.panel.setVisible(previewVisible)
|
self.preview_controller.panel.setVisible(previewVisible)
|
||||||
liveVisible = Settings().value(u'user interface/live panel')
|
liveVisible = Settings().value(u'user interface/live panel')
|
||||||
panelLocked = Settings().value(u'user interface/lock panel')
|
panelLocked = Settings().value(u'user interface/lock panel')
|
||||||
self.liveController.panel.setVisible(liveVisible)
|
self.live_controller.panel.setVisible(liveVisible)
|
||||||
# Create menu
|
# Create menu
|
||||||
self.menuBar = QtGui.QMenuBar(main_window)
|
self.menuBar = QtGui.QMenuBar(main_window)
|
||||||
self.menuBar.setObjectName(u'menuBar')
|
self.menuBar.setObjectName(u'menuBar')
|
||||||
@ -119,18 +119,18 @@ class Ui_MainWindow(object):
|
|||||||
self.fileMenu.setObjectName(u'fileMenu')
|
self.fileMenu.setObjectName(u'fileMenu')
|
||||||
self.recentFilesMenu = QtGui.QMenu(self.fileMenu)
|
self.recentFilesMenu = QtGui.QMenu(self.fileMenu)
|
||||||
self.recentFilesMenu.setObjectName(u'recentFilesMenu')
|
self.recentFilesMenu.setObjectName(u'recentFilesMenu')
|
||||||
self.fileImportMenu = QtGui.QMenu(self.fileMenu)
|
self.file_import_menu = QtGui.QMenu(self.fileMenu)
|
||||||
self.fileImportMenu.setObjectName(u'fileImportMenu')
|
self.file_import_menu.setObjectName(u'file_import_menu')
|
||||||
self.fileExportMenu = QtGui.QMenu(self.fileMenu)
|
self.file_export_menu = QtGui.QMenu(self.fileMenu)
|
||||||
self.fileExportMenu.setObjectName(u'fileExportMenu')
|
self.file_export_menu.setObjectName(u'file_export_menu')
|
||||||
# View Menu
|
# View Menu
|
||||||
self.viewMenu = QtGui.QMenu(self.menuBar)
|
self.viewMenu = QtGui.QMenu(self.menuBar)
|
||||||
self.viewMenu.setObjectName(u'viewMenu')
|
self.viewMenu.setObjectName(u'viewMenu')
|
||||||
self.viewModeMenu = QtGui.QMenu(self.viewMenu)
|
self.viewModeMenu = QtGui.QMenu(self.viewMenu)
|
||||||
self.viewModeMenu.setObjectName(u'viewModeMenu')
|
self.viewModeMenu.setObjectName(u'viewModeMenu')
|
||||||
# Tools Menu
|
# Tools Menu
|
||||||
self.toolsMenu = QtGui.QMenu(self.menuBar)
|
self.tools_menu = QtGui.QMenu(self.menuBar)
|
||||||
self.toolsMenu.setObjectName(u'toolsMenu')
|
self.tools_menu.setObjectName(u'tools_menu')
|
||||||
# Settings Menu
|
# Settings Menu
|
||||||
self.settingsMenu = QtGui.QMenu(self.menuBar)
|
self.settingsMenu = QtGui.QMenu(self.menuBar)
|
||||||
self.settingsMenu.setObjectName(u'settingsMenu')
|
self.settingsMenu.setObjectName(u'settingsMenu')
|
||||||
@ -174,99 +174,101 @@ class Ui_MainWindow(object):
|
|||||||
main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.themeManagerDock)
|
main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.themeManagerDock)
|
||||||
# Create the menu items
|
# Create the menu items
|
||||||
action_list = ActionList.get_instance()
|
action_list = ActionList.get_instance()
|
||||||
action_list.add_category(UiStrings().File, CategoryOrder.standardMenu)
|
action_list.add_category(UiStrings().File, CategoryOrder.standard_menu)
|
||||||
self.fileNewItem = create_action(main_window, u'fileNewItem',
|
self.fileNewItem = create_action(main_window, u'fileNewItem',
|
||||||
icon=u':/general/general_new.png',
|
icon=u':/general/general_new.png',
|
||||||
shortcuts=[QtGui.QKeySequence(u'Ctrl+N')],
|
can_shortcuts=True,
|
||||||
category=UiStrings().File,
|
category=UiStrings().File,
|
||||||
triggers=self.serviceManagerContents.on_new_service_clicked)
|
triggers=self.serviceManagerContents.on_new_service_clicked)
|
||||||
self.fileOpenItem = create_action(main_window, u'fileOpenItem',
|
self.fileOpenItem = create_action(main_window, u'fileOpenItem',
|
||||||
icon=u':/general/general_open.png',
|
icon=u':/general/general_open.png',
|
||||||
shortcuts=[QtGui.QKeySequence(u'Ctrl+O')],
|
can_shortcuts=True,
|
||||||
category=UiStrings().File,
|
category=UiStrings().File,
|
||||||
triggers=self.serviceManagerContents.on_load_service_clicked)
|
triggers=self.serviceManagerContents.on_load_service_clicked)
|
||||||
self.fileSaveItem = create_action(main_window, u'fileSaveItem',
|
self.fileSaveItem = create_action(main_window, u'fileSaveItem',
|
||||||
icon=u':/general/general_save.png',
|
icon=u':/general/general_save.png',
|
||||||
shortcuts=[QtGui.QKeySequence(u'Ctrl+S')],
|
can_shortcuts=True,
|
||||||
category=UiStrings().File,
|
category=UiStrings().File,
|
||||||
triggers=self.serviceManagerContents.save_file)
|
triggers=self.serviceManagerContents.save_file)
|
||||||
self.fileSaveAsItem = create_action(main_window, u'fileSaveAsItem',
|
self.fileSaveAsItem = create_action(main_window, u'fileSaveAsItem',
|
||||||
shortcuts=[QtGui.QKeySequence(u'Ctrl+Shift+S')],
|
can_shortcuts=True,
|
||||||
category=UiStrings().File,
|
category=UiStrings().File,
|
||||||
triggers=self.serviceManagerContents.save_file_as)
|
triggers=self.serviceManagerContents.save_file_as)
|
||||||
self.printServiceOrderItem = create_action(main_window,
|
self.printServiceOrderItem = create_action(main_window,
|
||||||
u'printServiceItem', shortcuts=[QtGui.QKeySequence(u'Ctrl+P')],
|
u'printServiceItem', can_shortcuts=True,
|
||||||
category=UiStrings().File,
|
category=UiStrings().File,
|
||||||
triggers=self.serviceManagerContents.print_service_order)
|
triggers=self.serviceManagerContents.print_service_order)
|
||||||
self.fileExitItem = create_action(main_window, u'fileExitItem',
|
self.fileExitItem = create_action(main_window, u'fileExitItem',
|
||||||
icon=u':/system/system_exit.png',
|
icon=u':/system/system_exit.png',
|
||||||
shortcuts=[QtGui.QKeySequence(u'Alt+F4')],
|
can_shortcuts=True,
|
||||||
category=UiStrings().File, triggers=main_window.close)
|
category=UiStrings().File, triggers=main_window.close)
|
||||||
# Give QT Extra Hint that this is the Exit Menu Item
|
# Give QT Extra Hint that this is the Exit Menu Item
|
||||||
self.fileExitItem.setMenuRole(QtGui.QAction.QuitRole)
|
self.fileExitItem.setMenuRole(QtGui.QAction.QuitRole)
|
||||||
action_list.add_category(UiStrings().Import, CategoryOrder.standardMenu)
|
action_list.add_category(UiStrings().Import, CategoryOrder.standard_menu)
|
||||||
self.importThemeItem = create_action(main_window, u'importThemeItem', category=UiStrings().Import)
|
self.importThemeItem = create_action(
|
||||||
|
main_window, u'importThemeItem', category=UiStrings().Import, can_shortcuts=True)
|
||||||
self.importLanguageItem = create_action(main_window, u'importLanguageItem')
|
self.importLanguageItem = create_action(main_window, u'importLanguageItem')
|
||||||
action_list.add_category(UiStrings().Export, CategoryOrder.standardMenu)
|
action_list.add_category(UiStrings().Export, CategoryOrder.standard_menu)
|
||||||
self.exportThemeItem = create_action(main_window, u'exportThemeItem', category=UiStrings().Export)
|
self.exportThemeItem = create_action(
|
||||||
|
main_window, u'exportThemeItem', category=UiStrings().Export, can_shortcuts=True)
|
||||||
self.exportLanguageItem = create_action(main_window, u'exportLanguageItem')
|
self.exportLanguageItem = create_action(main_window, u'exportLanguageItem')
|
||||||
action_list.add_category(UiStrings().View, CategoryOrder.standardMenu)
|
action_list.add_category(UiStrings().View, CategoryOrder.standard_menu)
|
||||||
self.viewMediaManagerItem = create_action(main_window,
|
self.viewMediaManagerItem = create_action(main_window,
|
||||||
u'viewMediaManagerItem', shortcuts=[QtGui.QKeySequence(u'F8')],
|
u'viewMediaManagerItem',
|
||||||
icon=u':/system/system_mediamanager.png',
|
icon=u':/system/system_mediamanager.png',
|
||||||
checked=self.mediaManagerDock.isVisible(),
|
checked=self.mediaManagerDock.isVisible(),
|
||||||
|
can_shortcuts=True,
|
||||||
category=UiStrings().View, triggers=self.toggleMediaManager)
|
category=UiStrings().View, triggers=self.toggleMediaManager)
|
||||||
self.viewThemeManagerItem = create_action(main_window,
|
self.viewThemeManagerItem = create_action(main_window,
|
||||||
u'viewThemeManagerItem', shortcuts=[QtGui.QKeySequence(u'F10')],
|
u'viewThemeManagerItem', can_shortcuts=True,
|
||||||
icon=u':/system/system_thememanager.png',
|
icon=u':/system/system_thememanager.png',
|
||||||
checked=self.themeManagerDock.isVisible(),
|
checked=self.themeManagerDock.isVisible(),
|
||||||
category=UiStrings().View, triggers=self.toggleThemeManager)
|
category=UiStrings().View, triggers=self.toggleThemeManager)
|
||||||
self.viewServiceManagerItem = create_action(main_window,
|
self.viewServiceManagerItem = create_action(main_window,
|
||||||
u'viewServiceManagerItem', shortcuts=[QtGui.QKeySequence(u'F9')],
|
u'viewServiceManagerItem', can_shortcuts=True,
|
||||||
icon=u':/system/system_servicemanager.png',
|
icon=u':/system/system_servicemanager.png',
|
||||||
checked=self.serviceManagerDock.isVisible(),
|
checked=self.serviceManagerDock.isVisible(),
|
||||||
category=UiStrings().View, triggers=self.toggleServiceManager)
|
category=UiStrings().View, triggers=self.toggleServiceManager)
|
||||||
self.viewPreviewPanel = create_action(main_window, u'viewPreviewPanel',
|
self.viewPreviewPanel = create_action(main_window, u'viewPreviewPanel',
|
||||||
shortcuts=[QtGui.QKeySequence(u'F11')], checked=previewVisible,
|
can_shortcuts=True, checked=previewVisible,
|
||||||
category=UiStrings().View, triggers=self.setPreviewPanelVisibility)
|
category=UiStrings().View, triggers=self.setPreviewPanelVisibility)
|
||||||
self.viewLivePanel = create_action(main_window, u'viewLivePanel',
|
self.viewLivePanel = create_action(main_window, u'viewLivePanel',
|
||||||
shortcuts=[QtGui.QKeySequence(u'F12')], checked=liveVisible,
|
can_shortcuts=True, checked=liveVisible,
|
||||||
category=UiStrings().View, triggers=self.setLivePanelVisibility)
|
category=UiStrings().View, triggers=self.setLivePanelVisibility)
|
||||||
self.lockPanel = create_action(main_window, u'lockPanel',
|
self.lockPanel = create_action(main_window, u'lockPanel',
|
||||||
checked=panelLocked, triggers=self.setLockPanel)
|
can_shortcuts=True, checked=panelLocked,
|
||||||
action_list.add_category(UiStrings().ViewMode,
|
category=UiStrings().View,
|
||||||
CategoryOrder.standardMenu)
|
triggers=self.setLockPanel)
|
||||||
self.modeDefaultItem = create_action(main_window, u'modeDefaultItem', checked=False,
|
action_list.add_category(UiStrings().ViewMode, CategoryOrder.standard_menu)
|
||||||
category=UiStrings().ViewMode)
|
self.modeDefaultItem = create_action(
|
||||||
self.modeSetupItem = create_action(main_window, u'modeSetupItem', checked=False, category=UiStrings().ViewMode)
|
main_window, u'modeDefaultItem', checked=False, category=UiStrings().ViewMode, can_shortcuts=True)
|
||||||
self.modeLiveItem = create_action(main_window, u'modeLiveItem', checked=True, category=UiStrings().ViewMode)
|
self.modeSetupItem = create_action(
|
||||||
|
main_window, u'modeSetupItem', checked=False, category=UiStrings().ViewMode, can_shortcuts=True)
|
||||||
|
self.modeLiveItem = create_action(
|
||||||
|
main_window, u'modeLiveItem', checked=True, category=UiStrings().ViewMode, can_shortcuts=True)
|
||||||
self.modeGroup = QtGui.QActionGroup(main_window)
|
self.modeGroup = QtGui.QActionGroup(main_window)
|
||||||
self.modeGroup.addAction(self.modeDefaultItem)
|
self.modeGroup.addAction(self.modeDefaultItem)
|
||||||
self.modeGroup.addAction(self.modeSetupItem)
|
self.modeGroup.addAction(self.modeSetupItem)
|
||||||
self.modeGroup.addAction(self.modeLiveItem)
|
self.modeGroup.addAction(self.modeLiveItem)
|
||||||
self.modeDefaultItem.setChecked(True)
|
self.modeDefaultItem.setChecked(True)
|
||||||
action_list.add_category(UiStrings().Tools, CategoryOrder.standardMenu)
|
action_list.add_category(UiStrings().Tools, CategoryOrder.standard_menu)
|
||||||
self.toolsAddToolItem = create_action(main_window,
|
self.toolsAddToolItem = create_action(main_window,
|
||||||
u'toolsAddToolItem', icon=u':/tools/tools_add.png',
|
u'toolsAddToolItem', icon=u':/tools/tools_add.png', category=UiStrings().Tools, can_shortcuts=True)
|
||||||
category=UiStrings().Tools)
|
|
||||||
self.toolsOpenDataFolder = create_action(main_window,
|
self.toolsOpenDataFolder = create_action(main_window,
|
||||||
u'toolsOpenDataFolder', icon=u':/general/general_open.png',
|
u'toolsOpenDataFolder', icon=u':/general/general_open.png', category=UiStrings().Tools, can_shortcuts=True)
|
||||||
category=UiStrings().Tools)
|
|
||||||
self.toolsFirstTimeWizard = create_action(main_window,
|
self.toolsFirstTimeWizard = create_action(main_window,
|
||||||
u'toolsFirstTimeWizard', icon=u':/general/general_revert.png',
|
u'toolsFirstTimeWizard', icon=u':/general/general_revert.png',
|
||||||
category=UiStrings().Tools)
|
category=UiStrings().Tools, can_shortcuts=True)
|
||||||
self.updateThemeImages = create_action(main_window,
|
self.updateThemeImages = create_action(main_window,
|
||||||
u'updateThemeImages', category=UiStrings().Tools)
|
u'updateThemeImages', category=UiStrings().Tools, can_shortcuts=True)
|
||||||
action_list.add_category(UiStrings().Settings,
|
action_list.add_category(UiStrings().Settings, CategoryOrder.standard_menu)
|
||||||
CategoryOrder.standardMenu)
|
|
||||||
self.settingsPluginListItem = create_action(main_window,
|
self.settingsPluginListItem = create_action(main_window,
|
||||||
u'settingsPluginListItem',
|
u'settingsPluginListItem',
|
||||||
icon=u':/system/settings_plugin_list.png',
|
icon=u':/system/settings_plugin_list.png',
|
||||||
shortcuts=[QtGui.QKeySequence(u'Alt+F7')],
|
can_shortcuts=True,
|
||||||
category=UiStrings().Settings, triggers=self.onPluginItemClicked)
|
category=UiStrings().Settings, triggers=self.onPluginItemClicked)
|
||||||
# i18n Language Items
|
# i18n Language Items
|
||||||
self.autoLanguageItem = create_action(main_window, u'autoLanguageItem',
|
self.autoLanguageItem = create_action(main_window, u'autoLanguageItem', checked=LanguageManager.auto_language)
|
||||||
checked=LanguageManager.auto_language)
|
|
||||||
self.languageGroup = QtGui.QActionGroup(main_window)
|
self.languageGroup = QtGui.QActionGroup(main_window)
|
||||||
self.languageGroup.setExclusive(True)
|
self.languageGroup.setExclusive(True)
|
||||||
self.languageGroup.setObjectName(u'languageGroup')
|
self.languageGroup.setObjectName(u'languageGroup')
|
||||||
@ -277,20 +279,21 @@ class Ui_MainWindow(object):
|
|||||||
languageItem = create_action(main_window, key, checked=qmList[key] == savedLanguage)
|
languageItem = create_action(main_window, key, checked=qmList[key] == savedLanguage)
|
||||||
add_actions(self.languageGroup, [languageItem])
|
add_actions(self.languageGroup, [languageItem])
|
||||||
self.settingsShortcutsItem = create_action(main_window, u'settingsShortcutsItem',
|
self.settingsShortcutsItem = create_action(main_window, u'settingsShortcutsItem',
|
||||||
icon=u':/system/system_configure_shortcuts.png', category=UiStrings().Settings)
|
icon=u':/system/system_configure_shortcuts.png', category=UiStrings().Settings, can_shortcuts=True)
|
||||||
# Formatting Tags were also known as display tags.
|
# Formatting Tags were also known as display tags.
|
||||||
self.formattingTagItem = create_action(main_window, u'displayTagItem',
|
self.formattingTagItem = create_action(main_window, u'displayTagItem',
|
||||||
icon=u':/system/tag_editor.png', category=UiStrings().Settings)
|
icon=u':/system/tag_editor.png', category=UiStrings().Settings, can_shortcuts=True)
|
||||||
self.settingsConfigureItem = create_action(main_window, u'settingsConfigureItem',
|
self.settingsConfigureItem = create_action(main_window, u'settingsConfigureItem',
|
||||||
icon=u':/system/system_settings.png', category=UiStrings().Settings)
|
icon=u':/system/system_settings.png', can_shortcuts=True, category=UiStrings().Settings)
|
||||||
# Give QT Extra Hint that this is the Preferences Menu Item
|
# Give QT Extra Hint that this is the Preferences Menu Item
|
||||||
self.settingsConfigureItem.setMenuRole(QtGui.QAction.PreferencesRole)
|
self.settingsConfigureItem.setMenuRole(QtGui.QAction.PreferencesRole)
|
||||||
self.settingsImportItem = create_action(main_window, u'settingsImportItem', category=UiStrings().Settings)
|
self.settingsImportItem = create_action(
|
||||||
self.settingsExportItem = create_action(main_window, u'settingsExportItem', category=UiStrings().Settings)
|
main_window, u'settingsImportItem', category=UiStrings().Import, can_shortcuts=True)
|
||||||
action_list.add_category(UiStrings().Help, CategoryOrder.standardMenu)
|
self.settingsExportItem = create_action(
|
||||||
|
main_window, u'settingsExportItem', category=UiStrings().Export, can_shortcuts=True)
|
||||||
|
action_list.add_category(UiStrings().Help, CategoryOrder.standard_menu)
|
||||||
self.aboutItem = create_action(main_window, u'aboutItem', icon=u':/system/system_about.png',
|
self.aboutItem = create_action(main_window, u'aboutItem', icon=u':/system/system_about.png',
|
||||||
shortcuts=[QtGui.QKeySequence(u'Ctrl+F1')],
|
can_shortcuts=True, category=UiStrings().Help, triggers=self.onAboutItemClicked)
|
||||||
category=UiStrings().Help, triggers=self.onAboutItemClicked)
|
|
||||||
# Give QT Extra Hint that this is an About Menu Item
|
# Give QT Extra Hint that this is an About Menu Item
|
||||||
self.aboutItem.setMenuRole(QtGui.QAction.AboutRole)
|
self.aboutItem.setMenuRole(QtGui.QAction.AboutRole)
|
||||||
if os.name == u'nt':
|
if os.name == u'nt':
|
||||||
@ -298,18 +301,20 @@ class Ui_MainWindow(object):
|
|||||||
AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm')
|
AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm')
|
||||||
self.offlineHelpItem = create_action(main_window, u'offlineHelpItem',
|
self.offlineHelpItem = create_action(main_window, u'offlineHelpItem',
|
||||||
icon=u':/system/system_help_contents.png',
|
icon=u':/system/system_help_contents.png',
|
||||||
shortcuts=[QtGui.QKeySequence(u'F1')],
|
can_shortcuts=True,
|
||||||
category=UiStrings().Help, triggers=self.onOfflineHelpClicked)
|
category=UiStrings().Help, triggers=self.onOfflineHelpClicked)
|
||||||
self.onlineHelpItem = create_action(main_window, u'onlineHelpItem',
|
self.onlineHelpItem = create_action(main_window, u'onlineHelpItem',
|
||||||
icon=u':/system/system_online_help.png',
|
icon=u':/system/system_online_help.png',
|
||||||
shortcuts=[QtGui.QKeySequence(u'Alt+F1')],
|
can_shortcuts=True,
|
||||||
category=UiStrings().Help, triggers=self.onOnlineHelpClicked)
|
category=UiStrings().Help, triggers=self.onOnlineHelpClicked)
|
||||||
self.webSiteItem = create_action(main_window, u'webSiteItem', category=UiStrings().Help)
|
self.webSiteItem = create_action(main_window, u'webSiteItem', can_shortcuts=True, category=UiStrings().Help)
|
||||||
add_actions(self.fileImportMenu, (self.settingsImportItem, None, self.importThemeItem, self.importLanguageItem))
|
add_actions(self.file_import_menu, (self.settingsImportItem, None, self.importThemeItem,
|
||||||
add_actions(self.fileExportMenu, (self.settingsExportItem, None, self.exportThemeItem, self.exportLanguageItem))
|
self.importLanguageItem))
|
||||||
|
add_actions(self.file_export_menu, (self.settingsExportItem, None, self.exportThemeItem,
|
||||||
|
self.exportLanguageItem))
|
||||||
add_actions(self.fileMenu, (self.fileNewItem, self.fileOpenItem,
|
add_actions(self.fileMenu, (self.fileNewItem, self.fileOpenItem,
|
||||||
self.fileSaveItem, self.fileSaveAsItem, self.recentFilesMenu.menuAction(), None,
|
self.fileSaveItem, self.fileSaveAsItem, self.recentFilesMenu.menuAction(), None,
|
||||||
self.fileImportMenu.menuAction(), self.fileExportMenu.menuAction(), None, self.printServiceOrderItem,
|
self.file_import_menu.menuAction(), self.file_export_menu.menuAction(), None, self.printServiceOrderItem,
|
||||||
self.fileExitItem))
|
self.fileExitItem))
|
||||||
add_actions(self.viewModeMenu, (self.modeDefaultItem, self.modeSetupItem, self.modeLiveItem))
|
add_actions(self.viewModeMenu, (self.modeDefaultItem, self.modeSetupItem, self.modeLiveItem))
|
||||||
add_actions(self.viewMenu, (self.viewModeMenu.menuAction(), None, self.viewMediaManagerItem,
|
add_actions(self.viewMenu, (self.viewModeMenu.menuAction(), None, self.viewMediaManagerItem,
|
||||||
@ -326,16 +331,16 @@ class Ui_MainWindow(object):
|
|||||||
else:
|
else:
|
||||||
add_actions(self.settingsMenu, (self.settingsPluginListItem, self.settingsLanguageMenu.menuAction(), None,
|
add_actions(self.settingsMenu, (self.settingsPluginListItem, self.settingsLanguageMenu.menuAction(), None,
|
||||||
self.formattingTagItem, self.settingsShortcutsItem, self.settingsConfigureItem))
|
self.formattingTagItem, self.settingsShortcutsItem, self.settingsConfigureItem))
|
||||||
add_actions(self.toolsMenu, (self.toolsAddToolItem, None))
|
add_actions(self.tools_menu, (self.toolsAddToolItem, None))
|
||||||
add_actions(self.toolsMenu, (self.toolsOpenDataFolder, None))
|
add_actions(self.tools_menu, (self.toolsOpenDataFolder, None))
|
||||||
add_actions(self.toolsMenu, (self.toolsFirstTimeWizard, None))
|
add_actions(self.tools_menu, (self.toolsFirstTimeWizard, None))
|
||||||
add_actions(self.toolsMenu, [self.updateThemeImages])
|
add_actions(self.tools_menu, [self.updateThemeImages])
|
||||||
if os.name == u'nt':
|
if os.name == u'nt':
|
||||||
add_actions(self.helpMenu, (self.offlineHelpItem, self.onlineHelpItem, None, self.webSiteItem,
|
add_actions(self.helpMenu, (self.offlineHelpItem, self.onlineHelpItem, None, self.webSiteItem,
|
||||||
self.aboutItem))
|
self.aboutItem))
|
||||||
else:
|
else:
|
||||||
add_actions(self.helpMenu, (self.onlineHelpItem, None, self.webSiteItem, self.aboutItem))
|
add_actions(self.helpMenu, (self.onlineHelpItem, None, self.webSiteItem, self.aboutItem))
|
||||||
add_actions(self.menuBar, (self.fileMenu.menuAction(), self.viewMenu.menuAction(), self.toolsMenu.menuAction(),
|
add_actions(self.menuBar, (self.fileMenu.menuAction(), self.viewMenu.menuAction(), self.tools_menu.menuAction(),
|
||||||
self.settingsMenu.menuAction(), self.helpMenu.menuAction()))
|
self.settingsMenu.menuAction(), self.helpMenu.menuAction()))
|
||||||
# Initialise the translation
|
# Initialise the translation
|
||||||
self.retranslateUi(main_window)
|
self.retranslateUi(main_window)
|
||||||
@ -356,12 +361,12 @@ class Ui_MainWindow(object):
|
|||||||
mainWindow.mainTitle = UiStrings().OLPV2x
|
mainWindow.mainTitle = UiStrings().OLPV2x
|
||||||
mainWindow.setWindowTitle(mainWindow.mainTitle)
|
mainWindow.setWindowTitle(mainWindow.mainTitle)
|
||||||
self.fileMenu.setTitle(translate('OpenLP.MainWindow', '&File'))
|
self.fileMenu.setTitle(translate('OpenLP.MainWindow', '&File'))
|
||||||
self.fileImportMenu.setTitle(translate('OpenLP.MainWindow', '&Import'))
|
self.file_import_menu.setTitle(translate('OpenLP.MainWindow', '&Import'))
|
||||||
self.fileExportMenu.setTitle(translate('OpenLP.MainWindow', '&Export'))
|
self.file_export_menu.setTitle(translate('OpenLP.MainWindow', '&Export'))
|
||||||
self.recentFilesMenu.setTitle(translate('OpenLP.MainWindow', '&Recent Files'))
|
self.recentFilesMenu.setTitle(translate('OpenLP.MainWindow', '&Recent Files'))
|
||||||
self.viewMenu.setTitle(translate('OpenLP.MainWindow', '&View'))
|
self.viewMenu.setTitle(translate('OpenLP.MainWindow', '&View'))
|
||||||
self.viewModeMenu.setTitle(translate('OpenLP.MainWindow', 'M&ode'))
|
self.viewModeMenu.setTitle(translate('OpenLP.MainWindow', 'M&ode'))
|
||||||
self.toolsMenu.setTitle(translate('OpenLP.MainWindow', '&Tools'))
|
self.tools_menu.setTitle(translate('OpenLP.MainWindow', '&Tools'))
|
||||||
self.settingsMenu.setTitle(translate('OpenLP.MainWindow', '&Settings'))
|
self.settingsMenu.setTitle(translate('OpenLP.MainWindow', '&Settings'))
|
||||||
self.settingsLanguageMenu.setTitle(translate('OpenLP.MainWindow', '&Language'))
|
self.settingsLanguageMenu.setTitle(translate('OpenLP.MainWindow', '&Language'))
|
||||||
self.helpMenu.setTitle(translate('OpenLP.MainWindow', '&Help'))
|
self.helpMenu.setTitle(translate('OpenLP.MainWindow', '&Help'))
|
||||||
@ -475,102 +480,67 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
self.playersSettingsSection = u'players'
|
self.playersSettingsSection = u'players'
|
||||||
self.displayTagsSection = u'displayTags'
|
self.displayTagsSection = u'displayTags'
|
||||||
self.headerSection = u'SettingsImport'
|
self.headerSection = u'SettingsImport'
|
||||||
|
self.recentFiles = []
|
||||||
|
self.timer_id = 0
|
||||||
|
self.timer_version_id = 0
|
||||||
|
self.new_data_path = None
|
||||||
|
self.copy_data = False
|
||||||
Settings().set_up_default_values()
|
Settings().set_up_default_values()
|
||||||
Settings().remove_obsolete_settings()
|
Settings().remove_obsolete_settings()
|
||||||
self.serviceNotSaved = False
|
self.serviceNotSaved = False
|
||||||
self.aboutForm = AboutForm(self)
|
self.aboutForm = AboutForm(self)
|
||||||
self.mediaController = MediaController(self)
|
self.media_controller = MediaController()
|
||||||
self.settingsForm = SettingsForm(self)
|
self.settingsForm = SettingsForm(self)
|
||||||
self.formattingTagForm = FormattingTagForm(self)
|
self.formattingTagForm = FormattingTagForm(self)
|
||||||
self.shortcutForm = ShortcutListForm(self)
|
self.shortcutForm = ShortcutListForm(self)
|
||||||
self.recentFiles = []
|
|
||||||
self.timer_id = 0
|
|
||||||
self.timer_version_id = 0
|
|
||||||
# Set up the path with plugins
|
# Set up the path with plugins
|
||||||
self.plugin_manager = PluginManager()
|
self.plugin_manager = PluginManager()
|
||||||
self.imageManager = ImageManager()
|
self.image_manager = ImageManager()
|
||||||
# Set up the interface
|
# Set up the interface
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
# Register the active media players and suffixes
|
# Define the media Dock Manager
|
||||||
self.mediaController.check_available_media_players()
|
self.mediaDockManager = MediaDockManager(self.mediaToolBox)
|
||||||
# Load settings after setupUi so default UI sizes are overwritten
|
# Load settings after setupUi so default UI sizes are overwritten
|
||||||
self.loadSettings()
|
self.loadSettings()
|
||||||
# Once settings are loaded update the menu with the recent files.
|
# Once settings are loaded update the menu with the recent files.
|
||||||
self.updateRecentFilesMenu()
|
self.updateRecentFilesMenu()
|
||||||
self.pluginForm = PluginForm(self)
|
self.pluginForm = PluginForm(self)
|
||||||
self.new_data_path = None
|
|
||||||
self.copy_data = False
|
|
||||||
# Set up signals and slots
|
# Set up signals and slots
|
||||||
QtCore.QObject.connect(self.importThemeItem, QtCore.SIGNAL(u'triggered()'),
|
|
||||||
self.themeManagerContents.on_import_theme)
|
|
||||||
QtCore.QObject.connect(self.exportThemeItem, QtCore.SIGNAL(u'triggered()'),
|
|
||||||
self.themeManagerContents.on_export_theme)
|
|
||||||
QtCore.QObject.connect(self.mediaManagerDock, QtCore.SIGNAL(u'visibilityChanged(bool)'),
|
QtCore.QObject.connect(self.mediaManagerDock, QtCore.SIGNAL(u'visibilityChanged(bool)'),
|
||||||
self.viewMediaManagerItem.setChecked)
|
self.viewMediaManagerItem.setChecked)
|
||||||
QtCore.QObject.connect(self.serviceManagerDock, QtCore.SIGNAL(u'visibilityChanged(bool)'),
|
QtCore.QObject.connect(self.serviceManagerDock, QtCore.SIGNAL(u'visibilityChanged(bool)'),
|
||||||
self.viewServiceManagerItem.setChecked)
|
self.viewServiceManagerItem.setChecked)
|
||||||
QtCore.QObject.connect(self.themeManagerDock, QtCore.SIGNAL(u'visibilityChanged(bool)'),
|
QtCore.QObject.connect(self.themeManagerDock, QtCore.SIGNAL(u'visibilityChanged(bool)'),
|
||||||
self.viewThemeManagerItem.setChecked)
|
self.viewThemeManagerItem.setChecked)
|
||||||
QtCore.QObject.connect(self.webSiteItem, QtCore.SIGNAL(u'triggered()'), self.onHelpWebSiteClicked)
|
self.importThemeItem.triggered.connect(self.themeManagerContents.on_import_theme)
|
||||||
QtCore.QObject.connect(self.toolsOpenDataFolder, QtCore.SIGNAL(u'triggered()'),
|
self.exportThemeItem.triggered.connect(self.themeManagerContents.on_export_theme)
|
||||||
self.onToolsOpenDataFolderClicked)
|
self.webSiteItem.triggered.connect(self.onHelpWebSiteClicked)
|
||||||
QtCore.QObject.connect(self.toolsFirstTimeWizard, QtCore.SIGNAL(u'triggered()'), self.onFirstTimeWizardClicked)
|
self.toolsOpenDataFolder.triggered.connect(self.onToolsOpenDataFolderClicked)
|
||||||
QtCore.QObject.connect(self.updateThemeImages, QtCore.SIGNAL(u'triggered()'), self.onUpdateThemeImages)
|
self.toolsFirstTimeWizard.triggered.connect(self.onFirstTimeWizardClicked)
|
||||||
QtCore.QObject.connect(self.formattingTagItem, QtCore.SIGNAL(u'triggered()'), self.onFormattingTagItemClicked)
|
self.updateThemeImages.triggered.connect(self.onUpdateThemeImages)
|
||||||
QtCore.QObject.connect(self.settingsConfigureItem, QtCore.SIGNAL(u'triggered()'),
|
self.formattingTagItem.triggered.connect(self.onFormattingTagItemClicked)
|
||||||
self.onSettingsConfigureItemClicked)
|
self.settingsConfigureItem.triggered.connect(self.onSettingsConfigureItemClicked)
|
||||||
QtCore.QObject.connect(self.settingsShortcutsItem, QtCore.SIGNAL(u'triggered()'),
|
self.settingsShortcutsItem.triggered.connect(self.onSettingsShortcutsItemClicked)
|
||||||
self.onSettingsShortcutsItemClicked)
|
self.settingsImportItem.triggered.connect(self.onSettingsImportItemClicked)
|
||||||
QtCore.QObject.connect(self.settingsImportItem, QtCore.SIGNAL(u'triggered()'),
|
self.settingsExportItem.triggered.connect(self.onSettingsExportItemClicked)
|
||||||
self.onSettingsImportItemClicked)
|
|
||||||
QtCore.QObject.connect(self.settingsExportItem, QtCore.SIGNAL(u'triggered()'), self.onSettingsExportItemClicked)
|
|
||||||
# i18n set signals for languages
|
# i18n set signals for languages
|
||||||
self.languageGroup.triggered.connect(LanguageManager.set_language)
|
self.languageGroup.triggered.connect(LanguageManager.set_language)
|
||||||
QtCore.QObject.connect(self.modeDefaultItem, QtCore.SIGNAL(u'triggered()'), self.onModeDefaultItemClicked)
|
self.modeDefaultItem.triggered.connect(self.onModeDefaultItemClicked)
|
||||||
QtCore.QObject.connect(self.modeSetupItem, QtCore.SIGNAL(u'triggered()'), self.onModeSetupItemClicked)
|
self.modeSetupItem.triggered.connect(self.onModeSetupItemClicked)
|
||||||
QtCore.QObject.connect(self.modeLiveItem, QtCore.SIGNAL(u'triggered()'), self.onModeLiveItemClicked)
|
self.modeLiveItem.triggered.connect(self.onModeLiveItemClicked)
|
||||||
# Media Manager
|
# Media Manager
|
||||||
QtCore.QObject.connect(self.mediaToolBox, QtCore.SIGNAL(u'currentChanged(int)'), self.onMediaToolBoxChanged)
|
self.mediaToolBox.currentChanged.connect(self.onMediaToolBoxChanged)
|
||||||
self.application.set_busy_cursor()
|
self.application.set_busy_cursor()
|
||||||
# Simple message boxes
|
# Simple message boxes
|
||||||
Registry().register_function(u'theme_update_global', self.default_theme_changed)
|
Registry().register_function(u'theme_update_global', self.default_theme_changed)
|
||||||
Registry().register_function(u'openlp_version_check', self.version_notice)
|
Registry().register_function(u'openlp_version_check', self.version_notice)
|
||||||
Registry().register_function(u'config_screen_changed', self.screen_changed)
|
Registry().register_function(u'config_screen_changed', self.screen_changed)
|
||||||
self.renderer = Renderer()
|
self.renderer = Renderer()
|
||||||
# Define the media Dock Manager
|
|
||||||
self.mediaDockManager = MediaDockManager(self.mediaToolBox)
|
|
||||||
log.info(u'Load Plugins')
|
|
||||||
self.plugin_manager.find_plugins()
|
|
||||||
# hook methods have to happen after find_plugins. Find plugins needs
|
|
||||||
# the controllers hence the hooks have moved from setupUI() to here
|
|
||||||
# Find and insert settings tabs
|
|
||||||
log.info(u'hook settings')
|
|
||||||
self.plugin_manager.hook_settings_tabs(self.settingsForm)
|
|
||||||
# Find and insert media manager items
|
|
||||||
log.info(u'hook media')
|
|
||||||
self.plugin_manager.hook_media_manager()
|
|
||||||
# Call the hook method to pull in import menus.
|
|
||||||
log.info(u'hook menus')
|
|
||||||
self.plugin_manager.hook_import_menu(self.fileImportMenu)
|
|
||||||
# Call the hook method to pull in export menus.
|
|
||||||
self.plugin_manager.hook_export_menu(self.fileExportMenu)
|
|
||||||
# Call the hook method to pull in tools menus.
|
|
||||||
self.plugin_manager.hook_tools_menu(self.toolsMenu)
|
|
||||||
# Call the initialise method to setup plugins.
|
|
||||||
log.info(u'initialise plugins')
|
|
||||||
self.plugin_manager.initialise_plugins()
|
|
||||||
# Create the displays as all necessary components are loaded.
|
|
||||||
self.previewController.screenSizeChanged()
|
|
||||||
self.liveController.screenSizeChanged()
|
|
||||||
log.info(u'Load data from Settings')
|
log.info(u'Load data from Settings')
|
||||||
if Settings().value(u'advanced/save current plugin'):
|
if Settings().value(u'advanced/save current plugin'):
|
||||||
savedPlugin = Settings().value(u'advanced/current media plugin')
|
savedPlugin = Settings().value(u'advanced/current media plugin')
|
||||||
if savedPlugin != -1:
|
if savedPlugin != -1:
|
||||||
self.mediaToolBox.setCurrentIndex(savedPlugin)
|
self.mediaToolBox.setCurrentIndex(savedPlugin)
|
||||||
self.settingsForm.postSetUp()
|
|
||||||
# Once all components are initialised load the Themes
|
|
||||||
log.info(u'Load Themes')
|
|
||||||
self.themeManagerContents.load_themes(True)
|
|
||||||
# Reset the cursor
|
# Reset the cursor
|
||||||
self.application.set_normal_cursor()
|
self.application.set_normal_cursor()
|
||||||
|
|
||||||
@ -605,8 +575,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
Show the main form, as well as the display form
|
Show the main form, as well as the display form
|
||||||
"""
|
"""
|
||||||
QtGui.QWidget.show(self)
|
QtGui.QWidget.show(self)
|
||||||
if self.liveController.display.isVisible():
|
if self.live_controller.display.isVisible():
|
||||||
self.liveController.display.setFocus()
|
self.live_controller.display.setFocus()
|
||||||
self.activateWindow()
|
self.activateWindow()
|
||||||
if self.arguments:
|
if self.arguments:
|
||||||
args = []
|
args = []
|
||||||
@ -699,7 +669,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
Check and display message if screen blank on setup.
|
Check and display message if screen blank on setup.
|
||||||
"""
|
"""
|
||||||
settings = Settings()
|
settings = Settings()
|
||||||
self.liveController.mainDisplaySetBackground()
|
self.live_controller.mainDisplaySetBackground()
|
||||||
if settings.value(u'%s/screen blank' % self.generalSettingsSection):
|
if settings.value(u'%s/screen blank' % self.generalSettingsSection):
|
||||||
if settings.value(u'%s/blank warning' % self.generalSettingsSection):
|
if settings.value(u'%s/blank warning' % self.generalSettingsSection):
|
||||||
QtGui.QMessageBox.question(self, translate('OpenLP.MainWindow', 'OpenLP Main Display Blanked'),
|
QtGui.QMessageBox.question(self, translate('OpenLP.MainWindow', 'OpenLP Main Display Blanked'),
|
||||||
@ -806,8 +776,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
"""
|
"""
|
||||||
We need to make sure, that the SlidePreview's size is correct.
|
We need to make sure, that the SlidePreview's size is correct.
|
||||||
"""
|
"""
|
||||||
self.previewController.previewSizeChanged()
|
self.preview_controller.previewSizeChanged()
|
||||||
self.liveController.previewSizeChanged()
|
self.live_controller.previewSizeChanged()
|
||||||
|
|
||||||
def onSettingsShortcutsItemClicked(self):
|
def onSettingsShortcutsItemClicked(self):
|
||||||
"""
|
"""
|
||||||
@ -1015,10 +985,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
"""
|
"""
|
||||||
log.debug(u'screen_changed')
|
log.debug(u'screen_changed')
|
||||||
self.application.set_busy_cursor()
|
self.application.set_busy_cursor()
|
||||||
self.imageManager.update_display()
|
self.image_manager.update_display()
|
||||||
self.renderer.update_display()
|
self.renderer.update_display()
|
||||||
self.previewController.screenSizeChanged()
|
self.preview_controller.screenSizeChanged()
|
||||||
self.liveController.screenSizeChanged()
|
self.live_controller.screenSizeChanged()
|
||||||
self.setFocus()
|
self.setFocus()
|
||||||
self.activateWindow()
|
self.activateWindow()
|
||||||
self.application.set_normal_cursor()
|
self.application.set_normal_cursor()
|
||||||
@ -1071,8 +1041,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
``save_settings``
|
``save_settings``
|
||||||
Switch to prevent saving settings. Defaults to **True**.
|
Switch to prevent saving settings. Defaults to **True**.
|
||||||
"""
|
"""
|
||||||
self.imageManager.stop_manager = True
|
self.image_manager.stop_manager = True
|
||||||
while self.imageManager.image_thread.isRunning():
|
while self.image_manager.image_thread.isRunning():
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
# Clean temporary files used by services
|
# Clean temporary files used by services
|
||||||
self.serviceManagerContents.clean_up()
|
self.serviceManagerContents.clean_up()
|
||||||
@ -1089,9 +1059,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
if self.new_data_path:
|
if self.new_data_path:
|
||||||
self.changeDataDirectory()
|
self.changeDataDirectory()
|
||||||
# Close down the display
|
# Close down the display
|
||||||
if self.liveController.display:
|
if self.live_controller.display:
|
||||||
self.liveController.display.close()
|
self.live_controller.display.close()
|
||||||
self.liveController.display = None
|
self.live_controller.display = None
|
||||||
|
|
||||||
def serviceChanged(self, reset=False, serviceName=None):
|
def serviceChanged(self, reset=False, serviceName=None):
|
||||||
"""
|
"""
|
||||||
@ -1172,7 +1142,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
True - Visible
|
True - Visible
|
||||||
False - Hidden
|
False - Hidden
|
||||||
"""
|
"""
|
||||||
self.previewController.panel.setVisible(visible)
|
self.preview_controller.panel.setVisible(visible)
|
||||||
Settings().setValue(u'user interface/preview panel', visible)
|
Settings().setValue(u'user interface/preview panel', visible)
|
||||||
self.viewPreviewPanel.setChecked(visible)
|
self.viewPreviewPanel.setChecked(visible)
|
||||||
|
|
||||||
@ -1210,7 +1180,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
True - Visible
|
True - Visible
|
||||||
False - Hidden
|
False - Hidden
|
||||||
"""
|
"""
|
||||||
self.liveController.panel.setVisible(visible)
|
self.live_controller.panel.setVisible(visible)
|
||||||
Settings().setValue(u'user interface/live panel', visible)
|
Settings().setValue(u'user interface/live panel', visible)
|
||||||
self.viewLivePanel.setChecked(visible)
|
self.viewLivePanel.setChecked(visible)
|
||||||
|
|
||||||
@ -1230,8 +1200,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
self.move(settings.value(u'main window position'))
|
self.move(settings.value(u'main window position'))
|
||||||
self.restoreGeometry(settings.value(u'main window geometry'))
|
self.restoreGeometry(settings.value(u'main window geometry'))
|
||||||
self.restoreState(settings.value(u'main window state'))
|
self.restoreState(settings.value(u'main window state'))
|
||||||
self.liveController.splitter.restoreState(settings.value(u'live splitter geometry'))
|
self.live_controller.splitter.restoreState(settings.value(u'live splitter geometry'))
|
||||||
self.previewController.splitter.restoreState(settings.value(u'preview splitter geometry'))
|
self.preview_controller.splitter.restoreState(settings.value(u'preview splitter geometry'))
|
||||||
self.controlSplitter.restoreState(settings.value(u'main window splitter geometry'))
|
self.controlSplitter.restoreState(settings.value(u'main window splitter geometry'))
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
|
|
||||||
@ -1251,8 +1221,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
settings.setValue(u'main window position', self.pos())
|
settings.setValue(u'main window position', self.pos())
|
||||||
settings.setValue(u'main window state', self.saveState())
|
settings.setValue(u'main window state', self.saveState())
|
||||||
settings.setValue(u'main window geometry', self.saveGeometry())
|
settings.setValue(u'main window geometry', self.saveGeometry())
|
||||||
settings.setValue(u'live splitter geometry', self.liveController.splitter.saveState())
|
settings.setValue(u'live splitter geometry', self.live_controller.splitter.saveState())
|
||||||
settings.setValue(u'preview splitter geometry', self.previewController.splitter.saveState())
|
settings.setValue(u'preview splitter geometry', self.preview_controller.splitter.saveState())
|
||||||
settings.setValue(u'main window splitter geometry', self.controlSplitter.saveState())
|
settings.setValue(u'main window splitter geometry', self.controlSplitter.saveState())
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
|
|
||||||
|
@ -61,8 +61,8 @@ class MediaSlider(QtGui.QSlider):
|
|||||||
"""
|
"""
|
||||||
Override event to allow hover time to be displayed.
|
Override event to allow hover time to be displayed.
|
||||||
"""
|
"""
|
||||||
timevalue = QtGui.QStyle.sliderValueFromPosition(self.minimum(), self.maximum(), event.x(), self.width())
|
time_value = QtGui.QStyle.sliderValueFromPosition(self.minimum(), self.maximum(), event.x(), self.width())
|
||||||
self.setToolTip(u'%s' % datetime.timedelta(seconds=int(timevalue / 1000)))
|
self.setToolTip(u'%s' % datetime.timedelta(seconds=int(time_value / 1000)))
|
||||||
QtGui.QSlider.mouseMoveEvent(self, event)
|
QtGui.QSlider.mouseMoveEvent(self, event)
|
||||||
|
|
||||||
def mousePressEvent(self, event):
|
def mousePressEvent(self, event):
|
||||||
@ -88,20 +88,20 @@ class MediaController(object):
|
|||||||
slidecontroller or plugin which built them. ControllerType is the class
|
slidecontroller or plugin which built them. ControllerType is the class
|
||||||
containing the key values.
|
containing the key values.
|
||||||
|
|
||||||
mediaPlayers are an array of media players keyed on player name.
|
media_players are an array of media players keyed on player name.
|
||||||
|
|
||||||
currentMediaPlayer is an array of player instances keyed on ControllerType.
|
current_media_players is an array of player instances keyed on ControllerType.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, parent):
|
def __init__(self):
|
||||||
"""
|
"""
|
||||||
Constructor
|
Constructor
|
||||||
"""
|
"""
|
||||||
self.mainWindow = parent
|
|
||||||
Registry().register(u'media_controller', self)
|
Registry().register(u'media_controller', self)
|
||||||
self.mediaPlayers = {}
|
Registry().register_function(u'bootstrap_initialise', self.check_available_media_players)
|
||||||
|
self.media_players = {}
|
||||||
self.displayControllers = {}
|
self.displayControllers = {}
|
||||||
self.currentMediaPlayer = {}
|
self.current_media_players = {}
|
||||||
# Timer for video state
|
# Timer for video state
|
||||||
self.timer = QtCore.QTimer()
|
self.timer = QtCore.QTimer()
|
||||||
self.timer.setInterval(200)
|
self.timer.setInterval(200)
|
||||||
@ -126,22 +126,22 @@ class MediaController(object):
|
|||||||
Set the active players and available media files
|
Set the active players and available media files
|
||||||
"""
|
"""
|
||||||
savedPlayers = get_media_players()[0]
|
savedPlayers = get_media_players()[0]
|
||||||
for player in self.mediaPlayers.keys():
|
for player in self.media_players.keys():
|
||||||
self.mediaPlayers[player].isActive = player in savedPlayers
|
self.media_players[player].isActive = player in savedPlayers
|
||||||
|
|
||||||
def _generate_extensions_lists(self):
|
def _generate_extensions_lists(self):
|
||||||
"""
|
"""
|
||||||
Set the active players and available media files
|
Set the active players and available media files
|
||||||
"""
|
"""
|
||||||
self.audio_extensions_list = []
|
self.audio_extensions_list = []
|
||||||
for player in self.mediaPlayers.values():
|
for player in self.media_players.values():
|
||||||
if player.isActive:
|
if player.isActive:
|
||||||
for item in player.audio_extensions_list:
|
for item in player.audio_extensions_list:
|
||||||
if not item in self.audio_extensions_list:
|
if not item in self.audio_extensions_list:
|
||||||
self.audio_extensions_list.append(item)
|
self.audio_extensions_list.append(item)
|
||||||
self.service_manager.supported_suffixes(item[2:])
|
self.service_manager.supported_suffixes(item[2:])
|
||||||
self.video_extensions_list = []
|
self.video_extensions_list = []
|
||||||
for player in self.mediaPlayers.values():
|
for player in self.media_players.values():
|
||||||
if player.isActive:
|
if player.isActive:
|
||||||
for item in player.video_extensions_list:
|
for item in player.video_extensions_list:
|
||||||
if item not in self.video_extensions_list:
|
if item not in self.video_extensions_list:
|
||||||
@ -156,16 +156,14 @@ class MediaController(object):
|
|||||||
``player``
|
``player``
|
||||||
Individual player class which has been enabled
|
Individual player class which has been enabled
|
||||||
"""
|
"""
|
||||||
self.mediaPlayers[player.name] = player
|
self.media_players[player.name] = player
|
||||||
|
|
||||||
def check_available_media_players(self):
|
def check_available_media_players(self):
|
||||||
"""
|
"""
|
||||||
Check to see if we have any media Player's available.
|
Check to see if we have any media Player's available.
|
||||||
"""
|
"""
|
||||||
log.debug(u'_check_available_media_players')
|
log.debug(u'_check_available_media_players')
|
||||||
controller_dir = os.path.join(
|
controller_dir = os.path.join(AppLocation.get_directory(AppLocation.AppDir), u'core', u'ui', u'media')
|
||||||
AppLocation.get_directory(AppLocation.AppDir),
|
|
||||||
u'core', u'ui', u'media')
|
|
||||||
for filename in os.listdir(controller_dir):
|
for filename in os.listdir(controller_dir):
|
||||||
if filename.endswith(u'player.py') and not filename == 'mediaplayer.py':
|
if filename.endswith(u'player.py') and not filename == 'mediaplayer.py':
|
||||||
path = os.path.join(controller_dir, filename)
|
path = os.path.join(controller_dir, filename)
|
||||||
@ -182,13 +180,13 @@ class MediaController(object):
|
|||||||
for player_class in player_classes:
|
for player_class in player_classes:
|
||||||
player = player_class(self)
|
player = player_class(self)
|
||||||
self.register_players(player)
|
self.register_players(player)
|
||||||
if not self.mediaPlayers:
|
if not self.media_players:
|
||||||
return False
|
return False
|
||||||
savedPlayers, overriddenPlayer = get_media_players()
|
savedPlayers, overriddenPlayer = get_media_players()
|
||||||
invalidMediaPlayers = [mediaPlayer for mediaPlayer in savedPlayers
|
invalid_media_players = [mediaPlayer for mediaPlayer in savedPlayers
|
||||||
if not mediaPlayer in self.mediaPlayers or not self.mediaPlayers[mediaPlayer].check_available()]
|
if not mediaPlayer in self.media_players or not self.media_players[mediaPlayer].check_available()]
|
||||||
if invalidMediaPlayers:
|
if invalid_media_players:
|
||||||
for invalidPlayer in invalidMediaPlayers:
|
for invalidPlayer in invalid_media_players:
|
||||||
savedPlayers.remove(invalidPlayer)
|
savedPlayers.remove(invalidPlayer)
|
||||||
set_media_players(savedPlayers, overriddenPlayer)
|
set_media_players(savedPlayers, overriddenPlayer)
|
||||||
self._set_active_players()
|
self._set_active_players()
|
||||||
@ -200,22 +198,22 @@ class MediaController(object):
|
|||||||
Check if there is a running media Player and do updating stuff (e.g.
|
Check if there is a running media Player and do updating stuff (e.g.
|
||||||
update the UI)
|
update the UI)
|
||||||
"""
|
"""
|
||||||
if not self.currentMediaPlayer.keys():
|
if not self.current_media_players.keys():
|
||||||
self.timer.stop()
|
self.timer.stop()
|
||||||
else:
|
else:
|
||||||
any_active = False
|
any_active = False
|
||||||
for source in self.currentMediaPlayer.keys():
|
for source in self.current_media_players.keys():
|
||||||
display = self._define_display(self.displayControllers[source])
|
display = self._define_display(self.displayControllers[source])
|
||||||
self.currentMediaPlayer[source].resize(display)
|
self.current_media_players[source].resize(display)
|
||||||
self.currentMediaPlayer[source].update_ui(display)
|
self.current_media_players[source].update_ui(display)
|
||||||
if self.currentMediaPlayer[source].state == MediaState.Playing:
|
if self.current_media_players[source].state == MediaState.Playing:
|
||||||
any_active = True
|
any_active = True
|
||||||
# There are still any active players - no need to stop timer.
|
# There are still any active players - no need to stop timer.
|
||||||
if any_active:
|
if any_active:
|
||||||
return
|
return
|
||||||
# no players are active anymore
|
# no players are active anymore
|
||||||
for source in self.currentMediaPlayer.keys():
|
for source in self.current_media_players.keys():
|
||||||
if self.currentMediaPlayer[source].state != MediaState.Paused:
|
if self.current_media_players[source].state != MediaState.Paused:
|
||||||
display = self._define_display(self.displayControllers[source])
|
display = self._define_display(self.displayControllers[source])
|
||||||
display.controller.seekSlider.setSliderPosition(0)
|
display.controller.seekSlider.setSliderPosition(0)
|
||||||
self.timer.stop()
|
self.timer.stop()
|
||||||
@ -225,7 +223,7 @@ class MediaController(object):
|
|||||||
Add css style sheets to htmlbuilder
|
Add css style sheets to htmlbuilder
|
||||||
"""
|
"""
|
||||||
css = u''
|
css = u''
|
||||||
for player in self.mediaPlayers.values():
|
for player in self.media_players.values():
|
||||||
if player.isActive:
|
if player.isActive:
|
||||||
css += player.get_media_display_css()
|
css += player.get_media_display_css()
|
||||||
return css
|
return css
|
||||||
@ -235,7 +233,7 @@ class MediaController(object):
|
|||||||
Add javascript functions to htmlbuilder
|
Add javascript functions to htmlbuilder
|
||||||
"""
|
"""
|
||||||
js = u''
|
js = u''
|
||||||
for player in self.mediaPlayers.values():
|
for player in self.media_players.values():
|
||||||
if player.isActive:
|
if player.isActive:
|
||||||
js += player.get_media_display_javascript()
|
js += player.get_media_display_javascript()
|
||||||
return js
|
return js
|
||||||
@ -245,7 +243,7 @@ class MediaController(object):
|
|||||||
Add html code to htmlbuilder
|
Add html code to htmlbuilder
|
||||||
"""
|
"""
|
||||||
html = u''
|
html = u''
|
||||||
for player in self.mediaPlayers.values():
|
for player in self.media_players.values():
|
||||||
if player.isActive:
|
if player.isActive:
|
||||||
html += player.get_media_display_html()
|
html += player.get_media_display_html()
|
||||||
return html
|
return html
|
||||||
@ -257,7 +255,7 @@ class MediaController(object):
|
|||||||
``controller``
|
``controller``
|
||||||
The controller where a player will be placed
|
The controller where a player will be placed
|
||||||
"""
|
"""
|
||||||
self.displayControllers[controller.controllerType] = controller
|
self.displayControllers[controller.controller_type] = controller
|
||||||
self.setup_generic_controls(controller)
|
self.setup_generic_controls(controller)
|
||||||
|
|
||||||
def setup_generic_controls(self, controller):
|
def setup_generic_controls(self, controller):
|
||||||
@ -272,13 +270,13 @@ class MediaController(object):
|
|||||||
controller.mediabar = OpenLPToolbar(controller)
|
controller.mediabar = OpenLPToolbar(controller)
|
||||||
controller.mediabar.addToolbarAction(u'playbackPlay', text=u'media_playback_play',
|
controller.mediabar.addToolbarAction(u'playbackPlay', text=u'media_playback_play',
|
||||||
icon=u':/slides/media_playback_start.png',
|
icon=u':/slides/media_playback_start.png',
|
||||||
tooltip=translate('OpenLP.SlideController', 'Start playing media.'), triggers=controller.sendToPlugins)
|
tooltip=translate('OpenLP.SlideController', 'Start playing media.'), triggers=controller.send_to_plugins)
|
||||||
controller.mediabar.addToolbarAction(u'playbackPause', text=u'media_playback_pause',
|
controller.mediabar.addToolbarAction(u'playbackPause', text=u'media_playback_pause',
|
||||||
icon=u':/slides/media_playback_pause.png',
|
icon=u':/slides/media_playback_pause.png',
|
||||||
tooltip=translate('OpenLP.SlideController', 'Pause playing media.'), triggers=controller.sendToPlugins)
|
tooltip=translate('OpenLP.SlideController', 'Pause playing media.'), triggers=controller.send_to_plugins)
|
||||||
controller.mediabar.addToolbarAction(u'playbackStop', text=u'media_playback_stop',
|
controller.mediabar.addToolbarAction(u'playbackStop', text=u'media_playback_stop',
|
||||||
icon=u':/slides/media_playback_stop.png',
|
icon=u':/slides/media_playback_stop.png',
|
||||||
tooltip=translate('OpenLP.SlideController', 'Stop playing media.'), triggers=controller.sendToPlugins)
|
tooltip=translate('OpenLP.SlideController', 'Stop playing media.'), triggers=controller.send_to_plugins)
|
||||||
# Build the seekSlider.
|
# Build the seekSlider.
|
||||||
controller.seekSlider = MediaSlider(QtCore.Qt.Horizontal, self, controller)
|
controller.seekSlider = MediaSlider(QtCore.Qt.Horizontal, self, controller)
|
||||||
controller.seekSlider.setMaximum(1000)
|
controller.seekSlider.setMaximum(1000)
|
||||||
@ -300,15 +298,15 @@ class MediaController(object):
|
|||||||
controller.volumeSlider.setGeometry(QtCore.QRect(90, 160, 221, 24))
|
controller.volumeSlider.setGeometry(QtCore.QRect(90, 160, 221, 24))
|
||||||
controller.volumeSlider.setObjectName(u'volumeSlider')
|
controller.volumeSlider.setObjectName(u'volumeSlider')
|
||||||
controller.mediabar.addToolbarWidget(controller.volumeSlider)
|
controller.mediabar.addToolbarWidget(controller.volumeSlider)
|
||||||
controller.controllerLayout.addWidget(controller.mediabar)
|
controller.controller_layout.addWidget(controller.mediabar)
|
||||||
controller.mediabar.setVisible(False)
|
controller.mediabar.setVisible(False)
|
||||||
# Signals
|
# Signals
|
||||||
QtCore.QObject.connect(controller.seekSlider, QtCore.SIGNAL(u'valueChanged(int)'), controller.sendToPlugins)
|
controller.seekSlider.valueChanged.connect(controller.send_to_plugins)
|
||||||
QtCore.QObject.connect(controller.volumeSlider, QtCore.SIGNAL(u'valueChanged(int)'), controller.sendToPlugins)
|
controller.volumeSlider.valueChanged.connect(controller.send_to_plugins)
|
||||||
|
|
||||||
def setup_display(self, display, preview):
|
def setup_display(self, display, preview):
|
||||||
"""
|
"""
|
||||||
After a new display is configured, all media related widget will be
|
After a new display is configured, all media related widgets will be
|
||||||
created too
|
created too
|
||||||
|
|
||||||
``display``
|
``display``
|
||||||
@ -322,11 +320,11 @@ class MediaController(object):
|
|||||||
# update player status
|
# update player status
|
||||||
self._set_active_players()
|
self._set_active_players()
|
||||||
display.hasAudio = True
|
display.hasAudio = True
|
||||||
if display.isLive and preview:
|
if display.is_live and preview:
|
||||||
return
|
return
|
||||||
if preview:
|
if preview:
|
||||||
display.hasAudio = False
|
display.hasAudio = False
|
||||||
for player in self.mediaPlayers.values():
|
for player in self.media_players.values():
|
||||||
if player.isActive:
|
if player.isActive:
|
||||||
player.setup(display)
|
player.setup(display)
|
||||||
|
|
||||||
@ -343,10 +341,10 @@ class MediaController(object):
|
|||||||
"""
|
"""
|
||||||
# Generic controls
|
# Generic controls
|
||||||
controller.mediabar.setVisible(value)
|
controller.mediabar.setVisible(value)
|
||||||
if controller.isLive and controller.display:
|
if controller.is_live and controller.display:
|
||||||
if self.currentMediaPlayer and value:
|
if self.current_media_players and value:
|
||||||
if self.currentMediaPlayer[controller.controllerType] != self.mediaPlayers[u'webkit']:
|
if self.current_media_players[controller.controller_type] != self.media_players[u'webkit']:
|
||||||
controller.display.setTransparency(False)
|
controller.display.set_transparency(False)
|
||||||
|
|
||||||
def resize(self, display, player):
|
def resize(self, display, player):
|
||||||
"""
|
"""
|
||||||
@ -387,7 +385,7 @@ class MediaController(object):
|
|||||||
controller.media_info.is_background = videoBehindText
|
controller.media_info.is_background = videoBehindText
|
||||||
controller.media_info.file_info = QtCore.QFileInfo(serviceItem.get_frame_path())
|
controller.media_info.file_info = QtCore.QFileInfo(serviceItem.get_frame_path())
|
||||||
display = self._define_display(controller)
|
display = self._define_display(controller)
|
||||||
if controller.isLive:
|
if controller.is_live:
|
||||||
isValid = self._check_file_type(controller, display, serviceItem)
|
isValid = self._check_file_type(controller, display, serviceItem)
|
||||||
display.override[u'theme'] = u''
|
display.override[u'theme'] = u''
|
||||||
display.override[u'video'] = True
|
display.override[u'video'] = True
|
||||||
@ -398,7 +396,7 @@ class MediaController(object):
|
|||||||
else:
|
else:
|
||||||
controller.media_info.start_time = serviceItem.start_time
|
controller.media_info.start_time = serviceItem.start_time
|
||||||
controller.media_info.end_time = serviceItem.end_time
|
controller.media_info.end_time = serviceItem.end_time
|
||||||
elif controller.previewDisplay:
|
elif controller.preview_display:
|
||||||
isValid = self._check_file_type(controller, display, serviceItem)
|
isValid = self._check_file_type(controller, display, serviceItem)
|
||||||
if not isValid:
|
if not isValid:
|
||||||
# Media could not be loaded correctly
|
# Media could not be loaded correctly
|
||||||
@ -406,12 +404,12 @@ class MediaController(object):
|
|||||||
translate('MediaPlugin.MediaItem', 'Unsupported File'))
|
translate('MediaPlugin.MediaItem', 'Unsupported File'))
|
||||||
return False
|
return False
|
||||||
# dont care about actual theme, set a black background
|
# dont care about actual theme, set a black background
|
||||||
if controller.isLive and not controller.media_info.is_background:
|
if controller.is_live and not controller.media_info.is_background:
|
||||||
display.frame.evaluateJavaScript(u'show_video( "setBackBoard", null, null, null,"visible");')
|
display.frame.evaluateJavaScript(u'show_video( "setBackBoard", null, null, null,"visible");')
|
||||||
# now start playing - Preview is autoplay!
|
# now start playing - Preview is autoplay!
|
||||||
autoplay = False
|
autoplay = False
|
||||||
# Preview requested
|
# Preview requested
|
||||||
if not controller.isLive:
|
if not controller.is_live:
|
||||||
autoplay = True
|
autoplay = True
|
||||||
# Visible or background requested or Service Item wants to autostart
|
# Visible or background requested or Service Item wants to autostart
|
||||||
elif not hidden or controller.media_info.is_background or serviceItem.will_auto_start:
|
elif not hidden or controller.media_info.is_background or serviceItem.will_auto_start:
|
||||||
@ -425,7 +423,7 @@ class MediaController(object):
|
|||||||
translate('MediaPlugin.MediaItem', 'Unsupported File'))
|
translate('MediaPlugin.MediaItem', 'Unsupported File'))
|
||||||
return False
|
return False
|
||||||
self.set_controls_visible(controller, True)
|
self.set_controls_visible(controller, True)
|
||||||
log.debug(u'use %s controller' % self.currentMediaPlayer[controller.controllerType])
|
log.debug(u'use %s controller' % self.current_media_players[controller.controller_type])
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def media_length(self, serviceItem):
|
def media_length(self, serviceItem):
|
||||||
@ -442,7 +440,7 @@ class MediaController(object):
|
|||||||
controller.media_info = MediaInfo()
|
controller.media_info = MediaInfo()
|
||||||
controller.media_info.volume = 0
|
controller.media_info.volume = 0
|
||||||
controller.media_info.file_info = QtCore.QFileInfo(serviceItem.get_frame_path())
|
controller.media_info.file_info = QtCore.QFileInfo(serviceItem.get_frame_path())
|
||||||
display = controller.previewDisplay
|
display = controller._display
|
||||||
if not self._check_file_type(controller, display, serviceItem):
|
if not self._check_file_type(controller, display, serviceItem):
|
||||||
# Media could not be loaded correctly
|
# Media could not be loaded correctly
|
||||||
critical_error_message_box(translate('MediaPlugin.MediaItem', 'Unsupported File'),
|
critical_error_message_box(translate('MediaPlugin.MediaItem', 'Unsupported File'),
|
||||||
@ -454,7 +452,7 @@ class MediaController(object):
|
|||||||
return False
|
return False
|
||||||
serviceItem.set_media_length(controller.media_info.length)
|
serviceItem.set_media_length(controller.media_info.length)
|
||||||
self.media_stop(controller)
|
self.media_stop(controller)
|
||||||
log.debug(u'use %s controller' % self.currentMediaPlayer[controller.controllerType])
|
log.debug(u'use %s controller' % self.current_media_players[controller.controller_type])
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _check_file_type(self, controller, display, serviceItem):
|
def _check_file_type(self, controller, display, serviceItem):
|
||||||
@ -473,27 +471,27 @@ class MediaController(object):
|
|||||||
if controller.media_info.file_info.isFile():
|
if controller.media_info.file_info.isFile():
|
||||||
suffix = u'*.%s' % controller.media_info.file_info.suffix().lower()
|
suffix = u'*.%s' % controller.media_info.file_info.suffix().lower()
|
||||||
for title in usedPlayers:
|
for title in usedPlayers:
|
||||||
player = self.mediaPlayers[title]
|
player = self.media_players[title]
|
||||||
if suffix in player.video_extensions_list:
|
if suffix in player.video_extensions_list:
|
||||||
if not controller.media_info.is_background or controller.media_info.is_background and \
|
if not controller.media_info.is_background or controller.media_info.is_background and \
|
||||||
player.canBackground:
|
player.canBackground:
|
||||||
self.resize(display, player)
|
self.resize(display, player)
|
||||||
if player.load(display):
|
if player.load(display):
|
||||||
self.currentMediaPlayer[controller.controllerType] = player
|
self.current_media_players[controller.controller_type] = player
|
||||||
controller.media_info.media_type = MediaType.Video
|
controller.media_info.media_type = MediaType.Video
|
||||||
return True
|
return True
|
||||||
if suffix in player.audio_extensions_list:
|
if suffix in player.audio_extensions_list:
|
||||||
if player.load(display):
|
if player.load(display):
|
||||||
self.currentMediaPlayer[controller.controllerType] = player
|
self.current_media_players[controller.controller_type] = player
|
||||||
controller.media_info.media_type = MediaType.Audio
|
controller.media_info.media_type = MediaType.Audio
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
for title in usedPlayers:
|
for title in usedPlayers:
|
||||||
player = self.mediaPlayers[title]
|
player = self.media_players[title]
|
||||||
if player.canFolder:
|
if player.canFolder:
|
||||||
self.resize(display, player)
|
self.resize(display, player)
|
||||||
if player.load(display):
|
if player.load(display):
|
||||||
self.currentMediaPlayer[controller.controllerType] = player
|
self.current_media_players[controller.controller_type] = player
|
||||||
controller.media_info.media_type = MediaType.Video
|
controller.media_info.media_type = MediaType.Video
|
||||||
return True
|
return True
|
||||||
# no valid player found
|
# no valid player found
|
||||||
@ -520,7 +518,7 @@ class MediaController(object):
|
|||||||
controller.seekSlider.blockSignals(True)
|
controller.seekSlider.blockSignals(True)
|
||||||
controller.volumeSlider.blockSignals(True)
|
controller.volumeSlider.blockSignals(True)
|
||||||
display = self._define_display(controller)
|
display = self._define_display(controller)
|
||||||
if not self.currentMediaPlayer[controller.controllerType].play(display):
|
if not self.current_media_players[controller.controller_type].play(display):
|
||||||
controller.seekSlider.blockSignals(False)
|
controller.seekSlider.blockSignals(False)
|
||||||
controller.volumeSlider.blockSignals(False)
|
controller.volumeSlider.blockSignals(False)
|
||||||
return False
|
return False
|
||||||
@ -530,7 +528,7 @@ class MediaController(object):
|
|||||||
self.media_volume(controller, controller.media_info.volume)
|
self.media_volume(controller, controller.media_info.volume)
|
||||||
if status:
|
if status:
|
||||||
display.frame.evaluateJavaScript(u'show_blank("desktop");')
|
display.frame.evaluateJavaScript(u'show_blank("desktop");')
|
||||||
self.currentMediaPlayer[controller.controllerType].set_visible(display, True)
|
self.current_media_players[controller.controller_type].set_visible(display, True)
|
||||||
# Flash needs to be played and will not AutoPlay
|
# Flash needs to be played and will not AutoPlay
|
||||||
if controller.media_info.is_flash:
|
if controller.media_info.is_flash:
|
||||||
controller.mediabar.actions[u'playbackPlay'].setVisible(True)
|
controller.mediabar.actions[u'playbackPlay'].setVisible(True)
|
||||||
@ -539,9 +537,9 @@ class MediaController(object):
|
|||||||
controller.mediabar.actions[u'playbackPlay'].setVisible(False)
|
controller.mediabar.actions[u'playbackPlay'].setVisible(False)
|
||||||
controller.mediabar.actions[u'playbackPause'].setVisible(True)
|
controller.mediabar.actions[u'playbackPause'].setVisible(True)
|
||||||
controller.mediabar.actions[u'playbackStop'].setVisible(True)
|
controller.mediabar.actions[u'playbackStop'].setVisible(True)
|
||||||
if controller.isLive:
|
if controller.is_live:
|
||||||
if controller.hideMenu.defaultAction().isChecked():
|
if controller.hide_menu.defaultAction().isChecked():
|
||||||
controller.hideMenu.defaultAction().trigger()
|
controller.hide_menu.defaultAction().trigger()
|
||||||
# Start Timer for ui updates
|
# Start Timer for ui updates
|
||||||
if not self.timer.isActive():
|
if not self.timer.isActive():
|
||||||
self.timer.start()
|
self.timer.start()
|
||||||
@ -568,7 +566,7 @@ class MediaController(object):
|
|||||||
"""
|
"""
|
||||||
log.debug(u'media_pause')
|
log.debug(u'media_pause')
|
||||||
display = self._define_display(controller)
|
display = self._define_display(controller)
|
||||||
self.currentMediaPlayer[controller.controllerType].pause(display)
|
self.current_media_players[controller.controller_type].pause(display)
|
||||||
controller.mediabar.actions[u'playbackPlay'].setVisible(True)
|
controller.mediabar.actions[u'playbackPlay'].setVisible(True)
|
||||||
controller.mediabar.actions[u'playbackStop'].setVisible(True)
|
controller.mediabar.actions[u'playbackStop'].setVisible(True)
|
||||||
controller.mediabar.actions[u'playbackPause'].setVisible(False)
|
controller.mediabar.actions[u'playbackPause'].setVisible(False)
|
||||||
@ -592,10 +590,10 @@ class MediaController(object):
|
|||||||
"""
|
"""
|
||||||
log.debug(u'media_stop')
|
log.debug(u'media_stop')
|
||||||
display = self._define_display(controller)
|
display = self._define_display(controller)
|
||||||
if controller.controllerType in self.currentMediaPlayer:
|
if controller.controller_type in self.current_media_players:
|
||||||
display.frame.evaluateJavaScript(u'show_blank("black");')
|
display.frame.evaluateJavaScript(u'show_blank("black");')
|
||||||
self.currentMediaPlayer[controller.controllerType].stop(display)
|
self.current_media_players[controller.controller_type].stop(display)
|
||||||
self.currentMediaPlayer[controller.controllerType].set_visible(display, False)
|
self.current_media_players[controller.controller_type].set_visible(display, False)
|
||||||
controller.seekSlider.setSliderPosition(0)
|
controller.seekSlider.setSliderPosition(0)
|
||||||
controller.mediabar.actions[u'playbackPlay'].setVisible(True)
|
controller.mediabar.actions[u'playbackPlay'].setVisible(True)
|
||||||
controller.mediabar.actions[u'playbackStop'].setVisible(False)
|
controller.mediabar.actions[u'playbackStop'].setVisible(False)
|
||||||
@ -621,7 +619,7 @@ class MediaController(object):
|
|||||||
"""
|
"""
|
||||||
log.debug(u'media_volume %d' % volume)
|
log.debug(u'media_volume %d' % volume)
|
||||||
display = self._define_display(controller)
|
display = self._define_display(controller)
|
||||||
self.currentMediaPlayer[controller.controllerType].volume(display, volume)
|
self.current_media_players[controller.controller_type].volume(display, volume)
|
||||||
controller.volumeSlider.setValue(volume)
|
controller.volumeSlider.setValue(volume)
|
||||||
|
|
||||||
def media_seek_msg(self, msg):
|
def media_seek_msg(self, msg):
|
||||||
@ -647,7 +645,7 @@ class MediaController(object):
|
|||||||
"""
|
"""
|
||||||
log.debug(u'media_seek')
|
log.debug(u'media_seek')
|
||||||
display = self._define_display(controller)
|
display = self._define_display(controller)
|
||||||
self.currentMediaPlayer[controller.controllerType].seek(display, seekVal)
|
self.current_media_players[controller.controller_type].seek(display, seekVal)
|
||||||
|
|
||||||
def media_reset(self, controller):
|
def media_reset(self, controller):
|
||||||
"""
|
"""
|
||||||
@ -656,12 +654,12 @@ class MediaController(object):
|
|||||||
log.debug(u'media_reset')
|
log.debug(u'media_reset')
|
||||||
self.set_controls_visible(controller, False)
|
self.set_controls_visible(controller, False)
|
||||||
display = self._define_display(controller)
|
display = self._define_display(controller)
|
||||||
if controller.controllerType in self.currentMediaPlayer:
|
if controller.controller_type in self.current_media_players:
|
||||||
display.override = {}
|
display.override = {}
|
||||||
self.currentMediaPlayer[controller.controllerType].reset(display)
|
self.current_media_players[controller.controller_type].reset(display)
|
||||||
self.currentMediaPlayer[controller.controllerType].set_visible(display, False)
|
self.current_media_players[controller.controller_type].set_visible(display, False)
|
||||||
display.frame.evaluateJavaScript(u'show_video( "setBackBoard", null, null, null,"hidden");')
|
display.frame.evaluateJavaScript(u'show_video( "setBackBoard", null, null, null,"hidden");')
|
||||||
del self.currentMediaPlayer[controller.controllerType]
|
del self.current_media_players[controller.controller_type]
|
||||||
|
|
||||||
def media_hide(self, msg):
|
def media_hide(self, msg):
|
||||||
"""
|
"""
|
||||||
@ -670,15 +668,14 @@ class MediaController(object):
|
|||||||
``msg``
|
``msg``
|
||||||
First element is the boolean for Live indication
|
First element is the boolean for Live indication
|
||||||
"""
|
"""
|
||||||
isLive = msg[1]
|
is_live = msg[1]
|
||||||
if not isLive:
|
if not is_live:
|
||||||
return
|
return
|
||||||
controller = self.mainWindow.liveController
|
display = self._define_display(self.live_controller)
|
||||||
display = self._define_display(controller)
|
if self.live_controller.controller_type in self.current_media_players and \
|
||||||
if controller.controllerType in self.currentMediaPlayer and \
|
self.current_media_players[self.live_controller.controller_type].state == MediaState.Playing:
|
||||||
self.currentMediaPlayer[controller.controllerType].state == MediaState.Playing:
|
self.current_media_players[self.live_controller.controller_type].pause(display)
|
||||||
self.currentMediaPlayer[controller.controllerType].pause(display)
|
self.current_media_players[self.live_controller.controller_type].set_visible(display, False)
|
||||||
self.currentMediaPlayer[controller.controllerType].set_visible(display, False)
|
|
||||||
|
|
||||||
def media_blank(self, msg):
|
def media_blank(self, msg):
|
||||||
"""
|
"""
|
||||||
@ -688,16 +685,15 @@ class MediaController(object):
|
|||||||
First element is the boolean for Live indication
|
First element is the boolean for Live indication
|
||||||
Second element is the hide mode
|
Second element is the hide mode
|
||||||
"""
|
"""
|
||||||
isLive = msg[1]
|
is_live = msg[1]
|
||||||
hide_mode = msg[2]
|
hide_mode = msg[2]
|
||||||
if not isLive:
|
if not is_live:
|
||||||
return
|
return
|
||||||
Registry().execute(u'live_display_hide', hide_mode)
|
Registry().execute(u'live_display_hide', hide_mode)
|
||||||
controller = self.mainWindow.liveController
|
display = self._define_display(self.live_controller)
|
||||||
display = self._define_display(controller)
|
if self.current_media_players[self.live_controller.controller_type].state == MediaState.Playing:
|
||||||
if self.currentMediaPlayer[controller.controllerType].state == MediaState.Playing:
|
self.current_media_players[self.live_controller.controller_type].pause(display)
|
||||||
self.currentMediaPlayer[controller.controllerType].pause(display)
|
self.current_media_players[self.live_controller.controller_type].set_visible(display, False)
|
||||||
self.currentMediaPlayer[controller.controllerType].set_visible(display, False)
|
|
||||||
|
|
||||||
def media_unblank(self, msg):
|
def media_unblank(self, msg):
|
||||||
"""
|
"""
|
||||||
@ -708,15 +704,14 @@ class MediaController(object):
|
|||||||
Second element is the boolean for Live indication
|
Second element is the boolean for Live indication
|
||||||
"""
|
"""
|
||||||
Registry().execute(u'live_display_show')
|
Registry().execute(u'live_display_show')
|
||||||
isLive = msg[1]
|
is_live = msg[1]
|
||||||
if not isLive:
|
if not is_live:
|
||||||
return
|
return
|
||||||
controller = self.mainWindow.liveController
|
display = self._define_display(self.live_controller)
|
||||||
display = self._define_display(controller)
|
if self.live_controller.controller_type in self.current_media_players and \
|
||||||
if controller.controllerType in self.currentMediaPlayer and \
|
self.current_media_players[self.live_controller.controller_type].state != MediaState.Playing:
|
||||||
self.currentMediaPlayer[controller.controllerType].state != MediaState.Playing:
|
if self.current_media_players[self.live_controller.controller_type].play(display):
|
||||||
if self.currentMediaPlayer[controller.controllerType].play(display):
|
self.current_media_players[self.live_controller.controller_type].set_visible(display, True)
|
||||||
self.currentMediaPlayer[controller.controllerType].set_visible(display, True)
|
|
||||||
# Start Timer for ui updates
|
# Start Timer for ui updates
|
||||||
if not self.timer.isActive():
|
if not self.timer.isActive():
|
||||||
self.timer.start()
|
self.timer.start()
|
||||||
@ -736,9 +731,9 @@ class MediaController(object):
|
|||||||
``controller``
|
``controller``
|
||||||
Controller to be used
|
Controller to be used
|
||||||
"""
|
"""
|
||||||
if controller.isLive:
|
if controller.is_live:
|
||||||
return controller.display
|
return controller.display
|
||||||
return controller.previewDisplay
|
return controller.preview_display
|
||||||
|
|
||||||
def _get_service_manager(self):
|
def _get_service_manager(self):
|
||||||
"""
|
"""
|
||||||
@ -749,3 +744,13 @@ class MediaController(object):
|
|||||||
return self._service_manager
|
return self._service_manager
|
||||||
|
|
||||||
service_manager = property(_get_service_manager)
|
service_manager = property(_get_service_manager)
|
||||||
|
|
||||||
|
def _get_live_controller(self):
|
||||||
|
"""
|
||||||
|
Adds the live controller to the class dynamically
|
||||||
|
"""
|
||||||
|
if not hasattr(self, u'_live_controller'):
|
||||||
|
self._live_controller = Registry().get(u'live_controller')
|
||||||
|
return self._live_controller
|
||||||
|
|
||||||
|
live_controller = property(_get_live_controller)
|
||||||
|
@ -55,7 +55,7 @@ class PlayerTab(SettingsTab):
|
|||||||
"""
|
"""
|
||||||
Constructor
|
Constructor
|
||||||
"""
|
"""
|
||||||
self.mediaPlayers = self.media_controller.mediaPlayers
|
self.media_players = self.media_controller.media_players
|
||||||
self.savedUsedPlayers = None
|
self.savedUsedPlayers = None
|
||||||
self.iconPath = u':/media/multimedia-player.png'
|
self.iconPath = u':/media/multimedia-player.png'
|
||||||
player_translated = translate('OpenLP.PlayerTab', 'Players')
|
player_translated = translate('OpenLP.PlayerTab', 'Players')
|
||||||
@ -171,7 +171,7 @@ class PlayerTab(SettingsTab):
|
|||||||
self.playerCheckBoxes[u'%s' % player].setEnabled(False)
|
self.playerCheckBoxes[u'%s' % player].setEnabled(False)
|
||||||
else:
|
else:
|
||||||
self.playerCheckBoxes[u'%s' % player].setEnabled(True)
|
self.playerCheckBoxes[u'%s' % player].setEnabled(True)
|
||||||
self.playerOrderlistWidget.addItem(self.mediaPlayers[unicode(player)].original_name)
|
self.playerOrderlistWidget.addItem(self.media_players[unicode(player)].original_name)
|
||||||
|
|
||||||
def onUpButtonClicked(self):
|
def onUpButtonClicked(self):
|
||||||
"""
|
"""
|
||||||
@ -232,13 +232,13 @@ class PlayerTab(SettingsTab):
|
|||||||
Registry().execute(u'mediaitem_media_rebuild')
|
Registry().execute(u'mediaitem_media_rebuild')
|
||||||
Registry().execute(u'config_screen_changed')
|
Registry().execute(u'config_screen_changed')
|
||||||
|
|
||||||
def postSetUp(self, postUpdate=False):
|
def post_set_up(self):
|
||||||
"""
|
"""
|
||||||
Late setup for players as the MediaController has to be initialised
|
Late setup for players as the MediaController has to be initialised
|
||||||
first.
|
first.
|
||||||
"""
|
"""
|
||||||
for key, player in self.mediaPlayers.iteritems():
|
for key, player in self.media_players.iteritems():
|
||||||
player = self.mediaPlayers[key]
|
player = self.media_players[key]
|
||||||
checkbox = MediaQCheckBox(self.mediaPlayerGroupBox)
|
checkbox = MediaQCheckBox(self.mediaPlayerGroupBox)
|
||||||
checkbox.setEnabled(player.available)
|
checkbox.setEnabled(player.available)
|
||||||
checkbox.setObjectName(player.name + u'CheckBox')
|
checkbox.setObjectName(player.name + u'CheckBox')
|
||||||
@ -258,8 +258,8 @@ class PlayerTab(SettingsTab):
|
|||||||
"""
|
"""
|
||||||
Translations for players is dependent on their setup as well
|
Translations for players is dependent on their setup as well
|
||||||
"""
|
"""
|
||||||
for key in self.mediaPlayers:
|
for key in self.media_players:
|
||||||
player = self.mediaPlayers[key]
|
player = self.media_players[key]
|
||||||
checkbox = self.playerCheckBoxes[player.name]
|
checkbox = self.playerCheckBoxes[player.name]
|
||||||
checkbox.setPlayerName(player.name)
|
checkbox.setPlayerName(player.name)
|
||||||
if player.available:
|
if player.available:
|
||||||
|
@ -122,7 +122,7 @@ class VlcPlayer(MediaPlayer):
|
|||||||
command_line_options = u'--no-video-title-show'
|
command_line_options = u'--no-video-title-show'
|
||||||
if not display.hasAudio:
|
if not display.hasAudio:
|
||||||
command_line_options += u' --no-audio --no-video-title-show'
|
command_line_options += u' --no-audio --no-video-title-show'
|
||||||
if Settings().value(u'advanced/hide mouse') and display.controller.isLive:
|
if Settings().value(u'advanced/hide mouse') and display.controller.is_live:
|
||||||
command_line_options += u' --mouse-hide-timeout=0'
|
command_line_options += u' --mouse-hide-timeout=0'
|
||||||
display.vlcInstance = vlc.Instance(command_line_options)
|
display.vlcInstance = vlc.Instance(command_line_options)
|
||||||
# creating an empty vlc media player
|
# creating an empty vlc media player
|
||||||
|
@ -307,8 +307,8 @@ class WebkitPlayer(MediaPlayer):
|
|||||||
"""
|
"""
|
||||||
Set up the player
|
Set up the player
|
||||||
"""
|
"""
|
||||||
display.webView.resize(display.size())
|
display.web_view.resize(display.size())
|
||||||
display.webView.raise_()
|
display.web_view.raise_()
|
||||||
self.hasOwnWidget = False
|
self.hasOwnWidget = False
|
||||||
|
|
||||||
def check_available(self):
|
def check_available(self):
|
||||||
@ -333,7 +333,7 @@ class WebkitPlayer(MediaPlayer):
|
|||||||
loop = u'true'
|
loop = u'true'
|
||||||
else:
|
else:
|
||||||
loop = u'false'
|
loop = u'false'
|
||||||
display.webView.setVisible(True)
|
display.web_view.setVisible(True)
|
||||||
if controller.media_info.file_info.suffix() == u'swf':
|
if controller.media_info.file_info.suffix() == u'swf':
|
||||||
controller.media_info.is_flash = True
|
controller.media_info.is_flash = True
|
||||||
js = u'show_flash("load","%s");' % (path.replace(u'\\', u'\\\\'))
|
js = u'show_flash("load","%s");' % (path.replace(u'\\', u'\\\\'))
|
||||||
@ -346,14 +346,14 @@ class WebkitPlayer(MediaPlayer):
|
|||||||
"""
|
"""
|
||||||
Resize the player
|
Resize the player
|
||||||
"""
|
"""
|
||||||
display.webView.resize(display.size())
|
display.web_view.resize(display.size())
|
||||||
|
|
||||||
def play(self, display):
|
def play(self, display):
|
||||||
"""
|
"""
|
||||||
Play a video
|
Play a video
|
||||||
"""
|
"""
|
||||||
controller = display.controller
|
controller = display.controller
|
||||||
display.webLoaded = True
|
display.web_loaded = True
|
||||||
length = 0
|
length = 0
|
||||||
start_time = 0
|
start_time = 0
|
||||||
if self.state != MediaState.Paused and controller.media_info.start_time > 0:
|
if self.state != MediaState.Paused and controller.media_info.start_time > 0:
|
||||||
@ -368,7 +368,7 @@ class WebkitPlayer(MediaPlayer):
|
|||||||
# TODO add playing check and get the correct media length
|
# TODO add playing check and get the correct media length
|
||||||
controller.media_info.length = length
|
controller.media_info.length = length
|
||||||
self.state = MediaState.Playing
|
self.state = MediaState.Playing
|
||||||
display.webView.raise_()
|
display.web_view.raise_()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def pause(self, display):
|
def pause(self, display):
|
||||||
|
@ -406,7 +406,7 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
|||||||
# Only continue when we include the song's text.
|
# Only continue when we include the song's text.
|
||||||
if not self.slideTextCheckBox.isChecked():
|
if not self.slideTextCheckBox.isChecked():
|
||||||
return
|
return
|
||||||
for item in self.service_manager.serviceItems:
|
for item in self.service_manager.service_items:
|
||||||
# Trigger Audit requests
|
# Trigger Audit requests
|
||||||
Registry().register_function(u'print_service_started', [item[u'service_item']])
|
Registry().register_function(u'print_service_started', [item[u'service_item']])
|
||||||
|
|
||||||
|
@ -152,52 +152,52 @@ class ServiceManagerDialog(object):
|
|||||||
# Add the bottom toolbar
|
# Add the bottom toolbar
|
||||||
self.order_toolbar = OpenLPToolbar(self)
|
self.order_toolbar = OpenLPToolbar(self)
|
||||||
action_list = ActionList.get_instance()
|
action_list = ActionList.get_instance()
|
||||||
action_list.add_category(UiStrings().Service, CategoryOrder.standardToolbar)
|
action_list.add_category(UiStrings().Service, CategoryOrder.standard_toolbar)
|
||||||
self.service_manager_list.moveTop = self.order_toolbar.addToolbarAction(u'moveTop',
|
self.service_manager_list.moveTop = self.order_toolbar.addToolbarAction(u'moveTop',
|
||||||
text=translate('OpenLP.ServiceManager', 'Move to &top'), icon=u':/services/service_top.png',
|
text=translate('OpenLP.ServiceManager', 'Move to &top'), icon=u':/services/service_top.png',
|
||||||
tooltip=translate('OpenLP.ServiceManager', 'Move item to the top of the service.'),
|
tooltip=translate('OpenLP.ServiceManager', 'Move item to the top of the service.'),
|
||||||
shortcuts=[QtCore.Qt.Key_Home], category=UiStrings().Service, triggers=self.onServiceTop)
|
can_shortcuts=True, category=UiStrings().Service, triggers=self.onServiceTop)
|
||||||
self.service_manager_list.moveUp = self.order_toolbar.addToolbarAction(u'moveUp',
|
self.service_manager_list.moveUp = self.order_toolbar.addToolbarAction(u'moveUp',
|
||||||
text=translate('OpenLP.ServiceManager', 'Move &up'), icon=u':/services/service_up.png',
|
text=translate('OpenLP.ServiceManager', 'Move &up'), icon=u':/services/service_up.png',
|
||||||
tooltip=translate('OpenLP.ServiceManager', 'Move item up one position in the service.'),
|
tooltip=translate('OpenLP.ServiceManager', 'Move item up one position in the service.'),
|
||||||
shortcuts=[QtCore.Qt.Key_PageUp], category=UiStrings().Service, triggers=self.onServiceUp)
|
can_shortcuts=True, category=UiStrings().Service, triggers=self.onServiceUp)
|
||||||
self.service_manager_list.moveDown = self.order_toolbar.addToolbarAction(u'moveDown',
|
self.service_manager_list.moveDown = self.order_toolbar.addToolbarAction(u'moveDown',
|
||||||
text=translate('OpenLP.ServiceManager', 'Move &down'), icon=u':/services/service_down.png',
|
text=translate('OpenLP.ServiceManager', 'Move &down'), icon=u':/services/service_down.png',
|
||||||
tooltip=translate('OpenLP.ServiceManager', 'Move item down one position in the service.'),
|
tooltip=translate('OpenLP.ServiceManager', 'Move item down one position in the service.'),
|
||||||
shortcuts=[QtCore.Qt.Key_PageDown], category=UiStrings().Service, triggers=self.onServiceDown)
|
can_shortcuts=True, category=UiStrings().Service, triggers=self.onServiceDown)
|
||||||
self.service_manager_list.moveBottom = self.order_toolbar.addToolbarAction(u'moveBottom',
|
self.service_manager_list.moveBottom = self.order_toolbar.addToolbarAction(u'moveBottom',
|
||||||
text=translate('OpenLP.ServiceManager', 'Move to &bottom'), icon=u':/services/service_bottom.png',
|
text=translate('OpenLP.ServiceManager', 'Move to &bottom'), icon=u':/services/service_bottom.png',
|
||||||
tooltip=translate('OpenLP.ServiceManager', 'Move item to the end of the service.'),
|
tooltip=translate('OpenLP.ServiceManager', 'Move item to the end of the service.'),
|
||||||
shortcuts=[QtCore.Qt.Key_End], category=UiStrings().Service, triggers=self.onServiceEnd)
|
can_shortcuts=True, category=UiStrings().Service, triggers=self.onServiceEnd)
|
||||||
self.service_manager_list.down = self.order_toolbar.addToolbarAction(u'down',
|
self.service_manager_list.down = self.order_toolbar.addToolbarAction(u'down',
|
||||||
text=translate('OpenLP.ServiceManager', 'Move &down'),
|
text=translate('OpenLP.ServiceManager', 'Move &down'), can_shortcuts=True,
|
||||||
tooltip=translate('OpenLP.ServiceManager', 'Moves the selection down the window.'), visible=False,
|
tooltip=translate('OpenLP.ServiceManager', 'Moves the selection down the window.'), visible=False,
|
||||||
shortcuts=[QtCore.Qt.Key_Down], triggers=self.on_move_selection_down)
|
triggers=self.on_move_selection_down)
|
||||||
action_list.add_action(self.service_manager_list.down)
|
action_list.add_action(self.service_manager_list.down)
|
||||||
self.service_manager_list.up = self.order_toolbar.addToolbarAction(u'up',
|
self.service_manager_list.up = self.order_toolbar.addToolbarAction(u'up',
|
||||||
text=translate('OpenLP.ServiceManager', 'Move up'), tooltip=translate('OpenLP.ServiceManager',
|
text=translate('OpenLP.ServiceManager', 'Move up'), can_shortcuts=True,
|
||||||
'Moves the selection up the window.'), visible=False, shortcuts=[QtCore.Qt.Key_Up],
|
tooltip=translate('OpenLP.ServiceManager', 'Moves the selection up the window.'), visible=False,
|
||||||
triggers=self.on_move_selection_up)
|
triggers=self.on_move_selection_up)
|
||||||
action_list.add_action(self.service_manager_list.up)
|
action_list.add_action(self.service_manager_list.up)
|
||||||
self.order_toolbar.addSeparator()
|
self.order_toolbar.addSeparator()
|
||||||
self.service_manager_list.delete = self.order_toolbar.addToolbarAction(u'delete',
|
self.service_manager_list.delete = self.order_toolbar.addToolbarAction(u'delete', can_shortcuts=True,
|
||||||
text=translate('OpenLP.ServiceManager', '&Delete From Service'), icon=u':/general/general_delete.png',
|
text=translate('OpenLP.ServiceManager', '&Delete From Service'), icon=u':/general/general_delete.png',
|
||||||
tooltip=translate('OpenLP.ServiceManager', 'Delete the selected item from the service.'),
|
tooltip=translate('OpenLP.ServiceManager', 'Delete the selected item from the service.'),
|
||||||
shortcuts=[QtCore.Qt.Key_Delete], triggers=self.onDeleteFromService)
|
triggers=self.onDeleteFromService)
|
||||||
self.order_toolbar.addSeparator()
|
self.order_toolbar.addSeparator()
|
||||||
self.service_manager_list.expand = self.order_toolbar.addToolbarAction(u'expand',
|
self.service_manager_list.expand = self.order_toolbar.addToolbarAction(u'expand', can_shortcuts=True,
|
||||||
text=translate('OpenLP.ServiceManager', '&Expand all'), icon=u':/services/service_expand_all.png',
|
text=translate('OpenLP.ServiceManager', '&Expand all'), icon=u':/services/service_expand_all.png',
|
||||||
tooltip=translate('OpenLP.ServiceManager', 'Expand all the service items.'),
|
tooltip=translate('OpenLP.ServiceManager', 'Expand all the service items.'),
|
||||||
shortcuts=[QtCore.Qt.Key_Plus], category=UiStrings().Service, triggers=self.onExpandAll)
|
category=UiStrings().Service, triggers=self.onExpandAll)
|
||||||
self.service_manager_list.collapse = self.order_toolbar.addToolbarAction(u'collapse',
|
self.service_manager_list.collapse = self.order_toolbar.addToolbarAction(u'collapse', can_shortcuts=True,
|
||||||
text=translate('OpenLP.ServiceManager', '&Collapse all'), icon=u':/services/service_collapse_all.png',
|
text=translate('OpenLP.ServiceManager', '&Collapse all'), icon=u':/services/service_collapse_all.png',
|
||||||
tooltip=translate('OpenLP.ServiceManager', 'Collapse all the service items.'),
|
tooltip=translate('OpenLP.ServiceManager', 'Collapse all the service items.'),
|
||||||
shortcuts=[QtCore.Qt.Key_Minus], category=UiStrings().Service, triggers=self.onCollapseAll)
|
category=UiStrings().Service, triggers=self.onCollapseAll)
|
||||||
self.order_toolbar.addSeparator()
|
self.order_toolbar.addSeparator()
|
||||||
self.service_manager_list.make_live = self.order_toolbar.addToolbarAction(u'make_live',
|
self.service_manager_list.make_live = self.order_toolbar.addToolbarAction(u'make_live', can_shortcuts=True,
|
||||||
text=translate('OpenLP.ServiceManager', 'Go Live'), icon=u':/general/general_live.png',
|
text=translate('OpenLP.ServiceManager', 'Go Live'), icon=u':/general/general_live.png',
|
||||||
tooltip=translate('OpenLP.ServiceManager', 'Send the selected item to Live.'),
|
tooltip=translate('OpenLP.ServiceManager', 'Send the selected item to Live.'),
|
||||||
shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], category=UiStrings().Service,
|
category=UiStrings().Service,
|
||||||
triggers=self.make_live)
|
triggers=self.make_live)
|
||||||
self.layout.addWidget(self.order_toolbar)
|
self.layout.addWidget(self.order_toolbar)
|
||||||
# Connect up our signals and slots
|
# Connect up our signals and slots
|
||||||
|
@ -50,6 +50,7 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
|||||||
Initialise the settings form
|
Initialise the settings form
|
||||||
"""
|
"""
|
||||||
Registry().register(u'settings_form', self)
|
Registry().register(u'settings_form', self)
|
||||||
|
Registry().register_function(u'bootstrap_post_set_up', self.post_set_up)
|
||||||
QtGui.QDialog.__init__(self, parent)
|
QtGui.QDialog.__init__(self, parent)
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
# General tab
|
# General tab
|
||||||
@ -75,7 +76,7 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
|||||||
self.insertTab(self.advancedTab, 2, PluginStatus.Active)
|
self.insertTab(self.advancedTab, 2, PluginStatus.Active)
|
||||||
self.insertTab(self.playerTab, 3, PluginStatus.Active)
|
self.insertTab(self.playerTab, 3, PluginStatus.Active)
|
||||||
count = 4
|
count = 4
|
||||||
for plugin in self.plugins:
|
for plugin in self.plugin_manager.plugins:
|
||||||
if plugin.settingsTab:
|
if plugin.settingsTab:
|
||||||
self.insertTab(plugin.settingsTab, count, plugin.status)
|
self.insertTab(plugin.settingsTab, count, plugin.status)
|
||||||
count += 1
|
count += 1
|
||||||
@ -118,17 +119,17 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
|||||||
self.stackedLayout.widget(tabIndex).cancel()
|
self.stackedLayout.widget(tabIndex).cancel()
|
||||||
return QtGui.QDialog.reject(self)
|
return QtGui.QDialog.reject(self)
|
||||||
|
|
||||||
def postSetUp(self):
|
def post_set_up(self):
|
||||||
"""
|
"""
|
||||||
Run any post-setup code for the tabs on the form
|
Run any post-setup code for the tabs on the form
|
||||||
"""
|
"""
|
||||||
self.generalTab.postSetUp()
|
self.generalTab.post_set_up()
|
||||||
self.themesTab.postSetUp()
|
self.themesTab.post_set_up()
|
||||||
self.advancedTab.postSetUp()
|
self.advancedTab.post_set_up()
|
||||||
self.playerTab.postSetUp()
|
self.playerTab.post_set_up()
|
||||||
for plugin in self.plugins:
|
for plugin in self.plugin_manager.plugins:
|
||||||
if plugin.settingsTab:
|
if plugin.settingsTab:
|
||||||
plugin.settingsTab.postSetUp()
|
plugin.settingsTab.post_set_up()
|
||||||
|
|
||||||
def tabChanged(self, tabIndex):
|
def tabChanged(self, tabIndex):
|
||||||
"""
|
"""
|
||||||
@ -166,3 +167,13 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
|||||||
return self._service_manager
|
return self._service_manager
|
||||||
|
|
||||||
service_manager = property(_get_service_manager)
|
service_manager = property(_get_service_manager)
|
||||||
|
|
||||||
|
def _get_plugin_manager(self):
|
||||||
|
"""
|
||||||
|
Adds the plugin manager to the class dynamically
|
||||||
|
"""
|
||||||
|
if not hasattr(self, u'_plugin_manager'):
|
||||||
|
self._plugin_manager = Registry().get(u'plugin_manager')
|
||||||
|
return self._plugin_manager
|
||||||
|
|
||||||
|
plugin_manager = property(_get_plugin_manager)
|
||||||
|
@ -56,8 +56,8 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
self.changedActions = {}
|
self.changedActions = {}
|
||||||
self.action_list = ActionList.get_instance()
|
self.action_list = ActionList.get_instance()
|
||||||
QtCore.QObject.connect(self.primaryPushButton, QtCore.SIGNAL(u'toggled(bool)'),
|
self.dialog_was_shown = False
|
||||||
self.onPrimaryPushButtonClicked)
|
QtCore.QObject.connect(self.primaryPushButton, QtCore.SIGNAL(u'toggled(bool)'), self.onPrimaryPushButtonClicked)
|
||||||
QtCore.QObject.connect(self.alternatePushButton, QtCore.SIGNAL(u'toggled(bool)'),
|
QtCore.QObject.connect(self.alternatePushButton, QtCore.SIGNAL(u'toggled(bool)'),
|
||||||
self.onAlternatePushButtonClicked)
|
self.onAlternatePushButtonClicked)
|
||||||
QtCore.QObject.connect(self.treeWidget,
|
QtCore.QObject.connect(self.treeWidget,
|
||||||
@ -72,8 +72,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
self.onRestoreDefaultsClicked)
|
self.onRestoreDefaultsClicked)
|
||||||
QtCore.QObject.connect(self.defaultRadioButton, QtCore.SIGNAL(u'clicked(bool)'),
|
QtCore.QObject.connect(self.defaultRadioButton, QtCore.SIGNAL(u'clicked(bool)'),
|
||||||
self.onDefaultRadioButtonClicked)
|
self.onDefaultRadioButtonClicked)
|
||||||
QtCore.QObject.connect(self.customRadioButton, QtCore.SIGNAL(u'clicked(bool)'),
|
QtCore.QObject.connect(self.customRadioButton, QtCore.SIGNAL(u'clicked(bool)'), self.onCustomRadioButtonClicked)
|
||||||
self.onCustomRadioButtonClicked)
|
|
||||||
|
|
||||||
def keyPressEvent(self, event):
|
def keyPressEvent(self, event):
|
||||||
"""
|
"""
|
||||||
@ -93,9 +92,12 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
"""
|
"""
|
||||||
if not self.primaryPushButton.isChecked() and not self.alternatePushButton.isChecked():
|
if not self.primaryPushButton.isChecked() and not self.alternatePushButton.isChecked():
|
||||||
return
|
return
|
||||||
|
# Do not continue, as the event is for the dialog (close it).
|
||||||
|
if self.dialog_was_shown and event.key() in (QtCore.Qt.Key_Escape, QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
|
||||||
|
self.dialog_was_shown = False
|
||||||
|
return
|
||||||
key = event.key()
|
key = event.key()
|
||||||
if key == QtCore.Qt.Key_Shift or key == QtCore.Qt.Key_Control or \
|
if key in (QtCore.Qt.Key_Shift, QtCore.Qt.Key_Control, QtCore.Qt.Key_Meta, QtCore.Qt.Key_Alt):
|
||||||
key == QtCore.Qt.Key_Meta or key == QtCore.Qt.Key_Alt:
|
|
||||||
return
|
return
|
||||||
key_string = QtGui.QKeySequence(key).toString()
|
key_string = QtGui.QKeySequence(key).toString()
|
||||||
if event.modifiers() & QtCore.Qt.ControlModifier == QtCore.Qt.ControlModifier:
|
if event.modifiers() & QtCore.Qt.ControlModifier == QtCore.Qt.ControlModifier:
|
||||||
@ -109,11 +111,9 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
key_sequence = QtGui.QKeySequence(key_string)
|
key_sequence = QtGui.QKeySequence(key_string)
|
||||||
if self._validiate_shortcut(self._currentItemAction(), key_sequence):
|
if self._validiate_shortcut(self._currentItemAction(), key_sequence):
|
||||||
if self.primaryPushButton.isChecked():
|
if self.primaryPushButton.isChecked():
|
||||||
self._adjustButton(self.primaryPushButton,
|
self._adjustButton(self.primaryPushButton, False, text=key_sequence.toString())
|
||||||
False, text=key_sequence.toString())
|
|
||||||
elif self.alternatePushButton.isChecked():
|
elif self.alternatePushButton.isChecked():
|
||||||
self._adjustButton(self.alternatePushButton,
|
self._adjustButton(self.alternatePushButton, False, text=key_sequence.toString())
|
||||||
False, text=key_sequence.toString())
|
|
||||||
|
|
||||||
def exec_(self):
|
def exec_(self):
|
||||||
"""
|
"""
|
||||||
@ -147,8 +147,8 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
|
|
||||||
def refreshShortcutList(self):
|
def refreshShortcutList(self):
|
||||||
"""
|
"""
|
||||||
This refreshes the item's shortcuts shown in the list. Note, this
|
This refreshes the item's shortcuts shown in the list. Note, this neither adds new actions nor removes old
|
||||||
neither adds new actions nor removes old actions.
|
actions.
|
||||||
"""
|
"""
|
||||||
iterator = QtGui.QTreeWidgetItemIterator(self.treeWidget)
|
iterator = QtGui.QTreeWidgetItemIterator(self.treeWidget)
|
||||||
while iterator.value():
|
while iterator.value():
|
||||||
@ -204,21 +204,19 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
new_shortcuts = []
|
new_shortcuts = []
|
||||||
if shortcuts:
|
if shortcuts:
|
||||||
new_shortcuts.append(shortcuts[0])
|
new_shortcuts.append(shortcuts[0])
|
||||||
new_shortcuts.append(
|
new_shortcuts.append(QtGui.QKeySequence(self.alternatePushButton.text()))
|
||||||
QtGui.QKeySequence(self.alternatePushButton.text()))
|
|
||||||
self.changedActions[action] = new_shortcuts
|
self.changedActions[action] = new_shortcuts
|
||||||
if not self.primaryPushButton.text():
|
if not self.primaryPushButton.text():
|
||||||
# When we do not have a primary shortcut, the just entered alternate
|
# When we do not have a primary shortcut, the just entered alternate shortcut will automatically become the
|
||||||
# shortcut will automatically become the primary shortcut. That is
|
# primary shortcut. That is why we have to adjust the primary button's text.
|
||||||
# why we have to adjust the primary button's text.
|
|
||||||
self.primaryPushButton.setText(self.alternatePushButton.text())
|
self.primaryPushButton.setText(self.alternatePushButton.text())
|
||||||
self.alternatePushButton.setText(u'')
|
self.alternatePushButton.setText(u'')
|
||||||
self.refreshShortcutList()
|
self.refreshShortcutList()
|
||||||
|
|
||||||
def onItemDoubleClicked(self, item, column):
|
def onItemDoubleClicked(self, item, column):
|
||||||
"""
|
"""
|
||||||
A item has been double clicked. The ``primaryPushButton`` will be
|
A item has been double clicked. The ``primaryPushButton`` will be checked and the item's shortcut will be
|
||||||
checked and the item's shortcut will be displayed.
|
displayed.
|
||||||
"""
|
"""
|
||||||
action = self._currentItemAction(item)
|
action = self._currentItemAction(item)
|
||||||
if action is None:
|
if action is None:
|
||||||
@ -234,8 +232,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
|
|
||||||
def onCurrentItemChanged(self, item=None, previousItem=None):
|
def onCurrentItemChanged(self, item=None, previousItem=None):
|
||||||
"""
|
"""
|
||||||
A item has been pressed. We adjust the button's text to the action's
|
A item has been pressed. We adjust the button's text to the action's shortcut which is encapsulate in the item.
|
||||||
shortcut which is encapsulate in the item.
|
|
||||||
"""
|
"""
|
||||||
action = self._currentItemAction(item)
|
action = self._currentItemAction(item)
|
||||||
self.primaryPushButton.setEnabled(action is not None)
|
self.primaryPushButton.setEnabled(action is not None)
|
||||||
@ -253,9 +250,8 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
if len(action.defaultShortcuts) == 2:
|
if len(action.defaultShortcuts) == 2:
|
||||||
alternate_label_text = action.defaultShortcuts[1].toString()
|
alternate_label_text = action.defaultShortcuts[1].toString()
|
||||||
shortcuts = self._actionShortcuts(action)
|
shortcuts = self._actionShortcuts(action)
|
||||||
# We do not want to loose pending changes, that is why we have to
|
# We do not want to loose pending changes, that is why we have to keep the text when, this function has not
|
||||||
# keep the text when, this function has not been triggered by a
|
# been triggered by a signal.
|
||||||
# signal.
|
|
||||||
if item is None:
|
if item is None:
|
||||||
primary_text = self.primaryPushButton.text()
|
primary_text = self.primaryPushButton.text()
|
||||||
alternate_text = self.alternatePushButton.text()
|
alternate_text = self.alternatePushButton.text()
|
||||||
@ -264,8 +260,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
elif len(shortcuts) == 2:
|
elif len(shortcuts) == 2:
|
||||||
primary_text = shortcuts[0].toString()
|
primary_text = shortcuts[0].toString()
|
||||||
alternate_text = shortcuts[1].toString()
|
alternate_text = shortcuts[1].toString()
|
||||||
# When we are capturing a new shortcut, we do not want, the buttons to
|
# When we are capturing a new shortcut, we do not want, the buttons to display the current shortcut.
|
||||||
# display the current shortcut.
|
|
||||||
if self.primaryPushButton.isChecked():
|
if self.primaryPushButton.isChecked():
|
||||||
primary_text = u''
|
primary_text = u''
|
||||||
if self.alternatePushButton.isChecked():
|
if self.alternatePushButton.isChecked():
|
||||||
@ -274,8 +269,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
self.alternatePushButton.setText(alternate_text)
|
self.alternatePushButton.setText(alternate_text)
|
||||||
self.primaryLabel.setText(primary_label_text)
|
self.primaryLabel.setText(primary_label_text)
|
||||||
self.alternateLabel.setText(alternate_label_text)
|
self.alternateLabel.setText(alternate_label_text)
|
||||||
# We do not want to toggle and radio button, as the function has not
|
# We do not want to toggle and radio button, as the function has not been triggered by a signal.
|
||||||
# been triggered by a signal.
|
|
||||||
if item is None:
|
if item is None:
|
||||||
return
|
return
|
||||||
if primary_label_text == primary_text and alternate_label_text == alternate_text:
|
if primary_label_text == primary_text and alternate_label_text == alternate_text:
|
||||||
@ -303,8 +297,8 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
|
|
||||||
def onDefaultRadioButtonClicked(self, toggled):
|
def onDefaultRadioButtonClicked(self, toggled):
|
||||||
"""
|
"""
|
||||||
The default radio button has been clicked, which means we have to make
|
The default radio button has been clicked, which means we have to make sure, that we use the default shortcuts
|
||||||
sure, that we use the default shortcuts for the action.
|
for the action.
|
||||||
"""
|
"""
|
||||||
if not toggled:
|
if not toggled:
|
||||||
return
|
return
|
||||||
@ -325,9 +319,8 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
|
|
||||||
def onCustomRadioButtonClicked(self, toggled):
|
def onCustomRadioButtonClicked(self, toggled):
|
||||||
"""
|
"""
|
||||||
The custom shortcut radio button was clicked, thus we have to restore
|
The custom shortcut radio button was clicked, thus we have to restore the custom shortcuts by calling those
|
||||||
the custom shortcuts by calling those functions triggered by button
|
functions triggered by button clicks.
|
||||||
clicks.
|
|
||||||
"""
|
"""
|
||||||
if not toggled:
|
if not toggled:
|
||||||
return
|
return
|
||||||
@ -337,8 +330,8 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
"""
|
"""
|
||||||
Save the shortcuts. **Note**, that we do not have to load the shortcuts,
|
Save the shortcuts. **Note**, that we do not have to load the shortcuts, as they are loaded in
|
||||||
as they are loaded in :class:`~openlp.core.utils.ActionList`.
|
:class:`~openlp.core.utils.ActionList`.
|
||||||
"""
|
"""
|
||||||
settings = Settings()
|
settings = Settings()
|
||||||
settings.beginGroup(u'shortcuts')
|
settings.beginGroup(u'shortcuts')
|
||||||
@ -348,8 +341,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
continue
|
continue
|
||||||
for action in category.actions:
|
for action in category.actions:
|
||||||
if action in self.changedActions:
|
if action in self.changedActions:
|
||||||
old_shortcuts = map(unicode,
|
old_shortcuts = map(QtGui.QKeySequence.toString, action.shortcuts())
|
||||||
map(QtGui.QKeySequence.toString, action.shortcuts()))
|
|
||||||
action.setShortcuts(self.changedActions[action])
|
action.setShortcuts(self.changedActions[action])
|
||||||
self.action_list.update_shortcut_map(action, old_shortcuts)
|
self.action_list.update_shortcut_map(action, old_shortcuts)
|
||||||
settings.setValue(action.objectName(), action.shortcuts())
|
settings.setValue(action.objectName(), action.shortcuts())
|
||||||
@ -367,13 +359,10 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
new_shortcuts = []
|
new_shortcuts = []
|
||||||
if action.defaultShortcuts:
|
if action.defaultShortcuts:
|
||||||
new_shortcuts.append(action.defaultShortcuts[0])
|
new_shortcuts.append(action.defaultShortcuts[0])
|
||||||
# We have to check if the primary default shortcut is available. But
|
# We have to check if the primary default shortcut is available. But we only have to check, if the action
|
||||||
# we only have to check, if the action has a default primary
|
# has a default primary shortcut (an "empty" shortcut is always valid and if the action does not have a
|
||||||
# shortcut (an "empty" shortcut is always valid and if the action
|
# default primary shortcut, then the alternative shortcut (not the default one) will become primary
|
||||||
# does not have a default primary shortcut, then the alternative
|
# shortcut, thus the check will assume that an action were going to have the same shortcut twice.
|
||||||
# shortcut (not the default one) will become primary shortcut, thus
|
|
||||||
# the check will assume that an action were going to have the same
|
|
||||||
# shortcut twice.
|
|
||||||
if not self._validiate_shortcut(action, new_shortcuts[0]) and new_shortcuts[0] != shortcuts[0]:
|
if not self._validiate_shortcut(action, new_shortcuts[0]) and new_shortcuts[0] != shortcuts[0]:
|
||||||
return
|
return
|
||||||
if len(shortcuts) == 2:
|
if len(shortcuts) == 2:
|
||||||
@ -405,9 +394,8 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
|
|
||||||
def _validiate_shortcut(self, changing_action, key_sequence):
|
def _validiate_shortcut(self, changing_action, key_sequence):
|
||||||
"""
|
"""
|
||||||
Checks if the given ``changing_action `` can use the given
|
Checks if the given ``changing_action `` can use the given ``key_sequence``. Returns ``True`` if the
|
||||||
``key_sequence``. Returns ``True`` if the ``key_sequence`` can be used
|
``key_sequence`` can be used by the action, otherwise displays a dialog and returns ``False``.
|
||||||
by the action, otherwise displays a dialog and returns ``False``.
|
|
||||||
|
|
||||||
``changing_action``
|
``changing_action``
|
||||||
The action which wants to use the ``key_sequence``.
|
The action which wants to use the ``key_sequence``.
|
||||||
@ -429,11 +417,9 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
# Have the same parent, thus they cannot have the same shortcut.
|
# Have the same parent, thus they cannot have the same shortcut.
|
||||||
if action.parent() is changing_action.parent():
|
if action.parent() is changing_action.parent():
|
||||||
is_valid = False
|
is_valid = False
|
||||||
# The new shortcut is already assigned, but if both shortcuts
|
# The new shortcut is already assigned, but if both shortcuts are only valid in a different widget the
|
||||||
# are only valid in a different widget the new shortcut is
|
# new shortcut is vaild, because they will not interfere.
|
||||||
# vaild, because they will not interfere.
|
if action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
|
||||||
if action.shortcutContext() in [QtCore.Qt.WindowShortcut,
|
|
||||||
QtCore.Qt.ApplicationShortcut]:
|
|
||||||
is_valid = False
|
is_valid = False
|
||||||
if changing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
|
if changing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
|
||||||
is_valid = False
|
is_valid = False
|
||||||
@ -443,13 +429,13 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
'The shortcut "%s" is already assigned to another action, please use a different shortcut.') %
|
'The shortcut "%s" is already assigned to another action, please use a different shortcut.') %
|
||||||
key_sequence.toString()
|
key_sequence.toString()
|
||||||
)
|
)
|
||||||
|
self.dialog_was_shown = True
|
||||||
return is_valid
|
return is_valid
|
||||||
|
|
||||||
def _actionShortcuts(self, action):
|
def _actionShortcuts(self, action):
|
||||||
"""
|
"""
|
||||||
This returns the shortcuts for the given ``action``, which also includes
|
This returns the shortcuts for the given ``action``, which also includes those shortcuts which are not saved
|
||||||
those shortcuts which are not saved yet but already assigned (as changes
|
yet but already assigned (as changes yre applied when closing the dialog).
|
||||||
are applied when closing the dialog).
|
|
||||||
"""
|
"""
|
||||||
if action in self.changedActions:
|
if action in self.changedActions:
|
||||||
return self.changedActions[action]
|
return self.changedActions[action]
|
||||||
@ -457,8 +443,8 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
|
|
||||||
def _currentItemAction(self, item=None):
|
def _currentItemAction(self, item=None):
|
||||||
"""
|
"""
|
||||||
Returns the action of the given ``item``. If no item is given, we return
|
Returns the action of the given ``item``. If no item is given, we return the action of the current item of
|
||||||
the action of the current item of the ``treeWidget``.
|
the ``treeWidget``.
|
||||||
"""
|
"""
|
||||||
if item is None:
|
if item is None:
|
||||||
item = self.treeWidget.currentItem()
|
item = self.treeWidget.currentItem()
|
||||||
@ -487,3 +473,4 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog):
|
|||||||
return self._main_window
|
return self._main_window
|
||||||
|
|
||||||
main_window = property(_get_main_window)
|
main_window = property(_get_main_window)
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -38,9 +38,8 @@ import re
|
|||||||
from xml.etree.ElementTree import ElementTree, XML
|
from xml.etree.ElementTree import ElementTree, XML
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import ImageSource, OpenLPToolbar, Registry, SettingsManager, Settings, UiStrings, \
|
from openlp.core.lib import ImageSource, OpenLPToolbar, Registry, Settings, UiStrings, get_text_file_string, \
|
||||||
get_text_file_string, build_icon, translate, check_item_selected, check_directory_exists, create_thumb, \
|
build_icon, translate, check_item_selected, check_directory_exists, create_thumb, validate_thumb
|
||||||
validate_thumb
|
|
||||||
from openlp.core.lib.theme import ThemeXML, BackgroundType, VerticalType, BackgroundGradientType
|
from openlp.core.lib.theme import ThemeXML, BackgroundType, VerticalType, BackgroundGradientType
|
||||||
from openlp.core.lib.ui import critical_error_message_box, create_widget_action
|
from openlp.core.lib.ui import critical_error_message_box, create_widget_action
|
||||||
from openlp.core.theme import Theme
|
from openlp.core.theme import Theme
|
||||||
@ -60,6 +59,7 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
"""
|
"""
|
||||||
QtGui.QWidget.__init__(self, parent)
|
QtGui.QWidget.__init__(self, parent)
|
||||||
Registry().register(u'theme_manager', self)
|
Registry().register(u'theme_manager', self)
|
||||||
|
Registry().register_function(u'bootstrap_initialise', self.load_first_time_themes)
|
||||||
self.settingsSection = u'themes'
|
self.settingsSection = u'themes'
|
||||||
self.themeForm = ThemeForm(self)
|
self.themeForm = ThemeForm(self)
|
||||||
self.fileRenameForm = FileRenameForm()
|
self.fileRenameForm = FileRenameForm()
|
||||||
@ -145,18 +145,6 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
# Last little bits of setting up
|
# Last little bits of setting up
|
||||||
self.config_updated()
|
self.config_updated()
|
||||||
|
|
||||||
def first_time(self):
|
|
||||||
"""
|
|
||||||
Import new themes downloaded by the first time wizard
|
|
||||||
"""
|
|
||||||
self.application.set_busy_cursor()
|
|
||||||
files = SettingsManager.get_files(self.settingsSection, u'.otz')
|
|
||||||
for theme_file in files:
|
|
||||||
theme_file = os.path.join(self.path, theme_file)
|
|
||||||
self.unzip_theme(theme_file, self.path)
|
|
||||||
delete_file(theme_file)
|
|
||||||
self.application.set_normal_cursor()
|
|
||||||
|
|
||||||
def config_updated(self):
|
def config_updated(self):
|
||||||
"""
|
"""
|
||||||
Triggered when Config dialog is updated.
|
Triggered when Config dialog is updated.
|
||||||
@ -265,8 +253,8 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
self.cloneThemeData(old_theme_data, new_theme_name)
|
self.cloneThemeData(old_theme_data, new_theme_name)
|
||||||
self.delete_theme(old_theme_name)
|
self.delete_theme(old_theme_name)
|
||||||
for plugin in self.plugin_manager.plugins:
|
for plugin in self.plugin_manager.plugins:
|
||||||
if plugin.usesTheme(old_theme_name):
|
if plugin.uses_theme(old_theme_name):
|
||||||
plugin.renameTheme(old_theme_name, new_theme_name)
|
plugin.rename_theme(old_theme_name, new_theme_name)
|
||||||
self.renderer.update_theme(new_theme_name, old_theme_name)
|
self.renderer.update_theme(new_theme_name, old_theme_name)
|
||||||
self.load_themes()
|
self.load_themes()
|
||||||
|
|
||||||
@ -292,8 +280,7 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
save_to = None
|
save_to = None
|
||||||
save_from = None
|
save_from = None
|
||||||
if theme_data.background_type == u'image':
|
if theme_data.background_type == u'image':
|
||||||
save_to = os.path.join(self.path, new_theme_name,
|
save_to = os.path.join(self.path, new_theme_name, os.path.split(unicode(theme_data.background_filename))[1])
|
||||||
os.path.split(unicode(theme_data.background_filename))[1])
|
|
||||||
save_from = theme_data.background_filename
|
save_from = theme_data.background_filename
|
||||||
theme_data.theme_name = new_theme_name
|
theme_data.theme_name = new_theme_name
|
||||||
theme_data.extend_image_filename(self.path)
|
theme_data.extend_image_filename(self.path)
|
||||||
@ -389,7 +376,6 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
theme_zip.close()
|
theme_zip.close()
|
||||||
self.application.set_normal_cursor()
|
self.application.set_normal_cursor()
|
||||||
|
|
||||||
|
|
||||||
def on_import_theme(self):
|
def on_import_theme(self):
|
||||||
"""
|
"""
|
||||||
Opens a file dialog to select the theme file(s) to import before
|
Opens a file dialog to select the theme file(s) to import before
|
||||||
@ -410,19 +396,17 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
self.load_themes()
|
self.load_themes()
|
||||||
self.application.set_normal_cursor()
|
self.application.set_normal_cursor()
|
||||||
|
|
||||||
def load_themes(self, first_time=False):
|
def load_first_time_themes(self):
|
||||||
"""
|
"""
|
||||||
Loads the theme lists and triggers updates accross the whole system
|
Imports any themes on start up and makes sure there is at least one theme
|
||||||
using direct calls or core functions and events for the plugins.
|
|
||||||
The plugins will call back in to get the real list if they want it.
|
|
||||||
"""
|
"""
|
||||||
log.debug(u'Load themes from dir')
|
self.application.set_busy_cursor()
|
||||||
self.theme_list = []
|
files = AppLocation.get_files(self.settingsSection, u'.otz')
|
||||||
self.theme_list_widget.clear()
|
for theme_file in files:
|
||||||
files = SettingsManager.get_files(self.settingsSection, u'.png')
|
theme_file = os.path.join(self.path, theme_file)
|
||||||
if first_time:
|
self.unzip_theme(theme_file, self.path)
|
||||||
self.first_time()
|
delete_file(theme_file)
|
||||||
files = SettingsManager.get_files(self.settingsSection, u'.png')
|
files = AppLocation.get_files(self.settingsSection, u'.png')
|
||||||
# No themes have been found so create one
|
# No themes have been found so create one
|
||||||
if not files:
|
if not files:
|
||||||
theme = ThemeXML()
|
theme = ThemeXML()
|
||||||
@ -430,7 +414,19 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
self._write_theme(theme, None, None)
|
self._write_theme(theme, None, None)
|
||||||
Settings().setValue(self.settingsSection + u'/global theme', theme.theme_name)
|
Settings().setValue(self.settingsSection + u'/global theme', theme.theme_name)
|
||||||
self.config_updated()
|
self.config_updated()
|
||||||
files = SettingsManager.get_files(self.settingsSection, u'.png')
|
self.application.set_normal_cursor()
|
||||||
|
self.load_themes()
|
||||||
|
|
||||||
|
def load_themes(self):
|
||||||
|
"""
|
||||||
|
Loads the theme lists and triggers updates across the whole system
|
||||||
|
using direct calls or core functions and events for the plugins.
|
||||||
|
The plugins will call back in to get the real list if they want it.
|
||||||
|
"""
|
||||||
|
log.debug(u'Load themes from dir')
|
||||||
|
self.theme_list = []
|
||||||
|
self.theme_list_widget.clear()
|
||||||
|
files = AppLocation.get_files(self.settingsSection, u'.png')
|
||||||
# Sort the themes by its name considering language specific
|
# Sort the themes by its name considering language specific
|
||||||
files.sort(key=lambda file_name: unicode(file_name), cmp=locale_compare)
|
files.sort(key=lambda file_name: unicode(file_name), cmp=locale_compare)
|
||||||
# now process the file list of png files
|
# now process the file list of png files
|
||||||
@ -751,7 +747,7 @@ class ThemeManager(QtGui.QWidget):
|
|||||||
# check for use in the system else where.
|
# check for use in the system else where.
|
||||||
if testPlugin:
|
if testPlugin:
|
||||||
for plugin in self.plugin_manager.plugins:
|
for plugin in self.plugin_manager.plugins:
|
||||||
if plugin.usesTheme(theme):
|
if plugin.uses_theme(theme):
|
||||||
critical_error_message_box(translate('OpenLP.ThemeManager', 'Validation Error'),
|
critical_error_message_box(translate('OpenLP.ThemeManager', 'Validation Error'),
|
||||||
translate('OpenLP.ThemeManager', 'Theme %s is used in the %s plugin.') %
|
translate('OpenLP.ThemeManager', 'Theme %s is used in the %s plugin.') %
|
||||||
(theme, plugin.name))
|
(theme, plugin.name))
|
||||||
|
@ -155,7 +155,7 @@ class ThemesTab(SettingsTab):
|
|||||||
self.renderer.set_theme_level(self.theme_level)
|
self.renderer.set_theme_level(self.theme_level)
|
||||||
Registry().execute(u'theme_update_global', self.global_theme)
|
Registry().execute(u'theme_update_global', self.global_theme)
|
||||||
|
|
||||||
def postSetUp(self):
|
def post_set_up(self):
|
||||||
"""
|
"""
|
||||||
After setting things up...
|
After setting things up...
|
||||||
"""
|
"""
|
||||||
|
@ -39,9 +39,10 @@ from subprocess import Popen, PIPE
|
|||||||
import sys
|
import sys
|
||||||
import urllib2
|
import urllib2
|
||||||
|
|
||||||
|
from PyQt4 import QtGui, QtCore
|
||||||
|
|
||||||
from openlp.core.lib import Registry, Settings
|
from openlp.core.lib import Registry, Settings
|
||||||
|
|
||||||
from PyQt4 import QtGui, QtCore
|
|
||||||
|
|
||||||
if sys.platform != u'win32' and sys.platform != u'darwin':
|
if sys.platform != u'win32' and sys.platform != u'darwin':
|
||||||
try:
|
try:
|
||||||
@ -50,8 +51,7 @@ if sys.platform != u'win32' and sys.platform != u'darwin':
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
XDG_BASE_AVAILABLE = False
|
XDG_BASE_AVAILABLE = False
|
||||||
|
|
||||||
import openlp
|
from openlp.core.lib import translate
|
||||||
from openlp.core.lib import translate, check_directory_exists
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
APPLICATION_VERSION = {}
|
APPLICATION_VERSION = {}
|
||||||
@ -78,108 +78,6 @@ class VersionThread(QtCore.QThread):
|
|||||||
if LooseVersion(str(version)) > LooseVersion(str(app_version[u'full'])):
|
if LooseVersion(str(version)) > LooseVersion(str(app_version[u'full'])):
|
||||||
Registry().execute(u'openlp_version_check', u'%s' % version)
|
Registry().execute(u'openlp_version_check', u'%s' % version)
|
||||||
|
|
||||||
class AppLocation(object):
|
|
||||||
"""
|
|
||||||
The :class:`AppLocation` class is a static class which retrieves a
|
|
||||||
directory based on the directory type.
|
|
||||||
"""
|
|
||||||
AppDir = 1
|
|
||||||
ConfigDir = 2
|
|
||||||
DataDir = 3
|
|
||||||
PluginsDir = 4
|
|
||||||
VersionDir = 5
|
|
||||||
CacheDir = 6
|
|
||||||
LanguageDir = 7
|
|
||||||
SharedData = 8
|
|
||||||
|
|
||||||
# Base path where data/config/cache dir is located
|
|
||||||
BaseDir = None
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_directory(dir_type=1):
|
|
||||||
"""
|
|
||||||
Return the appropriate directory according to the directory type.
|
|
||||||
|
|
||||||
``dir_type``
|
|
||||||
The directory type you want, for instance the data directory.
|
|
||||||
"""
|
|
||||||
if dir_type == AppLocation.AppDir:
|
|
||||||
return _get_frozen_path(os.path.abspath(os.path.split(sys.argv[0])[0]), os.path.split(openlp.__file__)[0])
|
|
||||||
elif dir_type == AppLocation.PluginsDir:
|
|
||||||
app_path = os.path.abspath(os.path.split(sys.argv[0])[0])
|
|
||||||
return _get_frozen_path(os.path.join(app_path, u'plugins'),
|
|
||||||
os.path.join(os.path.split(openlp.__file__)[0], u'plugins'))
|
|
||||||
elif dir_type == AppLocation.VersionDir:
|
|
||||||
return _get_frozen_path(os.path.abspath(os.path.split(sys.argv[0])[0]), os.path.split(openlp.__file__)[0])
|
|
||||||
elif dir_type == AppLocation.LanguageDir:
|
|
||||||
app_path = _get_frozen_path(os.path.abspath(os.path.split(sys.argv[0])[0]), _get_os_dir_path(dir_type))
|
|
||||||
return os.path.join(app_path, u'i18n')
|
|
||||||
elif dir_type == AppLocation.DataDir and AppLocation.BaseDir:
|
|
||||||
return os.path.join(AppLocation.BaseDir, 'data')
|
|
||||||
else:
|
|
||||||
return _get_os_dir_path(dir_type)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_data_path():
|
|
||||||
"""
|
|
||||||
Return the path OpenLP stores all its data under.
|
|
||||||
"""
|
|
||||||
# Check if we have a different data location.
|
|
||||||
if Settings().contains(u'advanced/data path'):
|
|
||||||
path = Settings().value(u'advanced/data path')
|
|
||||||
else:
|
|
||||||
path = AppLocation.get_directory(AppLocation.DataDir)
|
|
||||||
check_directory_exists(path)
|
|
||||||
return os.path.normpath(path)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_section_data_path(section):
|
|
||||||
"""
|
|
||||||
Return the path a particular module stores its data under.
|
|
||||||
"""
|
|
||||||
data_path = AppLocation.get_data_path()
|
|
||||||
path = os.path.join(data_path, section)
|
|
||||||
check_directory_exists(path)
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def _get_os_dir_path(dir_type):
|
|
||||||
"""
|
|
||||||
Return a path based on which OS and environment we are running in.
|
|
||||||
"""
|
|
||||||
encoding = sys.getfilesystemencoding()
|
|
||||||
if sys.platform == u'win32':
|
|
||||||
if dir_type == AppLocation.DataDir:
|
|
||||||
return os.path.join(unicode(os.getenv(u'APPDATA'), encoding), u'openlp', u'data')
|
|
||||||
elif dir_type == AppLocation.LanguageDir or dir_type == AppLocation.SharedData:
|
|
||||||
return os.path.split(openlp.__file__)[0]
|
|
||||||
return os.path.join(unicode(os.getenv(u'APPDATA'), encoding), u'openlp')
|
|
||||||
elif sys.platform == u'darwin':
|
|
||||||
if dir_type == AppLocation.DataDir:
|
|
||||||
return os.path.join(unicode(os.getenv(u'HOME'), encoding),
|
|
||||||
u'Library', u'Application Support', u'openlp', u'Data')
|
|
||||||
elif dir_type == AppLocation.LanguageDir or dir_type == AppLocation.SharedData:
|
|
||||||
return os.path.split(openlp.__file__)[0]
|
|
||||||
return os.path.join(unicode(os.getenv(u'HOME'), encoding), u'Library', u'Application Support', u'openlp')
|
|
||||||
else:
|
|
||||||
if dir_type == AppLocation.LanguageDir or dir_type == AppLocation.SharedData:
|
|
||||||
prefixes = [u'/usr/local', u'/usr']
|
|
||||||
for prefix in prefixes:
|
|
||||||
directory = os.path.join(prefix, u'share', u'openlp')
|
|
||||||
if os.path.exists(directory):
|
|
||||||
return directory
|
|
||||||
return os.path.join(u'/usr', u'share', u'openlp')
|
|
||||||
if XDG_BASE_AVAILABLE:
|
|
||||||
if dir_type == AppLocation.ConfigDir:
|
|
||||||
return os.path.join(unicode(BaseDirectory.xdg_config_home, encoding), u'openlp')
|
|
||||||
elif dir_type == AppLocation.DataDir:
|
|
||||||
return os.path.join(unicode(BaseDirectory.xdg_data_home, encoding), u'openlp')
|
|
||||||
elif dir_type == AppLocation.CacheDir:
|
|
||||||
return os.path.join(unicode(BaseDirectory.xdg_cache_home, encoding), u'openlp')
|
|
||||||
if dir_type == AppLocation.DataDir:
|
|
||||||
return os.path.join(unicode(os.getenv(u'HOME'), encoding), u'.openlp', u'data')
|
|
||||||
return os.path.join(unicode(os.getenv(u'HOME'), encoding), u'.openlp')
|
|
||||||
|
|
||||||
|
|
||||||
def _get_frozen_path(frozen_option, non_frozen_option):
|
def _get_frozen_path(frozen_option, non_frozen_option):
|
||||||
"""
|
"""
|
||||||
@ -437,11 +335,11 @@ def get_uno_command():
|
|||||||
Returns the UNO command to launch an openoffice.org instance.
|
Returns the UNO command to launch an openoffice.org instance.
|
||||||
"""
|
"""
|
||||||
COMMAND = u'soffice'
|
COMMAND = u'soffice'
|
||||||
OPTIONS = u'-nologo -norestore -minimized -nodefault -nofirststartwizard'
|
OPTIONS = u'--nologo --norestore --minimized --nodefault --nofirststartwizard'
|
||||||
if UNO_CONNECTION_TYPE == u'pipe':
|
if UNO_CONNECTION_TYPE == u'pipe':
|
||||||
CONNECTION = u'"-accept=pipe,name=openlp_pipe;urp;"'
|
CONNECTION = u'"--accept=pipe,name=openlp_pipe;urp;"'
|
||||||
else:
|
else:
|
||||||
CONNECTION = u'"-accept=socket,host=localhost,port=2002;urp;"'
|
CONNECTION = u'"--accept=socket,host=localhost,port=2002;urp;"'
|
||||||
return u'%s %s %s' % (COMMAND, OPTIONS, CONNECTION)
|
return u'%s %s %s' % (COMMAND, OPTIONS, CONNECTION)
|
||||||
|
|
||||||
|
|
||||||
@ -498,9 +396,11 @@ def locale_compare(string1, string2):
|
|||||||
locale_direct_compare = locale.strcoll
|
locale_direct_compare = locale.strcoll
|
||||||
|
|
||||||
|
|
||||||
|
from applocation import AppLocation
|
||||||
from languagemanager import LanguageManager
|
from languagemanager import LanguageManager
|
||||||
from actions import ActionList
|
from actions import ActionList
|
||||||
|
|
||||||
|
|
||||||
__all__ = [u'AppLocation', u'ActionList', u'LanguageManager', u'get_application_version', u'check_latest_version',
|
__all__ = [u'AppLocation', u'ActionList', u'LanguageManager', u'get_application_version', u'check_latest_version',
|
||||||
u'add_actions', u'get_filesystem_encoding', u'get_web_page', u'get_uno_command', u'get_uno_instance',
|
u'add_actions', u'get_filesystem_encoding', u'get_web_page', u'get_uno_command', u'get_uno_instance',
|
||||||
u'delete_file', u'clean_filename', u'format_time', u'locale_compare', u'locale_direct_compare']
|
u'delete_file', u'clean_filename', u'format_time', u'locale_compare', u'locale_direct_compare']
|
||||||
|
@ -37,8 +37,8 @@ from openlp.core.lib import Settings
|
|||||||
|
|
||||||
class ActionCategory(object):
|
class ActionCategory(object):
|
||||||
"""
|
"""
|
||||||
The :class:`~openlp.core.utils.ActionCategory` class encapsulates a
|
The :class:`~openlp.core.utils.ActionCategory` class encapsulates a category for the
|
||||||
category for the :class:`~openlp.core.utils.CategoryList` class.
|
:class:`~openlp.core.utils.CategoryList` class.
|
||||||
"""
|
"""
|
||||||
def __init__(self, name, weight=0):
|
def __init__(self, name, weight=0):
|
||||||
"""
|
"""
|
||||||
@ -51,8 +51,7 @@ class ActionCategory(object):
|
|||||||
|
|
||||||
class CategoryActionList(object):
|
class CategoryActionList(object):
|
||||||
"""
|
"""
|
||||||
The :class:`~openlp.core.utils.CategoryActionList` class provides a sorted
|
The :class:`~openlp.core.utils.CategoryActionList` class provides a sorted list of actions within a category.
|
||||||
list of actions within a category.
|
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""
|
"""
|
||||||
@ -142,9 +141,9 @@ class CategoryActionList(object):
|
|||||||
|
|
||||||
class CategoryList(object):
|
class CategoryList(object):
|
||||||
"""
|
"""
|
||||||
The :class:`~openlp.core.utils.CategoryList` class encapsulates a category
|
The :class:`~openlp.core.utils.CategoryList` class encapsulates a category list for the
|
||||||
list for the :class:`~openlp.core.utils.ActionList` class and provides an
|
:class:`~openlp.core.utils.ActionList` class and provides an iterator interface for walking through the list of
|
||||||
iterator interface for walking through the list of actions in this category.
|
actions in this category.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -244,10 +243,9 @@ class CategoryList(object):
|
|||||||
|
|
||||||
class ActionList(object):
|
class ActionList(object):
|
||||||
"""
|
"""
|
||||||
The :class:`~openlp.core.utils.ActionList` class contains a list of menu
|
The :class:`~openlp.core.utils.ActionList` class contains a list of menu actions and categories associated with
|
||||||
actions and categories associated with those actions. Each category also
|
those actions. Each category also has a weight by which it is sorted when iterating through the list of actions or
|
||||||
has a weight by which it is sorted when iterating through the list of
|
categories.
|
||||||
actions or categories.
|
|
||||||
"""
|
"""
|
||||||
instance = None
|
instance = None
|
||||||
shortcut_map = {}
|
shortcut_map = {}
|
||||||
@ -271,48 +269,44 @@ class ActionList(object):
|
|||||||
"""
|
"""
|
||||||
Add an action to the list of actions.
|
Add an action to the list of actions.
|
||||||
|
|
||||||
|
**Note**: The action's objectName must be set when you want to add it!
|
||||||
|
|
||||||
``action``
|
``action``
|
||||||
The action to add (QAction). **Note**, the action must not have an
|
The action to add (QAction). **Note**, the action must not have an empty ``objectName``.
|
||||||
empty ``objectName``.
|
|
||||||
|
|
||||||
``category``
|
``category``
|
||||||
The category this action belongs to. The category has to be a python
|
The category this action belongs to. The category has to be a python string. . **Note**, if the category
|
||||||
string. . **Note**, if the category is ``None``, the category and
|
is ``None``, the category and its actions are being hidden in the shortcut dialog. However, if they are
|
||||||
its actions are being hidden in the shortcut dialog. However, if
|
added, it is possible to avoid assigning shortcuts twice, which is important.
|
||||||
they are added, it is possible to avoid assigning shortcuts twice,
|
|
||||||
which is important.
|
|
||||||
|
|
||||||
``weight``
|
``weight``
|
||||||
The weight specifies how important a category is. However, this only
|
The weight specifies how important a category is. However, this only has an impact on the order the
|
||||||
has an impact on the order the categories are displayed.
|
categories are displayed.
|
||||||
"""
|
"""
|
||||||
if category not in self.categories:
|
if category not in self.categories:
|
||||||
self.categories.append(category)
|
self.categories.append(category)
|
||||||
action.defaultShortcuts = action.shortcuts()
|
settings = Settings()
|
||||||
|
settings.beginGroup(u'shortcuts')
|
||||||
|
# Get the default shortcut from the config.
|
||||||
|
action.defaultShortcuts = settings.get_default_value(action.objectName())
|
||||||
if weight is None:
|
if weight is None:
|
||||||
self.categories[category].actions.append(action)
|
self.categories[category].actions.append(action)
|
||||||
else:
|
else:
|
||||||
self.categories[category].actions.add(action, weight)
|
self.categories[category].actions.add(action, weight)
|
||||||
# Load the shortcut from the config.
|
# Load the shortcut from the config.
|
||||||
settings = Settings()
|
|
||||||
settings.beginGroup(u'shortcuts')
|
|
||||||
shortcuts = settings.value(action.objectName())
|
shortcuts = settings.value(action.objectName())
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
if not shortcuts:
|
if not shortcuts:
|
||||||
action.setShortcuts([])
|
action.setShortcuts([])
|
||||||
return
|
return
|
||||||
# We have to do this to ensure that the loaded shortcut list e. g.
|
# We have to do this to ensure that the loaded shortcut list e. g. STRG+O (German) is converted to CTRL+O,
|
||||||
# STRG+O (German) is converted to CTRL+O, which is only done when we
|
# which is only done when we convert the strings in this way (QKeySequencet -> uncode).
|
||||||
# convert the strings in this way (QKeySequence -> QString -> unicode).
|
shortcuts = map(QtGui.QKeySequence.toString, map(QtGui.QKeySequence, shortcuts))
|
||||||
shortcuts = map(QtGui.QKeySequence, shortcuts)
|
# Check the alternate shortcut first, to avoid problems when the alternate shortcut becomes the primary shortcut
|
||||||
shortcuts = map(unicode, map(QtGui.QKeySequence.toString, shortcuts))
|
# after removing the (initial) primary shortcut due to conflicts.
|
||||||
# Check the alternate shortcut first, to avoid problems when the
|
|
||||||
# alternate shortcut becomes the primary shortcut after removing the
|
|
||||||
# (initial) primary shortcut due to conflicts.
|
|
||||||
if len(shortcuts) == 2:
|
if len(shortcuts) == 2:
|
||||||
existing_actions = ActionList.shortcut_map.get(shortcuts[1], [])
|
existing_actions = ActionList.shortcut_map.get(shortcuts[1], [])
|
||||||
# Check for conflicts with other actions considering the shortcut
|
# Check for conflicts with other actions considering the shortcut context.
|
||||||
# context.
|
|
||||||
if self._is_shortcut_available(existing_actions, action):
|
if self._is_shortcut_available(existing_actions, action):
|
||||||
actions = ActionList.shortcut_map.get(shortcuts[1], [])
|
actions = ActionList.shortcut_map.get(shortcuts[1], [])
|
||||||
actions.append(action)
|
actions.append(action)
|
||||||
@ -321,28 +315,24 @@ class ActionList(object):
|
|||||||
shortcuts.remove(shortcuts[1])
|
shortcuts.remove(shortcuts[1])
|
||||||
# Check the primary shortcut.
|
# Check the primary shortcut.
|
||||||
existing_actions = ActionList.shortcut_map.get(shortcuts[0], [])
|
existing_actions = ActionList.shortcut_map.get(shortcuts[0], [])
|
||||||
# Check for conflicts with other actions considering the shortcut
|
# Check for conflicts with other actions considering the shortcut context.
|
||||||
# context.
|
|
||||||
if self._is_shortcut_available(existing_actions, action):
|
if self._is_shortcut_available(existing_actions, action):
|
||||||
actions = ActionList.shortcut_map.get(shortcuts[0], [])
|
actions = ActionList.shortcut_map.get(shortcuts[0], [])
|
||||||
actions.append(action)
|
actions.append(action)
|
||||||
ActionList.shortcut_map[shortcuts[0]] = actions
|
ActionList.shortcut_map[shortcuts[0]] = actions
|
||||||
else:
|
else:
|
||||||
shortcuts.remove(shortcuts[0])
|
shortcuts.remove(shortcuts[0])
|
||||||
action.setShortcuts(
|
action.setShortcuts([QtGui.QKeySequence(shortcut) for shortcut in shortcuts])
|
||||||
[QtGui.QKeySequence(shortcut) for shortcut in shortcuts])
|
|
||||||
|
|
||||||
def remove_action(self, action, category=None):
|
def remove_action(self, action, category=None):
|
||||||
"""
|
"""
|
||||||
This removes an action from its category. Empty categories are
|
This removes an action from its category. Empty categories are automatically removed.
|
||||||
automatically removed.
|
|
||||||
|
|
||||||
``action``
|
``action``
|
||||||
The ``QAction`` object to be removed.
|
The ``QAction`` object to be removed.
|
||||||
|
|
||||||
``category``
|
``category``
|
||||||
The name (unicode string) of the category, which contains the
|
The name (unicode string) of the category, which contains the action. Defaults to None.
|
||||||
action. Defaults to None.
|
|
||||||
"""
|
"""
|
||||||
if category not in self.categories:
|
if category not in self.categories:
|
||||||
return
|
return
|
||||||
@ -350,10 +340,9 @@ class ActionList(object):
|
|||||||
# Remove empty categories.
|
# Remove empty categories.
|
||||||
if not self.categories[category].actions:
|
if not self.categories[category].actions:
|
||||||
self.categories.remove(category)
|
self.categories.remove(category)
|
||||||
shortcuts = map(unicode, map(QtGui.QKeySequence.toString, action.shortcuts()))
|
shortcuts = map(QtGui.QKeySequence.toString, action.shortcuts())
|
||||||
for shortcut in shortcuts:
|
for shortcut in shortcuts:
|
||||||
# Remove action from the list of actions which are using this
|
# Remove action from the list of actions which are using this shortcut.
|
||||||
# shortcut.
|
|
||||||
ActionList.shortcut_map[shortcut].remove(action)
|
ActionList.shortcut_map[shortcut].remove(action)
|
||||||
# Remove empty entries.
|
# Remove empty entries.
|
||||||
if not ActionList.shortcut_map[shortcut]:
|
if not ActionList.shortcut_map[shortcut]:
|
||||||
@ -361,8 +350,7 @@ class ActionList(object):
|
|||||||
|
|
||||||
def add_category(self, name, weight):
|
def add_category(self, name, weight):
|
||||||
"""
|
"""
|
||||||
Add an empty category to the list of categories. This is ony convenient
|
Add an empty category to the list of categories. This is only convenient for categories with a given weight.
|
||||||
for categories with a given weight.
|
|
||||||
|
|
||||||
``name``
|
``name``
|
||||||
The category's name.
|
The category's name.
|
||||||
@ -381,27 +369,24 @@ class ActionList(object):
|
|||||||
|
|
||||||
def update_shortcut_map(self, action, old_shortcuts):
|
def update_shortcut_map(self, action, old_shortcuts):
|
||||||
"""
|
"""
|
||||||
Remove the action for the given ``old_shortcuts`` from the
|
Remove the action for the given ``old_shortcuts`` from the ``shortcut_map`` to ensure its up-to-dateness.
|
||||||
``shortcut_map`` to ensure its up-to-dateness.
|
|
||||||
|
|
||||||
**Note**: The new action's shortcuts **must** be assigned to the given
|
**Note**: The new action's shortcuts **must** be assigned to the given ``action`` **before** calling this
|
||||||
``action`` **before** calling this method.
|
method.
|
||||||
|
|
||||||
``action``
|
``action``
|
||||||
The action whose shortcuts are supposed to be updated in the
|
The action whose shortcuts are supposed to be updated in the ``shortcut_map``.
|
||||||
``shortcut_map``.
|
|
||||||
|
|
||||||
``old_shortcuts``
|
``old_shortcuts``
|
||||||
A list of unicode keysequences.
|
A list of unicode keysequences.
|
||||||
"""
|
"""
|
||||||
for old_shortcut in old_shortcuts:
|
for old_shortcut in old_shortcuts:
|
||||||
# Remove action from the list of actions which are using this
|
# Remove action from the list of actions which are using this shortcut.
|
||||||
# shortcut.
|
|
||||||
ActionList.shortcut_map[old_shortcut].remove(action)
|
ActionList.shortcut_map[old_shortcut].remove(action)
|
||||||
# Remove empty entries.
|
# Remove empty entries.
|
||||||
if not ActionList.shortcut_map[old_shortcut]:
|
if not ActionList.shortcut_map[old_shortcut]:
|
||||||
del ActionList.shortcut_map[old_shortcut]
|
del ActionList.shortcut_map[old_shortcut]
|
||||||
new_shortcuts = map(unicode, map(QtGui.QKeySequence.toString, action.shortcuts()))
|
new_shortcuts = map(QtGui.QKeySequence.toString, action.shortcuts())
|
||||||
# Add the new shortcuts to the map.
|
# Add the new shortcuts to the map.
|
||||||
for new_shortcut in new_shortcuts:
|
for new_shortcut in new_shortcuts:
|
||||||
existing_actions = ActionList.shortcut_map.get(new_shortcut, [])
|
existing_actions = ActionList.shortcut_map.get(new_shortcut, [])
|
||||||
@ -410,8 +395,7 @@ class ActionList(object):
|
|||||||
|
|
||||||
def _is_shortcut_available(self, existing_actions, action):
|
def _is_shortcut_available(self, existing_actions, action):
|
||||||
"""
|
"""
|
||||||
Checks if the given ``action`` may use its assigned shortcut(s) or not.
|
Checks if the given ``action`` may use its assigned shortcut(s) or not. Returns ``True`` or ``False.
|
||||||
Returns ``True`` or ``False.
|
|
||||||
|
|
||||||
``existing_actions``
|
``existing_actions``
|
||||||
A list of actions which already use a particular shortcut.
|
A list of actions which already use a particular shortcut.
|
||||||
@ -419,28 +403,29 @@ class ActionList(object):
|
|||||||
``action``
|
``action``
|
||||||
The action which wants to use a particular shortcut.
|
The action which wants to use a particular shortcut.
|
||||||
"""
|
"""
|
||||||
local = action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]
|
global_context = action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]
|
||||||
affected_actions = filter(lambda a: isinstance(a, QtGui.QAction),
|
affected_actions = []
|
||||||
self.getAllChildObjects(action.parent())) if local else []
|
if global_context:
|
||||||
|
affected_actions = filter(
|
||||||
|
lambda a: isinstance(a, QtGui.QAction), self.get_all_child_objects(action.parent()))
|
||||||
for existing_action in existing_actions:
|
for existing_action in existing_actions:
|
||||||
if action is existing_action:
|
if action is existing_action:
|
||||||
continue
|
continue
|
||||||
if not local or existing_action in affected_actions:
|
if existing_action in affected_actions:
|
||||||
return False
|
return False
|
||||||
if existing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
|
if existing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]:
|
||||||
return False
|
return False
|
||||||
elif action in self.getAllChildObjects(existing_action.parent()):
|
elif action in self.get_all_child_objects(existing_action.parent()):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def getAllChildObjects(self, qobject):
|
def get_all_child_objects(self, qobject):
|
||||||
"""
|
"""
|
||||||
Goes recursively through the children of ``qobject`` and returns a list
|
Goes recursively through the children of ``qobject`` and returns a list of all child objects.
|
||||||
of all child objects.
|
|
||||||
"""
|
"""
|
||||||
children = [child for child in qobject.children()]
|
children = qobject.children()
|
||||||
for child in qobject.children():
|
# Append the children's children.
|
||||||
children.append(self.getAllChildObjects(child))
|
children.extend(map(self.get_all_child_objects, children))
|
||||||
return children
|
return children
|
||||||
|
|
||||||
|
|
||||||
@ -448,5 +433,5 @@ class CategoryOrder(object):
|
|||||||
"""
|
"""
|
||||||
An enumeration class for category weights.
|
An enumeration class for category weights.
|
||||||
"""
|
"""
|
||||||
standardMenu = -20
|
standard_menu = -20
|
||||||
standardToolbar = -10
|
standard_toolbar = -10
|
||||||
|
181
openlp/core/utils/applocation.py
Normal file
181
openlp/core/utils/applocation.py
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# OpenLP - Open Source Lyrics Projection #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# Copyright (c) 2008-2013 Raoul Snyman #
|
||||||
|
# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan #
|
||||||
|
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
|
||||||
|
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
|
||||||
|
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
|
||||||
|
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
|
||||||
|
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
|
||||||
|
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
|
||||||
|
# --------------------------------------------------------------------------- #
|
||||||
|
# This program is free software; you can redistribute it and/or modify it #
|
||||||
|
# under the terms of the GNU General Public License as published by the Free #
|
||||||
|
# Software Foundation; version 2 of the License. #
|
||||||
|
# #
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||||
|
# more details. #
|
||||||
|
# #
|
||||||
|
# You should have received a copy of the GNU General Public License along #
|
||||||
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
|
###############################################################################
|
||||||
|
"""
|
||||||
|
The :mod:`openlp.core.utils.applocation` module provides an utility for OpenLP receiving the data path etc.
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from openlp.core.lib import Settings
|
||||||
|
from openlp.core.utils import _get_frozen_path
|
||||||
|
|
||||||
|
|
||||||
|
if sys.platform != u'win32' and sys.platform != u'darwin':
|
||||||
|
try:
|
||||||
|
from xdg import BaseDirectory
|
||||||
|
XDG_BASE_AVAILABLE = True
|
||||||
|
except ImportError:
|
||||||
|
XDG_BASE_AVAILABLE = False
|
||||||
|
|
||||||
|
import openlp
|
||||||
|
from openlp.core.lib import check_directory_exists
|
||||||
|
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class AppLocation(object):
|
||||||
|
"""
|
||||||
|
The :class:`AppLocation` class is a static class which retrieves a
|
||||||
|
directory based on the directory type.
|
||||||
|
"""
|
||||||
|
AppDir = 1
|
||||||
|
ConfigDir = 2
|
||||||
|
DataDir = 3
|
||||||
|
PluginsDir = 4
|
||||||
|
VersionDir = 5
|
||||||
|
CacheDir = 6
|
||||||
|
LanguageDir = 7
|
||||||
|
SharedData = 8
|
||||||
|
|
||||||
|
# Base path where data/config/cache dir is located
|
||||||
|
BaseDir = None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_directory(dir_type=1):
|
||||||
|
"""
|
||||||
|
Return the appropriate directory according to the directory type.
|
||||||
|
|
||||||
|
``dir_type``
|
||||||
|
The directory type you want, for instance the data directory.
|
||||||
|
"""
|
||||||
|
if dir_type == AppLocation.AppDir:
|
||||||
|
return _get_frozen_path(os.path.abspath(os.path.split(sys.argv[0])[0]), os.path.split(openlp.__file__)[0])
|
||||||
|
elif dir_type == AppLocation.PluginsDir:
|
||||||
|
app_path = os.path.abspath(os.path.split(sys.argv[0])[0])
|
||||||
|
return _get_frozen_path(os.path.join(app_path, u'plugins'),
|
||||||
|
os.path.join(os.path.split(openlp.__file__)[0], u'plugins'))
|
||||||
|
elif dir_type == AppLocation.VersionDir:
|
||||||
|
return _get_frozen_path(os.path.abspath(os.path.split(sys.argv[0])[0]), os.path.split(openlp.__file__)[0])
|
||||||
|
elif dir_type == AppLocation.LanguageDir:
|
||||||
|
app_path = _get_frozen_path(os.path.abspath(os.path.split(sys.argv[0])[0]), _get_os_dir_path(dir_type))
|
||||||
|
return os.path.join(app_path, u'i18n')
|
||||||
|
elif dir_type == AppLocation.DataDir and AppLocation.BaseDir:
|
||||||
|
return os.path.join(AppLocation.BaseDir, 'data')
|
||||||
|
else:
|
||||||
|
return _get_os_dir_path(dir_type)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_data_path():
|
||||||
|
"""
|
||||||
|
Return the path OpenLP stores all its data under.
|
||||||
|
"""
|
||||||
|
# Check if we have a different data location.
|
||||||
|
if Settings().contains(u'advanced/data path'):
|
||||||
|
path = Settings().value(u'advanced/data path')
|
||||||
|
else:
|
||||||
|
path = AppLocation.get_directory(AppLocation.DataDir)
|
||||||
|
check_directory_exists(path)
|
||||||
|
return os.path.normpath(path)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_files(section=None, extension=None):
|
||||||
|
"""
|
||||||
|
Get a list of files from the data files path.
|
||||||
|
|
||||||
|
``section``
|
||||||
|
Defaults to *None*. The section of code getting the files - used to load from a section's data subdirectory.
|
||||||
|
|
||||||
|
``extension``
|
||||||
|
Defaults to *None*. The extension to search for. For example::
|
||||||
|
|
||||||
|
u'.png'
|
||||||
|
"""
|
||||||
|
path = AppLocation.get_data_path()
|
||||||
|
if section:
|
||||||
|
path = os.path.join(path, section)
|
||||||
|
try:
|
||||||
|
files = os.listdir(path)
|
||||||
|
except OSError:
|
||||||
|
return []
|
||||||
|
if extension:
|
||||||
|
return [filename for filename in files if extension == os.path.splitext(filename)[1]]
|
||||||
|
else:
|
||||||
|
# no filtering required
|
||||||
|
return files
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_section_data_path(section):
|
||||||
|
"""
|
||||||
|
Return the path a particular module stores its data under.
|
||||||
|
"""
|
||||||
|
data_path = AppLocation.get_data_path()
|
||||||
|
path = os.path.join(data_path, section)
|
||||||
|
check_directory_exists(path)
|
||||||
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
def _get_os_dir_path(dir_type):
|
||||||
|
"""
|
||||||
|
Return a path based on which OS and environment we are running in.
|
||||||
|
"""
|
||||||
|
encoding = sys.getfilesystemencoding()
|
||||||
|
if sys.platform == u'win32':
|
||||||
|
if dir_type == AppLocation.DataDir:
|
||||||
|
return os.path.join(unicode(os.getenv(u'APPDATA'), encoding), u'openlp', u'data')
|
||||||
|
elif dir_type == AppLocation.LanguageDir or dir_type == AppLocation.SharedData:
|
||||||
|
return os.path.split(openlp.__file__)[0]
|
||||||
|
return os.path.join(unicode(os.getenv(u'APPDATA'), encoding), u'openlp')
|
||||||
|
elif sys.platform == u'darwin':
|
||||||
|
if dir_type == AppLocation.DataDir:
|
||||||
|
return os.path.join(unicode(os.getenv(u'HOME'), encoding),
|
||||||
|
u'Library', u'Application Support', u'openlp', u'Data')
|
||||||
|
elif dir_type == AppLocation.LanguageDir or dir_type == AppLocation.SharedData:
|
||||||
|
return os.path.split(openlp.__file__)[0]
|
||||||
|
return os.path.join(unicode(os.getenv(u'HOME'), encoding), u'Library', u'Application Support', u'openlp')
|
||||||
|
else:
|
||||||
|
if dir_type == AppLocation.LanguageDir or dir_type == AppLocation.SharedData:
|
||||||
|
prefixes = [u'/usr/local', u'/usr']
|
||||||
|
for prefix in prefixes:
|
||||||
|
directory = os.path.join(prefix, u'share', u'openlp')
|
||||||
|
if os.path.exists(directory):
|
||||||
|
return directory
|
||||||
|
return os.path.join(u'/usr', u'share', u'openlp')
|
||||||
|
if XDG_BASE_AVAILABLE:
|
||||||
|
if dir_type == AppLocation.ConfigDir:
|
||||||
|
return os.path.join(unicode(BaseDirectory.xdg_config_home, encoding), u'openlp')
|
||||||
|
elif dir_type == AppLocation.DataDir:
|
||||||
|
return os.path.join(unicode(BaseDirectory.xdg_data_home, encoding), u'openlp')
|
||||||
|
elif dir_type == AppLocation.CacheDir:
|
||||||
|
return os.path.join(unicode(BaseDirectory.xdg_cache_home, encoding), u'openlp')
|
||||||
|
if dir_type == AppLocation.DataDir:
|
||||||
|
return os.path.join(unicode(os.getenv(u'HOME'), encoding), u'.openlp', u'data')
|
||||||
|
return os.path.join(unicode(os.getenv(u'HOME'), encoding), u'.openlp')
|
||||||
|
|
@ -150,8 +150,9 @@ class AlertsPlugin(Plugin):
|
|||||||
self.toolsAlertItem = create_action(tools_menu, u'toolsAlertItem',
|
self.toolsAlertItem = create_action(tools_menu, u'toolsAlertItem',
|
||||||
text=translate('AlertsPlugin', '&Alert'), icon=u':/plugins/plugin_alerts.png',
|
text=translate('AlertsPlugin', '&Alert'), icon=u':/plugins/plugin_alerts.png',
|
||||||
statustip=translate('AlertsPlugin', 'Show an alert message.'),
|
statustip=translate('AlertsPlugin', 'Show an alert message.'),
|
||||||
visible=False, shortcuts=[u'F7'], triggers=self.onAlertsTrigger)
|
visible=False, can_shortcuts=True, triggers=self.onAlertsTrigger)
|
||||||
self.main_window.toolsMenu.addAction(self.toolsAlertItem)
|
self.main_window.tools_menu.addAction(self.toolsAlertItem)
|
||||||
|
|
||||||
|
|
||||||
def initialise(self):
|
def initialise(self):
|
||||||
log.info(u'Alerts Initialising')
|
log.info(u'Alerts Initialising')
|
||||||
@ -184,7 +185,7 @@ class AlertsPlugin(Plugin):
|
|||||||
'<br />The alert plugin controls the displaying of nursery alerts on the display screen.')
|
'<br />The alert plugin controls the displaying of nursery alerts on the display screen.')
|
||||||
return about_text
|
return about_text
|
||||||
|
|
||||||
def setPluginTextStrings(self):
|
def set_plugin_text_strings(self):
|
||||||
"""
|
"""
|
||||||
Called to define all translatable texts of the plugin
|
Called to define all translatable texts of the plugin
|
||||||
"""
|
"""
|
||||||
|
@ -164,7 +164,7 @@ class BiblePlugin(Plugin):
|
|||||||
'verses from different sources during the service.')
|
'verses from different sources during the service.')
|
||||||
return about_text
|
return about_text
|
||||||
|
|
||||||
def usesTheme(self, theme):
|
def uses_theme(self, theme):
|
||||||
"""
|
"""
|
||||||
Called to find out if the bible plugin is currently using a theme.
|
Called to find out if the bible plugin is currently using a theme.
|
||||||
Returns ``True`` if the theme is being used, otherwise returns
|
Returns ``True`` if the theme is being used, otherwise returns
|
||||||
@ -172,7 +172,7 @@ class BiblePlugin(Plugin):
|
|||||||
"""
|
"""
|
||||||
return unicode(self.settingsTab.bible_theme) == theme
|
return unicode(self.settingsTab.bible_theme) == theme
|
||||||
|
|
||||||
def renameTheme(self, oldTheme, newTheme):
|
def rename_theme(self, oldTheme, newTheme):
|
||||||
"""
|
"""
|
||||||
Rename the theme the bible plugin is using making the plugin use the
|
Rename the theme the bible plugin is using making the plugin use the
|
||||||
new name.
|
new name.
|
||||||
@ -187,7 +187,7 @@ class BiblePlugin(Plugin):
|
|||||||
self.settingsTab.bible_theme = newTheme
|
self.settingsTab.bible_theme = newTheme
|
||||||
self.settingsTab.save()
|
self.settingsTab.save()
|
||||||
|
|
||||||
def setPluginTextStrings(self):
|
def set_plugin_text_strings(self):
|
||||||
"""
|
"""
|
||||||
Called to define all translatable texts of the plugin
|
Called to define all translatable texts of the plugin
|
||||||
"""
|
"""
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from openlp.core.lib import Registry, SettingsManager, Settings, translate
|
from openlp.core.lib import Registry, Settings, translate
|
||||||
from openlp.core.utils import AppLocation, delete_file
|
from openlp.core.utils import AppLocation, delete_file
|
||||||
from openlp.plugins.bibles.lib import parse_reference, get_reference_separator, LanguageSelection
|
from openlp.plugins.bibles.lib import parse_reference, get_reference_separator, LanguageSelection
|
||||||
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
|
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
|
||||||
@ -137,7 +137,7 @@ class BibleManager(object):
|
|||||||
BibleDB class.
|
BibleDB class.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Reload bibles')
|
log.debug(u'Reload bibles')
|
||||||
files = SettingsManager.get_files(self.settingsSection, self.suffix)
|
files = AppLocation.get_files(self.settingsSection, self.suffix)
|
||||||
if u'alternative_book_names.sqlite' in files:
|
if u'alternative_book_names.sqlite' in files:
|
||||||
files.remove(u'alternative_book_names.sqlite')
|
files.remove(u'alternative_book_names.sqlite')
|
||||||
log.debug(u'Bible Files %s', files)
|
log.debug(u'Bible Files %s', files)
|
||||||
|
@ -73,7 +73,7 @@ class CustomPlugin(Plugin):
|
|||||||
'the same way songs are. This plugin provides greater freedom over the songs plugin.')
|
'the same way songs are. This plugin provides greater freedom over the songs plugin.')
|
||||||
return about_text
|
return about_text
|
||||||
|
|
||||||
def usesTheme(self, theme):
|
def uses_theme(self, theme):
|
||||||
"""
|
"""
|
||||||
Called to find out if the custom plugin is currently using a theme.
|
Called to find out if the custom plugin is currently using a theme.
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ class CustomPlugin(Plugin):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def renameTheme(self, oldTheme, newTheme):
|
def rename_theme(self, oldTheme, newTheme):
|
||||||
"""
|
"""
|
||||||
Renames a theme the custom plugin is using making the plugin use the
|
Renames a theme the custom plugin is using making the plugin use the
|
||||||
new name.
|
new name.
|
||||||
@ -94,12 +94,12 @@ class CustomPlugin(Plugin):
|
|||||||
``newTheme``
|
``newTheme``
|
||||||
The new name the plugin should now use.
|
The new name the plugin should now use.
|
||||||
"""
|
"""
|
||||||
customsUsingTheme = self.manager.get_all_objects(CustomSlide, CustomSlide.theme_name == oldTheme)
|
customs_using_theme = self.manager.get_all_objects(CustomSlide, CustomSlide.theme_name == oldTheme)
|
||||||
for custom in customsUsingTheme:
|
for custom in customs_using_theme:
|
||||||
custom.theme_name = newTheme
|
custom.theme_name = newTheme
|
||||||
self.manager.save_object(custom)
|
self.manager.save_object(custom)
|
||||||
|
|
||||||
def setPluginTextStrings(self):
|
def set_plugin_text_strings(self):
|
||||||
"""
|
"""
|
||||||
Called to define all translatable texts of the plugin
|
Called to define all translatable texts of the plugin
|
||||||
"""
|
"""
|
||||||
|
@ -32,84 +32,86 @@ from PyQt4 import QtGui
|
|||||||
from openlp.core.lib import UiStrings, build_icon, translate
|
from openlp.core.lib import UiStrings, build_icon, translate
|
||||||
from openlp.core.lib.ui import create_button_box, create_button
|
from openlp.core.lib.ui import create_button_box, create_button
|
||||||
|
|
||||||
class Ui_CustomEditDialog(object):
|
|
||||||
def setupUi(self, customEditDialog):
|
|
||||||
customEditDialog.setObjectName(u'customEditDialog')
|
|
||||||
customEditDialog.resize(450, 350)
|
|
||||||
customEditDialog.setWindowIcon(build_icon(u':/icon/openlp-logo-16x16.png'))
|
|
||||||
self.dialogLayout = QtGui.QVBoxLayout(customEditDialog)
|
|
||||||
self.dialogLayout.setObjectName(u'dialog_layout')
|
|
||||||
self.titleLayout = QtGui.QHBoxLayout()
|
|
||||||
self.titleLayout.setObjectName(u'titleLayout')
|
|
||||||
self.titleLabel = QtGui.QLabel(customEditDialog)
|
|
||||||
self.titleLabel.setObjectName(u'titleLabel')
|
|
||||||
self.titleLayout.addWidget(self.titleLabel)
|
|
||||||
self.titleEdit = QtGui.QLineEdit(customEditDialog)
|
|
||||||
self.titleLabel.setBuddy(self.titleEdit)
|
|
||||||
self.titleEdit.setObjectName(u'titleEdit')
|
|
||||||
self.titleLayout.addWidget(self.titleEdit)
|
|
||||||
self.dialogLayout.addLayout(self.titleLayout)
|
|
||||||
self.centralLayout = QtGui.QHBoxLayout()
|
|
||||||
self.centralLayout.setObjectName(u'centralLayout')
|
|
||||||
self.slideListView = QtGui.QListWidget(customEditDialog)
|
|
||||||
self.slideListView.setAlternatingRowColors(True)
|
|
||||||
self.slideListView.setObjectName(u'slideListView')
|
|
||||||
self.centralLayout.addWidget(self.slideListView)
|
|
||||||
self.buttonLayout = QtGui.QVBoxLayout()
|
|
||||||
self.buttonLayout.setObjectName(u'buttonLayout')
|
|
||||||
self.addButton = QtGui.QPushButton(customEditDialog)
|
|
||||||
self.addButton.setObjectName(u'addButton')
|
|
||||||
self.buttonLayout.addWidget(self.addButton)
|
|
||||||
self.editButton = QtGui.QPushButton(customEditDialog)
|
|
||||||
self.editButton.setEnabled(False)
|
|
||||||
self.editButton.setObjectName(u'editButton')
|
|
||||||
self.buttonLayout.addWidget(self.editButton)
|
|
||||||
self.editAllButton = QtGui.QPushButton(customEditDialog)
|
|
||||||
self.editAllButton.setObjectName(u'editAllButton')
|
|
||||||
self.buttonLayout.addWidget(self.editAllButton)
|
|
||||||
self.deleteButton = create_button(customEditDialog, u'deleteButton', role=u'delete',
|
|
||||||
click=customEditDialog.onDeleteButtonClicked)
|
|
||||||
self.deleteButton.setEnabled(False)
|
|
||||||
self.buttonLayout.addWidget(self.deleteButton)
|
|
||||||
self.buttonLayout.addStretch()
|
|
||||||
self.upButton = create_button(customEditDialog, u'upButton', role=u'up', enabled=False,
|
|
||||||
click=customEditDialog.onUpButtonClicked)
|
|
||||||
self.downButton = create_button(customEditDialog, u'downButton', role=u'down', enabled=False,
|
|
||||||
click=customEditDialog.onDownButtonClicked)
|
|
||||||
self.buttonLayout.addWidget(self.upButton)
|
|
||||||
self.buttonLayout.addWidget(self.downButton)
|
|
||||||
self.centralLayout.addLayout(self.buttonLayout)
|
|
||||||
self.dialogLayout.addLayout(self.centralLayout)
|
|
||||||
self.bottomFormLayout = QtGui.QFormLayout()
|
|
||||||
self.bottomFormLayout.setObjectName(u'bottomFormLayout')
|
|
||||||
self.themeLabel = QtGui.QLabel(customEditDialog)
|
|
||||||
self.themeLabel.setObjectName(u'themeLabel')
|
|
||||||
self.themeComboBox = QtGui.QComboBox(customEditDialog)
|
|
||||||
self.themeComboBox.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents)
|
|
||||||
self.themeComboBox.setObjectName(u'themeComboBox')
|
|
||||||
self.themeLabel.setBuddy(self.themeComboBox)
|
|
||||||
self.bottomFormLayout.addRow(self.themeLabel, self.themeComboBox)
|
|
||||||
self.creditLabel = QtGui.QLabel(customEditDialog)
|
|
||||||
self.creditLabel.setObjectName(u'creditLabel')
|
|
||||||
self.creditEdit = QtGui.QLineEdit(customEditDialog)
|
|
||||||
self.creditEdit.setObjectName(u'creditEdit')
|
|
||||||
self.creditLabel.setBuddy(self.creditEdit)
|
|
||||||
self.bottomFormLayout.addRow(self.creditLabel, self.creditEdit)
|
|
||||||
self.dialogLayout.addLayout(self.bottomFormLayout)
|
|
||||||
self.previewButton = QtGui.QPushButton()
|
|
||||||
self.button_box = create_button_box(customEditDialog, u'button_box', [u'cancel', u'save'], [self.previewButton])
|
|
||||||
self.dialogLayout.addWidget(self.button_box)
|
|
||||||
self.retranslateUi(customEditDialog)
|
|
||||||
|
|
||||||
def retranslateUi(self, customEditDialog):
|
class Ui_CustomEditDialog(object):
|
||||||
customEditDialog.setWindowTitle(translate('CustomPlugin.EditCustomForm', 'Edit Custom Slides'))
|
def setupUi(self, custom_edit_dialog):
|
||||||
self.titleLabel.setText(translate('CustomPlugin.EditCustomForm', '&Title:'))
|
custom_edit_dialog.setObjectName(u'custom_edit_dialog')
|
||||||
self.addButton.setText(UiStrings().Add)
|
custom_edit_dialog.resize(450, 350)
|
||||||
self.addButton.setToolTip(translate('CustomPlugin.EditCustomForm', 'Add a new slide at bottom.'))
|
custom_edit_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo-16x16.png'))
|
||||||
self.editButton.setText(UiStrings().Edit)
|
self.dialog_layout = QtGui.QVBoxLayout(custom_edit_dialog)
|
||||||
self.editButton.setToolTip(translate('CustomPlugin.EditCustomForm', 'Edit the selected slide.'))
|
self.dialog_layout.setObjectName(u'dialog_layout')
|
||||||
self.editAllButton.setText(translate('CustomPlugin.EditCustomForm', 'Ed&it All'))
|
self.title_layout = QtGui.QHBoxLayout()
|
||||||
self.editAllButton.setToolTip(translate('CustomPlugin.EditCustomForm', 'Edit all the slides at once.'))
|
self.title_layout.setObjectName(u'title_layout')
|
||||||
self.themeLabel.setText(translate('CustomPlugin.EditCustomForm', 'The&me:'))
|
self.title_label = QtGui.QLabel(custom_edit_dialog)
|
||||||
self.creditLabel.setText(translate('CustomPlugin.EditCustomForm', '&Credits:'))
|
self.title_label.setObjectName(u'title_label')
|
||||||
self.previewButton.setText(UiStrings().SaveAndPreview)
|
self.title_layout.addWidget(self.title_label)
|
||||||
|
self.title_edit = QtGui.QLineEdit(custom_edit_dialog)
|
||||||
|
self.title_label.setBuddy(self.title_edit)
|
||||||
|
self.title_edit.setObjectName(u'title_edit')
|
||||||
|
self.title_layout.addWidget(self.title_edit)
|
||||||
|
self.dialog_layout.addLayout(self.title_layout)
|
||||||
|
self.central_layout = QtGui.QHBoxLayout()
|
||||||
|
self.central_layout.setObjectName(u'central_layout')
|
||||||
|
self.slide_list_view = QtGui.QListWidget(custom_edit_dialog)
|
||||||
|
self.slide_list_view.setAlternatingRowColors(True)
|
||||||
|
self.slide_list_view.setObjectName(u'slide_list_view')
|
||||||
|
self.central_layout.addWidget(self.slide_list_view)
|
||||||
|
self.button_layout = QtGui.QVBoxLayout()
|
||||||
|
self.button_layout.setObjectName(u'button_layout')
|
||||||
|
self.add_button = QtGui.QPushButton(custom_edit_dialog)
|
||||||
|
self.add_button.setObjectName(u'add_button')
|
||||||
|
self.button_layout.addWidget(self.add_button)
|
||||||
|
self.edit_button = QtGui.QPushButton(custom_edit_dialog)
|
||||||
|
self.edit_button.setEnabled(False)
|
||||||
|
self.edit_button.setObjectName(u'edit_button')
|
||||||
|
self.button_layout.addWidget(self.edit_button)
|
||||||
|
self.edit_all_button = QtGui.QPushButton(custom_edit_dialog)
|
||||||
|
self.edit_all_button.setObjectName(u'edit_all_button')
|
||||||
|
self.button_layout.addWidget(self.edit_all_button)
|
||||||
|
self.delete_button = create_button(custom_edit_dialog, u'delete_button', role=u'delete',
|
||||||
|
click=custom_edit_dialog.on_delete_button_clicked)
|
||||||
|
self.delete_button.setEnabled(False)
|
||||||
|
self.button_layout.addWidget(self.delete_button)
|
||||||
|
self.button_layout.addStretch()
|
||||||
|
self.up_button = create_button(custom_edit_dialog, u'up_button', role=u'up', enabled=False,
|
||||||
|
click=custom_edit_dialog.on_up_button_clicked)
|
||||||
|
self.down_button = create_button(custom_edit_dialog, u'down_button', role=u'down', enabled=False,
|
||||||
|
click=custom_edit_dialog.on_down_button_clicked)
|
||||||
|
self.button_layout.addWidget(self.up_button)
|
||||||
|
self.button_layout.addWidget(self.down_button)
|
||||||
|
self.central_layout.addLayout(self.button_layout)
|
||||||
|
self.dialog_layout.addLayout(self.central_layout)
|
||||||
|
self.bottom_form_layout = QtGui.QFormLayout()
|
||||||
|
self.bottom_form_layout.setObjectName(u'bottom_form_layout')
|
||||||
|
self.theme_label = QtGui.QLabel(custom_edit_dialog)
|
||||||
|
self.theme_label.setObjectName(u'theme_label')
|
||||||
|
self.theme_combo_box = QtGui.QComboBox(custom_edit_dialog)
|
||||||
|
self.theme_combo_box.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents)
|
||||||
|
self.theme_combo_box.setObjectName(u'theme_combo_box')
|
||||||
|
self.theme_label.setBuddy(self.theme_combo_box)
|
||||||
|
self.bottom_form_layout.addRow(self.theme_label, self.theme_combo_box)
|
||||||
|
self.credit_label = QtGui.QLabel(custom_edit_dialog)
|
||||||
|
self.credit_label.setObjectName(u'credit_label')
|
||||||
|
self.credit_edit = QtGui.QLineEdit(custom_edit_dialog)
|
||||||
|
self.credit_edit.setObjectName(u'credit_edit')
|
||||||
|
self.credit_label.setBuddy(self.credit_edit)
|
||||||
|
self.bottom_form_layout.addRow(self.credit_label, self.credit_edit)
|
||||||
|
self.dialog_layout.addLayout(self.bottom_form_layout)
|
||||||
|
self.preview_button = QtGui.QPushButton()
|
||||||
|
self.button_box = create_button_box(custom_edit_dialog, u'button_box', [u'cancel', u'save'],
|
||||||
|
[self.preview_button])
|
||||||
|
self.dialog_layout.addWidget(self.button_box)
|
||||||
|
self.retranslateUi(custom_edit_dialog)
|
||||||
|
|
||||||
|
def retranslateUi(self, custom_edit_dialog):
|
||||||
|
custom_edit_dialog.setWindowTitle(translate('CustomPlugin.EditCustomForm', 'Edit Custom Slides'))
|
||||||
|
self.title_label.setText(translate('CustomPlugin.EditCustomForm', '&Title:'))
|
||||||
|
self.add_button.setText(UiStrings().Add)
|
||||||
|
self.add_button.setToolTip(translate('CustomPlugin.EditCustomForm', 'Add a new slide at bottom.'))
|
||||||
|
self.edit_button.setText(UiStrings().Edit)
|
||||||
|
self.edit_button.setToolTip(translate('CustomPlugin.EditCustomForm', 'Edit the selected slide.'))
|
||||||
|
self.edit_all_button.setText(translate('CustomPlugin.EditCustomForm', 'Ed&it All'))
|
||||||
|
self.edit_all_button.setToolTip(translate('CustomPlugin.EditCustomForm', 'Edit all the slides at once.'))
|
||||||
|
self.theme_label.setText(translate('CustomPlugin.EditCustomForm', 'The&me:'))
|
||||||
|
self.credit_label.setText(translate('CustomPlugin.EditCustomForm', '&Credits:'))
|
||||||
|
self.preview_button.setText(UiStrings().SaveAndPreview)
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtGui
|
||||||
|
|
||||||
from openlp.core.lib import Registry, translate
|
from openlp.core.lib import Registry, translate
|
||||||
from openlp.core.lib.ui import critical_error_message_box, find_and_set_in_combo_box
|
from openlp.core.lib.ui import critical_error_message_box, find_and_set_in_combo_box
|
||||||
@ -56,14 +56,14 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
|||||||
self.mediaitem = mediaitem
|
self.mediaitem = mediaitem
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
# Create other objects and forms.
|
# Create other objects and forms.
|
||||||
self.editSlideForm = EditCustomSlideForm(self)
|
self.edit_slide_form = EditCustomSlideForm(self)
|
||||||
# Connecting signals and slots
|
# Connecting signals and slots
|
||||||
self.previewButton.clicked.connect(self.on_preview_button_clicked)
|
self.preview_button.clicked.connect(self.on_preview_button_clicked)
|
||||||
self.addButton.clicked.connect(self.on_add_button_clicked)
|
self.add_button.clicked.connect(self.on_add_button_clicked)
|
||||||
self.editButton.clicked.connect(self.on_edit_button_clicked)
|
self.edit_button.clicked.connect(self.on_edit_button_clicked)
|
||||||
self.editAllButton.clicked.connect(self.on_edit_all_button_clicked)
|
self.edit_all_button.clicked.connect(self.on_edit_all_button_clicked)
|
||||||
self.slideListView.currentRowChanged.connect(self.on_current_row_changed)
|
self.slide_list_view.currentRowChanged.connect(self.on_current_row_changed)
|
||||||
self.slideListView.doubleClicked.connect(self.on_edit_button_clicked)
|
self.slide_list_view.doubleClicked.connect(self.on_edit_button_clicked)
|
||||||
Registry().register_function(u'theme_update_list', self.load_themes)
|
Registry().register_function(u'theme_update_list', self.load_themes)
|
||||||
|
|
||||||
def load_themes(self, theme_list):
|
def load_themes(self, theme_list):
|
||||||
@ -73,11 +73,11 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
|||||||
``theme_list``
|
``theme_list``
|
||||||
The list of themes to load.
|
The list of themes to load.
|
||||||
"""
|
"""
|
||||||
self.themeComboBox.clear()
|
self.theme_combo_box.clear()
|
||||||
self.themeComboBox.addItem(u'')
|
self.theme_combo_box.addItem(u'')
|
||||||
self.themeComboBox.addItems(theme_list)
|
self.theme_combo_box.addItems(theme_list)
|
||||||
|
|
||||||
def loadCustom(self, id, preview=False):
|
def load_custom(self, id, preview=False):
|
||||||
"""
|
"""
|
||||||
Called when editing or creating a new custom.
|
Called when editing or creating a new custom.
|
||||||
|
|
||||||
@ -88,111 +88,111 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
|||||||
States whether the custom is edited while being previewed in the
|
States whether the custom is edited while being previewed in the
|
||||||
preview panel.
|
preview panel.
|
||||||
"""
|
"""
|
||||||
self.slideListView.clear()
|
self.slide_list_view.clear()
|
||||||
if id == 0:
|
if id == 0:
|
||||||
self.customSlide = CustomSlide()
|
self.custom_slide = CustomSlide()
|
||||||
self.titleEdit.setText(u'')
|
self.title_edit.set_text(u'')
|
||||||
self.creditEdit.setText(u'')
|
self.credit_edit.set_text(u'')
|
||||||
self.themeComboBox.setCurrentIndex(0)
|
self.theme_combo_box.setCurrentIndex(0)
|
||||||
else:
|
else:
|
||||||
self.customSlide = self.manager.get_object(CustomSlide, id)
|
self.custom_slide = self.manager.get_object(CustomSlide, id)
|
||||||
self.titleEdit.setText(self.customSlide.title)
|
self.title_edit.setText(self.custom_slide.title)
|
||||||
self.creditEdit.setText(self.customSlide.credits)
|
self.credit_edit.setText(self.custom_slide.credits)
|
||||||
customXML = CustomXMLParser(self.customSlide.text)
|
custom_XML = CustomXMLParser(self.custom_slide.text)
|
||||||
slideList = customXML.get_verses()
|
slide_list = custom_XML.get_verses()
|
||||||
for slide in slideList:
|
for slide in slide_list:
|
||||||
self.slideListView.addItem(slide[1])
|
self.slide_list_view.addItem(slide[1])
|
||||||
theme = self.customSlide.theme_name
|
theme = self.custom_slide.theme_name
|
||||||
find_and_set_in_combo_box(self.themeComboBox, theme)
|
find_and_set_in_combo_box(self.theme_combo_box, theme)
|
||||||
self.titleEdit.setFocus()
|
self.title_edit.setFocus()
|
||||||
# If not preview hide the preview button.
|
# If not preview hide the preview button.
|
||||||
self.previewButton.setVisible(preview)
|
self.preview_button.setVisible(preview)
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
"""
|
"""
|
||||||
Override the QDialog method to check if the custom slide has been saved before closing the dialog.
|
Override the QDialog method to check if the custom slide has been saved before closing the dialog.
|
||||||
"""
|
"""
|
||||||
log.debug(u'accept')
|
log.debug(u'accept')
|
||||||
if self.saveCustom():
|
if self.save_custom():
|
||||||
QtGui.QDialog.accept(self)
|
QtGui.QDialog.accept(self)
|
||||||
|
|
||||||
def saveCustom(self):
|
def save_custom(self):
|
||||||
"""
|
"""
|
||||||
Saves the custom.
|
Saves the custom.
|
||||||
"""
|
"""
|
||||||
if not self._validate():
|
if not self._validate():
|
||||||
return False
|
return False
|
||||||
sxml = CustomXMLBuilder()
|
sxml = CustomXMLBuilder()
|
||||||
for count in range(self.slideListView.count()):
|
for count in range(self.slide_list_view.count()):
|
||||||
sxml.add_verse_to_lyrics(u'custom', unicode(count + 1), self.slideListView.item(count).text())
|
sxml.add_verse_to_lyrics(u'custom', unicode(count + 1), self.slide_list_view.item(count).text())
|
||||||
self.customSlide.title = self.titleEdit.text()
|
self.custom_slide.title = self.title_edit.text()
|
||||||
self.customSlide.text = unicode(sxml.extract_xml(), u'utf-8')
|
self.custom_slide.text = unicode(sxml.extract_xml(), u'utf-8')
|
||||||
self.customSlide.credits = self.creditEdit.text()
|
self.custom_slide.credits = self.credit_edit.text()
|
||||||
self.customSlide.theme_name = self.themeComboBox.currentText()
|
self.custom_slide.theme_name = self.theme_combo_box.currentText()
|
||||||
success = self.manager.save_object(self.customSlide)
|
success = self.manager.save_object(self.custom_slide)
|
||||||
self.mediaitem.autoSelectId = self.customSlide.id
|
self.mediaitem.autoSelectId = self.custom_slide.id
|
||||||
return success
|
return success
|
||||||
|
|
||||||
def onUpButtonClicked(self):
|
def on_up_button_clicked(self):
|
||||||
"""
|
"""
|
||||||
Move a slide up in the list when the "Up" button is clicked.
|
Move a slide up in the list when the "Up" button is clicked.
|
||||||
"""
|
"""
|
||||||
selectedRow = self.slideListView.currentRow()
|
selectedRow = self.slide_list_view.currentRow()
|
||||||
if selectedRow != 0:
|
if selectedRow != 0:
|
||||||
qw = self.slideListView.takeItem(selectedRow)
|
qw = self.slide_list_view.takeItem(selectedRow)
|
||||||
self.slideListView.insertItem(selectedRow - 1, qw)
|
self.slide_list_view.insertItem(selectedRow - 1, qw)
|
||||||
self.slideListView.setCurrentRow(selectedRow - 1)
|
self.slide_list_view.setCurrentRow(selectedRow - 1)
|
||||||
|
|
||||||
def onDownButtonClicked(self):
|
def on_down_button_clicked(self):
|
||||||
"""
|
"""
|
||||||
Move a slide down in the list when the "Down" button is clicked.
|
Move a slide down in the list when the "Down" button is clicked.
|
||||||
"""
|
"""
|
||||||
selectedRow = self.slideListView.currentRow()
|
selectedRow = self.slide_list_view.currentRow()
|
||||||
# zero base arrays
|
# zero base arrays
|
||||||
if selectedRow != self.slideListView.count() - 1:
|
if selectedRow != self.slide_list_view.count() - 1:
|
||||||
qw = self.slideListView.takeItem(selectedRow)
|
qw = self.slide_list_view.takeItem(selectedRow)
|
||||||
self.slideListView.insertItem(selectedRow + 1, qw)
|
self.slide_list_view.insertItem(selectedRow + 1, qw)
|
||||||
self.slideListView.setCurrentRow(selectedRow + 1)
|
self.slide_list_view.setCurrentRow(selectedRow + 1)
|
||||||
|
|
||||||
def on_add_button_clicked(self):
|
def on_add_button_clicked(self):
|
||||||
"""
|
"""
|
||||||
Add a new blank slide.
|
Add a new blank slide.
|
||||||
"""
|
"""
|
||||||
self.editSlideForm.setText(u'')
|
self.edit_slide_form.set_text(u'')
|
||||||
if self.editSlideForm.exec_():
|
if self.edit_slide_form.exec_():
|
||||||
self.slideListView.addItems(self.editSlideForm.getText())
|
self.slide_list_view.addItems(self.edit_slide_form.get_text())
|
||||||
|
|
||||||
def on_edit_button_clicked(self):
|
def on_edit_button_clicked(self):
|
||||||
"""
|
"""
|
||||||
Edit the currently selected slide.
|
Edit the currently selected slide.
|
||||||
"""
|
"""
|
||||||
self.editSlideForm.setText(self.slideListView.currentItem().text())
|
self.edit_slide_form.set_text(self.slide_list_view.currentItem().text())
|
||||||
if self.editSlideForm.exec_():
|
if self.edit_slide_form.exec_():
|
||||||
self.updateSlideList(self.editSlideForm.getText())
|
self.update_slide_list(self.edit_slide_form.get_text())
|
||||||
|
|
||||||
def on_edit_all_button_clicked(self):
|
def on_edit_all_button_clicked(self):
|
||||||
"""
|
"""
|
||||||
Edits all slides.
|
Edits all slides.
|
||||||
"""
|
"""
|
||||||
slide_text = u''
|
slide_text = u''
|
||||||
for row in range(self.slideListView.count()):
|
for row in range(self.slide_list_view.count()):
|
||||||
item = self.slideListView.item(row)
|
item = self.slide_list_view.item(row)
|
||||||
slide_text += item.text()
|
slide_text += item.text()
|
||||||
if row != self.slideListView.count() - 1:
|
if row != self.slide_list_view.count() - 1:
|
||||||
slide_text += u'\n[===]\n'
|
slide_text += u'\n[===]\n'
|
||||||
self.editSlideForm.setText(slide_text)
|
self.edit_slide_form.set_text(slide_text)
|
||||||
if self.editSlideForm.exec_():
|
if self.edit_slide_form.exec_():
|
||||||
self.updateSlideList(self.editSlideForm.getText(), True)
|
self.update_slide_list(self.edit_slide_form.get_text(), True)
|
||||||
|
|
||||||
def on_preview_button_clicked(self):
|
def on_preview_button_clicked(self):
|
||||||
"""
|
"""
|
||||||
Save the custom item and preview it.
|
Save the custom item and preview it.
|
||||||
"""
|
"""
|
||||||
log.debug(u'onPreview')
|
log.debug(u'onPreview')
|
||||||
if self.saveCustom():
|
if self.save_custom():
|
||||||
Registry().execute(u'custom_preview')
|
Registry().execute(u'custom_preview')
|
||||||
|
|
||||||
def updateSlideList(self, slides, edit_all=False):
|
def update_slide_list(self, slides, edit_all=False):
|
||||||
"""
|
"""
|
||||||
Updates the slide list after editing slides.
|
Updates the slide list after editing slides.
|
||||||
|
|
||||||
@ -203,60 +203,59 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
|
|||||||
Indicates if all slides or only one slide has been edited.
|
Indicates if all slides or only one slide has been edited.
|
||||||
"""
|
"""
|
||||||
if edit_all:
|
if edit_all:
|
||||||
self.slideListView.clear()
|
self.slide_list_view.clear()
|
||||||
self.slideListView.addItems(slides)
|
self.slide_list_view.addItems(slides)
|
||||||
else:
|
else:
|
||||||
old_slides = []
|
old_slides = []
|
||||||
old_row = self.slideListView.currentRow()
|
old_row = self.slide_list_view.currentRow()
|
||||||
# Create a list with all (old/unedited) slides.
|
# Create a list with all (old/unedited) slides.
|
||||||
old_slides = [self.slideListView.item(row).text() for row in
|
old_slides = [self.slide_list_view.item(row).text() for row in range(self.slide_list_view.count())]
|
||||||
range(self.slideListView.count())]
|
self.slide_list_view.clear()
|
||||||
self.slideListView.clear()
|
|
||||||
old_slides.pop(old_row)
|
old_slides.pop(old_row)
|
||||||
# Insert all slides to make the old_slides list complete.
|
# Insert all slides to make the old_slides list complete.
|
||||||
for slide in slides:
|
for slide in slides:
|
||||||
old_slides.insert(old_row, slide)
|
old_slides.insert(old_row, slide)
|
||||||
self.slideListView.addItems(old_slides)
|
self.slide_list_view.addItems(old_slides)
|
||||||
self.slideListView.repaint()
|
self.slide_list_view.repaint()
|
||||||
|
|
||||||
def onDeleteButtonClicked(self):
|
def on_delete_button_clicked(self):
|
||||||
"""
|
"""
|
||||||
Removes the current row from the list.
|
Removes the current row from the list.
|
||||||
"""
|
"""
|
||||||
self.slideListView.takeItem(self.slideListView.currentRow())
|
self.slide_list_view.takeItem(self.slide_list_view.currentRow())
|
||||||
self.on_current_row_changed(self.slideListView.currentRow())
|
self.on_current_row_changed(self.slide_list_view.currentRow())
|
||||||
|
|
||||||
def on_current_row_changed(self, row):
|
def on_current_row_changed(self, row):
|
||||||
"""
|
"""
|
||||||
Called when the *slideListView*'s current row has been changed. This
|
Called when the *slide_list_view*'s current row has been changed. This
|
||||||
enables or disables buttons which require an slide to act on.
|
enables or disables buttons which require an slide to act on.
|
||||||
|
|
||||||
``row``
|
``row``
|
||||||
The row (int). If there is no current row, the value is -1.
|
The row (int). If there is no current row, the value is -1.
|
||||||
"""
|
"""
|
||||||
if row == -1:
|
if row == -1:
|
||||||
self.deleteButton.setEnabled(False)
|
self.delete_button.setEnabled(False)
|
||||||
self.editButton.setEnabled(False)
|
self.edit_button.setEnabled(False)
|
||||||
self.upButton.setEnabled(False)
|
self.up_button.setEnabled(False)
|
||||||
self.downButton.setEnabled(False)
|
self.down_button.setEnabled(False)
|
||||||
else:
|
else:
|
||||||
self.deleteButton.setEnabled(True)
|
self.delete_button.setEnabled(True)
|
||||||
self.editButton.setEnabled(True)
|
self.edit_button.setEnabled(True)
|
||||||
# Decide if the up/down buttons should be enabled or not.
|
# Decide if the up/down buttons should be enabled or not.
|
||||||
self.downButton.setEnabled(self.slideListView.count() - 1 != row)
|
self.down_button.setEnabled(self.slide_list_view.count() - 1 != row)
|
||||||
self.upButton.setEnabled(row != 0)
|
self.up_button.setEnabled(row != 0)
|
||||||
|
|
||||||
def _validate(self):
|
def _validate(self):
|
||||||
"""
|
"""
|
||||||
Checks whether a custom is valid or not.
|
Checks whether a custom is valid or not.
|
||||||
"""
|
"""
|
||||||
# We must have a title.
|
# We must have a title.
|
||||||
if not self.titleEdit.displayText():
|
if not self.title_edit.displayText():
|
||||||
self.titleEdit.setFocus()
|
self.title_edit.setFocus()
|
||||||
critical_error_message_box(message=translate('CustomPlugin.EditCustomForm', 'You need to type in a title.'))
|
critical_error_message_box(message=translate('CustomPlugin.EditCustomForm', 'You need to type in a title.'))
|
||||||
return False
|
return False
|
||||||
# We must have at least one slide.
|
# We must have at least one slide.
|
||||||
if self.slideListView.count() == 0:
|
if self.slide_list_view.count() == 0:
|
||||||
critical_error_message_box(message=translate('CustomPlugin.EditCustomForm',
|
critical_error_message_box(message=translate('CustomPlugin.EditCustomForm',
|
||||||
'You need to add at least one slide'))
|
'You need to add at least one slide'))
|
||||||
return False
|
return False
|
||||||
|
@ -33,24 +33,25 @@ from openlp.core.lib import SpellTextEdit, UiStrings, translate
|
|||||||
from openlp.core.lib.ui import create_button, create_button_box
|
from openlp.core.lib.ui import create_button, create_button_box
|
||||||
|
|
||||||
class Ui_CustomSlideEditDialog(object):
|
class Ui_CustomSlideEditDialog(object):
|
||||||
def setupUi(self, customSlideEditDialog):
|
def setupUi(self, custom_slide_edit_dialog):
|
||||||
customSlideEditDialog.setObjectName(u'customSlideEditDialog')
|
custom_slide_edit_dialog.setObjectName(u'custom_slide_edit_dialog')
|
||||||
customSlideEditDialog.resize(350, 300)
|
custom_slide_edit_dialog.resize(350, 300)
|
||||||
self.dialogLayout = QtGui.QVBoxLayout(customSlideEditDialog)
|
self.dialog_layout = QtGui.QVBoxLayout(custom_slide_edit_dialog)
|
||||||
self.slideTextEdit = SpellTextEdit(self)
|
self.slide_text_edit = SpellTextEdit(self)
|
||||||
self.slideTextEdit.setObjectName(u'slideTextEdit')
|
self.slide_text_edit.setObjectName(u'slide_text_edit')
|
||||||
self.dialogLayout.addWidget(self.slideTextEdit)
|
self.dialog_layout.addWidget(self.slide_text_edit)
|
||||||
self.splitButton = create_button(customSlideEditDialog, u'splitButton', icon=u':/general/general_add.png')
|
self.split_button = create_button(custom_slide_edit_dialog, u'splitButton', icon=u':/general/general_add.png')
|
||||||
self.insertButton = create_button(customSlideEditDialog, u'insertButton', icon=u':/general/general_add.png')
|
self.insert_button = create_button(custom_slide_edit_dialog, u'insertButton',
|
||||||
self.button_box = create_button_box(customSlideEditDialog, u'button_box', [u'cancel', u'save'],
|
icon=u':/general/general_add.png')
|
||||||
[self.splitButton, self.insertButton])
|
self.button_box = create_button_box(custom_slide_edit_dialog, u'button_box', [u'cancel', u'save'],
|
||||||
self.dialogLayout.addWidget(self.button_box)
|
[self.split_button, self.insert_button])
|
||||||
self.retranslateUi(customSlideEditDialog)
|
self.dialog_layout.addWidget(self.button_box)
|
||||||
|
self.retranslateUi(custom_slide_edit_dialog)
|
||||||
|
|
||||||
def retranslateUi(self, customSlideEditDialog):
|
def retranslateUi(self, custom_slide_edit_dialog):
|
||||||
customSlideEditDialog.setWindowTitle(translate('CustomPlugin.EditVerseForm', 'Edit Slide'))
|
custom_slide_edit_dialog.setWindowTitle(translate('CustomPlugin.EditVerseForm', 'Edit Slide'))
|
||||||
self.splitButton.setText(UiStrings().Split)
|
self.split_button.setText(UiStrings().Split)
|
||||||
self.splitButton.setToolTip(UiStrings().SplitToolTip)
|
self.split_button.setToolTip(UiStrings().SplitToolTip)
|
||||||
self.insertButton.setText(translate('CustomPlugin.EditCustomForm', 'Insert Slide'))
|
self.insert_button.setText(translate('CustomPlugin.EditCustomForm', 'Insert Slide'))
|
||||||
self.insertButton.setToolTip(translate('CustomPlugin.EditCustomForm',
|
self.insert_button.setToolTip(translate('CustomPlugin.EditCustomForm',
|
||||||
'Split a slide into two by inserting a slide splitter.'))
|
'Split a slide into two by inserting a slide splitter.'))
|
||||||
|
@ -50,51 +50,49 @@ class EditCustomSlideForm(QtGui.QDialog, Ui_CustomSlideEditDialog):
|
|||||||
super(EditCustomSlideForm, self).__init__(parent)
|
super(EditCustomSlideForm, self).__init__(parent)
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
# Connecting signals and slots
|
# Connecting signals and slots
|
||||||
QtCore.QObject.connect(self.insertButton, QtCore.SIGNAL(u'clicked()'), self.onInsertButtonClicked)
|
self.insert_button.clicked.connect(self.on_insert_button_clicked)
|
||||||
QtCore.QObject.connect(self.splitButton, QtCore.SIGNAL(u'clicked()'), self.onSplitButtonClicked)
|
self.split_button.clicked.connect(self.on_split_button_clicked)
|
||||||
|
|
||||||
def setText(self, text):
|
def set_text(self, text):
|
||||||
"""
|
"""
|
||||||
Set the text for slideTextEdit.
|
Set the text for slide_text_edit.
|
||||||
|
|
||||||
``text``
|
``text``
|
||||||
The text (unicode).
|
The text (unicode).
|
||||||
"""
|
"""
|
||||||
self.slideTextEdit.clear()
|
self.slide_text_edit.clear()
|
||||||
if text:
|
if text:
|
||||||
self.slideTextEdit.setPlainText(text)
|
self.slide_text_edit.setPlainText(text)
|
||||||
self.slideTextEdit.setFocus()
|
self.slide_text_edit.setFocus()
|
||||||
|
|
||||||
def getText(self):
|
def get_text(self):
|
||||||
"""
|
"""
|
||||||
Returns a list with all slides.
|
Returns a list with all slides.
|
||||||
"""
|
"""
|
||||||
return self.slideTextEdit.toPlainText().split(u'\n[===]\n')
|
return self.slide_text_edit.toPlainText().split(u'\n[===]\n')
|
||||||
|
|
||||||
def onInsertButtonClicked(self):
|
def on_insert_button_clicked(self):
|
||||||
"""
|
"""
|
||||||
Adds a slide split at the cursor.
|
Adds a slide split at the cursor.
|
||||||
"""
|
"""
|
||||||
self.insertSingleLineTextAtCursor(u'[===]')
|
self.insert_single_line_text_at_cursor(u'[===]')
|
||||||
self.slideTextEdit.setFocus()
|
self.slide_text_edit.setFocus()
|
||||||
|
|
||||||
def onSplitButtonClicked(self):
|
def on_split_button_clicked(self):
|
||||||
"""
|
"""
|
||||||
Adds an optional split at cursor.
|
Adds an optional split at cursor.
|
||||||
"""
|
"""
|
||||||
self.insertSingleLineTextAtCursor(u'[---]')
|
self.insert_single_line_text_at_cursor(u'[---]')
|
||||||
self.slideTextEdit.setFocus()
|
self.slide_text_edit.setFocus()
|
||||||
|
|
||||||
def insertSingleLineTextAtCursor(self, text):
|
def insert_single_line_text_at_cursor(self, text):
|
||||||
"""
|
"""
|
||||||
Adds ``text`` in a single line at the cursor position.
|
Adds ``text`` in a single line at the cursor position.
|
||||||
"""
|
"""
|
||||||
full_text = self.slideTextEdit.toPlainText()
|
full_text = self.slide_text_edit.toPlainText()
|
||||||
position = self.slideTextEdit.textCursor().position()
|
position = self.slide_text_edit.textCursor().position()
|
||||||
if position and full_text[position - 1] != u'\n':
|
if position and full_text[position - 1] != u'\n':
|
||||||
text = u'\n' + text
|
text = u'\n' + text
|
||||||
if position == len(full_text) or full_text[position] != u'\n':
|
if position == len(full_text) or full_text[position] != u'\n':
|
||||||
text += u'\n'
|
text += u'\n'
|
||||||
self.slideTextEdit.insertPlainText(text)
|
self.slide_text_edit.insertPlainText(text)
|
||||||
|
|
||||||
#lint:enable
|
|
||||||
|
@ -45,38 +45,36 @@ class CustomTab(SettingsTab):
|
|||||||
def setupUi(self):
|
def setupUi(self):
|
||||||
self.setObjectName(u'CustomTab')
|
self.setObjectName(u'CustomTab')
|
||||||
SettingsTab.setupUi(self)
|
SettingsTab.setupUi(self)
|
||||||
self.customModeGroupBox = QtGui.QGroupBox(self.leftColumn)
|
self.custom_mode_group_box = QtGui.QGroupBox(self.leftColumn)
|
||||||
self.customModeGroupBox.setObjectName(u'customModeGroupBox')
|
self.custom_mode_group_box.setObjectName(u'custom_mode_group_box')
|
||||||
self.customModeLayout = QtGui.QFormLayout(self.customModeGroupBox)
|
self.custom_mode_layout = QtGui.QFormLayout(self.custom_mode_group_box)
|
||||||
self.customModeLayout.setObjectName(u'customModeLayout')
|
self.custom_mode_layout.setObjectName(u'custom_mode_layout')
|
||||||
self.displayFooterCheckBox = QtGui.QCheckBox(self.customModeGroupBox)
|
self.display_footer_check_box = QtGui.QCheckBox(self.custom_mode_group_box)
|
||||||
self.displayFooterCheckBox.setObjectName(u'displayFooterCheckBox')
|
self.display_footer_check_box.setObjectName(u'display_footer_check_box')
|
||||||
self.customModeLayout.addRow(self.displayFooterCheckBox)
|
self.custom_mode_layout.addRow(self.display_footer_check_box)
|
||||||
self.add_from_service_checkbox = QtGui.QCheckBox(self.customModeGroupBox)
|
self.add_from_service_checkbox = QtGui.QCheckBox(self.custom_mode_group_box)
|
||||||
self.add_from_service_checkbox.setObjectName(u'add_from_service_checkbox')
|
self.add_from_service_checkbox.setObjectName(u'add_from_service_checkbox')
|
||||||
self.customModeLayout.addRow(self.add_from_service_checkbox)
|
self.custom_mode_layout.addRow(self.add_from_service_checkbox)
|
||||||
self.leftLayout.addWidget(self.customModeGroupBox)
|
self.leftLayout.addWidget(self.custom_mode_group_box)
|
||||||
self.leftLayout.addStretch()
|
self.leftLayout.addStretch()
|
||||||
self.rightLayout.addStretch()
|
self.rightLayout.addStretch()
|
||||||
QtCore.QObject.connect(self.displayFooterCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
|
self.display_footer_check_box.stateChanged.connect(self.on_display_footer_check_box_changed)
|
||||||
self.onDisplayFooterCheckBoxChanged)
|
self.add_from_service_checkbox.stateChanged.connect(self.on_add_from_service_check_box_changed)
|
||||||
QtCore.QObject.connect(self.add_from_service_checkbox, QtCore.SIGNAL(u'stateChanged(int)'),
|
|
||||||
self.on_add_from_service_check_box_changed)
|
|
||||||
|
|
||||||
def retranslateUi(self):
|
def retranslateUi(self):
|
||||||
self.customModeGroupBox.setTitle(translate('CustomPlugin.CustomTab', 'Custom Display'))
|
self.custom_mode_group_box.setTitle(translate('CustomPlugin.CustomTab', 'Custom Display'))
|
||||||
self.displayFooterCheckBox.setText(translate('CustomPlugin.CustomTab', 'Display footer'))
|
self.display_footer_check_box.setText(translate('CustomPlugin.CustomTab', 'Display footer'))
|
||||||
self.add_from_service_checkbox.setText(translate('CustomPlugin.CustomTab',
|
self.add_from_service_checkbox.setText(translate('CustomPlugin.CustomTab',
|
||||||
'Import missing custom slides from service files'))
|
'Import missing custom slides from service files'))
|
||||||
|
|
||||||
def onDisplayFooterCheckBoxChanged(self, check_state):
|
def on_display_footer_check_box_changed(self, check_state):
|
||||||
"""
|
"""
|
||||||
Toggle the setting for displaying the footer.
|
Toggle the setting for displaying the footer.
|
||||||
"""
|
"""
|
||||||
self.displayFooter = False
|
self.display_footer = False
|
||||||
# we have a set value convert to True/False
|
# we have a set value convert to True/False
|
||||||
if check_state == QtCore.Qt.Checked:
|
if check_state == QtCore.Qt.Checked:
|
||||||
self.displayFooter = True
|
self.display_footer = True
|
||||||
|
|
||||||
def on_add_from_service_check_box_changed(self, check_state):
|
def on_add_from_service_check_box_changed(self, check_state):
|
||||||
self.update_load = (check_state == QtCore.Qt.Checked)
|
self.update_load = (check_state == QtCore.Qt.Checked)
|
||||||
@ -84,15 +82,15 @@ class CustomTab(SettingsTab):
|
|||||||
def load(self):
|
def load(self):
|
||||||
settings = Settings()
|
settings = Settings()
|
||||||
settings.beginGroup(self.settingsSection)
|
settings.beginGroup(self.settingsSection)
|
||||||
self.displayFooter = settings.value(u'display footer')
|
self.display_footer = settings.value(u'display footer')
|
||||||
self.update_load = settings.value(u'add custom from service')
|
self.update_load = settings.value(u'add custom from service')
|
||||||
self.displayFooterCheckBox.setChecked(self.displayFooter)
|
self.display_footer_check_box.setChecked(self.display_footer)
|
||||||
self.add_from_service_checkbox.setChecked(self.update_load)
|
self.add_from_service_checkbox.setChecked(self.update_load)
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
settings = Settings()
|
settings = Settings()
|
||||||
settings.beginGroup(self.settingsSection)
|
settings.beginGroup(self.settingsSection)
|
||||||
settings.setValue(u'display footer', self.displayFooter)
|
settings.setValue(u'display footer', self.display_footer)
|
||||||
settings.setValue(u'add custom from service', self.update_load)
|
settings.setValue(u'add custom from service', self.update_load)
|
||||||
settings.endGroup()
|
settings.endGroup()
|
||||||
|
@ -114,7 +114,7 @@ class CustomMediaItem(MediaManagerItem):
|
|||||||
# active trigger it and clean up so it will not update again.
|
# active trigger it and clean up so it will not update again.
|
||||||
|
|
||||||
def onNewClick(self):
|
def onNewClick(self):
|
||||||
self.edit_custom_form.loadCustom(0)
|
self.edit_custom_form.load_custom(0)
|
||||||
self.edit_custom_form.exec_()
|
self.edit_custom_form.exec_()
|
||||||
self.onClearTextButtonClick()
|
self.onClearTextButtonClick()
|
||||||
self.onSelectionChange()
|
self.onSelectionChange()
|
||||||
@ -128,7 +128,7 @@ class CustomMediaItem(MediaManagerItem):
|
|||||||
custom_id = int(custom_id)
|
custom_id = int(custom_id)
|
||||||
valid = self.manager.get_object(CustomSlide, custom_id)
|
valid = self.manager.get_object(CustomSlide, custom_id)
|
||||||
if valid:
|
if valid:
|
||||||
self.edit_custom_form.loadCustom(custom_id, preview)
|
self.edit_custom_form.load_custom(custom_id, preview)
|
||||||
if self.edit_custom_form.exec_() == QtGui.QDialog.Accepted:
|
if self.edit_custom_form.exec_() == QtGui.QDialog.Accepted:
|
||||||
self.remoteTriggered = True
|
self.remoteTriggered = True
|
||||||
self.remoteCustom = custom_id
|
self.remoteCustom = custom_id
|
||||||
@ -148,7 +148,7 @@ class CustomMediaItem(MediaManagerItem):
|
|||||||
if check_item_selected(self.listView, UiStrings().SelectEdit):
|
if check_item_selected(self.listView, UiStrings().SelectEdit):
|
||||||
item = self.listView.currentItem()
|
item = self.listView.currentItem()
|
||||||
item_id = item.data(QtCore.Qt.UserRole)
|
item_id = item.data(QtCore.Qt.UserRole)
|
||||||
self.edit_custom_form.loadCustom(item_id, False)
|
self.edit_custom_form.load_custom(item_id, False)
|
||||||
self.edit_custom_form.exec_()
|
self.edit_custom_form.exec_()
|
||||||
self.autoSelectId = -1
|
self.autoSelectId = -1
|
||||||
self.onSearchTextButtonClicked()
|
self.onSearchTextButtonClicked()
|
||||||
|
@ -65,7 +65,7 @@ class ImagePlugin(Plugin):
|
|||||||
'provided by the theme.')
|
'provided by the theme.')
|
||||||
return about_text
|
return about_text
|
||||||
|
|
||||||
def setPluginTextStrings(self):
|
def set_plugin_text_strings(self):
|
||||||
"""
|
"""
|
||||||
Called to define all translatable texts of the plugin
|
Called to define all translatable texts of the plugin
|
||||||
"""
|
"""
|
||||||
|
@ -32,9 +32,8 @@ import os
|
|||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import MediaManagerItem, ItemCapabilities, Registry, SettingsManager, ServiceItemContext, \
|
from openlp.core.lib import MediaManagerItem, ItemCapabilities, Registry, ServiceItemContext, Settings, UiStrings, \
|
||||||
Settings, UiStrings, build_icon, check_item_selected, check_directory_exists, create_thumb, translate, \
|
build_icon, check_item_selected, check_directory_exists, create_thumb, translate, validate_thumb
|
||||||
validate_thumb
|
|
||||||
from openlp.core.lib.ui import critical_error_message_box
|
from openlp.core.lib.ui import critical_error_message_box
|
||||||
from openlp.core.utils import AppLocation, delete_file, locale_compare, get_images_filter
|
from openlp.core.utils import AppLocation, delete_file, locale_compare, get_images_filter
|
||||||
|
|
||||||
@ -107,7 +106,7 @@ class ImageMediaItem(MediaManagerItem):
|
|||||||
delete_file(os.path.join(self.servicePath, text.text()))
|
delete_file(os.path.join(self.servicePath, text.text()))
|
||||||
self.listView.takeItem(row)
|
self.listView.takeItem(row)
|
||||||
self.main_window.incrementProgressBar()
|
self.main_window.incrementProgressBar()
|
||||||
SettingsManager.setValue(self.settingsSection + u'/images files', self.getFileList())
|
Settings.setValue(self.settingsSection + u'/images files', self.getFileList())
|
||||||
self.main_window.finishedProgressBar()
|
self.main_window.finishedProgressBar()
|
||||||
self.application.set_normal_cursor()
|
self.application.set_normal_cursor()
|
||||||
self.listView.blockSignals(False)
|
self.listView.blockSignals(False)
|
||||||
@ -192,7 +191,7 @@ class ImageMediaItem(MediaManagerItem):
|
|||||||
Called to reset the Live background with the image selected,
|
Called to reset the Live background with the image selected,
|
||||||
"""
|
"""
|
||||||
self.resetAction.setVisible(False)
|
self.resetAction.setVisible(False)
|
||||||
self.live_controller.display.resetImage()
|
self.live_controller.display.reset_image()
|
||||||
|
|
||||||
def live_theme_changed(self):
|
def live_theme_changed(self):
|
||||||
"""
|
"""
|
||||||
@ -211,7 +210,7 @@ class ImageMediaItem(MediaManagerItem):
|
|||||||
bitem = self.listView.item(item.row())
|
bitem = self.listView.item(item.row())
|
||||||
filename = bitem.data(QtCore.Qt.UserRole)
|
filename = bitem.data(QtCore.Qt.UserRole)
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename):
|
||||||
if self.live_controller.display.directImage(filename, background):
|
if self.live_controller.display.direct_image(filename, background):
|
||||||
self.resetAction.setVisible(True)
|
self.resetAction.setVisible(True)
|
||||||
else:
|
else:
|
||||||
critical_error_message_box(UiStrings().LiveBGError,
|
critical_error_message_box(UiStrings().LiveBGError,
|
||||||
|
@ -61,16 +61,16 @@ class MediaMediaItem(MediaManagerItem):
|
|||||||
self.singleServiceItem = False
|
self.singleServiceItem = False
|
||||||
self.hasSearch = True
|
self.hasSearch = True
|
||||||
self.mediaObject = None
|
self.mediaObject = None
|
||||||
self.displayController = DisplayController(parent)
|
self.display_controller = DisplayController(parent)
|
||||||
self.displayController.controllerLayout = QtGui.QVBoxLayout()
|
self.display_controller.controller_layout = QtGui.QVBoxLayout()
|
||||||
self.media_controller.register_controller(self.displayController)
|
self.media_controller.register_controller(self.display_controller)
|
||||||
self.media_controller.set_controls_visible(self.displayController, False)
|
self.media_controller.set_controls_visible(self.display_controller, False)
|
||||||
self.displayController.previewDisplay = Display(self.displayController, False, self.displayController)
|
self.display_controller.preview_display = Display(self.display_controller, False, self.display_controller)
|
||||||
self.displayController.previewDisplay.hide()
|
self.display_controller.preview_display.hide()
|
||||||
self.displayController.previewDisplay.setGeometry(QtCore.QRect(0, 0, 300, 300))
|
self.display_controller.preview_display.setGeometry(QtCore.QRect(0, 0, 300, 300))
|
||||||
self.displayController.previewDisplay.screen = {u'size':self.displayController.previewDisplay.geometry()}
|
self.display_controller.preview_display.screen = {u'size': self.display_controller.preview_display.geometry()}
|
||||||
self.displayController.previewDisplay.setup()
|
self.display_controller.preview_display.setup()
|
||||||
self.media_controller.setup_display(self.displayController.previewDisplay, False)
|
self.media_controller.setup_display(self.display_controller.preview_display, False)
|
||||||
Registry().register_function(u'video_background_replaced', self.video_background_replaced)
|
Registry().register_function(u'video_background_replaced', self.video_background_replaced)
|
||||||
Registry().register_function(u'mediaitem_media_rebuild', self.rebuild_players)
|
Registry().register_function(u'mediaitem_media_rebuild', self.rebuild_players)
|
||||||
Registry().register_function(u'config_screen_changed', self.display_setup)
|
Registry().register_function(u'config_screen_changed', self.display_setup)
|
||||||
@ -214,7 +214,7 @@ class MediaMediaItem(MediaManagerItem):
|
|||||||
u' '.join(self.media_controller.audio_extensions_list), UiStrings().AllFiles)
|
u' '.join(self.media_controller.audio_extensions_list), UiStrings().AllFiles)
|
||||||
|
|
||||||
def display_setup(self):
|
def display_setup(self):
|
||||||
self.media_controller.setup_display(self.displayController.previewDisplay, False)
|
self.media_controller.setup_display(self.display_controller.previewDisplay, False)
|
||||||
|
|
||||||
def populateDisplayTypes(self):
|
def populateDisplayTypes(self):
|
||||||
"""
|
"""
|
||||||
@ -226,11 +226,11 @@ class MediaMediaItem(MediaManagerItem):
|
|||||||
self.displayTypeComboBox.blockSignals(True)
|
self.displayTypeComboBox.blockSignals(True)
|
||||||
self.displayTypeComboBox.clear()
|
self.displayTypeComboBox.clear()
|
||||||
usedPlayers, overridePlayer = get_media_players()
|
usedPlayers, overridePlayer = get_media_players()
|
||||||
mediaPlayers = self.media_controller.mediaPlayers
|
media_players = self.media_controller.media_players
|
||||||
currentIndex = 0
|
currentIndex = 0
|
||||||
for player in usedPlayers:
|
for player in usedPlayers:
|
||||||
# load the drop down selection
|
# load the drop down selection
|
||||||
self.displayTypeComboBox.addItem(mediaPlayers[player].original_name)
|
self.displayTypeComboBox.addItem(media_players[player].original_name)
|
||||||
if overridePlayer == player:
|
if overridePlayer == player:
|
||||||
currentIndex = len(self.displayTypeComboBox)
|
currentIndex = len(self.displayTypeComboBox)
|
||||||
if self.displayTypeComboBox.count() > 1:
|
if self.displayTypeComboBox.count() > 1:
|
||||||
|
@ -66,7 +66,7 @@ class MediaPlugin(Plugin):
|
|||||||
'<br />The media plugin provides playback of audio and video.')
|
'<br />The media plugin provides playback of audio and video.')
|
||||||
return about_text
|
return about_text
|
||||||
|
|
||||||
def setPluginTextStrings(self):
|
def set_plugin_text_strings(self):
|
||||||
"""
|
"""
|
||||||
Called to define all translatable texts of the plugin
|
Called to define all translatable texts of the plugin
|
||||||
"""
|
"""
|
||||||
|
@ -156,7 +156,7 @@ class PresentationPlugin(Plugin):
|
|||||||
'available to the user in a drop down box.')
|
'available to the user in a drop down box.')
|
||||||
return about_text
|
return about_text
|
||||||
|
|
||||||
def setPluginTextStrings(self):
|
def set_plugin_text_strings(self):
|
||||||
"""
|
"""
|
||||||
Called to define all translatable texts of the plugin
|
Called to define all translatable texts of the plugin
|
||||||
"""
|
"""
|
||||||
|
@ -130,7 +130,6 @@ from openlp.plugins.remotes.lib.httpauth import AuthController, require_auth
|
|||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class HttpServer(object):
|
class HttpServer(object):
|
||||||
"""
|
"""
|
||||||
Ability to control OpenLP via a web browser.
|
Ability to control OpenLP via a web browser.
|
||||||
@ -400,9 +399,9 @@ class HttpConnection(object):
|
|||||||
u'slide': self.parent.current_slide or 0,
|
u'slide': self.parent.current_slide or 0,
|
||||||
u'item': self.parent.current_item.unique_identifier if self.parent.current_item else u'',
|
u'item': self.parent.current_item.unique_identifier if self.parent.current_item else u'',
|
||||||
u'twelve': Settings().value(u'remotes/twelve hour'),
|
u'twelve': Settings().value(u'remotes/twelve hour'),
|
||||||
u'blank': self.live_controller.blankScreen.isChecked(),
|
u'blank': self.live_controller.blank_screen.isChecked(),
|
||||||
u'theme': self.live_controller.themeScreen.isChecked(),
|
u'theme': self.live_controller.theme_screen.isChecked(),
|
||||||
u'display': self.live_controller.desktopScreen.isChecked()
|
u'display': self.live_controller.desktop_screen.isChecked()
|
||||||
}
|
}
|
||||||
cherrypy.response.headers['Content-Type'] = u'application/json'
|
cherrypy.response.headers['Content-Type'] = u'application/json'
|
||||||
return json.dumps({u'results': result})
|
return json.dumps({u'results': result})
|
||||||
@ -437,18 +436,17 @@ class HttpConnection(object):
|
|||||||
cherrypy.response.headers['Content-Type'] = u'application/json'
|
cherrypy.response.headers['Content-Type'] = u'application/json'
|
||||||
return json.dumps({u'results': {u'success': success}})
|
return json.dumps({u'results': {u'success': success}})
|
||||||
|
|
||||||
def controller(self, type, action):
|
def controller(self, display_type, action):
|
||||||
"""
|
"""
|
||||||
Perform an action on the slide controller.
|
Perform an action on the slide controller.
|
||||||
|
|
||||||
``type``
|
``display_type``
|
||||||
This is the type of slide controller, either ``preview`` or
|
This is the type of slide controller, either ``preview`` or ``live``.
|
||||||
``live``.
|
|
||||||
|
|
||||||
``action``
|
``action``
|
||||||
The action to perform.
|
The action to perform.
|
||||||
"""
|
"""
|
||||||
event = u'slidecontroller_%s_%s' % (type, action)
|
event = u'slidecontroller_%s_%s' % (display_type, action)
|
||||||
if action == u'text':
|
if action == u'text':
|
||||||
current_item = self.parent.current_item
|
current_item = self.parent.current_item
|
||||||
data = []
|
data = []
|
||||||
@ -489,7 +487,10 @@ class HttpConnection(object):
|
|||||||
|
|
||||||
def service(self, action):
|
def service(self, action):
|
||||||
"""
|
"""
|
||||||
List details of the Service and update the UI
|
Handles requests for service items
|
||||||
|
|
||||||
|
``action``
|
||||||
|
The action to perform.
|
||||||
"""
|
"""
|
||||||
event = u'servicemanager_%s' % action
|
event = u'servicemanager_%s' % action
|
||||||
if action == u'list':
|
if action == u'list':
|
||||||
@ -524,11 +525,11 @@ class HttpConnection(object):
|
|||||||
cherrypy.response.headers['Content-Type'] = u'application/json'
|
cherrypy.response.headers['Content-Type'] = u'application/json'
|
||||||
return json.dumps({u'results': {u'items': searches}})
|
return json.dumps({u'results': {u'items': searches}})
|
||||||
|
|
||||||
def search(self, type):
|
def search(self, plugin_name):
|
||||||
"""
|
"""
|
||||||
Return a list of items that match the search text.
|
Return a list of items that match the search text.
|
||||||
|
|
||||||
``type``
|
``plugin``
|
||||||
The plugin name to search in.
|
The plugin name to search in.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
@ -536,7 +537,7 @@ class HttpConnection(object):
|
|||||||
except KeyError, ValueError:
|
except KeyError, ValueError:
|
||||||
return self._http_bad_request()
|
return self._http_bad_request()
|
||||||
text = urllib.unquote(text)
|
text = urllib.unquote(text)
|
||||||
plugin = self.plugin_manager.get_plugin_by_name(type)
|
plugin = self.plugin_manager.get_plugin_by_name(plugin_name)
|
||||||
if plugin.status == PluginStatus.Active and plugin.mediaItem and plugin.mediaItem.hasSearch:
|
if plugin.status == PluginStatus.Active and plugin.mediaItem and plugin.mediaItem.hasSearch:
|
||||||
results = plugin.mediaItem.search(text, False)
|
results = plugin.mediaItem.search(text, False)
|
||||||
else:
|
else:
|
||||||
@ -544,9 +545,9 @@ class HttpConnection(object):
|
|||||||
cherrypy.response.headers['Content-Type'] = u'application/json'
|
cherrypy.response.headers['Content-Type'] = u'application/json'
|
||||||
return json.dumps({u'results': {u'items': results}})
|
return json.dumps({u'results': {u'items': results}})
|
||||||
|
|
||||||
def go_live(self, type):
|
def go_live(self, plugin_name):
|
||||||
"""
|
"""
|
||||||
Go live on an item of type ``type``.
|
Go live on an item of type ``plugin``.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
|
id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
|
||||||
@ -557,9 +558,9 @@ class HttpConnection(object):
|
|||||||
plugin.mediaItem.goLive(id, remote=True)
|
plugin.mediaItem.goLive(id, remote=True)
|
||||||
return self._http_success()
|
return self._http_success()
|
||||||
|
|
||||||
def add_to_service(self, type):
|
def add_to_service(self, plugin_name):
|
||||||
"""
|
"""
|
||||||
Add item of type ``type`` to the end of the service.
|
Add item of type ``plugin_name`` to the end of the service.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
|
id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
|
||||||
|
@ -56,6 +56,7 @@ class RemoteTab(SettingsTab):
|
|||||||
self.address_label.setObjectName(u'address_label')
|
self.address_label.setObjectName(u'address_label')
|
||||||
self.address_edit = QtGui.QLineEdit(self.server_settings_group_box)
|
self.address_edit = QtGui.QLineEdit(self.server_settings_group_box)
|
||||||
self.address_edit.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
|
self.address_edit.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
|
||||||
|
|
||||||
self.address_edit.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp(u'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'),
|
self.address_edit.setValidator(QtGui.QRegExpValidator(QtCore.QRegExp(u'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'),
|
||||||
self))
|
self))
|
||||||
self.address_edit.setObjectName(u'address_edit')
|
self.address_edit.setObjectName(u'address_edit')
|
||||||
@ -63,6 +64,7 @@ class RemoteTab(SettingsTab):
|
|||||||
self.twelve_hour_check_box = QtGui.QCheckBox(self.server_settings_group_box)
|
self.twelve_hour_check_box = QtGui.QCheckBox(self.server_settings_group_box)
|
||||||
self.twelve_hour_check_box.setObjectName(u'twelve_hour_check_box')
|
self.twelve_hour_check_box.setObjectName(u'twelve_hour_check_box')
|
||||||
self.server_settings_layout.addRow(self.twelve_hour_check_box)
|
self.server_settings_layout.addRow(self.twelve_hour_check_box)
|
||||||
|
|
||||||
self.leftLayout.addWidget(self.server_settings_group_box)
|
self.leftLayout.addWidget(self.server_settings_group_box)
|
||||||
self.http_settings_group_box = QtGui.QGroupBox(self.leftColumn)
|
self.http_settings_group_box = QtGui.QGroupBox(self.leftColumn)
|
||||||
self.http_settings_group_box.setObjectName(u'http_settings_group_box')
|
self.http_settings_group_box.setObjectName(u'http_settings_group_box')
|
||||||
@ -73,6 +75,7 @@ class RemoteTab(SettingsTab):
|
|||||||
self.port_spin_box = QtGui.QSpinBox(self.http_settings_group_box)
|
self.port_spin_box = QtGui.QSpinBox(self.http_settings_group_box)
|
||||||
self.port_spin_box.setMaximum(32767)
|
self.port_spin_box.setMaximum(32767)
|
||||||
self.port_spin_box.setObjectName(u'port_spin_box')
|
self.port_spin_box.setObjectName(u'port_spin_box')
|
||||||
|
|
||||||
self.http_setting_layout.addRow(self.port_label, self.port_spin_box)
|
self.http_setting_layout.addRow(self.port_label, self.port_spin_box)
|
||||||
self.remote_url_label = QtGui.QLabel(self.http_settings_group_box)
|
self.remote_url_label = QtGui.QLabel(self.http_settings_group_box)
|
||||||
self.remote_url_label.setObjectName(u'remote_url_label')
|
self.remote_url_label.setObjectName(u'remote_url_label')
|
||||||
@ -180,7 +183,7 @@ class RemoteTab(SettingsTab):
|
|||||||
self.password_label.setText(translate('RemotePlugin.RemoteTab', 'Password:'))
|
self.password_label.setText(translate('RemotePlugin.RemoteTab', 'Password:'))
|
||||||
|
|
||||||
def set_urls(self):
|
def set_urls(self):
|
||||||
ipAddress = u'localhost'
|
ip_address = u'localhost'
|
||||||
if self.address_edit.text() == ZERO_URL:
|
if self.address_edit.text() == ZERO_URL:
|
||||||
interfaces = QtNetwork.QNetworkInterface.allInterfaces()
|
interfaces = QtNetwork.QNetworkInterface.allInterfaces()
|
||||||
for interface in interfaces:
|
for interface in interfaces:
|
||||||
@ -191,12 +194,12 @@ class RemoteTab(SettingsTab):
|
|||||||
for address in interface.addressEntries():
|
for address in interface.addressEntries():
|
||||||
ip = address.ip()
|
ip = address.ip()
|
||||||
if ip.protocol() == 0 and ip != QtNetwork.QHostAddress.LocalHost:
|
if ip.protocol() == 0 and ip != QtNetwork.QHostAddress.LocalHost:
|
||||||
ipAddress = ip
|
ip_address = ip
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
ipAddress = self.address_edit.text()
|
ip_address = self.address_edit.text()
|
||||||
http_url = u'http://%s:%s/' % (ipAddress, self.port_spin_box.value())
|
http_url = u'http://%s:%s/' % (ip_address, self.port_spin_box.value())
|
||||||
https_url = u'https://%s:%s/' % (ipAddress, self.https_port_spin_box.value())
|
https_url = u'https://%s:%s/' % (ip_address, self.https_port_spin_box.value())
|
||||||
self.remote_url.setText(u'<a href="%s">%s</a>' % (http_url, http_url))
|
self.remote_url.setText(u'<a href="%s">%s</a>' % (http_url, http_url))
|
||||||
self.remote_https_url.setText(u'<a href="%s">%s</a>' % (https_url, https_url))
|
self.remote_https_url.setText(u'<a href="%s">%s</a>' % (https_url, https_url))
|
||||||
http_url += u'stage'
|
http_url += u'stage'
|
||||||
@ -243,6 +246,7 @@ class RemoteTab(SettingsTab):
|
|||||||
if changed:
|
if changed:
|
||||||
Registry().register_function(u'remotes_config_updated')
|
Registry().register_function(u'remotes_config_updated')
|
||||||
|
|
||||||
|
|
||||||
def on_twelve_hour_check_box_changed(self, check_state):
|
def on_twelve_hour_check_box_changed(self, check_state):
|
||||||
self.twelve_hour = False
|
self.twelve_hour = False
|
||||||
# we have a set value convert to True/False
|
# we have a set value convert to True/False
|
||||||
|
@ -86,7 +86,7 @@ class RemotesPlugin(Plugin):
|
|||||||
'browser or through the remote API.')
|
'browser or through the remote API.')
|
||||||
return about_text
|
return about_text
|
||||||
|
|
||||||
def setPluginTextStrings(self):
|
def set_plugin_text_strings(self):
|
||||||
"""
|
"""
|
||||||
Called to define all translatable texts of the plugin
|
Called to define all translatable texts of the plugin
|
||||||
"""
|
"""
|
||||||
|
@ -291,7 +291,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
verse_tags_translated = True
|
verse_tags_translated = True
|
||||||
if index is None:
|
if index is None:
|
||||||
index = VerseType.from_tag(verse_tag)
|
index = VerseType.from_tag(verse_tag)
|
||||||
verse[0][u'type'] = VerseType.Tags[index]
|
verse[0][u'type'] = VerseType.tags[index]
|
||||||
if verse[0][u'label'] == u'':
|
if verse[0][u'label'] == u'':
|
||||||
verse[0][u'label'] = u'1'
|
verse[0][u'label'] = u'1'
|
||||||
verse_def = u'%s%s' % (verse[0][u'type'], verse[0][u'label'])
|
verse_def = u'%s%s' % (verse[0][u'type'], verse[0][u'label'])
|
||||||
@ -303,7 +303,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
for count, verse in enumerate(verses):
|
for count, verse in enumerate(verses):
|
||||||
self.verseListWidget.setRowCount(self.verseListWidget.rowCount() + 1)
|
self.verseListWidget.setRowCount(self.verseListWidget.rowCount() + 1)
|
||||||
item = QtGui.QTableWidgetItem(verse)
|
item = QtGui.QTableWidgetItem(verse)
|
||||||
verse_def = u'%s%s' % (VerseType.Tags[VerseType.Verse], unicode(count + 1))
|
verse_def = u'%s%s' % (VerseType.tags[VerseType.Verse], unicode(count + 1))
|
||||||
item.setData(QtCore.Qt.UserRole, verse_def)
|
item.setData(QtCore.Qt.UserRole, verse_def)
|
||||||
self.verseListWidget.setItem(count, 0, item)
|
self.verseListWidget.setItem(count, 0, item)
|
||||||
if self.song.verse_order:
|
if self.song.verse_order:
|
||||||
@ -315,7 +315,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
verse_index = VerseType.from_translated_tag(verse_def[0], None)
|
verse_index = VerseType.from_translated_tag(verse_def[0], None)
|
||||||
if verse_index is None:
|
if verse_index is None:
|
||||||
verse_index = VerseType.from_tag(verse_def[0])
|
verse_index = VerseType.from_tag(verse_def[0])
|
||||||
verse_tag = VerseType.TranslatedTags[verse_index].upper()
|
verse_tag = VerseType.translated_tags[verse_index].upper()
|
||||||
translated.append(u'%s%s' % (verse_tag, verse_def[1:]))
|
translated.append(u'%s%s' % (verse_tag, verse_def[1:]))
|
||||||
self.verseOrderEdit.setText(u' '.join(translated))
|
self.verseOrderEdit.setText(u' '.join(translated))
|
||||||
else:
|
else:
|
||||||
@ -547,7 +547,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
verse_name = parts
|
verse_name = parts
|
||||||
verse_num = u'1'
|
verse_num = u'1'
|
||||||
verse_index = VerseType.from_loose_input(verse_name)
|
verse_index = VerseType.from_loose_input(verse_name)
|
||||||
verse_tag = VerseType.Tags[verse_index]
|
verse_tag = VerseType.tags[verse_index]
|
||||||
# Later we need to handle v1a as well.
|
# Later we need to handle v1a as well.
|
||||||
#regex = re.compile(r'(\d+\w.)')
|
#regex = re.compile(r'(\d+\w.)')
|
||||||
regex = re.compile(r'\D*(\d+)\D*')
|
regex = re.compile(r'\D*(\d+)\D*')
|
||||||
@ -599,7 +599,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
if len(item) == 1:
|
if len(item) == 1:
|
||||||
verse_index = VerseType.from_translated_tag(item, None)
|
verse_index = VerseType.from_translated_tag(item, None)
|
||||||
if verse_index is not None:
|
if verse_index is not None:
|
||||||
order.append(VerseType.Tags[verse_index] + u'1')
|
order.append(VerseType.tags[verse_index] + u'1')
|
||||||
else:
|
else:
|
||||||
# it matches no verses anyway
|
# it matches no verses anyway
|
||||||
order.append(u'')
|
order.append(u'')
|
||||||
@ -609,7 +609,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
# it matches no verses anyway
|
# it matches no verses anyway
|
||||||
order.append(u'')
|
order.append(u'')
|
||||||
else:
|
else:
|
||||||
verse_tag = VerseType.Tags[verse_index]
|
verse_tag = VerseType.tags[verse_index]
|
||||||
verse_num = item[1:].lower()
|
verse_num = item[1:].lower()
|
||||||
order.append(verse_tag + verse_num)
|
order.append(verse_tag + verse_num)
|
||||||
return order
|
return order
|
||||||
@ -831,7 +831,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
ordertext = self.verseOrderEdit.text()
|
ordertext = self.verseOrderEdit.text()
|
||||||
order = []
|
order = []
|
||||||
for item in ordertext.split():
|
for item in ordertext.split():
|
||||||
verse_tag = VerseType.Tags[VerseType.from_translated_tag(item[0])]
|
verse_tag = VerseType.tags[VerseType.from_translated_tag(item[0])]
|
||||||
verse_num = item[1:].lower()
|
verse_num = item[1:].lower()
|
||||||
order.append(u'%s%s' % (verse_tag, verse_num))
|
order.append(u'%s%s' % (verse_tag, verse_num))
|
||||||
self.song.verse_order = u' '.join(order)
|
self.song.verse_order = u' '.join(order)
|
||||||
@ -923,6 +923,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
self.song.verse_order)
|
self.song.verse_order)
|
||||||
except:
|
except:
|
||||||
log.exception(u'Problem processing song Lyrics \n%s', sxml.dump_xml())
|
log.exception(u'Problem processing song Lyrics \n%s', sxml.dump_xml())
|
||||||
|
raise
|
||||||
|
|
||||||
def _get_plugin_manager(self):
|
def _get_plugin_manager(self):
|
||||||
"""
|
"""
|
||||||
|
@ -74,13 +74,13 @@ class Ui_EditVerseDialog(object):
|
|||||||
def retranslateUi(self, editVerseDialog):
|
def retranslateUi(self, editVerseDialog):
|
||||||
editVerseDialog.setWindowTitle(translate('SongsPlugin.EditVerseForm', 'Edit Verse'))
|
editVerseDialog.setWindowTitle(translate('SongsPlugin.EditVerseForm', 'Edit Verse'))
|
||||||
self.verseTypeLabel.setText(translate('SongsPlugin.EditVerseForm', '&Verse type:'))
|
self.verseTypeLabel.setText(translate('SongsPlugin.EditVerseForm', '&Verse type:'))
|
||||||
self.verseTypeComboBox.setItemText(VerseType.Verse, VerseType.TranslatedNames[VerseType.Verse])
|
self.verseTypeComboBox.setItemText(VerseType.Verse, VerseType.translated_names[VerseType.Verse])
|
||||||
self.verseTypeComboBox.setItemText(VerseType.Chorus, VerseType.TranslatedNames[VerseType.Chorus])
|
self.verseTypeComboBox.setItemText(VerseType.Chorus, VerseType.translated_names[VerseType.Chorus])
|
||||||
self.verseTypeComboBox.setItemText(VerseType.Bridge, VerseType.TranslatedNames[VerseType.Bridge])
|
self.verseTypeComboBox.setItemText(VerseType.Bridge, VerseType.translated_names[VerseType.Bridge])
|
||||||
self.verseTypeComboBox.setItemText(VerseType.PreChorus, VerseType.TranslatedNames[VerseType.PreChorus])
|
self.verseTypeComboBox.setItemText(VerseType.PreChorus, VerseType.translated_names[VerseType.PreChorus])
|
||||||
self.verseTypeComboBox.setItemText(VerseType.Intro, VerseType.TranslatedNames[VerseType.Intro])
|
self.verseTypeComboBox.setItemText(VerseType.Intro, VerseType.translated_names[VerseType.Intro])
|
||||||
self.verseTypeComboBox.setItemText(VerseType.Ending, VerseType.TranslatedNames[VerseType.Ending])
|
self.verseTypeComboBox.setItemText(VerseType.Ending, VerseType.translated_names[VerseType.Ending])
|
||||||
self.verseTypeComboBox.setItemText(VerseType.Other, VerseType.TranslatedNames[VerseType.Other])
|
self.verseTypeComboBox.setItemText(VerseType.Other, VerseType.translated_names[VerseType.Other])
|
||||||
self.splitButton.setText(UiStrings().Split)
|
self.splitButton.setText(UiStrings().Split)
|
||||||
self.splitButton.setToolTip(UiStrings().SplitToolTip)
|
self.splitButton.setToolTip(UiStrings().SplitToolTip)
|
||||||
self.insertButton.setText(translate('SongsPlugin.EditVerseForm', '&Insert'))
|
self.insertButton.setText(translate('SongsPlugin.EditVerseForm', '&Insert'))
|
||||||
|
@ -82,8 +82,7 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
|
|||||||
|
|
||||||
def onInsertButtonClicked(self):
|
def onInsertButtonClicked(self):
|
||||||
verse_type_index = self.verseTypeComboBox.currentIndex()
|
verse_type_index = self.verseTypeComboBox.currentIndex()
|
||||||
self.insertVerse(VerseType.Tags[verse_type_index],
|
self.insertVerse(VerseType.tags[verse_type_index], self.verseNumberBox.value())
|
||||||
self.verseNumberBox.value())
|
|
||||||
|
|
||||||
def onVerseTypeComboBoxChanged(self):
|
def onVerseTypeComboBoxChanged(self):
|
||||||
self.updateSuggestedVerseNumber()
|
self.updateSuggestedVerseNumber()
|
||||||
@ -93,12 +92,11 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
|
|||||||
|
|
||||||
def updateSuggestedVerseNumber(self):
|
def updateSuggestedVerseNumber(self):
|
||||||
"""
|
"""
|
||||||
Adjusts the verse number SpinBox in regard to the selected verse type
|
Adjusts the verse number SpinBox in regard to the selected verse type and the cursor's position.
|
||||||
and the cursor's position.
|
|
||||||
"""
|
"""
|
||||||
position = self.verseTextEdit.textCursor().position()
|
position = self.verseTextEdit.textCursor().position()
|
||||||
text = self.verseTextEdit.toPlainText()
|
text = self.verseTextEdit.toPlainText()
|
||||||
verse_name = VerseType.TranslatedNames[
|
verse_name = VerseType.translated_names[
|
||||||
self.verseTypeComboBox.currentIndex()]
|
self.verseTypeComboBox.currentIndex()]
|
||||||
if not text:
|
if not text:
|
||||||
return
|
return
|
||||||
@ -120,8 +118,7 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
|
|||||||
verse_num = 1
|
verse_num = 1
|
||||||
self.verseNumberBox.setValue(verse_num)
|
self.verseNumberBox.setValue(verse_num)
|
||||||
|
|
||||||
def setVerse(self, text, single=False,
|
def setVerse(self, text, single=False, tag=u'%s1' % VerseType.tags[VerseType.Verse]):
|
||||||
tag=u'%s1' % VerseType.Tags[VerseType.Verse]):
|
|
||||||
self.hasSingleVerse = single
|
self.hasSingleVerse = single
|
||||||
if single:
|
if single:
|
||||||
verse_type_index = VerseType.from_tag(tag[0], None)
|
verse_type_index = VerseType.from_tag(tag[0], None)
|
||||||
@ -132,7 +129,7 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
|
|||||||
self.insertButton.setVisible(False)
|
self.insertButton.setVisible(False)
|
||||||
else:
|
else:
|
||||||
if not text:
|
if not text:
|
||||||
text = u'---[%s:1]---\n' % VerseType.TranslatedNames[VerseType.Verse]
|
text = u'---[%s:1]---\n' % VerseType.translated_names[VerseType.Verse]
|
||||||
self.verseTypeComboBox.setCurrentIndex(0)
|
self.verseTypeComboBox.setCurrentIndex(0)
|
||||||
self.verseNumberBox.setValue(1)
|
self.verseNumberBox.setValue(1)
|
||||||
self.insertButton.setVisible(True)
|
self.insertButton.setVisible(True)
|
||||||
@ -141,12 +138,12 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
|
|||||||
self.verseTextEdit.moveCursor(QtGui.QTextCursor.End)
|
self.verseTextEdit.moveCursor(QtGui.QTextCursor.End)
|
||||||
|
|
||||||
def getVerse(self):
|
def getVerse(self):
|
||||||
return self.verseTextEdit.toPlainText(), VerseType.Tags[self.verseTypeComboBox.currentIndex()], \
|
return self.verseTextEdit.toPlainText(), VerseType.tags[self.verseTypeComboBox.currentIndex()], \
|
||||||
unicode(self.verseNumberBox.value())
|
unicode(self.verseNumberBox.value())
|
||||||
|
|
||||||
def getVerseAll(self):
|
def getVerseAll(self):
|
||||||
text = self.verseTextEdit.toPlainText()
|
text = self.verseTextEdit.toPlainText()
|
||||||
if not text.startswith(u'---['):
|
if not text.startswith(u'---['):
|
||||||
text = u'---[%s:1]---\n%s' % (VerseType.TranslatedNames[VerseType.Verse], text)
|
text = u'---[%s:1]---\n%s' % (VerseType.translated_names[VerseType.Verse], text)
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ import os
|
|||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import Settings, UiStrings, translate
|
from openlp.core.lib import Registry, Settings, UiStrings, translate
|
||||||
from openlp.core.lib.ui import critical_error_message_box
|
from openlp.core.lib.ui import critical_error_message_box
|
||||||
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
|
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
|
||||||
from openlp.plugins.songs.lib.importer import SongFormat, SongFormatSelect
|
from openlp.plugins.songs.lib.importer import SongFormat, SongFormatSelect
|
||||||
@ -489,6 +489,16 @@ class SongImportForm(OpenLPWizard):
|
|||||||
self.formatWidgets[this_format][u'importWidget'] = importWidget
|
self.formatWidgets[this_format][u'importWidget'] = importWidget
|
||||||
return importWidget
|
return importWidget
|
||||||
|
|
||||||
|
def _get_main_window(self):
|
||||||
|
"""
|
||||||
|
Adds the main window to the class dynamically
|
||||||
|
"""
|
||||||
|
if not hasattr(self, u'_main_window'):
|
||||||
|
self._main_window = Registry().get(u'main_window')
|
||||||
|
return self._main_window
|
||||||
|
|
||||||
|
main_window = property(_get_main_window)
|
||||||
|
|
||||||
|
|
||||||
class SongImportSourcePage(QtGui.QWizardPage):
|
class SongImportSourcePage(QtGui.QWizardPage):
|
||||||
"""
|
"""
|
||||||
|
@ -37,8 +37,7 @@ from ui import SongStrings
|
|||||||
|
|
||||||
WHITESPACE = re.compile(r'[\W_]+', re.UNICODE)
|
WHITESPACE = re.compile(r'[\W_]+', re.UNICODE)
|
||||||
APOSTROPHE = re.compile(u'[\'`’ʻ′]', re.UNICODE)
|
APOSTROPHE = re.compile(u'[\'`’ʻ′]', re.UNICODE)
|
||||||
PATTERN = re.compile(r"\\([a-z]{1,32})(-?\d{1,10})?[ ]?|\\'"
|
PATTERN = re.compile(r"\\([a-z]{1,32})(-?\d{1,10})?[ ]?|\\'([0-9a-f]{2})|\\([^a-z])|([{}])|[\r\n]+|(.)", re.I)
|
||||||
r"([0-9a-f]{2})|\\([^a-z])|([{}])|[\r\n]+|(.)", re.I)
|
|
||||||
# RTF control words which specify a "destination" to be ignored.
|
# RTF control words which specify a "destination" to be ignored.
|
||||||
DESTINATIONS = frozenset((
|
DESTINATIONS = frozenset((
|
||||||
u'aftncn', u'aftnsep', u'aftnsepc', u'annotation', u'atnauthor',
|
u'aftncn', u'aftnsep', u'aftnsepc', u'annotation', u'atnauthor',
|
||||||
@ -138,8 +137,7 @@ CHARSET_MAPPING = {
|
|||||||
|
|
||||||
class VerseType(object):
|
class VerseType(object):
|
||||||
"""
|
"""
|
||||||
VerseType provides an enumeration for the tags that may be associated
|
VerseType provides an enumeration for the tags that may be associated with verses in songs.
|
||||||
with verses in songs.
|
|
||||||
"""
|
"""
|
||||||
Verse = 0
|
Verse = 0
|
||||||
Chorus = 1
|
Chorus = 1
|
||||||
@ -149,7 +147,7 @@ class VerseType(object):
|
|||||||
Ending = 5
|
Ending = 5
|
||||||
Other = 6
|
Other = 6
|
||||||
|
|
||||||
Names = [
|
names = [
|
||||||
u'Verse',
|
u'Verse',
|
||||||
u'Chorus',
|
u'Chorus',
|
||||||
u'Bridge',
|
u'Bridge',
|
||||||
@ -157,9 +155,9 @@ class VerseType(object):
|
|||||||
u'Intro',
|
u'Intro',
|
||||||
u'Ending',
|
u'Ending',
|
||||||
u'Other']
|
u'Other']
|
||||||
Tags = [name[0].lower() for name in Names]
|
tags = [name[0].lower() for name in names]
|
||||||
|
|
||||||
TranslatedNames = [
|
translated_names = [
|
||||||
translate('SongsPlugin.VerseType', 'Verse'),
|
translate('SongsPlugin.VerseType', 'Verse'),
|
||||||
translate('SongsPlugin.VerseType', 'Chorus'),
|
translate('SongsPlugin.VerseType', 'Chorus'),
|
||||||
translate('SongsPlugin.VerseType', 'Bridge'),
|
translate('SongsPlugin.VerseType', 'Bridge'),
|
||||||
@ -167,13 +165,12 @@ class VerseType(object):
|
|||||||
translate('SongsPlugin.VerseType', 'Intro'),
|
translate('SongsPlugin.VerseType', 'Intro'),
|
||||||
translate('SongsPlugin.VerseType', 'Ending'),
|
translate('SongsPlugin.VerseType', 'Ending'),
|
||||||
translate('SongsPlugin.VerseType', 'Other')]
|
translate('SongsPlugin.VerseType', 'Other')]
|
||||||
TranslatedTags = [name[0].lower() for name in TranslatedNames]
|
translated_tags = [name[0].lower() for name in translated_names]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def translated_tag(verse_tag, default=Other):
|
def translated_tag(verse_tag, default=Other):
|
||||||
"""
|
"""
|
||||||
Return the translated UPPERCASE tag for a given tag,
|
Return the translated UPPERCASE tag for a given tag, used to show translated verse tags in UI
|
||||||
used to show translated verse tags in UI
|
|
||||||
|
|
||||||
``verse_tag``
|
``verse_tag``
|
||||||
The string to return a VerseType for
|
The string to return a VerseType for
|
||||||
@ -182,11 +179,11 @@ class VerseType(object):
|
|||||||
Default return value if no matching tag is found
|
Default return value if no matching tag is found
|
||||||
"""
|
"""
|
||||||
verse_tag = verse_tag[0].lower()
|
verse_tag = verse_tag[0].lower()
|
||||||
for num, tag in enumerate(VerseType.Tags):
|
for num, tag in enumerate(VerseType.tags):
|
||||||
if verse_tag == tag:
|
if verse_tag == tag:
|
||||||
return VerseType.TranslatedTags[num].upper()
|
return VerseType.translated_tags[num].upper()
|
||||||
if default in VerseType.TranslatedTags:
|
if default in VerseType.translated_tags:
|
||||||
return VerseType.TranslatedTags[default].upper()
|
return VerseType.translated_tags[default].upper()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def translated_name(verse_tag, default=Other):
|
def translated_name(verse_tag, default=Other):
|
||||||
@ -200,11 +197,11 @@ class VerseType(object):
|
|||||||
Default return value if no matching tag is found
|
Default return value if no matching tag is found
|
||||||
"""
|
"""
|
||||||
verse_tag = verse_tag[0].lower()
|
verse_tag = verse_tag[0].lower()
|
||||||
for num, tag in enumerate(VerseType.Tags):
|
for num, tag in enumerate(VerseType.tags):
|
||||||
if verse_tag == tag:
|
if verse_tag == tag:
|
||||||
return VerseType.TranslatedNames[num]
|
return VerseType.translated_names[num]
|
||||||
if default in VerseType.TranslatedNames:
|
if default in VerseType.translated_names:
|
||||||
return VerseType.TranslatedNames[default]
|
return VerseType.translated_names[default]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_tag(verse_tag, default=Other):
|
def from_tag(verse_tag, default=Other):
|
||||||
@ -218,7 +215,7 @@ class VerseType(object):
|
|||||||
Default return value if no matching tag is found
|
Default return value if no matching tag is found
|
||||||
"""
|
"""
|
||||||
verse_tag = verse_tag[0].lower()
|
verse_tag = verse_tag[0].lower()
|
||||||
for num, tag in enumerate(VerseType.Tags):
|
for num, tag in enumerate(VerseType.tags):
|
||||||
if verse_tag == tag:
|
if verse_tag == tag:
|
||||||
return num
|
return num
|
||||||
return default
|
return default
|
||||||
@ -235,7 +232,7 @@ class VerseType(object):
|
|||||||
Default return value if no matching tag is found
|
Default return value if no matching tag is found
|
||||||
"""
|
"""
|
||||||
verse_tag = verse_tag[0].lower()
|
verse_tag = verse_tag[0].lower()
|
||||||
for num, tag in enumerate(VerseType.TranslatedTags):
|
for num, tag in enumerate(VerseType.translated_tags):
|
||||||
if verse_tag == tag:
|
if verse_tag == tag:
|
||||||
return num
|
return num
|
||||||
return default
|
return default
|
||||||
@ -252,7 +249,7 @@ class VerseType(object):
|
|||||||
Default return value if no matching tag is found
|
Default return value if no matching tag is found
|
||||||
"""
|
"""
|
||||||
verse_name = verse_name.lower()
|
verse_name = verse_name.lower()
|
||||||
for num, name in enumerate(VerseType.Names):
|
for num, name in enumerate(VerseType.names):
|
||||||
if verse_name == name.lower():
|
if verse_name == name.lower():
|
||||||
return num
|
return num
|
||||||
return default
|
return default
|
||||||
@ -266,7 +263,7 @@ class VerseType(object):
|
|||||||
The string to return a VerseType for
|
The string to return a VerseType for
|
||||||
"""
|
"""
|
||||||
verse_name = verse_name.lower()
|
verse_name = verse_name.lower()
|
||||||
for num, translation in enumerate(VerseType.TranslatedNames):
|
for num, translation in enumerate(VerseType.translated_names):
|
||||||
if verse_name == translation.lower():
|
if verse_name == translation.lower():
|
||||||
return num
|
return num
|
||||||
|
|
||||||
@ -296,13 +293,11 @@ class VerseType(object):
|
|||||||
|
|
||||||
def retrieve_windows_encoding(recommendation=None):
|
def retrieve_windows_encoding(recommendation=None):
|
||||||
"""
|
"""
|
||||||
Determines which encoding to use on an information source. The process uses
|
Determines which encoding to use on an information source. The process uses both automated detection, which is
|
||||||
both automated detection, which is passed to this method as a
|
passed to this method as a recommendation, and user confirmation to return an encoding.
|
||||||
recommendation, and user confirmation to return an encoding.
|
|
||||||
|
|
||||||
``recommendation``
|
``recommendation``
|
||||||
A recommended encoding discovered programmatically for the user to
|
A recommended encoding discovered programmatically for the user to confirm.
|
||||||
confirm.
|
|
||||||
"""
|
"""
|
||||||
# map chardet result to compatible windows standard code page
|
# map chardet result to compatible windows standard code page
|
||||||
codepage_mapping = {'IBM866': u'cp866', 'TIS-620': u'cp874',
|
codepage_mapping = {'IBM866': u'cp866', 'TIS-620': u'cp874',
|
||||||
@ -355,24 +350,22 @@ def retrieve_windows_encoding(recommendation=None):
|
|||||||
|
|
||||||
def clean_string(string):
|
def clean_string(string):
|
||||||
"""
|
"""
|
||||||
Strips punctuation from the passed string to assist searching
|
Strips punctuation from the passed string to assist searching.
|
||||||
"""
|
"""
|
||||||
return WHITESPACE.sub(u' ', APOSTROPHE.sub(u'', string)).lower()
|
return WHITESPACE.sub(u' ', APOSTROPHE.sub(u'', string)).lower()
|
||||||
|
|
||||||
|
|
||||||
def clean_title(title):
|
def clean_title(title):
|
||||||
"""
|
"""
|
||||||
Cleans the song title by removing Unicode control chars groups C0 & C1,
|
Cleans the song title by removing Unicode control chars groups C0 & C1, as well as any trailing spaces.
|
||||||
as well as any trailing spaces
|
|
||||||
"""
|
"""
|
||||||
return CONTROL_CHARS.sub(u'', title).rstrip()
|
return CONTROL_CHARS.sub(u'', title).rstrip()
|
||||||
|
|
||||||
|
|
||||||
def clean_song(manager, song):
|
def clean_song(manager, song):
|
||||||
"""
|
"""
|
||||||
Cleans the search title, rebuilds the search lyrics, adds a default author
|
Cleans the search title, rebuilds the search lyrics, adds a default author if the song does not have one and other
|
||||||
if the song does not have one and other clean ups. This should always
|
clean ups. This should always called when a new song is added or changed.
|
||||||
called when a new song is added or changed.
|
|
||||||
|
|
||||||
``manager``
|
``manager``
|
||||||
The song's manager.
|
The song's manager.
|
||||||
@ -397,21 +390,20 @@ def clean_song(manager, song):
|
|||||||
song.search_title = clean_string(song.title) + u'@' + clean_string(song.alternate_title)
|
song.search_title = clean_string(song.title) + u'@' + clean_string(song.alternate_title)
|
||||||
# Only do this, if we the song is a 1.9.4 song (or older).
|
# Only do this, if we the song is a 1.9.4 song (or older).
|
||||||
if song.lyrics.find(u'<lyrics language="en">') != -1:
|
if song.lyrics.find(u'<lyrics language="en">') != -1:
|
||||||
# Remove the old "language" attribute from lyrics tag (prior to 1.9.5).
|
# Remove the old "language" attribute from lyrics tag (prior to 1.9.5). This is not very important, but this
|
||||||
# This is not very important, but this keeps the database clean. This
|
# keeps the database clean. This can be removed when everybody has cleaned his songs.
|
||||||
# can be removed when everybody has cleaned his songs.
|
|
||||||
song.lyrics = song.lyrics.replace(u'<lyrics language="en">', u'<lyrics>')
|
song.lyrics = song.lyrics.replace(u'<lyrics language="en">', u'<lyrics>')
|
||||||
verses = SongXML().get_verses(song.lyrics)
|
verses = SongXML().get_verses(song.lyrics)
|
||||||
song.search_lyrics = u' '.join([clean_string(verse[1])
|
song.search_lyrics = u' '.join([clean_string(verse[1])
|
||||||
for verse in verses])
|
for verse in verses])
|
||||||
# We need a new and clean SongXML instance.
|
# We need a new and clean SongXML instance.
|
||||||
sxml = SongXML()
|
sxml = SongXML()
|
||||||
# Rebuild the song's verses, to remove any wrong verse names (for
|
# Rebuild the song's verses, to remove any wrong verse names (for example translated ones), which might have
|
||||||
# example translated ones), which might have been added prior to 1.9.5.
|
# been added prior to 1.9.5.
|
||||||
# List for later comparison.
|
# List for later comparison.
|
||||||
compare_order = []
|
compare_order = []
|
||||||
for verse in verses:
|
for verse in verses:
|
||||||
verse_type = VerseType.Tags[VerseType.from_loose_input(verse[0][u'type'])]
|
verse_type = VerseType.tags[VerseType.from_loose_input(verse[0][u'type'])]
|
||||||
sxml.add_verse_to_lyrics(
|
sxml.add_verse_to_lyrics(
|
||||||
verse_type,
|
verse_type,
|
||||||
verse[0][u'label'],
|
verse[0][u'label'],
|
||||||
@ -422,15 +414,14 @@ def clean_song(manager, song):
|
|||||||
if verse[0][u'label'] == u'1':
|
if verse[0][u'label'] == u'1':
|
||||||
compare_order.append(verse_type.upper())
|
compare_order.append(verse_type.upper())
|
||||||
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
|
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
|
||||||
# Rebuild the verse order, to convert translated verse tags, which might
|
# Rebuild the verse order, to convert translated verse tags, which might have been added prior to 1.9.5.
|
||||||
# have been added prior to 1.9.5.
|
|
||||||
if song.verse_order:
|
if song.verse_order:
|
||||||
order = CONTROL_CHARS.sub(u'', song.verse_order).strip().split()
|
order = CONTROL_CHARS.sub(u'', song.verse_order).strip().split()
|
||||||
else:
|
else:
|
||||||
order = []
|
order = []
|
||||||
new_order = []
|
new_order = []
|
||||||
for verse_def in order:
|
for verse_def in order:
|
||||||
verse_type = VerseType.Tags[
|
verse_type = VerseType.tags[
|
||||||
VerseType.from_loose_input(verse_def[0])]
|
VerseType.from_loose_input(verse_def[0])]
|
||||||
if len(verse_def) > 1:
|
if len(verse_def) > 1:
|
||||||
new_order.append((u'%s%s' % (verse_type, verse_def[1:])).upper())
|
new_order.append((u'%s%s' % (verse_type, verse_def[1:])).upper())
|
||||||
@ -589,8 +580,7 @@ def strip_rtf(text, default_encoding=None):
|
|||||||
|
|
||||||
def natcmp(a, b):
|
def natcmp(a, b):
|
||||||
"""
|
"""
|
||||||
Natural string comparison which mimics the behaviour of Python's internal
|
Natural string comparison which mimics the behaviour of Python's internal cmp function.
|
||||||
cmp function.
|
|
||||||
"""
|
"""
|
||||||
if len(a) <= len(b):
|
if len(a) <= len(b):
|
||||||
for i, key in enumerate(a):
|
for i, key in enumerate(a):
|
||||||
|
@ -188,13 +188,13 @@ class CCLIFileImport(SongImport):
|
|||||||
words_list = song_words.split(u'/t')
|
words_list = song_words.split(u'/t')
|
||||||
for counter in range(len(field_list)):
|
for counter in range(len(field_list)):
|
||||||
if field_list[counter].startswith(u'Ver'):
|
if field_list[counter].startswith(u'Ver'):
|
||||||
verse_type = VerseType.Tags[VerseType.Verse]
|
verse_type = VerseType.tags[VerseType.Verse]
|
||||||
elif field_list[counter].startswith(u'Ch'):
|
elif field_list[counter].startswith(u'Ch'):
|
||||||
verse_type = VerseType.Tags[VerseType.Chorus]
|
verse_type = VerseType.tags[VerseType.Chorus]
|
||||||
elif field_list[counter].startswith(u'Br'):
|
elif field_list[counter].startswith(u'Br'):
|
||||||
verse_type = VerseType.Tags[VerseType.Bridge]
|
verse_type = VerseType.tags[VerseType.Bridge]
|
||||||
else:
|
else:
|
||||||
verse_type = VerseType.Tags[VerseType.Other]
|
verse_type = VerseType.tags[VerseType.Other]
|
||||||
check_first_verse_line = True
|
check_first_verse_line = True
|
||||||
verse_text = unicode(words_list[counter])
|
verse_text = unicode(words_list[counter])
|
||||||
verse_text = verse_text.replace(u'/n', u'\n')
|
verse_text = verse_text.replace(u'/n', u'\n')
|
||||||
@ -202,15 +202,15 @@ class CCLIFileImport(SongImport):
|
|||||||
verse_lines = verse_text.split(u'\n', 1)
|
verse_lines = verse_text.split(u'\n', 1)
|
||||||
if check_first_verse_line:
|
if check_first_verse_line:
|
||||||
if verse_lines[0].startswith(u'(PRE-CHORUS'):
|
if verse_lines[0].startswith(u'(PRE-CHORUS'):
|
||||||
verse_type = VerseType.Tags[VerseType.PreChorus]
|
verse_type = VerseType.tags[VerseType.PreChorus]
|
||||||
log.debug(u'USR verse PRE-CHORUS: %s', verse_lines[0])
|
log.debug(u'USR verse PRE-CHORUS: %s', verse_lines[0])
|
||||||
verse_text = verse_lines[1]
|
verse_text = verse_lines[1]
|
||||||
elif verse_lines[0].startswith(u'(BRIDGE'):
|
elif verse_lines[0].startswith(u'(BRIDGE'):
|
||||||
verse_type = VerseType.Tags[VerseType.Bridge]
|
verse_type = VerseType.tags[VerseType.Bridge]
|
||||||
log.debug(u'USR verse BRIDGE')
|
log.debug(u'USR verse BRIDGE')
|
||||||
verse_text = verse_lines[1]
|
verse_text = verse_lines[1]
|
||||||
elif verse_lines[0].startswith(u'('):
|
elif verse_lines[0].startswith(u'('):
|
||||||
verse_type = VerseType.Tags[VerseType.Other]
|
verse_type = VerseType.tags[VerseType.Other]
|
||||||
verse_text = verse_lines[1]
|
verse_text = verse_lines[1]
|
||||||
if verse_text:
|
if verse_text:
|
||||||
self.addVerse(verse_text, verse_type)
|
self.addVerse(verse_text, verse_type)
|
||||||
@ -292,31 +292,31 @@ class CCLIFileImport(SongImport):
|
|||||||
verse_desc_parts = clean_line.split(u' ')
|
verse_desc_parts = clean_line.split(u' ')
|
||||||
if len(verse_desc_parts) == 2:
|
if len(verse_desc_parts) == 2:
|
||||||
if verse_desc_parts[0].startswith(u'Ver'):
|
if verse_desc_parts[0].startswith(u'Ver'):
|
||||||
verse_type = VerseType.Tags[VerseType.Verse]
|
verse_type = VerseType.tags[VerseType.Verse]
|
||||||
elif verse_desc_parts[0].startswith(u'Ch'):
|
elif verse_desc_parts[0].startswith(u'Ch'):
|
||||||
verse_type = VerseType.Tags[VerseType.Chorus]
|
verse_type = VerseType.tags[VerseType.Chorus]
|
||||||
elif verse_desc_parts[0].startswith(u'Br'):
|
elif verse_desc_parts[0].startswith(u'Br'):
|
||||||
verse_type = VerseType.Tags[VerseType.Bridge]
|
verse_type = VerseType.tags[VerseType.Bridge]
|
||||||
else:
|
else:
|
||||||
# we need to analyse the next line for
|
# we need to analyse the next line for
|
||||||
# verse type, so set flag
|
# verse type, so set flag
|
||||||
verse_type = VerseType.Tags[VerseType.Other]
|
verse_type = VerseType.tags[VerseType.Other]
|
||||||
check_first_verse_line = True
|
check_first_verse_line = True
|
||||||
verse_number = verse_desc_parts[1]
|
verse_number = verse_desc_parts[1]
|
||||||
else:
|
else:
|
||||||
verse_type = VerseType.Tags[VerseType.Other]
|
verse_type = VerseType.tags[VerseType.Other]
|
||||||
verse_number = 1
|
verse_number = 1
|
||||||
verse_start = True
|
verse_start = True
|
||||||
else:
|
else:
|
||||||
# check first line for verse type
|
# check first line for verse type
|
||||||
if check_first_verse_line:
|
if check_first_verse_line:
|
||||||
if line.startswith(u'(PRE-CHORUS'):
|
if line.startswith(u'(PRE-CHORUS'):
|
||||||
verse_type = VerseType.Tags[VerseType.PreChorus]
|
verse_type = VerseType.tags[VerseType.PreChorus]
|
||||||
elif line.startswith(u'(BRIDGE'):
|
elif line.startswith(u'(BRIDGE'):
|
||||||
verse_type = VerseType.Tags[VerseType.Bridge]
|
verse_type = VerseType.tags[VerseType.Bridge]
|
||||||
# Handle all other misc types
|
# Handle all other misc types
|
||||||
elif line.startswith(u'('):
|
elif line.startswith(u'('):
|
||||||
verse_type = VerseType.Tags[VerseType.Other]
|
verse_type = VerseType.tags[VerseType.Other]
|
||||||
else:
|
else:
|
||||||
verse_text = verse_text + line
|
verse_text = verse_text + line
|
||||||
check_first_verse_line = False
|
check_first_verse_line = False
|
||||||
|
@ -175,12 +175,12 @@ class EasySlidesImport(SongImport):
|
|||||||
# if the regions are inside verses
|
# if the regions are inside verses
|
||||||
regionsInVerses = (regions and regionlines[regionlines.keys()[0]] > 1)
|
regionsInVerses = (regions and regionlines[regionlines.keys()[0]] > 1)
|
||||||
MarkTypes = {
|
MarkTypes = {
|
||||||
u'CHORUS': VerseType.Tags[VerseType.Chorus],
|
u'CHORUS': VerseType.tags[VerseType.Chorus],
|
||||||
u'VERSE': VerseType.Tags[VerseType.Verse],
|
u'VERSE': VerseType.tags[VerseType.Verse],
|
||||||
u'INTRO': VerseType.Tags[VerseType.Intro],
|
u'INTRO': VerseType.tags[VerseType.Intro],
|
||||||
u'ENDING': VerseType.Tags[VerseType.Ending],
|
u'ENDING': VerseType.tags[VerseType.Ending],
|
||||||
u'BRIDGE': VerseType.Tags[VerseType.Bridge],
|
u'BRIDGE': VerseType.tags[VerseType.Bridge],
|
||||||
u'PRECHORUS': VerseType.Tags[VerseType.PreChorus]
|
u'PRECHORUS': VerseType.tags[VerseType.PreChorus]
|
||||||
}
|
}
|
||||||
verses = {}
|
verses = {}
|
||||||
# list as [region, versetype, versenum, instance]
|
# list as [region, versetype, versenum, instance]
|
||||||
|
@ -178,7 +178,7 @@ class EasyWorshipSongImport(SongImport):
|
|||||||
if result is None:
|
if result is None:
|
||||||
return
|
return
|
||||||
words, self.encoding = result
|
words, self.encoding = result
|
||||||
verse_type = VerseType.Tags[VerseType.Verse]
|
verse_type = VerseType.tags[VerseType.Verse]
|
||||||
for verse in SLIDE_BREAK_REGEX.split(words):
|
for verse in SLIDE_BREAK_REGEX.split(words):
|
||||||
verse = verse.strip()
|
verse = verse.strip()
|
||||||
if not verse:
|
if not verse:
|
||||||
@ -187,17 +187,17 @@ class EasyWorshipSongImport(SongImport):
|
|||||||
first_line_is_tag = False
|
first_line_is_tag = False
|
||||||
# EW tags: verse, chorus, pre-chorus, bridge, tag,
|
# EW tags: verse, chorus, pre-chorus, bridge, tag,
|
||||||
# intro, ending, slide
|
# intro, ending, slide
|
||||||
for type in VerseType.Names+[u'tag', u'slide']:
|
for tag in VerseType.tags + [u'tag', u'slide']:
|
||||||
type = type.lower()
|
tag = tag.lower()
|
||||||
ew_tag = verse_split[0].strip().lower()
|
ew_tag = verse_split[0].strip().lower()
|
||||||
if ew_tag.startswith(type):
|
if ew_tag.startswith(tag):
|
||||||
verse_type = type[0]
|
verse_type = tag[0]
|
||||||
if type == u'tag' or type == u'slide':
|
if tag == u'tag' or tag == u'slide':
|
||||||
verse_type = VerseType.Tags[VerseType.Other]
|
verse_type = VerseType.tags[VerseType.Other]
|
||||||
first_line_is_tag = True
|
first_line_is_tag = True
|
||||||
number_found = False
|
number_found = False
|
||||||
# check if tag is followed by number and/or note
|
# check if tag is followed by number and/or note
|
||||||
if len(ew_tag) > len(type):
|
if len(ew_tag) > len(tag):
|
||||||
match = NUMBER_REGEX.search(ew_tag)
|
match = NUMBER_REGEX.search(ew_tag)
|
||||||
if match:
|
if match:
|
||||||
number = match.group()
|
number = match.group()
|
||||||
@ -209,10 +209,7 @@ class EasyWorshipSongImport(SongImport):
|
|||||||
if not number_found:
|
if not number_found:
|
||||||
verse_type += u'1'
|
verse_type += u'1'
|
||||||
break
|
break
|
||||||
self.addVerse(
|
self.addVerse(verse_split[-1].strip() if first_line_is_tag else verse, verse_type)
|
||||||
verse_split[-1].strip() \
|
|
||||||
if first_line_is_tag else verse,
|
|
||||||
verse_type)
|
|
||||||
if len(self.comments) > 5:
|
if len(self.comments) > 5:
|
||||||
self.comments += unicode(translate('SongsPlugin.EasyWorshipSongImport',
|
self.comments += unicode(translate('SongsPlugin.EasyWorshipSongImport',
|
||||||
'\n[above are Song Tags with notes imported from EasyWorship]'))
|
'\n[above are Song Tags with notes imported from EasyWorship]'))
|
||||||
@ -224,8 +221,7 @@ class EasyWorshipSongImport(SongImport):
|
|||||||
self.memoFile.close()
|
self.memoFile.close()
|
||||||
|
|
||||||
def findField(self, field_name):
|
def findField(self, field_name):
|
||||||
return [i for i, x in enumerate(self.fieldDescs)
|
return [i for i, x in enumerate(self.fieldDescs) if x.name == field_name][0]
|
||||||
if x.name == field_name][0]
|
|
||||||
|
|
||||||
def setRecordStruct(self, field_descs):
|
def setRecordStruct(self, field_descs):
|
||||||
# Begin with empty field struct list
|
# Begin with empty field struct list
|
||||||
|
@ -412,13 +412,13 @@ class FoilPresenter(object):
|
|||||||
temp_sortnr_backup = 1
|
temp_sortnr_backup = 1
|
||||||
temp_sortnr_liste = []
|
temp_sortnr_liste = []
|
||||||
verse_count = {
|
verse_count = {
|
||||||
VerseType.Tags[VerseType.Verse]: 1,
|
VerseType.tags[VerseType.Verse]: 1,
|
||||||
VerseType.Tags[VerseType.Chorus]: 1,
|
VerseType.tags[VerseType.Chorus]: 1,
|
||||||
VerseType.Tags[VerseType.Bridge]: 1,
|
VerseType.tags[VerseType.Bridge]: 1,
|
||||||
VerseType.Tags[VerseType.Ending]: 1,
|
VerseType.tags[VerseType.Ending]: 1,
|
||||||
VerseType.Tags[VerseType.Other]: 1,
|
VerseType.tags[VerseType.Other]: 1,
|
||||||
VerseType.Tags[VerseType.Intro]: 1,
|
VerseType.tags[VerseType.Intro]: 1,
|
||||||
VerseType.Tags[VerseType.PreChorus]: 1
|
VerseType.tags[VerseType.PreChorus]: 1
|
||||||
}
|
}
|
||||||
for strophe in foilpresenterfolie.strophen.strophe:
|
for strophe in foilpresenterfolie.strophen.strophe:
|
||||||
text = self._child(strophe.text_) if hasattr(strophe, u'text_') else u''
|
text = self._child(strophe.text_) if hasattr(strophe, u'text_') else u''
|
||||||
@ -438,25 +438,25 @@ class FoilPresenter(object):
|
|||||||
temp_verse_name = re.compile(u'[0-9].*').sub(u'', verse_name)
|
temp_verse_name = re.compile(u'[0-9].*').sub(u'', verse_name)
|
||||||
temp_verse_name = temp_verse_name[:3].lower()
|
temp_verse_name = temp_verse_name[:3].lower()
|
||||||
if temp_verse_name == u'ref':
|
if temp_verse_name == u'ref':
|
||||||
verse_type = VerseType.Tags[VerseType.Chorus]
|
verse_type = VerseType.tags[VerseType.Chorus]
|
||||||
elif temp_verse_name == u'r':
|
elif temp_verse_name == u'r':
|
||||||
verse_type = VerseType.Tags[VerseType.Chorus]
|
verse_type = VerseType.tags[VerseType.Chorus]
|
||||||
elif temp_verse_name == u'':
|
elif temp_verse_name == u'':
|
||||||
verse_type = VerseType.Tags[VerseType.Verse]
|
verse_type = VerseType.tags[VerseType.Verse]
|
||||||
elif temp_verse_name == u'v':
|
elif temp_verse_name == u'v':
|
||||||
verse_type = VerseType.Tags[VerseType.Verse]
|
verse_type = VerseType.tags[VerseType.Verse]
|
||||||
elif temp_verse_name == u'bri':
|
elif temp_verse_name == u'bri':
|
||||||
verse_type = VerseType.Tags[VerseType.Bridge]
|
verse_type = VerseType.tags[VerseType.Bridge]
|
||||||
elif temp_verse_name == u'cod':
|
elif temp_verse_name == u'cod':
|
||||||
verse_type = VerseType.Tags[VerseType.Ending]
|
verse_type = VerseType.tags[VerseType.Ending]
|
||||||
elif temp_verse_name == u'sch':
|
elif temp_verse_name == u'sch':
|
||||||
verse_type = VerseType.Tags[VerseType.Ending]
|
verse_type = VerseType.tags[VerseType.Ending]
|
||||||
elif temp_verse_name == u'pre':
|
elif temp_verse_name == u'pre':
|
||||||
verse_type = VerseType.Tags[VerseType.PreChorus]
|
verse_type = VerseType.tags[VerseType.PreChorus]
|
||||||
elif temp_verse_name == u'int':
|
elif temp_verse_name == u'int':
|
||||||
verse_type = VerseType.Tags[VerseType.Intro]
|
verse_type = VerseType.tags[VerseType.Intro]
|
||||||
else:
|
else:
|
||||||
verse_type = VerseType.Tags[VerseType.Other]
|
verse_type = VerseType.tags[VerseType.Other]
|
||||||
verse_number = re.compile(u'[a-zA-Z.+-_ ]*').sub(u'', verse_name)
|
verse_number = re.compile(u'[a-zA-Z.+-_ ]*').sub(u'', verse_name)
|
||||||
# Foilpresenter allows e. g. "C", but we need "C1".
|
# Foilpresenter allows e. g. "C", but we need "C1".
|
||||||
if not verse_number:
|
if not verse_number:
|
||||||
@ -469,7 +469,7 @@ class FoilPresenter(object):
|
|||||||
if value == u''.join((verse_type, verse_number)):
|
if value == u''.join((verse_type, verse_number)):
|
||||||
verse_number = unicode(int(verse_number) + 1)
|
verse_number = unicode(int(verse_number) + 1)
|
||||||
verse_type_index = VerseType.from_tag(verse_type[0])
|
verse_type_index = VerseType.from_tag(verse_type[0])
|
||||||
verse_type = VerseType.Names[verse_type_index]
|
verse_type = VerseType.tags[verse_type_index]
|
||||||
temp_verse_order[verse_sortnr] = u''.join((verse_type[0],
|
temp_verse_order[verse_sortnr] = u''.join((verse_type[0],
|
||||||
verse_number))
|
verse_number))
|
||||||
temp_verse_order_backup.append(u''.join((verse_type[0],
|
temp_verse_order_backup.append(u''.join((verse_type[0],
|
||||||
|
@ -430,7 +430,7 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
verse_index = VerseType.from_string(verse_tag, None)
|
verse_index = VerseType.from_string(verse_tag, None)
|
||||||
if verse_index is None:
|
if verse_index is None:
|
||||||
verse_index = VerseType.from_tag(verse_tag)
|
verse_index = VerseType.from_tag(verse_tag)
|
||||||
verse_tag = VerseType.TranslatedTags[verse_index].upper()
|
verse_tag = VerseType.translated_tags[verse_index].upper()
|
||||||
verse_def = u'%s%s' % (verse_tag, verse[0][u'label'])
|
verse_def = u'%s%s' % (verse_tag, verse[0][u'label'])
|
||||||
service_item.add_from_text(unicode(verse[1]), verse_def)
|
service_item.add_from_text(unicode(verse[1]), verse_def)
|
||||||
else:
|
else:
|
||||||
@ -445,7 +445,7 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
verse_index = VerseType.from_translated_tag(verse[0][u'type'])
|
verse_index = VerseType.from_translated_tag(verse[0][u'type'])
|
||||||
else:
|
else:
|
||||||
verse_index = VerseType.from_tag(verse[0][u'type'])
|
verse_index = VerseType.from_tag(verse[0][u'type'])
|
||||||
verse_tag = VerseType.TranslatedTags[verse_index]
|
verse_tag = VerseType.translated_tags[verse_index]
|
||||||
verse_def = u'%s%s' % (verse_tag, verse[0][u'label'])
|
verse_def = u'%s%s' % (verse_tag, verse[0][u'label'])
|
||||||
service_item.add_from_text(verse[1], verse_def)
|
service_item.add_from_text(verse[1], verse_def)
|
||||||
else:
|
else:
|
||||||
|
@ -160,7 +160,7 @@ class OpenSongImport(SongImport):
|
|||||||
# keep track of verses appearance order
|
# keep track of verses appearance order
|
||||||
our_verse_order = []
|
our_verse_order = []
|
||||||
# default verse
|
# default verse
|
||||||
verse_tag = VerseType.Tags[VerseType.Verse]
|
verse_tag = VerseType.tags[VerseType.Verse]
|
||||||
verse_num = u'1'
|
verse_num = u'1'
|
||||||
# for the case where song has several sections with same marker
|
# for the case where song has several sections with same marker
|
||||||
inst = 1
|
inst = 1
|
||||||
@ -184,21 +184,18 @@ class OpenSongImport(SongImport):
|
|||||||
# drop the square brackets
|
# drop the square brackets
|
||||||
right_bracket = this_line.find(u']')
|
right_bracket = this_line.find(u']')
|
||||||
content = this_line[1:right_bracket].lower()
|
content = this_line[1:right_bracket].lower()
|
||||||
# have we got any digits?
|
# have we got any digits? If so, verse number is everything from the digits to the end (openlp does not
|
||||||
# If so, verse number is everything from the digits
|
# have concept of part verses, so just ignore any non integers on the end (including floats))
|
||||||
# to the end (openlp does not have concept of part verses, so
|
|
||||||
# just ignore any non integers on the end (including floats))
|
|
||||||
match = re.match(u'(\D*)(\d+)', content)
|
match = re.match(u'(\D*)(\d+)', content)
|
||||||
if match is not None:
|
if match is not None:
|
||||||
verse_tag = match.group(1)
|
verse_tag = match.group(1)
|
||||||
verse_num = match.group(2)
|
verse_num = match.group(2)
|
||||||
else:
|
else:
|
||||||
# otherwise we assume number 1 and take the whole prefix as
|
# otherwise we assume number 1 and take the whole prefix as the verse tag
|
||||||
# the verse tag
|
|
||||||
verse_tag = content
|
verse_tag = content
|
||||||
verse_num = u'1'
|
verse_num = u'1'
|
||||||
verse_index = VerseType.from_loose_input(verse_tag) if verse_tag else 0
|
verse_index = VerseType.from_loose_input(verse_tag) if verse_tag else 0
|
||||||
verse_tag = VerseType.Tags[verse_index]
|
verse_tag = VerseType.tags[verse_index]
|
||||||
inst = 1
|
inst = 1
|
||||||
if [verse_tag, verse_num, inst] in our_verse_order and verse_num in verses.get(verse_tag, {}):
|
if [verse_tag, verse_num, inst] in our_verse_order and verse_num in verses.get(verse_tag, {}):
|
||||||
inst = len(verses[verse_tag][verse_num]) + 1
|
inst = len(verses[verse_tag][verse_num]) + 1
|
||||||
@ -236,8 +233,8 @@ class OpenSongImport(SongImport):
|
|||||||
# figure out the presentation order, if present
|
# figure out the presentation order, if present
|
||||||
if u'presentation' in fields and root.presentation:
|
if u'presentation' in fields and root.presentation:
|
||||||
order = unicode(root.presentation)
|
order = unicode(root.presentation)
|
||||||
# We make all the tags in the lyrics lower case, so match that here
|
# We make all the tags in the lyrics lower case, so match that here and then split into a list on the
|
||||||
# and then split into a list on the whitespace
|
# whitespace.
|
||||||
order = order.lower().split()
|
order = order.lower().split()
|
||||||
for verse_def in order:
|
for verse_def in order:
|
||||||
match = re.match(u'(\D*)(\d+.*)', verse_def)
|
match = re.match(u'(\D*)(\d+.*)', verse_def)
|
||||||
@ -245,7 +242,7 @@ class OpenSongImport(SongImport):
|
|||||||
verse_tag = match.group(1)
|
verse_tag = match.group(1)
|
||||||
verse_num = match.group(2)
|
verse_num = match.group(2)
|
||||||
if not verse_tag:
|
if not verse_tag:
|
||||||
verse_tag = VerseType.Tags[VerseType.Verse]
|
verse_tag = VerseType.tags[VerseType.Verse]
|
||||||
else:
|
else:
|
||||||
# Assume it's no.1 if there are no digits
|
# Assume it's no.1 if there are no digits
|
||||||
verse_tag = verse_def
|
verse_tag = verse_def
|
||||||
|
@ -27,8 +27,7 @@
|
|||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
"""
|
"""
|
||||||
The :mod:`songbeamerimport` module provides the functionality for importing
|
The :mod:`songbeamerimport` module provides the functionality for importing SongBeamer songs into the OpenLP database.
|
||||||
SongBeamer songs into the OpenLP database.
|
|
||||||
"""
|
"""
|
||||||
import chardet
|
import chardet
|
||||||
import codecs
|
import codecs
|
||||||
@ -43,32 +42,31 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
class SongBeamerTypes(object):
|
class SongBeamerTypes(object):
|
||||||
MarkTypes = {
|
MarkTypes = {
|
||||||
u'Refrain': VerseType.Tags[VerseType.Chorus],
|
u'Refrain': VerseType.tags[VerseType.Chorus],
|
||||||
u'Chorus': VerseType.Tags[VerseType.Chorus],
|
u'Chorus': VerseType.tags[VerseType.Chorus],
|
||||||
u'Vers': VerseType.Tags[VerseType.Verse],
|
u'Vers': VerseType.tags[VerseType.Verse],
|
||||||
u'Verse': VerseType.Tags[VerseType.Verse],
|
u'Verse': VerseType.tags[VerseType.Verse],
|
||||||
u'Strophe': VerseType.Tags[VerseType.Verse],
|
u'Strophe': VerseType.tags[VerseType.Verse],
|
||||||
u'Intro': VerseType.Tags[VerseType.Intro],
|
u'Intro': VerseType.tags[VerseType.Intro],
|
||||||
u'Coda': VerseType.Tags[VerseType.Ending],
|
u'Coda': VerseType.tags[VerseType.Ending],
|
||||||
u'Ending': VerseType.Tags[VerseType.Ending],
|
u'Ending': VerseType.tags[VerseType.Ending],
|
||||||
u'Bridge': VerseType.Tags[VerseType.Bridge],
|
u'Bridge': VerseType.tags[VerseType.Bridge],
|
||||||
u'Interlude': VerseType.Tags[VerseType.Bridge],
|
u'Interlude': VerseType.tags[VerseType.Bridge],
|
||||||
u'Zwischenspiel': VerseType.Tags[VerseType.Bridge],
|
u'Zwischenspiel': VerseType.tags[VerseType.Bridge],
|
||||||
u'Pre-Chorus': VerseType.Tags[VerseType.PreChorus],
|
u'Pre-Chorus': VerseType.tags[VerseType.PreChorus],
|
||||||
u'Pre-Refrain': VerseType.Tags[VerseType.PreChorus],
|
u'Pre-Refrain': VerseType.tags[VerseType.PreChorus],
|
||||||
u'Pre-Bridge': VerseType.Tags[VerseType.Other],
|
u'Pre-Bridge': VerseType.tags[VerseType.Other],
|
||||||
u'Pre-Coda': VerseType.Tags[VerseType.Other],
|
u'Pre-Coda': VerseType.tags[VerseType.Other],
|
||||||
u'Unbekannt': VerseType.Tags[VerseType.Other],
|
u'Unbekannt': VerseType.tags[VerseType.Other],
|
||||||
u'Unknown': VerseType.Tags[VerseType.Other],
|
u'Unknown': VerseType.tags[VerseType.Other],
|
||||||
u'Unbenannt': VerseType.Tags[VerseType.Other]
|
u'Unbenannt': VerseType.tags[VerseType.Other]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class SongBeamerImport(SongImport):
|
class SongBeamerImport(SongImport):
|
||||||
"""
|
"""
|
||||||
Import Song Beamer files(s)
|
Import Song Beamer files(s). Song Beamer file format is text based in the beginning are one or more control tags
|
||||||
Song Beamer file format is text based
|
written.
|
||||||
in the beginning are one or more control tags written
|
|
||||||
"""
|
"""
|
||||||
HTML_TAG_PAIRS = [
|
HTML_TAG_PAIRS = [
|
||||||
(re.compile(u'<b>'), u'{st}'),
|
(re.compile(u'<b>'), u'{st}'),
|
||||||
@ -113,7 +111,7 @@ class SongBeamerImport(SongImport):
|
|||||||
return
|
return
|
||||||
self.setDefaults()
|
self.setDefaults()
|
||||||
self.currentVerse = u''
|
self.currentVerse = u''
|
||||||
self.currentVerseType = VerseType.Tags[VerseType.Verse]
|
self.currentVerseType = VerseType.tags[VerseType.Verse]
|
||||||
read_verses = False
|
read_verses = False
|
||||||
file_name = os.path.split(file)[1]
|
file_name = os.path.split(file)[1]
|
||||||
if os.path.isfile(file):
|
if os.path.isfile(file):
|
||||||
@ -137,7 +135,7 @@ class SongBeamerImport(SongImport):
|
|||||||
self.replaceHtmlTags()
|
self.replaceHtmlTags()
|
||||||
self.addVerse(self.currentVerse, self.currentVerseType)
|
self.addVerse(self.currentVerse, self.currentVerseType)
|
||||||
self.currentVerse = u''
|
self.currentVerse = u''
|
||||||
self.currentVerseType = VerseType.Tags[VerseType.Verse]
|
self.currentVerseType = VerseType.tags[VerseType.Verse]
|
||||||
read_verses = True
|
read_verses = True
|
||||||
verse_start = True
|
verse_start = True
|
||||||
elif read_verses:
|
elif read_verses:
|
||||||
@ -155,8 +153,7 @@ class SongBeamerImport(SongImport):
|
|||||||
|
|
||||||
def replaceHtmlTags(self):
|
def replaceHtmlTags(self):
|
||||||
"""
|
"""
|
||||||
This can be called to replace SongBeamer's specific (html) tags with
|
This can be called to replace SongBeamer's specific (html) tags with OpenLP's specific (html) tags.
|
||||||
OpenLP's specific (html) tags.
|
|
||||||
"""
|
"""
|
||||||
for pair in SongBeamerImport.HTML_TAG_PAIRS:
|
for pair in SongBeamerImport.HTML_TAG_PAIRS:
|
||||||
self.currentVerse = pair[0].sub(pair[1], self.currentVerse)
|
self.currentVerse = pair[0].sub(pair[1], self.currentVerse)
|
||||||
@ -166,8 +163,7 @@ class SongBeamerImport(SongImport):
|
|||||||
Parses a meta data line.
|
Parses a meta data line.
|
||||||
|
|
||||||
``line``
|
``line``
|
||||||
The line in the file. It should consist of a tag and a value
|
The line in the file. It should consist of a tag and a value for this tag (unicode)::
|
||||||
for this tag (unicode)::
|
|
||||||
|
|
||||||
u'#Title=Nearer my God to Thee'
|
u'#Title=Nearer my God to Thee'
|
||||||
"""
|
"""
|
||||||
@ -272,8 +268,8 @@ class SongBeamerImport(SongImport):
|
|||||||
|
|
||||||
def checkVerseMarks(self, line):
|
def checkVerseMarks(self, line):
|
||||||
"""
|
"""
|
||||||
Check and add the verse's MarkType. Returns ``True`` if the given line
|
Check and add the verse's MarkType. Returns ``True`` if the given linE contains a correct verse mark otherwise
|
||||||
contains a correct verse mark otherwise ``False``.
|
``False``.
|
||||||
|
|
||||||
``line``
|
``line``
|
||||||
The line to check for marks (unicode).
|
The line to check for marks (unicode).
|
||||||
|
@ -303,13 +303,13 @@ class SongImport(QtCore.QObject):
|
|||||||
sxml = SongXML()
|
sxml = SongXML()
|
||||||
other_count = 1
|
other_count = 1
|
||||||
for (verse_def, verse_text, lang) in self.verses:
|
for (verse_def, verse_text, lang) in self.verses:
|
||||||
if verse_def[0].lower() in VerseType.Tags:
|
if verse_def[0].lower() in VerseType.tags:
|
||||||
verse_tag = verse_def[0].lower()
|
verse_tag = verse_def[0].lower()
|
||||||
else:
|
else:
|
||||||
new_verse_def = u'%s%d' % (VerseType.Tags[VerseType.Other], other_count)
|
new_verse_def = u'%s%d' % (VerseType.tags[VerseType.Other], other_count)
|
||||||
verses_changed_to_other[verse_def] = new_verse_def
|
verses_changed_to_other[verse_def] = new_verse_def
|
||||||
other_count += 1
|
other_count += 1
|
||||||
verse_tag = VerseType.Tags[VerseType.Other]
|
verse_tag = VerseType.tags[VerseType.Other]
|
||||||
log.info(u'Versetype %s changing to %s', verse_def, new_verse_def)
|
log.info(u'Versetype %s changing to %s', verse_def, new_verse_def)
|
||||||
verse_def = new_verse_def
|
verse_def = new_verse_def
|
||||||
sxml.add_verse_to_lyrics(verse_tag, verse_def[1:], verse_text, lang)
|
sxml.add_verse_to_lyrics(verse_tag, verse_def[1:], verse_text, lang)
|
||||||
|
@ -152,11 +152,11 @@ class SongShowPlusImport(SongImport):
|
|||||||
elif block_key == CCLI_NO:
|
elif block_key == CCLI_NO:
|
||||||
self.ccliNumber = int(data)
|
self.ccliNumber = int(data)
|
||||||
elif block_key == VERSE:
|
elif block_key == VERSE:
|
||||||
self.addVerse(unicode(data, u'cp1252'), "%s%s" % (VerseType.Tags[VerseType.Verse], verse_no))
|
self.addVerse(unicode(data, u'cp1252'), "%s%s" % (VerseType.tags[VerseType.Verse], verse_no))
|
||||||
elif block_key == CHORUS:
|
elif block_key == CHORUS:
|
||||||
self.addVerse(unicode(data, u'cp1252'), "%s%s" % (VerseType.Tags[VerseType.Chorus], verse_no))
|
self.addVerse(unicode(data, u'cp1252'), "%s%s" % (VerseType.tags[VerseType.Chorus], verse_no))
|
||||||
elif block_key == BRIDGE:
|
elif block_key == BRIDGE:
|
||||||
self.addVerse(unicode(data, u'cp1252'), "%s%s" % (VerseType.Tags[VerseType.Bridge], verse_no))
|
self.addVerse(unicode(data, u'cp1252'), "%s%s" % (VerseType.tags[VerseType.Bridge], verse_no))
|
||||||
elif block_key == TOPIC:
|
elif block_key == TOPIC:
|
||||||
self.topics.append(unicode(data, u'cp1252'))
|
self.topics.append(unicode(data, u'cp1252'))
|
||||||
elif block_key == COMMENTS:
|
elif block_key == COMMENTS:
|
||||||
@ -192,19 +192,19 @@ class SongShowPlusImport(SongImport):
|
|||||||
verse_number = "1"
|
verse_number = "1"
|
||||||
verse_type = verse_type.lower()
|
verse_type = verse_type.lower()
|
||||||
if verse_type == "verse":
|
if verse_type == "verse":
|
||||||
verse_tag = VerseType.Tags[VerseType.Verse]
|
verse_tag = VerseType.tags[VerseType.Verse]
|
||||||
elif verse_type == "chorus":
|
elif verse_type == "chorus":
|
||||||
verse_tag = VerseType.Tags[VerseType.Chorus]
|
verse_tag = VerseType.tags[VerseType.Chorus]
|
||||||
elif verse_type == "bridge":
|
elif verse_type == "bridge":
|
||||||
verse_tag = VerseType.Tags[VerseType.Bridge]
|
verse_tag = VerseType.tags[VerseType.Bridge]
|
||||||
elif verse_type == "pre-chorus":
|
elif verse_type == "pre-chorus":
|
||||||
verse_tag = VerseType.Tags[VerseType.PreChorus]
|
verse_tag = VerseType.tags[VerseType.PreChorus]
|
||||||
else:
|
else:
|
||||||
if verse_name not in self.otherList:
|
if verse_name not in self.otherList:
|
||||||
if ignore_unique:
|
if ignore_unique:
|
||||||
return None
|
return None
|
||||||
self.otherCount += 1
|
self.otherCount += 1
|
||||||
self.otherList[verse_name] = str(self.otherCount)
|
self.otherList[verse_name] = str(self.otherCount)
|
||||||
verse_tag = VerseType.Tags[VerseType.Other]
|
verse_tag = VerseType.tags[VerseType.Other]
|
||||||
verse_number = self.otherList[verse_name]
|
verse_number = self.otherList[verse_name]
|
||||||
return verse_tag + verse_number
|
return verse_tag + verse_number
|
||||||
|
@ -52,8 +52,7 @@ class SundayPlusImport(SongImport):
|
|||||||
"""
|
"""
|
||||||
Import Sunday Plus songs
|
Import Sunday Plus songs
|
||||||
|
|
||||||
The format examples can be found attached to bug report at
|
The format examples can be found attached to bug report at <http://support.openlp.org/issues/395>
|
||||||
<http://support.openlp.org/issues/395>
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, manager, **kwargs):
|
def __init__(self, manager, **kwargs):
|
||||||
@ -90,7 +89,7 @@ class SundayPlusImport(SongImport):
|
|||||||
self.logError(u'File is malformed')
|
self.logError(u'File is malformed')
|
||||||
return False
|
return False
|
||||||
i = 1
|
i = 1
|
||||||
verse_type = VerseType.Tags[VerseType.Verse]
|
verse_type = VerseType.tags[VerseType.Verse]
|
||||||
while i < len(data):
|
while i < len(data):
|
||||||
# Data is held as #name: value pairs inside groups marked as [].
|
# Data is held as #name: value pairs inside groups marked as [].
|
||||||
# Now we are looking for the name.
|
# Now we are looking for the name.
|
||||||
@ -137,8 +136,7 @@ class SundayPlusImport(SongImport):
|
|||||||
if name == 'MARKER_NAME':
|
if name == 'MARKER_NAME':
|
||||||
value = value.strip()
|
value = value.strip()
|
||||||
if len(value):
|
if len(value):
|
||||||
verse_type = VerseType.Tags[
|
verse_type = VerseType.tags[VerseType.from_loose_input(value[0])]
|
||||||
VerseType.from_loose_input(value[0])]
|
|
||||||
if len(value) >= 2 and value[-1] in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']:
|
if len(value) >= 2 and value[-1] in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']:
|
||||||
verse_type = "%s%s" % (verse_type, value[-1])
|
verse_type = "%s%s" % (verse_type, value[-1])
|
||||||
elif name == 'Hotkey':
|
elif name == 'Hotkey':
|
||||||
@ -168,8 +166,7 @@ class SundayPlusImport(SongImport):
|
|||||||
self.copyright = u'Public Domain'
|
self.copyright = u'Public Domain'
|
||||||
continue
|
continue
|
||||||
processed_lines.append(line)
|
processed_lines.append(line)
|
||||||
self.addVerse('\n'.join(processed_lines).strip(),
|
self.addVerse('\n'.join(processed_lines).strip(), verse_type)
|
||||||
verse_type)
|
|
||||||
if end == -1:
|
if end == -1:
|
||||||
break
|
break
|
||||||
i = end + 1
|
i = end + 1
|
||||||
|
@ -97,10 +97,8 @@ class SongXML(object):
|
|||||||
Add a verse to the ``<lyrics>`` tag.
|
Add a verse to the ``<lyrics>`` tag.
|
||||||
|
|
||||||
``type``
|
``type``
|
||||||
A string denoting the type of verse. Possible values are *v*,
|
A string denoting the type of verse. Possible values are *v*, *c*, *b*, *p*, *i*, *e* and *o*. Any other
|
||||||
*c*, *b*, *p*, *i*, *e* and *o*.
|
type is **not** allowed, this also includes translated types.
|
||||||
Any other type is **not** allowed, this also includes translated
|
|
||||||
types.
|
|
||||||
|
|
||||||
``number``
|
``number``
|
||||||
An integer denoting the number of the item, for example: verse 1.
|
An integer denoting the number of the item, for example: verse 1.
|
||||||
@ -109,8 +107,7 @@ class SongXML(object):
|
|||||||
The actual text of the verse to be stored.
|
The actual text of the verse to be stored.
|
||||||
|
|
||||||
``lang``
|
``lang``
|
||||||
The verse's language code (ISO-639). This is not required, but
|
The verse's language code (ISO-639). This is not required, but should be added if available.
|
||||||
should be added if available.
|
|
||||||
"""
|
"""
|
||||||
verse = etree.Element(u'verse', type=unicode(type),
|
verse = etree.Element(u'verse', type=unicode(type),
|
||||||
label=unicode(number))
|
label=unicode(number))
|
||||||
@ -128,24 +125,21 @@ class SongXML(object):
|
|||||||
|
|
||||||
def get_verses(self, xml):
|
def get_verses(self, xml):
|
||||||
"""
|
"""
|
||||||
Iterates through the verses in the XML and returns a list of verses
|
Iterates through the verses in the XML and returns a list of verses and their attributes.
|
||||||
and their attributes.
|
|
||||||
|
|
||||||
``xml``
|
``xml``
|
||||||
The XML of the song to be parsed.
|
The XML of the song to be parsed.
|
||||||
|
|
||||||
The returned list has the following format::
|
The returned list has the following format::
|
||||||
|
|
||||||
[[{'type': 'v', 'label': '1'},
|
[[{'type': 'v', 'label': '1'}, u"optional slide split 1[---]optional slide split 2"],
|
||||||
u"optional slide split 1[---]optional slide split 2"],
|
|
||||||
[{'lang': 'en', 'type': 'c', 'label': '1'}, u"English chorus"]]
|
[{'lang': 'en', 'type': 'c', 'label': '1'}, u"English chorus"]]
|
||||||
"""
|
"""
|
||||||
self.song_xml = None
|
self.song_xml = None
|
||||||
verse_list = []
|
verse_list = []
|
||||||
if not xml.startswith(u'<?xml') and not xml.startswith(u'<song'):
|
if not xml.startswith(u'<?xml') and not xml.startswith(u'<song'):
|
||||||
# This is an old style song, without XML. Let's handle it correctly
|
# This is an old style song, without XML. Let's handle it correctly by iterating through the verses, and
|
||||||
# by iterating through the verses, and then recreating the internal
|
# then recreating the internal xml object as well.
|
||||||
# xml object as well.
|
|
||||||
self.song_xml = objectify.fromstring(u'<song version="1.0" />')
|
self.song_xml = objectify.fromstring(u'<song version="1.0" />')
|
||||||
self.lyrics = etree.SubElement(self.song_xml, u'lyrics')
|
self.lyrics = etree.SubElement(self.song_xml, u'lyrics')
|
||||||
verses = xml.split(u'\n\n')
|
verses = xml.split(u'\n\n')
|
||||||
@ -176,11 +170,10 @@ class SongXML(object):
|
|||||||
|
|
||||||
class OpenLyrics(object):
|
class OpenLyrics(object):
|
||||||
"""
|
"""
|
||||||
This class represents the converter for OpenLyrics XML (version 0.8)
|
This class represents the converter for OpenLyrics XML (version 0.8) to/from a song.
|
||||||
to/from a song.
|
|
||||||
|
|
||||||
As OpenLyrics has a rich set of different features, we cannot support them
|
As OpenLyrics has a rich set of different features, we cannot support them all. The following features are
|
||||||
all. The following features are supported by the :class:`OpenLyrics` class:
|
supported by the :class:`OpenLyrics` class:
|
||||||
|
|
||||||
``<authors>``
|
``<authors>``
|
||||||
OpenLP does not support the attribute *type* and *lang*.
|
OpenLP does not support the attribute *type* and *lang*.
|
||||||
@ -189,8 +182,7 @@ class OpenLyrics(object):
|
|||||||
This property is not supported.
|
This property is not supported.
|
||||||
|
|
||||||
``<comments>``
|
``<comments>``
|
||||||
The ``<comments>`` property is fully supported. But comments in lyrics
|
The ``<comments>`` property is fully supported. But comments in lyrics are not supported.
|
||||||
are not supported.
|
|
||||||
|
|
||||||
``<copyright>``
|
``<copyright>``
|
||||||
This property is fully supported.
|
This property is fully supported.
|
||||||
@ -208,23 +200,20 @@ class OpenLyrics(object):
|
|||||||
This property is not supported.
|
This property is not supported.
|
||||||
|
|
||||||
``<lines>``
|
``<lines>``
|
||||||
The attribute *part* is not supported. The *break* attribute is
|
The attribute *part* is not supported. The *break* attribute is supported.
|
||||||
supported.
|
|
||||||
|
|
||||||
``<publisher>``
|
``<publisher>``
|
||||||
This property is not supported.
|
This property is not supported.
|
||||||
|
|
||||||
``<songbooks>``
|
``<songbooks>``
|
||||||
As OpenLP does only support one songbook, we cannot consider more than
|
As OpenLP does only support one songbook, we cannot consider more than one songbook.
|
||||||
one songbook.
|
|
||||||
|
|
||||||
``<tempo>``
|
``<tempo>``
|
||||||
This property is not supported.
|
This property is not supported.
|
||||||
|
|
||||||
``<themes>``
|
``<themes>``
|
||||||
Topics, as they are called in OpenLP, are fully supported, whereby only
|
Topics, as they are called in OpenLP, are fully supported, whereby only the topic text (e. g. Grace) is
|
||||||
the topic text (e. g. Grace) is considered, but neither the *id* nor
|
considered, but neither the *id* nor *lang*.
|
||||||
*lang*.
|
|
||||||
|
|
||||||
``<transposition>``
|
``<transposition>``
|
||||||
This property is not supported.
|
This property is not supported.
|
||||||
@ -233,9 +222,8 @@ class OpenLyrics(object):
|
|||||||
This property is not supported.
|
This property is not supported.
|
||||||
|
|
||||||
``<verse name="v1a" lang="he" translit="en">``
|
``<verse name="v1a" lang="he" translit="en">``
|
||||||
The attribute *translit* is not supported. Note, the attribute *lang* is
|
The attribute *translit* is not supported. Note, the attribute *lang* is considered, but there is not further
|
||||||
considered, but there is not further functionality implemented yet. The
|
functionality implemented yet. The following verse "types" are supported by OpenLP:
|
||||||
following verse "types" are supported by OpenLP:
|
|
||||||
|
|
||||||
* v
|
* v
|
||||||
* c
|
* c
|
||||||
@ -245,13 +233,10 @@ class OpenLyrics(object):
|
|||||||
* e
|
* e
|
||||||
* o
|
* o
|
||||||
|
|
||||||
The verse "types" stand for *Verse*, *Chorus*, *Bridge*, *Pre-Chorus*,
|
The verse "types" stand for *Verse*, *Chorus*, *Bridge*, *Pre-Chorus*, *Intro*, *Ending* and *Other*. Any
|
||||||
*Intro*, *Ending* and *Other*. Any numeric value is allowed after the
|
numeric value is allowed after the verse type. The complete verse name in OpenLP always consists of the verse
|
||||||
verse type. The complete verse name in OpenLP always consists of the
|
type and the verse number. If not number is present *1* is assumed. OpenLP will merge verses which are split
|
||||||
verse type and the verse number. If not number is present *1* is
|
up by appending a letter to the verse name, such as *v1a*.
|
||||||
assumed.
|
|
||||||
OpenLP will merge verses which are split up by appending a letter to the
|
|
||||||
verse name, such as *v1a*.
|
|
||||||
|
|
||||||
``<verseOrder>``
|
``<verseOrder>``
|
||||||
OpenLP supports this property.
|
OpenLP supports this property.
|
||||||
@ -359,17 +344,14 @@ class OpenLyrics(object):
|
|||||||
|
|
||||||
def _get_missing_tags(self, text):
|
def _get_missing_tags(self, text):
|
||||||
"""
|
"""
|
||||||
Tests the given text for not closed formatting tags and returns a tuple
|
Tests the given text for not closed formatting tags and returns a tuple consisting of two unicode strings::
|
||||||
consisting of two unicode strings::
|
|
||||||
|
|
||||||
(u'{st}{r}', u'{/r}{/st}')
|
(u'{st}{r}', u'{/r}{/st}')
|
||||||
|
|
||||||
The first unicode string are the start tags (for the next slide). The
|
The first unicode string are the start tags (for the next slide). The second unicode string are the end tags.
|
||||||
second unicode string are the end tags.
|
|
||||||
|
|
||||||
``text``
|
``text``
|
||||||
The text to test. The text must **not** contain html tags, only
|
The text to test. The text must **not** contain html tags, only OpenLP formatting tags are allowed::
|
||||||
OpenLP formatting tags are allowed::
|
|
||||||
|
|
||||||
{st}{r}Text text text
|
{st}{r}Text text text
|
||||||
"""
|
"""
|
||||||
@ -379,9 +361,8 @@ class OpenLyrics(object):
|
|||||||
continue
|
continue
|
||||||
if text.count(tag[u'start tag']) != text.count(tag[u'end tag']):
|
if text.count(tag[u'start tag']) != text.count(tag[u'end tag']):
|
||||||
tags.append((text.find(tag[u'start tag']), tag[u'start tag'], tag[u'end tag']))
|
tags.append((text.find(tag[u'start tag']), tag[u'start tag'], tag[u'end tag']))
|
||||||
# Sort the lists, so that the tags which were opened first on the first
|
# Sort the lists, so that the tags which were opened first on the first slide (the text we are checking) will
|
||||||
# slide (the text we are checking) will be opened first on the next
|
# be opened first on the next slide as well.
|
||||||
# slide as well.
|
|
||||||
tags.sort(key=lambda tag: tag[0])
|
tags.sort(key=lambda tag: tag[0])
|
||||||
end_tags = []
|
end_tags = []
|
||||||
start_tags = []
|
start_tags = []
|
||||||
@ -393,16 +374,15 @@ class OpenLyrics(object):
|
|||||||
|
|
||||||
def xml_to_song(self, xml, parse_and_temporary_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
|
Create and save a song from OpenLyrics format xml to the database. Since we also export XML from external
|
||||||
we also export XML from external sources (e. g. OpenLyrics import), we
|
sources (e. g. OpenLyrics import), we cannot ensure, that it completely conforms to the OpenLyrics standard.
|
||||||
cannot ensure, that it completely conforms to the OpenLyrics standard.
|
|
||||||
|
|
||||||
``xml``
|
``xml``
|
||||||
The XML to parse (unicode).
|
The XML to parse (unicode).
|
||||||
|
|
||||||
``parse_and_temporary_save``
|
``parse_and_temporary_save``
|
||||||
Switch to skip processing the whole song and storing the songs in
|
Switch to skip processing the whole song and storing the songs in the database with a temporary flag.
|
||||||
the database with a temporary flag. Defaults to ``False``.
|
Defaults to ``False``.
|
||||||
"""
|
"""
|
||||||
# No xml get out of here.
|
# No xml get out of here.
|
||||||
if not xml:
|
if not xml:
|
||||||
@ -448,8 +428,7 @@ class OpenLyrics(object):
|
|||||||
|
|
||||||
def _add_tag_to_formatting(self, tag_name, tags_element):
|
def _add_tag_to_formatting(self, tag_name, tags_element):
|
||||||
"""
|
"""
|
||||||
Add new formatting tag to the element ``<format>`` if the tag is not
|
Add new formatting tag to the element ``<format>`` if the tag is not present yet.
|
||||||
present yet.
|
|
||||||
"""
|
"""
|
||||||
available_tags = FormattingTags.get_html_tags()
|
available_tags = FormattingTags.get_html_tags()
|
||||||
start_tag = '{%s}' % tag_name
|
start_tag = '{%s}' % tag_name
|
||||||
@ -469,8 +448,7 @@ class OpenLyrics(object):
|
|||||||
|
|
||||||
def _add_text_with_tags_to_lines(self, verse_element, text, tags_element):
|
def _add_text_with_tags_to_lines(self, verse_element, text, tags_element):
|
||||||
"""
|
"""
|
||||||
Convert text with formatting tags from OpenLP format to OpenLyrics
|
Convert text with formatting tags from OpenLP format to OpenLyrics format and append it to element ``<lines>``.
|
||||||
format and append it to element ``<lines>``.
|
|
||||||
"""
|
"""
|
||||||
start_tags = OpenLyrics.START_TAGS_REGEX.findall(text)
|
start_tags = OpenLyrics.START_TAGS_REGEX.findall(text)
|
||||||
end_tags = OpenLyrics.END_TAGS_REGEX.findall(text)
|
end_tags = OpenLyrics.END_TAGS_REGEX.findall(text)
|
||||||
@ -478,8 +456,7 @@ class OpenLyrics(object):
|
|||||||
for tag in start_tags:
|
for tag in start_tags:
|
||||||
# Tags already converted to xml structure.
|
# Tags already converted to xml structure.
|
||||||
xml_tags = tags_element.xpath(u'tag/attribute::name')
|
xml_tags = tags_element.xpath(u'tag/attribute::name')
|
||||||
# Some formatting tag has only starting part e.g. <br>.
|
# Some formatting tag has only starting part e.g. <br>. Handle this case.
|
||||||
# Handle this case.
|
|
||||||
if tag in end_tags:
|
if tag in end_tags:
|
||||||
text = text.replace(u'{%s}' % tag, u'<tag name="%s">' % tag)
|
text = text.replace(u'{%s}' % tag, u'<tag name="%s">' % tag)
|
||||||
else:
|
else:
|
||||||
@ -586,8 +563,8 @@ class OpenLyrics(object):
|
|||||||
|
|
||||||
def _process_formatting_tags(self, song_xml, temporary):
|
def _process_formatting_tags(self, song_xml, temporary):
|
||||||
"""
|
"""
|
||||||
Process the formatting tags from the song and either add missing tags
|
Process the formatting tags from the song and either add missing tags temporary or permanently to the
|
||||||
temporary or permanently to the formatting tag list.
|
formatting tag list.
|
||||||
"""
|
"""
|
||||||
if not hasattr(song_xml, u'format'):
|
if not hasattr(song_xml, u'format'):
|
||||||
return
|
return
|
||||||
@ -608,8 +585,8 @@ class OpenLyrics(object):
|
|||||||
u'end html': tag.close.text if hasattr(tag, 'close') else u'',
|
u'end html': tag.close.text if hasattr(tag, 'close') else u'',
|
||||||
u'protected': False,
|
u'protected': False,
|
||||||
}
|
}
|
||||||
# Add 'temporary' key in case the formatting tag should not be
|
# Add 'temporary' key in case the formatting tag should not be saved otherwise it is supposed that
|
||||||
# saved otherwise it is supposed that formatting tag is permanent.
|
# formatting tag is permanent.
|
||||||
if temporary:
|
if temporary:
|
||||||
openlp_tag[u'temporary'] = temporary
|
openlp_tag[u'temporary'] = temporary
|
||||||
found_tags.append(openlp_tag)
|
found_tags.append(openlp_tag)
|
||||||
@ -620,15 +597,14 @@ class OpenLyrics(object):
|
|||||||
|
|
||||||
def _process_lines_mixed_content(self, element, newlines=True):
|
def _process_lines_mixed_content(self, element, newlines=True):
|
||||||
"""
|
"""
|
||||||
Converts the xml text with mixed content to OpenLP representation.
|
Converts the xml text with mixed content to OpenLP representation. Chords are skipped and formatting tags are
|
||||||
Chords are skipped and formatting tags are converted.
|
converted.
|
||||||
|
|
||||||
``element``
|
``element``
|
||||||
The property object (lxml.etree.Element).
|
The property object (lxml.etree.Element).
|
||||||
|
|
||||||
``newlines``
|
``newlines``
|
||||||
The switch to enable/disable processing of line breaks <br/>.
|
The switch to enable/disable processing of line breaks <br/>. The <br/> is used since OpenLyrics 0.8.
|
||||||
The <br/> is used since OpenLyrics 0.8.
|
|
||||||
"""
|
"""
|
||||||
text = u''
|
text = u''
|
||||||
use_endtag = True
|
use_endtag = True
|
||||||
@ -684,12 +660,10 @@ class OpenLyrics(object):
|
|||||||
lines = etree.tostring(lines)
|
lines = etree.tostring(lines)
|
||||||
element = etree.XML(lines)
|
element = etree.XML(lines)
|
||||||
|
|
||||||
# OpenLyrics 0.8 uses <br/> for new lines.
|
# OpenLyrics 0.8 uses <br/> for new lines. Append text from "lines" element to verse text.
|
||||||
# Append text from "lines" element to verse text.
|
|
||||||
if version > '0.7':
|
if version > '0.7':
|
||||||
text = self._process_lines_mixed_content(element)
|
text = self._process_lines_mixed_content(element)
|
||||||
# OpenLyrics version <= 0.7 contais <line> elements to represent lines.
|
# OpenLyrics version <= 0.7 contais <line> elements to represent lines. First child element is tested.
|
||||||
# First child element is tested.
|
|
||||||
else:
|
else:
|
||||||
# Loop over the "line" elements removing comments and chords.
|
# Loop over the "line" elements removing comments and chords.
|
||||||
for line in element:
|
for line in element:
|
||||||
@ -742,16 +716,15 @@ class OpenLyrics(object):
|
|||||||
text += u'\n[---]'
|
text += u'\n[---]'
|
||||||
verse_def = verse.get(u'name', u' ').lower()
|
verse_def = verse.get(u'name', u' ').lower()
|
||||||
verse_tag, verse_number, verse_part = OpenLyrics.VERSE_TAG_SPLITTER.search(verse_def).groups()
|
verse_tag, verse_number, verse_part = OpenLyrics.VERSE_TAG_SPLITTER.search(verse_def).groups()
|
||||||
if verse_tag not in VerseType.Tags:
|
if verse_tag not in VerseType.tags:
|
||||||
verse_tag = VerseType.Tags[VerseType.Other]
|
verse_tag = VerseType.tags[VerseType.Other]
|
||||||
# OpenLyrics allows e. g. "c", but we need "c1". However, this does
|
# OpenLyrics allows e. g. "c", but we need "c1". However, this does not correct the verse order.
|
||||||
# not correct the verse order.
|
|
||||||
if not verse_number:
|
if not verse_number:
|
||||||
verse_number = u'1'
|
verse_number = u'1'
|
||||||
lang = verse.get(u'lang')
|
lang = verse.get(u'lang')
|
||||||
translit = verse.get(u'translit')
|
translit = verse.get(u'translit')
|
||||||
# In OpenLP 1.9.6 we used v1a, v1b ... to represent visual slide
|
# In OpenLP 1.9.6 we used v1a, v1b ... to represent visual slide breaks. In OpenLyrics 0.7 an attribute has
|
||||||
# breaks. In OpenLyrics 0.7 an attribute has been added.
|
# been added.
|
||||||
if song_xml.get(u'modifiedIn') in (u'1.9.6', u'OpenLP 1.9.6') and \
|
if song_xml.get(u'modifiedIn') in (u'1.9.6', u'OpenLP 1.9.6') and \
|
||||||
song_xml.get(u'version') == u'0.7' and (verse_tag, verse_number, lang, translit) in verses:
|
song_xml.get(u'version') == u'0.7' and (verse_tag, verse_number, lang, translit) in verses:
|
||||||
verses[(verse_tag, verse_number, lang, translit, None)] += u'\n[---]\n' + text
|
verses[(verse_tag, verse_number, lang, translit, None)] += u'\n[---]\n' + text
|
||||||
|
@ -176,7 +176,7 @@ class SongsPlugin(Plugin):
|
|||||||
return translate('SongsPlugin', '<strong>Songs Plugin</strong>'
|
return translate('SongsPlugin', '<strong>Songs Plugin</strong>'
|
||||||
'<br />The songs plugin provides the ability to display and manage songs.')
|
'<br />The songs plugin provides the ability to display and manage songs.')
|
||||||
|
|
||||||
def usesTheme(self, theme):
|
def uses_theme(self, theme):
|
||||||
"""
|
"""
|
||||||
Called to find out if the song plugin is currently using a theme.
|
Called to find out if the song plugin is currently using a theme.
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ class SongsPlugin(Plugin):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def renameTheme(self, oldTheme, newTheme):
|
def rename_theme(self, oldTheme, newTheme):
|
||||||
"""
|
"""
|
||||||
Renames a theme the song plugin is using making the plugin use the new
|
Renames a theme the song plugin is using making the plugin use the new
|
||||||
name.
|
name.
|
||||||
@ -209,7 +209,7 @@ class SongsPlugin(Plugin):
|
|||||||
importer.register(self.mediaItem.importWizard)
|
importer.register(self.mediaItem.importWizard)
|
||||||
return importer
|
return importer
|
||||||
|
|
||||||
def setPluginTextStrings(self):
|
def set_plugin_text_strings(self):
|
||||||
"""
|
"""
|
||||||
Called to define all translatable texts of the plugin
|
Called to define all translatable texts of the plugin
|
||||||
"""
|
"""
|
||||||
|
@ -99,7 +99,7 @@ class SongUsagePlugin(Plugin):
|
|||||||
self.song_usage_status = create_action(tools_menu, u'songUsageStatus',
|
self.song_usage_status = create_action(tools_menu, u'songUsageStatus',
|
||||||
text=translate('SongUsagePlugin', 'Toggle Tracking'),
|
text=translate('SongUsagePlugin', 'Toggle Tracking'),
|
||||||
statustip=translate('SongUsagePlugin', 'Toggle the tracking of song usage.'), checked=False,
|
statustip=translate('SongUsagePlugin', 'Toggle the tracking of song usage.'), checked=False,
|
||||||
shortcuts=[QtCore.Qt.Key_F4], triggers=self.toggle_song_usage_state)
|
can_shortcuts=True, triggers=self.toggle_song_usage_state)
|
||||||
# Add Menus together
|
# Add Menus together
|
||||||
self.toolsMenu.addAction(self.song_usage_menu.menuAction())
|
self.toolsMenu.addAction(self.song_usage_menu.menuAction())
|
||||||
self.song_usage_menu.addAction(self.song_usage_status)
|
self.song_usage_menu.addAction(self.song_usage_status)
|
||||||
@ -219,7 +219,7 @@ class SongUsagePlugin(Plugin):
|
|||||||
'</strong><br />This plugin tracks the usage of songs in services.')
|
'</strong><br />This plugin tracks the usage of songs in services.')
|
||||||
return about_text
|
return about_text
|
||||||
|
|
||||||
def setPluginTextStrings(self):
|
def set_plugin_text_strings(self):
|
||||||
"""
|
"""
|
||||||
Called to define all translatable texts of the plugin
|
Called to define all translatable texts of the plugin
|
||||||
"""
|
"""
|
||||||
|
@ -92,6 +92,7 @@ OPTIONAL_MODULES = [
|
|||||||
('MySQLdb', ' (MySQL support)'),
|
('MySQLdb', ' (MySQL support)'),
|
||||||
('psycopg2', ' (PostgreSQL support)'),
|
('psycopg2', ' (PostgreSQL support)'),
|
||||||
('nose', ' (testing framework)'),
|
('nose', ' (testing framework)'),
|
||||||
|
('mock', ' (testing module)'),
|
||||||
]
|
]
|
||||||
|
|
||||||
w = sys.stdout.write
|
w = sys.stdout.write
|
||||||
|
@ -45,8 +45,8 @@ class TestFormattingTags(TestCase):
|
|||||||
FormattingTags.load_tags()
|
FormattingTags.load_tags()
|
||||||
new_tags_list = FormattingTags.get_html_tags()
|
new_tags_list = FormattingTags.get_html_tags()
|
||||||
|
|
||||||
# THEN: Lists should be identically.
|
# THEN: Lists should be identical.
|
||||||
assert old_tags_list == new_tags_list, u'The formatting tag lists should be identically.'
|
assert old_tags_list == new_tags_list, u'The formatting tag lists should be identical.'
|
||||||
|
|
||||||
def get_html_tags_with_user_tags_test(self):
|
def get_html_tags_with_user_tags_test(self):
|
||||||
"""
|
"""
|
||||||
@ -69,16 +69,16 @@ class TestFormattingTags(TestCase):
|
|||||||
FormattingTags.add_html_tags([TAG])
|
FormattingTags.add_html_tags([TAG])
|
||||||
new_tags_list = copy.deepcopy(FormattingTags.get_html_tags())
|
new_tags_list = copy.deepcopy(FormattingTags.get_html_tags())
|
||||||
|
|
||||||
# THEN: Lists should not be identically.
|
# THEN: Lists should not be identical.
|
||||||
assert old_tags_list != new_tags_list, u'The lists should be different.'
|
assert old_tags_list != new_tags_list, u'The lists should be different.'
|
||||||
|
|
||||||
# THEN: Added tag and last tag should be the same.
|
# THEN: Added tag and last tag should be the same.
|
||||||
new_tag = new_tags_list.pop()
|
new_tag = new_tags_list.pop()
|
||||||
assert TAG == new_tag, u'Tags should be identically.'
|
assert TAG == new_tag, u'Tags should be identical.'
|
||||||
|
|
||||||
# WHEN: Remove the new tag.
|
# WHEN: Remove the new tag.
|
||||||
FormattingTags.remove_html_tag(len(new_tags_list))
|
FormattingTags.remove_html_tag(len(new_tags_list))
|
||||||
|
|
||||||
# THEN: The lists should now be identically.
|
# THEN: The lists should now be identical.
|
||||||
assert old_tags_list == FormattingTags.get_html_tags(), u'The lists should be identically.'
|
assert old_tags_list == FormattingTags.get_html_tags(), u'The lists should be identical.'
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ from datetime import datetime, timedelta
|
|||||||
from mock import MagicMock, patch
|
from mock import MagicMock, patch
|
||||||
|
|
||||||
from openlp.core.lib import str_to_bool, translate, check_directory_exists, get_text_file_string, build_icon, \
|
from openlp.core.lib import str_to_bool, translate, check_directory_exists, get_text_file_string, build_icon, \
|
||||||
image_to_byte, check_item_selected, validate_thumb, create_separated_list
|
image_to_byte, check_item_selected, validate_thumb, create_separated_list, expand_tags
|
||||||
|
|
||||||
class TestLib(TestCase):
|
class TestLib(TestCase):
|
||||||
|
|
||||||
@ -299,6 +299,45 @@ class TestLib(TestCase):
|
|||||||
MockedQtGui.QMessageBox.information.assert_called_with(u'parent', u'mocked translate', 'message')
|
MockedQtGui.QMessageBox.information.assert_called_with(u'parent', u'mocked translate', 'message')
|
||||||
assert not result, u'The result should be False'
|
assert not result, u'The result should be False'
|
||||||
|
|
||||||
|
def expand_tags_test(self):
|
||||||
|
"""
|
||||||
|
Test the expand_tags() method.
|
||||||
|
"""
|
||||||
|
with patch(u'openlp.core.lib.FormattingTags.get_html_tags') as mocked_get_tags:
|
||||||
|
# GIVEN: Mocked get_html_tags() method.
|
||||||
|
mocked_get_tags.return_value = [
|
||||||
|
{
|
||||||
|
u'desc': u'Black',
|
||||||
|
u'start tag': u'{b}',
|
||||||
|
u'start html': u'<span style="-webkit-text-fill-color:black">',
|
||||||
|
u'end tag': u'{/b}', u'end html': u'</span>', u'protected': True,
|
||||||
|
u'temporary': False
|
||||||
|
},
|
||||||
|
{
|
||||||
|
u'desc': u'Yellow',
|
||||||
|
u'start tag': u'{y}',
|
||||||
|
u'start html': u'<span style="-webkit-text-fill-color:yellow">',
|
||||||
|
u'end tag': u'{/y}', u'end html': u'</span>', u'protected': True,
|
||||||
|
u'temporary': False
|
||||||
|
},
|
||||||
|
{
|
||||||
|
u'desc': u'Green',
|
||||||
|
u'start tag': u'{g}',
|
||||||
|
u'start html': u'<span style="-webkit-text-fill-color:green">',
|
||||||
|
u'end tag': u'{/g}', u'end html': u'</span>', u'protected': True,
|
||||||
|
u'temporary': False
|
||||||
|
}
|
||||||
|
]
|
||||||
|
string_to_pass = u'{b}black{/b}{y}yellow{/y}'
|
||||||
|
wanted_string = u'<span style="-webkit-text-fill-color:black">black</span>' + \
|
||||||
|
'<span style="-webkit-text-fill-color:yellow">yellow</span>'
|
||||||
|
|
||||||
|
# WHEN: Replace the tags.
|
||||||
|
result_string = expand_tags(string_to_pass)
|
||||||
|
|
||||||
|
# THEN: The strings should be identical.
|
||||||
|
assert result_string == wanted_string, u'The strings should be identical.'
|
||||||
|
|
||||||
def validate_thumb_file_does_not_exist_test(self):
|
def validate_thumb_file_does_not_exist_test(self):
|
||||||
"""
|
"""
|
||||||
Test the validate_thumb() function when the thumbnail does not exist
|
Test the validate_thumb() function when the thumbnail does not exist
|
||||||
|
@ -18,8 +18,15 @@ class TestPluginManager(TestCase):
|
|||||||
"""
|
"""
|
||||||
Some pre-test setup required.
|
Some pre-test setup required.
|
||||||
"""
|
"""
|
||||||
|
self.mocked_main_window = MagicMock()
|
||||||
|
self.mocked_main_window.file_import_menu.return_value = None
|
||||||
|
self.mocked_main_window.file_export_menu.return_value = None
|
||||||
|
self.mocked_main_window.file_export_menu.return_value = None
|
||||||
|
self.mocked_settings_form = MagicMock()
|
||||||
Registry.create()
|
Registry.create()
|
||||||
Registry().register(u'service_list', MagicMock())
|
Registry().register(u'service_list', MagicMock())
|
||||||
|
Registry().register(u'main_window', self.mocked_main_window)
|
||||||
|
Registry().register(u'settings_form', self.mocked_settings_form)
|
||||||
|
|
||||||
def hook_media_manager_with_disabled_plugin_test(self):
|
def hook_media_manager_with_disabled_plugin_test(self):
|
||||||
"""
|
"""
|
||||||
@ -78,17 +85,41 @@ class TestPluginManager(TestCase):
|
|||||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||||
mocked_plugin = MagicMock()
|
mocked_plugin = MagicMock()
|
||||||
mocked_plugin.status = PluginStatus.Disabled
|
mocked_plugin.status = PluginStatus.Disabled
|
||||||
mocked_settings_form = MagicMock()
|
|
||||||
plugin_manager = PluginManager()
|
plugin_manager = PluginManager()
|
||||||
plugin_manager.plugins = [mocked_plugin]
|
plugin_manager.plugins = [mocked_plugin]
|
||||||
|
mocked_settings_form = MagicMock()
|
||||||
|
# Replace the autoloaded plugin with the version for testing in real code this would error
|
||||||
|
mocked_settings_form.plugin_manager = plugin_manager
|
||||||
|
|
||||||
# WHEN: We run hook_settings_tabs()
|
# WHEN: We run hook_settings_tabs()
|
||||||
plugin_manager.hook_settings_tabs(mocked_settings_form)
|
plugin_manager.hook_settings_tabs()
|
||||||
|
|
||||||
# THEN: The createSettingsTab() method should not have been called, but the plugins lists should be the same
|
# THEN: The createSettingsTab() method should not have been called, but the plugins lists should be the same
|
||||||
assert mocked_plugin.createSettingsTab.call_count == 0, \
|
assert mocked_plugin.createSettingsTab.call_count == 0, \
|
||||||
u'The createMediaManagerItem() method should not have been called.'
|
u'The createMediaManagerItem() method should not have been called.'
|
||||||
self.assertEqual(mocked_settings_form.plugins, plugin_manager.plugins,
|
self.assertEqual(mocked_settings_form.plugin_manager.plugins, plugin_manager.plugins,
|
||||||
|
u'The plugins on the settings form should be the same as the plugins in the plugin manager')
|
||||||
|
|
||||||
|
def hook_settings_tabs_with_active_plugin_and_mocked_form_test(self):
|
||||||
|
"""
|
||||||
|
Test running the hook_settings_tabs() method with an active plugin and a mocked settings form
|
||||||
|
"""
|
||||||
|
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||||
|
mocked_plugin = MagicMock()
|
||||||
|
mocked_plugin.status = PluginStatus.Active
|
||||||
|
plugin_manager = PluginManager()
|
||||||
|
plugin_manager.plugins = [mocked_plugin]
|
||||||
|
mocked_settings_form = MagicMock()
|
||||||
|
# Replace the autoloaded plugin with the version for testing in real code this would error
|
||||||
|
mocked_settings_form.plugin_manager = plugin_manager
|
||||||
|
|
||||||
|
# WHEN: We run hook_settings_tabs()
|
||||||
|
plugin_manager.hook_settings_tabs()
|
||||||
|
|
||||||
|
# THEN: The createMediaManagerItem() method should have been called with the mocked settings form
|
||||||
|
assert mocked_plugin.createSettingsTab.call_count == 1, \
|
||||||
|
u'The createMediaManagerItem() method should have been called once.'
|
||||||
|
self.assertEqual(mocked_settings_form.plugin_manager.plugins, plugin_manager.plugins,
|
||||||
u'The plugins on the settings form should be the same as the plugins in the plugin manager')
|
u'The plugins on the settings form should be the same as the plugins in the plugin manager')
|
||||||
|
|
||||||
def hook_settings_tabs_with_active_plugin_and_no_form_test(self):
|
def hook_settings_tabs_with_active_plugin_and_no_form_test(self):
|
||||||
@ -105,26 +136,7 @@ class TestPluginManager(TestCase):
|
|||||||
plugin_manager.hook_settings_tabs()
|
plugin_manager.hook_settings_tabs()
|
||||||
|
|
||||||
# THEN: The createSettingsTab() method should have been called
|
# THEN: The createSettingsTab() method should have been called
|
||||||
mocked_plugin.createSettingsTab.assert_called_with(None)
|
mocked_plugin.createSettingsTab.assert_called_with(self.mocked_settings_form)
|
||||||
|
|
||||||
def hook_settings_tabs_with_active_plugin_and_mocked_form_test(self):
|
|
||||||
"""
|
|
||||||
Test running the hook_settings_tabs() method with an active plugin and a mocked settings form
|
|
||||||
"""
|
|
||||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
|
||||||
mocked_plugin = MagicMock()
|
|
||||||
mocked_plugin.status = PluginStatus.Active
|
|
||||||
mocked_settings_form = MagicMock()
|
|
||||||
plugin_manager = PluginManager()
|
|
||||||
plugin_manager.plugins = [mocked_plugin]
|
|
||||||
|
|
||||||
# WHEN: We run hook_settings_tabs()
|
|
||||||
plugin_manager.hook_settings_tabs(mocked_settings_form)
|
|
||||||
|
|
||||||
# THEN: The createMediaManagerItem() method should have been called with the mocked settings form
|
|
||||||
mocked_plugin.createSettingsTab.assert_called_with(mocked_settings_form)
|
|
||||||
self.assertEqual(mocked_settings_form.plugins, plugin_manager.plugins,
|
|
||||||
u'The plugins on the settings form should be the same as the plugins in the plugin manager')
|
|
||||||
|
|
||||||
def hook_import_menu_with_disabled_plugin_test(self):
|
def hook_import_menu_with_disabled_plugin_test(self):
|
||||||
"""
|
"""
|
||||||
@ -133,12 +145,11 @@ class TestPluginManager(TestCase):
|
|||||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||||
mocked_plugin = MagicMock()
|
mocked_plugin = MagicMock()
|
||||||
mocked_plugin.status = PluginStatus.Disabled
|
mocked_plugin.status = PluginStatus.Disabled
|
||||||
mocked_import_menu = MagicMock()
|
|
||||||
plugin_manager = PluginManager()
|
plugin_manager = PluginManager()
|
||||||
plugin_manager.plugins = [mocked_plugin]
|
plugin_manager.plugins = [mocked_plugin]
|
||||||
|
|
||||||
# WHEN: We run hook_import_menu()
|
# WHEN: We run hook_import_menu()
|
||||||
plugin_manager.hook_import_menu(mocked_import_menu)
|
plugin_manager.hook_import_menu()
|
||||||
|
|
||||||
# THEN: The createMediaManagerItem() method should have been called
|
# THEN: The createMediaManagerItem() method should have been called
|
||||||
assert mocked_plugin.addImportMenuItem.call_count == 0, \
|
assert mocked_plugin.addImportMenuItem.call_count == 0, \
|
||||||
@ -151,15 +162,14 @@ class TestPluginManager(TestCase):
|
|||||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||||
mocked_plugin = MagicMock()
|
mocked_plugin = MagicMock()
|
||||||
mocked_plugin.status = PluginStatus.Active
|
mocked_plugin.status = PluginStatus.Active
|
||||||
mocked_import_menu = MagicMock()
|
|
||||||
plugin_manager = PluginManager()
|
plugin_manager = PluginManager()
|
||||||
plugin_manager.plugins = [mocked_plugin]
|
plugin_manager.plugins = [mocked_plugin]
|
||||||
|
|
||||||
# WHEN: We run hook_import_menu()
|
# WHEN: We run hook_import_menu()
|
||||||
plugin_manager.hook_import_menu(mocked_import_menu)
|
plugin_manager.hook_import_menu()
|
||||||
|
|
||||||
# THEN: The addImportMenuItem() method should have been called
|
# THEN: The addImportMenuItem() method should have been called
|
||||||
mocked_plugin.addImportMenuItem.assert_called_with(mocked_import_menu)
|
mocked_plugin.addImportMenuItem.assert_called_with(self.mocked_main_window.file_import_menu)
|
||||||
|
|
||||||
def hook_export_menu_with_disabled_plugin_test(self):
|
def hook_export_menu_with_disabled_plugin_test(self):
|
||||||
"""
|
"""
|
||||||
@ -168,12 +178,11 @@ class TestPluginManager(TestCase):
|
|||||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||||
mocked_plugin = MagicMock()
|
mocked_plugin = MagicMock()
|
||||||
mocked_plugin.status = PluginStatus.Disabled
|
mocked_plugin.status = PluginStatus.Disabled
|
||||||
mocked_export_menu = MagicMock()
|
|
||||||
plugin_manager = PluginManager()
|
plugin_manager = PluginManager()
|
||||||
plugin_manager.plugins = [mocked_plugin]
|
plugin_manager.plugins = [mocked_plugin]
|
||||||
|
|
||||||
# WHEN: We run hook_export_menu()
|
# WHEN: We run hook_export_menu()
|
||||||
plugin_manager.hook_export_menu(mocked_export_menu)
|
plugin_manager.hook_export_menu()
|
||||||
|
|
||||||
# THEN: The addExportMenuItem() method should have been called
|
# THEN: The addExportMenuItem() method should have been called
|
||||||
assert mocked_plugin.addExportMenuItem.call_count == 0, \
|
assert mocked_plugin.addExportMenuItem.call_count == 0, \
|
||||||
@ -186,15 +195,14 @@ class TestPluginManager(TestCase):
|
|||||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||||
mocked_plugin = MagicMock()
|
mocked_plugin = MagicMock()
|
||||||
mocked_plugin.status = PluginStatus.Active
|
mocked_plugin.status = PluginStatus.Active
|
||||||
mocked_export_menu = MagicMock()
|
|
||||||
plugin_manager = PluginManager()
|
plugin_manager = PluginManager()
|
||||||
plugin_manager.plugins = [mocked_plugin]
|
plugin_manager.plugins = [mocked_plugin]
|
||||||
|
|
||||||
# WHEN: We run hook_export_menu()
|
# WHEN: We run hook_export_menu()
|
||||||
plugin_manager.hook_export_menu(mocked_export_menu)
|
plugin_manager.hook_export_menu()
|
||||||
|
|
||||||
# THEN: The addExportMenuItem() method should have been called
|
# THEN: The addExportMenuItem() method should have been called
|
||||||
mocked_plugin.addExportMenuItem.assert_called_with(mocked_export_menu)
|
mocked_plugin.addExportMenuItem.assert_called_with(self.mocked_main_window.file_export_menu)
|
||||||
|
|
||||||
def hook_tools_menu_with_disabled_plugin_test(self):
|
def hook_tools_menu_with_disabled_plugin_test(self):
|
||||||
"""
|
"""
|
||||||
@ -203,12 +211,11 @@ class TestPluginManager(TestCase):
|
|||||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||||
mocked_plugin = MagicMock()
|
mocked_plugin = MagicMock()
|
||||||
mocked_plugin.status = PluginStatus.Disabled
|
mocked_plugin.status = PluginStatus.Disabled
|
||||||
mocked_tools_menu = MagicMock()
|
|
||||||
plugin_manager = PluginManager()
|
plugin_manager = PluginManager()
|
||||||
plugin_manager.plugins = [mocked_plugin]
|
plugin_manager.plugins = [mocked_plugin]
|
||||||
|
|
||||||
# WHEN: We run hook_tools_menu()
|
# WHEN: We run hook_tools_menu()
|
||||||
plugin_manager.hook_tools_menu(mocked_tools_menu)
|
plugin_manager.hook_tools_menu()
|
||||||
|
|
||||||
# THEN: The addToolsMenuItem() method should have been called
|
# THEN: The addToolsMenuItem() method should have been called
|
||||||
assert mocked_plugin.addToolsMenuItem.call_count == 0, \
|
assert mocked_plugin.addToolsMenuItem.call_count == 0, \
|
||||||
@ -221,15 +228,14 @@ class TestPluginManager(TestCase):
|
|||||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||||
mocked_plugin = MagicMock()
|
mocked_plugin = MagicMock()
|
||||||
mocked_plugin.status = PluginStatus.Active
|
mocked_plugin.status = PluginStatus.Active
|
||||||
mocked_tools_menu = MagicMock()
|
|
||||||
plugin_manager = PluginManager()
|
plugin_manager = PluginManager()
|
||||||
plugin_manager.plugins = [mocked_plugin]
|
plugin_manager.plugins = [mocked_plugin]
|
||||||
|
|
||||||
# WHEN: We run hook_tools_menu()
|
# WHEN: We run hook_tools_menu()
|
||||||
plugin_manager.hook_tools_menu(mocked_tools_menu)
|
plugin_manager.hook_tools_menu()
|
||||||
|
|
||||||
# THEN: The addToolsMenuItem() method should have been called
|
# THEN: The addToolsMenuItem() method should have been called
|
||||||
mocked_plugin.addToolsMenuItem.assert_called_with(mocked_tools_menu)
|
mocked_plugin.addToolsMenuItem.assert_called_with(self.mocked_main_window.tools_menu)
|
||||||
|
|
||||||
def initialise_plugins_with_disabled_plugin_test(self):
|
def initialise_plugins_with_disabled_plugin_test(self):
|
||||||
"""
|
"""
|
||||||
|
@ -54,5 +54,5 @@ class TestScreenList(TestCase):
|
|||||||
new_screens = self.screens.screen_list
|
new_screens = self.screens.screen_list
|
||||||
assert len(old_screens) + 1 == len(new_screens), u'The new_screens list should be bigger.'
|
assert len(old_screens) + 1 == len(new_screens), u'The new_screens list should be bigger.'
|
||||||
|
|
||||||
# THEN: The screens should be identically.
|
# THEN: The screens should be identical.
|
||||||
assert SCREEN == new_screens.pop(), u'The new screen should be identically to the screen defined above.'
|
assert SCREEN == new_screens.pop(), u'The new screen should be identical to the screen defined above.'
|
||||||
|
@ -216,12 +216,15 @@ class TestServiceItem(TestCase):
|
|||||||
assert service_item.get_frame_path(0) == test_file, u'The frame path should match the full path to the image'
|
assert service_item.get_frame_path(0) == test_file, u'The frame path should match the full path to the image'
|
||||||
assert service_item.get_frame_title(0) == image_name, u'The frame title should match the image name'
|
assert service_item.get_frame_title(0) == image_name, u'The frame title should match the image name'
|
||||||
assert service_item.get_display_title() == image_name, u'The display title should match the first image name'
|
assert service_item.get_display_title() == image_name, u'The display title should match the first image name'
|
||||||
assert service_item.is_image() is True, u'This service item is an Image'
|
assert service_item.is_image() is True, u'This service item should be of an "image" type'
|
||||||
assert service_item.is_capable(ItemCapabilities.CanMaintain) is True, u'This service item can be Maintained'
|
assert service_item.is_capable(ItemCapabilities.CanMaintain) is True, \
|
||||||
assert service_item.is_capable(ItemCapabilities.CanPreview) is True, u'This service item can be Previewed'
|
u'This service item should be able to be Maintained'
|
||||||
assert service_item.is_capable(ItemCapabilities.CanLoop) is True, u'This service item can be made to Loop'
|
assert service_item.is_capable(ItemCapabilities.CanPreview) is True, \
|
||||||
|
u'This service item should be able to be be Previewed'
|
||||||
|
assert service_item.is_capable(ItemCapabilities.CanLoop) is True, \
|
||||||
|
u'This service item should be able to be run in a can be made to Loop'
|
||||||
assert service_item.is_capable(ItemCapabilities.CanAppend) is True, \
|
assert service_item.is_capable(ItemCapabilities.CanAppend) is True, \
|
||||||
u'This service item can have new items added'
|
u'This service item should be able to have new items added to it'
|
||||||
|
|
||||||
def serviceitem_load_image_from_local_service_test(self):
|
def serviceitem_load_image_from_local_service_test(self):
|
||||||
"""
|
"""
|
||||||
@ -256,11 +259,14 @@ class TestServiceItem(TestCase):
|
|||||||
assert service_item.get_display_title().lower() == service_item.name, \
|
assert service_item.get_display_title().lower() == service_item.name, \
|
||||||
u'The plugin name should match the display title, as there are > 1 Images'
|
u'The plugin name should match the display title, as there are > 1 Images'
|
||||||
assert service_item.is_image() is True, u'This service item should be of an "image" type'
|
assert service_item.is_image() is True, u'This service item should be of an "image" type'
|
||||||
assert service_item.is_capable(ItemCapabilities.CanMaintain) is True, u'This service item can be Maintained'
|
assert service_item.is_capable(ItemCapabilities.CanMaintain) is True, \
|
||||||
assert service_item.is_capable(ItemCapabilities.CanPreview) is True, u'This service item can be Previewed'
|
u'This service item should be able to be Maintained'
|
||||||
assert service_item.is_capable(ItemCapabilities.CanLoop) is True, u'This service item can be made to Loop'
|
assert service_item.is_capable(ItemCapabilities.CanPreview) is True, \
|
||||||
|
u'This service item should be able to be be Previewed'
|
||||||
|
assert service_item.is_capable(ItemCapabilities.CanLoop) is True, \
|
||||||
|
u'This service item should be able to be run in a can be made to Loop'
|
||||||
assert service_item.is_capable(ItemCapabilities.CanAppend) is True, \
|
assert service_item.is_capable(ItemCapabilities.CanAppend) is True, \
|
||||||
u'This service item can have new items added'
|
u'This service item should be able to have new items added to it'
|
||||||
|
|
||||||
def convert_file_service_item(self, name):
|
def convert_file_service_item(self, name):
|
||||||
service_file = os.path.join(TEST_PATH, name)
|
service_file = os.path.join(TEST_PATH, name)
|
||||||
|
124
tests/functional/openlp_core_utils/test_actions.py
Normal file
124
tests/functional/openlp_core_utils/test_actions.py
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
"""
|
||||||
|
Package to test the openlp.core.utils.actions package.
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
from tempfile import mkstemp
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from PyQt4 import QtGui, QtCore
|
||||||
|
|
||||||
|
from openlp.core.lib import Settings
|
||||||
|
from openlp.core.utils import ActionList
|
||||||
|
|
||||||
|
|
||||||
|
class TestActionList(TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
"""
|
||||||
|
Prepare the tests
|
||||||
|
"""
|
||||||
|
self.action_list = ActionList.get_instance()
|
||||||
|
self.settings = Settings()
|
||||||
|
fd, self.ini_file = mkstemp(u'.ini')
|
||||||
|
self.settings.set_filename(self.ini_file)
|
||||||
|
self.settings.beginGroup(u'shortcuts')
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
"""
|
||||||
|
Clean up
|
||||||
|
"""
|
||||||
|
self.settings.endGroup()
|
||||||
|
os.unlink(self.ini_file)
|
||||||
|
|
||||||
|
def test_add_action_same_parent(self):
|
||||||
|
"""
|
||||||
|
ActionList test - Tests the add_action method. The actions have the same parent, the same shortcuts and both
|
||||||
|
have the QtCore.Qt.WindowShortcut shortcut context set.
|
||||||
|
"""
|
||||||
|
# GIVEN: Two actions with the same shortcuts.
|
||||||
|
parent = QtCore.QObject()
|
||||||
|
action1 = QtGui.QAction(parent)
|
||||||
|
action1.setObjectName(u'action1')
|
||||||
|
action_with_same_shortcuts1 = QtGui.QAction(parent)
|
||||||
|
action_with_same_shortcuts1.setObjectName(u'action_with_same_shortcuts1')
|
||||||
|
# Add default shortcuts to Settings class.
|
||||||
|
default_shortcuts = {
|
||||||
|
u'shortcuts/action1': [QtGui.QKeySequence(u'a'), QtGui.QKeySequence(u'b')],
|
||||||
|
u'shortcuts/action_with_same_shortcuts1': [QtGui.QKeySequence(u'b'), QtGui.QKeySequence(u'a')]
|
||||||
|
}
|
||||||
|
Settings.extend_default_settings(default_shortcuts)
|
||||||
|
|
||||||
|
# WHEN: Add the two actions to the action list.
|
||||||
|
self.action_list.add_action(action1, u'example_category')
|
||||||
|
self.action_list.add_action(action_with_same_shortcuts1, u'example_category')
|
||||||
|
# Remove the actions again.
|
||||||
|
self.action_list.remove_action(action1, u'example_category')
|
||||||
|
self.action_list.remove_action(action_with_same_shortcuts1, u'example_category')
|
||||||
|
|
||||||
|
# THEN: As both actions have the same shortcuts, they should be removed from one action.
|
||||||
|
assert len(action1.shortcuts()) == 2, u'The action should have two shortcut assigned.'
|
||||||
|
assert len(action_with_same_shortcuts1.shortcuts()) == 0, u'The action should not have a shortcut assigned.'
|
||||||
|
|
||||||
|
def test_add_action_different_parent(self):
|
||||||
|
"""
|
||||||
|
ActionList test - Tests the add_action method. The actions have the different parent, the same shortcuts and
|
||||||
|
both have the QtCore.Qt.WindowShortcut shortcut context set.
|
||||||
|
"""
|
||||||
|
# GIVEN: Two actions with the same shortcuts.
|
||||||
|
parent = QtCore.QObject()
|
||||||
|
action2 = QtGui.QAction(parent)
|
||||||
|
action2.setObjectName(u'action2')
|
||||||
|
second_parent = QtCore.QObject()
|
||||||
|
action_with_same_shortcuts2 = QtGui.QAction(second_parent)
|
||||||
|
action_with_same_shortcuts2.setObjectName(u'action_with_same_shortcuts2')
|
||||||
|
# Add default shortcuts to Settings class.
|
||||||
|
default_shortcuts = {
|
||||||
|
u'shortcuts/action2': [QtGui.QKeySequence(u'c'), QtGui.QKeySequence(u'd')],
|
||||||
|
u'shortcuts/action_with_same_shortcuts2': [QtGui.QKeySequence(u'd'), QtGui.QKeySequence(u'c')]
|
||||||
|
}
|
||||||
|
Settings.extend_default_settings(default_shortcuts)
|
||||||
|
|
||||||
|
# WHEN: Add the two actions to the action list.
|
||||||
|
self.action_list.add_action(action2, u'example_category')
|
||||||
|
self.action_list.add_action(action_with_same_shortcuts2, u'example_category')
|
||||||
|
# Remove the actions again.
|
||||||
|
self.action_list.remove_action(action2, u'example_category')
|
||||||
|
self.action_list.remove_action(action_with_same_shortcuts2, u'example_category')
|
||||||
|
|
||||||
|
# THEN: As both actions have the same shortcuts, they should be removed from one action.
|
||||||
|
assert len(action2.shortcuts()) == 2, u'The action should have two shortcut assigned.'
|
||||||
|
assert len(action_with_same_shortcuts2.shortcuts()) == 0, u'The action should not have a shortcut assigned.'
|
||||||
|
|
||||||
|
def test_add_action_different_context(self):
|
||||||
|
"""
|
||||||
|
ActionList test - Tests the add_action method. The actions have the different parent, the same shortcuts and
|
||||||
|
both have the QtCore.Qt.WidgetShortcut shortcut context set.
|
||||||
|
"""
|
||||||
|
# GIVEN: Two actions with the same shortcuts.
|
||||||
|
parent = QtCore.QObject()
|
||||||
|
action3 = QtGui.QAction(parent)
|
||||||
|
action3.setObjectName(u'action3')
|
||||||
|
action3.setShortcutContext(QtCore.Qt.WidgetShortcut)
|
||||||
|
second_parent = QtCore.QObject()
|
||||||
|
action_with_same_shortcuts3 = QtGui.QAction(second_parent)
|
||||||
|
action_with_same_shortcuts3.setObjectName(u'action_with_same_shortcuts3')
|
||||||
|
action_with_same_shortcuts3.setShortcutContext(QtCore.Qt.WidgetShortcut)
|
||||||
|
# Add default shortcuts to Settings class.
|
||||||
|
default_shortcuts = {
|
||||||
|
u'shortcuts/action3': [QtGui.QKeySequence(u'e'), QtGui.QKeySequence(u'f')],
|
||||||
|
u'shortcuts/action_with_same_shortcuts3': [QtGui.QKeySequence(u'e'), QtGui.QKeySequence(u'f')]
|
||||||
|
}
|
||||||
|
Settings.extend_default_settings(default_shortcuts)
|
||||||
|
|
||||||
|
# WHEN: Add the two actions to the action list.
|
||||||
|
self.action_list.add_action(action3, u'example_category2')
|
||||||
|
self.action_list.add_action(action_with_same_shortcuts3, u'example_category2')
|
||||||
|
# Remove the actions again.
|
||||||
|
self.action_list.remove_action(action3, u'example_category2')
|
||||||
|
self.action_list.remove_action(action_with_same_shortcuts3, u'example_category2')
|
||||||
|
|
||||||
|
# THEN: Both action should keep their shortcuts.
|
||||||
|
assert len(action3.shortcuts()) == 2, u'The action should have two shortcut assigned.'
|
||||||
|
assert len(action_with_same_shortcuts3.shortcuts()) == 2, u'The action should have two shortcuts assigned.'
|
||||||
|
|
||||||
|
|
@ -1,12 +1,17 @@
|
|||||||
"""
|
"""
|
||||||
Functional tests to test the AppLocation class and related methods.
|
Functional tests to test the AppLocation class and related methods.
|
||||||
"""
|
"""
|
||||||
|
import copy
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
from mock import patch
|
from mock import patch
|
||||||
|
|
||||||
from openlp.core.utils import AppLocation
|
from openlp.core.utils import AppLocation
|
||||||
|
|
||||||
|
|
||||||
|
FILE_LIST = [u'file1', u'file2', u'file3.txt', u'file4.txt', u'file5.mp3', u'file6.mp3']
|
||||||
|
|
||||||
|
|
||||||
class TestAppLocation(TestCase):
|
class TestAppLocation(TestCase):
|
||||||
"""
|
"""
|
||||||
A test suite to test out various methods around the AppLocation class.
|
A test suite to test out various methods around the AppLocation class.
|
||||||
@ -15,10 +20,10 @@ class TestAppLocation(TestCase):
|
|||||||
"""
|
"""
|
||||||
Test the AppLocation.get_data_path() method
|
Test the AppLocation.get_data_path() method
|
||||||
"""
|
"""
|
||||||
with patch(u'openlp.core.utils.Settings') as mocked_class, \
|
with patch(u'openlp.core.utils.applocation.Settings') as mocked_class, \
|
||||||
patch(u'openlp.core.utils.AppLocation.get_directory') as mocked_get_directory, \
|
patch(u'openlp.core.utils.AppLocation.get_directory') as mocked_get_directory, \
|
||||||
patch(u'openlp.core.utils.check_directory_exists') as mocked_check_directory_exists, \
|
patch(u'openlp.core.utils.applocation.check_directory_exists') as mocked_check_directory_exists, \
|
||||||
patch(u'openlp.core.utils.os') as mocked_os:
|
patch(u'openlp.core.utils.applocation.os') as mocked_os:
|
||||||
# GIVEN: A mocked out Settings class and a mocked out AppLocation.get_directory()
|
# GIVEN: A mocked out Settings class and a mocked out AppLocation.get_directory()
|
||||||
mocked_settings = mocked_class.return_value
|
mocked_settings = mocked_class.return_value
|
||||||
mocked_settings.contains.return_value = False
|
mocked_settings.contains.return_value = False
|
||||||
@ -37,8 +42,8 @@ class TestAppLocation(TestCase):
|
|||||||
"""
|
"""
|
||||||
Test the AppLocation.get_data_path() method when a custom location is set in the settings
|
Test the AppLocation.get_data_path() method when a custom location is set in the settings
|
||||||
"""
|
"""
|
||||||
with patch(u'openlp.core.utils.Settings') as mocked_class,\
|
with patch(u'openlp.core.utils.applocation.Settings') as mocked_class,\
|
||||||
patch(u'openlp.core.utils.os') as mocked_os:
|
patch(u'openlp.core.utils.applocation.os') as mocked_os:
|
||||||
# GIVEN: A mocked out Settings class which returns a custom data location
|
# GIVEN: A mocked out Settings class which returns a custom data location
|
||||||
mocked_settings = mocked_class.return_value
|
mocked_settings = mocked_class.return_value
|
||||||
mocked_settings.contains.return_value = True
|
mocked_settings.contains.return_value = True
|
||||||
@ -51,12 +56,47 @@ class TestAppLocation(TestCase):
|
|||||||
mocked_settings.value.assert_called_with(u'advanced/data path')
|
mocked_settings.value.assert_called_with(u'advanced/data path')
|
||||||
assert data_path == u'custom/dir', u'Result should be "custom/dir"'
|
assert data_path == u'custom/dir', u'Result should be "custom/dir"'
|
||||||
|
|
||||||
|
def get_files_no_section_no_extension_test(self):
|
||||||
|
"""
|
||||||
|
Test the AppLocation.get_files() method with no parameters passed.
|
||||||
|
"""
|
||||||
|
with patch(u'openlp.core.utils.AppLocation.get_data_path') as mocked_get_data_path, \
|
||||||
|
patch(u'openlp.core.utils.applocation.os.listdir') as mocked_listdir:
|
||||||
|
# GIVEN: Our mocked modules/methods.
|
||||||
|
mocked_get_data_path.return_value = u'test/dir'
|
||||||
|
mocked_listdir.return_value = copy.deepcopy(FILE_LIST)
|
||||||
|
|
||||||
|
# When: Get the list of files.
|
||||||
|
result = AppLocation.get_files()
|
||||||
|
|
||||||
|
# Then: check if the file lists are identical.
|
||||||
|
assert result == FILE_LIST, u'The file lists should be identical.'
|
||||||
|
|
||||||
|
def get_files_test(self):
|
||||||
|
"""
|
||||||
|
Test the AppLocation.get_files() method with all parameters passed.
|
||||||
|
"""
|
||||||
|
with patch(u'openlp.core.utils.AppLocation.get_data_path') as mocked_get_data_path, \
|
||||||
|
patch(u'openlp.core.utils.applocation.os.listdir') as mocked_listdir:
|
||||||
|
# GIVEN: Our mocked modules/methods.
|
||||||
|
mocked_get_data_path.return_value = u'test/dir'
|
||||||
|
mocked_listdir.return_value = copy.deepcopy(FILE_LIST)
|
||||||
|
|
||||||
|
# When: Get the list of files.
|
||||||
|
result = AppLocation.get_files(u'section', u'.mp3')
|
||||||
|
|
||||||
|
# Then: Check if the section parameter was used correctly.
|
||||||
|
mocked_listdir.assert_called_with(u'test/dir/section')
|
||||||
|
|
||||||
|
# Then: check if the file lists are identical.
|
||||||
|
assert result == [u'file5.mp3', u'file6.mp3'], u'The file lists should be identical.'
|
||||||
|
|
||||||
def get_section_data_path_test(self):
|
def get_section_data_path_test(self):
|
||||||
"""
|
"""
|
||||||
Test the AppLocation.get_section_data_path() method
|
Test the AppLocation.get_section_data_path() method
|
||||||
"""
|
"""
|
||||||
with patch(u'openlp.core.utils.AppLocation.get_data_path') as mocked_get_data_path, \
|
with patch(u'openlp.core.utils.AppLocation.get_data_path') as mocked_get_data_path, \
|
||||||
patch(u'openlp.core.utils.check_directory_exists') as mocked_check_directory_exists:
|
patch(u'openlp.core.utils.applocation.check_directory_exists') as mocked_check_directory_exists:
|
||||||
# GIVEN: A mocked out AppLocation.get_data_path()
|
# GIVEN: A mocked out AppLocation.get_data_path()
|
||||||
mocked_get_data_path.return_value = u'test/dir'
|
mocked_get_data_path.return_value = u'test/dir'
|
||||||
mocked_check_directory_exists.return_value = True
|
mocked_check_directory_exists.return_value = True
|
||||||
@ -70,7 +110,7 @@ class TestAppLocation(TestCase):
|
|||||||
"""
|
"""
|
||||||
Test the AppLocation.get_directory() method for AppLocation.AppDir
|
Test the AppLocation.get_directory() method for AppLocation.AppDir
|
||||||
"""
|
"""
|
||||||
with patch(u'openlp.core.utils._get_frozen_path') as mocked_get_frozen_path:
|
with patch(u'openlp.core.utils.applocation._get_frozen_path') as mocked_get_frozen_path:
|
||||||
mocked_get_frozen_path.return_value = u'app/dir'
|
mocked_get_frozen_path.return_value = u'app/dir'
|
||||||
# WHEN: We call AppLocation.get_directory
|
# WHEN: We call AppLocation.get_directory
|
||||||
directory = AppLocation.get_directory(AppLocation.AppDir)
|
directory = AppLocation.get_directory(AppLocation.AppDir)
|
||||||
@ -81,10 +121,10 @@ class TestAppLocation(TestCase):
|
|||||||
"""
|
"""
|
||||||
Test the AppLocation.get_directory() method for AppLocation.PluginsDir
|
Test the AppLocation.get_directory() method for AppLocation.PluginsDir
|
||||||
"""
|
"""
|
||||||
with patch(u'openlp.core.utils._get_frozen_path') as mocked_get_frozen_path, \
|
with patch(u'openlp.core.utils.applocation._get_frozen_path') as mocked_get_frozen_path, \
|
||||||
patch(u'openlp.core.utils.os.path.abspath') as mocked_abspath, \
|
patch(u'openlp.core.utils.applocation.os.path.abspath') as mocked_abspath, \
|
||||||
patch(u'openlp.core.utils.os.path.split') as mocked_split, \
|
patch(u'openlp.core.utils.applocation.os.path.split') as mocked_split, \
|
||||||
patch(u'openlp.core.utils.sys') as mocked_sys:
|
patch(u'openlp.core.utils.applocation.sys') as mocked_sys:
|
||||||
mocked_abspath.return_value = u'plugins/dir'
|
mocked_abspath.return_value = u'plugins/dir'
|
||||||
mocked_split.return_value = [u'openlp']
|
mocked_split.return_value = [u'openlp']
|
||||||
mocked_get_frozen_path.return_value = u'plugins/dir'
|
mocked_get_frozen_path.return_value = u'plugins/dir'
|
||||||
|
@ -21,15 +21,15 @@ class TestServiceManager(TestCase):
|
|||||||
self.app = QtGui.QApplication.instance()
|
self.app = QtGui.QApplication.instance()
|
||||||
ScreenList.create(self.app.desktop())
|
ScreenList.create(self.app.desktop())
|
||||||
Registry().register(u'application', MagicMock())
|
Registry().register(u'application', MagicMock())
|
||||||
#with patch(u'openlp.core.lib.PluginManager'):
|
with patch(u'openlp.core.lib.PluginManager'):
|
||||||
# self.main_window = MainWindow()
|
self.main_window = MainWindow()
|
||||||
#self.service_manager = Registry().get(u'service_manager')
|
self.service_manager = Registry().get(u'service_manager')
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
"""
|
"""
|
||||||
Delete all the C++ objects at the end so that we don't have a segfault
|
Delete all the C++ objects at the end so that we don't have a segfault
|
||||||
"""
|
"""
|
||||||
#del self.main_window
|
del self.main_window
|
||||||
del self.app
|
del self.app
|
||||||
|
|
||||||
def basic_service_manager_test(self):
|
def basic_service_manager_test(self):
|
||||||
@ -40,6 +40,5 @@ class TestServiceManager(TestCase):
|
|||||||
|
|
||||||
# WHEN I have an empty display
|
# WHEN I have an empty display
|
||||||
# THEN the count of items should be zero
|
# THEN the count of items should be zero
|
||||||
#self.assertEqual(self.service_manager.service_manager_list.topLevelItemCount(), 0,
|
self.assertEqual(self.service_manager.service_manager_list.topLevelItemCount(), 0,
|
||||||
# u'The service manager list should be empty ')
|
u'The service manager list should be empty ')
|
||||||
pass
|
|
||||||
|
Loading…
Reference in New Issue
Block a user