- i18n for scripture references and custom configuration settings

This commit is contained in:
M2j 2012-01-18 18:52:48 +01:00
parent 1757436853
commit 9ef317db2a
3 changed files with 294 additions and 48 deletions

View File

@ -31,10 +31,15 @@ plugin.
import logging
import re
from PyQt4 import QtCore
from openlp.core.lib import translate
log = logging.getLogger(__name__)
REFERENCE_MATCHES = {}
REFERENCE_SEPARATORS = {}
class LayoutStyle(object):
"""
An enumeration for bible screen layout styles.
@ -54,51 +59,86 @@ class DisplayStyle(object):
Square = 3
def update_reference_separators():
"""
Updates separators and matches for parsing and formating scripture
references.
"""
default_separators = unicode(translate('BiblesPlugin',
':|v|V|verse;;-|to;;,|and;;end',
'This are 4 values seperated each by two semicolons representing the '
'seperators for parsing references. This values are verse separators, '
'range separators, list separators and end mark. Alternative values '
'to be seperated by a vertical bar "|". In this case the first value '
'is the default and used for the display format.')).split(u';;')
settings = QtCore.QSettings()
settings.beginGroup(u'bibles') # FIXME: get the name from somewere else
custom_separators = [
unicode(settings.value(u'verse separator',
QtCore.QVariant(u'')).toString()),
unicode(settings.value(u'range separator',
QtCore.QVariant(u'')).toString()),
unicode(settings.value(u'list separator',
QtCore.QVariant(u'')).toString()),
unicode(settings.value(u'end separator',
QtCore.QVariant(u'')).toString())]
settings.endGroup()
for index, role in enumerate([u'v', u'r', u'l', u'e']):
if custom_separators[index].strip(u'|') == u'':
source_string = default_separators[index].strip(u'|')
else:
source_string = custom_separators[index].strip(u'|')
while u'||' in source_string:
source_string = source_string.replace(u'||', u'|')
if role != u'e':
REFERENCE_SEPARATORS[u'sep_%s_display' % role] = \
source_string.split(u'|')[0]
# escape reserved characters
for character in u'\\.^$*+?{}[]()':
source_string = source_string.replace(character, u'\\' + character)
# add various unicode alternatives
source_string = source_string.replace(u'-',
u'(?:[-\u00AD\u2010\u2011\u2012\u2013\u2014\u2212\uFE63\uFF0D])')
source_string = source_string.replace(u',', u'(?:[,\u201A])')
REFERENCE_SEPARATORS[u'sep_%s' % role] = u'\s*(?:%s)\s*' % source_string
REFERENCE_SEPARATORS[u'sep_%s_default' % role] = \
default_separators[index]
# verse range match: (<chapter>:)?<verse>(-((<chapter>:)?<verse>|end)?)?
range_string = u'(?:(?P<from_chapter>[0-9]+)%(sep_v)s)?' \
u'(?P<from_verse>[0-9]+)(?P<range_to>%(sep_r)s(?:(?:(?P<to_chapter>' \
u'[0-9]+)%(sep_v)s)?(?P<to_verse>[0-9]+)|%(sep_e)s)?)?' % \
REFERENCE_SEPARATORS
REFERENCE_MATCHES[u'range'] = re.compile(u'^\s*%s\s*$' % range_string,
re.UNICODE)
REFERENCE_MATCHES[u'range_separator'] = re.compile(
REFERENCE_SEPARATORS[u'sep_l'], re.UNICODE)
# full reference match: <book>(<range>(,|(?=$)))+
REFERENCE_MATCHES[u'full'] = re.compile(u'^\s*(?!\s)(?P<book>[\d]*[^\d]+)'
u'(?<!\s)\s*(?P<ranges>(?:%(range)s(?:%(sep_l)s|(?=\s*$)))+)\s*$' % \
dict(REFERENCE_SEPARATORS.items() + [(u'range', range_string)]),
re.UNICODE)
def get_reference_separator(separator_type):
"""
Provides separators for parsing and formatting scripture references.
``separator_type``
The role and format of the separator.
"""
if len(REFERENCE_SEPARATORS) == 0:
update_reference_separators()
return REFERENCE_SEPARATORS[separator_type]
def get_reference_match(match_type):
"""
Provides the regexes and matches to use while parsing strings for bible
references.
Provides matches for parsing scripture references strings.
``match_type``
The type of reference information trying to be extracted in this call.
The type of match is ``range_separator``, ``range`` or ``full``.
"""
local_separator = unicode(translate('BiblesPlugin',
':;;:|v|V;;-;;-;;,;;,;;end',
'Seperators for parsing references. There are 7 values separated each '
'by two semicolons. Verse, range and list separators have each one '
'display symbol which appears on slides and in the GUI and a regular '
'expression for detecting this symbols.\n'
'Please ask a developer to double check your translation or make '
'yourself familar with regular experssions on: '
'http://docs.python.org/library/re.html')
).split(u';;')
separators = {
u'sep_v_display': local_separator[0],
u'sep_v': u'\s*(?:' + local_separator[1] + u')\s*',
u'sep_r_display': local_separator[2],
u'sep_r': u'\s*(?:' + local_separator[3] + u')\s*',
u'sep_l_display': local_separator[4],
u'sep_l': u'\s*(?:' + local_separator[5] + u')\s*',
u'sep_e': u'\s*(?:' + local_separator[6] + u')\s*'}
for role in [u'sep_v', u'sep_r', u'sep_l', u'sep_e']:
separators[role] = separators[role].replace(u'-',
u'(?:[-\u00AD\u2010\u2011\u2012\u2013\u2014\u2212\uFE63\uFF0D])')
separators[role] = separators[role].replace(u',', u'(?:[,\u201A])')
# verse range match: (<chapter>:)?<verse>(-((<chapter>:)?<verse>|end)?)?
range_string = unicode(u'(?:(?P<from_chapter>[0-9]+)%(sep_v)s)?'
u'(?P<from_verse>[0-9]+)(?P<range_to>%(sep_r)s(?:(?:(?P<to_chapter>'
u'[0-9]+)%(sep_v)s)?(?P<to_verse>[0-9]+)|%(sep_e)s)?)?') % separators
if match_type == u'range':
return re.compile(u'^\s*' + range_string + u'\s*$', re.UNICODE)
elif match_type == u'range_separator':
return re.compile(separators[u'sep_l'], re.UNICODE)
elif match_type == u'full':
# full reference match: <book>(<range>(,|(?=$)))+
return re.compile(unicode(u'^\s*(?!\s)(?P<book>[\d]*[^\d]+)(?<!\s)\s*'
u'(?P<ranges>(?:' + range_string + u'(?:%(sep_l)s|(?=\s*$)))+)\s*$')
% separators, re.UNICODE)
else:
return separators[match_type]
if len(REFERENCE_MATCHES) == 0:
update_reference_separators()
return REFERENCE_MATCHES[match_type]
def parse_reference(reference):
"""

