← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~m2j/openlp/i18n into lp:openlp

 

Meinert Jordan has proposed merging lp:~m2j/openlp/i18n into lp:openlp.

Requested reviews:
  Tim Bentley (trb143)

For more details, see:
https://code.launchpad.net/~m2j/openlp/i18n/+merge/89111

i18n for scripture references.

I've implemented i18n for scripture reference strings.
Translation is available through translate().
Custom configuration is available through the configuration dialog.

For our English friends (namely jseagull1): A list of unicode hypens is available to catch your remaining non-unicode inputs.

I'm not sure, if the current file is the right place for all the code.
Does someone has a suggestion for a better place?
Otherwhise I have to look for a way to get settingsSection available.
-- 
https://code.launchpad.net/~m2j/openlp/i18n/+merge/89111
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/plugins/bibles/lib/__init__.py'
--- openlp/plugins/bibles/lib/__init__.py	2011-12-27 10:33:55 +0000
+++ openlp/plugins/bibles/lib/__init__.py	2012-01-18 18:58:26 +0000
@@ -31,8 +31,15 @@
 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.
@@ -52,39 +59,86 @@
     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(u':;;\s*[:vV]\s*;;-;;\s*-\s*;;,;;\s*,\s*;;end'
-        ).split(u';;') # English
-    # local_separator = unicode(u',;;\s*,\s*;;-;;\s*-\s*;;.;;\.;;[Ee]nde'
-    #   ).split(u';;') # German
-    separators = {
-        u'sep_v_display': local_separator[0], u'sep_v': local_separator[1],
-        u'sep_r_display': local_separator[2], u'sep_r': local_separator[3],
-        u'sep_l_display': local_separator[4], u'sep_l': local_separator[5],
-        u'sep_e': local_separator[6]}
-
-    # verse range match: (<chapter>:)?<verse>(-((<chapter>:)?<verse>|end)?)?
-    range_string = str(r'(?:(?P<from_chapter>[0-9]+)%(sep_v)s)?(?P<from_verse>'
-        r'[0-9]+)(?P<range_to>%(sep_r)s(?:(?:(?P<to_chapter>[0-9]+)%(sep_v)s)?'
-        r'(?P<to_verse>[0-9]+)|%(sep_e)s)?)?') % separators
-    if match_type == u'range':
-        return re.compile(r'^\s*' + range_string + r'\s*$', re.UNICODE)
-    elif match_type == u'range_separator':
-        return re.compile(separators[u'sep_l'])
-    elif match_type == u'full':
-        # full reference match: <book>(<range>(,|(?=$)))+
-        return re.compile(str(r'^\s*(?!\s)(?P<book>[\d]*[^\d]+)(?<!\s)\s*'
-            r'(?P<ranges>(?:' + range_string + r'(?:%(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):
     """

=== modified file 'openlp/plugins/bibles/lib/biblestab.py'
--- openlp/plugins/bibles/lib/biblestab.py	2011-12-27 10:33:55 +0000
+++ openlp/plugins/bibles/lib/biblestab.py	2012-01-18 18:58:26 +0000
@@ -30,8 +30,9 @@
 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 @@
         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 @@
         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 @@
             '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 @@
         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 @@
         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 @@
             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):

=== modified file 'openlp/plugins/bibles/lib/mediaitem.py'
--- openlp/plugins/bibles/lib/mediaitem.py	2011-12-27 10:33:55 +0000
+++ openlp/plugins/bibles/lib/mediaitem.py	2012-01-18 18:58:26 +0000
@@ -38,7 +38,7 @@
     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 @@
         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 @@
         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 @@
         ``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 @@
         ``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:


Follow ups