← 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)
  Raoul Snyman (raoul-snyman)
  mahfiaz (mahfiaz)
  Andreas Preikschat (googol)
Related bugs:
  Bug #802166 in OpenLP: "Allow different scripture notations"
  https://bugs.launchpad.net/openlp/+bug/802166

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

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.
-- 
https://code.launchpad.net/~m2j/openlp/i18n/+merge/91591
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-02-05 19:31:21 +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,85 @@
     Square = 3
 
 
+def update_reference_separators():
+    """
+    Updates separators and matches for parsing and formating scripture
+    references.
+    """
+    default_separators = unicode(translate('BiblesPlugin',
+        ':|v|V|verse|verses;;-|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. If a semicolon should '
+        'be used you have to give an alternative separator afterwards to allow '
+        'OpenLP correct splitting of the translation.')).split(u';;')
+    settings = QtCore.QSettings()
+    settings.beginGroup(u'bibles')
+    custom_separators = [
+        unicode(settings.value(u'verse separator').toString()),
+        unicode(settings.value(u'range separator').toString()),
+        unicode(settings.value(u'list separator').toString()),
+        unicode(settings.value(u'end separator').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_regex = 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_regex,
+        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]+)(?<!\s)\s*'
+        u'(?P<ranges>(?:%(range_regex)s(?:%(sep_l)s(?!\s*$)|(?=\s*$)))+)\s*$' \
+        % dict(REFERENCE_SEPARATORS.items() + [(u'range_regex', range_regex)]),
+        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):
     """
@@ -140,7 +193,7 @@
     If there is a range separator without further verse declaration the last
     refered chapter is addressed until the end.
 
-    ``range_string`` is a regular expression which matches for verse range
+    ``range_regex`` is a regular expression which matches for verse range
     declarations:
 
     ``(?:(?P<from_chapter>[0-9]+)%(sep_v)s)?``
@@ -169,9 +222,9 @@
         are optional leading digits followed by non-digits. The group ends
         before the whitspace in front of the next digit.
 
-    ``(?P<ranges>(?:`` + range_string + ``(?:%(sep_l)s|(?=\s*$)))+)\s*$``
+    ``(?P<ranges>(?:%(range_regex)s(?:%(sep_l)s(?!\s*$)|(?=\s*$)))+)\s*$``
         The second group contains all ``ranges``. This can be multiple
-        declarations of a range_string separated by a list separator.
+        declarations of range_regex separated by a list separator.
 
     """
     log.debug(u'parse_reference("%s")', 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-02-05 19:31:21 +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,55 @@
         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.setPalette
+        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.endSeparatorLineEdit.setValidator(QtGui.QRegExpValidator(
+            QtCore.QRegExp(r'[^0-9]*'), self.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 +160,42 @@
         QtCore.QObject.connect(
             self.bibleSecondCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
             self.onBibleSecondCheckBox)
+        QtCore.QObject.connect(
+            self.verseSeparatorCheckBox, QtCore.SIGNAL(u'clicked(bool)'),
+            self.onVerseSeparatorCheckBoxClicked)
+        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.onRangeSeparatorCheckBoxClicked)
+        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.onListSeparatorCheckBoxClicked)
+        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.onEndSeparatorCheckBoxClicked)
+        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 +227,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 '
+                'verse 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 '
+                'range 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 '
+                'list 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 +279,106 @@
         if check_state == QtCore.Qt.Checked:
             self.second_bibles = True
 
+    def onVerseSeparatorCheckBoxClicked(self, checked):
+        if checked:
+            self.verseSeparatorLineEdit.setFocus()
+        else:
+            self.verseSeparatorLineEdit.setText(
+                get_reference_separator(u'sep_v_default'))
+        self.verseSeparatorLineEdit.setPalette(
+            self.getGreyTextPalette(not checked))
+
+    def onVerseSeparatorLineEditEdited(self, text):
+        self.verseSeparatorCheckBox.setChecked(True)
+        self.verseSeparatorLineEdit.setPalette(
+            self.getGreyTextPalette(False))
+
+    def onVerseSeparatorLineEditFinished(self):
+        if self.verseSeparatorLineEdit.isModified():
+            text = self.verseSeparatorLineEdit.text()
+            if text == get_reference_separator(u'sep_v_default') or \
+                text.remove(u'|').isEmpty():
+                self.verseSeparatorCheckBox.setChecked(False)
+                self.verseSeparatorLineEdit.setText(
+                    get_reference_separator(u'sep_v_default'))
+                self.verseSeparatorLineEdit.setPalette(
+                    self.getGreyTextPalette(True))
+
+    def onRangeSeparatorCheckBoxClicked(self, checked):
+        if checked:
+            self.rangeSeparatorLineEdit.setFocus()
+        else:
+            self.rangeSeparatorLineEdit.setText(
+                get_reference_separator(u'sep_r_default'))
+        self.rangeSeparatorLineEdit.setPalette(
+            self.getGreyTextPalette(not checked))
+
+    def onRangeSeparatorLineEditEdited(self, text):
+        self.rangeSeparatorCheckBox.setChecked(True)
+        self.rangeSeparatorLineEdit.setPalette(
+            self.getGreyTextPalette(False))
+
+    def onRangeSeparatorLineEditFinished(self):
+        if self.rangeSeparatorLineEdit.isModified():
+            text = self.rangeSeparatorLineEdit.text()
+            if text == get_reference_separator(u'sep_r_default') or \
+                text.remove(u'|').isEmpty():
+                self.rangeSeparatorCheckBox.setChecked(False)
+                self.rangeSeparatorLineEdit.setText(
+                    get_reference_separator(u'sep_r_default'))
+                self.rangeSeparatorLineEdit.setPalette(
+                    self.getGreyTextPalette(True))
+
+    def onListSeparatorCheckBoxClicked(self, checked):
+        if checked:
+            self.listSeparatorLineEdit.setFocus()
+        else:
+            self.listSeparatorLineEdit.setText(
+                get_reference_separator(u'sep_l_default'))
+        self.listSeparatorLineEdit.setPalette(
+            self.getGreyTextPalette(not checked))
+
+    def onListSeparatorLineEditEdited(self, text):
+        self.listSeparatorCheckBox.setChecked(True)
+        self.listSeparatorLineEdit.setPalette(
+            self.getGreyTextPalette(False))
+
+    def onListSeparatorLineEditFinished(self):
+        if self.listSeparatorLineEdit.isModified():
+            text = self.listSeparatorLineEdit.text()
+            if text == get_reference_separator(u'sep_l_default') or \
+                text.remove(u'|').isEmpty():
+                self.listSeparatorCheckBox.setChecked(False)
+                self.listSeparatorLineEdit.setText(
+                    get_reference_separator(u'sep_l_default'))
+                self.listSeparatorLineEdit.setPalette(
+                    self.getGreyTextPalette(True))
+
+    def onEndSeparatorCheckBoxClicked(self, checked):
+        if checked:
+            self.endSeparatorLineEdit.setFocus()
+        else:
+            self.endSeparatorLineEdit.setText(
+                get_reference_separator(u'sep_e_default'))
+        self.endSeparatorLineEdit.setPalette(
+            self.getGreyTextPalette(not checked))
+
+    def onEndSeparatorLineEditEdited(self, text):
+        self.endSeparatorCheckBox.setChecked(True)
+        self.endSeparatorLineEdit.setPalette(
+            self.getGreyTextPalette(False))
+
+    def onEndSeparatorLineEditFinished(self):
+        if self.endSeparatorLineEdit.isModified():
+            text = self.endSeparatorLineEdit.text()
+            if text == get_reference_separator(u'sep_e_default') or \
+                text.remove(u'|').isEmpty():
+                self.endSeparatorCheckBox.setChecked(False)
+                self.endSeparatorLineEdit.setText(
+                    get_reference_separator(u'sep_e_default'))
+                self.endSeparatorLineEdit.setPalette(
+                    self.getGreyTextPalette(True))
+
     def load(self):
         settings = QtCore.QSettings()
         settings.beginGroup(self.settingsSection)