View File

@ -30,8 +30,9 @@ import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Receiver, SettingsTab, translate
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle
from openlp.core.lib.ui import UiStrings, find_and_set_in_combo_box
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, \
update_reference_separators, get_reference_separator
log = logging.getLogger(__name__)
@ -90,6 +91,52 @@ class BiblesTab(SettingsTab):
self.changeNoteLabel.setObjectName(u'changeNoteLabel')
self.verseDisplayLayout.addRow(self.changeNoteLabel)
self.leftLayout.addWidget(self.verseDisplayGroupBox)
self.scriptureReferenceGroupBox = QtGui.QGroupBox(self.leftColumn)
self.scriptureReferenceGroupBox.setObjectName(
u'scriptureReferenceGroupBox')
self.scriptureReferenceLayout = QtGui.QGridLayout(
self.scriptureReferenceGroupBox)
self.verseSeparatorCheckBox = QtGui.QCheckBox(
self.scriptureReferenceGroupBox)
self.verseSeparatorCheckBox.setObjectName(u'verseSeparatorCheckBox')
self.scriptureReferenceLayout.addWidget(self.verseSeparatorCheckBox, 0,
0)
self.verseSeparatorLineEdit = QtGui.QLineEdit(
self.scriptureReferenceGroupBox)
self.verseSeparatorLineEdit.setObjectName(u'verseSeparatorLineEdit')
self.scriptureReferenceLayout.addWidget(self.verseSeparatorLineEdit, 0,
1)
self.rangeSeparatorCheckBox = QtGui.QCheckBox(
self.scriptureReferenceGroupBox)
self.rangeSeparatorCheckBox.setObjectName(u'rangeSeparatorCheckBox')
self.scriptureReferenceLayout.addWidget(self.rangeSeparatorCheckBox, 1,
0)
self.rangeSeparatorLineEdit = QtGui.QLineEdit(
self.scriptureReferenceGroupBox)
self.rangeSeparatorLineEdit.setObjectName(u'rangeSeparatorLineEdit')
self.scriptureReferenceLayout.addWidget(self.rangeSeparatorLineEdit, 1,
1)
self.listSeparatorCheckBox = QtGui.QCheckBox(
self.scriptureReferenceGroupBox)
self.listSeparatorCheckBox.setObjectName(u'listSeparatorCheckBox')
self.scriptureReferenceLayout.addWidget(self.listSeparatorCheckBox, 2,
0)
self.listSeparatorLineEdit = QtGui.QLineEdit(
self.scriptureReferenceGroupBox)
self.listSeparatorLineEdit.setObjectName(u'listSeparatorLineEdit')
self.scriptureReferenceLayout.addWidget(self.listSeparatorLineEdit, 2,
1)
self.endSeparatorCheckBox = QtGui.QCheckBox(
self.scriptureReferenceGroupBox)
self.endSeparatorCheckBox.setObjectName(u'endSeparatorCheckBox')
self.scriptureReferenceLayout.addWidget(self.endSeparatorCheckBox, 3,
0)
self.endSeparatorLineEdit = QtGui.QLineEdit(
self.scriptureReferenceGroupBox)
self.endSeparatorLineEdit.setObjectName(u'endSeparatorLineEdit')
self.scriptureReferenceLayout.addWidget(self.endSeparatorLineEdit, 3,
1)
self.leftLayout.addWidget(self.scriptureReferenceGroupBox)
self.leftLayout.addStretch()
self.rightColumn.setSizePolicy(
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
@ -110,6 +157,42 @@ class BiblesTab(SettingsTab):
QtCore.QObject.connect(
self.bibleSecondCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
self.onBibleSecondCheckBox)
QtCore.QObject.connect(
self.verseSeparatorCheckBox, QtCore.SIGNAL(u'clicked(bool)'),
self.onVerseSeparatorCheckBoxToggled)
QtCore.QObject.connect(
self.verseSeparatorLineEdit, QtCore.SIGNAL(u'textEdited(QString)'),
self.onVerseSeparatorLineEditEdited)
QtCore.QObject.connect(
self.verseSeparatorLineEdit, QtCore.SIGNAL(u'editingFinished()'),
self.onVerseSeparatorLineEditFinished)
QtCore.QObject.connect(
self.rangeSeparatorCheckBox, QtCore.SIGNAL(u'clicked(bool)'),
self.onRangeSeparatorCheckBoxToggled)
QtCore.QObject.connect(
self.rangeSeparatorLineEdit, QtCore.SIGNAL(u'textEdited(QString)'),
self.onRangeSeparatorLineEditEdited)
QtCore.QObject.connect(
self.rangeSeparatorLineEdit, QtCore.SIGNAL(u'editingFinished()'),
self.onRangeSeparatorLineEditFinished)
QtCore.QObject.connect(
self.listSeparatorCheckBox, QtCore.SIGNAL(u'clicked(bool)'),
self.onListSeparatorCheckBoxToggled)
QtCore.QObject.connect(
self.listSeparatorLineEdit, QtCore.SIGNAL(u'textEdited(QString)'),
self.onListSeparatorLineEditEdited)
QtCore.QObject.connect(
self.listSeparatorLineEdit, QtCore.SIGNAL(u'editingFinished()'),
self.onListSeparatorLineEditFinished)
QtCore.QObject.connect(
self.endSeparatorCheckBox, QtCore.SIGNAL(u'clicked(bool)'),
self.onEndSeparatorCheckBoxToggled)
QtCore.QObject.connect(
self.endSeparatorLineEdit, QtCore.SIGNAL(u'textEdited(QString)'),
self.onEndSeparatorLineEditEdited)
QtCore.QObject.connect(
self.endSeparatorLineEdit, QtCore.SIGNAL(u'editingFinished()'),
self.onEndSeparatorLineEditFinished)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'theme_update_list'), self.updateThemeList)
@ -141,6 +224,36 @@ class BiblesTab(SettingsTab):
'Note:\nChanges do not affect verses already in the service.'))
self.bibleSecondCheckBox.setText(
translate('BiblesPlugin.BiblesTab', 'Display second Bible verses'))
self.scriptureReferenceGroupBox.setTitle(
translate('BiblesPlugin.BiblesTab', 'Custom Scripture References'))
self.verseSeparatorCheckBox.setText(
translate('BiblesPlugin.BiblesTab', 'Verse Separator:'))
self.rangeSeparatorCheckBox.setText(
translate('BiblesPlugin.BiblesTab', 'Range Separator:'))
self.listSeparatorCheckBox.setText(
translate('BiblesPlugin.BiblesTab', 'List Separator:'))
self.endSeparatorCheckBox.setText(
translate('BiblesPlugin.BiblesTab', 'End Mark:'))
self.verseSeparatorLineEdit.setToolTip(
translate('BiblesPlugin.BiblesTab', 'Multiple alternative '
'separators may be defined.\nThey have to be separated '
'by a vertical bar "|".\nPlease clear this edit line to use '
'the default value.'))
self.rangeSeparatorLineEdit.setToolTip(
translate('BiblesPlugin.BiblesTab', 'Multiple alternative '
'separators may be defined.\nThey have to be separated '
'by a vertical bar "|".\nPlease clear this edit line to use '
'the default value.'))
self.listSeparatorLineEdit.setToolTip(
translate('BiblesPlugin.BiblesTab', 'Multiple alternative '
'separators may be defined.\nThey have to be separated '
'by a vertical bar "|".\nPlease clear this edit line to use '
'the default value.'))
self.endSeparatorLineEdit.setToolTip(
translate('BiblesPlugin.BiblesTab', 'Multiple alternative '
'end marks may be defined.\nThey have to be separated by a '
'vertical bar "|".\nPlease clear this edit line to use the '
'default value.'))
def onBibleThemeComboBoxChanged(self):
self.bible_theme = self.bibleThemeComboBox.currentText()
@ -163,6 +276,66 @@ class BiblesTab(SettingsTab):
if check_state == QtCore.Qt.Checked:
self.second_bibles = True
def onVerseSeparatorCheckBoxToggled(self, checked):
if not checked:
self.verseSeparatorLineEdit.clear()
elif self.verseSeparatorCheckBox.hasFocus():
self.verseSeparatorLineEdit.setFocus()
def onVerseSeparatorLineEditEdited(self, text):
self.verseSeparatorCheckBox.setChecked(True)
def onVerseSeparatorLineEditFinished(self):
if self.verseSeparatorLineEdit.text().remove(u'|').isEmpty() and \
not self.verseSeparatorCheckBox.hasFocus():
self.verseSeparatorCheckBox.setChecked(False)
self.verseSeparatorLineEdit.clear()
def onRangeSeparatorCheckBoxToggled(self, checked):
if not checked:
self.rangeSeparatorLineEdit.clear()
elif self.rangeSeparatorCheckBox.hasFocus():
self.rangeSeparatorLineEdit.setFocus()
def onRangeSeparatorLineEditEdited(self, text):
self.rangeSeparatorCheckBox.setChecked(True)
def onRangeSeparatorLineEditFinished(self):
if self.rangeSeparatorLineEdit.text().remove(u'|').isEmpty() and \
not self.rangeSeparatorCheckBox.hasFocus():
self.rangeSeparatorCheckBox.setChecked(False)
self.rangeSeparatorLineEdit.clear()
def onListSeparatorCheckBoxToggled(self, checked):
if not checked:
self.listSeparatorLineEdit.clear()
elif self.listSeparatorCheckBox.hasFocus():
self.listSeparatorLineEdit.setFocus()
def onListSeparatorLineEditEdited(self, text):
self.listSeparatorCheckBox.setChecked(True)
def onListSeparatorLineEditFinished(self):
if self.listSeparatorLineEdit.text().remove(u'|').isEmpty() and \
not self.listSeparatorCheckBox.hasFocus():
self.listSeparatorCheckBox.setChecked(False)
self.listSeparatorLineEdit.clear()
def onEndSeparatorCheckBoxToggled(self, checked):
if not checked:
self.endSeparatorLineEdit.clear()
elif self.endSeparatorCheckBox.hasFocus():
self.endSeparatorLineEdit.setFocus()
def onEndSeparatorLineEditEdited(self, text):
self.endSeparatorCheckBox.setChecked(True)
def onEndSeparatorLineEditFinished(self):
if self.endSeparatorLineEdit.text().remove(u'|').isEmpty() and \
not self.endSeparatorCheckBox.hasFocus():
self.endSeparatorCheckBox.setChecked(False)
self.endSeparatorLineEdit.clear()
def load(self):
settings = QtCore.QSettings()
settings.beginGroup(self.settingsSection)
@ -180,6 +353,30 @@ class BiblesTab(SettingsTab):
self.displayStyleComboBox.setCurrentIndex(self.display_style)
self.layoutStyleComboBox.setCurrentIndex(self.layout_style)
self.bibleSecondCheckBox.setChecked(self.second_bibles)
self.verseSeparatorLineEdit.setPlaceholderText(
get_reference_separator(u'sep_v_default'))
self.verseSeparatorLineEdit.setText(settings.value(u'verse separator',
QtCore.QVariant(u'')).toString())
self.verseSeparatorCheckBox.setChecked(
self.verseSeparatorLineEdit.text() != u'')
self.rangeSeparatorLineEdit.setPlaceholderText(
get_reference_separator(u'sep_r_default'))
self.rangeSeparatorLineEdit.setText(settings.value(u'range separator',
QtCore.QVariant(u'')).toString())
self.rangeSeparatorCheckBox.setChecked(
self.rangeSeparatorLineEdit.text() != u'')
self.listSeparatorLineEdit.setPlaceholderText(
get_reference_separator(u'sep_l_default'))
self.listSeparatorLineEdit.setText(settings.value(u'list separator',
QtCore.QVariant(u'')).toString())
self.listSeparatorCheckBox.setChecked(
self.listSeparatorLineEdit.text() != u'')
self.endSeparatorLineEdit.setPlaceholderText(
get_reference_separator(u'sep_e_default'))
self.endSeparatorLineEdit.setText(settings.value(u'end separator',
QtCore.QVariant(u'')).toString())
self.endSeparatorCheckBox.setChecked(
self.endSeparatorLineEdit.text() != u'')
settings.endGroup()
def save(self):
@ -193,6 +390,15 @@ class BiblesTab(SettingsTab):
QtCore.QVariant(self.layout_style))
settings.setValue(u'second bibles', QtCore.QVariant(self.second_bibles))
settings.setValue(u'bible theme', QtCore.QVariant(self.bible_theme))
settings.setValue(u'verse separator',
QtCore.QVariant(self.verseSeparatorLineEdit.text()))
settings.setValue(u'range separator',
QtCore.QVariant(self.rangeSeparatorLineEdit.text()))
settings.setValue(u'list separator',
QtCore.QVariant(self.listSeparatorLineEdit.text()))
settings.setValue(u'end separator',
QtCore.QVariant(self.endSeparatorLineEdit.text()))
update_reference_separators()
settings.endGroup()
def updateThemeList(self, theme_list):

