merge trunk

This commit is contained in:
Samuel Mehrbrodt 2014-05-13 11:50:36 +02:00
commit 35e23456fe
41 changed files with 220 additions and 53 deletions

View File

@ -32,3 +32,4 @@ tests.kdev4
*.orig
__pycache__
*.dll
.directory

View File

@ -1,16 +1,15 @@
OpenLP 2.0
==========
OpenLP
======
You're probably reading this because you've just downloaded the source code for
OpenLP 2.0. If you are looking for the installer file, please go to the download
OpenLP. If you are looking for the installer file, please go to the download
page on the web site::
http://openlp.org/en/download.html
http://openlp.org/download
If you're looking for how to contribute to OpenLP, then please look at the
OpenLP wiki::
http://wiki.openlp.org/
Thanks for downloading OpenLP 2.0!
Thanks for downloading OpenLP!

View File

@ -44,7 +44,7 @@ class Ui_AboutDialog(object):
Set up the UI for the dialog.
"""
about_dialog.setObjectName('about_dialog')
about_dialog.setWindowIcon(build_icon(':/icon/openlp-logo-16x16.png'))
about_dialog.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
self.about_dialog_layout = QtGui.QVBoxLayout(about_dialog)
self.about_dialog_layout.setObjectName('about_dialog_layout')
self.logo_label = QtGui.QLabel(about_dialog)

View File

@ -32,7 +32,7 @@ The GUI widgets of the exception dialog.
from PyQt4 import QtGui
from openlp.core.lib import translate
from openlp.core.lib import translate, build_icon
from openlp.core.lib.ui import create_button, create_button_box
@ -45,6 +45,7 @@ class Ui_ExceptionDialog(object):
Set up the UI.
"""
exception_dialog.setObjectName('exception_dialog')
exception_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
self.exception_layout = QtGui.QVBoxLayout(exception_dialog)
self.exception_layout.setObjectName('exception_layout')
self.message_layout = QtGui.QHBoxLayout()

View File

@ -31,7 +31,7 @@ The UI widgets for the rename dialog
"""
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
from openlp.core.lib import translate, build_icon
from openlp.core.lib.ui import create_button_box
@ -44,6 +44,7 @@ class Ui_FileRenameDialog(object):
Set up the UI
"""
file_rename_dialog.setObjectName('file_rename_dialog')
file_rename_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
file_rename_dialog.resize(300, 10)
self.dialog_layout = QtGui.QGridLayout(file_rename_dialog)
self.dialog_layout.setObjectName('dialog_layout')

View File

@ -32,6 +32,7 @@ The UI widgets of the language selection dialog.
from PyQt4 import QtGui
from openlp.core.common import translate
from openlp.core.lib import build_icon
from openlp.core.lib.ui import create_button_box
@ -44,6 +45,7 @@ class Ui_FirstTimeLanguageDialog(object):
Set up the UI.
"""
language_dialog.setObjectName('language_dialog')
language_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
language_dialog.resize(300, 50)
self.dialog_layout = QtGui.QVBoxLayout(language_dialog)
self.dialog_layout.setContentsMargins(8, 8, 8, 8)

View File

@ -34,6 +34,7 @@ from PyQt4 import QtCore, QtGui
import sys
from openlp.core.common import translate
from openlp.core.lib import build_icon
from openlp.core.lib.ui import add_welcome_page
@ -60,6 +61,7 @@ class Ui_FirstTimeWizard(object):
Set up the UI.
"""
first_time_wizard.setObjectName('first_time_wizard')
first_time_wizard.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
first_time_wizard.resize(550, 386)
first_time_wizard.setModal(True)
first_time_wizard.setWizardStyle(QtGui.QWizard.ModernStyle)

View File

@ -45,6 +45,7 @@ class Ui_FormattingTagDialog(object):
Set up the UI
"""
formatting_tag_dialog.setObjectName('formatting_tag_dialog')
formatting_tag_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
formatting_tag_dialog.resize(725, 548)
self.list_data_grid_layout = QtGui.QVBoxLayout(formatting_tag_dialog)
self.list_data_grid_layout.setMargin(8)

View File

@ -89,7 +89,7 @@ class Ui_MainWindow(object):
Set up the user interface
"""
main_window.setObjectName('MainWindow')
main_window.setWindowIcon(build_icon(':/icon/openlp-logo-64x64.png'))
main_window.setWindowIcon(build_icon(':/icon/openlp-logo.svg'))
main_window.setDockNestingEnabled(True)
# Set up the main container, which contains all the other form widgets.
self.main_content = QtGui.QWidget(main_window)

View File

@ -32,6 +32,7 @@ The UI widgets of the plugin view dialog
from PyQt4 import QtCore, QtGui
from openlp.core.common import UiStrings, translate
from openlp.core.lib import build_icon
from openlp.core.lib.ui import create_button_box
@ -44,6 +45,7 @@ class Ui_PluginViewDialog(object):
Set up the UI
"""
pluginViewDialog.setObjectName('pluginViewDialog')
pluginViewDialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
pluginViewDialog.setWindowModality(QtCore.Qt.ApplicationModal)
self.plugin_layout = QtGui.QVBoxLayout(pluginViewDialog)
self.plugin_layout.setObjectName('plugin_layout')

View File

@ -56,6 +56,7 @@ class Ui_PrintServiceDialog(object):
Set up the UI
"""
print_service_dialog.setObjectName('print_service_dialog')
print_service_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
print_service_dialog.resize(664, 594)
self.main_layout = QtGui.QVBoxLayout(print_service_dialog)
self.main_layout.setSpacing(0)

View File

@ -32,6 +32,7 @@ The UI widgets for the service item edit dialog
from PyQt4 import QtGui
from openlp.core.common import translate
from openlp.core.lib import build_icon
from openlp.core.lib.ui import create_button_box, create_button
@ -44,6 +45,7 @@ class Ui_ServiceItemEditDialog(object):
Set up the UI
"""
serviceItemEditDialog.setObjectName('serviceItemEditDialog')
serviceItemEditDialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
self.dialog_layout = QtGui.QGridLayout(serviceItemEditDialog)
self.dialog_layout.setContentsMargins(8, 8, 8, 8)
self.dialog_layout.setSpacing(8)

View File

@ -45,8 +45,8 @@ class Ui_SettingsDialog(object):
Set up the UI
"""
settings_dialog.setObjectName('settings_dialog')
settings_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
settings_dialog.resize(800, 500)
settings_dialog.setWindowIcon(build_icon(':/system/system_settings.png'))
self.dialog_layout = QtGui.QGridLayout(settings_dialog)
self.dialog_layout.setObjectName('dialog_layout')
self.dialog_layout.setMargin(8)

View File

@ -66,6 +66,7 @@ class Ui_ShortcutListDialog(object):
Set up the UI
"""
shortcutListDialog.setObjectName('shortcutListDialog')
shortcutListDialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
shortcutListDialog.resize(500, 438)
self.shortcut_list_layout = QtGui.QVBoxLayout(shortcutListDialog)
self.shortcut_list_layout.setObjectName('shortcut_list_layout')

View File

@ -32,6 +32,7 @@ The UI widgets for the time dialog
from PyQt4 import QtCore, QtGui
from openlp.core.common import UiStrings, translate
from openlp.core.lib import build_icon
from openlp.core.lib.ui import create_button_box
@ -44,6 +45,7 @@ class Ui_StartTimeDialog(object):
Set up the UI
"""
StartTimeDialog.setObjectName('StartTimeDialog')
StartTimeDialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
StartTimeDialog.resize(350, 10)
self.dialog_layout = QtGui.QGridLayout(StartTimeDialog)
self.dialog_layout.setObjectName('dialog_layout')

View File

