Head 2087

This commit is contained in:
Tim Bentley 2012-10-13 21:55:41 +01:00
commit 7ce17e99f8
24 changed files with 202 additions and 129 deletions

View File

@ -29,12 +29,12 @@
The :mod:`advancedtab` provides an advanced settings facility.
"""
from datetime import datetime, timedelta
from PyQt4 import QtCore, QtGui
import logging
import os
import sys
from PyQt4 import QtCore, QtGui
from openlp.core.lib import SettingsTab, translate, build_icon, Receiver
from openlp.core.lib.settings import Settings
from openlp.core.lib.ui import UiStrings
@ -432,8 +432,7 @@ class AdvancedTab(SettingsTab):
translate('OpenLP.AdvancedTab',
'<strong>WARNING:</strong> New data directory location contains '
'OpenLP data files. These files WILL be replaced during a copy.'))
self.x11GroupBox.setTitle(translate('OpenLP.AdvancedTab',
'X11'))
self.x11GroupBox.setTitle(translate('OpenLP.AdvancedTab', 'X11'))
self.x11BypassCheckBox.setText(translate('OpenLP.AdvancedTab',
'Bypass X11 Window Manager'))
# Slide Limits
@ -493,8 +492,14 @@ class AdvancedTab(SettingsTab):
QtCore.QVariant(True)).toBool()
self.serviceNameCheckBox.setChecked(default_service_enabled)
self.serviceNameCheckBoxToggled(default_service_enabled)
self.x11BypassCheckBox.setChecked(
settings.value(u'x11 bypass wm', QtCore.QVariant(True)).toBool())
# Fix for bug #1014422.
x11_bypass_default = True
if sys.platform.startswith(u'linux'):
# Default to False on Gnome.
x11_bypass_default = bool(not
os.environ.get(u'GNOME_DESKTOP_SESSION_ID'))
self.x11BypassCheckBox.setChecked(settings.value(
u'x11 bypass wm', QtCore.QVariant(x11_bypass_default)).toBool())
self.defaultColor = settings.value(u'default color',
QtCore.QVariant(u'#ffffff')).toString()
self.defaultFileEdit.setText(settings.value(u'default image',
@ -766,7 +771,7 @@ class AdvancedTab(SettingsTab):
self.dataExists = False
self.dataDirectoryCopyCheckBox.setChecked(True)
self.newDataDirectoryHasFilesLabel.hide()
def onDataDirectoryCancelButtonClicked(self):
"""
Cancel the data directory location change

View File

@ -31,6 +31,7 @@ and play multimedia within OpenLP.
"""
import cgi
import logging
import os
import sys
from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL
@ -135,8 +136,14 @@ class MainDisplay(Display):
self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;')
windowFlags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool | \
QtCore.Qt.WindowStaysOnTopHint
# Fix for bug #1014422.
x11_bypass_default = True
if sys.platform.startswith(u'linux'):
# Default to False on Gnome.
x11_bypass_default = bool(not
os.environ.get(u'GNOME_DESKTOP_SESSION_ID'))
if Settings().value(u'advanced/x11 bypass wm',
QtCore.QVariant(True)).toBool():
QtCore.QVariant(x11_bypass_default)).toBool():
windowFlags |= QtCore.Qt.X11BypassWindowManagerHint
# TODO: The following combination of windowFlags works correctly
# on Mac OS X. For next OpenLP version we should test it on other

View File

@ -30,7 +30,6 @@ import os
import zipfile
import shutil
import logging
import locale
import re
from xml.etree.ElementTree import ElementTree, XML
@ -46,7 +45,8 @@ from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
create_widget_action
from openlp.core.theme import Theme
from openlp.core.ui import FileRenameForm, ThemeForm
from openlp.core.utils import AppLocation, delete_file, get_filesystem_encoding
from openlp.core.utils import AppLocation, delete_file, locale_compare, \
get_filesystem_encoding
log = logging.getLogger(__name__)
@ -457,9 +457,8 @@ class ThemeManager(QtGui.QWidget):
self.configUpdated()
files = SettingsManager.get_files(self.settingsSection, u'.png')
# Sort the themes by its name considering language specific characters.
# lower() is needed for windows!
files.sort(key=lambda file_name: unicode(file_name).lower(),
cmp=locale.strcoll)
files.sort(key=lambda file_name: unicode(file_name),
cmp=locale_compare)
# now process the file list of png files
for name in files:
# check to see file is in theme root directory

View File

@ -488,10 +488,24 @@ def format_time(text, local_time):
return re.sub('\%[a-zA-Z]', match_formatting, text)
def locale_compare(string1, string2):
"""
Compares two strings according to the current locale settings.
As any other compare function, returns a negative, or a positive value,
or 0, depending on whether string1 collates before or after string2 or
is equal to it. Comparison is case insensitive.
"""
# Function locale.strcol() from standard Python library does not work
# properly on Windows and probably somewhere else.
return int(QtCore.QString.localeAwareCompare(
QtCore.QString(string1).toLower(), QtCore.QString(string2).toLower()))
from languagemanager import LanguageManager
from actions import ActionList
__all__ = [u'AppLocation', u'get_application_version', u'check_latest_version',
u'add_actions', u'get_filesystem_encoding', u'LanguageManager',
u'ActionList', u'get_web_page', u'get_uno_command', u'get_uno_instance',
u'delete_file', u'clean_filename', u'format_time']
u'delete_file', u'clean_filename', u'format_time', u'locale_compare']

View File

@ -105,6 +105,7 @@ CSS = """
font-size: %spt;
color: %s;
background-color: %s;
word-wrap: break-word;
}
"""

View File

@ -80,6 +80,10 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
item_name = QtGui.QListWidgetItem(alert.text)
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(alert.id))
self.alertListWidget.addItem(item_name)
if alert.text == unicode(self.alertTextEdit.text()):
self.item_id = alert.id
self.alertListWidget.setCurrentRow(
self.alertListWidget.row(item_name))
def onDisplayClicked(self):
self.triggerAlert(unicode(self.alertTextEdit.text()))
@ -112,7 +116,6 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
alert = AlertItem()
alert.text = unicode(self.alertTextEdit.text())
self.manager.save_object(alert)
self.alertTextEdit.setText(u'')
self.loadList()
def onSaveClick(self):
@ -125,6 +128,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
self.manager.save_object(alert)
self.item_id = None
self.loadList()
self.saveButton.setEnabled(False)
def onTextChanged(self):
"""

View File

@ -57,8 +57,6 @@ class AlertsManager(QtCore.QObject):
"""
if message:
self.displayAlert(message[0])
else:
self.displayAlert(u'')
def displayAlert(self, text=u''):
"""
@ -68,14 +66,15 @@ class AlertsManager(QtCore.QObject):
display text
"""
log.debug(u'display alert called %s' % text)
self.alertList.append(text)
if self.timer_id != 0:
Receiver.send_message(u'mainwindow_status_text',
translate('AlertsPlugin.AlertsManager',
'Alert message created and displayed.'))
return
Receiver.send_message(u'mainwindow_status_text', u'')
self.generateAlert()
if text:
self.alertList.append(text)
if self.timer_id != 0:
Receiver.send_message(u'mainwindow_status_text',
translate('AlertsPlugin.AlertsManager',
'Alert message created and displayed.'))
return
Receiver.send_message(u'mainwindow_status_text', u'')
self.generateAlert()
def generateAlert(self):
"""

View File

@ -30,7 +30,6 @@ The bible import functions for OpenLP
"""
import logging
import os
import locale
from PyQt4 import QtCore, QtGui
@ -39,7 +38,7 @@ from openlp.core.lib.db import delete_database
from openlp.core.lib.ui import UiStrings, critical_error_message_box
from openlp.core.lib.settings import Settings
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
from openlp.core.utils import AppLocation
from openlp.core.utils import AppLocation, locale_compare
from openlp.plugins.bibles.lib.manager import BibleFormat
from openlp.plugins.bibles.lib.db import BiblesResourcesDB, clean_filename
@ -523,7 +522,7 @@ class BibleImportForm(OpenLPWizard):
"""
self.webTranslationComboBox.clear()
bibles = self.web_bible_list[index].keys()
bibles.sort(cmp=locale.strcoll)
bibles.sort(cmp=locale_compare)
self.webTranslationComboBox.addItems(bibles)
def onOsisBrowseButtonClicked(self):

View File

@ -355,37 +355,8 @@ def parse_reference(reference, bible, language_selection, book_ref_id=False):
log.debug(u'Matched reference %s' % reference)
book = match.group(u'book')
if not book_ref_id:
book_names = BibleStrings().BookNames
# escape reserved characters
book_escaped = book
for character in u'\\.^$*+?{}[]()':
book_escaped = book_escaped.replace(
character, u'\\' + character)
regex_book = re.compile(u'\s*%s\s*' % u'\s*'.join(
book_escaped.split()), re.UNICODE | re.IGNORECASE)
if language_selection == LanguageSelection.Bible:
db_book = bible.get_book(book)
if db_book:
book_ref_id = db_book.book_reference_id
elif language_selection == LanguageSelection.Application:
books = filter(lambda key:
regex_book.match(unicode(book_names[key])), book_names.keys())
books = filter(None, map(BiblesResourcesDB.get_book, books))
for value in books:
if bible.get_book_by_book_ref_id(value[u'id']):
book_ref_id = value[u'id']
break
elif language_selection == LanguageSelection.English:
books = BiblesResourcesDB.get_books_like(book)
if books:
book_list = filter(
lambda value: regex_book.match(value[u'name']), books)
if not book_list:
book_list = books
for value in book_list:
if bible.get_book_by_book_ref_id(value[u'id']):
book_ref_id = value[u'id']
break
book_ref_id = bible.get_book_ref_id_by_localised_name(
book, language_selection)
elif not bible.get_book_by_book_ref_id(book_ref_id):
book_ref_id = False
ranges = match.group(u'ranges')

View File

@ -29,6 +29,7 @@
import chardet
import logging
import os
import re
import sqlite3
from PyQt4 import QtCore
@ -44,6 +45,8 @@ import upgrade
log = logging.getLogger(__name__)
RESERVED_CHARACTERS = u'\\.^$*+?{}[]()'
class BibleMeta(BaseModel):
"""
Bible Meta Data
@ -352,6 +355,53 @@ class BibleDB(QtCore.QObject, Manager):
book, book_id, language_id)
return book_id
def get_book_ref_id_by_localised_name(self, book,
language_selection):
"""
Return the id of a named book.
``book``
The name of the book, according to the selected language.
``language_selection``
The language selection the user has chosen in the settings
section of the Bible.
"""
log.debug(u'get_book_ref_id_by_localised_name("%s", "%s")',
book, language_selection)
from openlp.plugins.bibles.lib import LanguageSelection, \
BibleStrings
book_names = BibleStrings().BookNames
# escape reserved characters
book_escaped = book
for character in RESERVED_CHARACTERS:
book_escaped = book_escaped.replace(
character, u'\\' + character)
regex_book = re.compile(u'\s*%s\s*' % u'\s*'.join(
book_escaped.split()), re.UNICODE | re.IGNORECASE)
if language_selection == LanguageSelection.Bible:
db_book = self.get_book(book)
if db_book:
return db_book.book_reference_id
elif language_selection == LanguageSelection.Application:
books = filter(lambda key:
regex_book.match(unicode(book_names[key])), book_names.keys())
books = filter(None, map(BiblesResourcesDB.get_book, books))
for value in books:
if self.get_book_by_book_ref_id(value[u'id']):
return value[u'id']
elif language_selection == LanguageSelection.English:
books = BiblesResourcesDB.get_books_like(book)
if books:
book_list = filter(
lambda value: regex_book.match(value[u'name']), books)
if not book_list:
book_list = books
for value in book_list:
if self.get_book_by_book_ref_id(value[u'id']):
return value[u'id']
return False
def get_verses(self, reference_list, show_error=True):
"""
This is probably the most used function. It retrieves the list of

View File

@ -277,8 +277,9 @@ class BibleManager(object):
"""
log.debug(u'BibleManager.get_verse_count("%s", "%s", %s)',
bible, book, chapter)
db_book = self.db_cache[bible].get_book(book)
book_ref_id = db_book.book_reference_id
language_selection = self.get_language_selection(bible)
book_ref_id = self.db_cache[bible].get_book_ref_id_by_localised_name(
book, language_selection)
return self.db_cache[bible].get_verse_count(book_ref_id, chapter)
def get_verse_count_by_book_ref_id(self, bible, book_ref_id, chapter):

View File

@ -27,7 +27,6 @@
###############################################################################
import logging
import locale
from PyQt4 import QtCore, QtGui
@ -38,6 +37,7 @@ from openlp.core.lib.settings import Settings
from openlp.core.lib.ui import UiStrings, set_case_insensitive_completer, \
create_horizontal_adjusting_combo_box, critical_error_message_box, \
find_and_set_in_combo_box, build_icon
from openlp.core.utils import locale_compare
from openlp.plugins.bibles.forms import BibleImportForm, EditBibleForm
from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, \
VerseReferenceList, get_reference_separator, LanguageSelection, \
@ -381,7 +381,7 @@ class BibleMediaItem(MediaManagerItem):
# Get all bibles and sort the list.
bibles = self.plugin.manager.get_bibles().keys()
bibles = filter(None, bibles)
bibles.sort(cmp=locale.strcoll)
bibles.sort(cmp=locale_compare)
# Load the bibles into the combo boxes.
self.quickVersionComboBox.addItems(bibles)
self.quickSecondComboBox.addItems(bibles)
@ -538,7 +538,7 @@ class BibleMediaItem(MediaManagerItem):
data = BiblesResourcesDB.get_book_by_id(
book.book_reference_id)
books.append(data[u'name'] + u' ')
books.sort(cmp=locale.strcoll)
books.sort(cmp=locale_compare)
set_case_insensitive_completer(books, self.quickSearchEdit)
def onImportClick(self):

View File

@ -34,12 +34,21 @@ from sqlalchemy import Column, Table, types
from sqlalchemy.orm import mapper
from openlp.core.lib.db import BaseModel, init_db
from openlp.core.utils import locale_compare
class CustomSlide(BaseModel):
"""
CustomSlide model
"""
pass
# By default sort the customs by its title considering language specific
# characters.
def __lt__(self, other):
r = locale_compare(self.title, other.title)
return True if r < 0 else False
def __eq__(self, other):
return 0 == locale_compare(self.title, other.title)
def init_schema(url):
"""

View File

@ -27,7 +27,6 @@
###############################################################################
import logging
import locale
from PyQt4 import QtCore, QtGui
from sqlalchemy.sql import or_, func
@ -109,10 +108,7 @@ class CustomMediaItem(MediaManagerItem):
# Sort out what custom we want to select after loading the list.
self.saveAutoSelectId()
self.listView.clear()
# Sort the customs by its title considering language specific
# characters. lower() is needed for windows!
custom_slides.sort(
cmp=locale.strcoll, key=lambda custom: custom.title.lower())
custom_slides.sort()
for custom_slide in custom_slides:
custom_name = QtGui.QListWidgetItem(custom_slide.title)
custom_name.setData(

View File

@ -28,7 +28,6 @@
import logging
import os
import locale
from PyQt4 import QtCore, QtGui
@ -37,7 +36,8 @@ from openlp.core.lib import MediaManagerItem, build_icon, ItemCapabilities, \
Receiver, create_thumb, validate_thumb
from openlp.core.lib.ui import UiStrings, critical_error_message_box
from openlp.core.lib.settings import Settings
from openlp.core.utils import AppLocation, delete_file, get_images_filter
from openlp.core.utils import AppLocation, delete_file, locale_compare, \
get_images_filter
log = logging.getLogger(__name__)
@ -126,10 +126,10 @@ class ImageMediaItem(MediaManagerItem):
if not initialLoad:
Receiver.send_message(u'cursor_busy')
self.plugin.formParent.displayProgressBar(len(images))
# Sort the themes by its filename considering language specific
# characters. lower() is needed for windows!
images.sort(cmp=locale.strcoll,
key=lambda filename: os.path.split(unicode(filename))[1].lower())
# Sort the images by its filename considering language specific
# characters.
images.sort(cmp=locale_compare,
key=lambda filename: os.path.split(unicode(filename))[1])
for imageFile in images:
filename = os.path.split(unicode(imageFile))[1]
thumb = os.path.join(self.servicePath, filename)

View File

@ -28,7 +28,6 @@
import logging
import os
import locale
from PyQt4 import QtCore, QtGui
@ -40,6 +39,7 @@ from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
create_horizontal_adjusting_combo_box
from openlp.core.ui import DisplayController, Display
from openlp.core.ui.media import get_media_players, set_media_players
from openlp.core.utils import locale_compare
log = logging.getLogger(__name__)
@ -292,10 +292,10 @@ class MediaMediaItem(MediaManagerItem):
u'media', self.getFileList())
def loadList(self, media):
# Sort the themes by its filename considering language specific
# characters. lower() is needed for windows!
media.sort(cmp=locale.strcoll,
key=lambda filename: os.path.split(unicode(filename))[1].lower())
# Sort the media by its filename considering language specific
# characters.
media.sort(cmp=locale_compare,
key=lambda filename: os.path.split(unicode(filename))[1])
for track in media:
track_info = QtCore.QFileInfo(track)
if track_info.isFile():
@ -317,8 +317,8 @@ class MediaMediaItem(MediaManagerItem):
def getList(self, type=MediaType.Audio):
media = SettingsManager.load_list(self.settingsSection, u'media')
media.sort(cmp=locale.strcoll,
key=lambda filename: os.path.split(unicode(filename))[1].lower())
media.sort(cmp=locale_compare,
key=lambda filename: os.path.split(unicode(filename))[1])
ext = []
if type == MediaType.Audio:
ext = self.plugin.audio_extensions_list

View File

@ -28,7 +28,6 @@
import logging
import os
import locale
from PyQt4 import QtCore, QtGui
@ -38,6 +37,7 @@ from openlp.core.lib import MediaManagerItem, build_icon, SettingsManager, \
from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
create_horizontal_adjusting_combo_box
from openlp.core.lib.settings import Settings
from openlp.core.utils import locale_compare
from openlp.plugins.presentations.lib import MessageListener
log = logging.getLogger(__name__)
@ -164,10 +164,10 @@ class PresentationMediaItem(MediaManagerItem):
if not initialLoad:
Receiver.send_message(u'cursor_busy')
self.plugin.formParent.displayProgressBar(len(files))
# Sort the themes by its filename considering language specific
# characters. lower() is needed for windows!
files.sort(cmp=locale.strcoll,
key=lambda filename: os.path.split(unicode(filename))[1].lower())
# Sort the presentations by its filename considering language specific
# characters.
files.sort(cmp=locale_compare,
key=lambda filename: os.path.split(unicode(filename))[1])
for file in files:
if not initialLoad:
self.plugin.formParent.incrementProgressBar()

View File

@ -66,10 +66,10 @@
<a href="#" id="service-refresh" data-role="button" data-icon="refresh">${refresh}</a>
<div data-role="navbar">
<ul>
<li><a href="#service-manager" data-theme="e">Service</a></li>
<li><a href="#slide-controller">Slides</a></li>
<li><a href="#alerts">Alerts</a></li>
<li><a href="#search">Search</a></li>
<li><a href="#service-manager" data-theme="e">${service}</a></li>
<li><a href="#slide-controller">${slides}</a></li>
<li><a href="#alerts">${alerts}</a></li>
<li><a href="#search">${search}</a></li>
</ul>
</div>
</div>
@ -97,10 +97,10 @@
<a href="#" id="controller-refresh" data-role="button" data-icon="refresh">${refresh}</a>
<div data-role="navbar">
<ul>
<li><a href="#service-manager">Service</a></li>
<li><a href="#slide-controller" data-theme="e">Slides</a></li>
<li><a href="#alerts">Alerts</a></li>
<li><a href="#search">Search</a></li>
<li><a href="#service-manager">${service}</a></li>
<li><a href="#slide-controller" data-theme="e">${slides}</a></li>
<li><a href="#alerts">${alerts}</a></li>
<li><a href="#search">${search}</a></li>
</ul>
</div>
</div>
@ -127,10 +127,10 @@
<h1>${alerts}</h1>
<div data-role="navbar">
<ul>
<li><a href="#service-manager">Service</a></li>
<li><a href="#slide-controller">Slides</a></li>
<li><a href="#alerts" data-theme="e">Alerts</a></li>
<li><a href="#search">Search</a></li>
<li><a href="#service-manager">${service}</a></li>
<li><a href="#slide-controller">${slides}</a></li>
<li><a href="#alerts" data-theme="e">${alerts}</a></li>
<li><a href="#search">${search}</a></li>
</ul>
</div>
</div>
@ -148,10 +148,10 @@
<h1>${search}</h1>
<div data-role="navbar">
<ul>
<li><a href="#service-manager">Service</a></li>
<li><a href="#slide-controller">Slides</a></li>
<li><a href="#alerts">Alerts</a></li>
<li><a href="#search" data-theme="e">Search</a></li>
<li><a href="#service-manager">${service}</a></li>
<li><a href="#slide-controller">${slides}</a></li>
<li><a href="#alerts">${alerts}</a></li>
<li><a href="#search" data-theme="e">${search}</a></li>
</ul>
</div>
</div>

View File

@ -308,7 +308,9 @@ class HttpConnection(object):
'add_and_go_to_service': translate('RemotePlugin.Mobile',
'Add &amp; Go to Service'),
'no_results': translate('RemotePlugin.Mobile', 'No Results'),
'options': translate('RemotePlugin.Mobile', 'Options')
'options': translate('RemotePlugin.Mobile', 'Options'),
'service': translate('RemotePlugin.Mobile', 'Service'),
'slides': translate('RemotePlugin.Mobile', 'Slides')
}
def ready_read(self):

View File

@ -29,7 +29,6 @@
The :mod:`songexportform` module provides the wizard for exporting songs to the
OpenLyrics format.
"""
import locale
import logging
from PyQt4 import QtCore, QtGui
@ -252,7 +251,7 @@ class SongExportForm(OpenLPWizard):
# Load the list of songs.
Receiver.send_message(u'cursor_busy')
songs = self.plugin.manager.get_all_objects(Song)
songs.sort(cmp=locale.strcoll, key=lambda song: song.title.lower())
songs.sort()
for song in songs:
# No need to export temporary songs.
if song.temporary:

View File

@ -35,6 +35,7 @@ from sqlalchemy.orm import mapper, relation
from sqlalchemy.sql.expression import func
from openlp.core.lib.db import BaseModel, init_db
from openlp.core.utils import locale_compare
class Author(BaseModel):
"""
@ -63,7 +64,14 @@ class Song(BaseModel):
"""
Song model
"""
pass
# By default sort the songs by its title considering language specific
# characters.
def __lt__(self, other):
r = locale_compare(self.title, other.title)
return True if r < 0 else False
def __eq__(self, other):
return 0 == locale_compare(self.title, other.title)
class Topic(BaseModel):

View File

@ -27,7 +27,6 @@
###############################################################################
import logging
import locale
import re
import os
import shutil
@ -260,10 +259,7 @@ class SongMediaItem(MediaManagerItem):
log.debug(u'display results Song')
self.saveAutoSelectId()
self.listView.clear()
# Sort the songs by its title considering language specific characters.
# lower() is needed for windows!
searchresults.sort(
cmp=locale.strcoll, key=lambda song: song.title.lower())
searchresults.sort()
for song in searchresults:
# Do not display temporary songs
if song.temporary:

View File

@ -154,18 +154,20 @@ class SundayPlusImport(SongImport):
# If any line inside any verse contains CCLI or
# only Public Domain, we treat this as special data:
# we remove that line and add data to specific field.
processed_lines = []
for i in xrange(len(lines)):
lines[i] = lines[i].strip()
line = lines[i]
if line[:4].lower() == u'ccli':
line = lines[i].strip()
if line[:3].lower() == u'ccl':
m = re.search(r'[0-9]+', line)
if m:
self.ccliNumber = int(m.group(0))
lines.pop(i)
continue
elif line.lower() == u'public domain':
self.copyright = u'Public Domain'
lines.pop(i)
self.addVerse('\n'.join(lines).strip(), verse_type)
continue
processed_lines.append(line)
self.addVerse('\n'.join(processed_lines).strip(),
verse_type)
if end == -1:
break
i = end + 1

View File

@ -260,7 +260,7 @@ class OpenLyrics(object):
IMPLEMENTED_VERSION = u'0.8'
START_TAGS_REGEX = re.compile(r'\{(\w+)\}')
END_TAGS_REGEX = re.compile(r'\{\/(\w+)\}')
VERSE_NUMBER_REGEX = re.compile(u'[a-zA-Z]*')
VERSE_TAG_SPLITTER = re.compile(u'([a-zA-Z]+)([0-9]*)([a-zA-Z]?)')
def __init__(self, manager):
self.manager = manager
@ -325,10 +325,22 @@ class OpenLyrics(object):
# Process the song's lyrics.
lyrics = etree.SubElement(song_xml, u'lyrics')
verse_list = sxml.get_verses(song.lyrics)
# Add a suffix letter to each verse
verse_tags = []
for verse in verse_list:
verse_tag = verse[0][u'type'][0].lower()
verse_number = verse[0][u'label']
verse_def = verse_tag + verse_number
verse_tags.append(verse_def)
# Create the letter from the number of duplicates
verse[0][u'suffix'] = chr(96 + verse_tags.count(verse_def))
# If the verse tag is a duplicate use the suffix letter
for verse in verse_list:
verse_tag = verse[0][u'type'][0].lower()
verse_number = verse[0][u'label']
verse_def = verse_tag + verse_number
if verse_tags.count(verse_def) > 1:
verse_def += verse[0][u'suffix']
verse_element = \
self._add_text_to_element(u'verse', lyrics, None, verse_def)
if u'lang' in verse[0]:
@ -742,11 +754,10 @@ class OpenLyrics(object):
if lines.get(u'break') is not None:
text += u'\n[---]'
verse_def = verse.get(u'name', u' ').lower()
if verse_def[0] in VerseType.Tags:
verse_tag = verse_def[0]
else:
verse_tag, verse_number, verse_part = \
OpenLyrics.VERSE_TAG_SPLITTER.search(verse_def).groups()
if verse_tag not in VerseType.Tags:
verse_tag = VerseType.Tags[VerseType.Other]
verse_number = OpenLyrics.VERSE_NUMBER_REGEX.sub(u'', verse_def)
# OpenLyrics allows e. g. "c", but we need "c1". However, this does
# not correct the verse order.
if not verse_number:
@ -757,13 +768,13 @@ class OpenLyrics(object):
if song_xml.get(u'modifiedIn') in (u'1.9.6', u'OpenLP 1.9.6') and \
song_xml.get(u'version') == u'0.7' and \
(verse_tag, verse_number, lang) in verses:
verses[(verse_tag, verse_number, lang)] += u'\n[---]\n' + text
verses[(verse_tag, verse_number, lang, None)] += u'\n[---]\n' + text
# Merge v1a, v1b, .... to v1.
elif (verse_tag, verse_number, lang) in verses:
elif (verse_tag, verse_number, lang, verse_part) in verses:
verses[(verse_tag, verse_number, lang)] += u'\n' + text
else:
verses[(verse_tag, verse_number, lang)] = text
verse_def_list.append((verse_tag, verse_number, lang))
verses[(verse_tag, verse_number, lang, verse_part)] = text
verse_def_list.append((verse_tag, verse_number, lang, verse_part))
# We have to use a list to keep the order, as dicts are not sorted.
for verse in verse_def_list:
sxml.add_verse_to_lyrics(