@@ -180,6 +396,58 @@
         self.displayStyleComboBox.setCurrentIndex(self.display_style)
         self.layoutStyleComboBox.setCurrentIndex(self.layout_style)
         self.bibleSecondCheckBox.setChecked(self.second_bibles)
+        verse_separator = unicode(settings.value(u'verse separator').toString())
+        if (verse_separator.strip(u'|') == u'') or \
+            (verse_separator == get_reference_separator(u'sep_v_default')):
+            self.verseSeparatorLineEdit.setText(
+                get_reference_separator(u'sep_v_default'))
+            self.verseSeparatorLineEdit.setPalette(
+                self.getGreyTextPalette(True))
+            self.verseSeparatorCheckBox.setChecked(False)
+        else:
+            self.verseSeparatorLineEdit.setText(verse_separator)
+            self.verseSeparatorLineEdit.setPalette(
+                self.getGreyTextPalette(False))
+            self.verseSeparatorCheckBox.setChecked(True)
+        range_separator = unicode(settings.value(u'range separator').toString())
+        if (range_separator.strip(u'|') == u'') or \
+            (range_separator == get_reference_separator(u'sep_r_default')):
+            self.rangeSeparatorLineEdit.setText(
+                get_reference_separator(u'sep_r_default'))
+            self.rangeSeparatorLineEdit.setPalette(
+                self.getGreyTextPalette(True))
+            self.rangeSeparatorCheckBox.setChecked(False)
+        else:
+            self.rangeSeparatorLineEdit.setText(range_separator)
+            self.rangeSeparatorLineEdit.setPalette(
+                self.getGreyTextPalette(False))
+            self.rangeSeparatorCheckBox.setChecked(True)
+        list_separator = unicode(settings.value(u'list separator').toString())
+        if (list_separator.strip(u'|') == u'') or \
+            (list_separator == get_reference_separator(u'sep_l_default')):
+            self.listSeparatorLineEdit.setText(
+                get_reference_separator(u'sep_l_default'))
+            self.listSeparatorLineEdit.setPalette(
+                self.getGreyTextPalette(True))
+            self.listSeparatorCheckBox.setChecked(False)
+        else:
+            self.listSeparatorLineEdit.setText(list_separator)
+            self.listSeparatorLineEdit.setPalette(
+                self.getGreyTextPalette(False))
+            self.listSeparatorCheckBox.setChecked(True)
+        end_separator = unicode(settings.value(u'end separator').toString())
+        if (end_separator.strip(u'|') == u'') or \
+            (end_separator == get_reference_separator(u'sep_e_default')):
+            self.endSeparatorLineEdit.setText(
+                get_reference_separator(u'sep_e_default'))
+            self.endSeparatorLineEdit.setPalette(
+                self.getGreyTextPalette(True))
+            self.endSeparatorCheckBox.setChecked(False)
+        else:
+            self.endSeparatorLineEdit.setText(end_separator)
+            self.endSeparatorLineEdit.setPalette(
+                self.getGreyTextPalette(False))
+            self.endSeparatorCheckBox.setChecked(True)
         settings.endGroup()
 
     def save(self):
@@ -193,6 +461,27 @@
             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))
+        if self.verseSeparatorCheckBox.isChecked():
+            settings.setValue(u'verse separator',
+                self.verseSeparatorLineEdit.text())
+        else:
+            settings.remove(u'verse separator')
+        if self.rangeSeparatorCheckBox.isChecked():
+            settings.setValue(u'range separator',
+                self.rangeSeparatorLineEdit.text())
+        else:
+            settings.remove(u'range separator')
+        if self.listSeparatorCheckBox.isChecked():
+            settings.setValue(u'list separator',
+                self.listSeparatorLineEdit.text())
+        else:
+            settings.remove(u'list separator')
+        if self.endSeparatorCheckBox.isChecked():
+            settings.setValue(u'end separator',
+                self.endSeparatorLineEdit.text())
+        else:
+            settings.remove(u'end separator')
+        update_reference_separators()
         settings.endGroup()
 
     def updateThemeList(self, theme_list):
@@ -209,3 +498,15 @@
         for theme in theme_list:
             self.bibleThemeComboBox.addItem(theme)
         find_and_set_in_combo_box(self.bibleThemeComboBox, self.bible_theme)
+
+    def getGreyTextPalette(self, greyed):
+        """
+        Returns a QPalette with greyed out text as used for placeholderText.
+        """
+        palette = QtGui.QPalette()
+        color = self.palette().color(QtGui.QPalette.Active, QtGui.QPalette.Text)
+        if greyed:
+            color.setAlpha(128)
+        palette.setColor(QtGui.QPalette.Active, QtGui.QPalette.Text, color)
+        return palette
+

=== modified file 'openlp/plugins/bibles/lib/manager.py'
--- openlp/plugins/bibles/lib/manager.py	2011-12-27 10:33:55 +0000
+++ openlp/plugins/bibles/lib/manager.py	2012-02-05 19:31:21 +0000
@@ -33,7 +33,7 @@
 from openlp.core.lib import Receiver, SettingsManager, translate
 from openlp.core.lib.ui import critical_error_message_box
 from openlp.core.utils import AppLocation, delete_file
-from openlp.plugins.bibles.lib import parse_reference
+from openlp.plugins.bibles.lib import parse_reference, get_reference_separator
 from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
 from csvbible import CSVBible
 from http import HTTPBible
@@ -309,19 +309,29 @@
             return self.db_cache[bible].get_verses(reflist, show_error)
         else:
             if show_error:
+                reference_seperators = {
+                    u'verse': get_reference_separator(u'sep_v_display'),
+                    u'range': get_reference_separator(u'sep_r_display'),
+                    u'list': get_reference_separator(u'sep_l_display')}
                 Receiver.send_message(u'openlp_information_message', {
                     u'title': translate('BiblesPlugin.BibleManager',
                     'Scripture Reference Error'),
-                    u'message': translate('BiblesPlugin.BibleManager',
+                    u'message': unicode(translate('BiblesPlugin.BibleManager',
                     'Your scripture reference is either not supported by '
                     'OpenLP or is invalid. Please make sure your reference '
-                    'conforms to one of the following patterns:\n\n'
+                    'conforms to one of the following patterns or consult the '
+                    'manual:\n\n'
                     'Book Chapter\n'
-                    'Book Chapter-Chapter\n'
-                    'Book Chapter:Verse-Verse\n'
-                    'Book Chapter:Verse-Verse,Verse-Verse\n'
-                    'Book Chapter:Verse-Verse,Chapter:Verse-Verse\n'
-                    'Book Chapter:Verse-Chapter:Verse')
+                    'Book Chapter%(range)sChapter\n'
+                    'Book Chapter%(verse)sVerse%(range)sVerse\n'
+                    'Book Chapter%(verse)sVerse%(range)sVerse%(list)sVerse'
+                    '%(range)sVerse\n'
+                    'Book Chapter%(verse)sVerse%(range)sVerse%(list)sChapter'
+                    '%(verse)sVerse%(range)sVerse\n'
+                    'Book Chapter%(verse)sVerse%(range)sChapter%(verse)sVerse',
+                    'Please pay attention to the appended "s" of the wildcards '
+                    'and refrain from translating the words inside the '
+                    'names in the brackets.')) % reference_seperators
                     })
             return None
 

=== 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-02-05 19:31:21 +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