@ -32,6 +32,7 @@ The layout of the theme
from PyQt4 import QtGui
from openlp.core.common import translate
from openlp.core.lib import build_icon
from openlp.core.lib.ui import create_button_box
@ -44,6 +45,7 @@ class Ui_ThemeLayoutDialog(object):
Set up the UI
"""
themeLayoutDialog.setObjectName('themeLayoutDialogDialog')
themeLayoutDialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
self.preview_layout = QtGui.QVBoxLayout(themeLayoutDialog)
self.preview_layout.setObjectName('preview_layout')
self.preview_area = QtGui.QWidget(themeLayoutDialog)

View File

@ -46,6 +46,7 @@ class Ui_ThemeWizard(object):
Set up the UI
"""
themeWizard.setObjectName('OpenLP.ThemeWizard')
themeWizard.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
themeWizard.setModal(True)
themeWizard.setWizardStyle(QtGui.QWizard.ModernStyle)
themeWizard.setOptions(QtGui.QWizard.IndependentPages |

View File

@ -118,6 +118,7 @@ class OpenLPWizard(QtGui.QWizard, RegistryProperties):
"""
Set up the wizard UI.
"""
self.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
self.setModal(True)
self.setWizardStyle(QtGui.QWizard.ModernStyle)
self.setOptions(QtGui.QWizard.IndependentPages |

View File

@ -46,7 +46,7 @@ class Ui_AlertDialog(object):
"""
alert_dialog.setObjectName('alert_dialog')
alert_dialog.resize(400, 300)
alert_dialog.setWindowIcon(build_icon(':/icon/openlp-logo-16x16.png'))
alert_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
self.alert_dialog_layout = QtGui.QGridLayout(alert_dialog)
self.alert_dialog_layout.setObjectName('alert_dialog_layout')
self.alert_text_layout = QtGui.QFormLayout()

View File

@ -30,12 +30,14 @@
from PyQt4 import QtCore, QtGui
from openlp.core.common import translate
from openlp.core.lib import build_icon
from openlp.core.lib.ui import create_button_box
class Ui_BookNameDialog(object):
def setupUi(self, book_name_dialog):
book_name_dialog.setObjectName('book_name_dialog')
book_name_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
book_name_dialog.resize(400, 271)
self.book_name_layout = QtGui.QVBoxLayout(book_name_dialog)
self.book_name_layout.setSpacing(8)

View File

@ -39,8 +39,8 @@ from openlp.plugins.bibles.lib.db import BiblesResourcesDB
class Ui_EditBibleDialog(object):
def setupUi(self, edit_bible_dialog):
edit_bible_dialog.setObjectName('edit_bible_dialog')
edit_bible_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
edit_bible_dialog.resize(520, 400)
edit_bible_dialog.setWindowIcon(build_icon(':/icon/openlp-logo-16x16.png'))
edit_bible_dialog.setModal(True)
self.dialog_layout = QtGui.QVBoxLayout(edit_bible_dialog)
self.dialog_layout.setSpacing(8)

View File

@ -30,12 +30,14 @@
from PyQt4 import QtGui
from openlp.core.common import translate
from openlp.core.lib import build_icon
from openlp.core.lib.ui import create_button_box
class Ui_LanguageDialog(object):
def setupUi(self, language_dialog):
language_dialog.setObjectName('language_dialog')
language_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
language_dialog.resize(400, 165)
self.language_layout = QtGui.QVBoxLayout(language_dialog)
self.language_layout.setSpacing(8)

View File

@ -60,7 +60,6 @@ class BibleMediaItem(MediaManagerItem):
log.info('Bible Media Item loaded')
def __init__(self, parent, plugin):
self.icon_path = 'songs/song'
self.lock_icon = build_icon(':/bibles/bibles_search_lock.png')
self.unlock_icon = build_icon(':/bibles/bibles_search_unlock.png')
MediaManagerItem.__init__(self, parent, plugin)
@ -172,6 +171,7 @@ class BibleMediaItem(MediaManagerItem):
self.page_layout.addWidget(tab)
tab.setVisible(False)
lock_button.toggled.connect(self.on_lock_button_toggled)
second_combo_box.currentIndexChanged.connect(self.on_second_bible_combobox_index_changed)
setattr(self, prefix + 'VersionLabel', version_label)
setattr(self, prefix + 'VersionComboBox', version_combo_box)
setattr(self, prefix + 'SecondLabel', second_label)
@ -263,11 +263,15 @@ class BibleMediaItem(MediaManagerItem):
def config_update(self):
log.debug('config_update')
if Settings().value(self.settings_section + '/second bibles'):
self.quickSecondLabel.setVisible(True)
self.quickSecondComboBox.setVisible(True)
self.advancedSecondLabel.setVisible(True)
self.advancedSecondComboBox.setVisible(True)
self.quickSecondLabel.setVisible(True)
self.quickSecondComboBox.setVisible(True)
else:
self.quickSecondLabel.setVisible(False)
self.quickSecondComboBox.setVisible(False)
self.advancedSecondLabel.setVisible(False)
self.advancedSecondComboBox.setVisible(False)
self.quickSecondLabel.setVisible(False)
@ -459,6 +463,17 @@ class BibleMediaItem(MediaManagerItem):
books.sort(key=get_locale_key)
set_case_insensitive_completer(books, self.quick_search_edit)
def on_second_bible_combobox_index_changed(self, selection):
"""
Activate the style combobox only when no second bible is selected
"""
if selection == 0:
self.quickStyleComboBox.setEnabled(True)
self.advancedStyleComboBox.setEnabled(True)
else:
self.quickStyleComboBox.setEnabled(False)
self.advancedStyleComboBox.setEnabled(False)
def on_import_click(self):
if not hasattr(self, 'import_wizard'):
self.import_wizard = BibleImportForm(self, self.plugin.manager, self.plugin)

View File

@ -41,8 +41,8 @@ class Ui_CustomEditDialog(object):
:param custom_edit_dialog: The Dialog
"""
custom_edit_dialog.setObjectName('custom_edit_dialog')
custom_edit_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
custom_edit_dialog.resize(450, 350)
custom_edit_dialog.setWindowIcon(build_icon(':/icon/openlp-logo-16x16.png'))
self.dialog_layout = QtGui.QVBoxLayout(custom_edit_dialog)
self.dialog_layout.setObjectName('dialog_layout')
self.title_layout = QtGui.QHBoxLayout()

View File

@ -30,13 +30,14 @@
from PyQt4 import QtGui
from openlp.core.common import UiStrings, translate
from openlp.core.lib import SpellTextEdit
from openlp.core.lib import SpellTextEdit, build_icon
from openlp.core.lib.ui import create_button, create_button_box
class Ui_CustomSlideEditDialog(object):
def setupUi(self, custom_slide_edit_dialog):
custom_slide_edit_dialog.setObjectName('custom_slide_edit_dialog')
custom_slide_edit_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
custom_slide_edit_dialog.resize(350, 300)
self.dialog_layout = QtGui.QVBoxLayout(custom_slide_edit_dialog)
self.slide_text_edit = SpellTextEdit(self)

View File

@ -43,8 +43,8 @@ class Ui_AuthorsDialog(object):
Set up the UI for the dialog.
"""
authors_dialog.setObjectName('authors_dialog')
authors_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
authors_dialog.resize(300, 10)
authors_dialog.setWindowIcon(build_icon(':/icon/openlp-logo-16x16.png'))
authors_dialog.setModal(True)
self.dialog_layout = QtGui.QVBoxLayout(authors_dialog)
self.dialog_layout.setObjectName('dialog_layout')

View File

@ -43,8 +43,8 @@ class Ui_EditSongDialog(object):
"""
def setupUi(self, edit_song_dialog):
edit_song_dialog.setObjectName('edit_song_dialog')
edit_song_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
edit_song_dialog.resize(650, 400)
edit_song_dialog.setWindowIcon(build_icon(':/icon/openlp-logo-16x16.png'))
edit_song_dialog.setModal(True)
self.dialog_layout = QtGui.QVBoxLayout(edit_song_dialog)
self.dialog_layout.setSpacing(8)

View File

@ -107,6 +107,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog, RegistryProperties):
self.audio_list_widget.setAlternatingRowColors(True)
self.find_verse_split = re.compile('---\[\]---\n', re.UNICODE)
self.whitespace = re.compile(r'\W+', re.UNICODE)
self.find_tags = re.compile(u'\{/?\w+\}', re.UNICODE)
def _load_objects(self, cls, combo, cache):
"""
@ -234,8 +235,57 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog, RegistryProperties):
self.manager.save_object(book)
else:
return False
# Validate tags (lp#1199639)
misplaced_tags = []
verse_tags = []
for i in range(self.verse_list_widget.rowCount()):
item = self.verse_list_widget.item(i, 0)
tags = self.find_tags.findall(item.text())
field = item.data(QtCore.Qt.UserRole)
verse_tags.append(field)
if not self._validate_tags(tags):
misplaced_tags.append('%s %s' % (VerseType.translated_name(field[0]), field[1:]))
if misplaced_tags:
critical_error_message_box(
message=translate('SongsPlugin.EditSongForm',
'There are misplaced formatting tags in the following verses:\n\n%s\n\n'
'Please correct these tags before continuing.' % ', '.join(misplaced_tags)))
return False
for tag in verse_tags:
if verse_tags.count(tag) > 26:
# lp#1310523: OpenLyrics allows only a-z variants of one verse:
# http://openlyrics.info/dataformat.html#verse-name
critical_error_message_box(message=translate(
'SongsPlugin.EditSongForm', 'You have %(count)s verses named %(name)s %(number)s. '
'You can have at most 26 verses with the same name' %
{'count': verse_tags.count(tag),
'name': VerseType.translated_name(tag[0]),
'number': tag[1:]}))
return False
return True
def _validate_tags(self, tags):
"""
Validates a list of tags
Deletes the first affiliated tag pair which is located side by side in the list
and call itself recursively with the shortened tag list.
If there is any misplaced tag in the list, either the length of the tag list is not even,
or the function won't find any tag pairs side by side.
If there is no misplaced tag, the length of the list will be zero on any recursive run.
:param tags: A list of tags
:return: True if the function can't find any mismatched tags. Else False.
"""
if len(tags) == 0:
return True
if len(tags) % 2 != 0:
return False
for i in range(len(tags)-1):
if tags[i+1] == "{/" + tags[i][1:]:
del tags[i:i+2]
return self._validate_tags(tags)
return False
def _process_lyrics(self):
"""
Process the lyric data entered by the user into the OpenLP XML format.

View File

@ -37,6 +37,7 @@ from openlp.plugins.songs.lib import VerseType
class Ui_EditVerseDialog(object):
def setupUi(self, edit_verse_dialog):
edit_verse_dialog.setObjectName('edit_verse_dialog')
edit_verse_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
edit_verse_dialog.resize(400, 400)
edit_verse_dialog.setModal(True)
self.dialog_layout = QtGui.QVBoxLayout(edit_verse_dialog)

View File

@ -42,10 +42,10 @@ class Ui_MediaFilesDialog(object):
Set up the user interface.
"""
media_files_dialog.setObjectName('media_files_dialog')
media_files_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
media_files_dialog.setWindowModality(QtCore.Qt.ApplicationModal)
media_files_dialog.resize(400, 300)
media_files_dialog.setModal(True)
media_files_dialog.setWindowIcon(build_icon(':/icon/openlp-logo-16x16.png'))
self.files_vertical_layout = QtGui.QVBoxLayout(media_files_dialog)
self.files_vertical_layout.setSpacing(8)
self.files_vertical_layout.setMargin(8)

View File

@ -29,7 +29,7 @@
from PyQt4 import QtGui
from openlp.core.lib import translate
from openlp.core.lib import translate, build_icon
from openlp.core.lib.ui import create_button_box
@ -42,6 +42,7 @@ class Ui_SongBookDialog(object):
Set up the user interface.
"""
song_book_dialog.setObjectName('song_book_dialog')
song_book_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
song_book_dialog.resize(300, 10)
self.dialog_layout = QtGui.QVBoxLayout(song_book_dialog)
self.dialog_layout.setObjectName('dialog_layout')

View File

@ -44,6 +44,7 @@ class Ui_SongMaintenanceDialog(object):
Set up the user interface for the song maintenance dialog
"""
song_maintenance_dialog.setObjectName('song_maintenance_dialog')
song_maintenance_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
song_maintenance_dialog.setWindowModality(QtCore.Qt.ApplicationModal)
song_maintenance_dialog.resize(10, 350)
self.dialog_layout = QtGui.QGridLayout(song_maintenance_dialog)

View File

@ -29,7 +29,7 @@
from PyQt4 import QtGui
from openlp.core.lib import translate
from openlp.core.lib import translate, build_icon
from openlp.core.lib.ui import create_button_box
@ -42,6 +42,7 @@ class Ui_TopicsDialog(object):
Set up the user interface for the topics dialog.
"""
topics_dialog.setObjectName('topics_dialog')
topics_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
topics_dialog.resize(300, 10)
self.dialog_layout = QtGui.QVBoxLayout(topics_dialog)
self.dialog_layout.setObjectName('dialog_layout')

View File

@ -206,14 +206,14 @@ class VerseType(object):
Return the VerseType for a given tag
:param verse_tag: The string to return a VerseType for
:param default: Default return value if no matching tag is found
:param default: Default return value if no matching tag is found (a valid VerseType or None)
:return: A VerseType of the tag
"""
verse_tag = verse_tag[0].lower()
for num, tag in enumerate(VerseType.tags):
if verse_tag == tag:
return num
if len(VerseType.names) > default:
if default in range(0, len(VerseType.names)) or default is None:
return default
else:
return VerseType.Other
@ -231,7 +231,7 @@ class VerseType(object):
for num, tag in enumerate(VerseType.translated_tags):
if verse_tag == tag:
return num
if len(VerseType.names) > default:
if default in range(0, len(VerseType.names)) or default is None:
return default
else:
return VerseType.Other

View File

@ -68,7 +68,7 @@ class SundayPlusImport(SongImport):
for filename in self.import_source:
if self.stop_import_flag:
return
song_file = open(filename)
song_file = open(filename, 'rb')
self.do_import_file(song_file)
song_file.close()
@ -103,7 +103,7 @@ class SundayPlusImport(SongImport):
# Now we are looking for the name.
if data[i:i + 1] == '#':
name_end = data.find(':', i + 1)
name = data[i + 1:name_end]
name = data[i + 1:name_end].upper()
i = name_end + 1
while data[i:i + 1] == ' ':
i += 1
@ -129,13 +129,13 @@ class SundayPlusImport(SongImport):
value = data[i:end]
# If we are in the main group.
if not cell:
if name == 'title':
if name == 'TITLE':
self.title = self.decode(self.unescape(value))
elif name == 'Author':
elif name == 'AUTHOR':
author = self.decode(self.unescape(value))
if len(author):
self.add_author(author)
elif name == 'Copyright':
elif name == 'COPYRIGHT':
self.copyright = self.decode(self.unescape(value))
elif name[0:4] == 'CELL':
self.parse(value, cell=name[4:])
@ -147,12 +147,12 @@ class SundayPlusImport(SongImport):
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':
# Hotkey always appears after MARKER_NAME, so it
elif name == 'HOTKEY':
# HOTKEY always appears after MARKER_NAME, so it
# effectively overrides MARKER_NAME, if present.
if len(value) and value in list(HOTKEY_TO_VERSE_TYPE.keys()):
verse_type = HOTKEY_TO_VERSE_TYPE[value]
if name == 'rtf':
if name == 'RTF':
value = self.unescape(value)
result = strip_rtf(value, self.encoding)
if result is None:

View File

@ -310,9 +310,9 @@ class OpenLyrics(object):
verse_tag = verse[0]['type'][0].lower()
verse_number = verse[0]['label']
verse_def = verse_tag + verse_number
verse_tags.append(verse_def)
# Create the letter from the number of duplicates
verse[0]['suffix'] = chr(96 + verse_tags.count(verse_def))
verse[0][u'suffix'] = chr(97 + (verse_tags.count(verse_def) % 26))
verse_tags.append(verse_def)
# If the verse tag is a duplicate use the suffix letter
for verse in verse_list:
verse_tag = verse[0]['type'][0].lower()

View File

@ -30,6 +30,7 @@
from PyQt4 import QtCore, QtGui
from openlp.core.common import translate
from openlp.core.lib import build_icon
from openlp.core.lib.ui import create_button_box
@ -44,6 +45,7 @@ class Ui_SongUsageDeleteDialog(object):
:param song_usage_delete_dialog:
"""
song_usage_delete_dialog.setObjectName('song_usage_delete_dialog')
song_usage_delete_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
song_usage_delete_dialog.resize(291, 243)
self.vertical_layout = QtGui.QVBoxLayout(song_usage_delete_dialog)
self.vertical_layout.setSpacing(8)

View File

@ -45,6 +45,7 @@ class Ui_SongUsageDetailDialog(object):
:param song_usage_detail_dialog:
"""
song_usage_detail_dialog.setObjectName('song_usage_detail_dialog')
song_usage_detail_dialog.setWindowIcon(build_icon(u':/icon/openlp-logo.svg'))
song_usage_detail_dialog.resize(609, 413)
self.vertical_layout = QtGui.QVBoxLayout(song_usage_detail_dialog)
self.vertical_layout.setSpacing(8)

View File

@ -82,6 +82,21 @@ class TestUi(TestCase):
self.assertEqual(1, len(btnbox.buttons()))
self.assertEqual(QtGui.QDialogButtonBox.HelpRole, btnbox.buttonRole(btnbox.buttons()[0]))
def test_create_horizontal_adjusting_combo_box(self):
"""
Test creating a horizontal adjusting combo box
"""
# GIVEN: A dialog
dialog = QtGui.QDialog()
# WHEN: We create the combobox
combo = create_horizontal_adjusting_combo_box(dialog, 'combo1')
# THEN: We should get a ComboBox
self.assertIsInstance(combo, QtGui.QComboBox)
self.assertEqual('combo1', combo.objectName())
self.assertEqual(QtGui.QComboBox.AdjustToMinimumContentsLength, combo.sizeAdjustPolicy())
def test_create_button(self):
"""
Test creating a button
@ -114,23 +129,6 @@ class TestUi(TestCase):
self.assertEqual('my_btn', btn.objectName())
self.assertTrue(btn.isEnabled())
def test_create_valign_selection_widgets(self):
"""
Test creating a combo box for valign selection
"""
# GIVEN: A dialog
dialog = QtGui.QDialog()
# WHEN: We create the widgets
label, combo = create_valign_selection_widgets(dialog)
# THEN: We should get a label and a combobox.
self.assertEqual(translate('OpenLP.Ui', '&Vertical Align:'), label.text())
self.assertIsInstance(combo, QtGui.QComboBox)
self.assertEqual(combo, label.buddy())
for text in [UiStrings().Top, UiStrings().Middle, UiStrings().Bottom]:
self.assertTrue(combo.findText(text) >= 0)
def test_create_horizontal_adjusting_combo_box(self):
"""
Test creating a horizontal adjusting combo box
@ -184,3 +182,47 @@ class TestUi(TestCase):
self.assertIsInstance(action.icon(), QtGui.QIcon)
self.assertEqual('my tooltip', action.toolTip())
self.assertEqual('my statustip', action.statusTip())
def test_create_valign_selection_widgets(self):
"""
Test creating a combo box for valign selection
"""
# GIVEN: A dialog
dialog = QtGui.QDialog()
# WHEN: We create the widgets
label, combo = create_valign_selection_widgets(dialog)
# THEN: We should get a label and a combobox.
self.assertEqual(translate('OpenLP.Ui', '&Vertical Align:'), label.text())
self.assertIsInstance(combo, QtGui.QComboBox)
self.assertEqual(combo, label.buddy())
for text in [UiStrings().Top, UiStrings().Middle, UiStrings().Bottom]:
self.assertTrue(combo.findText(text) >= 0)
def test_find_and_set_in_combo_box(self):
"""
Test finding a string in a combo box and setting it as the selected item if present
"""
# GIVEN: A ComboBox
combo = QtGui.QComboBox()
combo.addItems(['One', 'Two', 'Three'])
combo.setCurrentIndex(1)
# WHEN: We call the method with a non-existing value and set_missing=False
find_and_set_in_combo_box(combo, 'Four', set_missing=False)
# THEN: The index should not have changed
self.assertEqual(1, combo.currentIndex())
# WHEN: We call the method with a non-existing value
find_and_set_in_combo_box(combo, 'Four')
# THEN: The index should have been reset
self.assertEqual(0, combo.currentIndex())
# WHEN: We call the method with the default behavior
find_and_set_in_combo_box(combo, 'Three')
# THEN: The index should have changed
self.assertEqual(2, combo.currentIndex())

View File

@ -445,9 +445,9 @@ class TestVerseType(TestCase):
# THEN: The result should be VerseType.Chorus
self.assertEqual(result, VerseType.Chorus, 'The result should be VerseType.Chorus, but was "%s"' % result)
def from_tag_with_invalid_default_test(self):
def from_tag_with_invalid_intdefault_test(self):
"""
Test that the from_tag() method returns a sane default when passed an invalid tag and an invalid default.
Test that the from_tag() method returns a sane default when passed an invalid tag and an invalid int default.
"""
# GIVEN: A mocked out translate() function that just returns what it was given
with patch('openlp.plugins.songs.lib.translate') as mocked_translate:
@ -458,3 +458,31 @@ class TestVerseType(TestCase):
# THEN: The result should be VerseType.Other
self.assertEqual(result, VerseType.Other, 'The result should be VerseType.Other, but was "%s"' % result)
def from_tag_with_invalid_default_test(self):
"""
Test that the from_tag() method returns a sane default when passed an invalid tag and an invalid default.
"""
# GIVEN: A mocked out translate() function that just returns what it was given
with patch('openlp.plugins.songs.lib.translate') as mocked_translate:
mocked_translate.side_effect = lambda x, y: y
# WHEN: We run the from_tag() method with an invalid verse type, we get the specified default back
result = VerseType.from_tag('@', 'asdf')
# THEN: The result should be VerseType.Other
self.assertEqual(result, VerseType.Other, 'The result should be VerseType.Other, but was "%s"' % result)
def from_tag_with_none_default_test(self):
"""
Test that the from_tag() method returns a sane default when passed an invalid tag and None as default.
"""
# GIVEN: A mocked out translate() function that just returns what it was given
with patch('openlp.plugins.songs.lib.translate') as mocked_translate:
mocked_translate.side_effect = lambda x, y: y
# WHEN: We run the from_tag() method with an invalid verse type, we get the specified default back
result = VerseType.from_tag('m', None)
# THEN: The result should be None
self.assertIsNone(result, 'The result should be None, but was "%s"' % result)

View File

@ -53,6 +53,7 @@ TAGS = [
['2.0.1', '?'],
['2.0.2', '?'],
['2.0.3', '?'],
['2.0.4', '?'],
['2.1.0', '2119']
]