diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index b7d6ffc7f..62fda42a7 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -30,6 +30,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import SongXMLBuilder, SongXMLParser, Receiver, translate from openlp.plugins.songs.forms import EditVerseForm +from openlp.plugins.songs.lib import VerseType from openlp.plugins.songs.lib.models import Song, Author, Topic, Book from editsongdialog import Ui_EditSongDialog @@ -90,16 +91,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.parent.parent.render_manager.theme_manager.onAddTheme) QtCore.QObject.connect(self.MaintenanceButton, QtCore.SIGNAL(u'clicked()'), self.onMaintenanceButtonClicked) - QtCore.QObject.connect(self.TitleEditItem, - QtCore.SIGNAL(u'editingFinished()'), self.onTitleEditItemLostFocus) - QtCore.QObject.connect(self.CCLNumberEdit, - QtCore.SIGNAL(u'lostFocus()'), self.onCCLNumberEditLostFocus) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'theme_update_list'), self.loadThemes) - QtCore.QObject.connect(self.CommentsEdit, - QtCore.SIGNAL(u'lostFocus()'), self.onCommentsEditLostFocus) - QtCore.QObject.connect(self.VerseOrderEdit, - QtCore.SIGNAL(u'lostFocus()'), self.onVerseOrderEditLostFocus) self.previewButton = QtGui.QPushButton() self.previewButton.setObjectName(u'previewButton') self.previewButton.setText( @@ -247,7 +240,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.VerseListWidget.setRowCount( self.VerseListWidget.rowCount() + 1) item = QtGui.QTableWidgetItem(verse) - variant = u'Verse:%s' % unicode(count + 1) + variant = u'%s:%s' % \ + (VerseType.to_string(VerseType.Verse), unicode(count + 1)) item.setData(QtCore.Qt.UserRole, QtCore.QVariant(variant)) self.VerseListWidget.setItem(count, 0, item) self.VerseListWidget.resizeRowsToContents() @@ -519,42 +513,63 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): if len(self.TitleEditItem.displayText()) == 0: self.SongTabWidget.setCurrentIndex(0) self.TitleEditItem.setFocus() - return False, translate(u'SongsPlugin.EditSongForm', + return u'failed', translate(u'SongsPlugin.EditSongForm', u'You need to enter a song title.') if self.VerseListWidget.rowCount() == 0: self.SongTabWidget.setCurrentIndex(0) self.VerseListWidget.setFocus() - return False, translate(u'SongsPlugin.EditSongForm', + return u'failed', translate('uSongsPlugin.EditSongForm', u'You need to enter some verses.') if self.AuthorsListView.count() == 0: self.SongTabWidget.setCurrentIndex(1) self.AuthorsListView.setFocus() - #split the verse list by space and mark lower case for testing - taglist = unicode(translate(u'SongsPlugin.EditSongForm', u' bitpeovc')) - for verse in unicode(self.VerseOrderEdit.text()).lower().split(u' '): - if len(verse) > 1: - if taglist.find(verse[0:1]) > -1 \ - and verse[1:].isdigit(): - pass + answer = QtGui.QMessageBox.warning(self, + translate(u'SongsPlugin.EditSongForm', u'Warning'), + translate('SongsPlugin.EditSongForm', + 'You have set no author.\n' + 'Do you want to add now a author?'), + QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) + if answer == QtGui.QMessageBox.Yes: + return u'aborted', u'' + if self.song.verse_order: + order = [] + order_names = self.song.verse_order.split(u' ') + for item in order_names: + if len(item) == 1: + order.append(item.lower() + u'1') else: + order.append(item.lower()) + verses = [] + verse_names = [] + for index in range (0, self.VerseListWidget.rowCount()): + verse = self.VerseListWidget.item(index, 0) + verse = unicode(verse.data(QtCore.Qt.UserRole).toString()) + if verse not in verse_names: + verses.append( + re.sub(r'(.)[^:]*:(.*)', r'\1\2', verse.lower())) + verse_names.append(verse) + for count, item in enumerate(order): + if item not in verses: self.SongTabWidget.setCurrentIndex(0) self.VerseOrderEdit.setFocus() - return False, translate(u'SongsPlugin.EditSongForm', - u'Invalid verse entry, values must be I,B,T,P,E,O,V,C ' - u'followed by a number') - return True, u'' - - def onTitleEditItemLostFocus(self): - self.song.title = unicode(self.TitleEditItem.text()) - - def onVerseOrderEditLostFocus(self): - self.song.verse_order = unicode(self.VerseOrderEdit.text()) - - def onCommentsEditLostFocus(self): - self.song.comments = unicode(self.CommentsEdit.text()) - - def onCCLNumberEditLostFocus(self): - self.song.ccli_number = self.CCLNumberEdit.text() + return u'failed', unicode(translate( + 'SongsPlugin.EditSongForm', 'The verse order is ' + 'invalid. There is no verse corresponding to %s.')) % \ + order_names[count] + for count, verse in enumerate(verses): + if verse not in order: + self.SongTabWidget.setCurrentIndex(0) + self.VerseOrderEdit.setFocus() + answer = QtGui.QMessageBox.warning(self, + translate(u'SongsPlugin.EditSongForm', u'Warning'), + unicode(translate('SongsPlugin.EditSongForm', + '%s is not addressed in the verse order.\n' + 'Do you want to save anyhow?')) % \ + order_names[count].replace(u':', u' '), + QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) + if answer == QtGui.QMessageBox.No: + return u'aborted', u'' + return u'passed', u'' def onCopyrightInsertButtonTriggered(self): text = self.CopyrightEditItem.text() @@ -590,19 +605,19 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.close() def saveSong(self): - valid, message = self._validate_song() - if not valid: - QtGui.QMessageBox.critical( - self, translate(u'SongsPlugin.EditSongForm', u'Error'), message, - QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) - return False self.song.title = unicode(self.TitleEditItem.text()) self.song.copyright = unicode(self.CopyrightEditItem.text()) - self.song.search_title = unicode(self.TitleEditItem.text()) + \ - u'@'+ unicode(self.AlternativeEdit.text()) + self.song.search_title = self.song.title + u'@' + \ + unicode(self.AlternativeEdit.text()) self.song.comments = unicode(self.CommentsEdit.toPlainText()) self.song.verse_order = unicode(self.VerseOrderEdit.text()) self.song.ccli_number = unicode(self.CCLNumberEdit.text()) + status, message = self._validate_song() + if status == u'failed': + QtGui.QMessageBox.critical(self, + translate(u'SongsPlugin.EditSongForm', u'Error'), message) + if status != u'passed': + return False self.processLyrics() self.processTitle() self.songmanager.save_song(self.song) @@ -614,24 +629,15 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): sxml = SongXMLBuilder() sxml.new_document() sxml.add_lyrics_to_song() - text = u' ' + text = u'' for i in range (0, self.VerseListWidget.rowCount()): item = self.VerseListWidget.item(i, 0) verseId = unicode(item.data(QtCore.Qt.UserRole).toString()) bits = verseId.split(u':') sxml.add_verse_to_lyrics(bits[0], bits[1], unicode(item.text())) - text = text + unicode(self.VerseListWidget.item(i, 0).text()) \ - + u' ' - text = text.replace(u'\'', u'') - text = text.replace(u',', u'') - text = text.replace(u';', u'') - text = text.replace(u':', u'') - text = text.replace(u'(', u'') - text = text.replace(u')', u'') - text = text.replace(u'{', u'') - text = text.replace(u'}', u'') - text = text.replace(u'?', u'') - self.song.search_lyrics = unicode(text) + text = text + re.sub(r'\W+', u' ', + unicode(self.VerseListWidget.item(i, 0).text())) + u' ' + self.song.search_lyrics = text self.song.lyrics = unicode(sxml.extract_xml(), u'utf-8') except: log.exception(u'Problem processing song Lyrics \n%s', @@ -639,16 +645,6 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): def processTitle(self): log.debug(u'processTitle') - self.song.search_title = unicode(self.song.search_title) - self.song.search_title = self.song.search_title.replace(u'\'', u'') - self.song.search_title = self.song.search_title.replace(u'\"', u'') - self.song.search_title = self.song.search_title.replace(u'`', u'') - self.song.search_title = self.song.search_title.replace(u',', u'') - self.song.search_title = self.song.search_title.replace(u';', u'') - self.song.search_title = self.song.search_title.replace(u':', u'') - self.song.search_title = self.song.search_title.replace(u'(', u'') - self.song.search_title = self.song.search_title.replace(u')', u'') - self.song.search_title = self.song.search_title.replace(u'{', u'') - self.song.search_title = self.song.search_title.replace(u'}', u'') - self.song.search_title = self.song.search_title.replace(u'?', u'') + self.song.search_title = \ + re.sub(r'[\'"`,;:(){}?]+', u'', unicode(self.song.search_title)) diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index ecf0684dd..c60a67a42 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -23,6 +23,7 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### +import re import logging from PyQt4 import QtCore, QtGui @@ -160,6 +161,7 @@ class SongMediaItem(MediaManagerItem): def onSearchTextButtonClick(self): search_keywords = unicode(self.SearchTextEdit.displayText()) + search_keywords = re.sub(r'\W+', u' ', search_keywords) search_results = [] search_type = self.SearchTypeComboBox.currentIndex() if search_type == 0: @@ -350,8 +352,8 @@ class SongMediaItem(MediaManagerItem): if len(order) == 0: break for verse in verseList: - if verse[0][u'label'] == order[1:] and \ - verse[0][u'type'][0] == order[0]: + if verse[0][u'type'][0] == order[0] and \ + (verse[0][u'label'] == order[1:] or not order[1:]): verseTag = u'%s:%s' % \ (verse[0][u'type'], verse[0][u'label']) service_item.add_from_text( diff --git a/openlp/plugins/songs/lib/songimport.py b/openlp/plugins/songs/lib/songimport.py index 9fd7194e2..479828ddd 100644 --- a/openlp/plugins/songs/lib/songimport.py +++ b/openlp/plugins/songs/lib/songimport.py @@ -24,6 +24,7 @@ ############################################################################### import string +import re from PyQt4 import QtGui @@ -89,9 +90,6 @@ class SongImport(object): Get rid of some dodgy unicode and formatting characters we're not interested in. Some can be converted to ascii. """ - text = text.replace(u'\t', u' ') - text = text.replace(u'\r\n', u'\n') - text = text.replace(u'\r', u'\n') text = text.replace(u'\u2018', u'\'') text = text.replace(u'\u2019', u'\'') text = text.replace(u'\u201c', u'"') @@ -100,15 +98,9 @@ class SongImport(object): text = text.replace(u'\u2013', u'-') text = text.replace(u'\u2014', u'-') # Remove surplus blank lines, spaces, trailing/leading spaces - while text.find(u' ') >= 0: - text = text.replace(u' ', u' ') - text = text.replace(u'\n ', u'\n') - text = text.replace(u' \n', u'\n') - text = text.replace(u'\n\n\n\n\n', u'\f') - text = text.replace(u'\f ', u'\f') - text = text.replace(u' \f', u'\f') - while text.find(u'\f\f') >= 0: - text = text.replace(u'\f\f', u'\f') + text = re.sub(r'[ \t\v]+', u' ', text) + text = re.sub(r' ?(\r\n?|\n) ?', u'\n', text) + text = re.sub(r' ?(\n{5}|\f)+ ?', u'\f', text) return text def process_song_text(self, text): @@ -264,11 +256,9 @@ class SongImport(object): def remove_punctuation(self, text): """ - Remove punctuation from the string for searchable fields + Extracts alphanumeric words for searchable fields """ - for character in string.punctuation: - text = text.replace(character, u'') - return text + return re.sub(r'\W+', u' ', text) def finish(self): """