View File

@ -38,7 +38,7 @@ from openlp.core.lib.ui import UiStrings, add_widget_completer, \
find_and_set_in_combo_box, build_icon
from openlp.plugins.bibles.forms import BibleImportForm
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, \
VerseReferenceList, get_reference_match
VerseReferenceList, get_reference_separator
log = logging.getLogger(__name__)
@ -634,8 +634,8 @@ class BibleMediaItem(MediaManagerItem):
chapter_to = self.advancedToChapter.currentText()
verse_from = self.advancedFromVerse.currentText()
verse_to = self.advancedToVerse.currentText()
verse_separator = get_reference_match(u'sep_v_display')
range_separator = get_reference_match(u'sep_r_display')
verse_separator = get_reference_separator(u'sep_v_display')
range_separator = get_reference_separator(u'sep_r_display')
verse_range = chapter_from + verse_separator + verse_from + \
range_separator + chapter_to + verse_separator + verse_to
versetext = u'%s %s' % (book, verse_range)
@ -737,7 +737,7 @@ class BibleMediaItem(MediaManagerItem):
Displays the search results in the media manager. All data needed for
further action is saved for/in each row.
"""
verse_separator = get_reference_match(u'sep_v_display')
verse_separator = get_reference_separator(u'sep_v_display')
version = self.plugin.manager.get_meta_data(bible, u'Version').value
copyright = self.plugin.manager.get_meta_data(bible, u'Copyright').value
permissions = \
@ -890,8 +890,8 @@ class BibleMediaItem(MediaManagerItem):
``old_item``
The last item of a range.
"""
verse_separator = get_reference_match(u'sep_v_display')
range_separator = get_reference_match(u'sep_r_display')
verse_separator = get_reference_separator(u'sep_v_display')
range_separator = get_reference_separator(u'sep_r_display')
old_chapter = self._decodeQtObject(old_bitem, 'chapter')
old_verse = self._decodeQtObject(old_bitem, 'verse')
start_book = self._decodeQtObject(start_bitem, 'book')
@ -971,7 +971,7 @@ class BibleMediaItem(MediaManagerItem):
``verse``
The verse number (int).
"""
verse_separator = get_reference_match(u'sep_v_display')
verse_separator = get_reference_separator(u'sep_v_display')
if not self.settings.show_new_chapters or old_chapter != chapter:
verse_text = unicode(chapter) + verse_separator + unicode(verse)
else: