diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 3519a526a..e2b1dbf80 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -271,12 +271,23 @@ class SongMediaItem(MediaManagerItem): self.edit_song_form.exec_() def onDeleteClick(self): - item = self.ListView.currentItem() - if item: - item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] - self.parent.songmanager.delete_song(item_id) - row = self.ListView.row(item) - self.ListView.takeItem(row) + items = self.ListView.selectedIndexes() + if items: + if len(items) == 1: + del_message = self.trUtf8('Delete song?') + else: + del_message = unicode(self.trUtf8('Delete %d song?')) % len(items) + ans = QtGui.QMessageBox.question(self, + self.trUtf8('Delete Confirmation'), del_message, + QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok| + QtGui.QMessageBox.Cancel), + QtGui.QMessageBox.Ok) + if ans == QtGui.QMessageBox.Cancel: + return + for item in items: + item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] + self.parent.songmanager.delete_song(item_id) + self.onSearchTextButtonClick() def generateSlideData(self, service_item): raw_footer = [] diff --git a/openlp/plugins/songs/lib/sofimport.py b/openlp/plugins/songs/lib/sofimport.py index 63870f35c..ed5bb095d 100644 --- a/openlp/plugins/songs/lib/sofimport.py +++ b/openlp/plugins/songs/lib/sofimport.py @@ -44,7 +44,6 @@ if os.name == u'nt': PAGE_BOTH = 6 else: import uno - from com.sun.star.beans import PropertyValue from com.sun.star.awt.FontWeight import BOLD from com.sun.star.awt.FontSlant import ITALIC from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH @@ -71,7 +70,8 @@ class SofImport(object): to SongImport for writing song to disk """ self.song = None - self.manager = songmanager + self.manager = songmanager + self.process_started = False def import_sof(self, filename): self.start_ooo() @@ -85,17 +85,9 @@ class SofImport(object): TODO: The presentation/Impress plugin may already have it running """ if os.name == u'nt': - manager = Dispatch(u'com.sun.star.ServiceManager') - manager._FlagAsMethod(u'Bridge_GetStruct') - manager._FlagAsMethod(u'Bridge_GetValueObject') - self.desktop = manager.createInstance(u'com.sun.star.frame.Desktop') + self.start_ooo_process() + self.desktop = self.manager.createInstance(u'com.sun.star.frame.Desktop') else: - cmd = u'openoffice.org -nologo -norestore -minimized -invisible ' \ - + u'-nofirststartwizard ' \ - + '-accept="socket,host=localhost,port=2002;urp;"' - process = QtCore.QProcess() - process.startDetached(cmd) - process.waitForStarted() context = uno.getComponentContext() resolver = context.ServiceManager.createInstanceWithContext( u'com.sun.star.bridge.UnoUrlResolver', context) @@ -107,12 +99,29 @@ class SofImport(object): + 'port=2002;urp;StarOffice.ComponentContext') except: pass - time.sleep(1) + self.start_ooo_process() loop += 1 manager = ctx.ServiceManager self.desktop = manager.createInstanceWithContext( "com.sun.star.frame.Desktop", ctx ) + def start_ooo_process(self): + try: + if os.name == u'nt': + self.manager = Dispatch(u'com.sun.star.ServiceManager') + self.manager._FlagAsMethod(u'Bridge_GetStruct') + self.manager._FlagAsMethod(u'Bridge_GetValueObject') + else: + cmd = u'openoffice.org -nologo -norestore -minimized -invisible ' \ + + u'-nofirststartwizard ' \ + + '-accept="socket,host=localhost,port=2002;urp;"' + process = QtCore.QProcess() + process.startDetached(cmd) + process.waitForStarted() + self.process_started = True + except: + pass + def open_ooo_file(self, filepath): """ Open the passed file in OpenOffice.org Writer @@ -129,10 +138,12 @@ class SofImport(object): def close_ooo(self): """ - Close down OpenOffice.org. - TODO: Further checks that it have other docs open, e.g. Impress! + Close RTF file. Note, on Windows we'll leave OOo running + Leave running on Windows """ - self.desktop.terminate() + self.document.close(True) + if self.process_started: + self.desktop.terminate() def process_doc(self): """ @@ -273,7 +284,8 @@ class SofImport(object): Add a song number, store as alternate title. Also use the song number to work out which songbook we're in """ - self.song.set_song_number(song_no) + self.song.set_song_number(song_no) + self.song.set_alternate_title(song_no + u'.') if int(song_no) <= 640: self.song.set_song_book(u'Songs of Fellowship 1', u'Kingsway Publications') @@ -313,8 +325,11 @@ class SofImport(object): author2 = authors[i].strip() if author2.find(u' ') == -1 and i < len(authors) - 1: author2 = author2 + u' ' \ - + authors[i + 1].strip().split(u' ')[-1] - self.song.add_author(author2) + + authors[i + 1].strip().split(u' ')[-1] + if author2.endswith(u'.'): + author2 = author2[:-1] + if author2: + self.song.add_author(author2) def add_verse_line(self, text): """ @@ -337,11 +352,11 @@ class SofImport(object): """ if self.currentverse.strip() == u'': return - if self.is_chorus: - versetag = 'C' + if self.is_chorus: + versetag = u'C' splitat = None else: - versetag = 'V' + versetag = u'V' splitat = self.verse_splits(self.song.get_song_number()) if splitat: ln = 0 diff --git a/openlp/plugins/songs/lib/songimport.py b/openlp/plugins/songs/lib/songimport.py index aa9a73fd8..6adfcad7f 100644 --- a/openlp/plugins/songs/lib/songimport.py +++ b/openlp/plugins/songs/lib/songimport.py @@ -46,6 +46,7 @@ class SongImport(object): self.manager = song_manager self.title = u'' self.song_number = u'' + self.alternate_title = u'' self.copyright = u'' self.comment = u'' self.theme_name = u'' @@ -73,7 +74,7 @@ class SongImport(object): def get_song_number(self): """ - Return the song number (also known as alternate title) + Return the song number """ return self.song_number @@ -82,10 +83,16 @@ class SongImport(object): Set the title """ self.title = title - + + def set_alternate_title(self, title): + """ + Set the alternate title + """ + self.alternate_title = title + def set_song_number(self, song_number): """ - Set the song number/alternate title + Set the song number """ self.song_number = song_number @@ -113,7 +120,7 @@ class SongImport(object): def add_verse(self, verse, versetag): """ Add a verse. This is the whole verse, lines split by \n - Verse tag can be V1/C1/B1 etc, or 'V' and 'C' (will count the verses/ + Verse tag can be V1/C1/B etc, or 'V' and 'C' (will count the verses/ choruses itself) or None, where it will assume verse It will also attempt to detect duplicates. In this case it will just add to the verse order @@ -121,16 +128,17 @@ class SongImport(object): for (oldversetag, oldverse) in self.verses: if oldverse.strip() == verse.strip(): self.verse_order_list.append(oldversetag) - return - if versetag == u'C': + return + if versetag.startswith(u'C'): self.choruscount += 1 + if versetag == u'C': versetag += unicode(self.choruscount) if versetag == u'V' or not versetag: self.versecount += 1 versetag = u'V' + unicode(self.versecount) - self.verses.append([versetag, verse]) + self.verses.append([versetag, verse.rstrip()]) self.verse_order_list.append(versetag) - if self.choruscount > 0 and not versetag.startswith(u'C'): + if versetag.startswith(u'V') and self.contains_verse(u'C1'): self.verse_order_list.append(u'C1') def repeat_verse(self): @@ -138,7 +146,10 @@ class SongImport(object): Repeat the previous verse in the verse order """ self.verse_order_list.append(self.verse_order_list[-1]) - + + def contains_verse(self, versetag): + return versetag in self.verse_order_list + def check_complete(self): """ Check the mandatory fields are entered (i.e. title and a verse) @@ -173,7 +184,8 @@ class SongImport(object): """ song = Song() song.title = self.title - song.search_title = self.remove_punctuation(self.title) + song.search_title = self.remove_punctuation(self.title) \ + + '@' + self.alternate_title song.song_number = self.song_number song.search_lyrics = u'' sxml = SongXMLBuilder() @@ -235,6 +247,7 @@ class SongImport(object): print u'========================================' \ + u'========================================' print u'TITLE: ' + self.title + print u'ALT TITLE: ' + self.alternate_title for (versetag, versetext) in self.verses: print u'VERSE ' + versetag + u': ' + versetext print u'ORDER: ' + u' '.join(self.verse_order_list) diff --git a/openlp/plugins/songs/songsplugin.py b/openlp/plugins/songs/songsplugin.py index 6d39daa48..2155e3c16 100644 --- a/openlp/plugins/songs/songsplugin.py +++ b/openlp/plugins/songs/songsplugin.py @@ -27,7 +27,7 @@ import logging from PyQt4 import QtCore, QtGui -from openlp.core.lib import Plugin, build_icon, PluginStatus +from openlp.core.lib import Plugin, build_icon, PluginStatus, Receiver from openlp.plugins.songs.lib import SongManager, SongMediaItem, SongsTab, \ SofImport from openlp.plugins.songs.forms import OpenLPImportForm, OpenSongExportForm, \ @@ -187,8 +187,20 @@ class SongsPlugin(Plugin): filename = QtGui.QFileDialog.getOpenFileName( None, self.trUtf8('Open Songs of Fellowship file'), u'', u'Songs of Fellowship file (*.rtf *.RTF)') - sofimport = SofImport(self.songmanager) - sofimport.import_sof(unicode(filename)) + try: + sofimport = SofImport(self.songmanager) + sofimport.import_sof(unicode(filename)) + except: + log.exception('Could not import SoF file') + QtGui.QMessageBox.critical(None, + self.ImportSongMenu.trUtf8('Import Error'), + self.ImportSongMenu.trUtf8('Error importing Songs of ' + + 'Fellowship file.\nOpenOffice.org must be installed' + + ' and you must be using an unedited copy of the RTF' + + ' included with the Songs of Fellowship Music Editions'), + QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok), + QtGui.QMessageBox.Ok) + Receiver.send_message(u'load_song_list') def onExportOpenlp1ItemClicked(self): self.openlp_export_form.show()