first working example with unilanguage tags handling

This commit is contained in:
Mattias Põldaru 2011-02-17 17:05:58 +02:00
parent 18f43fc858
commit 02c1bd4413
5 changed files with 161 additions and 86 deletions

View File

@ -228,7 +228,14 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.verseListWidget.clear()
self.verseListWidget.setRowCount(0)
if self.song.verse_order:
self.verseOrderEdit.setText(self.song.verse_order)
# we translate verse order
translated = []
for verse in self.song.verse_order.split():
verseindex = VerseType.from_tag(verse[0])
versetype = VerseType.Translations[verseindex][0]
versetag = verse[1:]
translated.append(u'%s%s' % (versetype, versetag))
self.verseOrderEdit.setText(u' '.join(translated))
else:
self.verseOrderEdit.setText(u'')
if self.song.comments:
@ -256,6 +263,20 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
for count, verse in enumerate(verseList):
self.verseListWidget.setRowCount(
self.verseListWidget.rowCount() + 1)
# this takes care of silently migrating from old or any markup
# if we entirely trusted the database, this should
# be unnecessary in the future
vtype = verse[0][u'type']
index = None
if len(vtype) > 1:
index = VerseType.from_translated_string(vtype)
if index is None:
index = VerseType.from_string(vtype)
if index is None:
index = VerseType.from_tag(vtype)
if index is None:
index = VerseType.Other
verse[0][u'type'] = VerseType.Tags[index]
variant = u'%s:%s' % (verse[0][u'type'], verse[0][u'label'])
item = QtGui.QTableWidgetItem(verse[1])
item.setData(QtCore.Qt.UserRole, QtCore.QVariant(variant))
@ -267,7 +288,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.verseListWidget.rowCount() + 1)
item = QtGui.QTableWidgetItem(verse)
variant = u'%s:%s' % \
(VerseType.to_string(VerseType.Verse), unicode(count + 1))
(VerseType.Tags[VerseType.Verse], unicode(count + 1))
item.setData(QtCore.Qt.UserRole, QtCore.QVariant(variant))
self.verseListWidget.setItem(count, 0, item)
self.verseListWidget.resizeRowsToContents()
@ -299,7 +320,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
item = self.verseListWidget.item(row, 0)
data = unicode(item.data(QtCore.Qt.UserRole).toString())
bit = data.split(u':')
rowTag = u'%s%s' % (bit[0][0:1], bit[1])
bit[0] = VerseType.Translations[VerseType.from_tag(bit[0])][0]
rowTag = u'%s%s' % (bit[0], bit[1])
rowLabel.append(rowTag)
self.verseListWidget.setVerticalHeaderLabels(rowLabel)
@ -467,7 +489,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
for row in range(0, self.verseListWidget.rowCount()):
item = self.verseListWidget.item(row, 0)
field = unicode(item.data(QtCore.Qt.UserRole).toString())
verse_list += u'---[%s]---\n' % field
versetype, versenum = field.split(u':')
versetype = VerseType.to_translated_string(versetype)
verse_list += u'---[%s:%s]---\n' % (versetype, versenum)
verse_list += item.text()
verse_list += u'\n'
self.verse_form.setVerse(verse_list)
@ -483,9 +507,18 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
for count, parts in enumerate(match.split(u']---\n')):
if len(parts) > 1:
if count == 0:
# make sure the tag is correctly cased
variant = u'%s%s' % \
(parts[0:1].upper(), parts[1:].lower())
# handling carefully user inputted versetags
separator = parts.find(u':')
if separator >= 0:
verse = parts[0:separator].strip()
subVerse = parts[separator+1:].strip()
else:
verse = parts
verseIndex = VerseType.from_loose_input(verse)
verseType = VerseType.Tags[verseIndex]
if not len(subVerse):
subVerse = u'1'
variant = u'%s:%s' % (verseType, subVerse)
else:
if parts.endswith(u'\n'):
parts = parts.rstrip(u'\n')
@ -543,9 +576,13 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
order_names = unicode(self.verseOrderEdit.text()).split()
for item in order_names:
if len(item) == 1:
order.append(item.lower() + u'1')
order.append(VerseType.Tags[VerseType.from_translated_tag(
item)] + u'1')
else:
order.append(item.lower())
versetag = VerseType.Tags[
VerseType.from_translated_tag(item[0])]
versenum = item[1:].lower()
order.append(u'%s%s' % (versetag, versenum))
verses = []
verse_names = []
for index in range (0, self.verseListWidget.rowCount()):
@ -561,7 +598,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.verseOrderEdit.setFocus()
valid = verses.pop(0)
for verse in verses:
valid = valid + u', ' + verse
valid = valid + u', ' + verse.upper()
critical_error_message_box(
message=unicode(translate('SongsPlugin.EditSongForm',
'The verse order is invalid. There is no verse '
@ -572,12 +609,16 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
if verse not in order:
self.songTabWidget.setCurrentIndex(0)
self.verseOrderEdit.setFocus()
versetype, versenum = verse_names[count].split(u':')
verseindex = VerseType.from_tag(versetype)
versetype = VerseType.Translations[verseindex][0]
versename = u'%s%s' % (versetype, versenum)
answer = QtGui.QMessageBox.warning(self,
translate('SongsPlugin.EditSongForm', 'Warning'),
unicode(translate('SongsPlugin.EditSongForm',
'You have not used %s anywhere in the verse '
'order. Are you sure you want to save the song '
'like this?')) % verse_names[count].replace(u':', u' '),
'like this?')) % versename,
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
if answer == QtGui.QMessageBox.No:
return False
@ -684,7 +725,14 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
else:
self.song.search_title = self.song.title
self.song.comments = unicode(self.commentsEdit.toPlainText())
self.song.verse_order = unicode(self.verseOrderEdit.text())
ordertext = unicode(self.verseOrderEdit.text())
order = []
for item in ordertext.split():
versetag = VerseType.Tags[
VerseType.from_translated_tag(item[0])]
versenum = item[1:].lower()
order.append(u'%s%s' % (versetag, versenum))
self.song.verse_order = u' '.join(order)
self.song.ccli_number = unicode(self.CCLNumberEdit.text())
self.song.song_number = unicode(self.songBookNumberEdit.text())
book_name = unicode(self.songBookComboBox.currentText())

View File

@ -71,18 +71,18 @@ class Ui_EditVerseDialog(object):
self.verseTypeLabel.setText(
translate('SongsPlugin.EditVerseForm', '&Verse type:'))
self.verseTypeComboBox.setItemText(0,
VerseType.to_string(VerseType.Verse))
VerseType.Translations[VerseType.Verse])
self.verseTypeComboBox.setItemText(1,
VerseType.to_string(VerseType.Chorus))
VerseType.Translations[VerseType.Chorus])
self.verseTypeComboBox.setItemText(2,
VerseType.to_string(VerseType.Bridge))
VerseType.Translations[VerseType.Bridge])
self.verseTypeComboBox.setItemText(3,
VerseType.to_string(VerseType.PreChorus))
VerseType.Translations[VerseType.PreChorus])
self.verseTypeComboBox.setItemText(4,
VerseType.to_string(VerseType.Intro))
VerseType.Translations[VerseType.Intro])
self.verseTypeComboBox.setItemText(5,
VerseType.to_string(VerseType.Ending))
VerseType.Translations[VerseType.Ending])
self.verseTypeComboBox.setItemText(6,
VerseType.to_string(VerseType.Other))
VerseType.Translations[VerseType.Other])
self.insertButton.setText(
translate('SongsPlugin.EditVerseForm', '&Insert'))

View File

@ -57,7 +57,7 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
QtCore.QObject.connect(self.verseTypeComboBox,
QtCore.SIGNAL(u'currentIndexChanged(int)'),
self.onVerseTypeComboBoxChanged)
self.verse_regex = re.compile(r'---\[([-\w]+):([\d]+)\]---')
self.verse_regex = re.compile(r'---\[(.+):(.+)\]---')
def contextMenu(self, point):
item = self.serviceManagerList.itemAt(point)
@ -70,8 +70,8 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
def onInsertButtonClicked(self):
verse_type = self.verseTypeComboBox.currentIndex()
if VerseType.to_string(verse_type) is not None:
self.insertVerse(VerseType.to_string(verse_type),
if VerseType.to_translated_string(verse_type) is not None:
self.insertVerse(VerseType.to_translated_string(verse_type),
self.verseNumberBox.value())
def onVerseTypeComboBoxChanged(self):
@ -81,7 +81,8 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
"""
position = self.verseTextEdit.textCursor().position()
text = unicode(self.verseTextEdit.toPlainText())
verse_type = VerseType.to_string(self.verseTypeComboBox.currentIndex())
verse_type = VerseType.Translations[
self.verseTypeComboBox.currentIndex()]
if not text:
return
position = text.rfind(u'---[%s' % verse_type, 0, position)
@ -97,7 +98,11 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
if match:
verse_type = match.group(1)
verse_number = int(match.group(2))
verse_type_index = VerseType.from_translated_string(verse_type)
if verse_type_index is None:
verse_type_index = VerseType.from_string(verse_type)
if verse_type_index is None:
verse_type_index = VerseType.from_tag(verse_type)
if verse_type_index is not None:
self.verseNumberBox.setValue(verse_number)
@ -125,24 +130,25 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
if match:
verse_type = match.group(1)
verse_number = int(match.group(2))
verse_type_index = VerseType.from_string(verse_type)
verse_type_index = VerseType.from_loose_input(verse_type)
if verse_type_index is not None:
self.verseTypeComboBox.setCurrentIndex(verse_type_index)
self.verseNumberBox.setValue(verse_number)
def setVerse(self, text, single=False,
tag=u'%s:1' % VerseType.to_string(VerseType.Verse)):
tag=u'%s:1' % VerseType.tag(VerseType.Verse)):
self.hasSingleVerse = single
if single:
verse_type, verse_number = tag.split(u':')
verse_type_index = VerseType.from_string(verse_type)
verse_type_index = VerseType.from_tag(verse_type)
if verse_type_index is not None:
self.verseTypeComboBox.setCurrentIndex(verse_type_index)
self.verseNumberBox.setValue(int(verse_number))
self.insertButton.setVisible(False)
else:
if not text:
text = u'---[%s:1]---\n' % VerseType.to_string(VerseType.Verse)
text = u'---[%s:1]---\n' % \
VerseType.to_translated_string(VerseType.Verse)
self.verseTypeComboBox.setCurrentIndex(0)
self.verseNumberBox.setValue(1)
self.insertButton.setVisible(True)
@ -152,14 +158,14 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
def getVerse(self):
return self.verseTextEdit.toPlainText(), \
VerseType.to_string(self.verseTypeComboBox.currentIndex()), \
VerseType.Tags[self.verseTypeComboBox.currentIndex()], \
unicode(self.verseNumberBox.value())
def getVerseAll(self):
text = self.verseTextEdit.toPlainText()
if not text.startsWith(u'---['):
text = u'---[%s:1]---\n%s' % (VerseType.to_string(VerseType.Verse),
text)
text = u'---[%s:1]---\n%s' % \
(VerseType.to_translated_string(VerseType.Verse), text)
return text
def accept(self):

View File

@ -56,121 +56,138 @@ class VerseType(object):
u'Ending',
u'Other']
Translations = [
translate('SongsPlugin.VerseType', 'Verse'),
translate('SongsPlugin.VerseType', 'Chorus'),
translate('SongsPlugin.VerseType', 'Bridge'),
translate('SongsPlugin.VerseType', 'Pre-Chorus'),
translate('SongsPlugin.VerseType', 'Intro'),
translate('SongsPlugin.VerseType', 'Ending'),
translate('SongsPlugin.VerseType', 'Other')]
unicode(translate('SongsPlugin.VerseType', 'Verse')),
unicode(translate('SongsPlugin.VerseType', 'Chorus')),
unicode(translate('SongsPlugin.VerseType', 'Bridge')),
unicode(translate('SongsPlugin.VerseType', 'Pre-Chorus')),
unicode(translate('SongsPlugin.VerseType', 'Intro')),
unicode(translate('SongsPlugin.VerseType', 'Ending')),
unicode(translate('SongsPlugin.VerseType', 'Other'))]
@staticmethod
def tag(verse_type, strict=False):
def tag(verse_type):
"""
Return a string for a given VerseType tag
``verse_type``
The verse type to return a string for
``strict``
If strict, False is returned instead of Other, when not found
"""
if isinstance(verse_type, int):
if verse_type >=0 and verse_type <= 6:
try:
return VerseType.Tags[verse_type]
else:
return self.returnvalue(VerseType.Tags, strict)
except:
return
elif verse_type[0].lower() in VerseType.Tags:
return verse_type[0].lower()
else:
return VerseType.returnvalue(VerseType.Tags, strict)
@staticmethod
def to_string(verse_type, strict=False):
def to_string(verse_type):
"""
Return a string for a given VerseType Name
``verse_type``
The type to return a string for
``strict``
If strict, False is returned instead of Other, when not found
"""
if isinstance(verse_type, int):
if verse_type >=0 and verse_type <= 6:
try:
return VerseType.Names[verse_type]
else:
return self.returnvalue(VerseType.Names, strict)
except:
return
else:
verse_type = verse_type[0].lower()
for num, tag in enumerate(VerseType.Tags):
if verse_type == tag:
return VerseType.Names[num]
return VerseType.returnvalue(VerseType.Names, strict)
@staticmethod
def to_translated_string(verse_type, strict=False):
def to_translated_string(verse_type):
"""
Return a string for a given VerseType Name
``verse_type``
The type to return a string for
``strict``
If strict, False is returned instead of Other, when not found
"""
if isinstance(verse_type, int):
if verse_type >=0 and verse_type <= 6:
try:
return VerseType.Translations[verse_type]
else:
return self.returnvalue(VerseType.Translations, strict)
except:
return
else:
verse_type = verse_type[0].lower()
for num, tag in enumerate(VerseType.Tags):
if verse_type == tag:
return VerseType.Translations[num]
return VerseType.returnvalue(VerseType.Translations, strict)
@staticmethod
def from_string(verse_type, strict=False):
def from_tag(verse_type):
"""
Return the VerseType for a given tag
``verse_type``
The string to return a VerseType for
"""
verse_type = verse_type[0].lower()
for num, string in enumerate(VerseType.Tags):
if verse_type == string:
return num
@staticmethod
def from_translated_tag(verse_type):
"""
Return the VerseType for a given tag
``verse_type``
The string to return a VerseType for
"""
verse_type = verse_type[0].lower()
for num, string in enumerate(VerseType.Translations):
if verse_type == string[0].lower():
return num
@staticmethod
def from_string(verse_type):
"""
Return the VerseType for a given string
``verse_type``
The string to return a VerseType for
``strict``
If strict, False is returned instead of Other, when not found
"""
verse_type = verse_type.lower()
for num, string in enumerate(VerseType.Names):
if verse_type == string:
if verse_type == string.lower():
return num
return VerseType.returnvalue(range(0,7), strict)
@staticmethod
def from_translated_string(verse_type, strict=False):
def from_translated_string(verse_type):
"""
Return the VerseType for a given string
``verse_type``
The string to return a VerseType for
``strict``
If strict, False is returned instead of Other, when not found
"""
verse_type = verse_type.lower()
for num, translation in enumerate(VerseType.Translations):
if verse_type == translation:
if verse_type == translation.lower():
return num
return VerseType.returnvalue(range(0,7), strict)
@staticmethod
def returnvalue(lst, strict):
if strict:
return False
else:
return lst[VerseType.Other]
def from_loose_input(verse_type):
"""
Return the VerseType for a given string, Other if not found
``verse_type``
The string to return a VerseType for
"""
verseIndex = None
if len(verse_type) > 1:
verseIndex = VerseType.from_translated_string(verse_type)
if verseIndex is None:
verseIndex = VerseType.from_string(verse_type)
if verseIndex is None:
verseIndex = VerseType.from_translated_tag(verse_type)
elif verseIndex is None:
verseIndex = VerseType.from_tag(verse_type)
return verseIndex
def retrieve_windows_encoding(recommendation=None):
"""

View File

@ -36,7 +36,7 @@ from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \
from openlp.core.lib.ui import UiStrings
from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \
SongImportForm, SongExportForm
from openlp.plugins.songs.lib import OpenLyrics, SongXML
from openlp.plugins.songs.lib import OpenLyrics, SongXML, VerseType
from openlp.plugins.songs.lib.db import Author, Song
from openlp.core.lib.searchedit import SearchEdit
@ -344,22 +344,26 @@ class SongMediaItem(MediaManagerItem):
if song.lyrics.startswith(u'<?xml version='):
verseList = SongXML().get_verses(song.lyrics)
# no verse list or only 1 space (in error)
if not song.verse_order or not song.verse_order.strip():
if not song.verse_order.strip():
for verse in verseList:
verseTag = u'%s:%s' % (
verse[0][u'type'], verse[0][u'label'])
verseindex = VerseType.from_tag(verse[0][u'type'])
versetype = VerseType.Translations[verseindex][0]
verseTag = u'%s:%s' % (versetype, verse[0][u'label'])
service_item.add_from_text(
verse[1][:30], unicode(verse[1]), verseTag)
else:
# Loop through the verse list and expand the song accordingly.
for order in song.verse_order.upper().split():
print song.verse_order
for order in song.verse_order.lower().split():
if len(order) == 0:
break
for verse in verseList:
if verse[0][u'type'][0] == order[0] and \
(verse[0][u'label'] == order[1:] or not order[1:]):
verseindex = VerseType.from_tag(verse[0][u'type'])
versetype = VerseType.Translations[verseindex][0]
verseTag = u'%s:%s' % \
(verse[0][u'type'], verse[0][u'label'])
(versetype, verse[0][u'label'])
service_item.add_from_text(
verse[1][:30], verse[1], verseTag)
else: