This commit is contained in:
Tim Bentley 2016-01-11 21:12:03 +00:00
commit 2218ecbcd7
66 changed files with 360 additions and 285 deletions

View File

@ -43,5 +43,4 @@ __pycache__
.coverage
cover
*.kdev4
./.coveragerc
./coverage
coverage

5
.coveragerc Normal file
View File

@ -0,0 +1,5 @@
[run]
source = openlp
[html]
directory = coverage

View File

@ -1 +1 @@
2.3.1
2.3.2

View File

@ -263,7 +263,8 @@ class Plugin(QtCore.QObject, RegistryProperties):
else:
self.media_item.on_add_click()
def about(self):
@staticmethod
def about():
"""
Show a dialog when the user clicks on the 'About' button in the plugin manager.
"""

View File

@ -273,7 +273,7 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties):
except ValueError:
text_to_render = text.split('\n[---]\n')[0]
text = ''
text_to_render, raw_tags, html_tags = self._get_start_tags(text_to_render)
text_to_render, raw_tags, html_tags = get_start_tags(text_to_render)
if text:
text = raw_tags + text
else:
@ -441,7 +441,7 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties):
previous_raw = line + line_end
continue
# Figure out how many words of the line will fit on screen as the line will not fit as a whole.
raw_words = self._words_split(line)
raw_words = Renderer.words_split(line)
html_words = list(map(expand_tags, raw_words))
previous_html, previous_raw = \
self._binary_chop(formatted, previous_html, previous_raw, html_words, raw_words, ' ', line_end)
@ -451,42 +451,6 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties):
formatted.append(previous_raw)
return formatted
def _get_start_tags(self, raw_text):
"""
Tests the given text for not closed formatting tags and returns a tuple consisting of three unicode strings::
('{st}{r}Text text text{/r}{/st}', '{st}{r}', '<strong><span style="-webkit-text-fill-color:red">')
The first unicode string is the text, with correct closing tags. The second unicode string are OpenLP's opening
formatting tags and the third unicode string the html opening formatting tags.
:param raw_text: The text to test. The text must **not** contain html tags, only OpenLP formatting tags
are allowed::
{st}{r}Text text text
"""
raw_tags = []
html_tags = []
for tag in FormattingTags.get_html_tags():
if tag['start tag'] == '{br}':
continue
if raw_text.count(tag['start tag']) != raw_text.count(tag['end tag']):
raw_tags.append((raw_text.find(tag['start tag']), tag['start tag'], tag['end tag']))
html_tags.append((raw_text.find(tag['start tag']), tag['start html']))
# 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.
raw_tags.sort(key=lambda tag: tag[0])
html_tags.sort(key=lambda tag: tag[0])
# Create a list with closing tags for the raw_text.
end_tags = []
start_tags = []
for tag in raw_tags:
start_tags.append(tag[1])
end_tags.append(tag[2])
end_tags.reverse()
# Remove the indexes.
html_tags = [tag[1] for tag in html_tags]
return raw_text + ''.join(end_tags), ''.join(start_tags), ''.join(html_tags)
def _binary_chop(self, formatted, previous_html, previous_raw, html_list, raw_list, separator, line_end):
"""
This implements the binary chop algorithm for faster rendering. This algorithm works line based (line by line)
@ -521,7 +485,7 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties):
if smallest_index == index or highest_index == index:
index = smallest_index
text = previous_raw.rstrip('<br>') + separator.join(raw_list[:index + 1])
text, raw_tags, html_tags = self._get_start_tags(text)
text, raw_tags, html_tags = get_start_tags(text)
formatted.append(text)
previous_html = ''
previous_raw = ''
@ -556,12 +520,50 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties):
self.web_frame.evaluateJavaScript('show_text("%s")' % text.replace('\\', '\\\\').replace('\"', '\\\"'))
return self.web_frame.contentsSize().height() <= self.empty_height
def _words_split(self, line):
"""
Split the slide up by word so can wrap better
:param line: Line to be split
"""
# this parse we are to be wordy
line = line.replace('\n', ' ')
return line.split(' ')
def words_split(line):
"""
Split the slide up by word so can wrap better
:param line: Line to be split
"""
# this parse we are to be wordy
line = line.replace('\n', ' ')
return line.split(' ')
def get_start_tags(raw_text):
"""
Tests the given text for not closed formatting tags and returns a tuple consisting of three unicode strings::
('{st}{r}Text text text{/r}{/st}', '{st}{r}', '<strong><span style="-webkit-text-fill-color:red">')
The first unicode string is the text, with correct closing tags. The second unicode string are OpenLP's opening
formatting tags and the third unicode string the html opening formatting tags.
:param raw_text: The text to test. The text must **not** contain html tags, only OpenLP formatting tags
are allowed::
{st}{r}Text text text
"""
raw_tags = []
html_tags = []
for tag in FormattingTags.get_html_tags():
if tag['start tag'] == '{br}':
continue
if raw_text.count(tag['start tag']) != raw_text.count(tag['end tag']):
raw_tags.append((raw_text.find(tag['start tag']), tag['start tag'], tag['end tag']))
html_tags.append((raw_text.find(tag['start tag']), tag['start html']))
# 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.
raw_tags.sort(key=lambda tag: tag[0])
html_tags.sort(key=lambda tag: tag[0])
# Create a list with closing tags for the raw_text.
end_tags = []
start_tags = []
for tag in raw_tags:
start_tags.append(tag[1])
end_tags.append(tag[2])
end_tags.reverse()
# Remove the indexes.
html_tags = [tag[1] for tag in html_tags]
return raw_text + ''.join(end_tags), ''.join(start_tags), ''.join(html_tags)

View File

@ -40,8 +40,7 @@ class AboutForm(QtWidgets.QDialog, UiAboutDialog):
"""
Do some initialisation stuff
"""
super(AboutForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(AboutForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self._setup()
def _setup(self):

View File

@ -89,8 +89,7 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
"""
Constructor.
"""
super(ExceptionForm, self).__init__(None, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(ExceptionForm, self).__init__(None, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi(self)
self.settings_section = 'crashreport'
self.report_text = '**OpenLP Bug Report**\n' \

View File

@ -39,7 +39,7 @@ class FileRenameForm(QtWidgets.QDialog, Ui_FileRenameDialog, RegistryProperties)
Constructor
"""
super(FileRenameForm, self).__init__(Registry().get('main_window'),
QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self._setup()
def _setup(self):

View File

@ -37,8 +37,7 @@ class FirstTimeLanguageForm(QtWidgets.QDialog, Ui_FirstTimeLanguageDialog):
"""
Constructor
"""
super(FirstTimeLanguageForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(FirstTimeLanguageForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi(self)
self.qm_list = LanguageManager.get_qm_list()
self.language_combo_box.addItem('Autodetect')

View File

@ -51,8 +51,7 @@ class FormattingTagForm(QtWidgets.QDialog, Ui_FormattingTagDialog, FormattingTag
"""
Constructor
"""
super(FormattingTagForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(FormattingTagForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi(self)
self._setup()

View File

@ -47,6 +47,7 @@ from openlp.core.utils import LanguageManager, add_actions, get_application_vers
from openlp.core.utils.actions import ActionList, CategoryOrder
from openlp.core.ui.firsttimeform import FirstTimeForm
from openlp.core.ui.projector.manager import ProjectorManager
from openlp.core.ui.printserviceform import PrintServiceForm
log = logging.getLogger(__name__)
@ -198,7 +199,7 @@ class Ui_MainWindow(object):
triggers=self.service_manager_contents.save_file_as)
self.print_service_order_item = create_action(main_window, 'printServiceItem', can_shortcuts=True,
category=UiStrings().File,
triggers=self.service_manager_contents.print_service_order)
triggers=lambda x: PrintServiceForm().exec())
self.file_exit_item = create_action(main_window, 'fileExitItem', icon=':/system/system_exit.png',
can_shortcuts=True,
category=UiStrings().File, triggers=main_window.close)

View File

@ -326,10 +326,10 @@ class WebkitPlayer(MediaPlayer):
controller = display.controller
if controller.media_info.is_flash:
seek = seek_value
display.frame.evaluateJavaScript('show_flash("seek", null, null, "%s");' % (seek))
display.frame.evaluateJavaScript('show_flash("seek", null, null, "%s");' % seek)
else:
seek = float(seek_value) / 1000
display.frame.evaluateJavaScript('show_video("seek", null, null, null, "%f");' % (seek))
display.frame.evaluateJavaScript('show_video("seek", null, null, null, "%f");' % seek)
def reset(self, display):
"""

View File

@ -41,8 +41,7 @@ class PluginForm(QtWidgets.QDialog, Ui_PluginViewDialog, RegistryProperties):
"""
Constructor
"""
super(PluginForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(PluginForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.active_plugin = None
self.programatic_change = False
self.setupUi(self)

View File

@ -113,7 +113,7 @@ class PrintServiceForm(QtWidgets.QDialog, Ui_PrintServiceDialog, RegistryPropert
Constructor
"""
super(PrintServiceForm, self).__init__(Registry().get('main_window'),
QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.printer = QtPrintSupport.QPrinter()
self.print_dialog = QtPrintSupport.QPrintDialog(self.printer, self)
self.document = QtGui.QTextDocument()

View File

@ -144,8 +144,7 @@ class ProjectorEditForm(QDialog, Ui_ProjectorEditForm):
editProjector = pyqtSignal(object)
def __init__(self, parent=None, projectordb=None):
super(ProjectorEditForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(ProjectorEditForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.projectordb = projectordb
self.setupUi(self)
self.button_box.accepted.connect(self.accept_me)

View File

@ -236,8 +236,7 @@ class SourceSelectTabs(QDialog):
:param projectordb: ProjectorDB session to use
"""
log.debug('Initializing SourceSelectTabs()')
super(SourceSelectTabs, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(SourceSelectTabs, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setMinimumWidth(350)
self.projectordb = projectordb
self.edit = edit
@ -386,8 +385,7 @@ class SourceSelectSingle(QDialog):
"""
log.debug('Initializing SourceSelectSingle()')
self.projectordb = projectordb
super(SourceSelectSingle, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(SourceSelectSingle, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.edit = edit
if self.edit:
title = translate('OpenLP.SourceSelectForm', 'Edit Projector Source Text')

View File

@ -38,7 +38,7 @@ class ServiceItemEditForm(QtWidgets.QDialog, Ui_ServiceItemEditDialog, RegistryP
Constructor
"""
super(ServiceItemEditForm, self).__init__(Registry().get('main_window'),
QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi(self)
self.item_list = []
self.list_widget.currentRowChanged.connect(self.on_current_row_changed)

View File

@ -144,8 +144,8 @@ class Ui_ServiceManager(object):
self.service_manager_list.customContextMenuRequested.connect(self.context_menu)
self.service_manager_list.setObjectName('service_manager_list')
# enable drop
self.service_manager_list.__class__.dragEnterEvent = self.drag_enter_event
self.service_manager_list.__class__.dragMoveEvent = self.drag_enter_event
self.service_manager_list.__class__.dragEnterEvent = lambda x, event: event.accept()
self.service_manager_list.__class__.dragMoveEvent = lambda x, event: event.accept()
self.service_manager_list.__class__.dropEvent = self.drop_event
self.layout.addWidget(self.service_manager_list)
# Add the bottom toolbar
@ -293,14 +293,6 @@ class Ui_ServiceManager(object):
Registry().register_function('theme_update_global', self.theme_change)
Registry().register_function('mediaitem_suffix_reset', self.reset_supported_suffixes)
def drag_enter_event(self, event):
"""
Accept Drag events
:param event: Handle of the event passed
"""
event.accept()
class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceManager, RegistryProperties):
"""
@ -1585,7 +1577,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
if item is None:
end_pos = len(self.service_items)
else:
end_pos = self._get_parent_item_data(item) - 1
end_pos = get_parent_item_data(item) - 1
service_item = self.service_items[start_pos]
self.service_items.remove(service_item)
self.service_items.insert(end_pos, service_item)
@ -1598,21 +1590,21 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
self.drop_position = len(self.service_items)
else:
# we are over something so lets investigate
pos = self._get_parent_item_data(item) - 1
pos = get_parent_item_data(item) - 1
service_item = self.service_items[pos]
if (plugin == service_item['service_item'].name and
service_item['service_item'].is_capable(ItemCapabilities.CanAppend)):
action = self.dnd_menu.exec(QtGui.QCursor.pos())
# New action required
if action == self.new_action:
self.drop_position = self._get_parent_item_data(item)
self.drop_position = get_parent_item_data(item)
# Append to existing action
if action == self.add_to_action:
self.drop_position = self._get_parent_item_data(item)
self.drop_position = get_parent_item_data(item)
item.setSelected(True)
replace = True
else:
self.drop_position = self._get_parent_item_data(item) - 1
self.drop_position = get_parent_item_data(item) - 1
Registry().execute('%s_add_service_item' % plugin, replace)
def update_theme_list(self, theme_list):
@ -1656,27 +1648,21 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtWidgets.QWidget, Ui_ServiceMa
self.service_items[item]['service_item'].update_theme(theme)
self.regenerate_service_items(True)
def _get_parent_item_data(self, item):
"""
Finds and returns the parent item for any item
:param item: The service item list item to be checked.
"""
parent_item = item.parent()
if parent_item is None:
return item.data(0, QtCore.Qt.UserRole)
else:
return parent_item.data(0, QtCore.Qt.UserRole)
def print_service_order(self, field=None):
"""
Print a Service Order Sheet.
"""
setting_dialog = PrintServiceForm()
setting_dialog.exec()
def get_drop_position(self):
"""
Getter for drop_position. Used in: MediaManagerItem
"""
return self.drop_position
def get_parent_item_data(item):
"""
Finds and returns the parent item for any item
:param item: The service item list item to be checked.
"""
parent_item = item.parent()
if parent_item is None:
return item.data(0, QtCore.Qt.UserRole)
else:
return parent_item.data(0, QtCore.Qt.UserRole)

View File

@ -38,7 +38,7 @@ class ServiceNoteForm(QtWidgets.QDialog, RegistryProperties):
Constructor
"""
super(ServiceNoteForm, self).__init__(Registry().get('main_window'),
QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi()
self.retranslateUi()

View File

@ -46,8 +46,7 @@ class SettingsForm(QtWidgets.QDialog, Ui_SettingsDialog, RegistryProperties):
"""
Registry().register('settings_form', self)
Registry().register_function('bootstrap_post_set_up', self.bootstrap_post_set_up)
super(SettingsForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(SettingsForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.processes = []
self.setupUi(self)
self.setting_list_widget.currentRowChanged.connect(self.list_item_changed)

View File

@ -44,8 +44,7 @@ class ShortcutListForm(QtWidgets.QDialog, Ui_ShortcutListDialog, RegistryPropert
"""
Constructor
"""
super(ShortcutListForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(ShortcutListForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi(self)
self.changed_actions = {}
self.action_list = ActionList.get_instance()

View File

@ -39,7 +39,7 @@ class StartTimeForm(QtWidgets.QDialog, Ui_StartTimeDialog, RegistryProperties):
Constructor
"""
super(StartTimeForm, self).__init__(Registry().get('main_window'),
QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi(self)
def exec(self):

View File

@ -191,7 +191,8 @@ class AlertsPlugin(Plugin):
self.alert_form.load_list()
self.alert_form.exec()
def about(self):
@staticmethod
def about():
"""
Plugin Alerts about method
@ -215,7 +216,8 @@ class AlertsPlugin(Plugin):
'title': translate('AlertsPlugin', 'Alerts', 'container title')
}
def get_display_javascript(self):
@staticmethod
def get_display_javascript():
"""
Add Javascript to the main display.
"""
@ -229,7 +231,8 @@ class AlertsPlugin(Plugin):
return CSS % (align, self.settings_tab.font_face, self.settings_tab.font_size, self.settings_tab.font_color,
self.settings_tab.background_color)
def get_display_html(self):
@staticmethod
def get_display_html():
"""
Add HTML to the main display.
"""

View File

@ -37,7 +37,7 @@ class AlertForm(QtWidgets.QDialog, Ui_AlertDialog):
Initialise the alert form
"""
super(AlertForm, self).__init__(Registry().get('main_window'),
QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.manager = plugin.manager
self.plugin = plugin
self.item_id = None

View File

@ -167,7 +167,8 @@ class BiblePlugin(Plugin):
if self.media_item:
self.media_item.on_import_click()
def about(self):
@staticmethod
def about():
"""
Return the about text for the plugin manager
"""

View File

@ -69,8 +69,8 @@ class BibleImportForm(OpenLPWizard):
"""
self.manager = manager
self.web_bible_list = {}
super(BibleImportForm, self).__init__(
parent, bible_plugin, 'bibleImportWizard', ':/wizards/wizard_importbible.bmp')
super(BibleImportForm, self).__init__(parent, bible_plugin,
'bibleImportWizard', ':/wizards/wizard_importbible.bmp')
def setupUi(self, image):
"""

View File

@ -49,8 +49,7 @@ class BookNameForm(QDialog, Ui_BookNameDialog):
"""
Constructor
"""
super(BookNameForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(BookNameForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi(self)
self.custom_signals()
self.book_names = BibleStrings().BookNames

View File

@ -45,8 +45,7 @@ class EditBibleForm(QtWidgets.QDialog, Ui_EditBibleDialog, RegistryProperties):
"""
Constructor
"""
super(EditBibleForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(EditBibleForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.media_item = media_item
self.book_names = BibleStrings().BookNames
self.setupUi(self)

View File

@ -47,8 +47,7 @@ class LanguageForm(QDialog, Ui_LanguageDialog):
"""
Constructor
"""
super(LanguageForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(LanguageForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi(self)
def exec(self, bible_name):

View File

@ -62,7 +62,8 @@ class CustomPlugin(Plugin):
self.icon_path = ':/plugins/plugin_custom.png'
self.icon = build_icon(self.icon_path)
def about(self):
@staticmethod
def about():
about_text = translate('CustomPlugin', '<strong>Custom Slide Plugin </strong><br />The custom slide plugin '
'provides the ability to set up custom text slides that can be displayed on the screen '
'the same way songs are. This plugin provides greater freedom over the songs plugin.')
@ -73,6 +74,7 @@ class CustomPlugin(Plugin):
Called to find out if the custom plugin is currently using a theme.
Returns count of the times the theme is used.
:param theme: Theme to be queried
"""
return len(self.db_manager.get_all_objects(CustomSlide, CustomSlide.theme_name == theme))

View File

@ -44,8 +44,7 @@ class EditCustomForm(QtWidgets.QDialog, Ui_CustomEditDialog):
"""
Constructor
"""
super(EditCustomForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(EditCustomForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.manager = manager
self.media_item = media_item
self.setupUi(self)

View File

@ -39,8 +39,7 @@ class EditCustomSlideForm(QtWidgets.QDialog, Ui_CustomSlideEditDialog):
"""
Constructor
"""
super(EditCustomSlideForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(EditCustomSlideForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi(self)
# Connecting signals and slots
self.insert_button.clicked.connect(self.on_insert_button_clicked)

View File

@ -35,8 +35,7 @@ class AddGroupForm(QtWidgets.QDialog, Ui_AddGroupDialog):
"""
Constructor
"""
super(AddGroupForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(AddGroupForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi(self)
def exec(self, clear=True, show_top_level_group=False, selected_group=None):

View File

@ -33,8 +33,7 @@ class ChooseGroupForm(QtWidgets.QDialog, Ui_ChooseGroupDialog):
"""
Constructor
"""
super(ChooseGroupForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(ChooseGroupForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi(self)
def exec(self, selected_group=None):

View File

@ -23,9 +23,8 @@
from PyQt5 import QtGui
import logging
import os
from openlp.core.common import Registry, Settings, translate
from openlp.core.common import Settings, translate
from openlp.core.lib import Plugin, StringContent, ImageSource, build_icon
from openlp.core.lib.db import Manager
from openlp.plugins.images.lib import ImageMediaItem, ImageTab
@ -53,7 +52,8 @@ class ImagePlugin(Plugin):
self.icon_path = ':/plugins/plugin_images.png'
self.icon = build_icon(self.icon_path)
def about(self):
@staticmethod
def about():
about_text = translate('ImagePlugin', '<strong>Image Plugin</strong>'
'<br />The image plugin provides displaying of images.<br />One '
'of the distinguishing features of this plugin is the ability to '

View File

@ -52,8 +52,7 @@ class MediaClipSelectorForm(QtWidgets.QDialog, Ui_MediaClipSelector, RegistryPro
"""
Constructor
"""
super(MediaClipSelectorForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(MediaClipSelectorForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.vlc_instance = None
self.vlc_media_player = None
self.vlc_media = None

View File

@ -84,7 +84,8 @@ class MediaPlugin(Plugin):
visible_name = self.get_string(StringContent.VisibleName)
self.settings_tab = MediaTab(parent, self.name, visible_name['title'], self.icon_path)
def about(self):
@staticmethod
def about():
"""
Return the about text for the plugin manager
"""

View File

@ -28,7 +28,7 @@ import logging
from PyQt5 import QtCore
from openlp.core.common import AppLocation, Settings, translate
from openlp.core.common import AppLocation, translate
from openlp.core.lib import Plugin, StringContent, build_icon
from openlp.plugins.presentations.lib import PresentationController, PresentationMediaItem, PresentationTab
@ -71,6 +71,7 @@ class PresentationPlugin(Plugin):
def create_settings_tab(self, parent):
"""
Create the settings Tab.
:param parent: parent UI Element
"""
visible_name = self.get_string(StringContent.VisibleName)
self.settings_tab = PresentationTab(parent, self.name, visible_name['title'], self.controllers, self.icon_path)
@ -112,6 +113,7 @@ class PresentationPlugin(Plugin):
def register_controllers(self, controller):
"""
Register each presentation controller (Impress, PPT etc) and store for later use.
:param controller: controller to register
"""
self.controllers[controller.name] = controller
@ -137,7 +139,8 @@ class PresentationPlugin(Plugin):
self.register_controllers(controller)
return bool(self.controllers)
def about(self):
@staticmethod
def about():
"""
Return information about this plugin.
"""

View File

@ -88,7 +88,8 @@ class RemotesPlugin(Plugin):
self.server.stop_server()
self.server = None
def about(self):
@staticmethod
def about():
"""
Information about this plugin
"""

View File

@ -35,8 +35,7 @@ class AuthorsForm(QtWidgets.QDialog, Ui_AuthorsDialog):
"""
Set up the screen and common data
"""
super(AuthorsForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(AuthorsForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi(self)
self.auto_display_name = False
self.first_name_edit.textEdited.connect(self.on_first_name_edited)

View File

@ -55,8 +55,7 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
"""
Constructor
"""
super(EditSongForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(EditSongForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.media_item = media_item
self.song = None
# can this be automated?

View File

@ -41,8 +41,7 @@ class EditVerseForm(QtWidgets.QDialog, Ui_EditVerseDialog):
"""
Constructor
"""
super(EditVerseForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(EditVerseForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi(self)
self.has_single_verse = False
self.insert_button.clicked.connect(self.on_insert_button_clicked)

View File

@ -37,8 +37,7 @@ class MediaFilesForm(QtWidgets.QDialog, Ui_MediaFilesDialog):
log.info('%s MediaFilesForm loaded', __name__)
def __init__(self, parent):
super(MediaFilesForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(MediaFilesForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi(self)
def populate_files(self, files):

View File

@ -38,8 +38,7 @@ class SongBookForm(QtWidgets.QDialog, Ui_SongBookDialog):
"""
Constructor
"""
super(SongBookForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(SongBookForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi(self)
def exec(self, clear=True):

View File

@ -72,7 +72,7 @@ class SongExportForm(OpenLPWizard):
"""
Song wizard specific signals.
"""
self.available_list_widget.itemActivated.connect(self.on_item_activated)
self.available_list_widget.itemActivated.connect(on_item_activated)
self.search_line_edit.textEdited.connect(self.on_search_line_edit_changed)
self.uncheck_button.clicked.connect(self.on_uncheck_button_clicked)
self.check_button.clicked.connect(self.on_check_button_clicked)
@ -172,7 +172,7 @@ class SongExportForm(OpenLPWizard):
return True
elif self.currentPage() == self.available_songs_page:
items = [
item for item in self._find_list_widget_items(self.available_list_widget) if item.checkState()
item for item in find_list_widget_items(self.available_list_widget) if item.checkState()
]
if not items:
critical_error_message_box(
@ -241,7 +241,7 @@ class SongExportForm(OpenLPWizard):
"""
songs = [
song.data(QtCore.Qt.UserRole)
for song in self._find_list_widget_items(self.selected_list_widget)
for song in find_list_widget_items(self.selected_list_widget)
]
exporter = OpenLyricsExport(self, songs, self.directory_line_edit.text())
try:
@ -255,28 +255,6 @@ class SongExportForm(OpenLPWizard):
self.progress_label.setText(translate('SongsPlugin.SongExportForm', 'Your song export failed because this '
'error occurred: %s') % ose.strerror)
def _find_list_widget_items(self, list_widget, text=''):
"""
Returns a list of *QListWidgetItem*s of the ``list_widget``. Note, that hidden items are included.
:param list_widget: The widget to get all items from. (QListWidget)
:param text: The text to search for. (unicode string)
"""
return [
item for item in list_widget.findItems(text, QtCore.Qt.MatchContains)
]
def on_item_activated(self, item):
"""
Called, when an item in the *available_list_widget* has been triggered.
The item is check if it was not checked, whereas it is unchecked when it
was checked.
:param item: The *QListWidgetItem* which was triggered.
"""
item.setCheckState(
QtCore.Qt.Unchecked if item.checkState() else QtCore.Qt.Checked)
def on_search_line_edit_changed(self, text):
"""
The *search_line_edit*'s text has been changed. Update the list of
@ -286,9 +264,9 @@ class SongExportForm(OpenLPWizard):
:param text: The text of the *search_line_edit*.
"""
search_result = [
song for song in self._find_list_widget_items(self.available_list_widget, text)
song for song in find_list_widget_items(self.available_list_widget, text)
]
for item in self._find_list_widget_items(self.available_list_widget):
for item in find_list_widget_items(self.available_list_widget):
item.setHidden(item not in search_result)
def on_uncheck_button_clicked(self):
@ -317,3 +295,26 @@ class SongExportForm(OpenLPWizard):
self.get_folder(
translate('SongsPlugin.ExportWizardForm', 'Select Destination Folder'),
self.directory_line_edit, 'last directory export')
def find_list_widget_items(list_widget, text=''):
"""
Returns a list of *QListWidgetItem*s of the ``list_widget``. Note, that hidden items are included.
:param list_widget: The widget to get all items from. (QListWidget)
:param text: The text to search for. (unicode string)
"""
return [
item for item in list_widget.findItems(text, QtCore.Qt.MatchContains)
]
def on_item_activated(item):
"""
Called, when an item in the *available_list_widget* has been triggered.
The item is check if it was not checked, whereas it is unchecked when it
was checked.
:param item: The *QListWidgetItem* which was triggered.
"""
item.setCheckState(QtCore.Qt.Unchecked if item.checkState() else QtCore.Qt.Checked)

View File

@ -44,8 +44,7 @@ class SongMaintenanceForm(QtWidgets.QDialog, Ui_SongMaintenanceDialog, RegistryP
"""
Constructor
"""
super(SongMaintenanceForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(SongMaintenanceForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi(self)
self.manager = manager
self.author_form = AuthorsForm(self)

View File

@ -81,8 +81,7 @@ class SongSelectForm(QtWidgets.QDialog, Ui_SongSelectDialog):
"""
def __init__(self, parent=None, plugin=None, db_manager=None):
QtWidgets.QDialog.__init__(self, parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
QtWidgets.QDialog.__init__(self, parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.plugin = plugin
self.db_manager = db_manager
self.setup_ui(self)

View File

@ -38,8 +38,7 @@ class TopicsForm(QtWidgets.QDialog, Ui_TopicsDialog):
"""
Constructor
"""
super(TopicsForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(TopicsForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi(self)
def exec(self, clear=True):

View File

@ -390,7 +390,7 @@ class SongFormat(object):
"""
Return a list of the supported song formats.
"""
return [
return sorted([
SongFormat.OpenLyrics,
SongFormat.OpenLP2,
SongFormat.Generic,
@ -400,6 +400,7 @@ class SongFormat(object):
SongFormat.EasyWorshipDB,
SongFormat.EasyWorshipService,
SongFormat.FoilPresenter,
SongFormat.Lyrix,
SongFormat.MediaShout,
SongFormat.OpenSong,
SongFormat.PowerPraise,
@ -411,13 +412,12 @@ class SongFormat(object):
SongFormat.SongShowPlus,
SongFormat.SongsOfFellowship,
SongFormat.SundayPlus,
SongFormat.VideoPsalm,
SongFormat.WordsOfWorship,
SongFormat.WorshipAssistant,
SongFormat.WorshipCenterPro,
SongFormat.ZionWorx,
SongFormat.Lyrix,
SongFormat.VideoPsalm
]
])
@staticmethod
def get(song_format, *attributes):

View File

@ -234,16 +234,6 @@ class FoilPresenter(object):
clean_song(self.manager, song)
self.manager.save_object(song)
def _child(self, element):
"""
This returns the text of an element as unicode string.
:param element: The element
"""
if element is not None:
return str(element)
return ''
def _process_authors(self, foilpresenterfolie, song):
"""
Adds the authors specified in the XML to the song.
@ -253,7 +243,7 @@ class FoilPresenter(object):
"""
authors = []
try:
copyright = self._child(foilpresenterfolie.copyright.text_)
copyright = to_str(foilpresenterfolie.copyright.text_)
except AttributeError:
copyright = None
if copyright:
@ -346,7 +336,7 @@ class FoilPresenter(object):
:param song: The song object.
"""
try:
song.ccli_number = self._child(foilpresenterfolie.ccliid)
song.ccli_number = to_str(foilpresenterfolie.ccliid)
except AttributeError:
song.ccli_number = ''
@ -358,7 +348,7 @@ class FoilPresenter(object):
:param song: The song object.
"""
try:
song.comments = self._child(foilpresenterfolie.notiz)
song.comments = to_str(foilpresenterfolie.notiz)
except AttributeError:
song.comments = ''
@ -370,7 +360,7 @@ class FoilPresenter(object):
:param song: The song object.
"""
try:
song.copyright = self._child(foilpresenterfolie.copyright.text_)
song.copyright = to_str(foilpresenterfolie.copyright.text_)
except AttributeError:
song.copyright = ''
@ -396,19 +386,19 @@ class FoilPresenter(object):
VerseType.tags[VerseType.PreChorus]: 1
}
if not hasattr(foilpresenterfolie.strophen, 'strophe'):
self.importer.log_error(self._child(foilpresenterfolie.titel),
self.importer.log_error(to_str(foilpresenterfolie.titel),
str(translate('SongsPlugin.FoilPresenterSongImport',
'Invalid Foilpresenter song file. No verses found.')))
self.save_song = False
return
for strophe in foilpresenterfolie.strophen.strophe:
text = self._child(strophe.text_) if hasattr(strophe, 'text_') else ''
verse_name = self._child(strophe.key)
text = to_str(strophe.text_) if hasattr(strophe, 'text_') else ''
verse_name = to_str(strophe.key)
children = strophe.getchildren()
sortnr = False
for child in children:
if child.tag == 'sortnr':
verse_sortnr = self._child(strophe.sortnr)
verse_sortnr = to_str(strophe.sortnr)
sortnr = True
# In older Version there is no sortnr, but we need one
if not sortnr:
@ -484,7 +474,7 @@ class FoilPresenter(object):
song.song_number = ''
try:
for bucheintrag in foilpresenterfolie.buch.bucheintrag:
book_name = self._child(bucheintrag.name)
book_name = to_str(bucheintrag.name)
if book_name:
book = self.manager.get_object_filtered(Book, Book.name == book_name)
if book is None:
@ -493,8 +483,8 @@ class FoilPresenter(object):
self.manager.save_object(book)
song.song_book_id = book.id
try:
if self._child(bucheintrag.nummer):
song.song_number = self._child(bucheintrag.nummer)
if to_str(bucheintrag.nummer):
song.song_number = to_str(bucheintrag.nummer)
except AttributeError:
pass
# We only support one song book, so take the first one.
@ -512,13 +502,13 @@ class FoilPresenter(object):
try:
for title_string in foilpresenterfolie.titel.titelstring:
if not song.title:
song.title = self._child(title_string)
song.title = to_str(title_string)
song.alternate_title = ''
else:
song.alternate_title = self._child(title_string)
song.alternate_title = to_str(title_string)
except AttributeError:
# Use first line of first verse
first_line = self._child(foilpresenterfolie.strophen.strophe.text_)
first_line = to_str(foilpresenterfolie.strophen.strophe.text_)
song.title = first_line.split('\n')[0]
def _process_topics(self, foilpresenterfolie, song):
@ -530,7 +520,7 @@ class FoilPresenter(object):
"""
try:
for name in foilpresenterfolie.kategorien.name:
topic_text = self._child(name)
topic_text = to_str(name)
if topic_text:
topic = self.manager.get_object_filtered(Topic, Topic.name == topic_text)
if topic is None:
@ -540,3 +530,14 @@ class FoilPresenter(object):
song.topics.append(topic)
except AttributeError:
pass
def to_str(element):
"""
This returns the text of an element as unicode string.
:param element: The element
"""
if element is not None:
return str(element)
return ''

View File

@ -36,28 +36,28 @@ log = logging.getLogger(__name__)
class SongBeamerTypes(object):
MarkTypes = {
'Refrain': VerseType.tags[VerseType.Chorus],
'Chorus': VerseType.tags[VerseType.Chorus],
'Vers': VerseType.tags[VerseType.Verse],
'Verse': VerseType.tags[VerseType.Verse],
'Strophe': VerseType.tags[VerseType.Verse],
'Intro': VerseType.tags[VerseType.Intro],
'Coda': VerseType.tags[VerseType.Ending],
'Ending': VerseType.tags[VerseType.Ending],
'Bridge': VerseType.tags[VerseType.Bridge],
'Interlude': VerseType.tags[VerseType.Bridge],
'Zwischenspiel': VerseType.tags[VerseType.Bridge],
'Pre-Chorus': VerseType.tags[VerseType.PreChorus],
'Pre-Refrain': VerseType.tags[VerseType.PreChorus],
'Misc': VerseType.tags[VerseType.Other],
'Pre-Bridge': VerseType.tags[VerseType.Other],
'Pre-Coda': VerseType.tags[VerseType.Other],
'Part': VerseType.tags[VerseType.Other],
'Teil': VerseType.tags[VerseType.Other],
'Unbekannt': VerseType.tags[VerseType.Other],
'Unknown': VerseType.tags[VerseType.Other],
'Unbenannt': VerseType.tags[VerseType.Other],
'$$M=': VerseType.tags[VerseType.Other]
'refrain': VerseType.tags[VerseType.Chorus],
'chorus': VerseType.tags[VerseType.Chorus],
'vers': VerseType.tags[VerseType.Verse],
'verse': VerseType.tags[VerseType.Verse],
'strophe': VerseType.tags[VerseType.Verse],
'intro': VerseType.tags[VerseType.Intro],
'coda': VerseType.tags[VerseType.Ending],
'ending': VerseType.tags[VerseType.Ending],
'bridge': VerseType.tags[VerseType.Bridge],
'interlude': VerseType.tags[VerseType.Bridge],
'zwischenspiel': VerseType.tags[VerseType.Bridge],
'pre-chorus': VerseType.tags[VerseType.PreChorus],
'pre-refrain': VerseType.tags[VerseType.PreChorus],
'misc': VerseType.tags[VerseType.Other],
'pre-bridge': VerseType.tags[VerseType.Other],
'pre-coda': VerseType.tags[VerseType.Other],
'part': VerseType.tags[VerseType.Other],
'teil': VerseType.tags[VerseType.Other],
'unbekannt': VerseType.tags[VerseType.Other],
'unknown': VerseType.tags[VerseType.Other],
'unbenannt': VerseType.tags[VerseType.Other],
'$$m=': VerseType.tags[VerseType.Other]
}
@ -267,20 +267,20 @@ class SongBeamerImport(SongImport):
def check_verse_marks(self, line):
"""
Check and add the verse's MarkType. Returns ``True`` if the given linE contains a correct verse mark otherwise
Check and add the verse's MarkType. Returns ``True`` if the given line contains a correct verse mark otherwise
``False``.
:param line: The line to check for marks (unicode).
"""
marks = line.split(' ')
if len(marks) <= 2 and marks[0] in SongBeamerTypes.MarkTypes:
self.current_verse_type = SongBeamerTypes.MarkTypes[marks[0]]
if len(marks) <= 2 and marks[0].lower() in SongBeamerTypes.MarkTypes:
self.current_verse_type = SongBeamerTypes.MarkTypes[marks[0].lower()]
if len(marks) == 2:
# If we have a digit, we append it to current_verse_type.
if marks[1].isdigit():
self.current_verse_type += marks[1]
return True
elif marks[0].startswith('$$M='): # this verse-mark cannot be numbered
self.current_verse_type = SongBeamerTypes.MarkTypes['$$M=']
elif marks[0].lower().startswith('$$m='): # this verse-mark cannot be numbered
self.current_verse_type = SongBeamerTypes.MarkTypes['$$m=']
return True
return False

View File

@ -364,7 +364,7 @@ class SongMediaItem(MediaManagerItem):
if QtWidgets.QMessageBox.question(
self, UiStrings().ConfirmDelete,
translate('SongsPlugin.MediaItem',
'Are you sure you want to delete the "%d" selected song(s)?') % len(items),
'Are you sure you want to delete the "%d" selected song(s)?') % len(items),
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No),
QtWidgets.QMessageBox.Yes) == QtWidgets.QMessageBox.No:
return

View File

@ -211,7 +211,8 @@ class SongsPlugin(Plugin):
if self.media_item:
self.media_item.on_export_click()
def about(self):
@staticmethod
def about():
"""
Provides information for the plugin manager to display.
@ -296,7 +297,7 @@ class SongsPlugin(Plugin):
if sfile.startswith('songs_') and sfile.endswith('.sqlite'):
self.application.process_events()
song_dbs.append(os.path.join(db_dir, sfile))
song_count += self._count_songs(os.path.join(db_dir, sfile))
song_count += SongsPlugin._count_songs(os.path.join(db_dir, sfile))
if not song_dbs:
return
self.application.process_events()
@ -343,7 +344,8 @@ class SongsPlugin(Plugin):
for song in songs:
self.manager.delete_object(Song, song.id)
def _count_songs(self, db_file):
@staticmethod
def _count_songs(db_file):
"""
Provide a count of the songs in the database

View File

@ -36,8 +36,8 @@ class SongUsageDeleteForm(QtWidgets.QDialog, Ui_SongUsageDeleteDialog, RegistryP
Constructor
"""
self.manager = manager
super(SongUsageDeleteForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(SongUsageDeleteForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint |
QtCore.Qt.WindowTitleHint)
self.setupUi(self)
self.button_box.clicked.connect(self.on_button_box_clicked)
@ -48,13 +48,14 @@ class SongUsageDeleteForm(QtWidgets.QDialog, Ui_SongUsageDeleteDialog, RegistryP
:param button: The button pressed
"""
if self.button_box.standardButton(button) == QtWidgets.QDialogButtonBox.Ok:
ret = QtWidgets.QMessageBox.question(
self,
translate('SongUsagePlugin.SongUsageDeleteForm', 'Delete Selected Song Usage Events?'),
translate('SongUsagePlugin.SongUsageDeleteForm',
'Are you sure you want to delete selected Song Usage data?'),
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No),
QtWidgets.QMessageBox.No)
ret = QtWidgets.QMessageBox.question(self,
translate('SongUsagePlugin.SongUsageDeleteForm',
'Delete Selected Song Usage Events?'),
translate('SongUsagePlugin.SongUsageDeleteForm',
'Are you sure you want to delete selected Song Usage data?'),
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes |
QtWidgets.QMessageBox.No),
QtWidgets.QMessageBox.No)
if ret == QtWidgets.QMessageBox.Yes:
delete_date = self.delete_calendar.selectedDate().toPyDate()
self.manager.delete_all_objects(SongUsageItem, SongUsageItem.usagedate <= delete_date)

View File

@ -44,8 +44,7 @@ class SongUsageDetailForm(QtWidgets.QDialog, Ui_SongUsageDetailDialog, RegistryP
"""
Initialise the form
"""
super(SongUsageDetailForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
super(SongUsageDetailForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.plugin = plugin
self.setupUi(self)

View File

@ -227,7 +227,8 @@ class SongUsagePlugin(Plugin):
self.song_usage_detail_form.initialise()
self.song_usage_detail_form.exec()
def about(self):
@staticmethod
def about():
"""
The plugin about text

View File

@ -25,10 +25,9 @@ Package to test the openlp.core.lib.projector.pjlink1 package.
from unittest import TestCase
from mock import MagicMock, patch
from openlp.core.lib.projector.pjlink1 import PJLink1
from tests.functional import patch
from tests.resources.projector.data import TEST_PIN, TEST_SALT, TEST_CONNECT_AUTHENTICATE
pjlink_test = PJLink1(name='test', ip='127.0.0.1', pin=TEST_PIN, no_poll=True)

View File

@ -142,12 +142,10 @@ class TestMainDisplay(TestCase, TestMixin):
mocked_bibles_plugin.refresh_css.assert_called_with(main_display.frame)
@skipUnless(is_macosx(), 'Can only run test on Mac OS X due to pyobjc dependency.')
def macosx_display_window_flags_state_test(self, is_macosx):
def macosx_display_window_flags_state_test(self):
"""
Test that on Mac OS X we set the proper window flags
"""
if not is_macosx():
self.skipTest('Can only run test on Mac OS X due to pyobjc dependency.')
# GIVEN: A new SlideController instance on Mac OS X.
self.screens.set_current_display(0)
display = MagicMock()

View File

@ -40,7 +40,7 @@ class MediaPluginTest(TestCase, TestMixin):
@patch(u'openlp.plugins.media.mediaplugin.Plugin.initialise')
@patch(u'openlp.plugins.media.mediaplugin.Settings')
def initialise_test(self, MockedSettings, mocked_initialise):
def initialise_test(self, _mocked_settings, mocked_initialise):
"""
Test that the initialise() method overwrites the built-in one, but still calls it
"""
@ -48,7 +48,7 @@ class MediaPluginTest(TestCase, TestMixin):
media_plugin = MediaPlugin()
mocked_settings = MagicMock()
mocked_settings.get_files_from_config.return_value = True # Not the real value, just need something "true-ish"
MockedSettings.return_value = mocked_settings
_mocked_settings.return_value = mocked_settings
# WHEN: initialise() is called
media_plugin.initialise()
@ -57,3 +57,11 @@ class MediaPluginTest(TestCase, TestMixin):
mocked_settings.get_files_from_config.assert_called_with(media_plugin)
mocked_settings.setValue.assert_called_with('media/media files', True)
mocked_initialise.assert_called_with()
def test_about_text(self):
# GIVEN: The MediaPlugin
# WHEN: Retrieving the about text
# THEN: about() should return a string object
self.assertIsInstance(MediaPlugin.about(), str)
# THEN: about() should return a non-empty string
self.assertNotEquals(len(MediaPlugin.about()), 0)

View File

@ -39,7 +39,7 @@ class TestFoilPresenter(TestCase):
"""
# TODO: The following modules still need tests written for
# xml_to_song
# _child
# to_str
# _process_authors
# _process_cclinumber
# _process_comments
@ -50,7 +50,7 @@ class TestFoilPresenter(TestCase):
# _process_topics
def setUp(self):
self.child_patcher = patch('openlp.plugins.songs.lib.importers.foilpresenter.FoilPresenter._child')
self.to_str_patcher = patch('openlp.plugins.songs.lib.importers.foilpresenter.to_str')
self.clean_song_patcher = patch('openlp.plugins.songs.lib.importers.foilpresenter.clean_song')
self.objectify_patcher = patch('openlp.plugins.songs.lib.importers.foilpresenter.objectify')
self.process_authors_patcher = \
@ -72,7 +72,7 @@ class TestFoilPresenter(TestCase):
self.song_xml_patcher = patch('openlp.plugins.songs.lib.importers.foilpresenter.SongXML')
self.translate_patcher = patch('openlp.plugins.songs.lib.importers.foilpresenter.translate')
self.mocked_child = self.child_patcher.start()
self.mocked_child = self.to_str_patcher.start()
self.mocked_clean_song = self.clean_song_patcher.start()
self.mocked_objectify = self.objectify_patcher.start()
self.mocked_process_authors = self.process_authors_patcher.start()
@ -92,7 +92,7 @@ class TestFoilPresenter(TestCase):
self.mocked_song_import = MagicMock()
def tearDown(self):
self.child_patcher.stop()
self.to_str_patcher.stop()
self.clean_song_patcher.stop()
self.objectify_patcher.stop()
self.process_authors_patcher.stop()

View File

@ -22,10 +22,13 @@
"""
This module contains tests for the OpenOffice/LibreOffice importer.
"""
from unittest import TestCase
from unittest import TestCase, SkipTest
from openlp.core.common import Registry
from openlp.plugins.songs.lib.importers.openoffice import OpenOfficeImport
try:
from openlp.plugins.songs.lib.importers.openoffice import OpenOfficeImport
except ImportError:
raise SkipTest('Could not import OpenOfficeImport probably due to unavailability of uno')
from tests.functional import MagicMock, patch
from tests.helpers.testmixin import TestMixin

View File

@ -28,7 +28,7 @@ from unittest import TestCase
from tests.helpers.songfileimport import SongImportTestHelper
from tests.functional import MagicMock, patch
from openlp.plugins.songs.lib.importers.songbeamer import SongBeamerImport
from openlp.plugins.songs.lib.importers.songbeamer import SongBeamerImport, SongBeamerTypes
from openlp.core.common import Registry
TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__),
@ -131,22 +131,22 @@ class TestSongBeamerImport(TestCase):
self.assertEqual(self.current_verse_type, 'c', '<Refrain> should be interpreted as <c>')
# GIVEN: line with unnumbered verse-type and trailing space
line = 'Refrain '
line = 'ReFrain '
self.current_verse_type = None
# WHEN: line is being checked for verse marks
result = SongBeamerImport.check_verse_marks(self, line)
# THEN: we should get back true and c as self.current_verse_type
self.assertTrue(result, 'Versemark for <Refrain > should be found, value true')
self.assertEqual(self.current_verse_type, 'c', '<Refrain > should be interpreted as <c>')
self.assertTrue(result, 'Versemark for <ReFrain > should be found, value true')
self.assertEqual(self.current_verse_type, 'c', '<ReFrain > should be interpreted as <c>')
# GIVEN: line with numbered verse-type
line = 'Verse 1'
line = 'VersE 1'
self.current_verse_type = None
# WHEN: line is being checked for verse marks
result = SongBeamerImport.check_verse_marks(self, line)
# THEN: we should get back true and v1 as self.current_verse_type
self.assertTrue(result, 'Versemark for <Verse 1> should be found, value true')
self.assertEqual(self.current_verse_type, 'v1', u'<Verse 1> should be interpreted as <v1>')
self.assertTrue(result, 'Versemark for <VersE 1> should be found, value true')
self.assertEqual(self.current_verse_type, 'v1', u'<VersE 1> should be interpreted as <v1>')
# GIVEN: line with special unnumbered verse-mark (used in Songbeamer to allow usage of non-supported tags)
line = '$$M=special'
@ -192,3 +192,12 @@ class TestSongBeamerImport(TestCase):
# THEN: we should get back false and none as self.current_verse_type
self.assertFalse(result, 'No versemark for <> should be found, value false')
self.assertIsNone(self.current_verse_type, '<> should be interpreted as none versemark')
def test_verse_marks_defined_in_lowercase(self):
"""
Test that the verse marks are all defined in lowercase
"""
# GIVEN: SongBeamber MarkTypes
for tag in SongBeamerTypes.MarkTypes.keys():
# THEN: tag should be defined in lowercase
self.assertEquals(tag, tag.lower(), 'Tags should be defined in lowercase')

View File

@ -40,7 +40,7 @@ class TestSongFormat(TestCase):
# WHEN: Retrieving the format list
# THEN: All SongFormats should be returned
self.assertEquals(len(SongFormat.get_format_list()), len(SongFormat.__attributes__),
"The returned SongFormats don't match the stored ones")
"The returned SongFormats don't match the stored ones")
def test_get_attributed_no_attributes(self):
"""
@ -51,7 +51,7 @@ class TestSongFormat(TestCase):
for song_format in SongFormat.get_format_list():
# THEN: All attributes associated with the SongFormat should be returned
self.assertEquals(SongFormat.get(song_format), SongFormat.__attributes__[song_format],
"The returned attributes don't match the stored ones")
"The returned attributes don't match the stored ones")
def test_get_attributed_single_attribute(self):
"""
@ -63,13 +63,13 @@ class TestSongFormat(TestCase):
for attribute in SongFormat.get(song_format).keys():
# THEN: Return the attribute
self.assertEquals(SongFormat.get(song_format, attribute), SongFormat.get(song_format)[attribute],
"The returned attribute doesn't match the stored one")
"The returned attribute doesn't match the stored one")
# WHEN: Retrieving an attribute that was not overridden
for attribute in SongFormat.__defaults__.keys():
if attribute not in SongFormat.get(song_format).keys():
# THEN: Return the default value
self.assertEquals(SongFormat.get(song_format, attribute), SongFormat.__defaults__[attribute],
"The returned attribute does not match the default values stored")
"The returned attribute does not match the default values stored")
def test_get_attributed_multiple_attributes(self):
"""
@ -80,4 +80,16 @@ class TestSongFormat(TestCase):
for song_format in SongFormat.get_format_list():
# THEN: Return all attributes that were specified
self.assertEquals(len(SongFormat.get(song_format, 'canDisable', 'availability')), 2,
"Did not return the correct number of attributes when retrieving multiple attributes at once")
"Did not return the correct number of attributes"
" when retrieving multiple attributes at once")
def test_get_format_list_returns_ordered_list(self):
"""
Test that get_format_list() returns a list that is ordered
according to the order specified in SongFormat
"""
# GIVEN: The SongFormat class
# WHEN: Retrieving all formats
# THEN: The returned list should be sorted according to the ordering defined in SongFormat
self.assertEquals(sorted(SongFormat.get_format_list()), SongFormat.get_format_list(),
"The list returned should be sorted according to the ordering in SongFormat")

View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2016 OpenLP Developers #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
"""
Tests for the Songusage plugin
"""

View File

@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2016 OpenLP Developers #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
"""
This module contains tests for the Songusage plugin.
"""
from unittest import TestCase
from openlp.plugins.songusage.songusageplugin import SongUsagePlugin
class TestSongUsage(TestCase):
def test_about_text(self):
# GIVEN: The SongUsagePlugin
# WHEN: Retrieving the about text
# THEN: about() should return a string object
self.assertIsInstance(SongUsagePlugin.about(), str)
# THEN: about() should return a non-empty string
self.assertNotEquals(len(SongUsagePlugin.about()), 0)
self.assertNotEquals(len(SongUsagePlugin.about()), 0)

View File

@ -29,7 +29,7 @@ from subprocess import Popen, PIPE
TAGS1 = {'1.9.0', '1.9.1', '1.9.2', '1.9.3', '1.9.4', '1.9.5', '1.9.6', '1.9.7', '1.9.8', '1.9.9', '1.9.10',
'1.9.11', '1.9.12', '2.0', '2.1.0', '2.1.1', '2.1.2', '2.1.3', '2.1.4', '2.1.5', '2.1.6', '2.2',
'2.3.1'}
'2.3.1', '2.3.2'}
class TestBzrTags(TestCase):