From 8bb88f3c9f2a44b1efe7c375d3ae6682866ac855 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 10 Feb 2013 13:29:42 +0100 Subject: [PATCH 01/48] fixed bug 1112587 Fixes: https://launchpad.net/bugs/1112587 --- openlp/core/ui/slidecontroller.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 607ae1dd5..4424081df 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -90,7 +90,6 @@ class SlideController(DisplayController): u'delaySpinBox' ] self.audioList = [ - u'songMenu', u'audioPauseItem', u'audioTimeLabel' ] @@ -293,6 +292,7 @@ class SlideController(DisplayController): self.audioTimeLabel.setObjectName(u'audioTimeLabel') self.toolbar.addToolbarWidget(self.audioTimeLabel) self.toolbar.setWidgetVisible(self.audioList, False) + self.toolbar.setWidgetVisible([u'songMenu'], False) # Screen preview area self.previewFrame = QtGui.QFrame(self.splitter) self.previewFrame.setGeometry(QtCore.QRect(0, 0, 300, 300 * self.ratio)) @@ -650,6 +650,7 @@ class SlideController(DisplayController): self.mediabar.hide() self.songMenu.hide() self.toolbar.setWidgetVisible(self.loopList, False) + self.toolbar.setWidgetVisible([u'songMenu'], False) # Reset the button self.playSlidesOnce.setChecked(False) self.playSlidesOnce.setIcon(build_icon(u':/media/media_time.png')) @@ -657,7 +658,7 @@ class SlideController(DisplayController): self.playSlidesLoop.setIcon(build_icon(u':/media/media_time.png')) if item.is_text(): if Settings().value(self.parent().songsSettingsSection + u'/display songbar') and self.slideList: - self.songMenu.show() + self.toolbar.setWidgetVisible([u'songMenu'], True) if item.is_capable(ItemCapabilities.CanLoop) and len(item.get_frames()) > 1: self.toolbar.setWidgetVisible(self.loopList) if item.is_media(): From 6eba926a70ed98b03201e07eee218ebb2e8fa2b8 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 10 Feb 2013 20:08:37 +0100 Subject: [PATCH 02/48] improved hide menu behaviour --- openlp/core/ui/slidecontroller.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 4424081df..540b1f563 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -602,10 +602,14 @@ class SlideController(DisplayController): Change layout of display control buttons on controller size change """ if self.isLive: - if width > 300 and self.hideMenu.isVisible(): + # Space used by the toolbar. + used_space = self.toolbar.size().width() + self.hideMenu.size().width() + # The + 40 is needed to prevent flickering. This can be considered a "buffer". + if width > used_space + 40 and self.hideMenu.isVisible(): self.toolbar.setWidgetVisible(self.hideMenuList, False) self.toolbar.setWidgetVisible(self.wideMenu) - elif width < 300 and not self.hideMenu.isVisible(): + # The - 40 is needed to prevent flickering. This can be considered a "buffer". + elif width < used_space - 40 and not self.hideMenu.isVisible(): self.toolbar.setWidgetVisible(self.wideMenu, False) self.toolbar.setWidgetVisible(self.hideMenuList) From b119783a2c9b9197f373e9953a50f7959f489685 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Mon, 11 Feb 2013 18:08:32 +0000 Subject: [PATCH 03/48] Start of settings tests --- .../openlp_core_lib/test_settings.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 tests/functional/openlp_core_lib/test_settings.py diff --git a/tests/functional/openlp_core_lib/test_settings.py b/tests/functional/openlp_core_lib/test_settings.py new file mode 100644 index 000000000..18158eda1 --- /dev/null +++ b/tests/functional/openlp_core_lib/test_settings.py @@ -0,0 +1,19 @@ +""" + Package to test the openlp.core.lib package. +""" +import os + +from unittest import TestCase +from mock import MagicMock +from openlp.core.lib import Settings + +TESTPATH = os.path.abspath(os.path.join(os.path.dirname(__file__), u'..', u'..', u'resources')) + +class TestSettings(TestCase): + + def settings_basic_test(self): + """ + Test the Settings creation and its usage + """ + # GIVEN: A new Settings + settings = Settings() From b4a3833858293973054019bf90d944eb3268ff45 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Mon, 11 Feb 2013 19:20:08 +0000 Subject: [PATCH 04/48] Fix up tests - initial --- openlp/core/lib/settings.py | 2 +- .../openlp_core_lib/test_settings.py | 36 +++++++++++++++++-- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/openlp/core/lib/settings.py b/openlp/core/lib/settings.py index 7e72c6d4c..ce41198c4 100644 --- a/openlp/core/lib/settings.py +++ b/openlp/core/lib/settings.py @@ -343,7 +343,7 @@ class Settings(QtCore.QSettings): """ # On OS X (and probably on other platforms too) empty value from QSettings is represented as type # PyQt4.QtCore.QPyNullVariant. This type has to be converted to proper 'None' Python type. - if isinstance(setting, QtCore.QPyNullVariant) and setting.isNull(): + if setting.isNull() and isinstance(setting, QtCore.QPyNullVariant): setting = None # Handle 'None' type (empty value) properly. if setting is None: diff --git a/tests/functional/openlp_core_lib/test_settings.py b/tests/functional/openlp_core_lib/test_settings.py index 18158eda1..2cc0f2ee4 100644 --- a/tests/functional/openlp_core_lib/test_settings.py +++ b/tests/functional/openlp_core_lib/test_settings.py @@ -7,13 +7,43 @@ from unittest import TestCase from mock import MagicMock from openlp.core.lib import Settings +from PyQt4 import QtGui, QtTest + TESTPATH = os.path.abspath(os.path.join(os.path.dirname(__file__), u'..', u'..', u'resources')) class TestSettings(TestCase): + def setUp(self): + """ + Create the UI + """ + self.application = QtGui.QApplication([]) + self.application.setOrganizationName(u'OpenLP-tests') + self.application.setOrganizationDomain(u'openlp.org') + Settings() + + def tearDown(self): + """ + Delete all the C++ objects at the end so that we don't have a segfault + """ + del self.application + os.remove(Settings().fileName()) + def settings_basic_test(self): """ - Test the Settings creation and its usage + Test the Settings creation and its default usage """ - # GIVEN: A new Settings - settings = Settings() + # GIVEN: A new Settings setup + + # WHEN reading a setting for the first time + default_value = Settings().value(u'general/has run wizard') + + # THEN the default value is returned + assert default_value is False, u'The default value defined is returned' + + # WHEN a new value is saved into config + Settings().setValue(u'general/has run wizard', True) + + # THEN the new value is returned when re-read + assert Settings().value(u'general/has run wizard') is True, u'The saved value is returned' + From 19f9cb8c248534eca8c67d55da22fb404a6ae92c Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Mon, 11 Feb 2013 19:48:38 +0000 Subject: [PATCH 05/48] Fix key error in tests --- openlp/core/lib/settings.py | 3 +- .../openlp_core_lib/test_settings.py | 45 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/openlp/core/lib/settings.py b/openlp/core/lib/settings.py index ce41198c4..d75179d9f 100644 --- a/openlp/core/lib/settings.py +++ b/openlp/core/lib/settings.py @@ -322,7 +322,8 @@ class Settings(QtCore.QSettings): """ # if group() is not empty the group has not been specified together with the key. if self.group(): - default_value = Settings.__default_settings__[self.group() + u'/' + key] + qq = self.group() + u'/' + key + default_value = Settings.__default_settings__[unicode(self.group() + u'/' + key)] else: default_value = Settings.__default_settings__[key] setting = super(Settings, self).value(key, default_value) diff --git a/tests/functional/openlp_core_lib/test_settings.py b/tests/functional/openlp_core_lib/test_settings.py index 2cc0f2ee4..dfe6f4974 100644 --- a/tests/functional/openlp_core_lib/test_settings.py +++ b/tests/functional/openlp_core_lib/test_settings.py @@ -47,3 +47,48 @@ class TestSettings(TestCase): # THEN the new value is returned when re-read assert Settings().value(u'general/has run wizard') is True, u'The saved value is returned' + def settings_override_test(self): + """ + Test the Settings creation and its override usage + """ + # GIVEN: an override for the settings + screen_settings = { + u'test/extend': u'very wide', + } + Settings().extend_default_settings(screen_settings) + + # WHEN reading a setting for the first time + extend = Settings().value(u'test/extend') + + # THEN the default value is returned + assert extend == u'very wide', u'The default value defined is returned' + + # WHEN a new value is saved into config + Settings().setValue(u'test/extend', u'very short') + + # THEN the new value is returned when re-read + assert Settings().value(u'test/extend') == u'very short', u'The saved value is returned' + + def settings_override_with_group_test(self): + """ + Test the Settings creation and its override usage - with groups + """ + # GIVEN: an override for the settings + screen_settings = { + u'test/extend': u'very wide', + } + Settings.extend_default_settings(screen_settings) + + # WHEN reading a setting for the first time + settings = Settings() + settings.beginGroup(u'test') + extend = settings.value(u'extend') + + # THEN the default value is returned + assert extend == u'very wide', u'The default value defined is returned' + + # WHEN a new value is saved into config + Settings().setValue(u'test/extend', u'very short') + + # THEN the new value is returned when re-read + assert Settings().value(u'test/extend') == u'very short', u'The saved value is returned' \ No newline at end of file From 5bc10bf1a9f8ef2ea0af271ee8f3a9b9c2eb88a1 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Mon, 11 Feb 2013 19:54:18 +0000 Subject: [PATCH 06/48] Fix delete issue --- tests/functional/openlp_core_lib/test_settings.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/functional/openlp_core_lib/test_settings.py b/tests/functional/openlp_core_lib/test_settings.py index dfe6f4974..48cc7fead 100644 --- a/tests/functional/openlp_core_lib/test_settings.py +++ b/tests/functional/openlp_core_lib/test_settings.py @@ -27,7 +27,10 @@ class TestSettings(TestCase): Delete all the C++ objects at the end so that we don't have a segfault """ del self.application - os.remove(Settings().fileName()) + try: + os.remove(Settings().fileName()) + except: + pass def settings_basic_test(self): """ From a73d4cce08ae1f80f8b99bd38e45dedaae1b8f26 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Tue, 12 Feb 2013 16:42:09 +0000 Subject: [PATCH 07/48] Fix review comments --- openlp/core/lib/settings.py | 1 - tests/functional/openlp_core_lib/test_settings.py | 14 +++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/openlp/core/lib/settings.py b/openlp/core/lib/settings.py index d75179d9f..e9085477f 100644 --- a/openlp/core/lib/settings.py +++ b/openlp/core/lib/settings.py @@ -322,7 +322,6 @@ class Settings(QtCore.QSettings): """ # if group() is not empty the group has not been specified together with the key. if self.group(): - qq = self.group() + u'/' + key default_value = Settings.__default_settings__[unicode(self.group() + u'/' + key)] else: default_value = Settings.__default_settings__[key] diff --git a/tests/functional/openlp_core_lib/test_settings.py b/tests/functional/openlp_core_lib/test_settings.py index 48cc7fead..fd43b901e 100644 --- a/tests/functional/openlp_core_lib/test_settings.py +++ b/tests/functional/openlp_core_lib/test_settings.py @@ -4,13 +4,13 @@ import os from unittest import TestCase -from mock import MagicMock from openlp.core.lib import Settings from PyQt4 import QtGui, QtTest TESTPATH = os.path.abspath(os.path.join(os.path.dirname(__file__), u'..', u'..', u'resources')) + class TestSettings(TestCase): def setUp(self): @@ -29,7 +29,7 @@ class TestSettings(TestCase): del self.application try: os.remove(Settings().fileName()) - except: + except OSError: pass def settings_basic_test(self): @@ -42,13 +42,13 @@ class TestSettings(TestCase): default_value = Settings().value(u'general/has run wizard') # THEN the default value is returned - assert default_value is False, u'The default value defined is returned' + assert default_value is False, u'The default value defined has not been returned' # WHEN a new value is saved into config Settings().setValue(u'general/has run wizard', True) # THEN the new value is returned when re-read - assert Settings().value(u'general/has run wizard') is True, u'The saved value is returned' + assert Settings().value(u'general/has run wizard') is True, u'The saved value has not been returned' def settings_override_test(self): """ @@ -79,7 +79,7 @@ class TestSettings(TestCase): # GIVEN: an override for the settings screen_settings = { u'test/extend': u'very wide', - } + } Settings.extend_default_settings(screen_settings) # WHEN reading a setting for the first time @@ -88,10 +88,10 @@ class TestSettings(TestCase): extend = settings.value(u'extend') # THEN the default value is returned - assert extend == u'very wide', u'The default value defined is returned' + assert extend == u'very wide', u'The default value defined has not been returned' # WHEN a new value is saved into config Settings().setValue(u'test/extend', u'very short') # THEN the new value is returned when re-read - assert Settings().value(u'test/extend') == u'very short', u'The saved value is returned' \ No newline at end of file + assert Settings().value(u'test/extend') == u'very short', u'The saved value has not been returned' From 193e96ee5ab02407d72ebc8fb18bc5016ee8ceb3 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Tue, 12 Feb 2013 18:37:51 +0000 Subject: [PATCH 08/48] Unicode madness --- openlp/core/lib/settings.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/openlp/core/lib/settings.py b/openlp/core/lib/settings.py index e9085477f..eff6a36eb 100644 --- a/openlp/core/lib/settings.py +++ b/openlp/core/lib/settings.py @@ -343,8 +343,13 @@ class Settings(QtCore.QSettings): """ # On OS X (and probably on other platforms too) empty value from QSettings is represented as type # PyQt4.QtCore.QPyNullVariant. This type has to be converted to proper 'None' Python type. - if setting.isNull() and isinstance(setting, QtCore.QPyNullVariant): - setting = None + # Python wants the test one way but nose wants it the other way Madness! + try: + if isinstance(setting, QtCore.QPyNullVariant) and setting.isNull(): + setting = None + except AttributeError: + if setting.isNull() and isinstance(setting, QtCore.QPyNullVariant): + setting = None # Handle 'None' type (empty value) properly. if setting is None: # An empty string saved to the settings results in a None type being returned. From 6be6a54d6e56ba7e0770a225ae75bb6a95bdf92c Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Wed, 13 Feb 2013 17:33:37 +0000 Subject: [PATCH 09/48] Fix tests in the correct manner --- openlp/core/lib/settings.py | 11 +++-------- tests/functional/openlp_core_lib/__init__.py | 8 ++++++++ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/openlp/core/lib/settings.py b/openlp/core/lib/settings.py index eff6a36eb..7e72c6d4c 100644 --- a/openlp/core/lib/settings.py +++ b/openlp/core/lib/settings.py @@ -322,7 +322,7 @@ class Settings(QtCore.QSettings): """ # if group() is not empty the group has not been specified together with the key. if self.group(): - default_value = Settings.__default_settings__[unicode(self.group() + u'/' + key)] + default_value = Settings.__default_settings__[self.group() + u'/' + key] else: default_value = Settings.__default_settings__[key] setting = super(Settings, self).value(key, default_value) @@ -343,13 +343,8 @@ class Settings(QtCore.QSettings): """ # On OS X (and probably on other platforms too) empty value from QSettings is represented as type # PyQt4.QtCore.QPyNullVariant. This type has to be converted to proper 'None' Python type. - # Python wants the test one way but nose wants it the other way Madness! - try: - if isinstance(setting, QtCore.QPyNullVariant) and setting.isNull(): - setting = None - except AttributeError: - if setting.isNull() and isinstance(setting, QtCore.QPyNullVariant): - setting = None + if isinstance(setting, QtCore.QPyNullVariant) and setting.isNull(): + setting = None # Handle 'None' type (empty value) properly. if setting is None: # An empty string saved to the settings results in a None type being returned. diff --git a/tests/functional/openlp_core_lib/__init__.py b/tests/functional/openlp_core_lib/__init__.py index e69de29bb..e0da50eb3 100644 --- a/tests/functional/openlp_core_lib/__init__.py +++ b/tests/functional/openlp_core_lib/__init__.py @@ -0,0 +1,8 @@ +import sip +sip.setapi(u'QDate', 2) +sip.setapi(u'QDateTime', 2) +sip.setapi(u'QString', 2) +sip.setapi(u'QTextStream', 2) +sip.setapi(u'QTime', 2) +sip.setapi(u'QUrl', 2) +sip.setapi(u'QVariant', 2) \ No newline at end of file From bd0ff619a9a6fc8ffdede6a5255340964b5ba45e Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Thu, 14 Feb 2013 21:31:17 +0000 Subject: [PATCH 10/48] Clean up settings and alerts --- openlp/core/lib/settings.py | 7 +- openlp/core/ui/exceptionform.py | 11 +- openlp/core/ui/maindisplay.py | 12 +- openlp/core/ui/slidecontroller.py | 41 ++++-- openlp/plugins/alerts/alertsplugin.py | 9 +- openlp/plugins/alerts/forms/alertdialog.py | 116 +++++++-------- openlp/plugins/alerts/forms/alertform.py | 138 +++++++++--------- openlp/plugins/alerts/lib/alertsmanager.py | 17 ++- .../openlp_core_lib/test_settings.py | 2 +- 9 files changed, 192 insertions(+), 161 deletions(-) diff --git a/openlp/core/lib/settings.py b/openlp/core/lib/settings.py index 56821f1d1..e16b41e30 100644 --- a/openlp/core/lib/settings.py +++ b/openlp/core/lib/settings.py @@ -36,9 +36,8 @@ import sys from PyQt4 import QtCore, QtGui -from openlp.core.lib import SlideLimits +from openlp.core.lib import SlideLimits, UiStrings from openlp.core.lib.theme import ThemeLevel -from openlp.core.lib import UiStrings log = logging.getLogger(__name__) @@ -70,7 +69,8 @@ class Settings(QtCore.QSettings): ``__obsolete_settings__`` Each entry is structured in the following way:: - (u'general/enable slide loop', u'advanced/slide limits', [(SlideLimits.Wrap, True), (SlideLimits.End, False)]) + (u'general/enable slide loop', u'advanced/slide limits', + [(SlideLimits.Wrap, True), (SlideLimits.End, False)]) The first entry is the *old key*; it will be removed. @@ -259,7 +259,6 @@ class Settings(QtCore.QSettings): """ Settings.__default_settings__ = dict(default_values.items() + Settings.__default_settings__.items()) - @staticmethod def set_filename(ini_file): """ diff --git a/openlp/core/ui/exceptionform.py b/openlp/core/ui/exceptionform.py index 0d8a7c74f..50885b15b 100644 --- a/openlp/core/ui/exceptionform.py +++ b/openlp/core/ui/exceptionform.py @@ -106,7 +106,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog): """ QtGui.QDialog.__init__(self, parent) self.setupUi(self) - self.settingsSection = u'crashreport' + self.settings_section = u'crashreport' def exec_(self): """ @@ -159,12 +159,11 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog): '--- Library Versions ---\n%s\n') filename = QtGui.QFileDialog.getSaveFileName(self, translate('OpenLP.ExceptionForm', 'Save Crash Report'), - Settings().value(self.settingsSection + u'/last directory'), - translate('OpenLP.ExceptionForm', - 'Text files (*.txt *.log *.text)')) + Settings().value(self.settings_section + u'/last directory'), + translate('OpenLP.ExceptionForm', 'Text files (*.txt *.log *.text)')) if filename: filename = unicode(filename).replace(u'/', os.path.sep) - Settings().setValue(self.settingsSection + u'/last directory', os.path.dirname(filename)) + Settings().setValue(self.settings_section + u'/last directory', os.path.dirname(filename)) report_text = report_text % self._createReport() try: report_file = open(filename, u'w') @@ -230,7 +229,7 @@ class ExceptionForm(QtGui.QDialog, Ui_ExceptionDialog): """ files = QtGui.QFileDialog.getOpenFileName( self, translate('ImagePlugin.ExceptionDialog', 'Select Attachment'), - Settings().value(self.settingsSection + u'/last directory'), u'%s (*.*) (*)' % UiStrings().AllFiles) + Settings().value(self.settings_section + u'/last directory'), u'%s (*.*) (*)' % UiStrings().AllFiles) log.info(u'New files(s) %s', unicode(files)) if files: self.fileAttachment = unicode(files) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 661516e7d..58d832101 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -300,7 +300,7 @@ class MainDisplay(Display): self.image(path) # Update the preview frame. if self.isLive: - self.parent().updatePreview() + self.live_controller.updatePreview() return True def image(self, path): @@ -513,6 +513,16 @@ class MainDisplay(Display): application = property(_get_application) + 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) + class AudioPlayer(QtCore.QObject): """ diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index e3c42a2f9..3390ff84e 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -230,7 +230,7 @@ class SlideController(DisplayController): self.playSlidesOnce = create_action(self, u'playSlidesOnce', text=UiStrings().PlaySlidesToEnd, icon=u':/media/media_time.png', checked=False, shortcuts=[], category=self.category, triggers=self.onPlaySlidesOnce) - if Settings().value(self.parent().advancedSettingsSection + u'/slide limits') == SlideLimits.Wrap: + if Settings().value(self.main_window.advancedSettingsSection + u'/slide limits') == SlideLimits.Wrap: self.playSlidesMenu.setDefaultAction(self.playSlidesLoop) else: self.playSlidesMenu.setDefaultAction(self.playSlidesOnce) @@ -582,7 +582,7 @@ class SlideController(DisplayController): self.previewListWidget.resizeRowsToContents() else: # Sort out image heights. - width = self.parent().controlSplitter.sizes()[self.split] + width = self.main_window.controlSplitter.sizes()[self.split] for framenumber in range(len(self.serviceItem.get_frames())): self.previewListWidget.setRowHeight(framenumber, width / self.ratio) self.onControllerSizeChanged(self.controller.width(), self.controller.height()) @@ -618,7 +618,7 @@ class SlideController(DisplayController): """ Updates the Slide Limits variable from the settings. """ - self.slide_limits = Settings().value(self.parent().advancedSettingsSection + u'/slide limits') + self.slide_limits = Settings().value(self.main_window.advancedSettingsSection + u'/slide limits') def enableToolBar(self, item): """ @@ -646,7 +646,7 @@ class SlideController(DisplayController): self.playSlidesLoop.setChecked(False) self.playSlidesLoop.setIcon(build_icon(u':/media/media_time.png')) if item.is_text(): - if Settings().value(self.parent().songsSettingsSection + u'/display songbar') and self.slideList: + if Settings().value(self.main_window.songsSettingsSection + u'/display songbar') and self.slideList: self.songMenu.show() if item.is_capable(ItemCapabilities.CanLoop) and len(item.get_frames()) > 1: self.toolbar.setWidgetVisible(self.loopList) @@ -748,7 +748,7 @@ class SlideController(DisplayController): self._resetBlank() Registry().execute(u'%s_start' % serviceItem.name.lower(), [serviceItem, self.isLive, self.hideMode(), slideno]) self.slideList = {} - width = self.parent().controlSplitter.sizes()[self.split] + width = self.main_window.controlSplitter.sizes()[self.split] self.previewListWidget.clear() self.previewListWidget.setRowCount(0) self.previewListWidget.setColumnWidth(0, width) @@ -767,8 +767,8 @@ class SlideController(DisplayController): action.setData(counter) QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'), self.onTrackTriggered) self.display.audioPlayer.repeat = Settings().value( - self.parent().generalSettingsSection + u'/audio repeat list') - if Settings().value(self.parent().generalSettingsSection + u'/audio start paused'): + self.main_window.generalSettingsSection + u'/audio repeat list') + if Settings().value(self.main_window.generalSettingsSection + u'/audio start paused'): self.audioPauseItem.setChecked(True) self.display.audioPlayer.pause() else: @@ -877,7 +877,7 @@ class SlideController(DisplayController): Allow the main display to blank the main display at startup time """ log.debug(u'mainDisplaySetBackground live = %s' % self.isLive) - display_type = Settings().value(self.parent().generalSettingsSection + u'/screen blank') + display_type = Settings().value(self.main_window.generalSettingsSection + u'/screen blank') if self.screens.which_screen(self.window()) != self.screens.which_screen(self.display): # Order done to handle initial conversion if display_type == u'themed': @@ -915,9 +915,9 @@ class SlideController(DisplayController): self.themeScreen.setChecked(False) self.desktopScreen.setChecked(False) if checked: - Settings().setValue(self.parent().generalSettingsSection + u'/screen blank', u'blanked') + Settings().setValue(self.main_window.generalSettingsSection + u'/screen blank', u'blanked') else: - Settings().remove(self.parent().generalSettingsSection + u'/screen blank') + Settings().remove(self.main_window.generalSettingsSection + u'/screen blank') self.blankPlugin() self.updatePreview() self.onToggleLoop() @@ -934,9 +934,9 @@ class SlideController(DisplayController): self.themeScreen.setChecked(checked) self.desktopScreen.setChecked(False) if checked: - Settings().setValue(self.parent().generalSettingsSection + u'/screen blank', u'themed') + Settings().setValue(self.main_window.generalSettingsSection + u'/screen blank', u'themed') else: - Settings().remove(self.parent().generalSettingsSection + u'/screen blank') + Settings().remove(self.main_window.generalSettingsSection + u'/screen blank') self.blankPlugin() self.updatePreview() self.onToggleLoop() @@ -953,9 +953,9 @@ class SlideController(DisplayController): self.themeScreen.setChecked(False) self.desktopScreen.setChecked(checked) if checked: - Settings().setValue(self.parent().generalSettingsSection + u'/screen blank', u'hidden') + Settings().setValue(self.main_window.generalSettingsSection + u'/screen blank', u'hidden') else: - Settings().remove(self.parent().generalSettingsSection + u'/screen blank') + Settings().remove(self.main_window.generalSettingsSection + u'/screen blank') self.hidePlugin(checked) self.updatePreview() self.onToggleLoop() @@ -1255,7 +1255,7 @@ class SlideController(DisplayController): def onGoLive(self): """ - If preview copy slide item to live + If preview copy slide item to live controller from Preview Controller """ row = self.previewListWidget.currentRow() if -1 < row < self.previewListWidget.rowCount(): @@ -1384,3 +1384,14 @@ class SlideController(DisplayController): return self._live_controller live_controller = property(_get_live_controller) + + 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) + diff --git a/openlp/plugins/alerts/alertsplugin.py b/openlp/plugins/alerts/alertsplugin.py index de2c92f7e..111abf795 100644 --- a/openlp/plugins/alerts/alertsplugin.py +++ b/openlp/plugins/alerts/alertsplugin.py @@ -122,7 +122,7 @@ __default_settings__ = { u'alerts/background color': u'#660000', u'alerts/font color': u'#ffffff', u'alerts/timeout': 5 - } +} class AlertsPlugin(Plugin): @@ -133,7 +133,7 @@ class AlertsPlugin(Plugin): self.weight = -3 self.iconPath = u':/plugins/plugin_alerts.png' self.icon = build_icon(self.iconPath) - self.alertsmanager = AlertsManager(self) + self.alerts_manager = AlertsManager(self) self.manager = Manager(u'alerts', init_schema) self.alertForm = AlertForm(self) @@ -176,7 +176,7 @@ class AlertsPlugin(Plugin): Settings().setValue(self.settingsSection + u'/active', self.alertsActive) def onAlertsTrigger(self): - self.alertForm.loadList() + self.alertForm.load_list() self.alertForm.exec_() def about(self): @@ -194,7 +194,8 @@ class AlertsPlugin(Plugin): u'plural': translate('AlertsPlugin', 'Alerts', 'name plural') } ## Name for MediaDockManager, SettingsManager ## - self.textStrings[StringContent.VisibleName] = {u'title': translate('AlertsPlugin', 'Alerts', 'container title') + self.textStrings[StringContent.VisibleName] = { + u'title': translate('AlertsPlugin', 'Alerts', 'container title') } def getDisplayJavaScript(self): diff --git a/openlp/plugins/alerts/forms/alertdialog.py b/openlp/plugins/alerts/forms/alertdialog.py index 1ca5a1113..1985fdcd1 100644 --- a/openlp/plugins/alerts/forms/alertdialog.py +++ b/openlp/plugins/alerts/forms/alertdialog.py @@ -32,61 +32,63 @@ from PyQt4 import QtGui from openlp.core.lib import build_icon, translate from openlp.core.lib.ui import create_button, create_button_box -class Ui_AlertDialog(object): - def setupUi(self, alertDialog): - alertDialog.setObjectName(u'alertDialog') - alertDialog.resize(400, 300) - alertDialog.setWindowIcon(build_icon(u':/icon/openlp-logo-16x16.png')) - self.alertDialogLayout = QtGui.QGridLayout(alertDialog) - self.alertDialogLayout.setObjectName(u'alertDialogLayout') - self.alertTextLayout = QtGui.QFormLayout() - self.alertTextLayout.setObjectName(u'alertTextLayout') - self.alertEntryLabel = QtGui.QLabel(alertDialog) - self.alertEntryLabel.setObjectName(u'alertEntryLabel') - self.alertTextEdit = QtGui.QLineEdit(alertDialog) - self.alertTextEdit.setObjectName(u'alertTextEdit') - self.alertEntryLabel.setBuddy(self.alertTextEdit) - self.alertTextLayout.addRow(self.alertEntryLabel, self.alertTextEdit) - self.alertParameter = QtGui.QLabel(alertDialog) - self.alertParameter.setObjectName(u'alertParameter') - self.parameterEdit = QtGui.QLineEdit(alertDialog) - self.parameterEdit.setObjectName(u'parameterEdit') - self.alertParameter.setBuddy(self.parameterEdit) - self.alertTextLayout.addRow(self.alertParameter, self.parameterEdit) - self.alertDialogLayout.addLayout(self.alertTextLayout, 0, 0, 1, 2) - self.alertListWidget = QtGui.QListWidget(alertDialog) - self.alertListWidget.setAlternatingRowColors(True) - self.alertListWidget.setObjectName(u'alertListWidget') - self.alertDialogLayout.addWidget(self.alertListWidget, 1, 0) - self.manageButtonLayout = QtGui.QVBoxLayout() - self.manageButtonLayout.setObjectName(u'manageButtonLayout') - self.newButton = QtGui.QPushButton(alertDialog) - self.newButton.setIcon(build_icon(u':/general/general_new.png')) - self.newButton.setObjectName(u'newButton') - self.manageButtonLayout.addWidget(self.newButton) - self.saveButton = QtGui.QPushButton(alertDialog) - self.saveButton.setEnabled(False) - self.saveButton.setIcon(build_icon(u':/general/general_save.png')) - self.saveButton.setObjectName(u'saveButton') - self.manageButtonLayout.addWidget(self.saveButton) - self.deleteButton = create_button(alertDialog, u'deleteButton', role=u'delete', enabled=False, - click=alertDialog.onDeleteButtonClicked) - self.manageButtonLayout.addWidget(self.deleteButton) - self.manageButtonLayout.addStretch() - self.alertDialogLayout.addLayout(self.manageButtonLayout, 1, 1) - displayIcon = build_icon(u':/general/general_live.png') - self.displayButton = create_button(alertDialog, u'displayButton', icon=displayIcon, enabled=False) - self.displayCloseButton = create_button(alertDialog, u'displayCloseButton', icon=displayIcon, enabled=False) - self.button_box = create_button_box(alertDialog, u'button_box', [u'close'], - [self.displayButton, self.displayCloseButton]) - self.alertDialogLayout.addWidget(self.button_box, 2, 0, 1, 2) - self.retranslateUi(alertDialog) - def retranslateUi(self, alertDialog): - alertDialog.setWindowTitle(translate('AlertsPlugin.AlertForm', 'Alert Message')) - self.alertEntryLabel.setText(translate('AlertsPlugin.AlertForm', 'Alert &text:')) - self.alertParameter.setText(translate('AlertsPlugin.AlertForm', '&Parameter:')) - self.newButton.setText(translate('AlertsPlugin.AlertForm', '&New')) - self.saveButton.setText(translate('AlertsPlugin.AlertForm', '&Save')) - self.displayButton.setText(translate('AlertsPlugin.AlertForm', 'Displ&ay')) - self.displayCloseButton.setText(translate('AlertsPlugin.AlertForm', 'Display && Cl&ose')) +class Ui_AlertDialog(object): + def setupUi(self, alert_dialog): + alert_dialog.setObjectName(u'alert_dialog') + alert_dialog.resize(400, 300) + alert_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo-16x16.png')) + self.alert_dialog_layout = QtGui.QGridLayout(alert_dialog) + self.alert_dialog_layout.setObjectName(u'alert_dialog_layout') + self.alert_text_layout = QtGui.QFormLayout() + self.alert_text_layout.setObjectName(u'alert_text_layout') + self.alert_entry_label = QtGui.QLabel(alert_dialog) + self.alert_entry_label.setObjectName(u'alert_entry_label') + self.alert_text_edit = QtGui.QLineEdit(alert_dialog) + self.alert_text_edit.setObjectName(u'alert_text_edit') + self.alert_entry_label.setBuddy(self.alert_text_edit) + self.alert_text_layout.addRow(self.alert_entry_label, self.alert_text_edit) + self.alert_parameter = QtGui.QLabel(alert_dialog) + self.alert_parameter.setObjectName(u'alert_parameter') + self.parameter_edit = QtGui.QLineEdit(alert_dialog) + self.parameter_edit.setObjectName(u'parameter_edit') + self.alert_parameter.setBuddy(self.parameter_edit) + self.alert_text_layout.addRow(self.alert_parameter, self.parameter_edit) + self.alert_dialog_layout.addLayout(self.alert_text_layout, 0, 0, 1, 2) + self.alert_list_widget = QtGui.QListWidget(alert_dialog) + self.alert_list_widget.setAlternatingRowColors(True) + self.alert_list_widget.setObjectName(u'alert_list_widget') + self.alert_dialog_layout.addWidget(self.alert_list_widget, 1, 0) + self.manage_button_layout = QtGui.QVBoxLayout() + self.manage_button_layout.setObjectName(u'manage_button_layout') + self.new_button = QtGui.QPushButton(alert_dialog) + self.new_button.setIcon(build_icon(u':/general/general_new.png')) + self.new_button.setObjectName(u'new_button') + self.manage_button_layout.addWidget(self.new_button) + self.save_button = QtGui.QPushButton(alert_dialog) + self.save_button.setEnabled(False) + self.save_button.setIcon(build_icon(u':/general/general_save.png')) + self.save_button.setObjectName(u'save_button') + self.manage_button_layout.addWidget(self.save_button) + self.delete_button = create_button(alert_dialog, u'delete_button', role=u'delete', enabled=False, + click=alert_dialog.onDeleteButtonClicked) + self.manage_button_layout.addWidget(self.delete_button) + self.manage_button_layout.addStretch() + self.alert_dialog_layout.addLayout(self.manage_button_layout, 1, 1) + displayIcon = build_icon(u':/general/general_live.png') + self.display_button = create_button(alert_dialog, u'display_button', icon=displayIcon, enabled=False) + self.display_close_button = create_button(alert_dialog, u'display_close_button', icon=displayIcon, + enabled=False) + self.button_box = create_button_box(alert_dialog, u'button_box', [u'close'], + [self.display_button, self.display_close_button]) + self.alert_dialog_layout.addWidget(self.button_box, 2, 0, 1, 2) + self.retranslateUi(alert_dialog) + + def retranslateUi(self, alert_dialog): + alert_dialog.setWindowTitle(translate('AlertsPlugin.AlertForm', 'Alert Message')) + self.alert_entry_label.setText(translate('AlertsPlugin.AlertForm', 'Alert &text:')) + self.alert_parameter.setText(translate('AlertsPlugin.AlertForm', '&Parameter:')) + self.new_button.setText(translate('AlertsPlugin.AlertForm', '&New')) + self.save_button.setText(translate('AlertsPlugin.AlertForm', '&Save')) + self.display_button.setText(translate('AlertsPlugin.AlertForm', 'Displ&ay')) + self.display_close_button.setText(translate('AlertsPlugin.AlertForm', 'Display && Cl&ose')) diff --git a/openlp/plugins/alerts/forms/alertform.py b/openlp/plugins/alerts/forms/alertform.py index c09180702..64aca1e26 100644 --- a/openlp/plugins/alerts/forms/alertform.py +++ b/openlp/plugins/alerts/forms/alertform.py @@ -48,131 +48,131 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog): self.item_id = None super(AlertForm, self).__init__(self.plugin.main_window) self.setupUi(self) - QtCore.QObject.connect(self.displayButton, QtCore.SIGNAL(u'clicked()'), self.onDisplayClicked) - QtCore.QObject.connect(self.displayCloseButton, QtCore.SIGNAL(u'clicked()'), self.onDisplayCloseClicked) - QtCore.QObject.connect(self.alertTextEdit, QtCore.SIGNAL(u'textChanged(const QString&)'), self.onTextChanged) - QtCore.QObject.connect(self.newButton, QtCore.SIGNAL(u'clicked()'), self.onNewClick) - QtCore.QObject.connect(self.saveButton, QtCore.SIGNAL(u'clicked()'), self.onSaveClick) - QtCore.QObject.connect(self.alertListWidget, QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onDoubleClick) - QtCore.QObject.connect(self.alertListWidget, QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSingleClick) - QtCore.QObject.connect(self.alertListWidget, QtCore.SIGNAL(u'currentRowChanged(int)'), self.onCurrentRowChanged) + self.display_button.clicked.connect(self.on_display_clicked) + self.display_close_button.clicked.connect(self.on_display_close_clicked) + self.alert_text_edit.textChanged.connect(self.on_text_changed) + self.new_button.clicked.connect(self.on_new_click) + self.save_button.clicked.connect(self.on_save_all) + self.alert_list_widget.doubleClicked.connect(self.on_double_click) + self.alert_list_widget.clicked.connect(self.on_single_click) + self.alert_list_widget.currentRowChanged.connect(self.on_current_row_changed) def exec_(self): """ Execute the dialog and return the exit code. """ - self.displayButton.setEnabled(False) - self.displayCloseButton.setEnabled(False) - self.alertTextEdit.setText(u'') + self.display_button.setEnabled(False) + self.display_close_button.setEnabled(False) + self.alert_text_edit.setText(u'') return QtGui.QDialog.exec_(self) - def loadList(self): + def load_list(self): """ Loads the list with alerts. """ - self.alertListWidget.clear() + self.alert_list_widget.clear() alerts = self.manager.get_all_objects(AlertItem, order_by_ref=AlertItem.text) for alert in alerts: item_name = QtGui.QListWidgetItem(alert.text) item_name.setData(QtCore.Qt.UserRole, alert.id) - self.alertListWidget.addItem(item_name) - if alert.text == unicode(self.alertTextEdit.text()): + self.alert_list_widget.addItem(item_name) + if alert.text == unicode(self.alert_text_edit.text()): self.item_id = alert.id - self.alertListWidget.setCurrentRow(self.alertListWidget.row(item_name)) + self.alert_list_widget.setCurrentRow(self.alert_list_widget.row(item_name)) - def onDisplayClicked(self): + def on_display_clicked(self): """ Display the current alert text. """ - self.triggerAlert(self.alertTextEdit.text()) + self.trigger_alert(self.alert_text_edit.text()) - def onDisplayCloseClicked(self): + def on_display_close_clicked(self): """ Close the alert preview. """ - if self.triggerAlert(self.alertTextEdit.text()): + if self.trigger_alert(self.alert_text_edit.text()): self.close() def onDeleteButtonClicked(self): """ Deletes the selected item. """ - item = self.alertListWidget.currentItem() + item = self.alert_list_widget.currentItem() if item: item_id = item.data(QtCore.Qt.UserRole) self.manager.delete_object(AlertItem, item_id) - row = self.alertListWidget.row(item) - self.alertListWidget.takeItem(row) + row = self.alert_list_widget.row(item) + self.alert_list_widget.takeItem(row) self.item_id = None - self.alertTextEdit.setText(u'') + self.alert_text_edit.setText(u'') - def onNewClick(self): + def on_new_click(self): """ Create a new alert. """ - if not self.alertTextEdit.text(): + if not self.alert_text_edit.text(): QtGui.QMessageBox.information(self, translate('AlertsPlugin.AlertForm', 'New Alert'), translate('AlertsPlugin.AlertForm', 'You haven\'t specified any text for your alert. \n' 'Please type in some text before clicking New.')) else: alert = AlertItem() - alert.text = self.alertTextEdit.text() + alert.text = self.alert_text_edit.text() self.manager.save_object(alert) - self.loadList() + self.load_list() - def onSaveClick(self): + def on_save_all(self): """ Save the alert, we are editing. """ if self.item_id: alert = self.manager.get_object(AlertItem, self.item_id) - alert.text = self.alertTextEdit.text() + alert.text = self.alert_text_edit.text() self.manager.save_object(alert) self.item_id = None - self.loadList() - self.saveButton.setEnabled(False) + self.load_list() + self.save_button.setEnabled(False) - def onTextChanged(self): + def on_text_changed(self): """ Enable save button when data has been changed by editing the form. """ # Only enable the button, if we are editing an item. if self.item_id: - self.saveButton.setEnabled(True) - if self.alertTextEdit.text(): - self.displayButton.setEnabled(True) - self.displayCloseButton.setEnabled(True) + self.save_button.setEnabled(True) + if self.alert_text_edit.text(): + self.display_button.setEnabled(True) + self.display_close_button.setEnabled(True) else: - self.displayButton.setEnabled(False) - self.displayCloseButton.setEnabled(False) + self.display_button.setEnabled(False) + self.display_close_button.setEnabled(False) - def onDoubleClick(self): + def on_double_click(self): """ List item has been double clicked to display it. """ - item = self.alertListWidget.selectedIndexes()[0] - bitem = self.alertListWidget.item(item.row()) - self.triggerAlert(bitem.text()) - self.alertTextEdit.setText(bitem.text()) + item = self.alert_list_widget.selectedIndexes()[0] + bitem = self.alert_list_widget.item(item.row()) + self.trigger_alert(bitem.text()) + self.alert_text_edit.setText(bitem.text()) self.item_id = bitem.data(QtCore.Qt.UserRole) - self.saveButton.setEnabled(False) + self.save_button.setEnabled(False) - def onSingleClick(self): + def on_single_click(self): """ List item has been single clicked to add it to the edit field so it can be changed. """ - item = self.alertListWidget.selectedIndexes()[0] - bitem = self.alertListWidget.item(item.row()) - self.alertTextEdit.setText(bitem.text()) + item = self.alert_list_widget.selectedIndexes()[0] + bitem = self.alert_list_widget.item(item.row()) + self.alert_text_edit.setText(bitem.text()) self.item_id = bitem.data(QtCore.Qt.UserRole) # If the alert does not contain '<>' we clear the ParameterEdit field. - if self.alertTextEdit.text().find(u'<>') == -1: - self.parameterEdit.setText(u'') - self.saveButton.setEnabled(False) + if self.alert_text_edit.text().find(u'<>') == -1: + self.parameter_edit.setText(u'') + self.save_button.setEnabled(False) - def triggerAlert(self, text): + def trigger_alert(self, text): """ Prepares the alert text for displaying. @@ -182,42 +182,42 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog): if not text: return False # We found '<>' in the alert text, but the ParameterEdit field is empty. - if text.find(u'<>') != -1 and not self.parameterEdit.text() and QtGui.QMessageBox.question(self, + if text.find(u'<>') != -1 and not self.parameter_edit.text() and QtGui.QMessageBox.question(self, translate('AlertsPlugin.AlertForm', 'No Parameter Found'), translate('AlertsPlugin.AlertForm', 'You have not entered a parameter to be replaced.\n' 'Do you want to continue anyway?'), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.No: - self.parameterEdit.setFocus() + self.parameter_edit.setFocus() return False # The ParameterEdit field is not empty, but we have not found '<>' # in the alert text. - elif text.find(u'<>') == -1 and self.parameterEdit.text() and QtGui.QMessageBox.question(self, + elif text.find(u'<>') == -1 and self.parameter_edit.text() and QtGui.QMessageBox.question(self, translate('AlertsPlugin.AlertForm', 'No Placeholder Found'), translate('AlertsPlugin.AlertForm', 'The alert text does not contain \'<>\'.\n' 'Do you want to continue anyway?'), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.No: - self.parameterEdit.setFocus() + self.parameter_edit.setFocus() return False - text = text.replace(u'<>', self.parameterEdit.text()) - self.plugin.alertsmanager.displayAlert(text) + text = text.replace(u'<>', self.parameter_edit.text()) + self.plugin.alerts_manager.display_alert(text) return True - def onCurrentRowChanged(self, row): + def on_current_row_changed(self, row): """ - Called when the *alertListWidget*'s current row has been changed. This + Called when the *alert_list_widget*'s current row has been changed. This enables or disables buttons which require an item to act on. ``row`` The row (int). If there is no current row, the value is -1. """ if row == -1: - self.displayButton.setEnabled(False) - self.displayCloseButton.setEnabled(False) - self.saveButton.setEnabled(False) - self.deleteButton.setEnabled(False) + self.display_button.setEnabled(False) + self.display_close_button.setEnabled(False) + self.save_button.setEnabled(False) + self.delete_button.setEnabled(False) else: - self.displayButton.setEnabled(True) - self.displayCloseButton.setEnabled(True) - self.deleteButton.setEnabled(True) + self.display_button.setEnabled(True) + self.display_close_button.setEnabled(True) + self.delete_button.setEnabled(True) # We do not need to enable the save button, as it is only enabled - # when typing text in the "alertTextEdit". + # when typing text in the "alert_text_edit". diff --git a/openlp/plugins/alerts/lib/alertsmanager.py b/openlp/plugins/alerts/lib/alertsmanager.py index 03f36f09e..7cfea701e 100644 --- a/openlp/plugins/alerts/lib/alertsmanager.py +++ b/openlp/plugins/alerts/lib/alertsmanager.py @@ -47,7 +47,6 @@ class AlertsManager(QtCore.QObject): def __init__(self, parent): QtCore.QObject.__init__(self, parent) - self.screen = None self.timer_id = 0 self.alert_list = [] Registry().register_function(u'live_display_active', self.generate_alert) @@ -87,7 +86,7 @@ class AlertsManager(QtCore.QObject): return text = self.alert_list.pop(0) alertTab = self.parent().settingsTab - self.parent().liveController.display.alert(text, alertTab.location) + self.live_controller.display.alert(text, alertTab.location) # Check to see if we have a timer running. if self.timer_id == 0: self.timer_id = self.startTimer(int(alertTab.timeout) * 1000) @@ -103,7 +102,7 @@ class AlertsManager(QtCore.QObject): log.debug(u'timer event') if event.timerId() == self.timer_id: alertTab = self.parent().settingsTab - self.parent().liveController.display.alert(u'', alertTab.location) + self.live_controller.display.alert(u'', alertTab.location) self.killTimer(self.timer_id) self.timer_id = 0 self.generate_alert() @@ -116,4 +115,14 @@ class AlertsManager(QtCore.QObject): self._main_window = Registry().get(u'main_window') return self._main_window - main_window = property(_get_main_window) \ No newline at end of file + main_window = property(_get_main_window) + + 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) diff --git a/tests/functional/openlp_core_lib/test_settings.py b/tests/functional/openlp_core_lib/test_settings.py index fd43b901e..779a1569d 100644 --- a/tests/functional/openlp_core_lib/test_settings.py +++ b/tests/functional/openlp_core_lib/test_settings.py @@ -42,7 +42,7 @@ class TestSettings(TestCase): default_value = Settings().value(u'general/has run wizard') # THEN the default value is returned - assert default_value is False, u'The default value defined has not been returned' + assert default_value is False, u'The default value should be False' # WHEN a new value is saved into config Settings().setValue(u'general/has run wizard', True) From c6ad115b103d681986bd7210be1e2d22060c14d0 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Thu, 14 Feb 2013 21:50:10 +0000 Subject: [PATCH 11/48] More Signal removals --- openlp/core/lib/ui.py | 9 ++++----- openlp/core/ui/servicemanager.py | 15 +++++---------- openlp/core/ui/thememanager.py | 9 +++------ 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index f4f29c36a..e09f4d164 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -109,8 +109,8 @@ def create_button_box(dialog, name, standard_buttons, custom_buttons=None): button_box.addButton(button, QtGui.QDialogButtonBox.ActionRole) else: button_box.addButton(*button) - QtCore.QObject.connect(button_box, QtCore.SIGNAL(u'accepted()'), dialog.accept) - QtCore.QObject.connect(button_box, QtCore.SIGNAL(u'rejected()'), dialog.reject) + button_box.accepted.connect(dialog.accept) + button_box.rejected.connect(dialog.reject) return button_box @@ -211,7 +211,7 @@ def create_button(parent, name, **kwargs): if not kwargs.pop(u'enabled', True): button.setEnabled(False) if kwargs.get(u'click'): - QtCore.QObject.connect(button, QtCore.SIGNAL(u'clicked()'), kwargs.pop(u'click')) + button.clicked.connect(kwargs.pop(u'click')) for key in kwargs.keys(): if key not in [u'text', u'icon', u'tooltip', u'click']: log.warn(u'Parameter %s was not consumed in create_button().', key) @@ -297,8 +297,7 @@ def create_action(parent, name, **kwargs): action_list = ActionList.get_instance() action_list.add_action(action, unicode(kwargs.pop(u'category'))) if kwargs.get(u'triggers'): - QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'), - kwargs.pop(u'triggers')) + action.triggered.connect(kwargs.pop(u'triggers')) 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']: log.warn(u'Parameter %s was not consumed in create_action().', key) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 23315d5e8..7762d72aa 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -142,8 +142,7 @@ class ServiceManagerDialog(object): self.service_manager_list.setHeaderHidden(True) self.service_manager_list.setExpandsOnDoubleClick(False) self.service_manager_list.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) - QtCore.QObject.connect(self.service_manager_list, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), - self.context_menu) + self.service_manager_list.customContextMenuRequested.connect(self.context_menu) self.service_manager_list.setObjectName(u'service_manager_list') # enable drop self.service_manager_list.__class__.dragEnterEvent = self.drag_enter_event @@ -202,14 +201,10 @@ class ServiceManagerDialog(object): triggers=self.make_live) self.layout.addWidget(self.order_toolbar) # Connect up our signals and slots - QtCore.QObject.connect(self.theme_combo_box, QtCore.SIGNAL(u'activated(int)'), - self.on_theme_combo_box_selected) - QtCore.QObject.connect(self.service_manager_list, QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), - self.on_make_live) - QtCore.QObject.connect(self.service_manager_list, QtCore.SIGNAL(u'itemCollapsed(QTreeWidgetItem*)'), - self.collapsed) - QtCore.QObject.connect(self.service_manager_list, QtCore.SIGNAL(u'itemExpanded(QTreeWidgetItem*)'), - self.expanded) + self.theme_combo_box.activated.connect(self.on_theme_combo_box_selected) + self.service_manager_list.doubleClicked.connect(self.on_make_live) + self.service_manager_list.itemCollapsed.connect(self.collapsed) + self.service_manager_list.itemExpanded.connect(self.expanded) Registry().register_function(u'theme_update_list', self.update_theme_list) Registry().register_function(u'config_updated', self.config_updated) Registry().register_function(u'config_screen_changed', self.regenerate_service_Items) diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index c58a8aefd..ed8f5c9fc 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -105,8 +105,7 @@ class ThemeManager(QtGui.QWidget): self.theme_list_widget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.theme_list_widget.setObjectName(u'theme_list_widget') self.layout.addWidget(self.theme_list_widget) - QtCore.QObject.connect(self.theme_list_widget, QtCore.SIGNAL('customContextMenuRequested(QPoint)'), - self.context_menu) + self.theme_list_widget.customContextMenuRequested.connect(self.context_menu) # build the context menu self.menu = QtGui.QMenu() self.edit_action = create_widget_action(self.menu, @@ -130,10 +129,8 @@ class ThemeManager(QtGui.QWidget): text=translate('OpenLP.ThemeManager', '&Export Theme'), icon=u':/general/general_export.png', triggers=self.on_export_theme) # Signals - QtCore.QObject.connect(self.theme_list_widget, - QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.change_global_from_screen) - QtCore.QObject.connect(self.theme_list_widget, - QtCore.SIGNAL(u'currentItemChanged(QListWidgetItem *, QListWidgetItem *)'), self.check_list_state) + self.theme_list_widget.doubleClicked.connect(self.change_global_from_screen) + self.theme_list_widget.currentItemChanged.connect(self.check_list_state) Registry().register_function(u'theme_update_global', self.change_global_from_tab) Registry().register_function(u'config_updated', self.config_updated) # Variables From ab31ffb77598e401edd48fa99fbbac14da496497 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 16 Feb 2013 10:38:02 +0000 Subject: [PATCH 12/48] Cleaning up SongUsage --- .../songusage/forms/songusagedeletedialog.py | 47 +++---- .../songusage/forms/songusagedeleteform.py | 13 +- .../songusage/forms/songusagedetaildialog.py | 88 ++++++------ .../songusage/forms/songusagedetailform.py | 47 +++---- openlp/plugins/songusage/songusageplugin.py | 128 +++++++++--------- 5 files changed, 161 insertions(+), 162 deletions(-) diff --git a/openlp/plugins/songusage/forms/songusagedeletedialog.py b/openlp/plugins/songusage/forms/songusagedeletedialog.py index 349c3258a..a1ad701b2 100644 --- a/openlp/plugins/songusage/forms/songusagedeletedialog.py +++ b/openlp/plugins/songusage/forms/songusagedeletedialog.py @@ -32,29 +32,30 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import translate from openlp.core.lib.ui import create_button_box -class Ui_SongUsageDeleteDialog(object): - def setupUi(self, songUsageDeleteDialog): - songUsageDeleteDialog.setObjectName(u'songUsageDeleteDialog') - songUsageDeleteDialog.resize(291, 243) - self.verticalLayout = QtGui.QVBoxLayout(songUsageDeleteDialog) - self.verticalLayout.setSpacing(8) - self.verticalLayout.setContentsMargins(8, 8, 8, 8) - self.verticalLayout.setObjectName(u'verticalLayout') - self.deleteLabel = QtGui.QLabel(songUsageDeleteDialog) - self.deleteLabel.setObjectName(u'deleteLabel') - self.verticalLayout.addWidget(self.deleteLabel) - self.deleteCalendar = QtGui.QCalendarWidget(songUsageDeleteDialog) - self.deleteCalendar.setFirstDayOfWeek(QtCore.Qt.Sunday) - self.deleteCalendar.setGridVisible(True) - self.deleteCalendar.setVerticalHeaderFormat(QtGui.QCalendarWidget.NoVerticalHeader) - self.deleteCalendar.setObjectName(u'deleteCalendar') - self.verticalLayout.addWidget(self.deleteCalendar) - self.button_box = create_button_box(songUsageDeleteDialog, u'button_box', [u'cancel', u'ok']) - self.verticalLayout.addWidget(self.button_box) - self.retranslateUi(songUsageDeleteDialog) - def retranslateUi(self, songUsageDeleteDialog): - songUsageDeleteDialog.setWindowTitle(translate('SongUsagePlugin.SongUsageDeleteForm', 'Delete Song Usage Data')) - self.deleteLabel.setText( +class Ui_SongUsageDeleteDialog(object): + def setupUi(self, song_usage_delete_dialog): + song_usage_delete_dialog.setObjectName(u'song_usage_delete_dialog') + song_usage_delete_dialog.resize(291, 243) + self.vertical_layout = QtGui.QVBoxLayout(song_usage_delete_dialog) + self.vertical_layout.setSpacing(8) + self.vertical_layout.setContentsMargins(8, 8, 8, 8) + self.vertical_layout.setObjectName(u'vertical_layout') + self.delete_label = QtGui.QLabel(song_usage_delete_dialog) + self.delete_label.setObjectName(u'delete_label') + self.vertical_layout.addWidget(self.delete_label) + self.delete_calendar = QtGui.QCalendarWidget(song_usage_delete_dialog) + self.delete_calendar.setFirstDayOfWeek(QtCore.Qt.Sunday) + self.delete_calendar.setGridVisible(True) + self.delete_calendar.setVerticalHeaderFormat(QtGui.QCalendarWidget.NoVerticalHeader) + self.delete_calendar.setObjectName(u'delete_calendar') + self.vertical_layout.addWidget(self.delete_calendar) + self.button_box = create_button_box(song_usage_delete_dialog, u'button_box', [u'cancel', u'ok']) + self.vertical_layout.addWidget(self.button_box) + self.retranslateUi(song_usage_delete_dialog) + + def retranslateUi(self, song_usage_delete_dialog): + song_usage_delete_dialog.setWindowTitle(translate('SongUsagePlugin.SongUsageDeleteForm', 'Delete Song Usage Data')) + self.delete_label.setText( translate('SongUsagePlugin.SongUsageDeleteForm', 'Select the date up to which the song usage data ' 'should be deleted. All data recorded before this date will be permanently deleted.')) diff --git a/openlp/plugins/songusage/forms/songusagedeleteform.py b/openlp/plugins/songusage/forms/songusagedeleteform.py index 47e8b9256..8ae2fa020 100644 --- a/openlp/plugins/songusage/forms/songusagedeleteform.py +++ b/openlp/plugins/songusage/forms/songusagedeleteform.py @@ -45,10 +45,9 @@ class SongUsageDeleteForm(QtGui.QDialog, Ui_SongUsageDeleteDialog): self.manager = manager QtGui.QDialog.__init__(self, parent) self.setupUi(self) - QtCore.QObject.connect(self.button_box, QtCore.SIGNAL(u'clicked(QAbstractButton*)'), - self.onButtonBoxClicked) + self.button_box.clicked.connect(self.on_button_box_clicked) - def onButtonBoxClicked(self, button): + def on_button_box_clicked(self, button): if self.button_box.standardButton(button) == QtGui.QDialogButtonBox.Ok: ret = QtGui.QMessageBox.question(self, translate('SongUsagePlugin.SongUsageDeleteForm', 'Delete Selected Song Usage Events?'), @@ -56,12 +55,12 @@ class SongUsageDeleteForm(QtGui.QDialog, Ui_SongUsageDeleteDialog): 'Are you sure you want to delete selected Song Usage data?'), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No), QtGui.QMessageBox.No) if ret == QtGui.QMessageBox.Yes: - deleteDate = self.deleteCalendar.selectedDate().toPyDate() - self.manager.delete_all_objects(SongUsageItem, SongUsageItem.usagedate <= deleteDate) + delete_date = self.delete_calendar.selectedDate().toPyDate() + self.manager.delete_all_objects(SongUsageItem, SongUsageItem.usagedate <= delete_date) self.main_window.information_message( translate('SongUsagePlugin.SongUsageDeleteForm', 'Deletion Successful'), translate( - 'SongUsagePlugin.SongUsageDeleteForm', 'All requested data has been deleted successfully. ') + 'SongUsagePlugin.SongUsageDeleteForm', 'All requested data has been deleted successfully.') ) self.accept() else: @@ -75,4 +74,4 @@ class SongUsageDeleteForm(QtGui.QDialog, Ui_SongUsageDeleteDialog): self._main_window = Registry().get(u'main_window') return self._main_window - main_window = property(_get_main_window) \ No newline at end of file + main_window = property(_get_main_window) diff --git a/openlp/plugins/songusage/forms/songusagedetaildialog.py b/openlp/plugins/songusage/forms/songusagedetaildialog.py index 740771a2b..0cdde6836 100644 --- a/openlp/plugins/songusage/forms/songusagedetaildialog.py +++ b/openlp/plugins/songusage/forms/songusagedetaildialog.py @@ -32,56 +32,56 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import build_icon, translate from openlp.core.lib.ui import create_button_box + class Ui_SongUsageDetailDialog(object): def setupUi(self, songUsageDetailDialog): songUsageDetailDialog.setObjectName(u'songUsageDetailDialog') songUsageDetailDialog.resize(609, 413) - self.verticalLayout = QtGui.QVBoxLayout(songUsageDetailDialog) - self.verticalLayout.setSpacing(8) - self.verticalLayout.setContentsMargins(8, 8, 8, 8) - self.verticalLayout.setObjectName(u'verticalLayout') - self.dateRangeGroupBox = QtGui.QGroupBox(songUsageDetailDialog) - self.dateRangeGroupBox.setObjectName(u'dateRangeGroupBox') - self.dateHorizontalLayout = QtGui.QHBoxLayout(self.dateRangeGroupBox) - self.dateHorizontalLayout.setSpacing(8) - self.dateHorizontalLayout.setContentsMargins(8, 8, 8, 8) - self.dateHorizontalLayout.setObjectName(u'dateHorizontalLayout') - self.fromDate = QtGui.QCalendarWidget(self.dateRangeGroupBox) - self.fromDate.setObjectName(u'fromDate') - self.dateHorizontalLayout.addWidget(self.fromDate) - self.toLabel = QtGui.QLabel(self.dateRangeGroupBox) - self.toLabel.setScaledContents(False) - self.toLabel.setAlignment(QtCore.Qt.AlignCenter) - self.toLabel.setObjectName(u'toLabel') - self.dateHorizontalLayout.addWidget(self.toLabel) - self.toDate = QtGui.QCalendarWidget(self.dateRangeGroupBox) - self.toDate.setObjectName(u'toDate') - self.dateHorizontalLayout.addWidget(self.toDate) - self.verticalLayout.addWidget(self.dateRangeGroupBox) - self.fileGroupBox = QtGui.QGroupBox(self.dateRangeGroupBox) - self.fileGroupBox.setObjectName(u'fileGroupBox') - self.fileHorizontalLayout = QtGui.QHBoxLayout(self.fileGroupBox) - self.fileHorizontalLayout.setSpacing(8) - self.fileHorizontalLayout.setContentsMargins(8, 8, 8, 8) - self.fileHorizontalLayout.setObjectName(u'fileHorizontalLayout') - self.fileLineEdit = QtGui.QLineEdit(self.fileGroupBox) - self.fileLineEdit.setObjectName(u'fileLineEdit') - self.fileLineEdit.setReadOnly(True) - self.fileHorizontalLayout.addWidget(self.fileLineEdit) - self.saveFilePushButton = QtGui.QPushButton(self.fileGroupBox) - self.saveFilePushButton.setMaximumWidth(self.saveFilePushButton.size().height()) - self.saveFilePushButton.setIcon(build_icon(u':/general/general_open.png')) - self.saveFilePushButton.setObjectName(u'saveFilePushButton') - self.fileHorizontalLayout.addWidget(self.saveFilePushButton) - self.verticalLayout.addWidget(self.fileGroupBox) + self.vertical_layout = QtGui.QVBoxLayout(songUsageDetailDialog) + self.vertical_layout.setSpacing(8) + self.vertical_layout.setContentsMargins(8, 8, 8, 8) + self.vertical_layout.setObjectName(u'vertical_layout') + self.date_range_group_box = QtGui.QGroupBox(songUsageDetailDialog) + self.date_range_group_box.setObjectName(u'date_range_group_box') + self.date_horizontal_layout = QtGui.QHBoxLayout(self.date_range_group_box) + self.date_horizontal_layout.setSpacing(8) + self.date_horizontal_layout.setContentsMargins(8, 8, 8, 8) + self.date_horizontal_layout.setObjectName(u'date_horizontal_layout') + self.from_date = QtGui.QCalendarWidget(self.date_range_group_box) + self.from_date.setObjectName(u'from_date') + self.date_horizontal_layout.addWidget(self.from_date) + self.to_label = QtGui.QLabel(self.date_range_group_box) + self.to_label.setScaledContents(False) + self.to_label.setAlignment(QtCore.Qt.AlignCenter) + self.to_label.setObjectName(u'to_label') + self.date_horizontal_layout.addWidget(self.to_label) + self.to_date = QtGui.QCalendarWidget(self.date_range_group_box) + self.to_date.setObjectName(u'to_date') + self.date_horizontal_layout.addWidget(self.to_date) + self.vertical_layout.addWidget(self.date_range_group_box) + self.file_group_box = QtGui.QGroupBox(self.date_range_group_box) + self.file_group_box.setObjectName(u'file_group_box') + self.file_horizontal_layout = QtGui.QHBoxLayout(self.file_group_box) + self.file_horizontal_layout.setSpacing(8) + self.file_horizontal_layout.setContentsMargins(8, 8, 8, 8) + self.file_horizontal_layout.setObjectName(u'file_horizontal_layout') + self.file_line_edit = QtGui.QLineEdit(self.file_group_box) + self.file_line_edit.setObjectName(u'file_line_edit') + self.file_line_edit.setReadOnly(True) + self.file_horizontal_layout.addWidget(self.file_line_edit) + self.save_file_push_button = QtGui.QPushButton(self.file_group_box) + self.save_file_push_button.setMaximumWidth(self.save_file_push_button.size().height()) + self.save_file_push_button.setIcon(build_icon(u':/general/general_open.png')) + self.save_file_push_button.setObjectName(u'save_file_push_button') + self.file_horizontal_layout.addWidget(self.save_file_push_button) + self.vertical_layout.addWidget(self.file_group_box) self.button_box = create_button_box(songUsageDetailDialog, u'button_box', [u'cancel', u'ok']) - self.verticalLayout.addWidget(self.button_box) + self.vertical_layout.addWidget(self.button_box) self.retranslateUi(songUsageDetailDialog) - QtCore.QObject.connect(self.saveFilePushButton, QtCore.SIGNAL(u'clicked()'), - songUsageDetailDialog.defineOutputLocation) + self.save_file_push_button.clicked.connect(songUsageDetailDialog.define_output_location) def retranslateUi(self, songUsageDetailDialog): songUsageDetailDialog.setWindowTitle(translate('SongUsagePlugin.SongUsageDetailForm', 'Song Usage Extraction')) - self.dateRangeGroupBox.setTitle(translate('SongUsagePlugin.SongUsageDetailForm', 'Select Date Range')) - self.toLabel.setText(translate('SongUsagePlugin.SongUsageDetailForm', 'to')) - self.fileGroupBox.setTitle(translate('SongUsagePlugin.SongUsageDetailForm', 'Report Location')) + self.date_range_group_box.setTitle(translate('SongUsagePlugin.SongUsageDetailForm', 'Select Date Range')) + self.to_label.setText(translate('SongUsagePlugin.SongUsageDetailForm', 'to')) + self.file_group_box.setTitle(translate('SongUsagePlugin.SongUsageDetailForm', 'Report Location')) diff --git a/openlp/plugins/songusage/forms/songusagedetailform.py b/openlp/plugins/songusage/forms/songusagedetailform.py index 1f68e1a97..b660b9715 100644 --- a/openlp/plugins/songusage/forms/songusagedetailform.py +++ b/openlp/plugins/songusage/forms/songusagedetailform.py @@ -39,6 +39,7 @@ from songusagedetaildialog import Ui_SongUsageDetailDialog log = logging.getLogger(__name__) + class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog): """ Class documentation goes here. @@ -57,13 +58,13 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog): """ We need to set up the screen """ - toDate = Settings().value(self.plugin.settingsSection + u'/to date') - fromDate = Settings().value(self.plugin.settingsSection + u'/from date') - self.fromDate.setSelectedDate(fromDate) - self.toDate.setSelectedDate(toDate) - self.fileLineEdit.setText(Settings().value(self.plugin.settingsSection + u'/last directory export')) + to_date = Settings().value(self.plugin.settingsSection + u'/to date') + from_date = Settings().value(self.plugin.settingsSection + u'/from date') + self.from_date.setSelectedDate(from_date) + self.to_date.setSelectedDate(to_date) + self.file_line_edit.setText(Settings().value(self.plugin.settingsSection + u'/last directory export')) - def defineOutputLocation(self): + def define_output_location(self): """ Triggered when the Directory selection button is clicked """ @@ -72,14 +73,14 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog): Settings().value(self.plugin.settingsSection + u'/last directory export')) if path: Settings().setValue(self.plugin.settingsSection + u'/last directory export', path) - self.fileLineEdit.setText(path) + self.file_line_edit.setText(path) def accept(self): """ Ok was triggered so lets save the data and run the report """ log.debug(u'accept') - path = self.fileLineEdit.text() + path = self.file_line_edit.text() if not path: self.main_window.error_message( translate('SongUsagePlugin.SongUsageDetailForm', 'Output Path Not Selected'), @@ -88,36 +89,36 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog): ) return check_directory_exists(path) - filename = translate('SongUsagePlugin.SongUsageDetailForm', 'usage_detail_%s_%s.txt') % ( - self.fromDate.selectedDate().toString(u'ddMMyyyy'), - self.toDate.selectedDate().toString(u'ddMMyyyy')) - Settings().setValue(u'songusage/from date', self.fromDate.selectedDate()) - Settings().setValue(u'songusage/to date', self.toDate.selectedDate()) + file_name = translate('SongUsagePlugin.SongUsageDetailForm', 'usage_detail_%s_%s.txt') % ( + self.from_date.selectedDate().toString(u'ddMMyyyy'), + self.to_date.selectedDate().toString(u'ddMMyyyy')) + Settings().setValue(u'songusage/from date', self.from_date.selectedDate()) + Settings().setValue(u'songusage/to date', self.to_date.selectedDate()) usage = self.plugin.manager.get_all_objects( SongUsageItem, and_( - SongUsageItem.usagedate >= self.fromDate.selectedDate().toPyDate(), - SongUsageItem.usagedate < self.toDate.selectedDate().toPyDate()), + SongUsageItem.usagedate >= self.from_date.selectedDate().toPyDate(), + SongUsageItem.usagedate < self.to_date.selectedDate().toPyDate()), [SongUsageItem.usagedate, SongUsageItem.usagetime]) - outname = os.path.join(path, filename) - fileHandle = None + report_file_name = os.path.join(path, file_name) + file_handle = None try: - fileHandle = open(outname, u'w') + file_handle = open(report_file_name, u'w') for instance in usage: record = u'\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",' \ u'\"%s\",\"%s\"\n' % (instance.usagedate, instance.usagetime, instance.title, instance.copyright, instance.ccl_number, instance.authors, instance.plugin_name, instance.source) - fileHandle.write(record.encode(u'utf-8')) + file_handle.write(record.encode(u'utf-8')) self.main_window.information_message( translate('SongUsagePlugin.SongUsageDetailForm', 'Report Creation'), translate('SongUsagePlugin.SongUsageDetailForm', 'Report \n%s \n' - 'has been successfully created. ') % outname + 'has been successfully created. ') % report_file_name ) except IOError: log.exception(u'Failed to write out song usage records') finally: - if fileHandle: - fileHandle.close() + if file_handle: + file_handle.close() self.close() def _get_main_window(self): @@ -128,4 +129,4 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog): self._main_window = Registry().get(u'main_window') return self._main_window - main_window = property(_get_main_window) \ No newline at end of file + main_window = property(_get_main_window) diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py index b91468531..5b56e2563 100644 --- a/openlp/plugins/songusage/songusageplugin.py +++ b/openlp/plugins/songusage/songusageplugin.py @@ -42,7 +42,6 @@ from openlp.plugins.songusage.lib.db import init_schema, SongUsageItem log = logging.getLogger(__name__) - YEAR = QtCore.QDate().currentDate().year() if QtCore.QDate().currentDate().month() < 9: YEAR -= 1 @@ -54,7 +53,7 @@ __default_settings__ = { u'songusage/to date': QtCore.QDate(YEAR, 8, 31), u'songusage/from date': QtCore.QDate(YEAR - 1, 9, 1), u'songusage/last directory export': u'' - } +} class SongUsagePlugin(Plugin): @@ -83,59 +82,59 @@ class SongUsagePlugin(Plugin): """ log.info(u'add tools menu') self.toolsMenu = tools_menu - self.songUsageMenu = QtGui.QMenu(tools_menu) - self.songUsageMenu.setObjectName(u'songUsageMenu') - self.songUsageMenu.setTitle(translate('SongUsagePlugin', '&Song Usage Tracking')) + self.song_usage_menu = QtGui.QMenu(tools_menu) + self.song_usage_menu.setObjectName(u'song_usage_menu') + self.song_usage_menu.setTitle(translate('SongUsagePlugin', '&Song Usage Tracking')) # SongUsage Delete - self.songUsageDelete = create_action(tools_menu, u'songUsageDelete', + self.song_usage_delete = create_action(tools_menu, u'songUsageDelete', text=translate('SongUsagePlugin', '&Delete Tracking Data'), statustip=translate('SongUsagePlugin', 'Delete song usage data up to a specified date.'), - triggers=self.onSongUsageDelete) + triggers=self.on_song_usage_delete) # SongUsage Report - self.songUsageReport = create_action(tools_menu, u'songUsageReport', + self.song_usage_report = create_action(tools_menu, u'songUsageReport', text=translate('SongUsagePlugin', '&Extract Tracking Data'), statustip=translate('SongUsagePlugin', 'Generate a report on song usage.'), - triggers=self.onSongUsageReport) + triggers=self.on_song_usage_report) # SongUsage activation - self.songUsageStatus = create_action(tools_menu, u'songUsageStatus', + self.song_usage_status = create_action(tools_menu, u'songUsageStatus', text=translate('SongUsagePlugin', 'Toggle Tracking'), statustip=translate('SongUsagePlugin', 'Toggle the tracking of song usage.'), checked=False, - shortcuts=[QtCore.Qt.Key_F4], triggers=self.toggleSongUsageState) + shortcuts=[QtCore.Qt.Key_F4], triggers=self.toggle_song_usage_state) # Add Menus together - self.toolsMenu.addAction(self.songUsageMenu.menuAction()) - self.songUsageMenu.addAction(self.songUsageStatus) - self.songUsageMenu.addSeparator() - self.songUsageMenu.addAction(self.songUsageReport) - self.songUsageMenu.addAction(self.songUsageDelete) - self.songUsageActiveButton = QtGui.QToolButton(self.main_window.statusBar) - self.songUsageActiveButton.setCheckable(True) - self.songUsageActiveButton.setAutoRaise(True) - self.songUsageActiveButton.setStatusTip(translate('SongUsagePlugin', 'Toggle the tracking of song usage.')) - self.songUsageActiveButton.setObjectName(u'songUsageActiveButton') - self.main_window.statusBar.insertPermanentWidget(1, self.songUsageActiveButton) - self.songUsageActiveButton.hide() + self.toolsMenu.addAction(self.song_usage_menu.menuAction()) + self.song_usage_menu.addAction(self.song_usage_status) + self.song_usage_menu.addSeparator() + self.song_usage_menu.addAction(self.song_usage_report) + self.song_usage_menu.addAction(self.song_usage_delete) + self.song_usage_active_button = QtGui.QToolButton(self.main_window.statusBar) + self.song_usage_active_button.setCheckable(True) + self.song_usage_active_button.setAutoRaise(True) + self.song_usage_active_button.setStatusTip(translate('SongUsagePlugin', 'Toggle the tracking of song usage.')) + self.song_usage_active_button.setObjectName(u'song_usage_active_button') + self.main_window.statusBar.insertPermanentWidget(1, self.song_usage_active_button) + self.song_usage_active_button.hide() # Signals and slots - QtCore.QObject.connect(self.songUsageStatus, QtCore.SIGNAL(u'visibilityChanged(bool)'), - self.songUsageStatus.setChecked) - QtCore.QObject.connect(self.songUsageActiveButton, QtCore.SIGNAL(u'toggled(bool)'), self.toggleSongUsageState) - self.songUsageMenu.menuAction().setVisible(False) + QtCore.QObject.connect(self.song_usage_status, QtCore.SIGNAL(u'visibilityChanged(bool)'), + self.song_usage_status.setChecked) + self.song_usage_active_button.toggled.connect(self.toggle_song_usage_state) + self.song_usage_menu.menuAction().setVisible(False) def initialise(self): log.info(u'SongUsage Initialising') Plugin.initialise(self) Registry().register_function(u'slidecontroller_live_started', self.display_song_usage) Registry().register_function(u'print_service_started', self.print_song_usage) - self.songUsageActive = Settings().value(self.settingsSection + u'/active') + self.song_usage_active = Settings().value(self.settingsSection + u'/active') # Set the button and checkbox state - self.setButtonState() + self.set_button_state() action_list = ActionList.get_instance() - action_list.add_action(self.songUsageStatus, translate('SongUsagePlugin', 'Song Usage')) - action_list.add_action(self.songUsageDelete, translate('SongUsagePlugin', 'Song Usage')) - action_list.add_action(self.songUsageReport, translate('SongUsagePlugin', 'Song Usage')) - self.songUsageDeleteForm = SongUsageDeleteForm(self.manager, self.main_window) - self.songUsageDetailForm = SongUsageDetailForm(self, self.main_window) - self.songUsageMenu.menuAction().setVisible(True) - self.songUsageActiveButton.show() + action_list.add_action(self.song_usage_status, translate('SongUsagePlugin', 'Song Usage')) + action_list.add_action(self.song_usage_delete, translate('SongUsagePlugin', 'Song Usage')) + action_list.add_action(self.song_usage_report, translate('SongUsagePlugin', 'Song Usage')) + self.song_usage_delete_form = SongUsageDeleteForm(self.manager, self.main_window) + self.song_usage_detail_form = SongUsageDetailForm(self, self.main_window) + self.song_usage_menu.menuAction().setVisible(True) + self.song_usage_active_button.show() def finalise(self): """ @@ -144,44 +143,43 @@ class SongUsagePlugin(Plugin): log.info(u'Plugin Finalise') self.manager.finalise() Plugin.finalise(self) - self.songUsageMenu.menuAction().setVisible(False) + self.song_usage_menu.menuAction().setVisible(False) action_list = ActionList.get_instance() - action_list.remove_action(self.songUsageStatus, translate('SongUsagePlugin', 'Song Usage')) - action_list.remove_action(self.songUsageDelete, translate('SongUsagePlugin', 'Song Usage')) - action_list.remove_action(self.songUsageReport, translate('SongUsagePlugin', 'Song Usage')) - self.songUsageActiveButton.hide() + action_list.remove_action(self.song_usage_status, translate('SongUsagePlugin', 'Song Usage')) + action_list.remove_action(self.song_usage_delete, translate('SongUsagePlugin', 'Song Usage')) + action_list.remove_action(self.song_usage_report, translate('SongUsagePlugin', 'Song Usage')) + self.song_usage_active_button.hide() # stop any events being processed - self.songUsageActive = False + self.song_usage_active = False - def toggleSongUsageState(self): + def toggle_song_usage_state(self): """ Manage the state of the audit collection and amend the UI when necessary, """ - self.songUsageActive = not self.songUsageActive - Settings().setValue(self.settingsSection + u'/active', self.songUsageActive) - self.setButtonState() + self.song_usage_active = not self.song_usage_active + Settings().setValue(self.settingsSection + u'/active', self.song_usage_active) + self.set_button_state() - def setButtonState(self): + def set_button_state(self): """ Keep buttons inline. Turn of signals to stop dead loop but we need the button and check box set correctly. """ - self.songUsageActiveButton.blockSignals(True) - self.songUsageStatus.blockSignals(True) + self.song_usage_active_button.blockSignals(True) + self.song_usage_status.blockSignals(True) if self.songUsageActive: - self.songUsageActiveButton.setIcon(self.activeIcon) - self.songUsageStatus.setChecked(True) - self.songUsageActiveButton.setChecked(True) - self.songUsageActiveButton.setToolTip(translate('SongUsagePlugin', 'Song usage tracking is active.')) + self.song_usage_active_button.setIcon(self.activeIcon) + self.song_usage_status.setChecked(True) + self.song_usage_active_button.setChecked(True) + self.song_usage_active_button.setToolTip(translate('SongUsagePlugin', 'Song usage tracking is active.')) else: - self.songUsageActiveButton.setIcon(self.inactiveIcon) - self.songUsageStatus.setChecked(False) - self.songUsageActiveButton.setChecked(False) - self.songUsageActiveButton.setToolTip(translate('SongUsagePlugin', 'Song usage tracking is inactive.')) - self.songUsageActiveButton.blockSignals(False) - self.songUsageStatus.blockSignals(False) - + self.song_usage_active_button.setIcon(self.inactiveIcon) + self.song_usage_status.setChecked(False) + self.song_usage_active_button.setChecked(False) + self.song_usage_active_button.setToolTip(translate('SongUsagePlugin', 'Song usage tracking is inactive.')) + self.song_usage_active_button.blockSignals(False) + self.song_usage_status.blockSignals(False) def display_song_usage(self, item): """ @@ -209,12 +207,12 @@ class SongUsagePlugin(Plugin): song_usage_item.source = source self.manager.save_object(song_usage_item) - def onSongUsageDelete(self): - self.songUsageDeleteForm.exec_() + def on_song_usage_delete(self): + self.song_usage_delete_form.exec_() - def onSongUsageReport(self): - self.songUsageDetailForm.initialise() - self.songUsageDetailForm.exec_() + def on_song_usage_report(self): + self.song_usage_detail_form.initialise() + self.song_usage_detail_form.exec_() def about(self): about_text = translate('SongUsagePlugin', 'SongUsage Plugin' From 0d6e9389b906ef195f08167d9baa01a20111e79d Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 16 Feb 2013 13:02:20 +0000 Subject: [PATCH 13/48] Clean up Song Usage dialog --- .../songusage/forms/songusagedetaildialog.py | 32 +++++++++---------- .../songusage/forms/songusagedetailform.py | 18 +++++------ openlp/plugins/songusage/songusageplugin.py | 6 ++-- .../openlp_core_lib/test_image_manager.py | 3 +- 4 files changed, 29 insertions(+), 30 deletions(-) diff --git a/openlp/plugins/songusage/forms/songusagedetaildialog.py b/openlp/plugins/songusage/forms/songusagedetaildialog.py index 0cdde6836..47fc9bf27 100644 --- a/openlp/plugins/songusage/forms/songusagedetaildialog.py +++ b/openlp/plugins/songusage/forms/songusagedetaildialog.py @@ -34,30 +34,30 @@ from openlp.core.lib.ui import create_button_box class Ui_SongUsageDetailDialog(object): - def setupUi(self, songUsageDetailDialog): - songUsageDetailDialog.setObjectName(u'songUsageDetailDialog') - songUsageDetailDialog.resize(609, 413) - self.vertical_layout = QtGui.QVBoxLayout(songUsageDetailDialog) + def setupUi(self, song_usage_detail_dialog): + song_usage_detail_dialog.setObjectName(u'song_usage_detail_dialog') + song_usage_detail_dialog.resize(609, 413) + self.vertical_layout = QtGui.QVBoxLayout(song_usage_detail_dialog) self.vertical_layout.setSpacing(8) self.vertical_layout.setContentsMargins(8, 8, 8, 8) self.vertical_layout.setObjectName(u'vertical_layout') - self.date_range_group_box = QtGui.QGroupBox(songUsageDetailDialog) + self.date_range_group_box = QtGui.QGroupBox(song_usage_detail_dialog) self.date_range_group_box.setObjectName(u'date_range_group_box') self.date_horizontal_layout = QtGui.QHBoxLayout(self.date_range_group_box) self.date_horizontal_layout.setSpacing(8) self.date_horizontal_layout.setContentsMargins(8, 8, 8, 8) self.date_horizontal_layout.setObjectName(u'date_horizontal_layout') - self.from_date = QtGui.QCalendarWidget(self.date_range_group_box) - self.from_date.setObjectName(u'from_date') - self.date_horizontal_layout.addWidget(self.from_date) + self.from_date_calendar = QtGui.QCalendarWidget(self.date_range_group_box) + self.from_date_calendar.setObjectName(u'from_date_calendar') + self.date_horizontal_layout.addWidget(self.from_date_calendar) self.to_label = QtGui.QLabel(self.date_range_group_box) self.to_label.setScaledContents(False) self.to_label.setAlignment(QtCore.Qt.AlignCenter) self.to_label.setObjectName(u'to_label') self.date_horizontal_layout.addWidget(self.to_label) - self.to_date = QtGui.QCalendarWidget(self.date_range_group_box) - self.to_date.setObjectName(u'to_date') - self.date_horizontal_layout.addWidget(self.to_date) + self.to_date_calendar = QtGui.QCalendarWidget(self.date_range_group_box) + self.to_date_calendar.setObjectName(u'to_date_calendar') + self.date_horizontal_layout.addWidget(self.to_date_calendar) self.vertical_layout.addWidget(self.date_range_group_box) self.file_group_box = QtGui.QGroupBox(self.date_range_group_box) self.file_group_box.setObjectName(u'file_group_box') @@ -75,13 +75,13 @@ class Ui_SongUsageDetailDialog(object): self.save_file_push_button.setObjectName(u'save_file_push_button') self.file_horizontal_layout.addWidget(self.save_file_push_button) self.vertical_layout.addWidget(self.file_group_box) - self.button_box = create_button_box(songUsageDetailDialog, u'button_box', [u'cancel', u'ok']) + self.button_box = create_button_box(song_usage_detail_dialog, u'button_box', [u'cancel', u'ok']) self.vertical_layout.addWidget(self.button_box) - self.retranslateUi(songUsageDetailDialog) - self.save_file_push_button.clicked.connect(songUsageDetailDialog.define_output_location) + self.retranslateUi(song_usage_detail_dialog) + self.save_file_push_button.clicked.connect(song_usage_detail_dialog.define_output_location) - def retranslateUi(self, songUsageDetailDialog): - songUsageDetailDialog.setWindowTitle(translate('SongUsagePlugin.SongUsageDetailForm', 'Song Usage Extraction')) + def retranslateUi(self, song_usage_detail_dialog): + song_usage_detail_dialog.setWindowTitle(translate('SongUsagePlugin.SongUsageDetailForm', 'Song Usage Extraction')) self.date_range_group_box.setTitle(translate('SongUsagePlugin.SongUsageDetailForm', 'Select Date Range')) self.to_label.setText(translate('SongUsagePlugin.SongUsageDetailForm', 'to')) self.file_group_box.setTitle(translate('SongUsagePlugin.SongUsageDetailForm', 'Report Location')) diff --git a/openlp/plugins/songusage/forms/songusagedetailform.py b/openlp/plugins/songusage/forms/songusagedetailform.py index b660b9715..69611fd69 100644 --- a/openlp/plugins/songusage/forms/songusagedetailform.py +++ b/openlp/plugins/songusage/forms/songusagedetailform.py @@ -58,10 +58,8 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog): """ We need to set up the screen """ - to_date = Settings().value(self.plugin.settingsSection + u'/to date') - from_date = Settings().value(self.plugin.settingsSection + u'/from date') - self.from_date.setSelectedDate(from_date) - self.to_date.setSelectedDate(to_date) + self.from_date_calendar.setSelectedDate(Settings().value(self.plugin.settingsSection + u'/from date')) + self.to_date_calendar.setSelectedDate(Settings().value(self.plugin.settingsSection + u'/to date')) self.file_line_edit.setText(Settings().value(self.plugin.settingsSection + u'/last directory export')) def define_output_location(self): @@ -90,14 +88,14 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog): return check_directory_exists(path) file_name = translate('SongUsagePlugin.SongUsageDetailForm', 'usage_detail_%s_%s.txt') % ( - self.from_date.selectedDate().toString(u'ddMMyyyy'), - self.to_date.selectedDate().toString(u'ddMMyyyy')) - Settings().setValue(u'songusage/from date', self.from_date.selectedDate()) - Settings().setValue(u'songusage/to date', self.to_date.selectedDate()) + self.from_date_calendar.selectedDate().toString(u'ddMMyyyy'), + self.to_date_calendar.selectedDate().toString(u'ddMMyyyy')) + Settings().setValue(self.plugin.settingsSection + u'/from date', self.from_date_calendar.selectedDate()) + Settings().setValue(self.plugin.settingsSection + u'/to date', self.to_date_calendar.selectedDate()) usage = self.plugin.manager.get_all_objects( SongUsageItem, and_( - SongUsageItem.usagedate >= self.from_date.selectedDate().toPyDate(), - SongUsageItem.usagedate < self.to_date.selectedDate().toPyDate()), + SongUsageItem.usagedate >= self.from_date_calendar.selectedDate().toPyDate(), + SongUsageItem.usagedate < self.to_date_calendar.selectedDate().toPyDate()), [SongUsageItem.usagedate, SongUsageItem.usagetime]) report_file_name = os.path.join(path, file_name) file_handle = None diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py index 5b56e2563..19b56a339 100644 --- a/openlp/plugins/songusage/songusageplugin.py +++ b/openlp/plugins/songusage/songusageplugin.py @@ -66,7 +66,7 @@ class SongUsagePlugin(Plugin): self.icon = build_icon(u':/plugins/plugin_songusage.png') self.activeIcon = build_icon(u':/songusage/song_usage_active.png') self.inactiveIcon = build_icon(u':/songusage/song_usage_inactive.png') - self.songUsageActive = False + self.song_usage_active = False def checkPreConditions(self): return self.manager.session is not None @@ -168,7 +168,7 @@ class SongUsagePlugin(Plugin): """ self.song_usage_active_button.blockSignals(True) self.song_usage_status.blockSignals(True) - if self.songUsageActive: + if self.song_usage_active: self.song_usage_active_button.setIcon(self.activeIcon) self.song_usage_status.setChecked(True) self.song_usage_active_button.setChecked(True) @@ -195,7 +195,7 @@ class SongUsagePlugin(Plugin): def _add_song_usage(self, source, item): audit = item[0].audit - if self.songUsageActive and audit: + if self.song_usage_active and audit: song_usage_item = SongUsageItem() song_usage_item.usagedate = datetime.today() song_usage_item.usagetime = datetime.now().time() diff --git a/tests/functional/openlp_core_lib/test_image_manager.py b/tests/functional/openlp_core_lib/test_image_manager.py index d13c82c04..a257fec20 100644 --- a/tests/functional/openlp_core_lib/test_image_manager.py +++ b/tests/functional/openlp_core_lib/test_image_manager.py @@ -28,7 +28,8 @@ class TestImageManager(TestCase): """ Delete all the C++ objects at the end so that we don't have a segfault """ - del self.app + #del self.app + pass def basic_image_manager_test(self): """ From 310f6032ed8db7300ac6fffe87a76cb047db4a0c Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 16 Feb 2013 13:24:56 +0000 Subject: [PATCH 14/48] tidy ups --- openlp/core/ui/servicemanager.py | 8 ++++---- openlp/core/ui/thememanager.py | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 7762d72aa..8ecc900be 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -205,10 +205,6 @@ class ServiceManagerDialog(object): self.service_manager_list.doubleClicked.connect(self.on_make_live) self.service_manager_list.itemCollapsed.connect(self.collapsed) self.service_manager_list.itemExpanded.connect(self.expanded) - Registry().register_function(u'theme_update_list', self.update_theme_list) - Registry().register_function(u'config_updated', self.config_updated) - Registry().register_function(u'config_screen_changed', self.regenerate_service_Items) - Registry().register_function(u'theme_update_global', self.theme_change) # Last little bits of setting up self.service_theme = Settings().value(self.main_window.serviceManagerSettingsSection + u'/service theme') self.servicePath = AppLocation.get_section_data_path(u'servicemanager') @@ -268,6 +264,10 @@ class ServiceManagerDialog(object): self.service_manager_list.expand, self.service_manager_list.collapse ]) + Registry().register_function(u'theme_update_list', self.update_theme_list) + Registry().register_function(u'config_updated', self.config_updated) + Registry().register_function(u'config_screen_changed', self.regenerate_service_Items) + Registry().register_function(u'theme_update_global', self.theme_change) def drag_enter_event(self, event): """ diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 99e78d34e..96ebfa694 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -157,7 +157,6 @@ class ThemeManager(QtGui.QWidget): delete_file(theme_file) self.application.set_normal_cursor() - def config_updated(self): """ Triggered when Config dialog is updated. From a14f624a81821718c8bf959b30d39b0b82ef3f6c Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 16 Feb 2013 20:45:15 +0000 Subject: [PATCH 15/48] Fixes --- tests/functional/openlp_core_lib/__init__.py | 8 -------- tests/functional/openlp_core_lib/test_image_manager.py | 3 +-- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/tests/functional/openlp_core_lib/__init__.py b/tests/functional/openlp_core_lib/__init__.py index e0da50eb3..e69de29bb 100644 --- a/tests/functional/openlp_core_lib/__init__.py +++ b/tests/functional/openlp_core_lib/__init__.py @@ -1,8 +0,0 @@ -import sip -sip.setapi(u'QDate', 2) -sip.setapi(u'QDateTime', 2) -sip.setapi(u'QString', 2) -sip.setapi(u'QTextStream', 2) -sip.setapi(u'QTime', 2) -sip.setapi(u'QUrl', 2) -sip.setapi(u'QVariant', 2) \ No newline at end of file diff --git a/tests/functional/openlp_core_lib/test_image_manager.py b/tests/functional/openlp_core_lib/test_image_manager.py index a257fec20..d13c82c04 100644 --- a/tests/functional/openlp_core_lib/test_image_manager.py +++ b/tests/functional/openlp_core_lib/test_image_manager.py @@ -28,8 +28,7 @@ class TestImageManager(TestCase): """ Delete all the C++ objects at the end so that we don't have a segfault """ - #del self.app - pass + del self.app def basic_image_manager_test(self): """ From 45ed3bd97eb63a39a1b78c6f04eaf2004f762b96 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Mon, 18 Feb 2013 20:44:55 +0000 Subject: [PATCH 16/48] Test messages --- tests/functional/openlp_core_lib/test_settings.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/functional/openlp_core_lib/test_settings.py b/tests/functional/openlp_core_lib/test_settings.py index 779a1569d..634865369 100644 --- a/tests/functional/openlp_core_lib/test_settings.py +++ b/tests/functional/openlp_core_lib/test_settings.py @@ -17,7 +17,7 @@ class TestSettings(TestCase): """ Create the UI """ - self.application = QtGui.QApplication([]) + self.application = QtGui.QApplication.instance() self.application.setOrganizationName(u'OpenLP-tests') self.application.setOrganizationDomain(u'openlp.org') Settings() @@ -48,7 +48,7 @@ class TestSettings(TestCase): Settings().setValue(u'general/has run wizard', True) # THEN the new value is returned when re-read - assert Settings().value(u'general/has run wizard') is True, u'The saved value has not been returned' + assert Settings().value(u'general/has run wizard') is True, u'The saved value should have been returned' def settings_override_test(self): """ @@ -64,13 +64,13 @@ class TestSettings(TestCase): extend = Settings().value(u'test/extend') # THEN the default value is returned - assert extend == u'very wide', u'The default value defined is returned' + assert extend == u'very wide', u'The default value of "very wide" should be returned' # WHEN a new value is saved into config Settings().setValue(u'test/extend', u'very short') # THEN the new value is returned when re-read - assert Settings().value(u'test/extend') == u'very short', u'The saved value is returned' + assert Settings().value(u'test/extend') == u'very short', u'The saved value should be returned' def settings_override_with_group_test(self): """ @@ -88,10 +88,10 @@ class TestSettings(TestCase): extend = settings.value(u'extend') # THEN the default value is returned - assert extend == u'very wide', u'The default value defined has not been returned' + assert extend == u'very wide', u'The default value defined should be returned' # WHEN a new value is saved into config Settings().setValue(u'test/extend', u'very short') # THEN the new value is returned when re-read - assert Settings().value(u'test/extend') == u'very short', u'The saved value has not been returned' + assert Settings().value(u'test/extend') == u'very short', u'The saved value should be returned' From cc97b4d127aa341a9f4867589be03ae7daf3af81 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 19 Feb 2013 08:16:56 +0100 Subject: [PATCH 17/48] updated vlc.py --- openlp/core/ui/media/vendor/vlc.py | 588 +++++++++++------------------ 1 file changed, 220 insertions(+), 368 deletions(-) diff --git a/openlp/core/ui/media/vendor/vlc.py b/openlp/core/ui/media/vendor/vlc.py index 36a2b206f..e7138b50a 100644 --- a/openlp/core/ui/media/vendor/vlc.py +++ b/openlp/core/ui/media/vendor/vlc.py @@ -2,7 +2,7 @@ # Python ctypes bindings for VLC # -# Copyright (C) 2009-2013 the VideoLAN team +# Copyright (C) 2009-2012 the VideoLAN team # $Id: $ # # Authors: Olivier Aubert @@ -48,7 +48,7 @@ import sys from inspect import getargspec __version__ = "N/A" -build_date = "Fri Oct 5 21:35:59 2012" +build_date = "Wed Feb 13 18:40:24 2013" if sys.version_info[0] > 2: str = str @@ -1000,6 +1000,50 @@ class MediaTrackInfo(_Cstruct): ('rate_or_width', ctypes.c_uint ), ] +class AudioTrack(_Cstruct): + _fields_ = [ + ('channels', ctypes.c_uint), + ('rate', ctypes.c_uint), + ] + +class VideoTrack(_Cstruct): + _fields_ = [ + ('height', ctypes.c_uint), + ('width', ctypes.c_uint), + ('sar_num', ctypes.c_uint), + ('sar_den', ctypes.c_uint), + ('frame_rate_num', ctypes.c_uint), + ('frame_rate_den', ctypes.c_uint), + ] + +class SubtitleTrack(_Cstruct): + _fields_ = [ + ('encoding', ctypes.c_char_p), + ] + +class MediaTrackTracks(ctypes.Union): + _fields_ = [ + ('audio', ctypes.POINTER(AudioTrack)), + ('video', ctypes.POINTER(VideoTrack)), + ('subtitle', ctypes.POINTER(SubtitleTrack)), + ] + +class MediaTrack(_Cstruct): + _anonymous_ = ("u",) + _fields_ = [ + ('codec', ctypes.c_uint32), + ('original_fourcc', ctypes.c_uint32), + ('id', ctypes.c_int ), + ('type', TrackType ), + ('profile', ctypes.c_int ), + ('level', ctypes.c_int ), + + ('u', MediaTrackTracks), + ('bitrate', ctypes.c_uint), + ('language', ctypes.c_char_p), + ('description', ctypes.c_char_p), + ] + class PlaylistItem(_Cstruct): _fields_ = [ ('id', ctypes.c_int ), @@ -1122,6 +1166,17 @@ def module_description_list(head): libvlc_module_description_list_release(head) return r +class AudioOutputDevice(_Cstruct): + + def __str__(self): + return '%s(%d:%s)' % (self.__class__.__name__, self.id, self.name) + +AudioOutputDevice._fields_ = [ # recursive struct + ('next', ctypes.POINTER(AudioOutputDevice)), + ('device', ctypes.c_char_p ), + ('description', ctypes.c_char_p), + ] + # End of header.py # class EventManager(_Ctype): @@ -1282,7 +1337,7 @@ class Instance(_Ctype): m = libvlc_media_new_location(self, str_to_bytes(mrl)) else: # Else it should be a local path. - m = libvlc_media_new_path(self, str_to_bytes(mrl)) + m = libvlc_media_new_path(self, str_to_bytes(os.path.normpath(mrl))) for o in options: libvlc_media_add_option(m, str_to_bytes(o)) m._instance = self @@ -1361,27 +1416,6 @@ class Instance(_Ctype): ''' return libvlc_set_user_agent(self, name, http) - def get_log_verbosity(self): - '''Always returns minus one. - This function is only provided for backward compatibility. - @return: always -1. - ''' - return libvlc_get_log_verbosity(self) - - def set_log_verbosity(self, level): - '''This function does nothing. - It is only provided for backward compatibility. - @param level: ignored. - ''' - return libvlc_set_log_verbosity(self, level) - - def log_open(self): - '''This function does nothing useful. - It is only provided for backward compatibility. - @return: an unique pointer or NULL on error. - ''' - return libvlc_log_open(self) - def media_new_location(self, psz_mrl): '''Create a media with a certain given media resource location, for instance a valid URL. @@ -1445,34 +1479,26 @@ class Instance(_Ctype): return libvlc_media_library_new(self) def audio_output_list_get(self): - '''Get the list of available audio outputs. + '''Gets the list of available audio outputs. @return: list of available audio outputs. It must be freed it with In case of error, NULL is returned. ''' return libvlc_audio_output_list_get(self) - def audio_output_device_count(self, psz_audio_output): - '''Get count of devices for audio output, these devices are hardware oriented - like analor or digital output of sound card. - @param psz_audio_output: - name of audio output, See L{AudioOutput}. - @return: number of devices. + def audio_output_device_list_get(self, aout): + '''Gets a list of audio output devices for a given audio output. + See L{audio_output_device_set}(). + @note: Not all audio outputs support this. In particular, an empty (NULL) + list of devices does B{not} imply that the specified audio output does + not work. + @note: The list might not be exhaustive. + @warning: Some audio output devices in the list might not actually work in + some circumstances. By default, it is recommended to not specify any + explicit audio device. + @param psz_aout: audio output name (as returned by L{audio_output_list_get}()). + @return: A NULL-terminated linked list of potential audio output devices. It must be freed it with L{audio_output_device_list_release}(). + @version: LibVLC 2.1.0 or later. ''' - return libvlc_audio_output_device_count(self, psz_audio_output) - - def audio_output_device_longname(self, psz_audio_output, i_device): - '''Get long name of device, if not available short name given. - @param psz_audio_output: - name of audio output, See L{AudioOutput}. - @param i_device: device index. - @return: long name of device. - ''' - return libvlc_audio_output_device_longname(self, psz_audio_output, i_device) - - def audio_output_device_id(self, psz_audio_output, i_device): - '''Get id name of device. - @param psz_audio_output: - name of audio output, See L{AudioOutput}. - @param i_device: device index. - @return: id name of device, use for setting device, need to be free after use. - ''' - return libvlc_audio_output_device_id(self, psz_audio_output, i_device) + return libvlc_audio_output_device_list_get(self, aout) def vlm_release(self): '''Release the vlm instance related to the given L{Instance}. @@ -1683,87 +1709,6 @@ class Instance(_Ctype): ''' return libvlc_vlm_get_event_manager(self) -class Log(_Ctype): - '''Create a new VLC log instance. - - ''' - - def __new__(cls, ptr=_internal_guard): - '''(INTERNAL) ctypes wrapper constructor. - ''' - return _Constructor(cls, ptr) - - def __iter__(self): - return self.get_iterator() - - def dump(self): - return [ str(m) for m in self ] - - - def close(self): - '''Frees memory allocated by L{open}(). - ''' - return libvlc_log_close(self) - - def count(self): - '''Always returns zero. - This function is only provided for backward compatibility. - @return: always zero. - ''' - return libvlc_log_count(self) - - def __len__(self): - return libvlc_log_count(self) - - def clear(self): - '''This function does nothing. - It is only provided for backward compatibility. - ''' - return libvlc_log_clear(self) - - def get_iterator(self): - '''This function does nothing useful. - It is only provided for backward compatibility. - @return: an unique pointer or NULL on error or if the parameter was NULL. - ''' - return libvlc_log_get_iterator(self) - -class LogIterator(_Ctype): - '''Create a new VLC log iterator. - - ''' - - def __new__(cls, ptr=_internal_guard): - '''(INTERNAL) ctypes wrapper constructor. - ''' - return _Constructor(cls, ptr) - - def __iter__(self): - return self - - def next(self): - if self.has_next(): - b = LogMessage() - i = libvlc_log_iterator_next(self, b) - return i.contents - raise StopIteration - - def __next__(self): - return self.next() - - - def free(self): - '''Frees memory allocated by L{log_get_iterator}(). - ''' - return libvlc_log_iterator_free(self) - - def has_next(self): - '''Always returns zero. - This function is only provided for backward compatibility. - @return: always zero. - ''' - return libvlc_log_iterator_has_next(self) - class Media(_Ctype): '''Create a new Media instance. @@ -1809,11 +1754,13 @@ class Media(_Ctype): This option will be used to determine how the media_player will read the media. This allows to use VLC's advanced reading/streaming options on a per-media basis. - The options are detailed in vlc --long-help, for instance - "--sout-all". Note that all options are not usable on medias: - specifically, due to architectural issues, video-related options - such as text renderer options cannot be set on a single media. They - must be set on the whole libvlc instance instead. + @note: The options are listed in 'vlc --long-help' from the command line, + e.g. "-sout-all". Keep in mind that available options and their semantics + vary across LibVLC versions and builds. + @warning: Not all options affects L{Media} objects: + Specifically, due to architectural issues most audio and video options, + such as text renderer options, have no effects on an individual media. + These options must be set through L{new}() instead. @param ppsz_options: the options (as a string). ''' return libvlc_media_add_option(self, ppsz_options) @@ -1906,6 +1853,14 @@ class Media(_Ctype): ''' return libvlc_media_get_stats(self, p_stats) + def subitems(self): + '''Get subitems of media descriptor object. This will increment + the reference count of supplied media descriptor object. Use + L{list_release}() to decrement the reference counting. + @return: list of media descriptor subitems or NULL. + ''' + return libvlc_media_subitems(self) + def event_manager(self): '''Get event manager from media descriptor object. NOTE: this function doesn't increment reference counting. @@ -1925,7 +1880,7 @@ class Media(_Ctype): The method is synchronous. See L{parse_async} See L{get_meta} - See L{get_tracks_info}. + See libvlc_media_get_tracks_info. ''' return libvlc_media_parse(self) @@ -1939,7 +1894,7 @@ class Media(_Ctype): See L{parse} See libvlc_MediaParsedChanged See L{get_meta} - See L{get_tracks_info}. + See libvlc_media_get_tracks_info. ''' return libvlc_media_parse_async(self) @@ -1965,15 +1920,16 @@ class Media(_Ctype): ''' return libvlc_media_get_user_data(self) - def get_tracks_info(self): + def tracks_get(self, tracks): '''Get media descriptor's elementary streams description Note, you need to call L{parse}() or play the media at least once before calling this function. Not doing this will result in an empty array. - @param tracks: address to store an allocated array of Elementary Streams descriptions (must be freed by the caller) [OUT]. - @return: the number of Elementary Streams. + @param tracks: address to store an allocated array of Elementary Streams descriptions (must be freed with L{tracks_release}. + @return: the number of Elementary Streams (zero on error). + @version: LibVLC 2.1.0 and later. ''' - return libvlc_media_get_tracks_info(self) + return libvlc_media_tracks_get(self, tracks) def player_new_from_media(self): '''Create a Media Player object from a Media. @@ -2255,7 +2211,7 @@ class MediaListPlayer(_Ctype): return libvlc_media_list_player_play(self) def pause(self): - '''Pause media list. + '''Toggle pause (or resume) media list. ''' return libvlc_media_list_player_pause(self) @@ -2681,13 +2637,14 @@ class MediaPlayer(_Ctype): return libvlc_media_player_set_time(self, i_time) def get_position(self): - '''Get movie position. + '''Get movie position as percentage between 0.0 and 1.0. @return: movie position, or -1. in case of error. ''' return libvlc_media_player_get_position(self) def set_position(self, f_pos): - '''Set movie position. This has no effect if playback is not enabled. + '''Set movie position as percentage between 0.0 and 1.0. + This has no effect if playback is not enabled. This might not work depending on the underlying input format and protocol. @param f_pos: the position. ''' @@ -2968,13 +2925,13 @@ class MediaPlayer(_Ctype): def video_get_track(self): '''Get current video track. - @return: the video track (int) or -1 if none. + @return: the video track ID (int) or -1 if no active input. ''' return libvlc_video_get_track(self) def video_set_track(self, i_track): '''Set video track. - @param i_track: the track (int). + @param i_track: the track ID (i_id field from track description). @return: 0 on success, -1 if out of range. ''' return libvlc_video_set_track(self, i_track) @@ -3084,33 +3041,30 @@ class MediaPlayer(_Ctype): return libvlc_video_set_adjust_float(self, option, value) def audio_output_set(self, psz_name): - '''Set the audio output. - Change will be applied after stop and play. + '''Sets the audio output. + @note: Any change will take be effect only after playback is stopped and + restarted. Audio output cannot be changed while playing. @param psz_name: name of audio output, use psz_name of See L{AudioOutput}. @return: 0 if function succeded, -1 on error. ''' return libvlc_audio_output_set(self, psz_name) def audio_output_device_set(self, psz_audio_output, psz_device_id): - '''Set audio output device. Changes are only effective after stop and play. + '''Configures an explicit audio output device for a given audio output plugin. + A list of possible devices can be obtained with + L{audio_output_device_list_get}(). + @note: This function does not select the specified audio output plugin. + L{audio_output_set}() is used for that purpose. + @warning: The syntax for the device parameter depends on the audio output. + This is not portable. Only use this function if you know what you are doing. + Some audio outputs do not support this function (e.g. PulseAudio, WASAPI). + Some audio outputs require further parameters (e.g. ALSA: channels map). @param psz_audio_output: - name of audio output, See L{AudioOutput}. @param psz_device_id: device. + @return: Nothing. Errors are ignored. ''' return libvlc_audio_output_device_set(self, psz_audio_output, psz_device_id) - def audio_output_get_device_type(self): - '''Get current audio device type. Device type describes something like - character of output sound - stereo sound, 2.1, 5.1 etc. - @return: the audio devices type See libvlc_audio_output_device_types_t. - ''' - return libvlc_audio_output_get_device_type(self) - - def audio_output_set_device_type(self, device_type): - '''Set current audio device type. - @param device_type: the audio device type, - ''' - return libvlc_audio_output_set_device_type(self, device_type) - def audio_toggle_mute(self): '''Toggle mute status. ''' @@ -3118,13 +3072,13 @@ class MediaPlayer(_Ctype): def audio_get_mute(self): '''Get current mute status. - @return: the mute status (boolean) \libvlc_return_bool. + @return: the mute status (boolean) if defined, -1 if undefined/unapplicable. ''' return libvlc_audio_get_mute(self) def audio_set_mute(self, status): '''Set mute status. - @param status: If status is true then mute, otherwise unmute. + @param status: If status is true then mute, otherwise unmute @warning This function does not always work. If there are no active audio playback stream, the mute status might not be available. If digital pass-through (S/PDIF, HDMI...) is in use, muting may be unapplicable. Also some audio output plugins do not support muting at all. @note To force silent playback, disable all audio tracks. This is more efficient and reliable than mute. ''' return libvlc_audio_set_mute(self, status) @@ -3149,13 +3103,13 @@ class MediaPlayer(_Ctype): def audio_get_track(self): '''Get current audio track. - @return: the audio track (int), or -1 if none. + @return: the audio track ID or -1 if no active input. ''' return libvlc_audio_get_track(self) def audio_set_track(self, i_track): '''Set current audio track. - @param i_track: the track (int). + @param i_track: the track ID (i_id field from track description). @return: 0 on success, -1 on error. ''' return libvlc_audio_set_track(self, i_track) @@ -3397,112 +3351,6 @@ def libvlc_log_unsubscribe(sub): None, ctypes.c_void_p) return f(sub) -def libvlc_get_log_verbosity(p_instance): - '''Always returns minus one. - This function is only provided for backward compatibility. - @param p_instance: ignored. - @return: always -1. - ''' - f = _Cfunctions.get('libvlc_get_log_verbosity', None) or \ - _Cfunction('libvlc_get_log_verbosity', ((1,),), None, - ctypes.c_uint, Instance) - return f(p_instance) - -def libvlc_set_log_verbosity(p_instance, level): - '''This function does nothing. - It is only provided for backward compatibility. - @param p_instance: ignored. - @param level: ignored. - ''' - f = _Cfunctions.get('libvlc_set_log_verbosity', None) or \ - _Cfunction('libvlc_set_log_verbosity', ((1,), (1,),), None, - None, Instance, ctypes.c_uint) - return f(p_instance, level) - -def libvlc_log_open(p_instance): - '''This function does nothing useful. - It is only provided for backward compatibility. - @param p_instance: libvlc instance. - @return: an unique pointer or NULL on error. - ''' - f = _Cfunctions.get('libvlc_log_open', None) or \ - _Cfunction('libvlc_log_open', ((1,),), class_result(Log), - ctypes.c_void_p, Instance) - return f(p_instance) - -def libvlc_log_close(p_log): - '''Frees memory allocated by L{libvlc_log_open}(). - @param p_log: libvlc log instance or NULL. - ''' - f = _Cfunctions.get('libvlc_log_close', None) or \ - _Cfunction('libvlc_log_close', ((1,),), None, - None, Log) - return f(p_log) - -def libvlc_log_count(p_log): - '''Always returns zero. - This function is only provided for backward compatibility. - @param p_log: ignored. - @return: always zero. - ''' - f = _Cfunctions.get('libvlc_log_count', None) or \ - _Cfunction('libvlc_log_count', ((1,),), None, - ctypes.c_uint, Log) - return f(p_log) - -def libvlc_log_clear(p_log): - '''This function does nothing. - It is only provided for backward compatibility. - @param p_log: ignored. - ''' - f = _Cfunctions.get('libvlc_log_clear', None) or \ - _Cfunction('libvlc_log_clear', ((1,),), None, - None, Log) - return f(p_log) - -def libvlc_log_get_iterator(p_log): - '''This function does nothing useful. - It is only provided for backward compatibility. - @param p_log: ignored. - @return: an unique pointer or NULL on error or if the parameter was NULL. - ''' - f = _Cfunctions.get('libvlc_log_get_iterator', None) or \ - _Cfunction('libvlc_log_get_iterator', ((1,),), class_result(LogIterator), - ctypes.c_void_p, Log) - return f(p_log) - -def libvlc_log_iterator_free(p_iter): - '''Frees memory allocated by L{libvlc_log_get_iterator}(). - @param p_iter: libvlc log iterator or NULL. - ''' - f = _Cfunctions.get('libvlc_log_iterator_free', None) or \ - _Cfunction('libvlc_log_iterator_free', ((1,),), None, - None, LogIterator) - return f(p_iter) - -def libvlc_log_iterator_has_next(p_iter): - '''Always returns zero. - This function is only provided for backward compatibility. - @param p_iter: ignored. - @return: always zero. - ''' - f = _Cfunctions.get('libvlc_log_iterator_has_next', None) or \ - _Cfunction('libvlc_log_iterator_has_next', ((1,),), None, - ctypes.c_int, LogIterator) - return f(p_iter) - -def libvlc_log_iterator_next(p_iter, p_buffer): - '''Always returns NULL. - This function is only provided for backward compatibility. - @param p_iter: libvlc log iterator or NULL. - @param p_buffer: ignored. - @return: always NULL. - ''' - f = _Cfunctions.get('libvlc_log_iterator_next', None) or \ - _Cfunction('libvlc_log_iterator_next', ((1,), (1,),), None, - ctypes.POINTER(LogMessage), LogIterator, ctypes.POINTER(LogMessage)) - return f(p_iter, p_buffer) - def libvlc_module_description_list_release(p_list): '''Release a list of module descriptions. @param p_list: the list to be released. @@ -3615,11 +3463,13 @@ def libvlc_media_add_option(p_md, ppsz_options): This option will be used to determine how the media_player will read the media. This allows to use VLC's advanced reading/streaming options on a per-media basis. - The options are detailed in vlc --long-help, for instance - "--sout-all". Note that all options are not usable on medias: - specifically, due to architectural issues, video-related options - such as text renderer options cannot be set on a single media. They - must be set on the whole libvlc instance instead. + @note: The options are listed in 'vlc --long-help' from the command line, + e.g. "-sout-all". Keep in mind that available options and their semantics + vary across LibVLC versions and builds. + @warning: Not all options affects L{Media} objects: + Specifically, due to architectural issues most audio and video options, + such as text renderer options, have no effects on an individual media. + These options must be set through L{libvlc_new}() instead. @param p_md: the media descriptor. @param ppsz_options: the options (as a string). ''' @@ -3756,6 +3606,18 @@ def libvlc_media_get_stats(p_md, p_stats): ctypes.c_int, Media, ctypes.POINTER(MediaStats)) return f(p_md, p_stats) +def libvlc_media_subitems(p_md): + '''Get subitems of media descriptor object. This will increment + the reference count of supplied media descriptor object. Use + L{libvlc_media_list_release}() to decrement the reference counting. + @param p_md: media descriptor object. + @return: list of media descriptor subitems or NULL. + ''' + f = _Cfunctions.get('libvlc_media_subitems', None) or \ + _Cfunction('libvlc_media_subitems', ((1,),), class_result(MediaList), + ctypes.c_void_p, Media) + return f(p_md) + def libvlc_media_event_manager(p_md): '''Get event manager from media descriptor object. NOTE: this function doesn't increment reference counting. @@ -3783,7 +3645,7 @@ def libvlc_media_parse(p_md): The method is synchronous. See L{libvlc_media_parse_async} See L{libvlc_media_get_meta} - See L{libvlc_media_get_tracks_info}. + See libvlc_media_get_tracks_info. @param p_md: media descriptor object. ''' f = _Cfunctions.get('libvlc_media_parse', None) or \ @@ -3801,7 +3663,7 @@ def libvlc_media_parse_async(p_md): See L{libvlc_media_parse} See libvlc_MediaParsedChanged See L{libvlc_media_get_meta} - See L{libvlc_media_get_tracks_info}. + See libvlc_media_get_tracks_info. @param p_md: media descriptor object. ''' f = _Cfunctions.get('libvlc_media_parse_async', None) or \ @@ -3843,19 +3705,31 @@ def libvlc_media_get_user_data(p_md): ctypes.c_void_p, Media) return f(p_md) -def libvlc_media_get_tracks_info(p_md): +def libvlc_media_tracks_get(p_md, tracks): '''Get media descriptor's elementary streams description Note, you need to call L{libvlc_media_parse}() or play the media at least once before calling this function. Not doing this will result in an empty array. @param p_md: media descriptor object. - @param tracks: address to store an allocated array of Elementary Streams descriptions (must be freed by the caller) [OUT]. - @return: the number of Elementary Streams. + @param tracks: address to store an allocated array of Elementary Streams descriptions (must be freed with L{libvlc_media_tracks_release}. + @return: the number of Elementary Streams (zero on error). + @version: LibVLC 2.1.0 and later. ''' - f = _Cfunctions.get('libvlc_media_get_tracks_info', None) or \ - _Cfunction('libvlc_media_get_tracks_info', ((1,), (2,),), None, - ctypes.c_int, Media, ctypes.POINTER(ctypes.c_void_p)) - return f(p_md) + f = _Cfunctions.get('libvlc_media_tracks_get', None) or \ + _Cfunction('libvlc_media_tracks_get', ((1,), (1,),), None, + ctypes.c_uint, Media, ctypes.POINTER(ctypes.POINTER(MediaTrack))) + return f(p_md, tracks) + +def libvlc_media_tracks_release(p_tracks, i_count): + '''Release media descriptor's elementary streams description array. + @param p_tracks: tracks info array to release. + @param i_count: number of elements in the array. + @version: LibVLC 2.1.0 and later. + ''' + f = _Cfunctions.get('libvlc_media_tracks_release', None) or \ + _Cfunction('libvlc_media_tracks_release', ((1,), (1,),), None, + None, ctypes.POINTER(MediaTrack), ctypes.c_uint) + return f(p_tracks, i_count) def libvlc_media_discoverer_new_from_name(p_inst, psz_name): '''Discover media service by name. @@ -4208,7 +4082,7 @@ def libvlc_media_list_player_play(p_mlp): return f(p_mlp) def libvlc_media_list_player_pause(p_mlp): - '''Pause media list. + '''Toggle pause (or resume) media list. @param p_mlp: media list player instance. ''' f = _Cfunctions.get('libvlc_media_list_player_pause', None) or \ @@ -4673,7 +4547,7 @@ def libvlc_media_player_set_time(p_mi, i_time): return f(p_mi, i_time) def libvlc_media_player_get_position(p_mi): - '''Get movie position. + '''Get movie position as percentage between 0.0 and 1.0. @param p_mi: the Media Player. @return: movie position, or -1. in case of error. ''' @@ -4683,7 +4557,8 @@ def libvlc_media_player_get_position(p_mi): return f(p_mi) def libvlc_media_player_set_position(p_mi, f_pos): - '''Set movie position. This has no effect if playback is not enabled. + '''Set movie position as percentage between 0.0 and 1.0. + This has no effect if playback is not enabled. This might not work depending on the underlying input format and protocol. @param p_mi: the Media Player. @param f_pos: the position. @@ -4894,14 +4769,6 @@ def libvlc_track_description_list_release(p_track_description): None, ctypes.POINTER(TrackDescription)) return f(p_track_description) -def libvlc_track_description_release(p_track_description): - '''\deprecated Use L{libvlc_track_description_list_release} instead. - ''' - f = _Cfunctions.get('libvlc_track_description_release', None) or \ - _Cfunction('libvlc_track_description_release', ((1,),), None, - None, ctypes.POINTER(TrackDescription)) - return f(p_track_description) - def libvlc_toggle_fullscreen(p_mi): '''Toggle fullscreen status on non-embedded video outputs. @warning: The same limitations applies to this function @@ -5219,7 +5086,7 @@ def libvlc_video_get_track_description(p_mi): def libvlc_video_get_track(p_mi): '''Get current video track. @param p_mi: media player. - @return: the video track (int) or -1 if none. + @return: the video track ID (int) or -1 if no active input. ''' f = _Cfunctions.get('libvlc_video_get_track', None) or \ _Cfunction('libvlc_video_get_track', ((1,),), None, @@ -5229,7 +5096,7 @@ def libvlc_video_get_track(p_mi): def libvlc_video_set_track(p_mi, i_track): '''Set video track. @param p_mi: media player. - @param i_track: the track (int). + @param i_track: the track ID (i_id field from track description). @return: 0 on success, -1 if out of range. ''' f = _Cfunctions.get('libvlc_video_set_track', None) or \ @@ -5394,7 +5261,7 @@ def libvlc_video_set_adjust_float(p_mi, option, value): return f(p_mi, option, value) def libvlc_audio_output_list_get(p_instance): - '''Get the list of available audio outputs. + '''Gets the list of available audio outputs. @param p_instance: libvlc instance. @return: list of available audio outputs. It must be freed it with In case of error, NULL is returned. ''' @@ -5404,7 +5271,7 @@ def libvlc_audio_output_list_get(p_instance): return f(p_instance) def libvlc_audio_output_list_release(p_list): - '''Free the list of available audio outputs. + '''Frees the list of available audio outputs. @param p_list: list with audio outputs for release. ''' f = _Cfunctions.get('libvlc_audio_output_list_release', None) or \ @@ -5413,8 +5280,9 @@ def libvlc_audio_output_list_release(p_list): return f(p_list) def libvlc_audio_output_set(p_mi, psz_name): - '''Set the audio output. - Change will be applied after stop and play. + '''Sets the audio output. + @note: Any change will take be effect only after playback is stopped and + restarted. Audio output cannot be changed while playing. @param p_mi: media player. @param psz_name: name of audio output, use psz_name of See L{AudioOutput}. @return: 0 if function succeded, -1 on error. @@ -5424,77 +5292,59 @@ def libvlc_audio_output_set(p_mi, psz_name): ctypes.c_int, MediaPlayer, ctypes.c_char_p) return f(p_mi, psz_name) -def libvlc_audio_output_device_count(p_instance, psz_audio_output): - '''Get count of devices for audio output, these devices are hardware oriented - like analor or digital output of sound card. +def libvlc_audio_output_device_list_get(p_instance, aout): + '''Gets a list of audio output devices for a given audio output. + See L{libvlc_audio_output_device_set}(). + @note: Not all audio outputs support this. In particular, an empty (NULL) + list of devices does B{not} imply that the specified audio output does + not work. + @note: The list might not be exhaustive. + @warning: Some audio output devices in the list might not actually work in + some circumstances. By default, it is recommended to not specify any + explicit audio device. @param p_instance: libvlc instance. - @param psz_audio_output: - name of audio output, See L{AudioOutput}. - @return: number of devices. + @param psz_aout: audio output name (as returned by L{libvlc_audio_output_list_get}()). + @return: A NULL-terminated linked list of potential audio output devices. It must be freed it with L{libvlc_audio_output_device_list_release}(). + @version: LibVLC 2.1.0 or later. ''' - f = _Cfunctions.get('libvlc_audio_output_device_count', None) or \ - _Cfunction('libvlc_audio_output_device_count', ((1,), (1,),), None, - ctypes.c_int, Instance, ctypes.c_char_p) - return f(p_instance, psz_audio_output) + f = _Cfunctions.get('libvlc_audio_output_device_list_get', None) or \ + _Cfunction('libvlc_audio_output_device_list_get', ((1,), (1,),), None, + ctypes.POINTER(AudioOutputDevice), Instance, ctypes.c_char_p) + return f(p_instance, aout) -def libvlc_audio_output_device_longname(p_instance, psz_audio_output, i_device): - '''Get long name of device, if not available short name given. - @param p_instance: libvlc instance. - @param psz_audio_output: - name of audio output, See L{AudioOutput}. - @param i_device: device index. - @return: long name of device. +def libvlc_audio_output_device_list_release(p_list): + '''Frees a list of available audio output devices. + @param p_list: list with audio outputs for release. + @version: LibVLC 2.1.0 or later. ''' - f = _Cfunctions.get('libvlc_audio_output_device_longname', None) or \ - _Cfunction('libvlc_audio_output_device_longname', ((1,), (1,), (1,),), string_result, - ctypes.c_void_p, Instance, ctypes.c_char_p, ctypes.c_int) - return f(p_instance, psz_audio_output, i_device) - -def libvlc_audio_output_device_id(p_instance, psz_audio_output, i_device): - '''Get id name of device. - @param p_instance: libvlc instance. - @param psz_audio_output: - name of audio output, See L{AudioOutput}. - @param i_device: device index. - @return: id name of device, use for setting device, need to be free after use. - ''' - f = _Cfunctions.get('libvlc_audio_output_device_id', None) or \ - _Cfunction('libvlc_audio_output_device_id', ((1,), (1,), (1,),), string_result, - ctypes.c_void_p, Instance, ctypes.c_char_p, ctypes.c_int) - return f(p_instance, psz_audio_output, i_device) + f = _Cfunctions.get('libvlc_audio_output_device_list_release', None) or \ + _Cfunction('libvlc_audio_output_device_list_release', ((1,),), None, + None, ctypes.POINTER(AudioOutputDevice)) + return f(p_list) def libvlc_audio_output_device_set(p_mi, psz_audio_output, psz_device_id): - '''Set audio output device. Changes are only effective after stop and play. + '''Configures an explicit audio output device for a given audio output plugin. + A list of possible devices can be obtained with + L{libvlc_audio_output_device_list_get}(). + @note: This function does not select the specified audio output plugin. + L{libvlc_audio_output_set}() is used for that purpose. + @warning: The syntax for the device parameter depends on the audio output. + This is not portable. Only use this function if you know what you are doing. + Some audio outputs do not support this function (e.g. PulseAudio, WASAPI). + Some audio outputs require further parameters (e.g. ALSA: channels map). @param p_mi: media player. @param psz_audio_output: - name of audio output, See L{AudioOutput}. @param psz_device_id: device. + @return: Nothing. Errors are ignored. ''' f = _Cfunctions.get('libvlc_audio_output_device_set', None) or \ _Cfunction('libvlc_audio_output_device_set', ((1,), (1,), (1,),), None, None, MediaPlayer, ctypes.c_char_p, ctypes.c_char_p) return f(p_mi, psz_audio_output, psz_device_id) -def libvlc_audio_output_get_device_type(p_mi): - '''Get current audio device type. Device type describes something like - character of output sound - stereo sound, 2.1, 5.1 etc. - @param p_mi: media player. - @return: the audio devices type See libvlc_audio_output_device_types_t. - ''' - f = _Cfunctions.get('libvlc_audio_output_get_device_type', None) or \ - _Cfunction('libvlc_audio_output_get_device_type', ((1,),), None, - ctypes.c_int, MediaPlayer) - return f(p_mi) - -def libvlc_audio_output_set_device_type(p_mi, device_type): - '''Set current audio device type. - @param p_mi: vlc instance. - @param device_type: the audio device type, - ''' - f = _Cfunctions.get('libvlc_audio_output_set_device_type', None) or \ - _Cfunction('libvlc_audio_output_set_device_type', ((1,), (1,),), None, - None, MediaPlayer, ctypes.c_int) - return f(p_mi, device_type) - def libvlc_audio_toggle_mute(p_mi): '''Toggle mute status. - @param p_mi: media player. + @param p_mi: media player @warning Toggling mute atomically is not always possible: On some platforms, other processes can mute the VLC audio playback stream asynchronously. Thus, there is a small race condition where toggling will not work. See also the limitations of L{libvlc_audio_set_mute}(). ''' f = _Cfunctions.get('libvlc_audio_toggle_mute', None) or \ _Cfunction('libvlc_audio_toggle_mute', ((1,),), None, @@ -5504,7 +5354,7 @@ def libvlc_audio_toggle_mute(p_mi): def libvlc_audio_get_mute(p_mi): '''Get current mute status. @param p_mi: media player. - @return: the mute status (boolean) \libvlc_return_bool. + @return: the mute status (boolean) if defined, -1 if undefined/unapplicable. ''' f = _Cfunctions.get('libvlc_audio_get_mute', None) or \ _Cfunction('libvlc_audio_get_mute', ((1,),), None, @@ -5514,7 +5364,7 @@ def libvlc_audio_get_mute(p_mi): def libvlc_audio_set_mute(p_mi, status): '''Set mute status. @param p_mi: media player. - @param status: If status is true then mute, otherwise unmute. + @param status: If status is true then mute, otherwise unmute @warning This function does not always work. If there are no active audio playback stream, the mute status might not be available. If digital pass-through (S/PDIF, HDMI...) is in use, muting may be unapplicable. Also some audio output plugins do not support muting at all. @note To force silent playback, disable all audio tracks. This is more efficient and reliable than mute. ''' f = _Cfunctions.get('libvlc_audio_set_mute', None) or \ _Cfunction('libvlc_audio_set_mute', ((1,), (1,),), None, @@ -5565,7 +5415,7 @@ def libvlc_audio_get_track_description(p_mi): def libvlc_audio_get_track(p_mi): '''Get current audio track. @param p_mi: media player. - @return: the audio track (int), or -1 if none. + @return: the audio track ID or -1 if no active input. ''' f = _Cfunctions.get('libvlc_audio_get_track', None) or \ _Cfunction('libvlc_audio_get_track', ((1,),), None, @@ -5575,7 +5425,7 @@ def libvlc_audio_get_track(p_mi): def libvlc_audio_set_track(p_mi, i_track): '''Set current audio track. @param p_mi: media player. - @param i_track: the track (int). + @param i_track: the track ID (i_id field from track description). @return: 0 on success, -1 on error. ''' f = _Cfunctions.get('libvlc_audio_set_track', None) or \ @@ -5933,11 +5783,14 @@ def libvlc_vlm_get_event_manager(p_instance): return f(p_instance) -# 2 function(s) blacklisted: +# 4 function(s) blacklisted: +# libvlc_audio_output_get_device_type +# libvlc_audio_output_set_device_type # libvlc_printerr # libvlc_set_exit_handler -# 17 function(s) not wrapped as methods: +# 18 function(s) not wrapped as methods: +# libvlc_audio_output_device_list_release # libvlc_audio_output_list_release # libvlc_clearerr # libvlc_clock @@ -5950,10 +5803,10 @@ def libvlc_vlm_get_event_manager(p_instance): # libvlc_log_subscribe # libvlc_log_subscribe_file # libvlc_log_unsubscribe +# libvlc_media_tracks_release # libvlc_module_description_list_release # libvlc_new # libvlc_track_description_list_release -# libvlc_track_description_release # libvlc_vprinterr # Start of footer.py # @@ -6075,9 +5928,9 @@ if __name__ == '__main__': print('Error: %s file not readable' % movie) sys.exit(1) - instance = Instance() + instance = Instance("--sub-source marq") try: - media = instance.media_new(movie, 'sub-filter=marq') # load marqee option + media = instance.media_new(movie) except NameError: print('NameError: %s (%s vs LibVLC %s)' % (sys.exc_info()[1], __version__, @@ -6087,13 +5940,12 @@ if __name__ == '__main__': player.set_media(media) player.play() - # Some marquee examples. Marquee requires 'sub-filter=marq' in the - # media_new() call above. See also the Media.add_options method - # and + # Some marquee examples. Marquee requires '--sub-source marq' in the + # Instance() call above. See player.video_set_marquee_int(VideoMarqueeOption.Enable, 1) player.video_set_marquee_int(VideoMarqueeOption.Size, 24) # pixels player.video_set_marquee_int(VideoMarqueeOption.Position, Position.Bottom) - if True: # only one marquee can be specified + if False: # only one marquee can be specified player.video_set_marquee_int(VideoMarqueeOption.Timeout, 5000) # millisec, 0==forever t = media.get_mrl() # movie else: # update marquee text periodically From 718a440b8fceba5da05701bb38110fe160200bc4 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 19 Feb 2013 08:27:55 +0100 Subject: [PATCH 18/48] added another formattingtags test --- .../functional/openlp_core_lib/test_formattingtags.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/functional/openlp_core_lib/test_formattingtags.py b/tests/functional/openlp_core_lib/test_formattingtags.py index 335650112..4c7b00909 100644 --- a/tests/functional/openlp_core_lib/test_formattingtags.py +++ b/tests/functional/openlp_core_lib/test_formattingtags.py @@ -50,7 +50,7 @@ class TestFormattingTags(TestCase): def get_html_tags_with_user_tags_test(self): """ - Test the FormattingTags class' get_html_tags static method in combination with user tags. + FormattingTags class - test the get_html_tags(), add_html_tags() and remove_html_tag() methods. """ with patch(u'openlp.core.lib.translate') as mocked_translate, \ patch(u'openlp.core.lib.settings') as mocked_settings, \ @@ -67,7 +67,7 @@ class TestFormattingTags(TestCase): # WHEN: Add our tag and get the tags again. FormattingTags.load_tags() FormattingTags.add_html_tags([TAG]) - new_tags_list = FormattingTags.get_html_tags() + new_tags_list = copy.deepcopy(FormattingTags.get_html_tags()) # THEN: Lists should not be identically. assert old_tags_list != new_tags_list, u'The lists should be different.' @@ -76,3 +76,9 @@ class TestFormattingTags(TestCase): new_tag = new_tags_list.pop() assert TAG == new_tag, u'Tags should be identically.' + # WHEN: Remove the new tag with the FormattingTags.remove_html_tag() method. + FormattingTags.remove_html_tag(len(new_tags_list)) + + # THEN: The lists should now be identically. + assert old_tags_list == FormattingTags.get_html_tags(), u'The lists should be identically.' + From 03941538e5261ea9c6e996ebb10bbde1119dc262 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 19 Feb 2013 08:30:41 +0100 Subject: [PATCH 19/48] changed comment --- tests/functional/openlp_core_lib/test_formattingtags.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/openlp_core_lib/test_formattingtags.py b/tests/functional/openlp_core_lib/test_formattingtags.py index 4c7b00909..6c60be5ac 100644 --- a/tests/functional/openlp_core_lib/test_formattingtags.py +++ b/tests/functional/openlp_core_lib/test_formattingtags.py @@ -76,7 +76,7 @@ class TestFormattingTags(TestCase): new_tag = new_tags_list.pop() assert TAG == new_tag, u'Tags should be identically.' - # WHEN: Remove the new tag with the FormattingTags.remove_html_tag() method. + # WHEN: Remove the new tag. FormattingTags.remove_html_tag(len(new_tags_list)) # THEN: The lists should now be identically. From 781da422b6cc89386f9ed265aff8d341f1227be9 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 19 Feb 2013 10:13:49 +0100 Subject: [PATCH 20/48] started to remove forgotten shortcut kwargs --- openlp/core/lib/mediamanageritem.py | 12 +- openlp/core/lib/settings.py | 31 +++++ openlp/core/lib/ui.py | 28 +++-- openlp/core/ui/mainwindow.py | 62 +++++----- openlp/core/ui/servicemanager.py | 34 +++--- openlp/core/ui/slidecontroller.py | 72 ++++++------ openlp/core/utils/actions.py | 121 +++++++++----------- openlp/plugins/alerts/alertsplugin.py | 2 +- openlp/plugins/images/lib/mediaitem.py | 4 +- openlp/plugins/songusage/songusageplugin.py | 2 +- 10 files changed, 196 insertions(+), 172 deletions(-) diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index bb8ee2f70..e473ce8bf 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -229,26 +229,26 @@ class MediaManagerItem(QtGui.QWidget): triggers=self.onEditClick) create_widget_action(self.listView, separator=True) if self.hasDeleteIcon: - create_widget_action(self.listView, + create_widget_action(self.listView, u'%s%s' % (self.plugin.name, StringContent.Delete), text=self.plugin.getString(StringContent.Delete)[u'title'], 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, text=self.plugin.getString(StringContent.Preview)[u'title'], icon=u':/general/general_preview.png', - shortcuts=[QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], + can_shortcuts=True, triggers=self.onPreviewClick) create_widget_action(self.listView, text=self.plugin.getString(StringContent.Live)[u'title'], icon=u':/general/general_live.png', - shortcuts=[QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter, - QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return], + can_shortcuts=True, triggers=self.onLiveClick) create_widget_action(self.listView, text=self.plugin.getString(StringContent.Service)[u'title'], + can_shortcuts=True, icon=u':/general/general_add.png', - shortcuts=[QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal], triggers=self.onAddClick) if self.addToServiceItem: create_widget_action(self.listView, separator=True) diff --git a/openlp/core/lib/settings.py b/openlp/core/lib/settings.py index 7e72c6d4c..6bd8c983a 100644 --- a/openlp/core/lib/settings.py +++ b/openlp/core/lib/settings.py @@ -151,12 +151,15 @@ class Settings(QtCore.QSettings): u'SettingsImport/type': u'OpenLP_settings_export', u'SettingsImport/version': u'', u'shortcuts/aboutItem': [QtGui.QKeySequence(u'Ctrl+F1')], + u'shortcuts/addToService': [], u'shortcuts/audioPauseItem': [], u'shortcuts/displayTagItem': [], u'shortcuts/blankScreen': [QtCore.Qt.Key_Period], u'shortcuts/collapse': [QtCore.Qt.Key_Minus], u'shortcuts/desktopScreen': [QtGui.QKeySequence(u'D')], + u'shortcuts/delete': [], u'shortcuts/down': [QtCore.Qt.Key_Down], + u'shortcuts/editSong': [], u'shortcuts/escapeItem': [QtCore.Qt.Key_Escape], u'shortcuts/expand': [QtCore.Qt.Key_Plus], u'shortcuts/exportThemeItem': [], @@ -165,8 +168,10 @@ class Settings(QtCore.QSettings): u'shortcuts/fileExitItem': [QtGui.QKeySequence(u'Alt+F4')], u'shortcuts/fileSaveItem': [QtGui.QKeySequence(u'Ctrl+S')], u'shortcuts/fileOpenItem': [QtGui.QKeySequence(u'Ctrl+O')], + u'shortcuts/goLive': [], u'shortcuts/importThemeItem': [], u'shortcuts/importBibleItem': [], + u'shortcuts/lockPanel': [], u'shortcuts/modeDefaultItem': [], u'shortcuts/modeLiveItem': [], u'shortcuts/make_live': [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], @@ -177,13 +182,21 @@ class Settings(QtCore.QSettings): u'shortcuts/moveDown': [QtCore.Qt.Key_PageDown], u'shortcuts/nextTrackItem': [], u'shortcuts/nextItem_live': [QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown], + u'shortcuts/nextItem_preview': [], u'shortcuts/nextService': [QtCore.Qt.Key_Right], + u'shortcuts/newService': [], u'shortcuts/offlineHelpItem': [], u'shortcuts/onlineHelpItem': [QtGui.QKeySequence(u'Alt+F1')], + u'shortcuts/openService': [], + u'shortcuts/saveService': [], u'shortcuts/previousItem_live': [QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp], + u'shortcuts/playbackPause': [], + u'shortcuts/playbackPlay': [], + u'shortcuts/playbackStop': [], u'shortcuts/playSlidesLoop': [], u'shortcuts/playSlidesOnce': [], u'shortcuts/previousService': [QtCore.Qt.Key_Left], + u'shortcuts/previousItem_preview': [], u'shortcuts/printServiceItem': [QtGui.QKeySequence(u'Ctrl+P')], u'shortcuts/songExportItem': [], u'shortcuts/songUsageStatus': [QtCore.Qt.Key_F4], @@ -199,6 +212,16 @@ class Settings(QtCore.QSettings): u'shortcuts/shortcutAction_O': [QtGui.QKeySequence(u'O')], u'shortcuts/shortcutAction_P': [QtGui.QKeySequence(u'P')], 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/songUsageReport': [], u'shortcuts/songImportItem': [], @@ -286,6 +309,14 @@ class Settings(QtCore.QSettings): else: 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): """ This method is only called to clean up the config. It removes old settings and it renames settings. See diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index 4f4aa0596..24835622c 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -33,7 +33,7 @@ import logging from PyQt4 import QtCore, QtGui -from openlp.core.lib import Receiver, UiStrings, build_icon, translate +from openlp.core.lib import Receiver, UiStrings, Settings, build_icon, translate from openlp.core.utils.actions import ActionList @@ -236,6 +236,11 @@ def create_action(parent, name, **kwargs): Either a QIcon, a resource string, or a file location string for the action icon. + ``can_shortcuts`` + Boolean stating if this action has shortcuts or if it can have shortcuts. If ``True`` the action is added to + shortcut dialog. **Note**: Never set the shortcuts yourselt; use the :class:`~openlp.core.lib.Settings` class + to define the action's shortcuts. + ``tooltip`` A string for the action tool tip. @@ -257,9 +262,6 @@ def create_action(parent, name, **kwargs): ``data`` The action's data. - ``shortcuts`` - A QList (or a list of strings) which are set as shortcuts. - ``context`` A context for the shortcut execution. @@ -290,18 +292,20 @@ def create_action(parent, name, **kwargs): action.setSeparator(True) if u'data' in kwargs: action.setData(kwargs.pop(u'data')) - if kwargs.get(u'shortcuts'): - action.setShortcuts(kwargs.pop(u'shortcuts')) if u'context' in kwargs: 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'): - QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'), - kwargs.pop(u'triggers')) + QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'), kwargs.pop(u'triggers')) + if kwargs.pop(u'can_shortcuts', False): + if not action.objectName(): + raise Exception("objectName not set") + action_list = ActionList.get_instance() + action_list.add_action(action, kwargs.pop(u'category', None)) + else: + pass + #print u'else', action.objectName() 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'category', u'triggers']: log.warn(u'Parameter %s was not consumed in create_action().', key) return action diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index cb94a0914..81936cfdc 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -174,68 +174,78 @@ class Ui_MainWindow(object): main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.themeManagerDock) # Create the menu items 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', icon=u':/general/general_new.png', - shortcuts=[QtGui.QKeySequence(u'Ctrl+N')], + can_shortcuts=True, category=UiStrings().File, triggers=self.serviceManagerContents.on_new_service_clicked) self.fileOpenItem = create_action(main_window, u'fileOpenItem', icon=u':/general/general_open.png', - shortcuts=[QtGui.QKeySequence(u'Ctrl+O')], + can_shortcuts=True, category=UiStrings().File, triggers=self.serviceManagerContents.on_load_service_clicked) self.fileSaveItem = create_action(main_window, u'fileSaveItem', icon=u':/general/general_save.png', - shortcuts=[QtGui.QKeySequence(u'Ctrl+S')], + can_shortcuts=True, category=UiStrings().File, triggers=self.serviceManagerContents.save_file) self.fileSaveAsItem = create_action(main_window, u'fileSaveAsItem', - shortcuts=[QtGui.QKeySequence(u'Ctrl+Shift+S')], + can_shortcuts=True, category=UiStrings().File, triggers=self.serviceManagerContents.save_file_as) self.printServiceOrderItem = create_action(main_window, - u'printServiceItem', shortcuts=[QtGui.QKeySequence(u'Ctrl+P')], + u'printServiceItem', + can_shortcuts=True, category=UiStrings().File, triggers=self.serviceManagerContents.print_service_order) self.fileExitItem = create_action(main_window, u'fileExitItem', icon=u':/system/system_exit.png', - shortcuts=[QtGui.QKeySequence(u'Alt+F4')], - category=UiStrings().File, triggers=main_window.close) + can_shortcuts=True, + category=UiStrings().File, + triggers=main_window.close) # Give QT Extra Hint that this is the Exit Menu Item 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.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.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, - u'viewMediaManagerItem', shortcuts=[QtGui.QKeySequence(u'F8')], + u'viewMediaManagerItem', icon=u':/system/system_mediamanager.png', checked=self.mediaManagerDock.isVisible(), + can_shortcuts=True, category=UiStrings().View, triggers=self.toggleMediaManager) self.viewThemeManagerItem = create_action(main_window, - u'viewThemeManagerItem', shortcuts=[QtGui.QKeySequence(u'F10')], + u'viewThemeManagerItem', icon=u':/system/system_thememanager.png', checked=self.themeManagerDock.isVisible(), + can_shortcuts=True, category=UiStrings().View, triggers=self.toggleThemeManager) self.viewServiceManagerItem = create_action(main_window, - u'viewServiceManagerItem', shortcuts=[QtGui.QKeySequence(u'F9')], + u'viewServiceManagerItem', icon=u':/system/system_servicemanager.png', checked=self.serviceManagerDock.isVisible(), + can_shortcuts=True, category=UiStrings().View, triggers=self.toggleServiceManager) self.viewPreviewPanel = create_action(main_window, u'viewPreviewPanel', - shortcuts=[QtGui.QKeySequence(u'F11')], checked=previewVisible, + checked=previewVisible, + can_shortcuts=True, category=UiStrings().View, triggers=self.setPreviewPanelVisibility) self.viewLivePanel = create_action(main_window, u'viewLivePanel', - shortcuts=[QtGui.QKeySequence(u'F12')], checked=liveVisible, + checked=liveVisible, + can_shortcuts=True, category=UiStrings().View, triggers=self.setLivePanelVisibility) self.lockPanel = create_action(main_window, u'lockPanel', - checked=panelLocked, triggers=self.setLockPanel) + checked=panelLocked, + can_shortcuts=True, + category=UiStrings().View, + triggers=self.setLockPanel) action_list.add_category(UiStrings().ViewMode, - CategoryOrder.standardMenu) + CategoryOrder.standard_menu) self.modeDefaultItem = create_action(main_window, u'modeDefaultItem', checked=False, category=UiStrings().ViewMode) self.modeSetupItem = create_action(main_window, u'modeSetupItem', checked=False, category=UiStrings().ViewMode) @@ -245,7 +255,7 @@ class Ui_MainWindow(object): self.modeGroup.addAction(self.modeSetupItem) self.modeGroup.addAction(self.modeLiveItem) self.modeDefaultItem.setChecked(True) - action_list.add_category(UiStrings().Tools, CategoryOrder.standardMenu) + action_list.add_category(UiStrings().Tools, CategoryOrder.standard_menu) self.toolsAddToolItem = create_action(main_window, u'toolsAddToolItem', icon=u':/tools/tools_add.png', category=UiStrings().Tools) @@ -258,11 +268,11 @@ class Ui_MainWindow(object): self.updateThemeImages = create_action(main_window, u'updateThemeImages', category=UiStrings().Tools) action_list.add_category(UiStrings().Settings, - CategoryOrder.standardMenu) + CategoryOrder.standard_menu) self.settingsPluginListItem = create_action(main_window, u'settingsPluginListItem', icon=u':/system/settings_plugin_list.png', - shortcuts=[QtGui.QKeySequence(u'Alt+F7')], + can_shortcuts=True, category=UiStrings().Settings, triggers=self.onPluginItemClicked) # i18n Language Items self.autoLanguageItem = create_action(main_window, u'autoLanguageItem', @@ -282,14 +292,14 @@ class Ui_MainWindow(object): self.formattingTagItem = create_action(main_window, u'displayTagItem', icon=u':/system/tag_editor.png', category=UiStrings().Settings) 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 self.settingsConfigureItem.setMenuRole(QtGui.QAction.PreferencesRole) self.settingsImportItem = create_action(main_window, u'settingsImportItem', category=UiStrings().Settings) self.settingsExportItem = create_action(main_window, u'settingsExportItem', category=UiStrings().Settings) - action_list.add_category(UiStrings().Help, CategoryOrder.standardMenu) + action_list.add_category(UiStrings().Help, CategoryOrder.standard_menu) 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) # Give QT Extra Hint that this is an About Menu Item self.aboutItem.setMenuRole(QtGui.QAction.AboutRole) @@ -298,11 +308,11 @@ class Ui_MainWindow(object): AppLocation.get_directory(AppLocation.AppDir), 'OpenLP.chm') self.offlineHelpItem = create_action(main_window, u'offlineHelpItem', icon=u':/system/system_help_contents.png', - shortcuts=[QtGui.QKeySequence(u'F1')], + can_shortcuts=True, category=UiStrings().Help, triggers=self.onOfflineHelpClicked) self.onlineHelpItem = create_action(main_window, u'onlineHelpItem', icon=u':/system/system_online_help.png', - shortcuts=[QtGui.QKeySequence(u'Alt+F1')], + can_shortcuts=True, category=UiStrings().Help, triggers=self.onOnlineHelpClicked) self.webSiteItem = create_action(main_window, u'webSiteItem', category=UiStrings().Help) add_actions(self.fileImportMenu, (self.settingsImportItem, None, self.importThemeItem, self.importLanguageItem)) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index cfa0d4707..5457056fb 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -153,52 +153,52 @@ class ServiceManagerDialog(object): # Add the bottom toolbar self.order_toolbar = OpenLPToolbar(self) 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', 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.'), - 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', text=translate('OpenLP.ServiceManager', 'Move &up'), icon=u':/services/service_up.png', 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', text=translate('OpenLP.ServiceManager', 'Move &down'), icon=u':/services/service_down.png', 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', 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.'), - 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', - 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, - 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) self.service_manager_list.up = self.order_toolbar.addToolbarAction(u'up', - text=translate('OpenLP.ServiceManager', 'Move up'), tooltip=translate('OpenLP.ServiceManager', - 'Moves the selection up the window.'), visible=False, shortcuts=[QtCore.Qt.Key_Up], + text=translate('OpenLP.ServiceManager', 'Move up'), can_shortcuts=True, + tooltip=translate('OpenLP.ServiceManager', 'Moves the selection up the window.'), visible=False, triggers=self.on_move_selection_up) action_list.add_action(self.service_manager_list.up) 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', 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.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', tooltip=translate('OpenLP.ServiceManager', 'Expand all the service items.'), - shortcuts=[QtCore.Qt.Key_Plus], category=UiStrings().Service, triggers=self.onExpandAll) - self.service_manager_list.collapse = self.order_toolbar.addToolbarAction(u'collapse', + category=UiStrings().Service, triggers=self.onExpandAll) + 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', 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.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', 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) self.layout.addWidget(self.order_toolbar) # Connect up our signals and slots diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 607ae1dd5..82c27ff07 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -44,6 +44,14 @@ from openlp.core.utils.actions import ActionList, CategoryOrder log = logging.getLogger(__name__) +AUDIO_TIME_LABEL_STYLESHEET = u'background-color: palette(background); ' \ + u'border-top-color: palette(shadow); ' \ + u'border-left-color: palette(shadow); ' \ + u'border-bottom-color: palette(light); ' \ + u'border-right-color: palette(light); ' \ + u'border-radius: 3px; border-style: inset; ' \ + u'border-width: 1; font-family: monospace; margin: 2px;' + class DisplayController(QtGui.QWidget): """ @@ -124,7 +132,7 @@ class SlideController(DisplayController): self.keypress_queue = deque() self.keypress_loop = False self.category = UiStrings().LiveToolbar - ActionList.get_instance().add_category(unicode(self.category), CategoryOrder.standardToolbar) + ActionList.get_instance().add_category(unicode(self.category), CategoryOrder.standard_toolbar) else: Registry().register(u'preview_controller', self) self.typeLabel.setText(UiStrings().Preview) @@ -168,13 +176,13 @@ class SlideController(DisplayController): self.previousItem = create_action(self, u'previousItem_' + self.typePrefix, text=translate('OpenLP.SlideController', 'Previous Slide'), icon=u':/slides/slide_previous.png', tooltip=translate('OpenLP.SlideController', 'Move to previous.'), - shortcuts=[QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp], context=QtCore.Qt.WidgetWithChildrenShortcut, + context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category, triggers=self.onSlideSelectedPrevious) self.toolbar.addAction(self.previousItem) self.nextItem = create_action(self, u'nextItem_' + self.typePrefix, text=translate('OpenLP.SlideController', 'Next Slide'), icon=u':/slides/slide_next.png', tooltip=translate('OpenLP.SlideController', 'Move to next.'), - shortcuts=[QtCore.Qt.Key_Down, QtCore.Qt.Key_PageDown], context=QtCore.Qt.WidgetWithChildrenShortcut, + context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category, triggers=self.onSlideSelectedNextAction) self.toolbar.addAction(self.nextItem) self.toolbar.addSeparator() @@ -190,14 +198,14 @@ class SlideController(DisplayController): self.toolbar.addToolbarWidget(self.hideMenu) self.blankScreen = create_action(self, u'blankScreen', text=translate('OpenLP.SlideController', 'Blank Screen'), icon=u':/slides/slide_blank.png', - checked=False, shortcuts=[QtCore.Qt.Key_Period], category=self.category, triggers=self.onBlankDisplay) + checked=False, category=self.category, triggers=self.onBlankDisplay) self.themeScreen = create_action(self, u'themeScreen', text=translate('OpenLP.SlideController', 'Blank to Theme'), icon=u':/slides/slide_theme.png', - checked=False, shortcuts=[QtGui.QKeySequence(u'T')], category=self.category, + checked=False, category=self.category, triggers=self.onThemeDisplay) self.desktopScreen = create_action(self, u'desktopScreen', text=translate('OpenLP.SlideController', 'Show Desktop'), icon=u':/slides/slide_desktop.png', - checked=False, shortcuts=[QtGui.QKeySequence(u'D')], category=self.category, + checked=False, category=self.category, triggers=self.onHideDisplay) self.hideMenu.setDefaultAction(self.blankScreen) self.hideMenu.menu().addAction(self.blankScreen) @@ -225,10 +233,10 @@ class SlideController(DisplayController): self.playSlidesMenu.setMenu(QtGui.QMenu(translate('OpenLP.SlideController', 'Play Slides'), self.toolbar)) self.toolbar.addToolbarWidget(self.playSlidesMenu) self.playSlidesLoop = create_action(self, u'playSlidesLoop', text=UiStrings().PlaySlidesInLoop, - icon=u':/media/media_time.png', checked=False, shortcuts=[], + icon=u':/media/media_time.png', checked=False, category=self.category, triggers=self.onPlaySlidesLoop) self.playSlidesOnce = create_action(self, u'playSlidesOnce', text=UiStrings().PlaySlidesToEnd, - icon=u':/media/media_time.png', checked=False, shortcuts=[], + icon=u':/media/media_time.png', checked=False, category=self.category, triggers=self.onPlaySlidesOnce) if Settings().value(self.parent().advancedSettingsSection + u'/slide limits') == SlideLimits.Wrap: self.playSlidesMenu.setDefaultAction(self.playSlidesLoop) @@ -267,7 +275,7 @@ class SlideController(DisplayController): icon=u':/slides/media_playback_pause.png', text=translate('OpenLP.SlideController', 'Pause Audio'), tooltip=translate('OpenLP.SlideController', 'Pause audio.'), checked=False, visible=False, category=self.category, context=QtCore.Qt.WindowShortcut, - shortcuts=[], triggers=self.onAudioPauseClicked) + triggers=self.onAudioPauseClicked) self.audioMenu = QtGui.QMenu(translate('OpenLP.SlideController', 'Background Audio'), self.toolbar) self.audioPauseItem.setMenu(self.audioMenu) self.audioPauseItem.setParent(self.toolbar) @@ -276,20 +284,12 @@ class SlideController(DisplayController): self.nextTrackItem = create_action(self, u'nextTrackItem', text=UiStrings().NextTrack, icon=u':/slides/media_playback_next.png', tooltip=translate('OpenLP.SlideController', 'Go to next audio track.'), - category=self.category, shortcuts=[], triggers=self.onNextTrackClicked) + category=self.category, triggers=self.onNextTrackClicked) self.audioMenu.addAction(self.nextTrackItem) self.trackMenu = self.audioMenu.addMenu(translate('OpenLP.SlideController', 'Tracks')) self.audioTimeLabel = QtGui.QLabel(u' 00:00 ', self.toolbar) self.audioTimeLabel.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignHCenter) - self.audioTimeLabel.setStyleSheet( - u'background-color: palette(background); ' - u'border-top-color: palette(shadow); ' - u'border-left-color: palette(shadow); ' - u'border-bottom-color: palette(light); ' - u'border-right-color: palette(light); ' - u'border-radius: 3px; border-style: inset; ' - u'border-width: 1; font-family: monospace; margin: 2px;' - ) + self.audioTimeLabel.setStyleSheet(AUDIO_TIME_LABEL_STYLESHEET) self.audioTimeLabel.setObjectName(u'audioTimeLabel') self.toolbar.addToolbarWidget(self.audioTimeLabel) self.toolbar.setWidgetVisible(self.audioList, False) @@ -334,28 +334,22 @@ class SlideController(DisplayController): self.shortcutTimer = QtCore.QTimer() self.shortcutTimer.setObjectName(u'shortcutTimer') self.shortcutTimer.setSingleShot(True) - shortcuts = [{u'key': u'V', u'configurable': True, - u'text': translate('OpenLP.SlideController', 'Go to "Verse"')}, - {u'key': u'C', u'configurable': True, - u'text': translate('OpenLP.SlideController', 'Go to "Chorus"')}, - {u'key': u'B', u'configurable': True, - u'text': translate('OpenLP.SlideController', 'Go to "Bridge"')}, + shortcuts = [ + {u'key': u'V', u'configurable': True, u'text': translate('OpenLP.SlideController', 'Go to "Verse"')}, + {u'key': u'C', u'configurable': True, u'text': translate('OpenLP.SlideController', 'Go to "Chorus"')}, + {u'key': u'B', u'configurable': True, u'text': translate('OpenLP.SlideController', 'Go to "Bridge"')}, {u'key': u'P', u'configurable': True, - u'text': translate('OpenLP.SlideController', - 'Go to "Pre-Chorus"')}, - {u'key': u'I', u'configurable': True, - u'text': translate('OpenLP.SlideController', 'Go to "Intro"')}, - {u'key': u'E', u'configurable': True, - u'text': translate('OpenLP.SlideController', 'Go to "Ending"')}, - {u'key': u'O', u'configurable': True, - u'text': translate('OpenLP.SlideController', 'Go to "Other"')}] - shortcuts += [{u'key': unicode(number)} for number in range(10)] + u'text': translate('OpenLP.SlideController', 'Go to "Pre-Chorus"')}, + {u'key': u'I', u'configurable': True, u'text': translate('OpenLP.SlideController', 'Go to "Intro"')}, + {u'key': u'E', u'configurable': True, u'text': translate('OpenLP.SlideController', 'Go to "Ending"')}, + {u'key': u'O', u'configurable': True, u'text': translate('OpenLP.SlideController', 'Go to "Other"')} + ] + shortcuts.extend([{u'key': unicode(number)} for number in range(10)]) self.previewListWidget.addActions([create_action(self, u'shortcutAction_%s' % s[u'key'], text=s.get(u'text'), - shortcuts=[QtGui.QKeySequence(s[u'key'])], context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category if s.get(u'configurable') else None, - triggers=self._slideShortcutActivated) for s in shortcuts]) + triggers=self._slideShortcutActivated, can_shortcuts=True) for s in shortcuts]) QtCore.QObject.connect( self.shortcutTimer, QtCore.SIGNAL(u'timeout()'), self._slideShortcutActivated) @@ -461,15 +455,15 @@ class SlideController(DisplayController): """ self.previousService = create_action(parent, u'previousService', text=translate('OpenLP.SlideController', 'Previous Service'), - shortcuts=[QtCore.Qt.Key_Left], context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category, + context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category, triggers=self.servicePrevious) self.nextService = create_action(parent, 'nextService', text=translate('OpenLP.SlideController', 'Next Service'), - shortcuts=[QtCore.Qt.Key_Right], context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category, + context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category, triggers=self.serviceNext) self.escapeItem = create_action(parent, 'escapeItem', text=translate('OpenLP.SlideController', 'Escape Item'), - shortcuts=[QtCore.Qt.Key_Escape], context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category, + context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category, triggers=self.liveEscape) def liveEscape(self): diff --git a/openlp/core/utils/actions.py b/openlp/core/utils/actions.py index c7b2bae49..dbf42dc84 100644 --- a/openlp/core/utils/actions.py +++ b/openlp/core/utils/actions.py @@ -37,8 +37,8 @@ from openlp.core.lib import Settings class ActionCategory(object): """ - The :class:`~openlp.core.utils.ActionCategory` class encapsulates a - category for the :class:`~openlp.core.utils.CategoryList` class. + The :class:`~openlp.core.utils.ActionCategory` class encapsulates a category for the + :class:`~openlp.core.utils.CategoryList` class. """ def __init__(self, name, weight=0): """ @@ -51,8 +51,7 @@ class ActionCategory(object): class CategoryActionList(object): """ - The :class:`~openlp.core.utils.CategoryActionList` class provides a sorted - list of actions within a category. + The :class:`~openlp.core.utils.CategoryActionList` class provides a sorted list of actions within a category. """ def __init__(self): """ @@ -142,9 +141,9 @@ class CategoryActionList(object): class CategoryList(object): """ - The :class:`~openlp.core.utils.CategoryList` class encapsulates a category - list for the :class:`~openlp.core.utils.ActionList` class and provides an - iterator interface for walking through the list of actions in this category. + The :class:`~openlp.core.utils.CategoryList` class encapsulates a category list for the + :class:`~openlp.core.utils.ActionList` class and provides an iterator interface for walking through the list of + actions in this category. """ def __init__(self): @@ -244,10 +243,9 @@ class CategoryList(object): class ActionList(object): """ - The :class:`~openlp.core.utils.ActionList` class contains a list of menu - actions and categories associated with those actions. Each category also - has a weight by which it is sorted when iterating through the list of - actions or categories. + The :class:`~openlp.core.utils.ActionList` class contains a list of menu actions and categories associated with + those actions. Each category also has a weight by which it is sorted when iterating through the list of actions or + categories. """ instance = None shortcut_map = {} @@ -271,48 +269,44 @@ class ActionList(object): """ Add an action to the list of actions. + **Note**: The action's objectName must be set when you want to add it! + ``action`` - The action to add (QAction). **Note**, the action must not have an - empty ``objectName``. + The action to add (QAction). **Note**, the action must not have an empty ``objectName``. ``category`` - The category this action belongs to. The category has to be a python - string. . **Note**, if the category is ``None``, the category and - its actions are being hidden in the shortcut dialog. However, if - they are added, it is possible to avoid assigning shortcuts twice, - which is important. + The category this action belongs to. The category has to be a python string. . **Note**, if the category + is ``None``, the category and its actions are being hidden in the shortcut dialog. However, if they are + added, it is possible to avoid assigning shortcuts twice, which is important. ``weight`` - The weight specifies how important a category is. However, this only - has an impact on the order the categories are displayed. + The weight specifies how important a category is. However, this only has an impact on the order the + categories are displayed. """ if category not in self.categories: 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: self.categories[category].actions.append(action) else: self.categories[category].actions.add(action, weight) # Load the shortcut from the config. - settings = Settings() - settings.beginGroup(u'shortcuts') shortcuts = settings.value(action.objectName()) settings.endGroup() if not shortcuts: action.setShortcuts([]) return - # We have to do this to ensure that the loaded shortcut list e. g. - # STRG+O (German) is converted to CTRL+O, which is only done when we - # convert the strings in this way (QKeySequence -> QString -> unicode). - shortcuts = map(QtGui.QKeySequence, shortcuts) - shortcuts = map(unicode, map(QtGui.QKeySequence.toString, shortcuts)) - # Check the alternate shortcut first, to avoid problems when the - # alternate shortcut becomes the primary shortcut after removing the - # (initial) primary shortcut due to conflicts. + # We have to do this to ensure that the loaded shortcut list e. g. STRG+O (German) is converted to CTRL+O, + # which is only done when we convert the strings in this way (QKeySequencet -> uncode). + shortcuts = map(QtGui.QKeySequence.toString, map(QtGui.QKeySequence, shortcuts)) + # Check the alternate shortcut first, to avoid problems when the alternate shortcut becomes the primary shortcut + # after removing the (initial) primary shortcut due to conflicts. if len(shortcuts) == 2: existing_actions = ActionList.shortcut_map.get(shortcuts[1], []) - # Check for conflicts with other actions considering the shortcut - # context. + # Check for conflicts with other actions considering the shortcut context. if self._is_shortcut_available(existing_actions, action): actions = ActionList.shortcut_map.get(shortcuts[1], []) actions.append(action) @@ -321,28 +315,24 @@ class ActionList(object): shortcuts.remove(shortcuts[1]) # Check the primary shortcut. existing_actions = ActionList.shortcut_map.get(shortcuts[0], []) - # Check for conflicts with other actions considering the shortcut - # context. + # Check for conflicts with other actions considering the shortcut context. if self._is_shortcut_available(existing_actions, action): actions = ActionList.shortcut_map.get(shortcuts[0], []) actions.append(action) ActionList.shortcut_map[shortcuts[0]] = actions else: shortcuts.remove(shortcuts[0]) - action.setShortcuts( - [QtGui.QKeySequence(shortcut) for shortcut in shortcuts]) + action.setShortcuts([QtGui.QKeySequence(shortcut) for shortcut in shortcuts]) def remove_action(self, action, category=None): """ - This removes an action from its category. Empty categories are - automatically removed. + This removes an action from its category. Empty categories are automatically removed. ``action`` The ``QAction`` object to be removed. ``category`` - The name (unicode string) of the category, which contains the - action. Defaults to None. + The name (unicode string) of the category, which contains the action. Defaults to None. """ if category not in self.categories: return @@ -350,10 +340,9 @@ class ActionList(object): # Remove empty categories. if not self.categories[category].actions: self.categories.remove(category) - shortcuts = map(unicode, map(QtGui.QKeySequence.toString, action.shortcuts())) + shortcuts = map(QtGui.QKeySequence.toString, action.shortcuts()) for shortcut in shortcuts: - # Remove action from the list of actions which are using this - # shortcut. + # Remove action from the list of actions which are using this shortcut. ActionList.shortcut_map[shortcut].remove(action) # Remove empty entries. if not ActionList.shortcut_map[shortcut]: @@ -361,8 +350,7 @@ class ActionList(object): def add_category(self, name, weight): """ - Add an empty category to the list of categories. This is ony convenient - for categories with a given weight. + Add an empty category to the list of categories. This is ony convenient for categories with a given weight. ``name`` The category's name. @@ -381,27 +369,24 @@ class ActionList(object): def update_shortcut_map(self, action, old_shortcuts): """ - Remove the action for the given ``old_shortcuts`` from the - ``shortcut_map`` to ensure its up-to-dateness. + Remove the action for the given ``old_shortcuts`` from the ``shortcut_map`` to ensure its up-to-dateness. - **Note**: The new action's shortcuts **must** be assigned to the given - ``action`` **before** calling this method. + **Note**: The new action's shortcuts **must** be assigned to the given ``action`` **before** calling this + method. ``action`` - The action whose shortcuts are supposed to be updated in the - ``shortcut_map``. + The action whose shortcuts are supposed to be updated in the ``shortcut_map``. ``old_shortcuts`` A list of unicode keysequences. """ for old_shortcut in old_shortcuts: - # Remove action from the list of actions which are using this - # shortcut. + # Remove action from the list of actions which are using this shortcut. ActionList.shortcut_map[old_shortcut].remove(action) # Remove empty entries. if not ActionList.shortcut_map[old_shortcut]: del ActionList.shortcut_map[old_shortcut] - new_shortcuts = map(unicode, map(QtGui.QKeySequence.toString, action.shortcuts())) + new_shortcuts = map(QtGui.QKeySequence.toString, action.shortcuts()) # Add the new shortcuts to the map. for new_shortcut in new_shortcuts: existing_actions = ActionList.shortcut_map.get(new_shortcut, []) @@ -410,8 +395,7 @@ class ActionList(object): def _is_shortcut_available(self, existing_actions, action): """ - Checks if the given ``action`` may use its assigned shortcut(s) or not. - Returns ``True`` or ``False. + Checks if the given ``action`` may use its assigned shortcut(s) or not. Returns ``True`` or ``False. ``existing_actions`` A list of actions which already use a particular shortcut. @@ -420,8 +404,10 @@ class ActionList(object): The action which wants to use a particular shortcut. """ local = action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut] - affected_actions = filter(lambda a: isinstance(a, QtGui.QAction), - self.getAllChildObjects(action.parent())) if local else [] + affected_actions = [] + if local: + affected_actions = filter( + lambda a: isinstance(a, QtGui.QAction), self.get_all_child_objects(action.parent())) for existing_action in existing_actions: if action is existing_action: continue @@ -429,18 +415,17 @@ class ActionList(object): return False if existing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]: return False - elif action in self.getAllChildObjects(existing_action.parent()): + elif action in self.get_all_child_objects(existing_action.parent()): return False return True - def getAllChildObjects(self, qobject): + def get_all_child_objects(self, qobject): """ - Goes recursively through the children of ``qobject`` and returns a list - of all child objects. + Goes recursively through the children of ``qobject`` and returns a list of all child objects. """ - children = [child for child in qobject.children()] - for child in qobject.children(): - children.append(self.getAllChildObjects(child)) + children = qobject.children() + # Append the children's children. + children.extend(map(self.get_all_child_objects, children)) return children @@ -448,5 +433,5 @@ class CategoryOrder(object): """ An enumeration class for category weights. """ - standardMenu = -20 - standardToolbar = -10 + standard_menu = -20 + standard_toolbar = -10 diff --git a/openlp/plugins/alerts/alertsplugin.py b/openlp/plugins/alerts/alertsplugin.py index de2c92f7e..fa7d2e848 100644 --- a/openlp/plugins/alerts/alertsplugin.py +++ b/openlp/plugins/alerts/alertsplugin.py @@ -150,7 +150,7 @@ class AlertsPlugin(Plugin): self.toolsAlertItem = create_action(tools_menu, u'toolsAlertItem', text=translate('AlertsPlugin', '&Alert'), icon=u':/plugins/plugin_alerts.png', statustip=translate('AlertsPlugin', 'Show an alert message.'), - visible=False, shortcuts=[u'F7'], triggers=self.onAlertsTrigger) + visible=False, triggers=self.onAlertsTrigger) self.main_window.toolsMenu.addAction(self.toolsAlertItem) def initialise(self): diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index 0ab73aa46..7d70728f8 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -32,7 +32,7 @@ import os from PyQt4 import QtCore, QtGui -from openlp.core.lib import MediaManagerItem, ItemCapabilities, Receiver, SettingsManager, ServiceItemContext, \ +from openlp.core.lib import MediaManagerItem, ItemCapabilities, Receiver, ServiceItemContext, \ Settings, UiStrings, build_icon, check_item_selected, check_directory_exists, create_thumb, translate, \ validate_thumb from openlp.core.lib.ui import critical_error_message_box @@ -107,7 +107,7 @@ class ImageMediaItem(MediaManagerItem): delete_file(os.path.join(self.servicePath, text.text())) self.listView.takeItem(row) 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.application.set_normal_cursor() self.listView.blockSignals(False) diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py index 3b3611f0e..cde949365 100644 --- a/openlp/plugins/songusage/songusageplugin.py +++ b/openlp/plugins/songusage/songusageplugin.py @@ -100,7 +100,7 @@ class SongUsagePlugin(Plugin): self.songUsageStatus = create_action(tools_menu, u'songUsageStatus', text=translate('SongUsagePlugin', 'Toggle Tracking'), statustip=translate('SongUsagePlugin', 'Toggle the tracking of song usage.'), checked=False, - shortcuts=[QtCore.Qt.Key_F4], triggers=self.toggleSongUsageState) + triggers=self.toggleSongUsageState) # Add Menus together self.toolsMenu.addAction(self.songUsageMenu.menuAction()) self.songUsageMenu.addAction(self.songUsageStatus) From 38c2c2db5efff7a88915657d8f5ef5a58c2ff2b3 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 19 Feb 2013 10:33:07 +0100 Subject: [PATCH 21/48] make diff more readable --- openlp/core/lib/mediamanageritem.py | 12 ++++----- openlp/core/lib/ui.py | 24 +++++++++--------- openlp/core/ui/mainwindow.py | 21 ++++++---------- openlp/core/ui/slidecontroller.py | 27 +++++++++++---------- openlp/plugins/alerts/alertsplugin.py | 2 +- openlp/plugins/songusage/songusageplugin.py | 2 +- 6 files changed, 40 insertions(+), 48 deletions(-) diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index ef9136672..ba272bf69 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -221,6 +221,7 @@ class MediaManagerItem(QtGui.QWidget): self.pageLayout.addWidget(self.listView) # define and add the context menu self.listView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) + # FIXME: Look for better objectNames. if self.hasEditIcon: create_widget_action(self.listView, text=self.plugin.getString(StringContent.Edit)[u'title'], @@ -231,22 +232,21 @@ class MediaManagerItem(QtGui.QWidget): create_widget_action(self.listView, u'%s%s' % (self.plugin.name, StringContent.Delete), text=self.plugin.getString(StringContent.Delete)[u'title'], icon=u':/general/general_delete.png', - can_shortcuts=True, - triggers=self.onDeleteClick) + can_shortcuts=True, triggers=self.onDeleteClick) create_widget_action(self.listView, separator=True) - create_widget_action(self.listView, + create_widget_action(self.listView, u'%s%s' % (self.plugin.name, StringContent.Preview), text=self.plugin.getString(StringContent.Preview)[u'title'], icon=u':/general/general_preview.png', can_shortcuts=True, triggers=self.onPreviewClick) - create_widget_action(self.listView, + create_widget_action(self.listView, u'%s%s' % (self.plugin.name, StringContent.Live), text=self.plugin.getString(StringContent.Live)[u'title'], icon=u':/general/general_live.png', can_shortcuts=True, triggers=self.onLiveClick) - create_widget_action(self.listView, - text=self.plugin.getString(StringContent.Service)[u'title'], + create_widget_action(self.listView, u'%s%s' % (self.plugin.name, StringContent.Service), can_shortcuts=True, + text=self.plugin.getString(StringContent.Service)[u'title'], icon=u':/general/general_add.png', triggers=self.onAddClick) if self.addToServiceItem: diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index 4b22ae337..82127db6d 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -235,11 +235,6 @@ def create_action(parent, name, **kwargs): Either a QIcon, a resource string, or a file location string for the action icon. - ``can_shortcuts`` - Boolean stating if this action has shortcuts or if it can have shortcuts. If ``True`` the action is added to - shortcut dialog. **Note**: Never set the shortcuts yourselt; use the :class:`~openlp.core.lib.Settings` class - to define the action's shortcuts. - ``tooltip`` A string for the action tool tip. @@ -261,6 +256,11 @@ def create_action(parent, name, **kwargs): ``data`` The action's data. + ``can_shortcuts`` + Boolean stating if this action has shortcuts or if it can have shortcuts. If ``True`` the action is added to + shortcut dialog. **Note**: Never set the shortcuts yourselt; use the :class:`~openlp.core.lib.Settings` class + to define the action's shortcuts. + ``context`` A context for the shortcut execution. @@ -291,20 +291,18 @@ def create_action(parent, name, **kwargs): action.setSeparator(True) if u'data' in kwargs: action.setData(kwargs.pop(u'data')) - if u'context' in kwargs: - action.setShortcutContext(kwargs.pop(u'context')) - if kwargs.get(u'triggers'): - QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'), kwargs.pop(u'triggers')) if kwargs.pop(u'can_shortcuts', False): if not action.objectName(): raise Exception("objectName not set") action_list = ActionList.get_instance() action_list.add_action(action, kwargs.pop(u'category', None)) - else: - pass - #print u'else', action.objectName() + if u'context' in kwargs: + action.setShortcutContext(kwargs.pop(u'context')) + if kwargs.get(u'triggers'): + QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered(bool)'), kwargs.pop(u'triggers')) for key in kwargs.keys(): - if key not in [u'text', u'icon', u'tooltip', u'statustip', u'checked', 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) return action diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 3bddf5496..9a95d75f2 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -195,15 +195,13 @@ class Ui_MainWindow(object): category=UiStrings().File, triggers=self.serviceManagerContents.save_file_as) self.printServiceOrderItem = create_action(main_window, - u'printServiceItem', - can_shortcuts=True, + u'printServiceItem', can_shortcuts=True, category=UiStrings().File, triggers=self.serviceManagerContents.print_service_order) self.fileExitItem = create_action(main_window, u'fileExitItem', icon=u':/system/system_exit.png', 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 self.fileExitItem.setMenuRole(QtGui.QAction.QuitRole) action_list.add_category(UiStrings().Import, CategoryOrder.standard_menu) @@ -220,28 +218,23 @@ class Ui_MainWindow(object): can_shortcuts=True, category=UiStrings().View, triggers=self.toggleMediaManager) self.viewThemeManagerItem = create_action(main_window, - u'viewThemeManagerItem', + u'viewThemeManagerItem', can_shortcuts=True, icon=u':/system/system_thememanager.png', checked=self.themeManagerDock.isVisible(), - can_shortcuts=True, category=UiStrings().View, triggers=self.toggleThemeManager) self.viewServiceManagerItem = create_action(main_window, - u'viewServiceManagerItem', + u'viewServiceManagerItem', can_shortcuts=True, icon=u':/system/system_servicemanager.png', checked=self.serviceManagerDock.isVisible(), - can_shortcuts=True, category=UiStrings().View, triggers=self.toggleServiceManager) self.viewPreviewPanel = create_action(main_window, u'viewPreviewPanel', - checked=previewVisible, - can_shortcuts=True, + can_shortcuts=True, checked=previewVisible, category=UiStrings().View, triggers=self.setPreviewPanelVisibility) self.viewLivePanel = create_action(main_window, u'viewLivePanel', - checked=liveVisible, - can_shortcuts=True, + can_shortcuts=True, checked=liveVisible, category=UiStrings().View, triggers=self.setLivePanelVisibility) self.lockPanel = create_action(main_window, u'lockPanel', - checked=panelLocked, - can_shortcuts=True, + can_shortcuts=True, checked=panelLocked, category=UiStrings().View, triggers=self.setLockPanel) action_list.add_category(UiStrings().ViewMode, diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 7d301cdd9..68e770382 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -176,13 +176,13 @@ class SlideController(DisplayController): self.previousItem = create_action(self, u'previousItem_' + self.typePrefix, text=translate('OpenLP.SlideController', 'Previous Slide'), icon=u':/slides/slide_previous.png', tooltip=translate('OpenLP.SlideController', 'Move to previous.'), - context=QtCore.Qt.WidgetWithChildrenShortcut, + can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category, triggers=self.on_slide_selected_previous) self.toolbar.addAction(self.previousItem) self.nextItem = create_action(self, u'nextItem_' + self.typePrefix, text=translate('OpenLP.SlideController', 'Next Slide'), icon=u':/slides/slide_next.png', tooltip=translate('OpenLP.SlideController', 'Move to next.'), - context=QtCore.Qt.WidgetWithChildrenShortcut, + can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category, triggers=self.on_slide_selected_next_action) self.toolbar.addAction(self.nextItem) self.toolbar.addSeparator() @@ -198,14 +198,14 @@ class SlideController(DisplayController): self.toolbar.addToolbarWidget(self.hideMenu) self.blankScreen = create_action(self, u'blankScreen', text=translate('OpenLP.SlideController', 'Blank Screen'), icon=u':/slides/slide_blank.png', - checked=False, category=self.category, triggers=self.onBlankDisplay) + checked=False, can_shortcuts=True, category=self.category, triggers=self.onBlankDisplay) self.themeScreen = create_action(self, u'themeScreen', text=translate('OpenLP.SlideController', 'Blank to Theme'), icon=u':/slides/slide_theme.png', - checked=False, category=self.category, + checked=False, can_shortcuts=True, category=self.category, triggers=self.onThemeDisplay) self.desktopScreen = create_action(self, u'desktopScreen', text=translate('OpenLP.SlideController', 'Show Desktop'), icon=u':/slides/slide_desktop.png', - checked=False, category=self.category, + checked=False, can_shortcuts=True, category=self.category, triggers=self.onHideDisplay) self.hideMenu.setDefaultAction(self.blankScreen) self.hideMenu.menu().addAction(self.blankScreen) @@ -233,10 +233,10 @@ class SlideController(DisplayController): self.playSlidesMenu.setMenu(QtGui.QMenu(translate('OpenLP.SlideController', 'Play Slides'), self.toolbar)) self.toolbar.addToolbarWidget(self.playSlidesMenu) self.playSlidesLoop = create_action(self, u'playSlidesLoop', text=UiStrings().PlaySlidesInLoop, - icon=u':/media/media_time.png', checked=False, + icon=u':/media/media_time.png', checked=False, can_shortcuts=True, category=self.category, triggers=self.onPlaySlidesLoop) self.playSlidesOnce = create_action(self, u'playSlidesOnce', text=UiStrings().PlaySlidesToEnd, - icon=u':/media/media_time.png', checked=False, + icon=u':/media/media_time.png', checked=False, can_shortcuts=True, category=self.category, triggers=self.onPlaySlidesOnce) if Settings().value(self.parent().advancedSettingsSection + u'/slide limits') == SlideLimits.Wrap: self.playSlidesMenu.setDefaultAction(self.playSlidesLoop) @@ -275,7 +275,7 @@ class SlideController(DisplayController): icon=u':/slides/media_playback_pause.png', text=translate('OpenLP.SlideController', 'Pause Audio'), tooltip=translate('OpenLP.SlideController', 'Pause audio.'), checked=False, visible=False, category=self.category, context=QtCore.Qt.WindowShortcut, - triggers=self.onAudioPauseClicked) + can_shortcuts=True, triggers=self.onAudioPauseClicked) self.audioMenu = QtGui.QMenu(translate('OpenLP.SlideController', 'Background Audio'), self.toolbar) self.audioPauseItem.setMenu(self.audioMenu) self.audioPauseItem.setParent(self.toolbar) @@ -284,7 +284,7 @@ class SlideController(DisplayController): self.nextTrackItem = create_action(self, u'nextTrackItem', text=UiStrings().NextTrack, icon=u':/slides/media_playback_next.png', tooltip=translate('OpenLP.SlideController', 'Go to next audio track.'), - category=self.category, triggers=self.onNextTrackClicked) + category=self.category, can_shortcuts=True, triggers=self.onNextTrackClicked) self.audioMenu.addAction(self.nextTrackItem) self.trackMenu = self.audioMenu.addMenu(translate('OpenLP.SlideController', 'Tracks')) self.audioTimeLabel = QtGui.QLabel(u' 00:00 ', self.toolbar) @@ -347,9 +347,10 @@ class SlideController(DisplayController): shortcuts.extend([{u'key': unicode(number)} for number in range(10)]) self.previewListWidget.addActions([create_action(self, u'shortcutAction_%s' % s[u'key'], text=s.get(u'text'), + can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category if s.get(u'configurable') else None, - triggers=self._slideShortcutActivated, can_shortcuts=True) for s in shortcuts]) + triggers=self._slideShortcutActivated) for s in shortcuts]) QtCore.QObject.connect( self.shortcutTimer, QtCore.SIGNAL(u'timeout()'), self._slideShortcutActivated) @@ -445,15 +446,15 @@ class SlideController(DisplayController): """ self.previousService = create_action(parent, u'previousService', text=translate('OpenLP.SlideController', 'Previous Service'), - context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category, + can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category, triggers=self.servicePrevious) self.nextService = create_action(parent, 'nextService', text=translate('OpenLP.SlideController', 'Next Service'), - context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category, + can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category, triggers=self.serviceNext) self.escapeItem = create_action(parent, 'escapeItem', text=translate('OpenLP.SlideController', 'Escape Item'), - context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category, + can_shortcuts=True, context=QtCore.Qt.WidgetWithChildrenShortcut, category=self.category, triggers=self.liveEscape) def liveEscape(self): diff --git a/openlp/plugins/alerts/alertsplugin.py b/openlp/plugins/alerts/alertsplugin.py index fa7d2e848..c752dbbc9 100644 --- a/openlp/plugins/alerts/alertsplugin.py +++ b/openlp/plugins/alerts/alertsplugin.py @@ -150,7 +150,7 @@ class AlertsPlugin(Plugin): self.toolsAlertItem = create_action(tools_menu, u'toolsAlertItem', text=translate('AlertsPlugin', '&Alert'), icon=u':/plugins/plugin_alerts.png', statustip=translate('AlertsPlugin', 'Show an alert message.'), - visible=False, triggers=self.onAlertsTrigger) + visible=False, can_shortcuts=True, triggers=self.onAlertsTrigger) self.main_window.toolsMenu.addAction(self.toolsAlertItem) def initialise(self): diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py index 29abecf2b..28a1a102e 100644 --- a/openlp/plugins/songusage/songusageplugin.py +++ b/openlp/plugins/songusage/songusageplugin.py @@ -100,7 +100,7 @@ class SongUsagePlugin(Plugin): self.songUsageStatus = create_action(tools_menu, u'songUsageStatus', text=translate('SongUsagePlugin', 'Toggle Tracking'), statustip=translate('SongUsagePlugin', 'Toggle the tracking of song usage.'), checked=False, - triggers=self.toggleSongUsageState) + can_shortcuts=True, triggers=self.toggleSongUsageState) # Add Menus together self.toolsMenu.addAction(self.songUsageMenu.menuAction()) self.songUsageMenu.addAction(self.songUsageStatus) From b6f6cc916ef266fb95f59515125ee8da1a50b3df Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 19 Feb 2013 10:56:36 +0100 Subject: [PATCH 22/48] added listView shortkeys --- openlp/core/lib/mediamanageritem.py | 13 +++++++----- openlp/core/lib/settings.py | 33 +++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index ba272bf69..2218bc1ae 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -221,7 +221,6 @@ class MediaManagerItem(QtGui.QWidget): self.pageLayout.addWidget(self.listView) # define and add the context menu self.listView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) - # FIXME: Look for better objectNames. if self.hasEditIcon: create_widget_action(self.listView, text=self.plugin.getString(StringContent.Edit)[u'title'], @@ -229,22 +228,26 @@ class MediaManagerItem(QtGui.QWidget): triggers=self.onEditClick) create_widget_action(self.listView, separator=True) if self.hasDeleteIcon: - create_widget_action(self.listView, u'%s%s' % (self.plugin.name, StringContent.Delete), + create_widget_action(self.listView, + u'listView%s%sItem' % (self.plugin.name.title(), StringContent.Delete.title()), text=self.plugin.getString(StringContent.Delete)[u'title'], icon=u':/general/general_delete.png', can_shortcuts=True, triggers=self.onDeleteClick) create_widget_action(self.listView, separator=True) - create_widget_action(self.listView, u'%s%s' % (self.plugin.name, StringContent.Preview), + create_widget_action(self.listView, + u'listView%s%sItem' % (self.plugin.name.title(), StringContent.Preview.title()), text=self.plugin.getString(StringContent.Preview)[u'title'], icon=u':/general/general_preview.png', can_shortcuts=True, triggers=self.onPreviewClick) - create_widget_action(self.listView, u'%s%s' % (self.plugin.name, StringContent.Live), + create_widget_action(self.listView, + u'listView%s%sItem' % (self.plugin.name.title(), StringContent.Live.title()), text=self.plugin.getString(StringContent.Live)[u'title'], icon=u':/general/general_live.png', can_shortcuts=True, triggers=self.onLiveClick) - create_widget_action(self.listView, u'%s%s' % (self.plugin.name, StringContent.Service), + 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'], icon=u':/general/general_add.png', diff --git a/openlp/core/lib/settings.py b/openlp/core/lib/settings.py index ff0a6fbb1..c2abbe443 100644 --- a/openlp/core/lib/settings.py +++ b/openlp/core/lib/settings.py @@ -240,6 +240,39 @@ class Settings(QtCore.QSettings): u'shortcuts/viewLivePanel': [QtGui.QKeySequence(u'F12')], u'shortcuts/viewServiceManagerItem': [QtGui.QKeySequence(u'F9')], u'shortcuts/webSiteItem': [], + + # FIXME: To be sorted. + u'shortcuts/listViewSongsDeleteItem': [QtCore.Qt.Key_Delete], + u'shortcuts/listViewSongsPreviewItem': [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], + u'shortcuts/listViewSongsLiveItem': [QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter, + QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return], + u'shortcuts/listViewSongsServiceItem': [QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal], + u'shortcuts/listViewBiblesDeleteItem': [QtCore.Qt.Key_Delete], + u'shortcuts/listViewBiblesPreviewItem': [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], + u'shortcuts/listViewBiblesLiveItem': [QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter, + QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return], + u'shortcuts/listViewBiblesServiceItem': [QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal], + u'shortcuts/listViewPresentationsDeleteItem': [QtCore.Qt.Key_Delete], + u'shortcuts/listViewPresentationsPreviewItem': [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], + u'shortcuts/listViewPresentationsLiveItem': [QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter, + QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return], + u'shortcuts/listViewPresentationsServiceItem': [QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal], + u'shortcuts/listViewImagesDeleteItem': [QtCore.Qt.Key_Delete], + u'shortcuts/listViewImagesPreviewItem': [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], + u'shortcuts/listViewImagesLiveItem': [QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter, + QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return], + u'shortcuts/listViewImagesServiceItem': [QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal], + u'shortcuts/listViewMediaDeleteItem': [QtCore.Qt.Key_Delete], + u'shortcuts/listViewMediaPreviewItem': [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], + u'shortcuts/listViewMediaLiveItem': [QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter, + QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return], + u'shortcuts/listViewMediaServiceItem': [QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal], + u'shortcuts/listViewCustomDeleteItem': [QtCore.Qt.Key_Delete], + u'shortcuts/listViewCustomPreviewItem': [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], + u'shortcuts/listViewCustomLiveItem': [QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter, + QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return], + u'shortcuts/listViewCustomServiceItem': [QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal], + u'themes/global theme': u'', u'themes/last directory': u'', u'themes/last directory export': u'', From ca23aedb5d6dea5816eddab65588a3c317598309 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 19 Feb 2013 11:50:36 +0100 Subject: [PATCH 23/48] fixed shortcut dialog --- openlp/core/lib/settings.py | 108 ++++++++++++++++------------- openlp/core/ui/shortcutlistform.py | 79 +++++++++------------ 2 files changed, 94 insertions(+), 93 deletions(-) diff --git a/openlp/core/lib/settings.py b/openlp/core/lib/settings.py index c2abbe443..e8d0c53c3 100644 --- a/openlp/core/lib/settings.py +++ b/openlp/core/lib/settings.py @@ -155,14 +155,14 @@ class Settings(QtCore.QSettings): u'shortcuts/addToService': [], u'shortcuts/audioPauseItem': [], u'shortcuts/displayTagItem': [], - u'shortcuts/blankScreen': [QtCore.Qt.Key_Period], - u'shortcuts/collapse': [QtCore.Qt.Key_Minus], + u'shortcuts/blankScreen': [QtGui.QKeySequence(QtCore.Qt.Key_Period)], + u'shortcuts/collapse': [QtGui.QKeySequence(QtCore.Qt.Key_Minus)], u'shortcuts/desktopScreen': [QtGui.QKeySequence(u'D')], u'shortcuts/delete': [], - u'shortcuts/down': [QtCore.Qt.Key_Down], + u'shortcuts/down': [QtGui.QKeySequence(QtCore.Qt.Key_Down)], u'shortcuts/editSong': [], - u'shortcuts/escapeItem': [QtCore.Qt.Key_Escape], - u'shortcuts/expand': [QtCore.Qt.Key_Plus], + u'shortcuts/escapeItem': [QtGui.QKeySequence(QtCore.Qt.Key_Escape)], + u'shortcuts/expand': [QtGui.QKeySequence(QtCore.Qt.Key_Plus)], u'shortcuts/exportThemeItem': [], u'shortcuts/fileNewItem': [QtGui.QKeySequence(u'Ctrl+N')], u'shortcuts/fileSaveAsItem': [QtGui.QKeySequence(u'Ctrl+Shift+S')], @@ -175,32 +175,34 @@ class Settings(QtCore.QSettings): u'shortcuts/lockPanel': [], u'shortcuts/modeDefaultItem': [], u'shortcuts/modeLiveItem': [], - u'shortcuts/make_live': [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], - u'shortcuts/moveUp': [QtCore.Qt.Key_PageUp], - u'shortcuts/moveTop': [QtCore.Qt.Key_Home], + u'shortcuts/make_live': [QtGui.QKeySequence(QtCore.Qt.Key_Enter), QtGui.QKeySequence(QtCore.Qt.Key_Return)], + u'shortcuts/moveUp': [QtGui.QKeySequence(QtCore.Qt.Key_PageUp)], + u'shortcuts/moveTop': [QtGui.QKeySequence(QtCore.Qt.Key_Home)], u'shortcuts/modeSetupItem': [], - u'shortcuts/moveBottom': [QtCore.Qt.Key_End], - u'shortcuts/moveDown': [QtCore.Qt.Key_PageDown], + u'shortcuts/moveBottom': [QtGui.QKeySequence(QtCore.Qt.Key_End)], + u'shortcuts/moveDown': [QtGui.QKeySequence(QtCore.Qt.Key_PageDown)], 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), + QtGui.QKeySequence(QtCore.Qt.Key_PageDown)], u'shortcuts/nextItem_preview': [], - u'shortcuts/nextService': [QtCore.Qt.Key_Right], + u'shortcuts/nextService': [QtGui.QKeySequence(QtCore.Qt.Key_Right)], u'shortcuts/newService': [], u'shortcuts/offlineHelpItem': [], u'shortcuts/onlineHelpItem': [QtGui.QKeySequence(u'Alt+F1')], u'shortcuts/openService': [], u'shortcuts/saveService': [], - u'shortcuts/previousItem_live': [QtCore.Qt.Key_Up, QtCore.Qt.Key_PageUp], + 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/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/songExportItem': [], - u'shortcuts/songUsageStatus': [QtCore.Qt.Key_F4], + u'shortcuts/songUsageStatus': [QtGui.QKeySequence(QtCore.Qt.Key_F4)], u'shortcuts/settingsShortcutsItem': [], u'shortcuts/settingsImportItem': [], u'shortcuts/settingsPluginListItem': [QtGui.QKeySequence(u'Alt+F7')], @@ -228,12 +230,12 @@ class Settings(QtCore.QSettings): u'shortcuts/songImportItem': [], u'shortcuts/themeScreen': [QtGui.QKeySequence(u'T')], u'shortcuts/toolsReindexItem': [], - u'shortcuts/toolsAlertItem': [u'F7'], + u'shortcuts/toolsAlertItem': [QtGui.QKeySequence(u'F7')], u'shortcuts/toolsFirstTimeWizard': [], u'shortcuts/toolsOpenDataFolder': [], u'shortcuts/toolsAddToolItem': [], 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/viewMediaManagerItem': [QtGui.QKeySequence(u'F8')], u'shortcuts/viewPreviewPanel': [QtGui.QKeySequence(u'F11')], @@ -242,36 +244,48 @@ class Settings(QtCore.QSettings): u'shortcuts/webSiteItem': [], # FIXME: To be sorted. - u'shortcuts/listViewSongsDeleteItem': [QtCore.Qt.Key_Delete], - u'shortcuts/listViewSongsPreviewItem': [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], - u'shortcuts/listViewSongsLiveItem': [QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter, - QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return], - u'shortcuts/listViewSongsServiceItem': [QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal], - u'shortcuts/listViewBiblesDeleteItem': [QtCore.Qt.Key_Delete], - u'shortcuts/listViewBiblesPreviewItem': [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], - u'shortcuts/listViewBiblesLiveItem': [QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter, - QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return], - u'shortcuts/listViewBiblesServiceItem': [QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal], - u'shortcuts/listViewPresentationsDeleteItem': [QtCore.Qt.Key_Delete], - u'shortcuts/listViewPresentationsPreviewItem': [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], - u'shortcuts/listViewPresentationsLiveItem': [QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter, - QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return], - u'shortcuts/listViewPresentationsServiceItem': [QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal], - u'shortcuts/listViewImagesDeleteItem': [QtCore.Qt.Key_Delete], - u'shortcuts/listViewImagesPreviewItem': [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], - u'shortcuts/listViewImagesLiveItem': [QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter, - QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return], - u'shortcuts/listViewImagesServiceItem': [QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal], - u'shortcuts/listViewMediaDeleteItem': [QtCore.Qt.Key_Delete], - u'shortcuts/listViewMediaPreviewItem': [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], - u'shortcuts/listViewMediaLiveItem': [QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter, - QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return], - u'shortcuts/listViewMediaServiceItem': [QtCore.Qt.Key_Plus, QtCore.Qt.Key_Equal], - u'shortcuts/listViewCustomDeleteItem': [QtCore.Qt.Key_Delete], - u'shortcuts/listViewCustomPreviewItem': [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return], - u'shortcuts/listViewCustomLiveItem': [QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Enter, - QtCore.Qt.ShiftModifier | QtCore.Qt.Key_Return], - u'shortcuts/listViewCustomServiceItem': [QtCore.Qt.Key_Plus, 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/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/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/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/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'themes/global theme': u'', u'themes/last directory': u'', diff --git a/openlp/core/ui/shortcutlistform.py b/openlp/core/ui/shortcutlistform.py index 75e7403d5..522a6507e 100644 --- a/openlp/core/ui/shortcutlistform.py +++ b/openlp/core/ui/shortcutlistform.py @@ -147,8 +147,8 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): def refreshShortcutList(self): """ - This refreshes the item's shortcuts shown in the list. Note, this - neither adds new actions nor removes old actions. + This refreshes the item's shortcuts shown in the list. Note, this neither adds new actions nor removes old + actions. """ iterator = QtGui.QTreeWidgetItemIterator(self.treeWidget) while iterator.value(): @@ -204,21 +204,19 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): new_shortcuts = [] if shortcuts: new_shortcuts.append(shortcuts[0]) - new_shortcuts.append( - QtGui.QKeySequence(self.alternatePushButton.text())) + new_shortcuts.append(QtGui.QKeySequence(self.alternatePushButton.text())) self.changedActions[action] = new_shortcuts if not self.primaryPushButton.text(): - # When we do not have a primary shortcut, the just entered alternate - # shortcut will automatically become the primary shortcut. That is - # why we have to adjust the primary button's text. + # When we do not have a primary shortcut, the just entered alternate shortcut will automatically become the + # primary shortcut. That is why we have to adjust the primary button's text. self.primaryPushButton.setText(self.alternatePushButton.text()) self.alternatePushButton.setText(u'') self.refreshShortcutList() def onItemDoubleClicked(self, item, column): """ - A item has been double clicked. The ``primaryPushButton`` will be - checked and the item's shortcut will be displayed. + A item has been double clicked. The ``primaryPushButton`` will be checked and the item's shortcut will be + displayed. """ action = self._currentItemAction(item) if action is None: @@ -234,8 +232,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): def onCurrentItemChanged(self, item=None, previousItem=None): """ - A item has been pressed. We adjust the button's text to the action's - shortcut which is encapsulate in the item. + A item has been pressed. We adjust the button's text to the action's shortcut which is encapsulate in the item. """ action = self._currentItemAction(item) self.primaryPushButton.setEnabled(action is not None) @@ -253,9 +250,8 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): if len(action.defaultShortcuts) == 2: alternate_label_text = action.defaultShortcuts[1].toString() shortcuts = self._actionShortcuts(action) - # We do not want to loose pending changes, that is why we have to - # keep the text when, this function has not been triggered by a - # signal. + # We do not want to loose pending changes, that is why we have to keep the text when, this function has not + # been triggered by a signal. if item is None: primary_text = self.primaryPushButton.text() alternate_text = self.alternatePushButton.text() @@ -264,8 +260,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): elif len(shortcuts) == 2: primary_text = shortcuts[0].toString() alternate_text = shortcuts[1].toString() - # When we are capturing a new shortcut, we do not want, the buttons to - # display the current shortcut. + # When we are capturing a new shortcut, we do not want, the buttons to display the current shortcut. if self.primaryPushButton.isChecked(): primary_text = u'' if self.alternatePushButton.isChecked(): @@ -274,8 +269,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): self.alternatePushButton.setText(alternate_text) self.primaryLabel.setText(primary_label_text) self.alternateLabel.setText(alternate_label_text) - # We do not want to toggle and radio button, as the function has not - # been triggered by a signal. + # We do not want to toggle and radio button, as the function has not been triggered by a signal. if item is None: return 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): """ - The default radio button has been clicked, which means we have to make - sure, that we use the default shortcuts for the action. + The default radio button has been clicked, which means we have to make sure, that we use the default shortcuts + for the action. """ if not toggled: return @@ -325,9 +319,8 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): def onCustomRadioButtonClicked(self, toggled): """ - The custom shortcut radio button was clicked, thus we have to restore - the custom shortcuts by calling those functions triggered by button - clicks. + The custom shortcut radio button was clicked, thus we have to restore the custom shortcuts by calling those + functions triggered by button clicks. """ if not toggled: return @@ -337,8 +330,8 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): def save(self): """ - Save the shortcuts. **Note**, that we do not have to load the shortcuts, - as they are loaded in :class:`~openlp.core.utils.ActionList`. + Save the shortcuts. **Note**, that we do not have to load the shortcuts, as they are loaded in + :class:`~openlp.core.utils.ActionList`. """ settings = Settings() settings.beginGroup(u'shortcuts') @@ -348,8 +341,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): continue for action in category.actions: if action in self.changedActions: - old_shortcuts = map(unicode, - map(QtGui.QKeySequence.toString, action.shortcuts())) + old_shortcuts = map(QtGui.QKeySequence.toString, action.shortcuts()) action.setShortcuts(self.changedActions[action]) self.action_list.update_shortcut_map(action, old_shortcuts) settings.setValue(action.objectName(), action.shortcuts()) @@ -367,13 +359,10 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): new_shortcuts = [] if action.defaultShortcuts: new_shortcuts.append(action.defaultShortcuts[0]) - # We have to check if the primary default shortcut is available. But - # we only have to check, if the action has a default primary - # shortcut (an "empty" shortcut is always valid and if the action - # does not have a default primary shortcut, then the alternative - # 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. + # We have to check if the primary default shortcut is available. But we only have to check, if the action + # has a default primary shortcut (an "empty" shortcut is always valid and if the action does not have a + # default primary shortcut, then the alternative 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]: return if len(shortcuts) == 2: @@ -405,9 +394,8 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): def _validiate_shortcut(self, changing_action, key_sequence): """ - Checks if the given ``changing_action `` can use the given - ``key_sequence``. Returns ``True`` if the ``key_sequence`` can be used - by the action, otherwise displays a dialog and returns ``False``. + Checks if the given ``changing_action `` can use the given ``key_sequence``. Returns ``True`` if the + ``key_sequence`` can be used by the action, otherwise displays a dialog and returns ``False``. ``changing_action`` The action which wants to use the ``key_sequence``. @@ -429,9 +417,8 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): # Have the same parent, thus they cannot have the same shortcut. if action.parent() is changing_action.parent(): is_valid = False - # The new shortcut is already assigned, but if both shortcuts - # are only valid in a different widget the new shortcut is - # vaild, because they will not interfere. + # The new shortcut is already assigned, but if both shortcuts are only valid in a different widget the + # new shortcut is vaild, because they will not interfere. if action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]: is_valid = False @@ -447,9 +434,8 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): def _actionShortcuts(self, action): """ - This returns the shortcuts for the given ``action``, which also includes - those shortcuts which are not saved yet but already assigned (as changes - are applied when closing the dialog). + This returns the shortcuts for the given ``action``, which also includes those shortcuts which are not saved + yet but already assigned (as changes yre applied when closing the dialog). """ if action in self.changedActions: return self.changedActions[action] @@ -457,8 +443,8 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): def _currentItemAction(self, item=None): """ - Returns the action of the given ``item``. If no item is given, we return - the action of the current item of the ``treeWidget``. + Returns the action of the given ``item``. If no item is given, we return the action of the current item of + the ``treeWidget``. """ if item is None: item = self.treeWidget.currentItem() @@ -486,4 +472,5 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): self._main_window = Registry().get(u'main_window') return self._main_window - main_window = property(_get_main_window) \ No newline at end of file + main_window = property(_get_main_window) + From 019e59d81f2063268730c9a7487064381c42082e Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 19 Feb 2013 11:54:24 +0100 Subject: [PATCH 24/48] added language manager test --- .../openlp_core_utils/test_languagemanager.py | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 tests/functional/openlp_core_utils/test_languagemanager.py diff --git a/tests/functional/openlp_core_utils/test_languagemanager.py b/tests/functional/openlp_core_utils/test_languagemanager.py new file mode 100644 index 000000000..e2034bcd8 --- /dev/null +++ b/tests/functional/openlp_core_utils/test_languagemanager.py @@ -0,0 +1,26 @@ +""" +Functional tests for the Language Manager. +""" + +from unittest import TestCase + +from mock import patch + +from openlp.core.utils import LanguageManager + +class TestLanguageManager(TestCase): + """ + A test suite to test out various methods around the LanguageManager class. + """ + def get_translator_linux_test(self): + """ + """ + with patch(u'openlp.core.utils.sys.platform') as mocked_platform: + # GIVEN: We are on linux. + mocked_platform.return_value = u'linux2' + + app_translator, default_translator = LanguageManager.get_translator('en') + + assert not app_translator.isEmpty(), u'The application translator should not be empty' + assert not default_translator.isEmpty(), u'The default translator should not be empty' + From 0f44fb3dd5ead31060022de02f9e99c3b684b09e Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 19 Feb 2013 13:53:24 +0100 Subject: [PATCH 25/48] added actions test file (not started yet); fixed short lines --- openlp/core/lib/ui.py | 41 +++++++------------ openlp/core/ui/shortcutlistform.py | 17 +++----- .../openlp_core_utils/test_actions.py | 22 ++++++++++ 3 files changed, 43 insertions(+), 37 deletions(-) create mode 100644 tests/functional/openlp_core_utils/test_actions.py diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index 82127db6d..c4b48f2ad 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -69,9 +69,8 @@ def add_welcome_page(parent, image): def create_button_box(dialog, name, standard_buttons, custom_buttons=None): """ - Creates a QDialogButtonBox with the given buttons. The ``accepted()`` and - ``rejected()`` signals of the button box are connected with the dialogs - ``accept()`` and ``reject()`` slots. + Creates a QDialogButtonBox with the given buttons. The ``accepted()`` and ``rejected()`` signals of the button box + are connected with the dialogs ``accept()`` and ``reject()`` slots. ``dialog`` 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. ``standard_buttons`` - A list of strings for the used buttons. It might contain: ``ok``, - ``save``, ``cancel``, ``close``, and ``defaults``. + A list of strings for the used buttons. It might contain: ``ok``, ``save``, ``cancel``, ``close``, and + ``defaults``. ``custom_buttons`` - A list of additional buttons. If a item is a instance of - QtGui.QAbstractButton it is added with QDialogButtonBox.ActionRole. - Otherwhise the item has to be a tuple of a button and a ButtonRole. + A list of additional buttons. If a item is a instance of QtGui.QAbstractButton it is added with + QDialogButtonBox.ActionRole. Otherwhise the item has to be a tuple of a button and a ButtonRole. """ if custom_buttons is None: 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): """ - Provides a standard critical message box for errors that OpenLP displays - to users. + Provides a standard critical message box for errors that OpenLP displays to users. ``title`` 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: return QtGui.QMessageBox.critical(parent, UiStrings().Error, message, 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) @@ -166,16 +162,14 @@ def create_button(parent, name, **kwargs): A string which is set as object name (required). ``role`` - A string which can have one value out of ``delete``, ``up``, and - ``down``. This decides about default values for properties like text, - icon, or tooltip. + A string which can have one value out of ``delete``, ``up``, and ``down``. This decides about default values + for properties like text, icon, or tooltip. ``text`` A string for the action text. ``icon`` - Either a QIcon, a resource string, or a file location string for the - action icon. + Either a QIcon, a resource string, or a file location string for the action icon. ``tooltip`` 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'tooltip', translate('OpenLP.Ui', 'Move selection down one position.')) else: - log.warn(u'The role "%s" is not defined in create_push_button().', - role) + log.warn(u'The role "%s" is not defined in create_push_button().', role) if kwargs.pop(u'class', u'') == u'toolbutton': button = QtGui.QToolButton(parent) else: @@ -291,9 +284,7 @@ def create_action(parent, name, **kwargs): action.setSeparator(True) if u'data' in kwargs: action.setData(kwargs.pop(u'data')) - if kwargs.pop(u'can_shortcuts', False): - if not action.objectName(): - raise Exception("objectName not set") + if kwargs.pop(u'can_shortcuts'): action_list = ActionList.get_instance() action_list.add_action(action, kwargs.pop(u'category', None)) if u'context' in kwargs: @@ -309,9 +300,8 @@ def create_action(parent, name, **kwargs): def create_widget_action(parent, name=u'', **kwargs): """ - Return a new QAction by calling ``create_action(parent, name, **kwargs)``. - The shortcut context defaults to ``QtCore.Qt.WidgetShortcut`` and the action - is added to the parents action list. + Return a new QAction by calling ``create_action(parent, name, **kwargs)``. The shortcut context defaults to + ``QtCore.Qt.WidgetShortcut`` and the action is added to the parents action list. """ kwargs.setdefault(u'context', QtCore.Qt.WidgetShortcut) action = create_action(parent, name, **kwargs) @@ -336,8 +326,7 @@ def set_case_insensitive_completer(cache, widget): def create_valign_selection_widgets(parent): """ - Creates a standard label and combo box for asking users to select a - vertical alignment. + Creates a standard label and combo box for asking users to select a vertical alignment. ``parent`` The parent object. This should be a ``QWidget`` descendant. diff --git a/openlp/core/ui/shortcutlistform.py b/openlp/core/ui/shortcutlistform.py index 522a6507e..481193940 100644 --- a/openlp/core/ui/shortcutlistform.py +++ b/openlp/core/ui/shortcutlistform.py @@ -56,8 +56,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): self.setupUi(self) self.changedActions = {} self.action_list = ActionList.get_instance() - QtCore.QObject.connect(self.primaryPushButton, QtCore.SIGNAL(u'toggled(bool)'), - self.onPrimaryPushButtonClicked) + QtCore.QObject.connect(self.primaryPushButton, QtCore.SIGNAL(u'toggled(bool)'), self.onPrimaryPushButtonClicked) QtCore.QObject.connect(self.alternatePushButton, QtCore.SIGNAL(u'toggled(bool)'), self.onAlternatePushButtonClicked) QtCore.QObject.connect(self.treeWidget, @@ -72,8 +71,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): self.onRestoreDefaultsClicked) QtCore.QObject.connect(self.defaultRadioButton, QtCore.SIGNAL(u'clicked(bool)'), self.onDefaultRadioButtonClicked) - QtCore.QObject.connect(self.customRadioButton, QtCore.SIGNAL(u'clicked(bool)'), - self.onCustomRadioButtonClicked) + QtCore.QObject.connect(self.customRadioButton, QtCore.SIGNAL(u'clicked(bool)'), self.onCustomRadioButtonClicked) def keyPressEvent(self, event): """ @@ -95,7 +93,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): return key = event.key() if key == QtCore.Qt.Key_Shift or key == QtCore.Qt.Key_Control or \ - key == QtCore.Qt.Key_Meta or key == QtCore.Qt.Key_Alt: + key == QtCore.Qt.Key_Meta or key == QtCore.Qt.Key_Alt: return key_string = QtGui.QKeySequence(key).toString() if event.modifiers() & QtCore.Qt.ControlModifier == QtCore.Qt.ControlModifier: @@ -109,11 +107,9 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): key_sequence = QtGui.QKeySequence(key_string) if self._validiate_shortcut(self._currentItemAction(), key_sequence): if self.primaryPushButton.isChecked(): - self._adjustButton(self.primaryPushButton, - False, text=key_sequence.toString()) + self._adjustButton(self.primaryPushButton, False, text=key_sequence.toString()) elif self.alternatePushButton.isChecked(): - self._adjustButton(self.alternatePushButton, - False, text=key_sequence.toString()) + self._adjustButton(self.alternatePushButton, False, text=key_sequence.toString()) def exec_(self): """ @@ -419,8 +415,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): is_valid = False # The new shortcut is already assigned, but if both shortcuts are only valid in a different widget the # new shortcut is 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 if changing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]: is_valid = False diff --git a/tests/functional/openlp_core_utils/test_actions.py b/tests/functional/openlp_core_utils/test_actions.py new file mode 100644 index 000000000..8cdae2e41 --- /dev/null +++ b/tests/functional/openlp_core_utils/test_actions.py @@ -0,0 +1,22 @@ +""" +Package to test the openlp.core.utils.actions package. +""" +from unittest import TestCase + +from mock import patch + +from openlp.core.utils import ActionList + + +class TestActionList(TestCase): + + def setUp(self): + """ + Prepare the tests + """ + self.action_list = ActionList.get_instance() + + def test_(self): + """ + """ + pass From 20d687524aad585a950838c55ab514125c4f6238 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 19 Feb 2013 14:09:00 +0100 Subject: [PATCH 26/48] fixed missing items --- openlp/core/lib/ui.py | 2 +- openlp/core/ui/mainwindow.py | 50 ++++++++++++++++++------------------ 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index c4b48f2ad..57a7d8f41 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -284,7 +284,7 @@ def create_action(parent, name, **kwargs): action.setSeparator(True) if u'data' in kwargs: action.setData(kwargs.pop(u'data')) - if kwargs.pop(u'can_shortcuts'): + if kwargs.pop(u'can_shortcuts', False): action_list = ActionList.get_instance() action_list.add_action(action, kwargs.pop(u'category', None)) if u'context' in kwargs: diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 9a95d75f2..a2ef572e0 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -205,10 +205,12 @@ class Ui_MainWindow(object): # Give QT Extra Hint that this is the Exit Menu Item self.fileExitItem.setMenuRole(QtGui.QAction.QuitRole) 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') 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') action_list.add_category(UiStrings().View, CategoryOrder.standard_menu) self.viewMediaManagerItem = create_action(main_window, @@ -237,12 +239,13 @@ class Ui_MainWindow(object): can_shortcuts=True, checked=panelLocked, category=UiStrings().View, triggers=self.setLockPanel) - action_list.add_category(UiStrings().ViewMode, - CategoryOrder.standard_menu) - self.modeDefaultItem = create_action(main_window, u'modeDefaultItem', checked=False, - category=UiStrings().ViewMode) - self.modeSetupItem = create_action(main_window, u'modeSetupItem', checked=False, category=UiStrings().ViewMode) - self.modeLiveItem = create_action(main_window, u'modeLiveItem', checked=True, category=UiStrings().ViewMode) + action_list.add_category(UiStrings().ViewMode, CategoryOrder.standard_menu) + self.modeDefaultItem = create_action( + main_window, u'modeDefaultItem', checked=False, category=UiStrings().ViewMode, can_shortcuts=True) + 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.addAction(self.modeDefaultItem) self.modeGroup.addAction(self.modeSetupItem) @@ -250,26 +253,22 @@ class Ui_MainWindow(object): self.modeDefaultItem.setChecked(True) action_list.add_category(UiStrings().Tools, CategoryOrder.standard_menu) self.toolsAddToolItem = create_action(main_window, - u'toolsAddToolItem', icon=u':/tools/tools_add.png', - category=UiStrings().Tools) + u'toolsAddToolItem', icon=u':/tools/tools_add.png', category=UiStrings().Tools, can_shortcuts=True) self.toolsOpenDataFolder = create_action(main_window, - u'toolsOpenDataFolder', icon=u':/general/general_open.png', - category=UiStrings().Tools) + u'toolsOpenDataFolder', icon=u':/general/general_open.png', category=UiStrings().Tools, can_shortcuts=True) self.toolsFirstTimeWizard = create_action(main_window, u'toolsFirstTimeWizard', icon=u':/general/general_revert.png', - category=UiStrings().Tools) + category=UiStrings().Tools, can_shortcuts=True) self.updateThemeImages = create_action(main_window, - u'updateThemeImages', category=UiStrings().Tools) - action_list.add_category(UiStrings().Settings, - CategoryOrder.standard_menu) + u'updateThemeImages', category=UiStrings().Tools, can_shortcuts=True) + action_list.add_category(UiStrings().Settings, CategoryOrder.standard_menu) self.settingsPluginListItem = create_action(main_window, u'settingsPluginListItem', icon=u':/system/settings_plugin_list.png', can_shortcuts=True, category=UiStrings().Settings, triggers=self.onPluginItemClicked) # i18n Language Items - self.autoLanguageItem = create_action(main_window, u'autoLanguageItem', - checked=LanguageManager.auto_language) + self.autoLanguageItem = create_action(main_window, u'autoLanguageItem', checked=LanguageManager.auto_language) self.languageGroup = QtGui.QActionGroup(main_window) self.languageGroup.setExclusive(True) self.languageGroup.setObjectName(u'languageGroup') @@ -280,20 +279,21 @@ class Ui_MainWindow(object): languageItem = create_action(main_window, key, checked=qmList[key] == savedLanguage) add_actions(self.languageGroup, [languageItem]) 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. 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', icon=u':/system/system_settings.png', can_shortcuts=True, category=UiStrings().Settings) # Give QT Extra Hint that this is the Preferences Menu Item self.settingsConfigureItem.setMenuRole(QtGui.QAction.PreferencesRole) - self.settingsImportItem = create_action(main_window, u'settingsImportItem', category=UiStrings().Settings) - self.settingsExportItem = create_action(main_window, u'settingsExportItem', category=UiStrings().Settings) + self.settingsImportItem = create_action( + main_window, u'settingsImportItem', category=UiStrings().Settings, can_shortcuts=True) + self.settingsExportItem = create_action( + main_window, u'settingsExportItem', category=UiStrings().Settings, 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', - can_shortcuts=True, - category=UiStrings().Help, triggers=self.onAboutItemClicked) + can_shortcuts=True, category=UiStrings().Help, triggers=self.onAboutItemClicked) # Give QT Extra Hint that this is an About Menu Item self.aboutItem.setMenuRole(QtGui.QAction.AboutRole) if os.name == u'nt': @@ -307,7 +307,7 @@ class Ui_MainWindow(object): icon=u':/system/system_online_help.png', can_shortcuts=True, 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.fileExportMenu, (self.settingsExportItem, None, self.exportThemeItem, self.exportLanguageItem)) add_actions(self.fileMenu, (self.fileNewItem, self.fileOpenItem, From 29194b5e1e627b77f027c217967de9b58f9b1fc6 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 19 Feb 2013 14:57:14 +0100 Subject: [PATCH 27/48] fixed bug #1128376 (Configure shortcuts has two items called settings) Fixes: https://launchpad.net/bugs/112837 --- openlp/core/ui/mainwindow.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index a2ef572e0..04cb4ebcb 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -288,9 +288,9 @@ class Ui_MainWindow(object): # Give QT Extra Hint that this is the Preferences Menu Item self.settingsConfigureItem.setMenuRole(QtGui.QAction.PreferencesRole) self.settingsImportItem = create_action( - main_window, u'settingsImportItem', category=UiStrings().Settings, can_shortcuts=True) + main_window, u'settingsImportItem', category=UiStrings().Import, can_shortcuts=True) self.settingsExportItem = create_action( - main_window, u'settingsExportItem', category=UiStrings().Settings, can_shortcuts=True) + 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', can_shortcuts=True, category=UiStrings().Help, triggers=self.onAboutItemClicked) From b9a0458200fca43c181346370a46d5861b06d6ca Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Tue, 19 Feb 2013 18:27:17 +0000 Subject: [PATCH 29/48] Minor updates --- tests/functional/openlp_core_lib/test_settings.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/functional/openlp_core_lib/test_settings.py b/tests/functional/openlp_core_lib/test_settings.py index 634865369..09e65a1e4 100644 --- a/tests/functional/openlp_core_lib/test_settings.py +++ b/tests/functional/openlp_core_lib/test_settings.py @@ -1,9 +1,11 @@ """ - Package to test the openlp.core.lib package. + Package to test the openlp.core.lib.settings package. """ import os from unittest import TestCase +from tempfile import mkstemp + from openlp.core.lib import Settings from PyQt4 import QtGui, QtTest @@ -17,20 +19,19 @@ class TestSettings(TestCase): """ Create the UI """ + fd, self.ini_file = mkstemp(u'.ini') + Settings().set_filename(self.ini_file) self.application = QtGui.QApplication.instance() self.application.setOrganizationName(u'OpenLP-tests') self.application.setOrganizationDomain(u'openlp.org') - Settings() def tearDown(self): """ Delete all the C++ objects at the end so that we don't have a segfault """ del self.application - try: - os.remove(Settings().fileName()) - except OSError: - pass + os.unlink(self.ini_file) + os.unlink(Settings().fileName()) def settings_basic_test(self): """ From 269e5f5901ffb216099511ae502dd2017b6b0be5 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 19 Feb 2013 19:29:32 +0100 Subject: [PATCH 30/48] added actionList tests; removed useless test --- openlp/core/utils/actions.py | 9 +- .../openlp_core_utils/test_actions.py | 108 +++++++++++++++++- .../openlp_core_utils/test_languagemanager.py | 26 ----- 3 files changed, 110 insertions(+), 33 deletions(-) delete mode 100644 tests/functional/openlp_core_utils/test_languagemanager.py diff --git a/openlp/core/utils/actions.py b/openlp/core/utils/actions.py index dbf42dc84..950d654dc 100644 --- a/openlp/core/utils/actions.py +++ b/openlp/core/utils/actions.py @@ -322,6 +322,7 @@ class ActionList(object): ActionList.shortcut_map[shortcuts[0]] = actions else: shortcuts.remove(shortcuts[0]) + action.setShortcuts([QtGui.QKeySequence(shortcut) for shortcut in shortcuts]) def remove_action(self, action, category=None): @@ -350,7 +351,7 @@ class ActionList(object): def add_category(self, name, weight): """ - Add an empty category to the list of categories. This is ony convenient for categories with a given weight. + Add an empty category to the list of categories. This is only convenient for categories with a given weight. ``name`` The category's name. @@ -403,15 +404,15 @@ class ActionList(object): ``action`` The action which wants to use a particular shortcut. """ - local = action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut] + local_context = action.shortcutContext() not in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut] affected_actions = [] - if local: + if local_context: affected_actions = filter( lambda a: isinstance(a, QtGui.QAction), self.get_all_child_objects(action.parent())) for existing_action in existing_actions: if action is existing_action: continue - if not local or existing_action in affected_actions: + if not local_context or existing_action in affected_actions: return False if existing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]: return False diff --git a/tests/functional/openlp_core_utils/test_actions.py b/tests/functional/openlp_core_utils/test_actions.py index 8cdae2e41..7b03493ba 100644 --- a/tests/functional/openlp_core_utils/test_actions.py +++ b/tests/functional/openlp_core_utils/test_actions.py @@ -1,10 +1,13 @@ """ Package to test the openlp.core.utils.actions package. """ +import os +from tempfile import mkstemp from unittest import TestCase -from mock import patch +from PyQt4 import QtGui, QtCore +from openlp.core.lib import Settings from openlp.core.utils import ActionList @@ -15,8 +18,107 @@ class TestActionList(TestCase): 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 test_(self): + def tearDown(self): """ + Clean up """ - pass + 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() + action = QtGui.QAction(parent) + action.setObjectName(u'action') + action_with_same_shortcuts = QtGui.QAction(parent) + action_with_same_shortcuts.setObjectName(u'action_with_same_shortcuts') + # Add default shortcuts to Settings class. + default_shortcuts = { + u'shortcuts/action': [QtGui.QKeySequence(u'v'), QtGui.QKeySequence(u'c')], + u'shortcuts/action_with_same_shortcuts': [QtGui.QKeySequence(u'v'), QtGui.QKeySequence(u'c')] + } + Settings.extend_default_settings(default_shortcuts) + + # WHEN: Add the two actions to the action list. + self.action_list.add_action(action, u'example_category') + self.action_list.add_action(action_with_same_shortcuts, u'example_category') + # Remove the actions again. + self.action_list.remove_action(action, u'example_category') + self.action_list.remove_action(action_with_same_shortcuts, u'example_category') + + # THEN: As both actions have the same shortcuts, they should be removed from one action. + assert len(action.shortcuts()) == 2, u'The action should have two shortcut assigned.' + assert len(action_with_same_shortcuts.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() + action = QtGui.QAction(parent) + action.setObjectName(u'action2') + second_parent = QtCore.QObject() + action_with_same_shortcuts = QtGui.QAction(second_parent) + action_with_same_shortcuts.setObjectName(u'action_with_same_shortcuts2') + # Add default shortcuts to Settings class. + default_shortcuts = { + u'shortcuts/action2': [QtGui.QKeySequence(u'v'), QtGui.QKeySequence(u'c')], + u'shortcuts/action_with_same_shortcuts2': [QtGui.QKeySequence(u'v'), QtGui.QKeySequence(u'c')] + } + Settings.extend_default_settings(default_shortcuts) + + # WHEN: Add the two actions to the action list. + self.action_list.add_action(action, u'example_category') + self.action_list.add_action(action_with_same_shortcuts, u'example_category') + # Remove the actions again. + self.action_list.remove_action(action, u'example_category') + self.action_list.remove_action(action_with_same_shortcuts, u'example_category') + + # THEN: As both actions have the same shortcuts, they should be removed from one action. + assert len(action.shortcuts()) == 2, u'The action should have two shortcut assigned.' + assert len(action_with_same_shortcuts.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() + action = QtGui.QAction(parent) + action.setObjectName(u'action3') + action.setShortcutContext(QtCore.Qt.WidgetShortcut) + second_parent = QtCore.QObject() + action_with_same_shortcuts = QtGui.QAction(second_parent) + action_with_same_shortcuts.setObjectName(u'action_with_same_shortcuts3') + action_with_same_shortcuts.setShortcutContext(QtCore.Qt.WidgetShortcut) + # Add default shortcuts to Settings class. + default_shortcuts = { + u'shortcuts/action3': [QtGui.QKeySequence(u'1'), QtGui.QKeySequence(u'2')], + u'shortcuts/action_with_same_shortcuts3': [QtGui.QKeySequence(u'1'), QtGui.QKeySequence(u'2')] + } + Settings.extend_default_settings(default_shortcuts) + + # WHEN: Add the two actions to the action list. + self.action_list.add_action(action, u'example_category2') + self.action_list.add_action(action_with_same_shortcuts, u'example_category2') + # Remove the actions again. + self.action_list.remove_action(action, u'example_category2') + self.action_list.remove_action(action_with_same_shortcuts, u'example_category2') + + # THEN: Both action should keep their shortcuts. + assert len(action.shortcuts()) == 2, u'The action should have two shortcut assigned.' + assert len(action_with_same_shortcuts.shortcuts()) == 2, u'The action should have two shortcuts assigned.' + + diff --git a/tests/functional/openlp_core_utils/test_languagemanager.py b/tests/functional/openlp_core_utils/test_languagemanager.py deleted file mode 100644 index e2034bcd8..000000000 --- a/tests/functional/openlp_core_utils/test_languagemanager.py +++ /dev/null @@ -1,26 +0,0 @@ -""" -Functional tests for the Language Manager. -""" - -from unittest import TestCase - -from mock import patch - -from openlp.core.utils import LanguageManager - -class TestLanguageManager(TestCase): - """ - A test suite to test out various methods around the LanguageManager class. - """ - def get_translator_linux_test(self): - """ - """ - with patch(u'openlp.core.utils.sys.platform') as mocked_platform: - # GIVEN: We are on linux. - mocked_platform.return_value = u'linux2' - - app_translator, default_translator = LanguageManager.get_translator('en') - - assert not app_translator.isEmpty(), u'The application translator should not be empty' - assert not default_translator.isEmpty(), u'The default translator should not be empty' - From c2b5c65756630312d42b2d1281ee189b4a7ce2ec Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 19 Feb 2013 19:36:43 +0100 Subject: [PATCH 31/48] fixed up _is_shortcut_available method --- openlp/core/utils/actions.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/openlp/core/utils/actions.py b/openlp/core/utils/actions.py index 950d654dc..c131fbc88 100644 --- a/openlp/core/utils/actions.py +++ b/openlp/core/utils/actions.py @@ -322,7 +322,6 @@ class ActionList(object): ActionList.shortcut_map[shortcuts[0]] = actions else: shortcuts.remove(shortcuts[0]) - action.setShortcuts([QtGui.QKeySequence(shortcut) for shortcut in shortcuts]) def remove_action(self, action, category=None): @@ -404,15 +403,15 @@ class ActionList(object): ``action`` The action which wants to use a particular shortcut. """ - local_context = action.shortcutContext() not in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut] + global_context = action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut] affected_actions = [] - if local_context: + 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: if action is existing_action: continue - if not local_context or existing_action in affected_actions: + if global_context or existing_action in affected_actions: return False if existing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]: return False From 4e3a4f1e599e552943855901aa23752a19afb5fb Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 20 Feb 2013 07:45:00 +0100 Subject: [PATCH 32/48] changed doc for can_shortcuts --- openlp/core/lib/ui.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index 57a7d8f41..605550043 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -250,9 +250,9 @@ def create_action(parent, name, **kwargs): The action's data. ``can_shortcuts`` - Boolean stating if this action has shortcuts or if it can have shortcuts. If ``True`` the action is added to - shortcut dialog. **Note**: Never set the shortcuts yourselt; use the :class:`~openlp.core.lib.Settings` class - to define the action's 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`` A context for the shortcut execution. From 8d164cd21e31527c04b15851c5ba61814979a262 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 20 Feb 2013 08:02:48 +0100 Subject: [PATCH 33/48] clean up --- openlp/core/ui/mainwindow.py | 2 +- openlp/core/ui/shortcutlistform.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 04cb4ebcb..14186cf78 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -1352,7 +1352,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.version_text) else: # the thread has not confirmed it is running or it has not yet sent any data so lets keep waiting - if not hasattr(self,u'version_update_running') or self.version_update_running: + if not hasattr(self, u'version_update_running') or self.version_update_running: self.timer_version_id = self.startTimer(1000) self.application.process_events() diff --git a/openlp/core/ui/shortcutlistform.py b/openlp/core/ui/shortcutlistform.py index 481193940..c2fbc61fc 100644 --- a/openlp/core/ui/shortcutlistform.py +++ b/openlp/core/ui/shortcutlistform.py @@ -420,7 +420,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): if changing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]: is_valid = False if not is_valid: - self.main_window.warning_message( translate('OpenLP.ShortcutListDialog', 'Duplicate Shortcut'), + self.main_window.warning_message(translate('OpenLP.ShortcutListDialog', 'Duplicate Shortcut'), translate('OpenLP.ShortcutListDialog', 'The shortcut "%s" is already assigned to another action, please use a different shortcut.') % key_sequence.toString() From b6efe5393dba68b1700e7a94a0016498e1549603 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 20 Feb 2013 08:27:51 +0100 Subject: [PATCH 34/48] do not react on ESC/Enter/Return event when closing the dialog --- openlp/core/ui/shortcutlistform.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openlp/core/ui/shortcutlistform.py b/openlp/core/ui/shortcutlistform.py index c2fbc61fc..718b7193e 100644 --- a/openlp/core/ui/shortcutlistform.py +++ b/openlp/core/ui/shortcutlistform.py @@ -56,6 +56,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): self.setupUi(self) self.changedActions = {} self.action_list = ActionList.get_instance() + self.dialog_was_shown = False QtCore.QObject.connect(self.primaryPushButton, QtCore.SIGNAL(u'toggled(bool)'), self.onPrimaryPushButtonClicked) QtCore.QObject.connect(self.alternatePushButton, QtCore.SIGNAL(u'toggled(bool)'), self.onAlternatePushButtonClicked) @@ -91,6 +92,10 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): """ if not self.primaryPushButton.isChecked() and not self.alternatePushButton.isChecked(): 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() if key == QtCore.Qt.Key_Shift or key == QtCore.Qt.Key_Control or \ key == QtCore.Qt.Key_Meta or key == QtCore.Qt.Key_Alt: @@ -425,6 +430,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): 'The shortcut "%s" is already assigned to another action, please use a different shortcut.') % key_sequence.toString() ) + self.dialog_was_shown = True return is_valid def _actionShortcuts(self, action): From 26599b0f73ab838189e5c4fa646b58e4720811e9 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 20 Feb 2013 08:29:03 +0100 Subject: [PATCH 35/48] clean up --- openlp/core/ui/shortcutlistform.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openlp/core/ui/shortcutlistform.py b/openlp/core/ui/shortcutlistform.py index 718b7193e..3b8a5f107 100644 --- a/openlp/core/ui/shortcutlistform.py +++ b/openlp/core/ui/shortcutlistform.py @@ -97,8 +97,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): self.dialog_was_shown = False return key = event.key() - if key == QtCore.Qt.Key_Shift or key == QtCore.Qt.Key_Control or \ - key == QtCore.Qt.Key_Meta or key == QtCore.Qt.Key_Alt: + if key in (QtCore.Qt.Key_Shift, QtCore.Qt.Key_Control, QtCore.Qt.Key_Meta, QtCore.Qt.Key_Alt): return key_string = QtGui.QKeySequence(key).toString() if event.modifiers() & QtCore.Qt.ControlModifier == QtCore.Qt.ControlModifier: From 477f5cefd0f5435e210c22019c24d9b6ed3df56e Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 20 Feb 2013 08:35:55 +0100 Subject: [PATCH 36/48] renamed actions --- .../openlp_core_utils/test_actions.py | 76 +++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/tests/functional/openlp_core_utils/test_actions.py b/tests/functional/openlp_core_utils/test_actions.py index 7b03493ba..83ed8af92 100644 --- a/tests/functional/openlp_core_utils/test_actions.py +++ b/tests/functional/openlp_core_utils/test_actions.py @@ -37,27 +37,27 @@ class TestActionList(TestCase): """ # GIVEN: Two actions with the same shortcuts. parent = QtCore.QObject() - action = QtGui.QAction(parent) - action.setObjectName(u'action') - action_with_same_shortcuts = QtGui.QAction(parent) - action_with_same_shortcuts.setObjectName(u'action_with_same_shortcuts') + 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/action': [QtGui.QKeySequence(u'v'), QtGui.QKeySequence(u'c')], - u'shortcuts/action_with_same_shortcuts': [QtGui.QKeySequence(u'v'), QtGui.QKeySequence(u'c')] + 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(action, u'example_category') - self.action_list.add_action(action_with_same_shortcuts, u'example_category') + 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(action, u'example_category') - self.action_list.remove_action(action_with_same_shortcuts, u'example_category') + 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(action.shortcuts()) == 2, u'The action should have two shortcut assigned.' - assert len(action_with_same_shortcuts.shortcuts()) == 0, u'The action should not have a shortcut assigned.' + 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): """ @@ -66,28 +66,28 @@ class TestActionList(TestCase): """ # GIVEN: Two actions with the same shortcuts. parent = QtCore.QObject() - action = QtGui.QAction(parent) - action.setObjectName(u'action2') + action2 = QtGui.QAction(parent) + action2.setObjectName(u'action2') second_parent = QtCore.QObject() - action_with_same_shortcuts = QtGui.QAction(second_parent) - action_with_same_shortcuts.setObjectName(u'action_with_same_shortcuts2') + 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'v'), QtGui.QKeySequence(u'c')], - u'shortcuts/action_with_same_shortcuts2': [QtGui.QKeySequence(u'v'), QtGui.QKeySequence(u'c')] + 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(action, u'example_category') - self.action_list.add_action(action_with_same_shortcuts, u'example_category') + 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(action, u'example_category') - self.action_list.remove_action(action_with_same_shortcuts, u'example_category') + 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(action.shortcuts()) == 2, u'The action should have two shortcut assigned.' - assert len(action_with_same_shortcuts.shortcuts()) == 0, u'The action should not have a shortcut assigned.' + 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): """ @@ -96,29 +96,29 @@ class TestActionList(TestCase): """ # GIVEN: Two actions with the same shortcuts. parent = QtCore.QObject() - action = QtGui.QAction(parent) - action.setObjectName(u'action3') - action.setShortcutContext(QtCore.Qt.WidgetShortcut) + action3 = QtGui.QAction(parent) + action3.setObjectName(u'action3') + action3.setShortcutContext(QtCore.Qt.WidgetShortcut) second_parent = QtCore.QObject() - action_with_same_shortcuts = QtGui.QAction(second_parent) - action_with_same_shortcuts.setObjectName(u'action_with_same_shortcuts3') - action_with_same_shortcuts.setShortcutContext(QtCore.Qt.WidgetShortcut) + 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'1'), QtGui.QKeySequence(u'2')], - u'shortcuts/action_with_same_shortcuts3': [QtGui.QKeySequence(u'1'), QtGui.QKeySequence(u'2')] + 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(action, u'example_category2') - self.action_list.add_action(action_with_same_shortcuts, u'example_category2') + 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(action, u'example_category2') - self.action_list.remove_action(action_with_same_shortcuts, u'example_category2') + 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(action.shortcuts()) == 2, u'The action should have two shortcut assigned.' - assert len(action_with_same_shortcuts.shortcuts()) == 2, u'The action should have two shortcuts assigned.' + 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.' From cfc1b5f84db16705772f7082463d3295bc2f14c8 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 20 Feb 2013 09:15:34 +0100 Subject: [PATCH 37/48] sorted entries; fix --- openlp/core/lib/settings.py | 87 +++++++++++++++++------------------- openlp/core/utils/actions.py | 2 +- 2 files changed, 43 insertions(+), 46 deletions(-) diff --git a/openlp/core/lib/settings.py b/openlp/core/lib/settings.py index e8d0c53c3..b1d0fad16 100644 --- a/openlp/core/lib/settings.py +++ b/openlp/core/lib/settings.py @@ -172,6 +172,48 @@ class Settings(QtCore.QSettings): u'shortcuts/goLive': [], u'shortcuts/importThemeItem': [], 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/modeLiveItem': [], @@ -242,51 +284,6 @@ class Settings(QtCore.QSettings): u'shortcuts/viewLivePanel': [QtGui.QKeySequence(u'F12')], u'shortcuts/viewServiceManagerItem': [QtGui.QKeySequence(u'F9')], u'shortcuts/webSiteItem': [], - - # FIXME: To be sorted. - 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/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/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/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/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'themes/global theme': u'', u'themes/last directory': u'', u'themes/last directory export': u'', diff --git a/openlp/core/utils/actions.py b/openlp/core/utils/actions.py index c131fbc88..922aa7767 100644 --- a/openlp/core/utils/actions.py +++ b/openlp/core/utils/actions.py @@ -411,7 +411,7 @@ class ActionList(object): for existing_action in existing_actions: if action is existing_action: continue - if global_context or existing_action in affected_actions: + if not global_context or existing_action in affected_actions: return False if existing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]: return False From c8a84969ccb7498ca006adae90399fc0bd69ad69 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 20 Feb 2013 10:03:53 +0100 Subject: [PATCH 38/48] fixed log verbosity --- openlp/core/ui/media/vlcplayer.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openlp/core/ui/media/vlcplayer.py b/openlp/core/ui/media/vlcplayer.py index 6d5a45549..2d3fdcd39 100644 --- a/openlp/core/ui/media/vlcplayer.py +++ b/openlp/core/ui/media/vlcplayer.py @@ -125,7 +125,6 @@ class VlcPlayer(MediaPlayer): if Settings().value(u'advanced/hide mouse') and display.controller.isLive: command_line_options += u' --mouse-hide-timeout=0' display.vlcInstance = vlc.Instance(command_line_options) - display.vlcInstance.set_log_verbosity(2) # creating an empty vlc media player display.vlcMediaPlayer = display.vlcInstance.media_player_new() display.vlcWidget.resize(display.size()) From 3da378a7b7f75bfa9ad819f595ce7448b3ffd685 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Thu, 21 Feb 2013 07:33:21 +0000 Subject: [PATCH 39/48] Fixes --- tests/functional/openlp_core_lib/test_settings.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/functional/openlp_core_lib/test_settings.py b/tests/functional/openlp_core_lib/test_settings.py index 09e65a1e4..827bfa156 100644 --- a/tests/functional/openlp_core_lib/test_settings.py +++ b/tests/functional/openlp_core_lib/test_settings.py @@ -2,15 +2,12 @@ Package to test the openlp.core.lib.settings package. """ import os - from unittest import TestCase from tempfile import mkstemp from openlp.core.lib import Settings -from PyQt4 import QtGui, QtTest - -TESTPATH = os.path.abspath(os.path.join(os.path.dirname(__file__), u'..', u'..', u'resources')) +from PyQt4 import QtGui class TestSettings(TestCase): @@ -22,8 +19,6 @@ class TestSettings(TestCase): fd, self.ini_file = mkstemp(u'.ini') Settings().set_filename(self.ini_file) self.application = QtGui.QApplication.instance() - self.application.setOrganizationName(u'OpenLP-tests') - self.application.setOrganizationDomain(u'openlp.org') def tearDown(self): """ From 31f28a757075b5b8372abeeba1b4df8d2bd749cc Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 24 Feb 2013 19:13:50 +0100 Subject: [PATCH 40/48] fixed same short lines --- openlp/core/ui/slidecontroller.py | 14 +- openlp/plugins/songs/forms/editsongform.py | 14 +- openlp/plugins/songs/forms/editversedialog.py | 14 +- openlp/plugins/songs/forms/editverseform.py | 17 +-- openlp/plugins/songs/lib/__init__.py | 90 ++++++------- openlp/plugins/songs/lib/cclifileimport.py | 30 ++--- openlp/plugins/songs/lib/easyslidesimport.py | 12 +- openlp/plugins/songs/lib/ewimport.py | 24 ++-- .../plugins/songs/lib/foilpresenterimport.py | 36 +++--- openlp/plugins/songs/lib/mediaitem.py | 4 +- openlp/plugins/songs/lib/opensongimport.py | 19 ++- openlp/plugins/songs/lib/songbeamerimport.py | 58 ++++----- openlp/plugins/songs/lib/songimport.py | 6 +- .../plugins/songs/lib/songshowplusimport.py | 16 +-- openlp/plugins/songs/lib/sundayplusimport.py | 11 +- openlp/plugins/songs/lib/xml.py | 121 +++++++----------- 16 files changed, 216 insertions(+), 270 deletions(-) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 84ea296d2..17c2e60fb 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -404,19 +404,19 @@ class SlideController(DisplayController): verse_type = sender_name[15:] if sender_name[:15] == u'shortcutAction_' else u'' if SONGS_PLUGIN_AVAILABLE: if verse_type == u'V': - self.current_shortcut = VerseType.TranslatedTags[VerseType.Verse] + self.current_shortcut = VerseType.translated_tags[VerseType.Verse] elif verse_type == u'C': - self.current_shortcut = VerseType.TranslatedTags[VerseType.Chorus] + self.current_shortcut = VerseType.translated_tags[VerseType.Chorus] elif verse_type == u'B': - self.current_shortcut = VerseType.TranslatedTags[VerseType.Bridge] + self.current_shortcut = VerseType.translated_tags[VerseType.Bridge] elif verse_type == u'P': - self.current_shortcut = VerseType.TranslatedTags[VerseType.PreChorus] + self.current_shortcut = VerseType.translated_tags[VerseType.PreChorus] elif verse_type == u'I': - self.current_shortcut = VerseType.TranslatedTags[VerseType.Intro] + self.current_shortcut = VerseType.translated_tags[VerseType.Intro] elif verse_type == u'E': - self.current_shortcut = VerseType.TranslatedTags[VerseType.Ending] + self.current_shortcut = VerseType.translated_tags[VerseType.Ending] elif verse_type == u'O': - self.current_shortcut = VerseType.TranslatedTags[VerseType.Other] + self.current_shortcut = VerseType.translated_tags[VerseType.Other] elif verse_type.isnumeric(): self.current_shortcut += verse_type self.current_shortcut = self.current_shortcut.upper() diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index f77f8d18e..501ee7eea 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -291,7 +291,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): verse_tags_translated = True if index is None: 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'': verse[0][u'label'] = u'1' 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): self.verseListWidget.setRowCount(self.verseListWidget.rowCount() + 1) 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) self.verseListWidget.setItem(count, 0, item) 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) if verse_index is None: 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:])) self.verseOrderEdit.setText(u' '.join(translated)) else: @@ -547,7 +547,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): verse_name = parts verse_num = u'1' 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. #regex = re.compile(r'(\d+\w.)') regex = re.compile(r'\D*(\d+)\D*') @@ -599,7 +599,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): if len(item) == 1: verse_index = VerseType.from_translated_tag(item, None) if verse_index is not None: - order.append(VerseType.Tags[verse_index] + u'1') + order.append(VerseType.tags[verse_index] + u'1') else: # it matches no verses anyway order.append(u'') @@ -609,7 +609,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): # it matches no verses anyway order.append(u'') else: - verse_tag = VerseType.Tags[verse_index] + verse_tag = VerseType.tags[verse_index] verse_num = item[1:].lower() order.append(verse_tag + verse_num) return order @@ -831,7 +831,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): ordertext = self.verseOrderEdit.text() order = [] 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() order.append(u'%s%s' % (verse_tag, verse_num)) self.song.verse_order = u' '.join(order) diff --git a/openlp/plugins/songs/forms/editversedialog.py b/openlp/plugins/songs/forms/editversedialog.py index e97a898f7..b694d046c 100644 --- a/openlp/plugins/songs/forms/editversedialog.py +++ b/openlp/plugins/songs/forms/editversedialog.py @@ -74,13 +74,13 @@ class Ui_EditVerseDialog(object): def retranslateUi(self, editVerseDialog): editVerseDialog.setWindowTitle(translate('SongsPlugin.EditVerseForm', 'Edit Verse')) self.verseTypeLabel.setText(translate('SongsPlugin.EditVerseForm', '&Verse type:')) - self.verseTypeComboBox.setItemText(VerseType.Verse, VerseType.TranslatedNames[VerseType.Verse]) - self.verseTypeComboBox.setItemText(VerseType.Chorus, VerseType.TranslatedNames[VerseType.Chorus]) - self.verseTypeComboBox.setItemText(VerseType.Bridge, VerseType.TranslatedNames[VerseType.Bridge]) - self.verseTypeComboBox.setItemText(VerseType.PreChorus, VerseType.TranslatedNames[VerseType.PreChorus]) - self.verseTypeComboBox.setItemText(VerseType.Intro, VerseType.TranslatedNames[VerseType.Intro]) - self.verseTypeComboBox.setItemText(VerseType.Ending, VerseType.TranslatedNames[VerseType.Ending]) - self.verseTypeComboBox.setItemText(VerseType.Other, VerseType.TranslatedNames[VerseType.Other]) + self.verseTypeComboBox.setItemText(VerseType.Verse, VerseType.translated_names[VerseType.Verse]) + self.verseTypeComboBox.setItemText(VerseType.Chorus, VerseType.translated_names[VerseType.Chorus]) + self.verseTypeComboBox.setItemText(VerseType.Bridge, VerseType.translated_names[VerseType.Bridge]) + self.verseTypeComboBox.setItemText(VerseType.PreChorus, VerseType.translated_names[VerseType.PreChorus]) + self.verseTypeComboBox.setItemText(VerseType.Intro, VerseType.translated_names[VerseType.Intro]) + self.verseTypeComboBox.setItemText(VerseType.Ending, VerseType.translated_names[VerseType.Ending]) + self.verseTypeComboBox.setItemText(VerseType.Other, VerseType.translated_names[VerseType.Other]) self.splitButton.setText(UiStrings().Split) self.splitButton.setToolTip(UiStrings().SplitToolTip) self.insertButton.setText(translate('SongsPlugin.EditVerseForm', '&Insert')) diff --git a/openlp/plugins/songs/forms/editverseform.py b/openlp/plugins/songs/forms/editverseform.py index 6e5c0127e..046c35c8b 100644 --- a/openlp/plugins/songs/forms/editverseform.py +++ b/openlp/plugins/songs/forms/editverseform.py @@ -82,8 +82,7 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog): def onInsertButtonClicked(self): verse_type_index = self.verseTypeComboBox.currentIndex() - self.insertVerse(VerseType.Tags[verse_type_index], - self.verseNumberBox.value()) + self.insertVerse(VerseType.tags[verse_type_index], self.verseNumberBox.value()) def onVerseTypeComboBoxChanged(self): self.updateSuggestedVerseNumber() @@ -93,12 +92,11 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog): def updateSuggestedVerseNumber(self): """ - Adjusts the verse number SpinBox in regard to the selected verse type - and the cursor's position. + Adjusts the verse number SpinBox in regard to the selected verse type and the cursor's position. """ position = self.verseTextEdit.textCursor().position() text = self.verseTextEdit.toPlainText() - verse_name = VerseType.TranslatedNames[ + verse_name = VerseType.translated_names[ self.verseTypeComboBox.currentIndex()] if not text: return @@ -120,8 +118,7 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog): verse_num = 1 self.verseNumberBox.setValue(verse_num) - def setVerse(self, text, single=False, - tag=u'%s1' % VerseType.Tags[VerseType.Verse]): + def setVerse(self, text, single=False, tag=u'%s1' % VerseType.tags[VerseType.Verse]): self.hasSingleVerse = single if single: verse_type_index = VerseType.from_tag(tag[0], None) @@ -132,7 +129,7 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog): self.insertButton.setVisible(False) else: 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.verseNumberBox.setValue(1) self.insertButton.setVisible(True) @@ -141,12 +138,12 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog): self.verseTextEdit.moveCursor(QtGui.QTextCursor.End) 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()) def getVerseAll(self): text = self.verseTextEdit.toPlainText() 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 diff --git a/openlp/plugins/songs/lib/__init__.py b/openlp/plugins/songs/lib/__init__.py index c7c24533b..93342c617 100644 --- a/openlp/plugins/songs/lib/__init__.py +++ b/openlp/plugins/songs/lib/__init__.py @@ -37,8 +37,7 @@ from ui import SongStrings WHITESPACE = re.compile(r'[\W_]+', re.UNICODE) APOSTROPHE = re.compile(u'[\'`’ʻ′]', re.UNICODE) -PATTERN = re.compile(r"\\([a-z]{1,32})(-?\d{1,10})?[ ]?|\\'" - r"([0-9a-f]{2})|\\([^a-z])|([{}])|[\r\n]+|(.)", re.I) +PATTERN = re.compile(r"\\([a-z]{1,32})(-?\d{1,10})?[ ]?|\\'([0-9a-f]{2})|\\([^a-z])|([{}])|[\r\n]+|(.)", re.I) # RTF control words which specify a "destination" to be ignored. DESTINATIONS = frozenset(( u'aftncn', u'aftnsep', u'aftnsepc', u'annotation', u'atnauthor', @@ -138,8 +137,7 @@ CHARSET_MAPPING = { class VerseType(object): """ - VerseType provides an enumeration for the tags that may be associated - with verses in songs. + VerseType provides an enumeration for the tags that may be associated with verses in songs. """ Verse = 0 Chorus = 1 @@ -149,7 +147,7 @@ class VerseType(object): Ending = 5 Other = 6 - Names = [ + names = [ u'Verse', u'Chorus', u'Bridge', @@ -157,9 +155,9 @@ class VerseType(object): u'Intro', u'Ending', 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', 'Chorus'), translate('SongsPlugin.VerseType', 'Bridge'), @@ -167,13 +165,12 @@ class VerseType(object): translate('SongsPlugin.VerseType', 'Intro'), translate('SongsPlugin.VerseType', 'Ending'), translate('SongsPlugin.VerseType', 'Other')] - TranslatedTags = [name[0].lower() for name in TranslatedNames] + tanslated_tags = [name[0].lower() for name in translated_names] @staticmethod def translated_tag(verse_tag, default=Other): """ - Return the translated UPPERCASE tag for a given tag, - used to show translated verse tags in UI + Return the translated UPPERCASE tag for a given tag, used to show translated verse tags in UI ``verse_tag`` The string to return a VerseType for @@ -182,11 +179,11 @@ class VerseType(object): Default return value if no matching tag is found """ verse_tag = verse_tag[0].lower() - for num, tag in enumerate(VerseType.Tags): + for num, tag in enumerate(VerseType.tags): if verse_tag == tag: - return VerseType.TranslatedTags[num].upper() - if default in VerseType.TranslatedTags: - return VerseType.TranslatedTags[default].upper() + return VerseType.tanslated_tags[num].upper() + if default in VerseType.tanslated_tags: + return VerseType.tanslated_tags[default].upper() @staticmethod def translated_name(verse_tag, default=Other): @@ -200,11 +197,11 @@ class VerseType(object): Default return value if no matching tag is found """ verse_tag = verse_tag[0].lower() - for num, tag in enumerate(VerseType.Tags): + for num, tag in enumerate(VerseType.tags): if verse_tag == tag: - return VerseType.TranslatedNames[num] - if default in VerseType.TranslatedNames: - return VerseType.TranslatedNames[default] + return VerseType.translated_names[num] + if default in VerseType.translated_names: + return VerseType.translated_names[default] @staticmethod def from_tag(verse_tag, default=Other): @@ -218,7 +215,7 @@ class VerseType(object): Default return value if no matching tag is found """ verse_tag = verse_tag[0].lower() - for num, tag in enumerate(VerseType.Tags): + for num, tag in enumerate(VerseType.tags): if verse_tag == tag: return num return default @@ -235,7 +232,7 @@ class VerseType(object): Default return value if no matching tag is found """ 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: return num return default @@ -252,7 +249,7 @@ class VerseType(object): Default return value if no matching tag is found """ verse_name = verse_name.lower() - for num, name in enumerate(VerseType.Names): + for num, name in enumerate(VerseType.names): if verse_name == name.lower(): return num return default @@ -266,7 +263,7 @@ class VerseType(object): The string to return a VerseType for """ 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(): return num @@ -296,13 +293,11 @@ class VerseType(object): def retrieve_windows_encoding(recommendation=None): """ - Determines which encoding to use on an information source. The process uses - both automated detection, which is passed to this method as a - recommendation, and user confirmation to return an encoding. + Determines which encoding to use on an information source. The process uses both automated detection, which is + passed to this method as a recommendation, and user confirmation to return an encoding. ``recommendation`` - A recommended encoding discovered programmatically for the user to - confirm. + A recommended encoding discovered programmatically for the user to confirm. """ # map chardet result to compatible windows standard code page codepage_mapping = {'IBM866': u'cp866', 'TIS-620': u'cp874', @@ -355,24 +350,22 @@ def retrieve_windows_encoding(recommendation=None): 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() def clean_title(title): """ - Cleans the song title by removing Unicode control chars groups C0 & C1, - as well as any trailing spaces + Cleans the song title by removing Unicode control chars groups C0 & C1, as well as any trailing spaces. """ return CONTROL_CHARS.sub(u'', title).rstrip() def clean_song(manager, song): """ - Cleans the search title, rebuilds the search lyrics, adds a default author - if the song does not have one and other clean ups. This should always - called when a new song is added or changed. + Cleans the search title, rebuilds the search lyrics, adds a default author if the song does not have one and other + clean ups. This should always called when a new song is added or changed. ``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) # Only do this, if we the song is a 1.9.4 song (or older). if song.lyrics.find(u'') != -1: - # Remove the old "language" attribute from lyrics tag (prior to 1.9.5). - # This is not very important, but this keeps the database clean. This - # can be removed when everybody has cleaned his songs. + # Remove the old "language" attribute from lyrics tag (prior to 1.9.5). This is not very important, but this + # keeps the database clean. This can be removed when everybody has cleaned his songs. song.lyrics = song.lyrics.replace(u'', u'') verses = SongXML().get_verses(song.lyrics) song.search_lyrics = u' '.join([clean_string(verse[1]) for verse in verses]) # We need a new and clean SongXML instance. sxml = SongXML() - # Rebuild the song's verses, to remove any wrong verse names (for - # example translated ones), which might have been added prior to 1.9.5. + # Rebuild the song's verses, to remove any wrong verse names (for example translated ones), which might have + # been added prior to 1.9.5. # List for later comparison. compare_order = [] 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( verse_type, verse[0][u'label'], @@ -422,15 +414,14 @@ def clean_song(manager, song): if verse[0][u'label'] == u'1': compare_order.append(verse_type.upper()) song.lyrics = unicode(sxml.extract_xml(), u'utf-8') - # Rebuild the verse order, to convert translated verse tags, which might - # have been added prior to 1.9.5. + # Rebuild the verse order, to convert translated verse tags, which might have been added prior to 1.9.5. if song.verse_order: order = CONTROL_CHARS.sub(u'', song.verse_order).strip().split() else: order = [] new_order = [] for verse_def in order: - verse_type = VerseType.Tags[ + verse_type = VerseType.tags[ VerseType.from_loose_input(verse_def[0])] if len(verse_def) > 1: new_order.append((u'%s%s' % (verse_type, verse_def[1:])).upper()) @@ -463,16 +454,16 @@ def get_encoding(font, font_table, default_encoding, failed=False): Finds an encoding to use. Asks user, if necessary. ``font`` - The number of currently active font. + The number of currently active font. ``font_table`` - Dictionary of fonts and respective encodings. + Dictionary of fonts and respective encodings. ``default_encoding`` - The default encoding to use when font_table is empty or no font is used. + The default encoding to use when font_table is empty or no font is used. ``failed`` - A boolean indicating whether the previous encoding didn't work. + A boolean indicating whether the previous encoding didn't work. """ encoding = None if font in font_table: @@ -494,10 +485,10 @@ def strip_rtf(text, default_encoding=None): http://stackoverflow.com/questions/188545 ``text`` - RTF-encoded text, a string. + RTF-encoded text, a string. ``default_encoding`` - Default encoding to use when no encoding is specified. + Default encoding to use when no encoding is specified. """ # Current font is the font tag we last met. font = u'' @@ -589,8 +580,7 @@ def strip_rtf(text, default_encoding=None): def natcmp(a, b): """ - Natural string comparison which mimics the behaviour of Python's internal - cmp function. + Natural string comparison which mimics the behaviour of Python's internal cmp function. """ if len(a) <= len(b): for i, key in enumerate(a): diff --git a/openlp/plugins/songs/lib/cclifileimport.py b/openlp/plugins/songs/lib/cclifileimport.py index d4ad0493a..e58903b49 100644 --- a/openlp/plugins/songs/lib/cclifileimport.py +++ b/openlp/plugins/songs/lib/cclifileimport.py @@ -188,13 +188,13 @@ class CCLIFileImport(SongImport): words_list = song_words.split(u'/t') for counter in range(len(field_list)): 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'): - verse_type = VerseType.Tags[VerseType.Chorus] + verse_type = VerseType.tags[VerseType.Chorus] elif field_list[counter].startswith(u'Br'): - verse_type = VerseType.Tags[VerseType.Bridge] + verse_type = VerseType.tags[VerseType.Bridge] else: - verse_type = VerseType.Tags[VerseType.Other] + verse_type = VerseType.tags[VerseType.Other] check_first_verse_line = True verse_text = unicode(words_list[counter]) verse_text = verse_text.replace(u'/n', u'\n') @@ -202,15 +202,15 @@ class CCLIFileImport(SongImport): verse_lines = verse_text.split(u'\n', 1) if check_first_verse_line: 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]) verse_text = verse_lines[1] 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') verse_text = verse_lines[1] elif verse_lines[0].startswith(u'('): - verse_type = VerseType.Tags[VerseType.Other] + verse_type = VerseType.tags[VerseType.Other] verse_text = verse_lines[1] if verse_text: self.addVerse(verse_text, verse_type) @@ -292,31 +292,31 @@ class CCLIFileImport(SongImport): verse_desc_parts = clean_line.split(u' ') if len(verse_desc_parts) == 2: 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'): - verse_type = VerseType.Tags[VerseType.Chorus] + verse_type = VerseType.tags[VerseType.Chorus] elif verse_desc_parts[0].startswith(u'Br'): - verse_type = VerseType.Tags[VerseType.Bridge] + verse_type = VerseType.tags[VerseType.Bridge] else: # we need to analyse the next line for # verse type, so set flag - verse_type = VerseType.Tags[VerseType.Other] + verse_type = VerseType.tags[VerseType.Other] check_first_verse_line = True verse_number = verse_desc_parts[1] else: - verse_type = VerseType.Tags[VerseType.Other] + verse_type = VerseType.tags[VerseType.Other] verse_number = 1 verse_start = True else: # check first line for verse type if check_first_verse_line: if line.startswith(u'(PRE-CHORUS'): - verse_type = VerseType.Tags[VerseType.PreChorus] + verse_type = VerseType.tags[VerseType.PreChorus] elif line.startswith(u'(BRIDGE'): - verse_type = VerseType.Tags[VerseType.Bridge] + verse_type = VerseType.tags[VerseType.Bridge] # Handle all other misc types elif line.startswith(u'('): - verse_type = VerseType.Tags[VerseType.Other] + verse_type = VerseType.tags[VerseType.Other] else: verse_text = verse_text + line check_first_verse_line = False diff --git a/openlp/plugins/songs/lib/easyslidesimport.py b/openlp/plugins/songs/lib/easyslidesimport.py index 36ffbeb63..e45edfcb0 100644 --- a/openlp/plugins/songs/lib/easyslidesimport.py +++ b/openlp/plugins/songs/lib/easyslidesimport.py @@ -175,12 +175,12 @@ class EasySlidesImport(SongImport): # if the regions are inside verses regionsInVerses = (regions and regionlines[regionlines.keys()[0]] > 1) MarkTypes = { - u'CHORUS': VerseType.Tags[VerseType.Chorus], - u'VERSE': VerseType.Tags[VerseType.Verse], - u'INTRO': VerseType.Tags[VerseType.Intro], - u'ENDING': VerseType.Tags[VerseType.Ending], - u'BRIDGE': VerseType.Tags[VerseType.Bridge], - u'PRECHORUS': VerseType.Tags[VerseType.PreChorus] + u'CHORUS': VerseType.tags[VerseType.Chorus], + u'VERSE': VerseType.tags[VerseType.Verse], + u'INTRO': VerseType.tags[VerseType.Intro], + u'ENDING': VerseType.tags[VerseType.Ending], + u'BRIDGE': VerseType.tags[VerseType.Bridge], + u'PRECHORUS': VerseType.tags[VerseType.PreChorus] } verses = {} # list as [region, versetype, versenum, instance] diff --git a/openlp/plugins/songs/lib/ewimport.py b/openlp/plugins/songs/lib/ewimport.py index 8a344c189..fbeac0449 100644 --- a/openlp/plugins/songs/lib/ewimport.py +++ b/openlp/plugins/songs/lib/ewimport.py @@ -178,7 +178,7 @@ class EasyWorshipSongImport(SongImport): if result is None: return words, self.encoding = result - verse_type = VerseType.Tags[VerseType.Verse] + verse_type = VerseType.tags[VerseType.Verse] for verse in SLIDE_BREAK_REGEX.split(words): verse = verse.strip() if not verse: @@ -187,17 +187,17 @@ class EasyWorshipSongImport(SongImport): first_line_is_tag = False # EW tags: verse, chorus, pre-chorus, bridge, tag, # intro, ending, slide - for type in VerseType.Names+[u'tag', u'slide']: - type = type.lower() + for tag in VerseType.tags + [u'tag', u'slide']: + tag = tag.lower() ew_tag = verse_split[0].strip().lower() - if ew_tag.startswith(type): - verse_type = type[0] - if type == u'tag' or type == u'slide': - verse_type = VerseType.Tags[VerseType.Other] + if ew_tag.startswith(tag): + verse_type = tag[0] + if tag == u'tag' or tag == u'slide': + verse_type = VerseType.tags[VerseType.Other] first_line_is_tag = True number_found = False # 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) if match: number = match.group() @@ -209,10 +209,7 @@ class EasyWorshipSongImport(SongImport): if not number_found: verse_type += u'1' break - self.addVerse( - verse_split[-1].strip() \ - if first_line_is_tag else verse, - verse_type) + self.addVerse(verse_split[-1].strip() if first_line_is_tag else verse, verse_type) if len(self.comments) > 5: self.comments += unicode(translate('SongsPlugin.EasyWorshipSongImport', '\n[above are Song Tags with notes imported from EasyWorship]')) @@ -224,8 +221,7 @@ class EasyWorshipSongImport(SongImport): self.memoFile.close() def findField(self, field_name): - return [i for i, x in enumerate(self.fieldDescs) - if x.name == field_name][0] + return [i for i, x in enumerate(self.fieldDescs) if x.name == field_name][0] def setRecordStruct(self, field_descs): # Begin with empty field struct list diff --git a/openlp/plugins/songs/lib/foilpresenterimport.py b/openlp/plugins/songs/lib/foilpresenterimport.py index d6c232b54..474edf733 100644 --- a/openlp/plugins/songs/lib/foilpresenterimport.py +++ b/openlp/plugins/songs/lib/foilpresenterimport.py @@ -412,13 +412,13 @@ class FoilPresenter(object): temp_sortnr_backup = 1 temp_sortnr_liste = [] verse_count = { - VerseType.Tags[VerseType.Verse]: 1, - VerseType.Tags[VerseType.Chorus]: 1, - VerseType.Tags[VerseType.Bridge]: 1, - VerseType.Tags[VerseType.Ending]: 1, - VerseType.Tags[VerseType.Other]: 1, - VerseType.Tags[VerseType.Intro]: 1, - VerseType.Tags[VerseType.PreChorus]: 1 + VerseType.tags[VerseType.Verse]: 1, + VerseType.tags[VerseType.Chorus]: 1, + VerseType.tags[VerseType.Bridge]: 1, + VerseType.tags[VerseType.Ending]: 1, + VerseType.tags[VerseType.Other]: 1, + VerseType.tags[VerseType.Intro]: 1, + VerseType.tags[VerseType.PreChorus]: 1 } for strophe in foilpresenterfolie.strophen.strophe: 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 = temp_verse_name[:3].lower() if temp_verse_name == u'ref': - verse_type = VerseType.Tags[VerseType.Chorus] + verse_type = VerseType.tags[VerseType.Chorus] elif temp_verse_name == u'r': - verse_type = VerseType.Tags[VerseType.Chorus] + verse_type = VerseType.tags[VerseType.Chorus] elif temp_verse_name == u'': - verse_type = VerseType.Tags[VerseType.Verse] + verse_type = VerseType.tags[VerseType.Verse] elif temp_verse_name == u'v': - verse_type = VerseType.Tags[VerseType.Verse] + verse_type = VerseType.tags[VerseType.Verse] elif temp_verse_name == u'bri': - verse_type = VerseType.Tags[VerseType.Bridge] + verse_type = VerseType.tags[VerseType.Bridge] elif temp_verse_name == u'cod': - verse_type = VerseType.Tags[VerseType.Ending] + verse_type = VerseType.tags[VerseType.Ending] elif temp_verse_name == u'sch': - verse_type = VerseType.Tags[VerseType.Ending] + verse_type = VerseType.tags[VerseType.Ending] elif temp_verse_name == u'pre': - verse_type = VerseType.Tags[VerseType.PreChorus] + verse_type = VerseType.tags[VerseType.PreChorus] elif temp_verse_name == u'int': - verse_type = VerseType.Tags[VerseType.Intro] + verse_type = VerseType.tags[VerseType.Intro] 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) # Foilpresenter allows e. g. "C", but we need "C1". if not verse_number: @@ -469,7 +469,7 @@ class FoilPresenter(object): if value == u''.join((verse_type, verse_number)): verse_number = unicode(int(verse_number) + 1) 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], verse_number)) temp_verse_order_backup.append(u''.join((verse_type[0], diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 68820f861..da706bdcb 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -430,7 +430,7 @@ class SongMediaItem(MediaManagerItem): verse_index = VerseType.from_string(verse_tag, None) if verse_index is None: 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']) service_item.add_from_text(unicode(verse[1]), verse_def) else: @@ -445,7 +445,7 @@ class SongMediaItem(MediaManagerItem): verse_index = VerseType.from_translated_tag(verse[0][u'type']) else: 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']) service_item.add_from_text(verse[1], verse_def) else: diff --git a/openlp/plugins/songs/lib/opensongimport.py b/openlp/plugins/songs/lib/opensongimport.py index 9eda898ae..e961fdf44 100644 --- a/openlp/plugins/songs/lib/opensongimport.py +++ b/openlp/plugins/songs/lib/opensongimport.py @@ -160,7 +160,7 @@ class OpenSongImport(SongImport): # keep track of verses appearance order our_verse_order = [] # default verse - verse_tag = VerseType.Tags[VerseType.Verse] + verse_tag = VerseType.tags[VerseType.Verse] verse_num = u'1' # for the case where song has several sections with same marker inst = 1 @@ -184,21 +184,18 @@ class OpenSongImport(SongImport): # drop the square brackets right_bracket = this_line.find(u']') content = this_line[1:right_bracket].lower() - # have we got any digits? - # If so, verse number is everything from the digits - # to the end (openlp does not have concept of part verses, so - # just ignore any non integers on the end (including floats)) + # have we got any digits? If so, verse number is everything from the digits 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) if match is not None: verse_tag = match.group(1) verse_num = match.group(2) else: - # otherwise we assume number 1 and take the whole prefix as - # the verse tag + # otherwise we assume number 1 and take the whole prefix as the verse tag verse_tag = content verse_num = u'1' 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 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 @@ -236,8 +233,8 @@ class OpenSongImport(SongImport): # figure out the presentation order, if present if u'presentation' in fields and root.presentation: order = unicode(root.presentation) - # We make all the tags in the lyrics lower case, so match that here - # and then split into a list on the whitespace + # We make all the tags in the lyrics lower case, so match that here and then split into a list on the + # whitespace. order = order.lower().split() for verse_def in order: match = re.match(u'(\D*)(\d+.*)', verse_def) @@ -245,7 +242,7 @@ class OpenSongImport(SongImport): verse_tag = match.group(1) verse_num = match.group(2) if not verse_tag: - verse_tag = VerseType.Tags[VerseType.Verse] + verse_tag = VerseType.tags[VerseType.Verse] else: # Assume it's no.1 if there are no digits verse_tag = verse_def diff --git a/openlp/plugins/songs/lib/songbeamerimport.py b/openlp/plugins/songs/lib/songbeamerimport.py index 534b1d121..e9a9bac19 100644 --- a/openlp/plugins/songs/lib/songbeamerimport.py +++ b/openlp/plugins/songs/lib/songbeamerimport.py @@ -27,8 +27,7 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### """ -The :mod:`songbeamerimport` module provides the functionality for importing - SongBeamer songs into the OpenLP database. +The :mod:`songbeamerimport` module provides the functionality for importing SongBeamer songs into the OpenLP database. """ import chardet import codecs @@ -43,32 +42,31 @@ log = logging.getLogger(__name__) class SongBeamerTypes(object): MarkTypes = { - u'Refrain': VerseType.Tags[VerseType.Chorus], - u'Chorus': VerseType.Tags[VerseType.Chorus], - u'Vers': VerseType.Tags[VerseType.Verse], - u'Verse': VerseType.Tags[VerseType.Verse], - u'Strophe': VerseType.Tags[VerseType.Verse], - u'Intro': VerseType.Tags[VerseType.Intro], - u'Coda': VerseType.Tags[VerseType.Ending], - u'Ending': VerseType.Tags[VerseType.Ending], - u'Bridge': VerseType.Tags[VerseType.Bridge], - u'Interlude': VerseType.Tags[VerseType.Bridge], - u'Zwischenspiel': VerseType.Tags[VerseType.Bridge], - u'Pre-Chorus': VerseType.Tags[VerseType.PreChorus], - u'Pre-Refrain': VerseType.Tags[VerseType.PreChorus], - u'Pre-Bridge': VerseType.Tags[VerseType.Other], - u'Pre-Coda': VerseType.Tags[VerseType.Other], - u'Unbekannt': VerseType.Tags[VerseType.Other], - u'Unknown': VerseType.Tags[VerseType.Other], - u'Unbenannt': VerseType.Tags[VerseType.Other] + u'Refrain': VerseType.tags[VerseType.Chorus], + u'Chorus': VerseType.tags[VerseType.Chorus], + u'Vers': VerseType.tags[VerseType.Verse], + u'Verse': VerseType.tags[VerseType.Verse], + u'Strophe': VerseType.tags[VerseType.Verse], + u'Intro': VerseType.tags[VerseType.Intro], + u'Coda': VerseType.tags[VerseType.Ending], + u'Ending': VerseType.tags[VerseType.Ending], + u'Bridge': VerseType.tags[VerseType.Bridge], + u'Interlude': VerseType.tags[VerseType.Bridge], + u'Zwischenspiel': VerseType.tags[VerseType.Bridge], + u'Pre-Chorus': VerseType.tags[VerseType.PreChorus], + u'Pre-Refrain': VerseType.tags[VerseType.PreChorus], + u'Pre-Bridge': VerseType.tags[VerseType.Other], + u'Pre-Coda': VerseType.tags[VerseType.Other], + u'Unbekannt': VerseType.tags[VerseType.Other], + u'Unknown': VerseType.tags[VerseType.Other], + u'Unbenannt': VerseType.tags[VerseType.Other] } class SongBeamerImport(SongImport): """ - Import Song Beamer files(s) - Song Beamer file format is text based - in the beginning are one or more control tags written + Import Song Beamer files(s). Song Beamer file format is text based in the beginning are one or more control tags + written. """ HTML_TAG_PAIRS = [ (re.compile(u''), u'{st}'), @@ -113,7 +111,7 @@ class SongBeamerImport(SongImport): return self.setDefaults() self.currentVerse = u'' - self.currentVerseType = VerseType.Tags[VerseType.Verse] + self.currentVerseType = VerseType.tags[VerseType.Verse] read_verses = False file_name = os.path.split(file)[1] if os.path.isfile(file): @@ -137,7 +135,7 @@ class SongBeamerImport(SongImport): self.replaceHtmlTags() self.addVerse(self.currentVerse, self.currentVerseType) self.currentVerse = u'' - self.currentVerseType = VerseType.Tags[VerseType.Verse] + self.currentVerseType = VerseType.tags[VerseType.Verse] read_verses = True verse_start = True elif read_verses: @@ -155,8 +153,7 @@ class SongBeamerImport(SongImport): def replaceHtmlTags(self): """ - This can be called to replace SongBeamer's specific (html) tags with - OpenLP's specific (html) tags. + This can be called to replace SongBeamer's specific (html) tags with OpenLP's specific (html) tags. """ for pair in SongBeamerImport.HTML_TAG_PAIRS: self.currentVerse = pair[0].sub(pair[1], self.currentVerse) @@ -166,8 +163,7 @@ class SongBeamerImport(SongImport): Parses a meta data line. ``line`` - The line in the file. It should consist of a tag and a value - for this tag (unicode):: + The line in the file. It should consist of a tag and a value for this tag (unicode):: u'#Title=Nearer my God to Thee' """ @@ -272,8 +268,8 @@ class SongBeamerImport(SongImport): def checkVerseMarks(self, line): """ - Check and add the verse's MarkType. Returns ``True`` if the given line - contains a correct verse mark otherwise ``False``. + Check and add the verse's MarkType. Returns ``True`` if the given linE contains a correct verse mark otherwise + ``False``. ``line`` The line to check for marks (unicode). diff --git a/openlp/plugins/songs/lib/songimport.py b/openlp/plugins/songs/lib/songimport.py index f6a84945c..c4c9719fc 100644 --- a/openlp/plugins/songs/lib/songimport.py +++ b/openlp/plugins/songs/lib/songimport.py @@ -303,13 +303,13 @@ class SongImport(QtCore.QObject): sxml = SongXML() other_count = 1 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() 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 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) verse_def = new_verse_def sxml.add_verse_to_lyrics(verse_tag, verse_def[1:], verse_text, lang) diff --git a/openlp/plugins/songs/lib/songshowplusimport.py b/openlp/plugins/songs/lib/songshowplusimport.py index c5bb8832d..ae54ef726 100644 --- a/openlp/plugins/songs/lib/songshowplusimport.py +++ b/openlp/plugins/songs/lib/songshowplusimport.py @@ -152,11 +152,11 @@ class SongShowPlusImport(SongImport): elif block_key == CCLI_NO: self.ccliNumber = int(data) 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: - 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: - 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: self.topics.append(unicode(data, u'cp1252')) elif block_key == COMMENTS: @@ -192,19 +192,19 @@ class SongShowPlusImport(SongImport): verse_number = "1" verse_type = verse_type.lower() if verse_type == "verse": - verse_tag = VerseType.Tags[VerseType.Verse] + verse_tag = VerseType.tags[VerseType.Verse] elif verse_type == "chorus": - verse_tag = VerseType.Tags[VerseType.Chorus] + verse_tag = VerseType.tags[VerseType.Chorus] elif verse_type == "bridge": - verse_tag = VerseType.Tags[VerseType.Bridge] + verse_tag = VerseType.tags[VerseType.Bridge] elif verse_type == "pre-chorus": - verse_tag = VerseType.Tags[VerseType.PreChorus] + verse_tag = VerseType.tags[VerseType.PreChorus] else: if verse_name not in self.otherList: if ignore_unique: return None self.otherCount += 1 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] return verse_tag + verse_number diff --git a/openlp/plugins/songs/lib/sundayplusimport.py b/openlp/plugins/songs/lib/sundayplusimport.py index f773183b3..63d281e12 100644 --- a/openlp/plugins/songs/lib/sundayplusimport.py +++ b/openlp/plugins/songs/lib/sundayplusimport.py @@ -52,8 +52,7 @@ class SundayPlusImport(SongImport): """ 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 """ def __init__(self, manager, **kwargs): @@ -90,7 +89,7 @@ class SundayPlusImport(SongImport): self.logError(u'File is malformed') return False i = 1 - verse_type = VerseType.Tags[VerseType.Verse] + verse_type = VerseType.tags[VerseType.Verse] while i < len(data): # Data is held as #name: value pairs inside groups marked as []. # Now we are looking for the name. @@ -137,8 +136,7 @@ class SundayPlusImport(SongImport): if name == 'MARKER_NAME': value = value.strip() if len(value): - verse_type = VerseType.Tags[ - VerseType.from_loose_input(value[0])] + verse_type = VerseType.tags[VerseType.from_loose_input(value[0])] 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]) elif name == 'Hotkey': @@ -168,8 +166,7 @@ class SundayPlusImport(SongImport): self.copyright = u'Public Domain' continue processed_lines.append(line) - self.addVerse('\n'.join(processed_lines).strip(), - verse_type) + self.addVerse('\n'.join(processed_lines).strip(), verse_type) if end == -1: break i = end + 1 diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index 22a4d803f..8d6bbc032 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -97,10 +97,8 @@ class SongXML(object): Add a verse to the ```` tag. ``type`` - A string denoting the type of verse. Possible values are *v*, - *c*, *b*, *p*, *i*, *e* and *o*. - Any other type is **not** allowed, this also includes translated - types. + A string denoting the type of verse. Possible values are *v*, *c*, *b*, *p*, *i*, *e* and *o*. Any other + type is **not** allowed, this also includes translated types. ``number`` 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. ``lang`` - The verse's language code (ISO-639). This is not required, but - should be added if available. + The verse's language code (ISO-639). This is not required, but should be added if available. """ verse = etree.Element(u'verse', type=unicode(type), label=unicode(number)) @@ -128,24 +125,21 @@ class SongXML(object): def get_verses(self, xml): """ - Iterates through the verses in the XML and returns a list of verses - and their attributes. + Iterates through the verses in the XML and returns a list of verses and their attributes. ``xml`` The XML of the song to be parsed. The returned list has the following format:: - [[{'type': 'v', 'label': '1'}, - u"optional slide split 1[---]optional slide split 2"], + [[{'type': 'v', 'label': '1'}, u"optional slide split 1[---]optional slide split 2"], [{'lang': 'en', 'type': 'c', 'label': '1'}, u"English chorus"]] """ self.song_xml = None verse_list = [] if not xml.startswith(u'') self.lyrics = etree.SubElement(self.song_xml, u'lyrics') verses = xml.split(u'\n\n') @@ -176,11 +170,10 @@ class SongXML(object): class OpenLyrics(object): """ - This class represents the converter for OpenLyrics XML (version 0.8) - to/from a song. + This class represents the converter for OpenLyrics XML (version 0.8) to/from a song. - As OpenLyrics has a rich set of different features, we cannot support them - all. The following features are supported by the :class:`OpenLyrics` class: + As OpenLyrics has a rich set of different features, we cannot support them all. The following features are + supported by the :class:`OpenLyrics` class: ```` OpenLP does not support the attribute *type* and *lang*. @@ -189,8 +182,7 @@ class OpenLyrics(object): This property is not supported. ```` - The ```` property is fully supported. But comments in lyrics - are not supported. + The ```` property is fully supported. But comments in lyrics are not supported. ```` This property is fully supported. @@ -208,23 +200,20 @@ class OpenLyrics(object): This property is not supported. ```` - The attribute *part* is not supported. The *break* attribute is - supported. + The attribute *part* is not supported. The *break* attribute is supported. ```` This property is not supported. ```` - As OpenLP does only support one songbook, we cannot consider more than - one songbook. + As OpenLP does only support one songbook, we cannot consider more than one songbook. ```` This property is not supported. ```` - Topics, as they are called in OpenLP, are fully supported, whereby only - the topic text (e. g. Grace) is considered, but neither the *id* nor - *lang*. + Topics, as they are called in OpenLP, are fully supported, whereby only the topic text (e. g. Grace) is + considered, but neither the *id* nor *lang*. ```` This property is not supported. @@ -233,9 +222,8 @@ class OpenLyrics(object): This property is not supported. ```` - The attribute *translit* is not supported. Note, the attribute *lang* is - considered, but there is not further functionality implemented yet. The - following verse "types" are supported by OpenLP: + The attribute *translit* is not supported. Note, the attribute *lang* is considered, but there is not further + functionality implemented yet. The following verse "types" are supported by OpenLP: * v * c @@ -245,13 +233,10 @@ class OpenLyrics(object): * e * o - The verse "types" stand for *Verse*, *Chorus*, *Bridge*, *Pre-Chorus*, - *Intro*, *Ending* and *Other*. Any numeric value is allowed after the - verse type. The complete verse name in OpenLP always consists of the - verse type and the verse number. If not number is present *1* is - assumed. - OpenLP will merge verses which are split up by appending a letter to the - verse name, such as *v1a*. + The verse "types" stand for *Verse*, *Chorus*, *Bridge*, *Pre-Chorus*, *Intro*, *Ending* and *Other*. Any + numeric value is allowed after the verse type. The complete verse name in OpenLP always consists of the verse + type and the verse number. If not number is present *1* is assumed. OpenLP will merge verses which are split + up by appending a letter to the verse name, such as *v1a*. ```` OpenLP supports this property. @@ -359,17 +344,14 @@ class OpenLyrics(object): def _get_missing_tags(self, text): """ - Tests the given text for not closed formatting tags and returns a tuple - consisting of two unicode strings:: + Tests the given text for not closed formatting tags and returns a tuple consisting of two unicode strings:: (u'{st}{r}', u'{/r}{/st}') - The first unicode string are the start tags (for the next slide). The - second unicode string are the end tags. + The first unicode string are the start tags (for the next slide). The second unicode string are the end tags. ``text`` - The text to test. The text must **not** contain html tags, only - OpenLP formatting tags are allowed:: + The text to test. The text must **not** contain html tags, only OpenLP formatting tags are allowed:: {st}{r}Text text text """ @@ -379,9 +361,8 @@ class OpenLyrics(object): continue 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'])) - # Sort the lists, so that the tags which were opened first on the first - # slide (the text we are checking) will be opened first on the next - # slide as well. + # Sort the lists, so that the tags which were opened first on the first slide (the text we are checking) will + # be opened first on the next slide as well. tags.sort(key=lambda tag: tag[0]) end_tags = [] start_tags = [] @@ -393,16 +374,15 @@ class OpenLyrics(object): def xml_to_song(self, xml, parse_and_temporary_save=False): """ - Create and save a song from OpenLyrics format xml to the database. Since - we also export XML from external sources (e. g. OpenLyrics import), we - cannot ensure, that it completely conforms to the OpenLyrics standard. + Create and save a song from OpenLyrics format xml to the database. Since we also export XML from external + sources (e. g. OpenLyrics import), we cannot ensure, that it completely conforms to the OpenLyrics standard. ``xml`` The XML to parse (unicode). ``parse_and_temporary_save`` - Switch to skip processing the whole song and storing the songs in - the database with a temporary flag. Defaults to ``False``. + Switch to skip processing the whole song and storing the songs in the database with a temporary flag. + Defaults to ``False``. """ # No xml get out of here. if not xml: @@ -448,8 +428,7 @@ class OpenLyrics(object): def _add_tag_to_formatting(self, tag_name, tags_element): """ - Add new formatting tag to the element ```` if the tag is not - present yet. + Add new formatting tag to the element ```` if the tag is not present yet. """ available_tags = FormattingTags.get_html_tags() 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): """ - Convert text with formatting tags from OpenLP format to OpenLyrics - format and append it to element ````. + Convert text with formatting tags from OpenLP format to OpenLyrics format and append it to element ````. """ start_tags = OpenLyrics.START_TAGS_REGEX.findall(text) end_tags = OpenLyrics.END_TAGS_REGEX.findall(text) @@ -478,8 +456,7 @@ class OpenLyrics(object): for tag in start_tags: # Tags already converted to xml structure. xml_tags = tags_element.xpath(u'tag/attribute::name') - # Some formatting tag has only starting part e.g.
. - # Handle this case. + # Some formatting tag has only starting part e.g.
. Handle this case. if tag in end_tags: text = text.replace(u'{%s}' % tag, u'' % tag) else: @@ -586,8 +563,8 @@ class OpenLyrics(object): def _process_formatting_tags(self, song_xml, temporary): """ - Process the formatting tags from the song and either add missing tags - temporary or permanently to the formatting tag list. + Process the formatting tags from the song and either add missing tags temporary or permanently to the + formatting tag list. """ if not hasattr(song_xml, u'format'): return @@ -608,8 +585,8 @@ class OpenLyrics(object): u'end html': tag.close.text if hasattr(tag, 'close') else u'', u'protected': False, } - # Add 'temporary' key in case the formatting tag should not be - # saved otherwise it is supposed that formatting tag is permanent. + # Add 'temporary' key in case the formatting tag should not be saved otherwise it is supposed that + # formatting tag is permanent. if temporary: openlp_tag[u'temporary'] = temporary found_tags.append(openlp_tag) @@ -620,15 +597,14 @@ class OpenLyrics(object): def _process_lines_mixed_content(self, element, newlines=True): """ - Converts the xml text with mixed content to OpenLP representation. - Chords are skipped and formatting tags are converted. + Converts the xml text with mixed content to OpenLP representation. Chords are skipped and formatting tags are + converted. ``element`` The property object (lxml.etree.Element). ``newlines`` - The switch to enable/disable processing of line breaks
. - The
is used since OpenLyrics 0.8. + The switch to enable/disable processing of line breaks
. The
is used since OpenLyrics 0.8. """ text = u'' use_endtag = True @@ -684,12 +660,10 @@ class OpenLyrics(object): lines = etree.tostring(lines) element = etree.XML(lines) - # OpenLyrics 0.8 uses
for new lines. - # Append text from "lines" element to verse text. + # OpenLyrics 0.8 uses
for new lines. Append text from "lines" element to verse text. if version > '0.7': text = self._process_lines_mixed_content(element) - # OpenLyrics version <= 0.7 contais elements to represent lines. - # First child element is tested. + # OpenLyrics version <= 0.7 contais elements to represent lines. First child element is tested. else: # Loop over the "line" elements removing comments and chords. for line in element: @@ -742,16 +716,15 @@ class OpenLyrics(object): text += u'\n[---]' verse_def = verse.get(u'name', u' ').lower() verse_tag, verse_number, verse_part = OpenLyrics.VERSE_TAG_SPLITTER.search(verse_def).groups() - if verse_tag not in VerseType.Tags: - verse_tag = VerseType.Tags[VerseType.Other] - # OpenLyrics allows e. g. "c", but we need "c1". However, this does - # not correct the verse order. + if verse_tag not in VerseType.tags: + verse_tag = VerseType.tags[VerseType.Other] + # OpenLyrics allows e. g. "c", but we need "c1". However, this does not correct the verse order. if not verse_number: verse_number = u'1' lang = verse.get(u'lang') translit = verse.get(u'translit') - # In OpenLP 1.9.6 we used v1a, v1b ... to represent visual slide - # breaks. In OpenLyrics 0.7 an attribute has been added. + # In OpenLP 1.9.6 we used v1a, v1b ... to represent visual slide breaks. In OpenLyrics 0.7 an attribute has + # been added. 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: verses[(verse_tag, verse_number, lang, translit, None)] += u'\n[---]\n' + text From 00451ebfe08d95f629c4ec2480d9250c9acff926 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 27 Feb 2013 12:04:05 +0100 Subject: [PATCH 41/48] moved SettingsManager --- openlp/core/lib/__init__.py | 1 - openlp/core/ui/thememanager.py | 7 +++---- openlp/core/utils/__init__.py | 7 ++++--- openlp/core/{lib => utils}/settingsmanager.py | 0 openlp/plugins/bibles/lib/manager.py | 4 ++-- openlp/plugins/images/lib/mediaitem.py | 7 +++---- 6 files changed, 12 insertions(+), 14 deletions(-) rename openlp/core/{lib => utils}/settingsmanager.py (100%) diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index a3d9cec4b..3b531fdec 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -393,7 +393,6 @@ from settings import Settings from listwidgetwithdnd import ListWidgetWithDnD from formattingtags import FormattingTags from spelltextedit import SpellTextEdit -from settingsmanager import SettingsManager from plugin import PluginStatus, StringContent, Plugin from pluginmanager import PluginManager from settingstab import SettingsTab diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 96ebfa694..08ba44f96 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -38,14 +38,13 @@ import re from xml.etree.ElementTree import ElementTree, XML from PyQt4 import QtCore, QtGui -from openlp.core.lib import ImageSource, OpenLPToolbar, Registry, SettingsManager, Settings, UiStrings, \ - get_text_file_string, build_icon, translate, check_item_selected, check_directory_exists, create_thumb, \ - validate_thumb +from openlp.core.lib import ImageSource, OpenLPToolbar, Registry, Settings, UiStrings, get_text_file_string, \ + build_icon, translate, check_item_selected, check_directory_exists, create_thumb, validate_thumb 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.theme import Theme from openlp.core.ui import FileRenameForm, ThemeForm -from openlp.core.utils import AppLocation, delete_file, locale_compare, get_filesystem_encoding +from openlp.core.utils import AppLocation, SettingsManager, delete_file, locale_compare, get_filesystem_encoding log = logging.getLogger(__name__) diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 104567039..c529fe34d 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -499,7 +499,8 @@ locale_direct_compare = locale.strcoll from languagemanager import LanguageManager from actions import ActionList +from settingsmanager import SettingsManager -__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'delete_file', u'clean_filename', u'format_time', u'locale_compare', u'locale_direct_compare'] +__all__ = [u'AppLocation', u'ActionList', u'LanguageManager', u'SettingsManager', 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'delete_file', u'clean_filename', u'format_time', u'locale_compare', u'locale_direct_compare'] diff --git a/openlp/core/lib/settingsmanager.py b/openlp/core/utils/settingsmanager.py similarity index 100% rename from openlp/core/lib/settingsmanager.py rename to openlp/core/utils/settingsmanager.py diff --git a/openlp/plugins/bibles/lib/manager.py b/openlp/plugins/bibles/lib/manager.py index d82e46965..38b5ea9c7 100644 --- a/openlp/plugins/bibles/lib/manager.py +++ b/openlp/plugins/bibles/lib/manager.py @@ -30,8 +30,8 @@ import logging import os -from openlp.core.lib import Registry, SettingsManager, Settings, translate -from openlp.core.utils import AppLocation, delete_file +from openlp.core.lib import Registry, Settings, translate +from openlp.core.utils import AppLocation, SettingsManager, delete_file from openlp.plugins.bibles.lib import parse_reference, get_reference_separator, LanguageSelection from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta from csvbible import CSVBible diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index 2280120c1..7fe3088e4 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -32,11 +32,10 @@ import os from PyQt4 import QtCore, QtGui -from openlp.core.lib import MediaManagerItem, ItemCapabilities, Registry, SettingsManager, ServiceItemContext, \ - Settings, UiStrings, build_icon, check_item_selected, check_directory_exists, create_thumb, translate, \ - validate_thumb +from openlp.core.lib import MediaManagerItem, ItemCapabilities, Registry, ServiceItemContext, Settings, UiStrings, \ + build_icon, check_item_selected, check_directory_exists, create_thumb, translate, validate_thumb 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, SettingsManager, delete_file, locale_compare, get_images_filter log = logging.getLogger(__name__) From 4d1d912aaa86f2aa405c07999ed760207702bb4b Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 27 Feb 2013 12:24:50 +0100 Subject: [PATCH 42/48] merged settingsmanager with applocation; moved applocation --- openlp/core/ui/thememanager.py | 10 +- openlp/core/utils/__init__.py | 111 +---------- openlp/core/utils/applocation.py | 184 ++++++++++++++++++ openlp/core/utils/settingsmanager.py | 66 ------- openlp/plugins/bibles/lib/manager.py | 4 +- openlp/plugins/images/lib/mediaitem.py | 4 +- .../openlp_core_utils/test_applocation.py | 22 +-- 7 files changed, 209 insertions(+), 192 deletions(-) create mode 100644 openlp/core/utils/applocation.py delete mode 100644 openlp/core/utils/settingsmanager.py diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 08ba44f96..38074517e 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -44,7 +44,7 @@ from openlp.core.lib.theme import ThemeXML, BackgroundType, VerticalType, Backgr from openlp.core.lib.ui import critical_error_message_box, create_widget_action from openlp.core.theme import Theme from openlp.core.ui import FileRenameForm, ThemeForm -from openlp.core.utils import AppLocation, SettingsManager, delete_file, locale_compare, get_filesystem_encoding +from openlp.core.utils import AppLocation, delete_file, locale_compare, get_filesystem_encoding log = logging.getLogger(__name__) @@ -149,7 +149,7 @@ class ThemeManager(QtGui.QWidget): Import new themes downloaded by the first time wizard """ self.application.set_busy_cursor() - files = SettingsManager.get_files(self.settingsSection, u'.otz') + files = AppLocation.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) @@ -418,10 +418,10 @@ class ThemeManager(QtGui.QWidget): log.debug(u'Load themes from dir') self.theme_list = [] self.theme_list_widget.clear() - files = SettingsManager.get_files(self.settingsSection, u'.png') + files = AppLocation.get_files(self.settingsSection, u'.png') if first_time: self.first_time() - files = SettingsManager.get_files(self.settingsSection, u'.png') + files = AppLocation.get_files(self.settingsSection, u'.png') # No themes have been found so create one if not files: theme = ThemeXML() @@ -429,7 +429,7 @@ class ThemeManager(QtGui.QWidget): self._write_theme(theme, None, None) Settings().setValue(self.settingsSection + u'/global theme', theme.theme_name) self.config_updated() - files = SettingsManager.get_files(self.settingsSection, u'.png') + files = AppLocation.get_files(self.settingsSection, u'.png') # Sort the themes by its name considering language specific files.sort(key=lambda file_name: unicode(file_name), cmp=locale_compare) # now process the file list of png files diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index c529fe34d..cf4eb4675 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -50,7 +50,6 @@ if sys.platform != u'win32' and sys.platform != u'darwin': except ImportError: XDG_BASE_AVAILABLE = False -import openlp from openlp.core.lib import translate, check_directory_exists log = logging.getLogger(__name__) @@ -78,107 +77,6 @@ class VersionThread(QtCore.QThread): if LooseVersion(str(version)) > LooseVersion(str(app_version[u'full'])): 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 - - # 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: - 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: - 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: - 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): """ @@ -497,10 +395,11 @@ def locale_compare(string1, string2): locale_direct_compare = locale.strcoll +from applocation import AppLocation from languagemanager import LanguageManager from actions import ActionList -from settingsmanager import SettingsManager -__all__ = [u'AppLocation', u'ActionList', u'LanguageManager', u'SettingsManager', 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'delete_file', u'clean_filename', u'format_time', u'locale_compare', u'locale_direct_compare'] + +__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'delete_file', u'clean_filename', u'format_time', u'locale_compare', u'locale_direct_compare'] diff --git a/openlp/core/utils/applocation.py b/openlp/core/utils/applocation.py new file mode 100644 index 000000000..611e5b731 --- /dev/null +++ b/openlp/core/utils/applocation.py @@ -0,0 +1,184 @@ +# -*- 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` module provides the utility libraries for OpenLP. +""" +import logging +import os +import re +import sys +import urllib2 + +from openlp.core.lib import Registry, 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 translate, 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 + + # 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. + """ + 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: + 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: + 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: + 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') + + + + + diff --git a/openlp/core/utils/settingsmanager.py b/openlp/core/utils/settingsmanager.py deleted file mode 100644 index 00bdda350..000000000 --- a/openlp/core/utils/settingsmanager.py +++ /dev/null @@ -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 diff --git a/openlp/plugins/bibles/lib/manager.py b/openlp/plugins/bibles/lib/manager.py index 38b5ea9c7..987817bdc 100644 --- a/openlp/plugins/bibles/lib/manager.py +++ b/openlp/plugins/bibles/lib/manager.py @@ -31,7 +31,7 @@ import logging import os from openlp.core.lib import Registry, Settings, translate -from openlp.core.utils import AppLocation, SettingsManager, 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.db import BibleDB, BibleMeta from csvbible import CSVBible @@ -137,7 +137,7 @@ class BibleManager(object): BibleDB class. """ 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: files.remove(u'alternative_book_names.sqlite') log.debug(u'Bible Files %s', files) diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index 7fe3088e4..fdc743f32 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -35,7 +35,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import MediaManagerItem, ItemCapabilities, Registry, ServiceItemContext, Settings, UiStrings, \ build_icon, check_item_selected, check_directory_exists, create_thumb, translate, validate_thumb from openlp.core.lib.ui import critical_error_message_box -from openlp.core.utils import AppLocation, SettingsManager, delete_file, locale_compare, get_images_filter +from openlp.core.utils import AppLocation, delete_file, locale_compare, get_images_filter log = logging.getLogger(__name__) @@ -106,7 +106,7 @@ class ImageMediaItem(MediaManagerItem): delete_file(os.path.join(self.servicePath, text.text())) self.listView.takeItem(row) self.main_window.incrementProgressBar() - SettingsManager.setValue(self.settingsSection + u'/images files', self.getFileList()) + AppLocation.setValue(self.settingsSection + u'/images files', self.getFileList()) self.main_window.finishedProgressBar() self.application.set_normal_cursor() self.listView.blockSignals(False) diff --git a/tests/functional/openlp_core_utils/test_applocation.py b/tests/functional/openlp_core_utils/test_applocation.py index f874de4db..b7f608966 100644 --- a/tests/functional/openlp_core_utils/test_applocation.py +++ b/tests/functional/openlp_core_utils/test_applocation.py @@ -15,10 +15,10 @@ class TestAppLocation(TestCase): """ 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.check_directory_exists') as mocked_check_directory_exists, \ - patch(u'openlp.core.utils.os') as mocked_os: + patch(u'openlp.core.utils.applocation.check_directory_exists') as mocked_check_directory_exists, \ + patch(u'openlp.core.utils.applocation.os') as mocked_os: # GIVEN: A mocked out Settings class and a mocked out AppLocation.get_directory() mocked_settings = mocked_class.return_value mocked_settings.contains.return_value = False @@ -37,8 +37,8 @@ class TestAppLocation(TestCase): """ 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,\ - patch(u'openlp.core.utils.os') as mocked_os: + with patch(u'openlp.core.utils.applocation.Settings') as mocked_class,\ + patch(u'openlp.core.utils.applocation.os') as mocked_os: # GIVEN: A mocked out Settings class which returns a custom data location mocked_settings = mocked_class.return_value mocked_settings.contains.return_value = True @@ -56,7 +56,7 @@ class TestAppLocation(TestCase): Test the AppLocation.get_section_data_path() method """ 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() mocked_get_data_path.return_value = u'test/dir' mocked_check_directory_exists.return_value = True @@ -70,7 +70,7 @@ class TestAppLocation(TestCase): """ 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' # WHEN: We call AppLocation.get_directory directory = AppLocation.get_directory(AppLocation.AppDir) @@ -81,10 +81,10 @@ class TestAppLocation(TestCase): """ Test the AppLocation.get_directory() method for AppLocation.PluginsDir """ - with patch(u'openlp.core.utils._get_frozen_path') as mocked_get_frozen_path, \ - patch(u'openlp.core.utils.os.path.abspath') as mocked_abspath, \ - patch(u'openlp.core.utils.os.path.split') as mocked_split, \ - patch(u'openlp.core.utils.sys') as mocked_sys: + with patch(u'openlp.core.utils.applocation._get_frozen_path') as mocked_get_frozen_path, \ + patch(u'openlp.core.utils.applocation.os.path.abspath') as mocked_abspath, \ + patch(u'openlp.core.utils.applocation.os.path.split') as mocked_split, \ + patch(u'openlp.core.utils.applocation.sys') as mocked_sys: mocked_abspath.return_value = u'plugins/dir' mocked_split.return_value = [u'openlp'] mocked_get_frozen_path.return_value = u'plugins/dir' From 0f8836ac54935ea37cfcfdcdcc68c8fa39af080e Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 27 Feb 2013 12:29:24 +0100 Subject: [PATCH 43/48] removed not needed imports --- openlp/core/utils/__init__.py | 5 +++-- openlp/core/utils/applocation.py | 6 ++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index cf4eb4675..6706750b5 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -39,9 +39,10 @@ from subprocess import Popen, PIPE import sys import urllib2 +from PyQt4 import QtGui, QtCore + from openlp.core.lib import Registry, Settings -from PyQt4 import QtGui, QtCore if sys.platform != u'win32' and sys.platform != u'darwin': try: @@ -50,7 +51,7 @@ if sys.platform != u'win32' and sys.platform != u'darwin': except ImportError: XDG_BASE_AVAILABLE = False -from openlp.core.lib import translate, check_directory_exists +from openlp.core.lib import translate log = logging.getLogger(__name__) APPLICATION_VERSION = {} diff --git a/openlp/core/utils/applocation.py b/openlp/core/utils/applocation.py index 611e5b731..e35b41fce 100644 --- a/openlp/core/utils/applocation.py +++ b/openlp/core/utils/applocation.py @@ -31,11 +31,9 @@ The :mod:`openlp.core.utils` module provides the utility libraries for OpenLP. """ import logging import os -import re import sys -import urllib2 -from openlp.core.lib import Registry, Settings +from openlp.core.lib import Settings from openlp.core.utils import _get_frozen_path @@ -47,7 +45,7 @@ if sys.platform != u'win32' and sys.platform != u'darwin': XDG_BASE_AVAILABLE = False import openlp -from openlp.core.lib import translate, check_directory_exists +from openlp.core.lib import check_directory_exists log = logging.getLogger(__name__) From 5b6f6ddee1f3369900cc4690f2cfccec9bb0f6cf Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 27 Feb 2013 12:31:06 +0100 Subject: [PATCH 44/48] removed not needed lines --- openlp/core/utils/applocation.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/openlp/core/utils/applocation.py b/openlp/core/utils/applocation.py index e35b41fce..7201cebe4 100644 --- a/openlp/core/utils/applocation.py +++ b/openlp/core/utils/applocation.py @@ -176,7 +176,3 @@ def _get_os_dir_path(dir_type): 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') - - - - From 51eb93fe7552ea7b52b24fcde4200202902b5b64 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 27 Feb 2013 13:03:17 +0100 Subject: [PATCH 45/48] added test --- openlp/core/utils/applocation.py | 4 +- .../openlp_core_utils/test_applocation.py | 53 ++++++++++++++++--- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/openlp/core/utils/applocation.py b/openlp/core/utils/applocation.py index 7201cebe4..fa4ce9958 100644 --- a/openlp/core/utils/applocation.py +++ b/openlp/core/utils/applocation.py @@ -113,7 +113,9 @@ class AppLocation(object): 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. + Defaults to *None*. The extension to search for. For example:: + + u'.png' """ path = AppLocation.get_data_path() if section: diff --git a/tests/functional/openlp_core_utils/test_applocation.py b/tests/functional/openlp_core_utils/test_applocation.py index b7f608966..36b9a76a4 100644 --- a/tests/functional/openlp_core_utils/test_applocation.py +++ b/tests/functional/openlp_core_utils/test_applocation.py @@ -1,12 +1,17 @@ """ Functional tests to test the AppLocation class and related methods. """ +import copy from unittest import TestCase from mock import patch 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): """ A test suite to test out various methods around the AppLocation class. @@ -16,9 +21,9 @@ class TestAppLocation(TestCase): Test the AppLocation.get_data_path() method """ 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.check_directory_exists') as mocked_check_directory_exists, \ - patch(u'openlp.core.utils.applocation.os') as mocked_os: + patch(u'openlp.core.utils.AppLocation.get_directory') as mocked_get_directory, \ + patch(u'openlp.core.utils.applocation.check_directory_exists') as mocked_check_directory_exists, \ + patch(u'openlp.core.utils.applocation.os') as mocked_os: # GIVEN: A mocked out Settings class and a mocked out AppLocation.get_directory() mocked_settings = mocked_class.return_value mocked_settings.contains.return_value = False @@ -38,7 +43,7 @@ class TestAppLocation(TestCase): Test the AppLocation.get_data_path() method when a custom location is set in the settings """ with patch(u'openlp.core.utils.applocation.Settings') as mocked_class,\ - patch(u'openlp.core.utils.applocation.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 mocked_settings = mocked_class.return_value mocked_settings.contains.return_value = True @@ -51,12 +56,44 @@ class TestAppLocation(TestCase): mocked_settings.value.assert_called_with(u'advanced/data path') 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 identically. + assert result == FILE_LIST, u'The file lists should be identically.' + + 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 file lists are identically. + assert result == [u'file5.mp3', u'file6.mp3'], u'The file lists should be identically.' + def get_section_data_path_test(self): """ Test the AppLocation.get_section_data_path() method """ with patch(u'openlp.core.utils.AppLocation.get_data_path') as mocked_get_data_path, \ - patch(u'openlp.core.utils.applocation.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() mocked_get_data_path.return_value = u'test/dir' mocked_check_directory_exists.return_value = True @@ -82,9 +119,9 @@ class TestAppLocation(TestCase): Test the AppLocation.get_directory() method for AppLocation.PluginsDir """ with patch(u'openlp.core.utils.applocation._get_frozen_path') as mocked_get_frozen_path, \ - patch(u'openlp.core.utils.applocation.os.path.abspath') as mocked_abspath, \ - patch(u'openlp.core.utils.applocation.os.path.split') as mocked_split, \ - patch(u'openlp.core.utils.applocation.sys') as mocked_sys: + patch(u'openlp.core.utils.applocation.os.path.abspath') as mocked_abspath, \ + patch(u'openlp.core.utils.applocation.os.path.split') as mocked_split, \ + patch(u'openlp.core.utils.applocation.sys') as mocked_sys: mocked_abspath.return_value = u'plugins/dir' mocked_split.return_value = [u'openlp'] mocked_get_frozen_path.return_value = u'plugins/dir' From 20e26e7ea1a5343a996f594d1150d81786b47874 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 27 Feb 2013 13:41:04 +0100 Subject: [PATCH 46/48] attempt to fix test; naming errors --- openlp/core/utils/actions.py | 2 +- openlp/plugins/songs/lib/__init__.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/openlp/core/utils/actions.py b/openlp/core/utils/actions.py index 922aa7767..a1b2bff38 100644 --- a/openlp/core/utils/actions.py +++ b/openlp/core/utils/actions.py @@ -411,7 +411,7 @@ class ActionList(object): for existing_action in existing_actions: if action is existing_action: continue - if not global_context or existing_action in affected_actions: + if existing_action in affected_actions: return False if existing_action.shortcutContext() in [QtCore.Qt.WindowShortcut, QtCore.Qt.ApplicationShortcut]: return False diff --git a/openlp/plugins/songs/lib/__init__.py b/openlp/plugins/songs/lib/__init__.py index 93342c617..c6093eec7 100644 --- a/openlp/plugins/songs/lib/__init__.py +++ b/openlp/plugins/songs/lib/__init__.py @@ -165,7 +165,7 @@ class VerseType(object): translate('SongsPlugin.VerseType', 'Intro'), translate('SongsPlugin.VerseType', 'Ending'), translate('SongsPlugin.VerseType', 'Other')] - tanslated_tags = [name[0].lower() for name in translated_names] + translated_tags = [name[0].lower() for name in translated_names] @staticmethod def translated_tag(verse_tag, default=Other): @@ -181,9 +181,9 @@ class VerseType(object): verse_tag = verse_tag[0].lower() for num, tag in enumerate(VerseType.tags): if verse_tag == tag: - return VerseType.tanslated_tags[num].upper() - if default in VerseType.tanslated_tags: - return VerseType.tanslated_tags[default].upper() + return VerseType.translated_tags[num].upper() + if default in VerseType.translated_tags: + return VerseType.translated_tags[default].upper() @staticmethod def translated_name(verse_tag, default=Other): From c3e01dd719d97fc616926dff1a9e92c2b8d23e55 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 27 Feb 2013 14:01:42 +0100 Subject: [PATCH 47/48] fixed docs --- openlp/core/utils/applocation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/core/utils/applocation.py b/openlp/core/utils/applocation.py index fa4ce9958..2f1cb45ba 100644 --- a/openlp/core/utils/applocation.py +++ b/openlp/core/utils/applocation.py @@ -27,7 +27,7 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### """ -The :mod:`openlp.core.utils` module provides the utility libraries for OpenLP. +The :mod:`openlp.core.utils.applocation` module provides an utility for OpenLP receiving the data path etc. """ import logging import os From e61d76ecff2c4155c0fcb5cba194929c56b98ae0 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 27 Feb 2013 22:40:55 +0100 Subject: [PATCH 48/48] fixed grammar --- .../openlp_core_lib/test_formattingtags.py | 12 ++++++------ tests/functional/openlp_core_lib/test_screen.py | 4 ++-- .../functional/openlp_core_utils/test_applocation.py | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/functional/openlp_core_lib/test_formattingtags.py b/tests/functional/openlp_core_lib/test_formattingtags.py index 6c60be5ac..26d87f466 100644 --- a/tests/functional/openlp_core_lib/test_formattingtags.py +++ b/tests/functional/openlp_core_lib/test_formattingtags.py @@ -45,8 +45,8 @@ class TestFormattingTags(TestCase): FormattingTags.load_tags() new_tags_list = FormattingTags.get_html_tags() - # THEN: Lists should be identically. - assert old_tags_list == new_tags_list, u'The formatting tag lists should be identically.' + # THEN: Lists should be identical. + assert old_tags_list == new_tags_list, u'The formatting tag lists should be identical.' def get_html_tags_with_user_tags_test(self): """ @@ -69,16 +69,16 @@ class TestFormattingTags(TestCase): FormattingTags.add_html_tags([TAG]) 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.' # THEN: Added tag and last tag should be the same. 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. FormattingTags.remove_html_tag(len(new_tags_list)) - # THEN: The lists should now be identically. - assert old_tags_list == FormattingTags.get_html_tags(), u'The lists should be identically.' + # THEN: The lists should now be identical. + assert old_tags_list == FormattingTags.get_html_tags(), u'The lists should be identical.' diff --git a/tests/functional/openlp_core_lib/test_screen.py b/tests/functional/openlp_core_lib/test_screen.py index d823a2469..4b4df8e9b 100644 --- a/tests/functional/openlp_core_lib/test_screen.py +++ b/tests/functional/openlp_core_lib/test_screen.py @@ -54,5 +54,5 @@ class TestScreenList(TestCase): new_screens = self.screens.screen_list assert len(old_screens) + 1 == len(new_screens), u'The new_screens list should be bigger.' - # THEN: The screens should be identically. - assert SCREEN == new_screens.pop(), u'The new screen should be identically to the screen defined above.' + # THEN: The screens should be identical. + assert SCREEN == new_screens.pop(), u'The new screen should be identical to the screen defined above.' diff --git a/tests/functional/openlp_core_utils/test_applocation.py b/tests/functional/openlp_core_utils/test_applocation.py index 36b9a76a4..d823b077c 100644 --- a/tests/functional/openlp_core_utils/test_applocation.py +++ b/tests/functional/openlp_core_utils/test_applocation.py @@ -69,8 +69,8 @@ class TestAppLocation(TestCase): # When: Get the list of files. result = AppLocation.get_files() - # Then: check if the file lists are identically. - assert result == FILE_LIST, u'The file lists should be identically.' + # Then: check if the file lists are identical. + assert result == FILE_LIST, u'The file lists should be identical.' def get_files_test(self): """ @@ -85,8 +85,8 @@ class TestAppLocation(TestCase): # When: Get the list of files. result = AppLocation.get_files(u'section', u'.mp3') - # Then: check if the file lists are identically. - assert result == [u'file5.mp3', u'file6.mp3'], u'The file lists should be identically.' + # 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): """