From cfb896e3b102a350fa5e4a4dd4ca23b098907e69 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 2 Jan 2011 17:42:09 +0100 Subject: [PATCH 01/56] started work on OpenLyrics importer --- openlp/plugins/songs/forms/songimportform.py | 49 +++++++++-------- .../plugins/songs/forms/songimportwizard.py | 11 ++-- openlp/plugins/songs/lib/importer.py | 6 ++- openlp/plugins/songs/lib/xml.py | 54 +++++++++++-------- 4 files changed, 65 insertions(+), 55 deletions(-) diff --git a/openlp/plugins/songs/forms/songimportform.py b/openlp/plugins/songs/forms/songimportform.py index 5ec7f45e1..5776dd21a 100644 --- a/openlp/plugins/songs/forms/songimportform.py +++ b/openlp/plugins/songs/forms/songimportform.py @@ -73,12 +73,12 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): QtCore.QObject.connect(self.openLP1BrowseButton, QtCore.SIGNAL(u'clicked()'), self.onOpenLP1BrowseButtonClicked) - #QtCore.QObject.connect(self.openLyricsAddButton, - # QtCore.SIGNAL(u'clicked()'), - # self.onOpenLyricsAddButtonClicked) - #QtCore.QObject.connect(self.openLyricsRemoveButton, - # QtCore.SIGNAL(u'clicked()'), - # self.onOpenLyricsRemoveButtonClicked) + QtCore.QObject.connect(self.openLyricsAddButton, + QtCore.SIGNAL(u'clicked()'), + self.onOpenLyricsAddButtonClicked) + QtCore.QObject.connect(self.openLyricsRemoveButton, + QtCore.SIGNAL(u'clicked()'), + self.onOpenLyricsRemoveButtonClicked) QtCore.QObject.connect(self.openSongAddButton, QtCore.SIGNAL(u'clicked()'), self.onOpenSongAddButtonClicked) @@ -167,16 +167,15 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): self.openLP1BrowseButton.setFocus() return False elif source_format == SongFormat.OpenLyrics: -# if self.openLyricsFileListWidget.count() == 0: -# QtGui.QMessageBox.critical(self, -# translate('SongsPlugin.ImportWizardForm', -# 'No OpenLyrics Files Selected'), -# translate('SongsPlugin.ImportWizardForm', -# 'You need to add at least one OpenLyrics ' -# 'song file to import from.')) -# self.openLyricsAddButton.setFocus() -# return False - return False + if self.openLyricsFileListWidget.count() == 0: + QtGui.QMessageBox.critical(self, + translate('SongsPlugin.ImportWizardForm', + 'No OpenLyrics Files Selected'), + translate('SongsPlugin.ImportWizardForm', + 'You need to add at least one OpenLyrics ' + 'song file to import from.')) + self.openLyricsAddButton.setFocus() + return False elif source_format == SongFormat.OpenSong: if self.openSongFileListWidget.count() == 0: QtGui.QMessageBox.critical(self, @@ -337,15 +336,15 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): 'openlp.org v1.x Databases') ) - #def onOpenLyricsAddButtonClicked(self): - # self.getFiles( - # translate('SongsPlugin.ImportWizardForm', - # 'Select OpenLyrics Files'), - # self.openLyricsFileListWidget - # ) + def onOpenLyricsAddButtonClicked(self): + self.getFiles( + translate('SongsPlugin.ImportWizardForm', + 'Select OpenLyrics Files'), + self.openLyricsFileListWidget + ) - #def onOpenLyricsRemoveButtonClicked(self): - # self.removeSelectedItems(self.openLyricsFileListWidget) + def onOpenLyricsRemoveButtonClicked(self): + self.removeSelectedItems(self.openLyricsFileListWidget) def onOpenSongAddButtonClicked(self): self.getFiles( @@ -435,7 +434,7 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): self.formatComboBox.setCurrentIndex(0) self.openLP2FilenameEdit.setText(u'') self.openLP1FilenameEdit.setText(u'') - #self.openLyricsFileListWidget.clear() + self.openLyricsFileListWidget.clear() self.openSongFileListWidget.clear() self.wordsOfWorshipFileListWidget.clear() self.ccliFileListWidget.clear() diff --git a/openlp/plugins/songs/forms/songimportwizard.py b/openlp/plugins/songs/forms/songimportwizard.py index 85fbb07fe..6eccff9b4 100644 --- a/openlp/plugins/songs/forms/songimportwizard.py +++ b/openlp/plugins/songs/forms/songimportwizard.py @@ -81,9 +81,6 @@ class Ui_SongImportWizard(object): self.addSingleFileSelectItem(u'openLP1', None, True) # OpenLyrics self.addMultiFileSelectItem(u'openLyrics', u'OpenLyrics', True) - # set OpenLyrics to disabled by default - self.openLyricsDisabledWidget.setVisible(True) - self.openLyricsImportWidget.setVisible(False) # Open Song self.addMultiFileSelectItem(u'openSong', u'OpenSong') # Words of Worship @@ -177,10 +174,10 @@ class Ui_SongImportWizard(object): 'importer has been disabled due to a missing Python module. If ' 'you want to use this importer, you will need to install the ' '"python-sqlite" module.')) - #self.openLyricsAddButton.setText( - # translate('SongsPlugin.ImportWizardForm', 'Add Files...')) - #self.openLyricsRemoveButton.setText( - # translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) + self.openLyricsAddButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Add Files...')) + self.openLyricsRemoveButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) self.openLyricsDisabledLabel.setText( translate('SongsPlugin.ImportWizardForm', 'The OpenLyrics ' 'importer has not yet been developed, but as you can see, we are ' diff --git a/openlp/plugins/songs/lib/importer.py b/openlp/plugins/songs/lib/importer.py index b82e14c12..128d80138 100644 --- a/openlp/plugins/songs/lib/importer.py +++ b/openlp/plugins/songs/lib/importer.py @@ -26,6 +26,7 @@ from opensongimport import OpenSongImport from olpimport import OpenLPSongImport +from openlyricsimport import OpenLyricsImport from wowimport import WowImport from cclifileimport import CCLIFileImport from ewimport import EasyWorshipSongImport @@ -77,8 +78,10 @@ class SongFormat(object): """ if format == SongFormat.OpenLP2: return OpenLPSongImport - if format == SongFormat.OpenLP1: + elif format == SongFormat.OpenLP1: return OpenLP1SongImport + elif format == SongFormat.OpenLyrics: + return OpenLyricsImport elif format == SongFormat.OpenSong: return OpenSongImport elif format == SongFormat.SongsOfFellowship: @@ -93,7 +96,6 @@ class SongFormat(object): return EasyWorshipSongImport elif format == SongFormat.SongBeamer: return SongBeamerImport -# else: return None @staticmethod diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index f00711bb6..a6558d669 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -80,8 +80,8 @@ class SongXMLBuilder(object): ``content`` The actual text of the verse to be stored. """ - verse = etree.Element(u'verse', type = unicode(type), - label = unicode(number)) + verse = etree.Element(u'verse', type=unicode(type), + label=unicode(number)) verse.text = etree.CDATA(content) self.lyrics.append(verse) @@ -194,9 +194,7 @@ class LyricsXML(object): text = text.replace('\r\n', '\n') verses = text.split('\n\n') self.languages = [{u'language': u'en', u'verses': []}] - counter = 0 - for verse in verses: - counter = counter + 1 + for counter, verse in enumerate(verses): self.languages[0][u'verses'].append({ u'type': u'verse', u'label': unicode(counter), @@ -245,14 +243,16 @@ class LyricsXML(object): class OpenLyricsParser(object): """ - This class represents the converter for Song to/from OpenLyrics XML. + This class represents the converter for Song to/from + `OpenLyrics `_ XML. """ + # TODO: complete OpenLyrics standard implementation! def __init__(self, manager): self.manager = manager def song_to_xml(self, song): """ - Convert the song to OpenLyrics Format + Convert the song to OpenLyrics Format. """ song_xml_parser = SongXMLParser(song.lyrics) verse_list = song_xml_parser.get_verses() @@ -286,7 +286,7 @@ class OpenLyricsParser(object): def xml_to_song(self, xml): """ - Create a Song from OpenLyrics format xml + Create and save a Song from OpenLyrics format xml. """ # No xml get out of here if not xml: @@ -299,23 +299,15 @@ class OpenLyricsParser(object): song.copyright = unicode(properties.copyright.text) if song.copyright == u'None': song.copyright = u'' - song.verse_order = unicode(properties.verseOrder.text) - if song.verse_order == u'None': - song.verse_order = u'' song.topics = [] song.book = None - theme_name = None try: song.ccli_number = unicode(properties.ccliNo.text) - except: + except AttributeError: song.ccli_number = u'' try: - theme_name = unicode(properties.themes.theme) - except: - pass - if theme_name: - song.theme_name = theme_name - else: + song.theme_name = unicode(properties.themes.theme) + except AttributeError: song.theme_name = u'' # Process Titles for title in properties.titles.title: @@ -331,6 +323,7 @@ class OpenLyricsParser(object): # Process Lyrics sxml = SongXMLBuilder() search_text = u'' + song.verse_order = u'' for lyrics in song_xml.lyrics: for verse in song_xml.lyrics.verse: text = u'' @@ -341,17 +334,36 @@ class OpenLyricsParser(object): else: text += u'\n' + line type = VerseType.expand_string(verse.attrib[u'name'][0]) + # Here we need to create the verse order for the case that the + # song does not have a verseOrder property. sxml.add_verse_to_lyrics(type, verse.attrib[u'name'][1], text) search_text = search_text + text song.search_lyrics = search_text.lower() song.lyrics = unicode(sxml.extract_xml(), u'utf-8') + try: + song.verse_order = unicode(properties.verseOrder.text) + except AttributeError: + # TODO: Do not allow empty verse order. + # Do not worry! + pass + if song.verse_order == u'None': + song.verse_order = u'' + # Process Comments song.comments = u'' + try: + for comment in properties.comments.comment: + if not song.comments: + song.comments = comment + else: + song.comments += u'\n' + comment + except AttributeError: + pass song.song_number = u'' # Process Authors try: for author in properties.authors.author: self._process_author(author.text, song) - except: + except AttributeError: # No Author in XML so ignore pass self.manager.save_object(song) @@ -396,4 +408,4 @@ class OpenLyricsParser(object): new_author = Author.populate(first_name=name.rsplit(u' ', 1)[0], last_name=name.rsplit(u' ', 1)[1], display_name=name) self.manager.save_object(new_author) - song.authors.append(new_author) \ No newline at end of file + song.authors.append(new_author) From 909fa25e7b08a6d9fc0de438c6c430b3929816c0 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 2 Jan 2011 18:24:47 +0100 Subject: [PATCH 02/56] clean ups, added missing file --- openlp/plugins/songs/lib/mediaitem.py | 13 ++-- openlp/plugins/songs/lib/openlyricsimport.py | 77 ++++++++++++++++++++ openlp/plugins/songs/lib/xml.py | 1 + 3 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 openlp/plugins/songs/lib/openlyricsimport.py diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index cd305877c..011373d68 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -314,15 +314,14 @@ class SongMediaItem(MediaManagerItem): translate('SongsPlugin.MediaItem', 'You must select an item to delete.')): items = self.listView.selectedIndexes() - ans = QtGui.QMessageBox.question(self, + if QtGui.QMessageBox.question(self, translate('SongsPlugin.MediaItem', 'Delete Song(s)?'), translate('SongsPlugin.MediaItem', 'Are you sure you want to delete the %n selected song(s)?', '', QtCore.QCoreApplication.CodecForTr, len(items)), - QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok| - QtGui.QMessageBox.Cancel), - QtGui.QMessageBox.Ok) - if ans == QtGui.QMessageBox.Cancel: + QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok | + QtGui.QMessageBox.Cancel), + QtGui.QMessageBox.Ok) == QtGui.QMessageBox.Cancel: return for item in items: item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] @@ -396,8 +395,8 @@ class SongMediaItem(MediaManagerItem): service_item.audit = [ song.title, author_audit, song.copyright, unicode(song.ccli_number) ] - service_item.data_string = {u'title':song.search_title, - u'authors':author_list} + service_item.data_string = {u'title': song.search_title, + u'authors': author_list} service_item.xml_version = self.openLyrics.song_to_xml(song) return True diff --git a/openlp/plugins/songs/lib/openlyricsimport.py b/openlp/plugins/songs/lib/openlyricsimport.py new file mode 100644 index 000000000..6deb9cc09 --- /dev/null +++ b/openlp/plugins/songs/lib/openlyricsimport.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2011 Raoul Snyman # +# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael # +# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian # +# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, # +# Carsten Tinggaard, Frode Woldsund # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### +""" +The :mod:`openlyricsimport` module provides the functionality for importing +songs which are saved as OpenLyrics files. +""" + +#import logging +import os + +from openlp.core.lib import translate +from openlp.plugins.songs.lib.songimport import SongImport +from openlp.plugins.songs.lib import OpenLyricsParser + +#log = logging.getLogger(__name__) + +class OpenLyricsImport(SongImport): + """ + This provides the Openlyrics import. + """ + def __init__(self, master_manager, **kwargs): + """ + Initialise the import. + """ + SongImport.__init__(self, master_manager) + self.master_manager = master_manager + self.openLyricsParser = OpenLyricsParser(master_manager) + if kwargs.has_key(u'filename'): + self.import_source = kwargs[u'filename'] + if kwargs.has_key(u'filenames'): + self.import_source = kwargs[u'filenames'] + + def do_import(self): + """ + Imports the songs. + """ + success = True + self.import_wizard.importProgressBar.setMaximum(len(self.import_source)) + for file_path in self.import_source: + if self.stop_import_flag: + success = False + break + file = open(file_path) + xml = file.read() + file.close() + self.import_wizard.incrementProgressBar(unicode(translate( + 'SongsPlugin.OpenLyricsImport', 'Importing %s...')) % + os.path.basename(file_path)) + if self.openLyricsParser.xml_to_song(xml) == 0: + success = false + break + if success: + return True + return False diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index a6558d669..65be3f5e4 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -367,6 +367,7 @@ class OpenLyricsParser(object): # No Author in XML so ignore pass self.manager.save_object(song) + # TODO: better return song itself, instead of song.id return song.id def _add_text_to_element(self, tag, parent, text=None, label=None): From 9fc113abceae1a21a3ce1747ba58b86af79edfd0 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Mon, 3 Jan 2011 08:16:21 +0100 Subject: [PATCH 03/56] fix wrong 'themes' usage (themes -> topics), improved methods, make sure a missing property does not crash openlp --- openlp/plugins/songs/lib/xml.py | 112 ++++++++++++++++++++++---------- 1 file changed, 76 insertions(+), 36 deletions(-) diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index 65be3f5e4..290d83d38 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -42,8 +42,10 @@ import logging import re from lxml import etree, objectify + +from openlp.core.lib import translate from openlp.plugins.songs.lib import VerseType -from openlp.plugins.songs.lib.db import Author, Song +from openlp.plugins.songs.lib.db import Author, Song, Topic log = logging.getLogger(__name__) @@ -246,7 +248,7 @@ class OpenLyricsParser(object): This class represents the converter for Song to/from `OpenLyrics `_ XML. """ - # TODO: complete OpenLyrics standard implementation! + # TODO: complete OpenLyrics standard implementation as fare as possible! def __init__(self, manager): self.manager = manager @@ -288,7 +290,7 @@ class OpenLyricsParser(object): """ Create and save a Song from OpenLyrics format xml. """ - # No xml get out of here + # No xml get out of here. if not xml: return 0 song = Song() @@ -296,19 +298,18 @@ class OpenLyricsParser(object): xml = xml[38:] song_xml = objectify.fromstring(xml) properties = song_xml.properties - song.copyright = unicode(properties.copyright.text) - if song.copyright == u'None': + # Process Copyright + try: + song.copyright = unicode(properties.copyright.text) + if song.copyright == u'None': + song.copyright = u'' + except AttributeError: song.copyright = u'' - song.topics = [] - song.book = None + # Process CCLI number try: song.ccli_number = unicode(properties.ccliNo.text) except AttributeError: song.ccli_number = u'' - try: - song.theme_name = unicode(properties.themes.theme) - except AttributeError: - song.theme_name = u'' # Process Titles for title in properties.titles.title: if not song.title: @@ -325,26 +326,29 @@ class OpenLyricsParser(object): search_text = u'' song.verse_order = u'' for lyrics in song_xml.lyrics: - for verse in song_xml.lyrics.verse: + for verse in lyrics.verse: text = u'' - for line in verse.lines.line: - line = unicode(line) - if not text: - text = line - else: - text += u'\n' + line - type = VerseType.expand_string(verse.attrib[u'name'][0]) - # Here we need to create the verse order for the case that the - # song does not have a verseOrder property. - sxml.add_verse_to_lyrics(type, verse.attrib[u'name'][1], text) + # Note that the element will not be in OpenLyrics 0.8: + # http://code.google.com/p/openlyrics/issues/detail?id=8 + for line in verse.lines: + for line in line.line: + line = unicode(line) + if not text: + text = line + else: + text += u'\n' + line + type_ = VerseType.expand_string(verse.attrib[u'name'][0]) + # TODO: Here we need to create the verse order for the case that + # the song does not have a verseOrder property. + sxml.add_verse_to_lyrics(type_, verse.attrib[u'name'][1], text) search_text = search_text + text song.search_lyrics = search_text.lower() song.lyrics = unicode(sxml.extract_xml(), u'utf-8') + # Process verse order try: song.verse_order = unicode(properties.verseOrder.text) except AttributeError: # TODO: Do not allow empty verse order. - # Do not worry! pass if song.verse_order == u'None': song.verse_order = u'' @@ -358,16 +362,26 @@ class OpenLyricsParser(object): song.comments += u'\n' + comment except AttributeError: pass - song.song_number = u'' # Process Authors try: for author in properties.authors.author: self._process_author(author.text, song) except AttributeError: - # No Author in XML so ignore pass + if not song.authors: + # Add "Author unknown" (can be translated) + self._process_author(translate('SongsPlugin.XML', + 'Author unknown'), song) + # Process Topcis + try: + for topic in properties.themes.theme: + self._process_topic(topic.text, song) + except AttributeError: + pass + # Properties not yet supported. + song.book = None + song.song_number = u'' self.manager.save_object(song) - # TODO: better return song itself, instead of song.id return song.id def _add_text_to_element(self, tag, parent, text=None, label=None): @@ -396,17 +410,43 @@ class OpenLyricsParser(object): def _process_author(self, name, song): """ - Find or create an Author from display_name. + Finds an existing Author or creates a new Author and adds it to the song + object. + + ``name`` + The display_name of the song (string). + + ``song`` + The song the Author will be added to. """ + if not name: + return name = unicode(name) author = self.manager.get_object_filtered(Author, Author.display_name == name) - if author: - # should only be one! so take the first - song.authors.append(author) - else: - # Need a new author - new_author = Author.populate(first_name=name.rsplit(u' ', 1)[0], - last_name=name.rsplit(u' ', 1)[1], display_name=name) - self.manager.save_object(new_author) - song.authors.append(new_author) + if author is None: + # We need to create a new author, as the author does not exist. + author = Author.populate(first_name=name.rsplit(u' ', 1)[0], + last_name=name.rsplit(u' ', 1)[1], display_name=name) + self.manager.save_object(author) + song.authors.append(author) + + def _process_topic(self, topictext, song): + """ + Finds an existing Topic or creates a new Topic and adds it to the song + object. + + ``topictext`` + The topictext we add to the song (string). + + ``song`` + The song the Topic will be added to. + """ + topictext = unicode(topictext) + # Check if topic already exists in the database. + topic = self.manager.get_object_filtered(Topic, Topic.name == topictext) + if topic is None: + # We need to create a new topic, as the topic does not exist. + topic = Topic.populate(name=topictext) + self.manager.save_object(topic) + song.topics.append(topic) From a127019f28c3d3810cb1392f7949e0cbdb23b9ed Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Mon, 3 Jan 2011 14:43:09 +0100 Subject: [PATCH 04/56] fixed wrong use of 'theme', implemented songbooks and songnumber, continued with openlyrics implementation, clean ups --- openlp/plugins/songs/lib/mediaitem.py | 7 +- openlp/plugins/songs/lib/openlyricsimport.py | 11 +-- openlp/plugins/songs/lib/xml.py | 91 ++++++++++++++++---- 3 files changed, 81 insertions(+), 28 deletions(-) diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 011373d68..d2565ad8f 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -404,11 +404,13 @@ class SongMediaItem(MediaManagerItem): """ Triggered by a song being loaded by the service item """ + # TODO: fix db flooding log.debug(u'serviceLoad') if item.data_string: + print item.data_string search_results = self.parent.manager.get_all_objects(Song, Song.search_title == - item.data_string[u'title'].split(u'@')[0].lower() , + item.data_string[u'title'].split(u'@')[0].lower(), Song.search_title.asc()) author_list = item.data_string[u'authors'].split(u', ') # The service item always has an author (at least it has u'' as @@ -417,7 +419,6 @@ class SongMediaItem(MediaManagerItem): if u'' in author_list: author_list.remove(u'') editId = 0 - uuid = item._uuid add_song = True if search_results: for song in search_results: @@ -444,7 +445,7 @@ class SongMediaItem(MediaManagerItem): # Update service with correct song id. if editId != 0: Receiver.send_message(u'service_item_update', - u'%s:%s' %(editId, uuid)) + u'%s:%s' % (editId, item._uuid)) def collateSongTitles(self, song_1, song_2): """ diff --git a/openlp/plugins/songs/lib/openlyricsimport.py b/openlp/plugins/songs/lib/openlyricsimport.py index 6deb9cc09..f4f49e1b5 100644 --- a/openlp/plugins/songs/lib/openlyricsimport.py +++ b/openlp/plugins/songs/lib/openlyricsimport.py @@ -61,8 +61,7 @@ class OpenLyricsImport(SongImport): self.import_wizard.importProgressBar.setMaximum(len(self.import_source)) for file_path in self.import_source: if self.stop_import_flag: - success = False - break + return False file = open(file_path) xml = file.read() file.close() @@ -70,8 +69,6 @@ class OpenLyricsImport(SongImport): 'SongsPlugin.OpenLyricsImport', 'Importing %s...')) % os.path.basename(file_path)) if self.openLyricsParser.xml_to_song(xml) == 0: - success = false - break - if success: - return True - return False + # Importing this song failed! For now we stop import. + return False + return True diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index 290d83d38..2a3ec4944 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -45,7 +45,7 @@ from lxml import etree, objectify from openlp.core.lib import translate from openlp.plugins.songs.lib import VerseType -from openlp.plugins.songs.lib.db import Author, Song, Topic +from openlp.plugins.songs.lib.db import Author, Book, Song, Topic log = logging.getLogger(__name__) @@ -265,22 +265,41 @@ class OpenLyricsParser(object): self._add_text_to_element(u'title', titles, song.title) if song.alternate_title: self._add_text_to_element(u'title', titles, song.alternate_title) - if song.theme_name: - themes = etree.SubElement(properties, u'themes') - self._add_text_to_element(u'theme', themes, song.theme_name) - self._add_text_to_element(u'copyright', properties, song.copyright) - self._add_text_to_element(u'verseOrder', properties, song.verse_order) + if song.comments: + comments = etree.SubElement(properties, u'comments') + self._add_text_to_element(u'comment', comments, song.comments) + if song.copyright: + self._add_text_to_element(u'copyright', properties, song.copyright) + if song.verse_order: + self._add_text_to_element( + u'verseOrder', properties, song.verse_order) if song.ccli_number: self._add_text_to_element(u'ccliNo', properties, song.ccli_number) - authors = etree.SubElement(properties, u'authors') - for author in song.authors: - self._add_text_to_element(u'author', authors, author.display_name) + if song.authors: + authors = etree.SubElement(properties, u'authors') + for author in song.authors: + self._add_text_to_element( + u'author', authors, author.display_name) + book = self.manager.get_object_filtered( + Book, Book.id == song.song_book_id) + if book is not None: + book = book.name + songbooks = etree.SubElement(properties, u'songbooks') + element = self._add_text_to_element( + u'songbook', songbooks, None, book) + element.set(u'entry', song.song_number) + if song.topics: + themes = etree.SubElement(properties, u'themes') + for topic in song.topics: + self._add_text_to_element(u'theme', themes, topic.name) lyrics = etree.SubElement(song_xml, u'lyrics') for verse in verse_list: verse_tag = u'%s%s' % ( verse[0][u'type'][0].lower(), verse[0][u'label']) element = \ self._add_text_to_element(u'verse', lyrics, None, verse_tag) + # Note that the element will not be in OpenLyrics 0.8: + # http://code.google.com/p/openlyrics/issues/detail?id=8 element = self._add_text_to_element(u'lines', element) for line in unicode(verse[1]).split(u'\n'): self._add_text_to_element(u'line', element, line) @@ -357,9 +376,9 @@ class OpenLyricsParser(object): try: for comment in properties.comments.comment: if not song.comments: - song.comments = comment + song.comments = unicode(comment.text) else: - song.comments += u'\n' + comment + song.comments += u'\n' + unicode(comment.text) except AttributeError: pass # Process Authors @@ -372,6 +391,18 @@ class OpenLyricsParser(object): # Add "Author unknown" (can be translated) self._process_author(translate('SongsPlugin.XML', 'Author unknown'), song) + # Process Song Book and Song Number + song.song_book_id = 0 + song.song_number = u'' + try: + for songbook in properties.songbooks.songbook: + self._process_songbook(songbook.get(u'name'), song) + if songbook.get(u'entry'): + song.song_number = unicode(songbook.get(u'entry')) + # OpenLp does only support one song book, so take the first one. + break + except AttributeError: + pass # Process Topcis try: for topic in properties.themes.theme: @@ -379,8 +410,7 @@ class OpenLyricsParser(object): except AttributeError: pass # Properties not yet supported. - song.book = None - song.song_number = u'' + song.theme_name = u'' self.manager.save_object(song) return song.id @@ -417,9 +447,10 @@ class OpenLyricsParser(object): The display_name of the song (string). ``song`` - The song the Author will be added to. + The song the object. """ if not name: + # Wrong use of XML here, as no text has been supplied. return name = unicode(name) author = self.manager.get_object_filtered(Author, @@ -433,20 +464,44 @@ class OpenLyricsParser(object): def _process_topic(self, topictext, song): """ - Finds an existing Topic or creates a new Topic and adds it to the song + Finds an existing topic or creates a new topic and adds it to the song object. ``topictext`` - The topictext we add to the song (string). + The topictext of the topic (string). ``song`` - The song the Topic will be added to. + The song object. """ + if not topictext: + # Wrong use of XML here, as no text has been supplied. + return topictext = unicode(topictext) - # Check if topic already exists in the database. topic = self.manager.get_object_filtered(Topic, Topic.name == topictext) if topic is None: # We need to create a new topic, as the topic does not exist. topic = Topic.populate(name=topictext) self.manager.save_object(topic) song.topics.append(topic) + + def _process_songbook(self, bookname, song): + """ + Finds an existing book or creates a new book and adds it to the song + object. + + ``bookname`` + The name of the book (string). + + ``song`` + The song object. + """ + if not bookname: + # Wrong use of XML here, as no text has been supplied. + return + bookname = unicode(bookname) + book = self.manager.get_object_filtered(Book, Book.name == bookname) + if book is None: + # We need to create a new book, as the book does not exist. + book = Book.populate(name=bookname, publisher=u'') + self.manager.save_object(book) + song.song_book_id = book.id From a5f73713d4192ef0ac9b961255c1f1eebbac8fda Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Mon, 3 Jan 2011 22:47:49 +0100 Subject: [PATCH 05/56] add standard verseOrder, if xml does not have any verseOrder property; added '_get' and '_text' methods which do the same as 'get' and 'text', but make sure that they never return 'None' (but u'' instead) --- openlp/plugins/songs/lib/mediaitem.py | 2 - openlp/plugins/songs/lib/openlyricsimport.py | 8 +- openlp/plugins/songs/lib/xml.py | 86 +++++++++++++------- 3 files changed, 58 insertions(+), 38 deletions(-) diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index d2565ad8f..93d648146 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -404,10 +404,8 @@ class SongMediaItem(MediaManagerItem): """ Triggered by a song being loaded by the service item """ - # TODO: fix db flooding log.debug(u'serviceLoad') if item.data_string: - print item.data_string search_results = self.parent.manager.get_all_objects(Song, Song.search_title == item.data_string[u'title'].split(u'@')[0].lower(), diff --git a/openlp/plugins/songs/lib/openlyricsimport.py b/openlp/plugins/songs/lib/openlyricsimport.py index f4f49e1b5..5346b5803 100644 --- a/openlp/plugins/songs/lib/openlyricsimport.py +++ b/openlp/plugins/songs/lib/openlyricsimport.py @@ -28,15 +28,12 @@ The :mod:`openlyricsimport` module provides the functionality for importing songs which are saved as OpenLyrics files. """ -#import logging import os from openlp.core.lib import translate from openlp.plugins.songs.lib.songimport import SongImport from openlp.plugins.songs.lib import OpenLyricsParser -#log = logging.getLogger(__name__) - class OpenLyricsImport(SongImport): """ This provides the Openlyrics import. @@ -57,14 +54,15 @@ class OpenLyricsImport(SongImport): """ Imports the songs. """ - success = True self.import_wizard.importProgressBar.setMaximum(len(self.import_source)) for file_path in self.import_source: if self.stop_import_flag: return False file = open(file_path) - xml = file.read() + lines = file.readlines() file.close() + lines = [line.strip() for line in lines] + xml = u''.join(lines) self.import_wizard.incrementProgressBar(unicode(translate( 'SongsPlugin.OpenLyricsImport', 'Importing %s...')) % os.path.basename(file_path)) diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index 2a3ec4944..326f97537 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -298,8 +298,6 @@ class OpenLyricsParser(object): verse[0][u'type'][0].lower(), verse[0][u'label']) element = \ self._add_text_to_element(u'verse', lyrics, None, verse_tag) - # Note that the element will not be in OpenLyrics 0.8: - # http://code.google.com/p/openlyrics/issues/detail?id=8 element = self._add_text_to_element(u'lines', element) for line in unicode(verse[1]).split(u'\n'): self._add_text_to_element(u'line', element, line) @@ -307,7 +305,10 @@ class OpenLyricsParser(object): def xml_to_song(self, xml): """ - Create and save a Song from OpenLyrics format xml. + Create and save a song from OpenLyrics format xml to the database. Since + we also export XML from external sources (e. g. OpenLyrics import), we + cannot ensure, that it completely conforms to the OpenLyrics standard. + That means, that we for example have to remove chords. """ # No xml get out of here. if not xml: @@ -315,28 +316,28 @@ class OpenLyricsParser(object): song = Song() if xml[:5] == u'').sub(u'', xml) song_xml = objectify.fromstring(xml) properties = song_xml.properties # Process Copyright try: - song.copyright = unicode(properties.copyright.text) - if song.copyright == u'None': - song.copyright = u'' + song.copyright = self._text(properties.copyright) except AttributeError: song.copyright = u'' # Process CCLI number try: - song.ccli_number = unicode(properties.ccliNo.text) + song.ccli_number = self._text(properties.ccliNo) except AttributeError: song.ccli_number = u'' # Process Titles for title in properties.titles.title: if not song.title: - song.title = unicode(title.text) + song.title = self._text(title) song.search_title = unicode(song.title) song.alternate_title = u'' else: - song.alternate_title = unicode(title.text) + song.alternate_title = self._text(title) song.search_title += u'@' + song.alternate_title song.search_title = re.sub(r'[\'"`,;:(){}?]+', u'', unicode(song.search_title)).lower() @@ -347,8 +348,6 @@ class OpenLyricsParser(object): for lyrics in song_xml.lyrics: for verse in lyrics.verse: text = u'' - # Note that the element will not be in OpenLyrics 0.8: - # http://code.google.com/p/openlyrics/issues/detail?id=8 for line in verse.lines: for line in line.line: line = unicode(line) @@ -356,18 +355,21 @@ class OpenLyricsParser(object): text = line else: text += u'\n' + line - type_ = VerseType.expand_string(verse.attrib[u'name'][0]) - # TODO: Here we need to create the verse order for the case that - # the song does not have a verseOrder property. - sxml.add_verse_to_lyrics(type_, verse.attrib[u'name'][1], text) + type = VerseType.expand_string(verse.attrib[u'name'][0]) + sxml.add_verse_to_lyrics(type, verse.attrib[u'name'][1], text) + # TODO: test this verse_order thing! + song.verse_order += u'%s%s ' % (type[0], + verse.attrib[u'name'][1]) search_text = search_text + text song.search_lyrics = search_text.lower() song.lyrics = unicode(sxml.extract_xml(), u'utf-8') + song.verse_order = song.verse_order.strip() # Process verse order try: - song.verse_order = unicode(properties.verseOrder.text) + song.verse_order = self._text(properties.verseOrder) except AttributeError: - # TODO: Do not allow empty verse order. + # Do not worry, as the verse order has cautionary already been + # saved while creating the verses. pass if song.verse_order == u'None': song.verse_order = u'' @@ -376,29 +378,29 @@ class OpenLyricsParser(object): try: for comment in properties.comments.comment: if not song.comments: - song.comments = unicode(comment.text) + song.comments = self._text(comment) else: - song.comments += u'\n' + unicode(comment.text) + song.comments += u'\n' + self._text(comment) except AttributeError: pass # Process Authors try: for author in properties.authors.author: - self._process_author(author.text, song) + self._process_author(self._text(author), song) except AttributeError: pass if not song.authors: # Add "Author unknown" (can be translated) - self._process_author(translate('SongsPlugin.XML', - 'Author unknown'), song) + self._process_author(unicode(translate('SongsPlugin.XML', + 'Author unknown')), song) # Process Song Book and Song Number song.song_book_id = 0 song.song_number = u'' try: for songbook in properties.songbooks.songbook: - self._process_songbook(songbook.get(u'name'), song) + self._process_songbook(self._get(songbook, u'name'), song) if songbook.get(u'entry'): - song.song_number = unicode(songbook.get(u'entry')) + song.song_number = self._get(songbook, u'entry') # OpenLp does only support one song book, so take the first one. break except AttributeError: @@ -406,7 +408,7 @@ class OpenLyricsParser(object): # Process Topcis try: for topic in properties.themes.theme: - self._process_topic(topic.text, song) + self._process_topic(self._text(topic), song) except AttributeError: pass # Properties not yet supported. @@ -414,6 +416,31 @@ class OpenLyricsParser(object): self.manager.save_object(song) return song.id + def _get(self, element, attribute): + """ + This takes care of empty attributes. It returns the element's attribute. + + ``element`` + The element. + + ``attribute`` + The element's attribute (unicode). + """ + if element.get(attribute) is not None: + return element.get(attribute) + return u'' + + def _text(self, element): + """ + This takes care of empty texts. It returns the element's text. + + ``element`` + The element. + """ + if element.text is not None: + return unicode(element.text) + return u'' + def _add_text_to_element(self, tag, parent, text=None, label=None): if label: element = etree.Element(tag, name=unicode(label)) @@ -444,7 +471,7 @@ class OpenLyricsParser(object): object. ``name`` - The display_name of the song (string). + The display_name of the song (unicode). ``song`` The song the object. @@ -452,7 +479,6 @@ class OpenLyricsParser(object): if not name: # Wrong use of XML here, as no text has been supplied. return - name = unicode(name) author = self.manager.get_object_filtered(Author, Author.display_name == name) if author is None: @@ -468,7 +494,7 @@ class OpenLyricsParser(object): object. ``topictext`` - The topictext of the topic (string). + The topictext of the topic (unicode). ``song`` The song object. @@ -476,7 +502,6 @@ class OpenLyricsParser(object): if not topictext: # Wrong use of XML here, as no text has been supplied. return - topictext = unicode(topictext) topic = self.manager.get_object_filtered(Topic, Topic.name == topictext) if topic is None: # We need to create a new topic, as the topic does not exist. @@ -490,7 +515,7 @@ class OpenLyricsParser(object): object. ``bookname`` - The name of the book (string). + The name of the book (unicode). ``song`` The song object. @@ -498,7 +523,6 @@ class OpenLyricsParser(object): if not bookname: # Wrong use of XML here, as no text has been supplied. return - bookname = unicode(bookname) book = self.manager.get_object_filtered(Book, Book.name == bookname) if book is None: # We need to create a new book, as the book does not exist. From 449610d50e2de222b3669dcb243b465fb1ff26a9 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 4 Jan 2011 23:06:43 +0100 Subject: [PATCH 07/56] - fixed author wihtou first_name e. g. "Luther" - open xml file properly - tweakes --- openlp/plugins/songs/lib/openlyricsimport.py | 15 ++++++--- openlp/plugins/songs/lib/xml.py | 33 ++++++++++---------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/openlp/plugins/songs/lib/openlyricsimport.py b/openlp/plugins/songs/lib/openlyricsimport.py index 5346b5803..27c2308f4 100644 --- a/openlp/plugins/songs/lib/openlyricsimport.py +++ b/openlp/plugins/songs/lib/openlyricsimport.py @@ -28,12 +28,17 @@ The :mod:`openlyricsimport` module provides the functionality for importing songs which are saved as OpenLyrics files. """ +import logging import os +from lxml import etree + from openlp.core.lib import translate from openlp.plugins.songs.lib.songimport import SongImport from openlp.plugins.songs.lib import OpenLyricsParser +log = logging.getLogger(__name__) + class OpenLyricsImport(SongImport): """ This provides the Openlyrics import. @@ -42,6 +47,7 @@ class OpenLyricsImport(SongImport): """ Initialise the import. """ + log.debug(u'initialise OpenLyricsImport') SongImport.__init__(self, master_manager) self.master_manager = master_manager self.openLyricsParser = OpenLyricsParser(master_manager) @@ -58,15 +64,14 @@ class OpenLyricsImport(SongImport): for file_path in self.import_source: if self.stop_import_flag: return False - file = open(file_path) - lines = file.readlines() - file.close() - lines = [line.strip() for line in lines] - xml = u''.join(lines) self.import_wizard.incrementProgressBar(unicode(translate( 'SongsPlugin.OpenLyricsImport', 'Importing %s...')) % os.path.basename(file_path)) + parser = etree.XMLParser(remove_blank_text=True) + file = etree.parse(file_path, parser) + xml = etree.tostring(file) if self.openLyricsParser.xml_to_song(xml) == 0: + log.debug(u'File could not be imported: %s' % file_path) # Importing this song failed! For now we stop import. return False return True diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index 326f97537..4045a412a 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -248,7 +248,8 @@ class OpenLyricsParser(object): This class represents the converter for Song to/from `OpenLyrics `_ XML. """ - # TODO: complete OpenLyrics standard implementation as fare as possible! + # TODO: Complete OpenLyrics standard implementation and document what is + # supported and what not! def __init__(self, manager): self.manager = manager @@ -316,8 +317,6 @@ class OpenLyricsParser(object): song = Song() if xml[:5] == u'').sub(u'', xml) song_xml = objectify.fromstring(xml) properties = song_xml.properties # Process Copyright @@ -349,17 +348,17 @@ class OpenLyricsParser(object): for verse in lyrics.verse: text = u'' for line in verse.lines: - for line in line.line: - line = unicode(line) - if not text: - text = line - else: - text += u'\n' + line - type = VerseType.expand_string(verse.attrib[u'name'][0]) - sxml.add_verse_to_lyrics(type, verse.attrib[u'name'][1], text) - # TODO: test this verse_order thing! + text = u'\n'.join([unicode(line) for line in line.line]) + # Remove chords + text = re.compile(u'').sub(u'', text) + # OpenLyrics allows e. g. "c", but we need "c1". + if self._get(verse, u'name').isalpha(): + verse.set(u'name', self._get(verse, u'name') + u'1') + type = VerseType.expand_string(self._get(verse, u'name')[0]) + sxml.add_verse_to_lyrics( + type, self._get(verse, u'name')[1], text) song.verse_order += u'%s%s ' % (type[0], - verse.attrib[u'name'][1]) + self._get(verse, u'name')[1]) search_text = search_text + text song.search_lyrics = search_text.lower() song.lyrics = unicode(sxml.extract_xml(), u'utf-8') @@ -399,7 +398,7 @@ class OpenLyricsParser(object): try: for songbook in properties.songbooks.songbook: self._process_songbook(self._get(songbook, u'name'), song) - if songbook.get(u'entry'): + if self._get(songbook, u'entry'): song.song_number = self._get(songbook, u'entry') # OpenLp does only support one song book, so take the first one. break @@ -427,7 +426,7 @@ class OpenLyricsParser(object): The element's attribute (unicode). """ if element.get(attribute) is not None: - return element.get(attribute) + return unicode(element.get(attribute)) return u'' def _text(self, element): @@ -483,8 +482,8 @@ class OpenLyricsParser(object): Author.display_name == name) if author is None: # We need to create a new author, as the author does not exist. - author = Author.populate(first_name=name.rsplit(u' ', 1)[0], - last_name=name.rsplit(u' ', 1)[1], display_name=name) + author = Author.populate(last_name=name.split(u' ')[-1], + first_name=u' '.join(name.split(u' ')[:-1]), display_name=name) self.manager.save_object(author) song.authors.append(author) From 4246c3b76ee8c3619bd201849a596a331a12550c Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 5 Jan 2011 17:31:04 +0100 Subject: [PATCH 08/56] - added documentation - commented not needed class out - split class 'OpenLyricsParser' - relocated and imporved some code in methods --- openlp/plugins/songs/lib/__init__.py | 3 +- openlp/plugins/songs/lib/mediaitem.py | 10 +- openlp/plugins/songs/lib/xml.py | 587 +++++++++++++++----------- 3 files changed, 341 insertions(+), 259 deletions(-) diff --git a/openlp/plugins/songs/lib/__init__.py b/openlp/plugins/songs/lib/__init__.py index 5093d6180..491c7e6c5 100644 --- a/openlp/plugins/songs/lib/__init__.py +++ b/openlp/plugins/songs/lib/__init__.py @@ -123,6 +123,7 @@ class VerseType(object): unicode(VerseType.to_string(VerseType.Other)).lower(): return VerseType.Other -from xml import LyricsXML, SongXMLBuilder, SongXMLParser, OpenLyricsParser +from xml import OpenLyricsBuilder, OpenLyricsParser, SongXMLBuilder, \ + SongXMLParser from songstab import SongsTab from mediaitem import SongMediaItem \ No newline at end of file diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 93d648146..d2776e1a4 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -35,7 +35,8 @@ from openlp.core.lib import MediaManagerItem, BaseListWithDnD, Receiver, \ ItemCapabilities, translate, check_item_selected from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \ SongImportForm -from openlp.plugins.songs.lib import SongXMLParser, OpenLyricsParser +from openlp.plugins.songs.lib import OpenLyricsBuilder, OpenLyricsParser, \ + SongXMLParser from openlp.plugins.songs.lib.db import Author, Song from openlp.core.lib.searchedit import SearchEdit @@ -58,7 +59,8 @@ class SongMediaItem(MediaManagerItem): self.ListViewWithDnD_class = SongListView MediaManagerItem.__init__(self, parent, self, icon) self.edit_song_form = EditSongForm(self, self.parent.manager) - self.openLyrics = OpenLyricsParser(self.parent.manager) + self.openLyricsParser = OpenLyricsParser(self.parent.manager) + self.openLyricsBuilder = OpenLyricsBuilder(self.parent.manager) self.singleServiceItem = False self.song_maintenance_form = SongMaintenanceForm( self.parent.manager, self) @@ -397,7 +399,7 @@ class SongMediaItem(MediaManagerItem): ] service_item.data_string = {u'title': song.search_title, u'authors': author_list} - service_item.xml_version = self.openLyrics.song_to_xml(song) + service_item.xml_version = self.openLyricsBuilder.song_to_xml(song) return True def serviceLoad(self, item): @@ -439,7 +441,7 @@ class SongMediaItem(MediaManagerItem): break if add_song: if self.addSongFromService: - editId = self.openLyrics.xml_to_song(item.xml_version) + editId = self.openLyricsParser.xml_to_song(item.xml_version) # Update service with correct song id. if editId != 0: Receiver.send_message(u'service_item_update', diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index 4045a412a..4d23ebd78 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -24,9 +24,9 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### """ -The :mod:`xml` module provides the XML functionality for songs +The :mod:`xml` module provides the XML functionality. -The basic XML is of the format:: +The basic XML for storing the lyrics in the song database is of the format:: @@ -36,6 +36,28 @@ The basic XML is of the format:: + + +The XML of `OpenLyrics `_ songs is of the format:: + + + + + Amazing Grace + + + + + + Amazing grace how sweet the sound + + + + """ import logging @@ -144,112 +166,109 @@ class SongXMLParser(object): return etree.dump(self.song_xml) -class LyricsXML(object): +#class LyricsXML(object): +# """ +# This class represents the XML in the ``lyrics`` field of a song. +# """ +# def __init__(self, song=None): +# if song: +# if song.lyrics.startswith(u'' % \ +# (verse[u'type'], verse[u'label'], verse[u'text']) +# lyrics_output = lyrics_output + \ +# u'%s' % \ +# (language[u'language'], verse_output) +# song_output = u'' + \ +# u'%s' % lyrics_output +# return song_output + + +class OpenLyricsBuilder(object): """ - This class represents the XML in the ``lyrics`` field of a song. + This class represents the converter for song to OpenLyrics XML. """ - def __init__(self, song=None): - if song: - if song.lyrics.startswith(u'' % \ - (verse[u'type'], verse[u'label'], verse[u'text']) - lyrics_output = lyrics_output + \ - u'%s' % \ - (language[u'language'], verse_output) - song_output = u'' + \ - u'%s' % lyrics_output - return song_output - - -class OpenLyricsParser(object): - """ - This class represents the converter for Song to/from - `OpenLyrics `_ XML. - """ - # TODO: Complete OpenLyrics standard implementation and document what is - # supported and what not! def __init__(self, manager): self.manager = manager @@ -304,6 +323,98 @@ class OpenLyricsParser(object): self._add_text_to_element(u'line', element, line) return self._extract_xml(song_xml) + def _add_text_to_element(self, tag, parent, text=None, label=None): + if label: + element = etree.Element(tag, name=unicode(label)) + else: + element = etree.Element(tag) + if text: + element.text = unicode(text) + parent.append(element) + return element + + def _extract_xml(self, xml): + """ + Extract our newly created XML song. + """ + return etree.tostring(xml, encoding=u'UTF-8', + xml_declaration=True) + + def _dump_xml(self, xml): + """ + Debugging aid to dump XML so that we can see what we have. + """ + return etree.tostring(xml, encoding=u'UTF-8', + xml_declaration=True, pretty_print=True) + + +class OpenLyricsParser(object): + """ + This class represents the converter for OpenLyrics XML to a song. + + As OpenLyrics has a rich set of different features, we cannot support them + all. The following features are supported by the :class:`OpenLyricsParser`:: + + ```` + OpenLP does not support the author ``type`` and consequently not + ``lang`` for the author of the type ``translation``. + + ```` + This property is not supported. + + ```` + The ```` property is fully supported. But comments in lyrics + are not supported. + + ```` + This property is fully supported. + + ```` + This property is not supported. + + ```` + This property is not supported. + + ```` + This property is not supported. + + ```` + The attribute ``part`` is not supported. + + ```` + This property is not supported. + + ```` + As OpenLP does only support one songbook, we cannot consider more than + one songbook. + + ```` + This property is not supported. + + ```` + Topics, as they are called in OpenLP, are fully supported, whereby only + the topic text (e. g. Grace) is considered, but neither the ``id`` nor + ``lang``. + + ```` + This property is not supported. + + ```` + This property is not supported. + + ```` + The attribute ``translit`` and ``lang`` are not supported. + This class support verse names of the format ```` and + ````. Whereas this class does not support verse names of + the format ```` as OpenLP does not support splitting + verses into different parts. + + ```` + OpenLP supports this property. + """ + def __init__(self, manager): + self.manager = manager + def xml_to_song(self, xml): """ Create and save a song from OpenLyrics format xml to the database. Since @@ -317,6 +428,8 @@ class OpenLyricsParser(object): song = Song() if xml[:5] == u'').sub(u'', xml) song_xml = objectify.fromstring(xml) properties = song_xml.properties # Process Copyright @@ -329,41 +442,11 @@ class OpenLyricsParser(object): song.ccli_number = self._text(properties.ccliNo) except AttributeError: song.ccli_number = u'' - # Process Titles - for title in properties.titles.title: - if not song.title: - song.title = self._text(title) - song.search_title = unicode(song.title) - song.alternate_title = u'' - else: - song.alternate_title = self._text(title) - song.search_title += u'@' + song.alternate_title - song.search_title = re.sub(r'[\'"`,;:(){}?]+', u'', - unicode(song.search_title)).lower() - # Process Lyrics - sxml = SongXMLBuilder() - search_text = u'' + self._process_titles(properties, song) song.verse_order = u'' - for lyrics in song_xml.lyrics: - for verse in lyrics.verse: - text = u'' - for line in verse.lines: - text = u'\n'.join([unicode(line) for line in line.line]) - # Remove chords - text = re.compile(u'').sub(u'', text) - # OpenLyrics allows e. g. "c", but we need "c1". - if self._get(verse, u'name').isalpha(): - verse.set(u'name', self._get(verse, u'name') + u'1') - type = VerseType.expand_string(self._get(verse, u'name')[0]) - sxml.add_verse_to_lyrics( - type, self._get(verse, u'name')[1], text) - song.verse_order += u'%s%s ' % (type[0], - self._get(verse, u'name')[1]) - search_text = search_text + text - song.search_lyrics = search_text.lower() - song.lyrics = unicode(sxml.extract_xml(), u'utf-8') - song.verse_order = song.verse_order.strip() + self._process_lyrics(song_xml, song) # Process verse order + song.verse_order = song.verse_order.strip() try: song.verse_order = self._text(properties.verseOrder) except AttributeError: @@ -372,46 +455,10 @@ class OpenLyricsParser(object): pass if song.verse_order == u'None': song.verse_order = u'' - # Process Comments - song.comments = u'' - try: - for comment in properties.comments.comment: - if not song.comments: - song.comments = self._text(comment) - else: - song.comments += u'\n' + self._text(comment) - except AttributeError: - pass - # Process Authors - try: - for author in properties.authors.author: - self._process_author(self._text(author), song) - except AttributeError: - pass - if not song.authors: - # Add "Author unknown" (can be translated) - self._process_author(unicode(translate('SongsPlugin.XML', - 'Author unknown')), song) - # Process Song Book and Song Number - song.song_book_id = 0 - song.song_number = u'' - try: - for songbook in properties.songbooks.songbook: - self._process_songbook(self._get(songbook, u'name'), song) - if self._get(songbook, u'entry'): - song.song_number = self._get(songbook, u'entry') - # OpenLp does only support one song book, so take the first one. - break - except AttributeError: - pass - # Process Topcis - try: - for topic in properties.themes.theme: - self._process_topic(self._text(topic), song) - except AttributeError: - pass - # Properties not yet supported. - song.theme_name = u'' + self._process_comments(properties, song) + self._process_authors(properties, song) + self._process_songbooks(properties, song) + self._process_topics(properties, song) self.manager.save_object(song) return song.id @@ -440,91 +487,123 @@ class OpenLyricsParser(object): return unicode(element.text) return u'' - def _add_text_to_element(self, tag, parent, text=None, label=None): - if label: - element = etree.Element(tag, name=unicode(label)) - else: - element = etree.Element(tag) - if text: - element.text = unicode(text) - parent.append(element) - return element - - def _dump_xml(self, xml): - """ - Debugging aid to dump XML so that we can see what we have. - """ - return etree.tostring(xml, encoding=u'UTF-8', - xml_declaration=True, pretty_print=True) - - def _extract_xml(self, xml): - """ - Extract our newly created XML song. - """ - return etree.tostring(xml, encoding=u'UTF-8', - xml_declaration=True) - - def _process_author(self, name, song): + def _process_authors(self, properties, song): """ Finds an existing Author or creates a new Author and adds it to the song object. - - ``name`` - The display_name of the song (unicode). - - ``song`` - The song the object. """ - if not name: - # Wrong use of XML here, as no text has been supplied. - return - author = self.manager.get_object_filtered(Author, - Author.display_name == name) - if author is None: - # We need to create a new author, as the author does not exist. - author = Author.populate(last_name=name.split(u' ')[-1], - first_name=u' '.join(name.split(u' ')[:-1]), display_name=name) + authors = [] + try: + for author in properties.authors.author: + display_name = self._text(author) + if display_name: + authors.append(display_name) + except AttributeError: + pass + if not authors: + # Add "Author unknown" (can be translated). + authors.append((unicode(translate('SongsPlugin.XML', + 'Author unknown')))) + for display_name in authors: + author = self.manager.get_object_filtered(Author, + Author.display_name == display_name) + if author is None: + # We need to create a new author, as the author does not exist. + author = Author.populate(display_name=display_name, + last_name=display_name.split(u' ')[-1], + first_name=u' '.join(display_name.split(u' ')[:-1])) self.manager.save_object(author) - song.authors.append(author) + song.authors.append(author) - def _process_topic(self, topictext, song): + def _process_comments(self, properties, song): """ - Finds an existing topic or creates a new topic and adds it to the song - object. - - ``topictext`` - The topictext of the topic (unicode). - - ``song`` - The song object. """ - if not topictext: - # Wrong use of XML here, as no text has been supplied. - return - topic = self.manager.get_object_filtered(Topic, Topic.name == topictext) - if topic is None: - # We need to create a new topic, as the topic does not exist. - topic = Topic.populate(name=topictext) - self.manager.save_object(topic) - song.topics.append(topic) + try: + song.comments = u'\n'.join( + [self._text(comment) for comment in properties.comments.comment] + ) + except AttributeError: + song.comments = u'' - def _process_songbook(self, bookname, song): + def _process_lyrics(self, song_xml, song): + """ + """ + sxml = SongXMLBuilder() + search_text = u'' + for verse in song_xml.lyrics.verse: + text = u'' + for lines in verse.lines: + if text: + text += u'\n' + text += u'\n'.join([unicode(line) for line in lines.line]) + # OpenLyrics allows e. g. "c", but we need "c1". + if self._get(verse, u'name').isalpha(): + verse.set(u'name', self._get(verse, u'name') + u'1') + type = VerseType.expand_string(self._get(verse, u'name')[0]) + sxml.add_verse_to_lyrics(type, self._get(verse, u'name')[1], text) + song.verse_order += u'%s%s ' % (type[0], + self._get(verse, u'name')[1]) + search_text = search_text + text + song.search_lyrics = search_text.lower() + song.lyrics = unicode(sxml.extract_xml(), u'utf-8') + #TODO: make sure "c" becomes "c1" + + def _process_songbooks(self, properties, song): """ Finds an existing book or creates a new book and adds it to the song object. - - ``bookname`` - The name of the book (unicode). - - ``song`` - The song object. """ - if not bookname: - # Wrong use of XML here, as no text has been supplied. - return - book = self.manager.get_object_filtered(Book, Book.name == bookname) - if book is None: - # We need to create a new book, as the book does not exist. - book = Book.populate(name=bookname, publisher=u'') - self.manager.save_object(book) - song.song_book_id = book.id + song.song_book_id = 0 + song.song_number = u'' + try: + for songbook in properties.songbooks.songbook: + bookname = self._get(songbook, u'name') + if bookname: + book = self.manager.get_object_filtered(Book, + Book.name == bookname) + if book is None: + # We need to create a book, because it does not exist. + book = Book.populate(name=bookname, publisher=u'') + self.manager.save_object(book) + song.song_book_id = book.id + if self._get(songbook, u'entry'): + song.song_number = self._get(songbook, u'entry') + # We does only support one song book, so take the first one. + break + except AttributeError: + pass + + def _process_titles(self, properties, song): + """ + """ + for title in properties.titles.title: + if not song.title: + song.title = self._text(title) + song.search_title = unicode(song.title) + song.alternate_title = u'' + else: + song.alternate_title = self._text(title) + song.search_title += u'@' + song.alternate_title + song.search_title = re.sub(r'[\'"`,;:(){}?]+', u'', + unicode(song.search_title)).lower() + + def _process_topics(self, properties, song): + """ + Finds an existing topic or creates a new topic and adds it to the song + object. + """ + try: + for topictext in properties.themes.theme: + topictext = self._text(topictext) + if not topictext: + # Wrong use of XML here, as no text has been supplied. + return + topic = self.manager.get_object_filtered(Topic, + Topic.name == topictext) + if topic is None: + # We need to create a new topic, as the topic does not exist. + topic = Topic.populate(name=topictext) + self.manager.save_object(topic) + song.topics.append(topic) + except AttributeError: + pass From 09e2fb7691c79c48ef431882f06f448b34283985 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 5 Jan 2011 17:45:29 +0100 Subject: [PATCH 09/56] clean up --- openlp/plugins/songs/lib/xml.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index 4d23ebd78..957c377ec 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -420,7 +420,6 @@ class OpenLyricsParser(object): Create and save a song from OpenLyrics format xml to the database. Since we also export XML from external sources (e. g. OpenLyrics import), we cannot ensure, that it completely conforms to the OpenLyrics standard. - That means, that we for example have to remove chords. """ # No xml get out of here. if not xml: @@ -453,8 +452,6 @@ class OpenLyricsParser(object): # Do not worry, as the verse order has cautionary already been # saved while creating the verses. pass - if song.verse_order == u'None': - song.verse_order = u'' self._process_comments(properties, song) self._process_authors(properties, song) self._process_songbooks(properties, song) From b4dfeca4d7be4984bc128a14541355e0302dd3d0 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 5 Jan 2011 20:34:56 +0100 Subject: [PATCH 10/56] --- openlp/plugins/songs/lib/xml.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index 957c377ec..8a9cc6930 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -545,6 +545,11 @@ class OpenLyricsParser(object): song.lyrics = unicode(sxml.extract_xml(), u'utf-8') #TODO: make sure "c" becomes "c1" +# name = self._get(verse, u'name') +# type = name[0] +# number = re.compile(u'[a-zA-Z]*').sub(u'', name) +# part = re.compile(u'[0-9]*').sub(u'', name[1:]) + def _process_songbooks(self, properties, song): """ Finds an existing book or creates a new book and adds it to the song From fc2142849932f289c0e4429254144188af8b8644 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Thu, 6 Jan 2011 10:34:26 +0100 Subject: [PATCH 11/56] fixed docs --- openlp/plugins/songs/lib/xml.py | 45 ++++++++++++++++----------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index 14d2f426f..4a676b1ad 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -355,57 +355,56 @@ class OpenLyricsParser(object): As OpenLyrics has a rich set of different features, we cannot support them all. The following features are supported by the :class:`OpenLyricsParser`:: - ```` - OpenLP does not support the author ``type`` and consequently not - ``lang`` for the author of the type ``translation``. + ** + OpenLP does not support the attribute *type* and *lang*. - ```` + ** This property is not supported. - ```` - The ```` property is fully supported. But comments in lyrics + ** + The ** property is fully supported. But comments in lyrics are not supported. - ```` + ** This property is fully supported. - ```` + ** This property is not supported. - ```` + ** This property is not supported. - ```` + ** This property is not supported. - ```` - The attribute ``part`` is not supported. + ** + The attribute *part* is not supported. - ```` + ** This property is not supported. - ```` + ** As OpenLP does only support one songbook, we cannot consider more than one songbook. - ```` + ** This property is not supported. - ```` + ** Topics, as they are called in OpenLP, are fully supported, whereby only - the topic text (e. g. Grace) is considered, but neither the ``id`` nor - ``lang``. + the topic text (e. g. Grace) is considered, but neither the *id* nor + *lang*. - ```` + ** This property is not supported. - ```` + ** This property is not supported. - ```` - The attribute ``translit`` and ``lang`` are not supported. + ** + The attribute *translit* and *lang* are not supported. - ```` + ** OpenLP supports this property. """ def __init__(self, manager): From 68c550cd711dab7160702645999fdfd9853bcbcd Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Thu, 6 Jan 2011 14:01:30 +0100 Subject: [PATCH 12/56] -basic work for OpenLyrics exporter (songexport wizard is missing) --- openlp/plugins/songs/lib/openlyricsexport.py | 72 ++++++++++++++++++++ openlp/plugins/songs/lib/xml.py | 8 +-- 2 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 openlp/plugins/songs/lib/openlyricsexport.py diff --git a/openlp/plugins/songs/lib/openlyricsexport.py b/openlp/plugins/songs/lib/openlyricsexport.py new file mode 100644 index 000000000..95c96517d --- /dev/null +++ b/openlp/plugins/songs/lib/openlyricsexport.py @@ -0,0 +1,72 @@ +## -*- coding: utf-8 -*- +## vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 +# +################################################################################ +## OpenLP - Open Source Lyrics Projection # +## --------------------------------------------------------------------------- # +## Copyright (c) 2008-2011 Raoul Snyman # +## Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael # +## Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian # +## Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, # +## Carsten Tinggaard, Frode Woldsund # +## --------------------------------------------------------------------------- # +## This program is free software; you can redistribute it and/or modify it # +## under the terms of the GNU General Public License as published by the Free # +## Software Foundation; version 2 of the License. # +## # +## This program is distributed in the hope that it will be useful, but WITHOUT # +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +## more details. # +## # +## You should have received a copy of the GNU General Public License along # +## with this program; if not, write to the Free Software Foundation, Inc., 59 # +## Temple Place, Suite 330, Boston, MA 02111-1307 USA # +################################################################################ +#""" +#The :mod:`openlyricsexport` module provides the functionality for exporting +#songs from the database. +#""" +# +#import logging +#import os +# +#from lxml import etree +# +#from openlp.core.lib import translate +#from openlp.plugins.songs.lib import OpenLyricsBuilder +#from openlp.plugins.songs.lib.songimport import SongImport +# +#log = logging.getLogger(__name__) +# +#class OpenLyricsExport(SongExport): +# """ +# This provides the Openlyrics export. +# """ +# def __init__(self, master_manager, songs=None, save_path=u''): +# """ +# Initialise the export. +# """ +# log.debug(u'initialise OpenLyricsExport') +# SongExport.__init__(self, master_manager) +# self.master_manager = master_manager +# self.songs = songs +# self.save_path = save_path +# +# def do_export(self): +# """ +# Exports the songs. +# """ +# openLyricsBuilder = OpenLyricsBuilder(self.master_manager) +# self.export_wizard.exportProgressBar.setMaximum(len(songs)) +# for song in self.songs: +# if self.stop_export_flag: +# return False +# self.import_wizard.incrementProgressBar(unicode(translate( +# 'SongsPlugin.OpenLyricsExport', 'Importing %s...')) % +# song.title) +# xml = openLyricsBuilder.song_to_xml(song, True) +# tree = etree.ElementTree(etree.fromstring(xml)) +# path = os.path.join(self.save_path, song.title) +# tree.write(path) +# return True diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index 4a676b1ad..a5c8ecd06 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -272,7 +272,7 @@ class OpenLyricsBuilder(object): def __init__(self, manager): self.manager = manager - def song_to_xml(self, song): + def song_to_xml(self, song, pretty_print=False): """ Convert the song to OpenLyrics Format. """ @@ -321,7 +321,7 @@ class OpenLyricsBuilder(object): element = self._add_text_to_element(u'lines', element) for line in unicode(verse[1]).split(u'\n'): self._add_text_to_element(u'line', element, line) - return self._extract_xml(song_xml) + return self._extract_xml(song_xml, pretty_print) def _add_text_to_element(self, tag, parent, text=None, label=None): if label: @@ -333,12 +333,12 @@ class OpenLyricsBuilder(object): parent.append(element) return element - def _extract_xml(self, xml): + def _extract_xml(self, xml, pretty_print): """ Extract our newly created XML song. """ return etree.tostring(xml, encoding=u'UTF-8', - xml_declaration=True) + xml_declaration=True, pretty_print=pretty_print) def _dump_xml(self, xml): """ From a51ad14322efafc6966eb7a9ff680685a11178d8 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sat, 8 Jan 2011 21:35:31 +0100 Subject: [PATCH 13/56] removed OpenLyrics export for now --- openlp/plugins/songs/lib/openlyricsexport.py | 72 -------------------- 1 file changed, 72 deletions(-) delete mode 100644 openlp/plugins/songs/lib/openlyricsexport.py diff --git a/openlp/plugins/songs/lib/openlyricsexport.py b/openlp/plugins/songs/lib/openlyricsexport.py deleted file mode 100644 index 95c96517d..000000000 --- a/openlp/plugins/songs/lib/openlyricsexport.py +++ /dev/null @@ -1,72 +0,0 @@ -## -*- coding: utf-8 -*- -## vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 -# -################################################################################ -## OpenLP - Open Source Lyrics Projection # -## --------------------------------------------------------------------------- # -## Copyright (c) 2008-2011 Raoul Snyman # -## Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael # -## Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian # -## Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, # -## Carsten Tinggaard, Frode Woldsund # -## --------------------------------------------------------------------------- # -## This program is free software; you can redistribute it and/or modify it # -## under the terms of the GNU General Public License as published by the Free # -## Software Foundation; version 2 of the License. # -## # -## This program is distributed in the hope that it will be useful, but WITHOUT # -## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # -## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # -## more details. # -## # -## You should have received a copy of the GNU General Public License along # -## with this program; if not, write to the Free Software Foundation, Inc., 59 # -## Temple Place, Suite 330, Boston, MA 02111-1307 USA # -################################################################################ -#""" -#The :mod:`openlyricsexport` module provides the functionality for exporting -#songs from the database. -#""" -# -#import logging -#import os -# -#from lxml import etree -# -#from openlp.core.lib import translate -#from openlp.plugins.songs.lib import OpenLyricsBuilder -#from openlp.plugins.songs.lib.songimport import SongImport -# -#log = logging.getLogger(__name__) -# -#class OpenLyricsExport(SongExport): -# """ -# This provides the Openlyrics export. -# """ -# def __init__(self, master_manager, songs=None, save_path=u''): -# """ -# Initialise the export. -# """ -# log.debug(u'initialise OpenLyricsExport') -# SongExport.__init__(self, master_manager) -# self.master_manager = master_manager -# self.songs = songs -# self.save_path = save_path -# -# def do_export(self): -# """ -# Exports the songs. -# """ -# openLyricsBuilder = OpenLyricsBuilder(self.master_manager) -# self.export_wizard.exportProgressBar.setMaximum(len(songs)) -# for song in self.songs: -# if self.stop_export_flag: -# return False -# self.import_wizard.incrementProgressBar(unicode(translate( -# 'SongsPlugin.OpenLyricsExport', 'Importing %s...')) % -# song.title) -# xml = openLyricsBuilder.song_to_xml(song, True) -# tree = etree.ElementTree(etree.fromstring(xml)) -# path = os.path.join(self.save_path, song.title) -# tree.write(path) -# return True From f2784fc4dd6874cba00112669018a4d3781c53fb Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sat, 8 Jan 2011 21:59:46 +0100 Subject: [PATCH 14/56] removed whitespaces --- openlp/core/ui/__init__.py | 4 ++-- openlp/plugins/bibles/forms/bibleimportwizard.py | 2 +- openlp/plugins/songs/forms/authorsdialog.py | 2 +- openlp/plugins/songs/forms/songimportwizard.py | 2 +- openlp/plugins/songs/lib/xml.py | 16 ++++++++-------- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/openlp/core/ui/__init__.py b/openlp/core/ui/__init__.py index 26c59ed0f..ca2123c87 100644 --- a/openlp/core/ui/__init__.py +++ b/openlp/core/ui/__init__.py @@ -35,11 +35,11 @@ class HideMode(object): ``Blank`` This mode is used to hide all output, specifically by covering the display with a black screen. - + ``Theme`` This mode is used to hide all output, but covers the display with the current theme background, as opposed to black. - + ``Desktop`` This mode hides all output by minimising the display, leaving the user's desktop showing. diff --git a/openlp/plugins/bibles/forms/bibleimportwizard.py b/openlp/plugins/bibles/forms/bibleimportwizard.py index a85e430a1..3200bf974 100644 --- a/openlp/plugins/bibles/forms/bibleimportwizard.py +++ b/openlp/plugins/bibles/forms/bibleimportwizard.py @@ -234,7 +234,7 @@ class Ui_BibleImportWizard(object): QtGui.QSizePolicy.Minimum) self.openlp1Layout.setItem(1, QtGui.QFormLayout.LabelRole, self.openlp1Spacer) - self.selectStack.addWidget(self.openlp1Widget) + self.selectStack.addWidget(self.openlp1Widget) self.selectPageLayout.addLayout(self.selectStack) bibleImportWizard.addPage(self.selectPage) # License Page diff --git a/openlp/plugins/songs/forms/authorsdialog.py b/openlp/plugins/songs/forms/authorsdialog.py index 28083ae05..6f1c7f2a4 100644 --- a/openlp/plugins/songs/forms/authorsdialog.py +++ b/openlp/plugins/songs/forms/authorsdialog.py @@ -54,7 +54,7 @@ class Ui_AuthorsDialog(object): self.displayEdit.setObjectName(u'displayEdit') self.displayLabel.setBuddy(self.displayEdit) self.authorLayout.addRow(self.displayLabel, self.displayEdit) - self.dialogLayout.addLayout(self.authorLayout) + self.dialogLayout.addLayout(self.authorLayout) self.buttonBox = QtGui.QDialogButtonBox(authorsDialog) self.buttonBox.setStandardButtons( QtGui.QDialogButtonBox.Save | QtGui.QDialogButtonBox.Cancel) diff --git a/openlp/plugins/songs/forms/songimportwizard.py b/openlp/plugins/songs/forms/songimportwizard.py index 6eccff9b4..903300d0c 100644 --- a/openlp/plugins/songs/forms/songimportwizard.py +++ b/openlp/plugins/songs/forms/songimportwizard.py @@ -39,7 +39,7 @@ class Ui_SongImportWizard(object): QtGui.QWizard.IndependentPages | QtGui.QWizard.NoBackButtonOnStartPage | QtGui.QWizard.NoBackButtonOnLastPage) - # Welcome Page + # Welcome Page self.welcomePage = QtGui.QWizardPage() self.welcomePage.setPixmap(QtGui.QWizard.WatermarkPixmap, QtGui.QPixmap(u':/wizards/wizard_importsong.bmp')) diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index a5c8ecd06..10d93b100 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -359,10 +359,10 @@ class OpenLyricsParser(object): OpenLP does not support the attribute *type* and *lang*. ** - This property is not supported. + This property is not supported. ** - The ** property is fully supported. But comments in lyrics + The ** property is fully supported. But comments in lyrics are not supported. ** @@ -372,23 +372,23 @@ class OpenLyricsParser(object): This property is not supported. ** - This property is not supported. + This property is not supported. ** - This property is not supported. + This property is not supported. ** The attribute *part* is not supported. ** - This property is not supported. + This property is not supported. ** As OpenLP does only support one songbook, we cannot consider more than one songbook. ** - This property is not supported. + This property is not supported. ** Topics, as they are called in OpenLP, are fully supported, whereby only @@ -399,9 +399,9 @@ class OpenLyricsParser(object): This property is not supported. ** - This property is not supported. + This property is not supported. - ** + ** The attribute *translit* and *lang* are not supported. ** From 6e8a371da7ea2531bb7901827e9ef504377b1c0f Mon Sep 17 00:00:00 2001 From: M2j Date: Sun, 9 Jan 2011 01:27:46 +0100 Subject: [PATCH 15/56] wrong parentship caused theme and servicemanager to disapear in a floating dock more intelligent resizing of item list in PluginForm and SongMaintenanceForm Fix in BS web bible parser --- openlp/core/ui/mainwindow.py | 6 +- openlp/core/ui/pluginform.py | 8 +- openlp/core/ui/servicemanager.py | 80 +++++++++---------- openlp/core/ui/themeform.py | 4 +- openlp/core/ui/thememanager.py | 12 +-- openlp/core/ui/themewizard.py | 30 ++++--- openlp/plugins/alerts/alertsplugin.py | 2 +- .../plugins/bibles/forms/bibleimportwizard.py | 32 ++++---- openlp/plugins/bibles/lib/http.py | 2 +- .../songs/forms/songmaintenancedialog.py | 19 +++-- 10 files changed, 101 insertions(+), 94 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 70b87966c..f2545766e 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -142,7 +142,8 @@ class Ui_MainWindow(object): build_icon(u':/system/system_servicemanager.png')) self.ServiceManagerDock.setMinimumWidth( self.settingsmanager.mainwindow_right) - self.ServiceManagerContents = ServiceManager(MainWindow) + self.ServiceManagerContents = ServiceManager(MainWindow, + self.ServiceManagerDock) self.ServiceManagerDock.setWidget(self.ServiceManagerContents) MainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.ServiceManagerDock) @@ -152,7 +153,8 @@ class Ui_MainWindow(object): build_icon(u':/system/system_thememanager.png')) self.ThemeManagerDock.setMinimumWidth( self.settingsmanager.mainwindow_right) - self.ThemeManagerContents = ThemeManager(MainWindow) + self.ThemeManagerContents = ThemeManager(MainWindow, + self.ThemeManagerDock) self.ThemeManagerContents.setObjectName(u'ThemeManagerContents') self.ThemeManagerDock.setWidget(self.ThemeManagerContents) MainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea, diff --git a/openlp/core/ui/pluginform.py b/openlp/core/ui/pluginform.py index 26e6cf06c..112cd04dd 100644 --- a/openlp/core/ui/pluginform.py +++ b/openlp/core/ui/pluginform.py @@ -61,6 +61,7 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog): self.programaticChange = True self._clearDetails() self.programaticChange = True + pluginListWidth = 0 for plugin in self.parent.pluginManager.plugins: item = QtGui.QListWidgetItem(self.pluginListWidget) # We do this just to make 100% sure the status is an integer as @@ -83,8 +84,11 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog): if plugin.icon: item.setIcon(plugin.icon) self.pluginListWidget.addItem(item) - self.pluginListWidget.setFixedWidth( - self.pluginListWidget.sizeHint().width()) + pluginListWidth = max(pluginListWidth, self.fontMetrics().width( + unicode(translate('OpenLP.PluginForm', '%s (Inactive)')) % + name_string[u'singular'])) + self.pluginListWidget.setFixedWidth(pluginListWidth + + self.pluginListWidget.iconSize().width() + 48) def _clearDetails(self): self.statusComboBox.setCurrentIndex(-1) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index e1aa126ae..3e272da47 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -43,33 +43,33 @@ class ServiceManagerList(QtGui.QTreeWidget): """ Set up key bindings and mouse behaviour for the service list """ - def __init__(self, parent=None, name=None): + def __init__(self, mainwindow, parent=None, name=None): QtGui.QTreeWidget.__init__(self, parent) - self.parent = parent + self.mainwindow = mainwindow def keyPressEvent(self, event): if isinstance(event, QtGui.QKeyEvent): #here accept the event and do something if event.key() == QtCore.Qt.Key_Enter: - self.parent.makeLive() + self.mainwindow.makeLive() event.accept() elif event.key() == QtCore.Qt.Key_Home: - self.parent.onServiceTop() + self.mainwindow.onServiceTop() event.accept() elif event.key() == QtCore.Qt.Key_End: - self.parent.onServiceEnd() + self.mainwindow.onServiceEnd() event.accept() elif event.key() == QtCore.Qt.Key_PageUp: - self.parent.onServiceUp() + self.mainwindow.onServiceUp() event.accept() elif event.key() == QtCore.Qt.Key_PageDown: - self.parent.onServiceDown() + self.mainwindow.onServiceDown() event.accept() elif event.key() == QtCore.Qt.Key_Up: - self.parent.onMoveSelectionUp() + self.mainwindow.onMoveSelectionUp() event.accept() elif event.key() == QtCore.Qt.Key_Down: - self.parent.onMoveSelectionDown() + self.mainwindow.onMoveSelectionDown() event.accept() event.ignore() else: @@ -98,12 +98,12 @@ class ServiceManager(QtGui.QWidget): the resources used into one OSZ file for use on any OpenLP v2 installation. Also handles the UI tasks of moving things up and down etc. """ - def __init__(self, parent): + def __init__(self, mainwindow, parent=None): """ Sets up the service manager, toolbars, list view, et al. """ QtGui.QWidget.__init__(self, parent) - self.parent = parent + self.mainwindow = mainwindow self.serviceItems = [] self.serviceName = u'' self.suffixes = [] @@ -112,8 +112,8 @@ class ServiceManager(QtGui.QWidget): # is a new service and has not been saved self._modified = False self._fileName = u'' - self.serviceNoteForm = ServiceNoteForm(self.parent) - self.serviceItemEditForm = ServiceItemEditForm(self.parent) + self.serviceNoteForm = ServiceNoteForm(self.mainwindow) + self.serviceItemEditForm = ServiceItemEditForm(self.mainwindow) # start with the layout self.layout = QtGui.QVBoxLayout(self) self.layout.setSpacing(0) @@ -247,7 +247,7 @@ class ServiceManager(QtGui.QWidget): QtCore.SIGNAL(u'service_item_update'), self.serviceItemUpdate) # Last little bits of setting up self.service_theme = unicode(QtCore.QSettings().value( - self.parent.serviceSettingsSection + u'/service theme', + self.mainwindow.serviceSettingsSection + u'/service theme', QtCore.QVariant(u'')).toString()) self.servicePath = AppLocation.get_section_data_path(u'servicemanager') #build the drag and drop context menu @@ -294,7 +294,7 @@ class ServiceManager(QtGui.QWidget): """ self._modified = modified serviceFile = self.shortFileName() or u'Untitled Service' - self.parent.setServiceModified(modified, serviceFile) + self.mainwindow.setServiceModified(modified, serviceFile) def isModified(self): """ @@ -307,7 +307,7 @@ class ServiceManager(QtGui.QWidget): Setter for service file. """ self._fileName = unicode(fileName) - self.parent.setServiceModified(self.isModified, self.shortFileName()) + self.mainwindow.setServiceModified(self.isModified, self.shortFileName()) QtCore.QSettings(). \ setValue(u'service/last file',QtCore.QVariant(fileName)) @@ -341,7 +341,7 @@ class ServiceManager(QtGui.QWidget): Create a new service. """ if self.isModified(): - result = QtGui.QMessageBox.question(self.parent, + result = QtGui.QMessageBox.question(self.mainwindow, translate('OpenLP.ServiceManager', 'Save Changes'), translate('OpenLP.ServiceManager', 'The current service has ' 'been modified, would you like to save it?'), @@ -356,7 +356,7 @@ class ServiceManager(QtGui.QWidget): def onLoadServiceClicked(self): if self.isModified(): - result = QtGui.QMessageBox.question(self.parent, + result = QtGui.QMessageBox.question(self.mainwindow, translate('OpenLP.ServiceManager', 'Save Changes'), translate('OpenLP.ServiceManager', 'The current service has ' 'been modified, would you like to save it?'), @@ -366,14 +366,14 @@ class ServiceManager(QtGui.QWidget): return False elif result == QtGui.QMessageBox.Save: self.saveFile() - fileName = unicode(QtGui.QFileDialog.getOpenFileName(self.parent, + fileName = unicode(QtGui.QFileDialog.getOpenFileName(self.mainwindow, translate('OpenLP.ServiceManager', 'Open File'), - SettingsManager.get_last_dir(self.parent.serviceSettingsSection), + SettingsManager.get_last_dir(self.mainwindow.serviceSettingsSection), translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)'))) if not fileName: return False - SettingsManager.set_last_dir(self.parent.serviceSettingsSection, + SettingsManager.set_last_dir(self.mainwindow.serviceSettingsSection, split_filename(fileName)[0]) self.loadFile(fileName) @@ -407,7 +407,7 @@ class ServiceManager(QtGui.QWidget): else: fileName = self.fileName() log.debug(u'ServiceManager.saveFile - %s' % fileName) - SettingsManager.set_last_dir(self.parent.serviceSettingsSection, + SettingsManager.set_last_dir(self.mainwindow.serviceSettingsSection, split_filename(fileName)[0]) service = [] serviceFileName = fileName.replace(u'.osz', u'.osd') @@ -447,7 +447,7 @@ class ServiceManager(QtGui.QWidget): except (IOError, OSError): # if not present do not worry pass - self.parent.addRecentFile(fileName) + self.mainwindow.addRecentFile(fileName) self.setModified(False) return True @@ -456,9 +456,9 @@ class ServiceManager(QtGui.QWidget): Get a file name and then call :function:`ServiceManager.saveFile` to save the file. """ - fileName = unicode(QtGui.QFileDialog.getSaveFileName(self.parent, + fileName = unicode(QtGui.QFileDialog.getSaveFileName(self.mainwindow, translate('OpenLP.ServiceManager', 'Save Service'), - SettingsManager.get_last_dir(self.parent.serviceSettingsSection), + SettingsManager.get_last_dir(self.mainwindow.serviceSettingsSection), translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)'))) if not fileName: @@ -508,7 +508,7 @@ class ServiceManager(QtGui.QWidget): self.newFile() for item in items: serviceItem = ServiceItem() - serviceItem.render_manager = self.parent.renderManager + serviceItem.render_manager = self.mainwindow.renderManager serviceItem.set_from_service(item, self.servicePath) self.validateItem(serviceItem) self.addServiceItem(serviceItem) @@ -535,7 +535,7 @@ class ServiceManager(QtGui.QWidget): if zip: zip.close() self.setFileName(fileName) - self.parent.addRecentFile(fileName) + self.mainwindow.addRecentFile(fileName) self.setModified(False) QtCore.QSettings(). \ setValue(u'service/last file',QtCore.QVariant(fileName)) @@ -886,9 +886,9 @@ class ServiceManager(QtGui.QWidget): """ log.debug(u'onThemeComboBoxSelected') self.service_theme = unicode(self.themeComboBox.currentText()) - self.parent.renderManager.set_service_theme(self.service_theme) + self.mainwindow.renderManager.set_service_theme(self.service_theme) QtCore.QSettings().setValue( - self.parent.serviceSettingsSection + u'/service theme', + self.mainwindow.serviceSettingsSection + u'/service theme', QtCore.QVariant(self.service_theme)) self.regenerateServiceItems() @@ -898,7 +898,7 @@ class ServiceManager(QtGui.QWidget): sure the theme combo box is in the correct state. """ log.debug(u'themeChange') - if self.parent.renderManager.theme_level == ThemeLevel.Global: + if self.mainwindow.renderManager.theme_level == ThemeLevel.Global: self.toolbar.actions[u'ThemeLabel'].setVisible(False) self.toolbar.actions[u'ThemeWidget'].setVisible(False) else: @@ -913,7 +913,7 @@ class ServiceManager(QtGui.QWidget): Receiver.send_message(u'cursor_busy') log.debug(u'regenerateServiceItems') # force reset of renderer as theme data has changed - self.parent.renderManager.themedata = None + self.mainwindow.renderManager.themedata = None if self.serviceItems: tempServiceItems = self.serviceItems self.serviceManagerList.clear() @@ -948,7 +948,7 @@ class ServiceManager(QtGui.QWidget): newItem.merge(item[u'service_item']) item[u'service_item'] = newItem self.repaintServiceList(itemcount + 1, 0) - self.parent.liveController.replaceServiceManagerItem(newItem) + self.mainwindow.liveController.replaceServiceManagerItem(newItem) self.setModified(True) def addServiceItem(self, item, rebuild=False, expand=None, replace=False): @@ -970,7 +970,7 @@ class ServiceManager(QtGui.QWidget): item.merge(self.serviceItems[sitem][u'service_item']) self.serviceItems[sitem][u'service_item'] = item self.repaintServiceList(sitem + 1, 0) - self.parent.liveController.replaceServiceManagerItem(item) + self.mainwindow.liveController.replaceServiceManagerItem(item) else: # nothing selected for dnd if self.dropPosition == 0: @@ -991,7 +991,7 @@ class ServiceManager(QtGui.QWidget): self.repaintServiceList(self.dropPosition, 0) # if rebuilding list make sure live is fixed. if rebuild: - self.parent.liveController.replaceServiceManagerItem(item) + self.mainwindow.liveController.replaceServiceManagerItem(item) self.dropPosition = 0 self.setModified(True) @@ -1001,7 +1001,7 @@ class ServiceManager(QtGui.QWidget): """ item, count = self.findServiceItem() if self.serviceItems[item][u'service_item'].is_valid: - self.parent.previewController.addServiceManagerItem( + self.mainwindow.previewController.addServiceManagerItem( self.serviceItems[item][u'service_item'], count) else: QtGui.QMessageBox.critical(self, @@ -1025,18 +1025,18 @@ class ServiceManager(QtGui.QWidget): """ item, count = self.findServiceItem() if self.serviceItems[item][u'service_item'].is_valid: - self.parent.liveController.addServiceManagerItem( + self.mainwindow.liveController.addServiceManagerItem( self.serviceItems[item][u'service_item'], count) if QtCore.QSettings().value( - self.parent.generalSettingsSection + u'/auto preview', + self.mainwindow.generalSettingsSection + u'/auto preview', QtCore.QVariant(False)).toBool(): item += 1 if self.serviceItems and item < len(self.serviceItems) and \ self.serviceItems[item][u'service_item'].is_capable( ItemCapabilities.AllowsPreview): - self.parent.previewController.addServiceManagerItem( + self.mainwindow.previewController.addServiceManagerItem( self.serviceItems[item][u'service_item'], 0) - self.parent.liveController.PreviewListWidget.setFocus() + self.mainwindow.liveController.PreviewListWidget.setFocus() else: QtGui.QMessageBox.critical(self, translate('OpenLP.ServiceManager', 'Missing Display Handler'), @@ -1156,7 +1156,7 @@ class ServiceManager(QtGui.QWidget): index = 0 self.service_theme = u'' self.themeComboBox.setCurrentIndex(index) - self.parent.renderManager.set_service_theme(self.service_theme) + self.mainwindow.renderManager.set_service_theme(self.service_theme) self.regenerateServiceItems() def onThemeChangeAction(self): diff --git a/openlp/core/ui/themeform.py b/openlp/core/ui/themeform.py index eaf54bdb9..43ca8828e 100644 --- a/openlp/core/ui/themeform.py +++ b/openlp/core/ui/themeform.py @@ -212,8 +212,8 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard): """ Updates the lines on a page on the wizard """ - self.mainLineCountLabel.setText(unicode(translate('OpenLP.ThemeForm', \ - '(%d lines per slide)' % int(lines)))) + self.mainLineCountLabel.setText(unicode(translate('OpenLP.ThemeForm', + '(%d lines per slide)')) % int(lines)) def resizeEvent(self, event=None): """ diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 0703402fd..9553a6028 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -45,13 +45,13 @@ class ThemeManager(QtGui.QWidget): """ Manages the orders of Theme. """ - def __init__(self, parent): + def __init__(self, mainwindow, parent=None): QtGui.QWidget.__init__(self, parent) - self.parent = parent + self.mainwindow = mainwindow self.settingsSection = u'themes' self.themeForm = ThemeForm(self) self.fileRenameForm = FileRenameForm(self) - self.serviceComboBox = self.parent.ServiceManagerContents.themeComboBox + self.serviceComboBox = self.mainwindow.ServiceManagerContents.themeComboBox # start with the layout self.layout = QtGui.QVBoxLayout(self) self.layout.setSpacing(0) @@ -641,7 +641,7 @@ class ThemeManager(QtGui.QWidget): (QtGui.QMessageBox.Yes | QtGui.QMessageBox.No), QtGui.QMessageBox.No) if self.saveThemeName != u'': - for plugin in self.parent.pluginManager.plugins: + for plugin in self.mainwindow.pluginManager.plugins: if plugin.usesTheme(self.saveThemeName): plugin.renameTheme(self.saveThemeName, name) if unicode(self.serviceComboBox.currentText()) == name: @@ -727,7 +727,7 @@ class ThemeManager(QtGui.QWidget): Flag to tell message lines per page need to be generated. """ log.debug(u'generateImage \n%s ', themeData) - return self.parent.renderManager.generate_preview(themeData, forcePage) + return self.mainwindow.renderManager.generate_preview(themeData, forcePage) def getPreviewImage(self, theme): """ @@ -788,7 +788,7 @@ class ThemeManager(QtGui.QWidget): return False else: if testPlugin: - for plugin in self.parent.pluginManager.plugins: + for plugin in self.mainwindow.pluginManager.plugins: if plugin.usesTheme(theme): QtGui.QMessageBox.critical(self, translate('OpenLP.ThemeManager', 'Error'), diff --git a/openlp/core/ui/themewizard.py b/openlp/core/ui/themewizard.py index 691b5e568..e30570903 100644 --- a/openlp/core/ui/themewizard.py +++ b/openlp/core/ui/themewizard.py @@ -471,8 +471,6 @@ class Ui_ThemeWizard(object): self.mainColorLabel.setText(translate('OpenLP.ThemeWizard', 'Color:')) self.mainSizeLabel.setText(translate('OpenLP.ThemeWizard', 'Size:')) self.mainSizeSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'pt')) - self.mainLineCountLabel.setText( - translate('OpenLP.ThemeWizard', '(%d lines per slide)')) self.lineSpacingLabel.setText( translate('OpenLP.ThemeWizard', 'Line Spacing:')) self.lineSpacingSpinBox.setSuffix(translate('OpenLP.ThemeWizard', 'pt')) @@ -564,17 +562,17 @@ class Ui_ThemeWizard(object): self.themeNameLabel.setText( translate('OpenLP.ThemeWizard', 'Theme name:')) # Align all QFormLayouts towards each other. - width = max(self.backgroundLabel.minimumSizeHint().width(), - self.colorLabel.minimumSizeHint().width()) - width = max(width, self.gradientStartLabel.minimumSizeHint().width()) - width = max(width, self.gradientEndLabel.minimumSizeHint().width()) - width = max(width, self.gradientTypeLabel.minimumSizeHint().width()) - width = max(width, self.imageLabel.minimumSizeHint().width()) - self.backgroundTypeSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Fixed) - self.colorSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Fixed) - self.gradientSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Fixed) - self.imageSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Fixed) + labelWidth = max(self.backgroundLabel.minimumSizeHint().width(), + self.colorLabel.minimumSizeHint().width(), + self.gradientStartLabel.minimumSizeHint().width(), + self.gradientEndLabel.minimumSizeHint().width(), + self.gradientTypeLabel.minimumSizeHint().width(), + self.imageLabel.minimumSizeHint().width()) + self.backgroundTypeSpacer.changeSize(labelWidth, 0, + QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + self.colorSpacer.changeSize(labelWidth, 0, + QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + self.gradientSpacer.changeSize(labelWidth, 0, + QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + self.imageSpacer.changeSize(labelWidth, 0, + QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) diff --git a/openlp/plugins/alerts/alertsplugin.py b/openlp/plugins/alerts/alertsplugin.py index 4a7e18cef..61be922d5 100644 --- a/openlp/plugins/alerts/alertsplugin.py +++ b/openlp/plugins/alerts/alertsplugin.py @@ -73,7 +73,7 @@ class AlertsPlugin(Plugin): self.toolsAlertItem.setStatusTip( translate('AlertsPlugin', 'Show an alert message.')) self.toolsAlertItem.setShortcut(u'F7') - self.serviceManager.parent.ToolsMenu.addAction(self.toolsAlertItem) + self.serviceManager.mainwindow.ToolsMenu.addAction(self.toolsAlertItem) QtCore.QObject.connect(self.toolsAlertItem, QtCore.SIGNAL(u'triggered()'), self.onAlertsTrigger) self.toolsAlertItem.setVisible(False) diff --git a/openlp/plugins/bibles/forms/bibleimportwizard.py b/openlp/plugins/bibles/forms/bibleimportwizard.py index a85e430a1..d22103fcb 100644 --- a/openlp/plugins/bibles/forms/bibleimportwizard.py +++ b/openlp/plugins/bibles/forms/bibleimportwizard.py @@ -373,19 +373,19 @@ class Ui_BibleImportWizard(object): 'you want to use this importer, you will need to install the ' '"python-sqlite" module.')) # Align all QFormLayouts towards each other. - width = max(self.formatLabel.minimumSizeHint().width(), - self.osisFileLabel.minimumSizeHint().width()) - width = max(width, self.csvBooksLabel.minimumSizeHint().width()) - width = max(width, self.csvVersesLabel.minimumSizeHint().width()) - width = max(width, self.openSongFileLabel.minimumSizeHint().width()) - width = max(width, self.openlp1FileLabel.minimumSizeHint().width()) - self.formatSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Fixed) - self.osisSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Fixed) - self.csvSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Fixed) - self.openSongSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Fixed) - self.openlp1Spacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Fixed) + labelWidth = max(self.formatLabel.minimumSizeHint().width(), + self.osisFileLabel.minimumSizeHint().width(), + self.csvBooksLabel.minimumSizeHint().width(), + self.csvVersesLabel.minimumSizeHint().width(), + self.openSongFileLabel.minimumSizeHint().width(), + self.openlp1FileLabel.minimumSizeHint().width()) + self.formatSpacer.changeSize(labelWidth, 0, + QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + self.osisSpacer.changeSize(labelWidth, 0, + QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + self.csvSpacer.changeSize(labelWidth, 0, + QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + self.openSongSpacer.changeSize(labelWidth, 0, + QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + self.openlp1Spacer.changeSize(labelWidth, 0, + QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index 6f26434de..64ee6da5a 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -306,7 +306,7 @@ class BSExtract(object): finally: if not content: return None - verse_number = re.compile(r'v(\d{2})(\d{3})(\d{3}) verse') + verse_number = re.compile(r'v(\d{1,2})(\d{3})(\d{3}) verse') verses = {} for verse in content: Receiver.send_message(u'openlp_process_events') diff --git a/openlp/plugins/songs/forms/songmaintenancedialog.py b/openlp/plugins/songs/forms/songmaintenancedialog.py index 582b6ebe5..51fafcc7a 100644 --- a/openlp/plugins/songs/forms/songmaintenancedialog.py +++ b/openlp/plugins/songs/forms/songmaintenancedialog.py @@ -36,8 +36,6 @@ class Ui_SongMaintenanceDialog(object): self.dialogLayout = QtGui.QGridLayout(songMaintenanceDialog) self.dialogLayout.setObjectName(u'dialogLayout') self.typeListWidget = QtGui.QListWidget(songMaintenanceDialog) - # Caution: fixed widget width - self.typeListWidget.setFixedWidth(172) self.typeListWidget.setIconSize(QtCore.QSize(32, 32)) self.typeListWidget.setUniformItemSizes(True) self.typeListWidget.setObjectName(u'typeListWidget') @@ -147,12 +145,12 @@ class Ui_SongMaintenanceDialog(object): def retranslateUi(self, songMaintenanceDialog): songMaintenanceDialog.setWindowTitle( translate('SongsPlugin.SongMaintenanceForm', 'Song Maintenance')) - self.listItemAuthors.setText( - translate('SongsPlugin.SongMaintenanceForm', 'Authors')) - self.listItemTopics.setText( - translate('SongsPlugin.SongMaintenanceForm', 'Topics')) - self.listItemBooks.setText( - translate('SongsPlugin.SongMaintenanceForm', 'Song Books')) + authorsString = translate('SongsPlugin.SongMaintenanceForm', 'Authors') + topicsString = translate('SongsPlugin.SongMaintenanceForm', 'Topics') + booksString = translate('SongsPlugin.SongMaintenanceForm', 'Song Books') + self.listItemAuthors.setText(authorsString) + self.listItemTopics.setText(topicsString) + self.listItemBooks.setText(booksString) self.authorsAddButton.setText( translate('SongsPlugin.SongMaintenanceForm', '&Add')) self.authorsEditButton.setText( @@ -171,3 +169,8 @@ class Ui_SongMaintenanceDialog(object): translate('SongsPlugin.SongMaintenanceForm', '&Edit')) self.booksDeleteButton.setText( translate('SongsPlugin.SongMaintenanceForm', '&Delete')) + typeListWidth = max(self.fontMetrics().width(authorsString), + self.fontMetrics().width(topicsString), + self.fontMetrics().width(booksString)) + self.typeListWidget.setFixedWidth(typeListWidth + + self.typeListWidget.iconSize().width() + 32) From ce1241aa0f9528cd06d0e1045e1f31f3e5b4b560 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 9 Jan 2011 17:52:31 +0100 Subject: [PATCH 16/56] merged classes together --- openlp/plugins/songs/forms/editsongform.py | 8 +- openlp/plugins/songs/lib/__init__.py | 3 +- openlp/plugins/songs/lib/mediaitem.py | 14 +- openlp/plugins/songs/lib/openlyricsimport.py | 6 +- openlp/plugins/songs/lib/songimport.py | 4 +- openlp/plugins/songs/lib/xml.py | 314 ++++++------------- openlp/plugins/songs/songsplugin.py | 4 +- 7 files changed, 109 insertions(+), 244 deletions(-) diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index 202cc43fe..86249f024 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -31,7 +31,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import Receiver, translate from openlp.plugins.songs.forms import EditVerseForm -from openlp.plugins.songs.lib import SongXMLBuilder, SongXMLParser, VerseType +from openlp.plugins.songs.lib import SongXML, VerseType from openlp.plugins.songs.lib.db import Book, Song, Author, Topic from editsongdialog import Ui_EditSongDialog @@ -263,8 +263,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): if isinstance(self.song.lyrics, buffer): self.song.lyrics = unicode(self.song.lyrics) if self.song.lyrics.startswith(u' - + @@ -71,32 +71,26 @@ from openlp.plugins.songs.lib.db import Author, Book, Song, Topic log = logging.getLogger(__name__) -class SongXMLBuilder(object): +class SongXML(object): """ - This class builds the XML used to describe songs. + This class builds and parses the XML used to describe songs. """ - log.info(u'SongXMLBuilder Loaded') + log.info(u'SongXML Loaded') - def __init__(self, song_language=None): + def __init__(self): """ - Set up the song builder. - - ``song_language`` - The language used in this song + Set up the default variables. """ - lang = u'en' - if song_language: - lang = song_language self.song_xml = objectify.fromstring(u'') - self.lyrics = etree.SubElement(self.song_xml, u'lyrics', language=lang) + self.lyrics = etree.SubElement(self.song_xml, u'lyrics') def add_verse_to_lyrics(self, type, number, content): """ - Add a verse to the ```` tag. + Add a verse to the ** tag. ``type`` - A string denoting the type of verse. Possible values are "Chorus", - "Verse", "Bridge", and "Custom". + A string denoting the type of verse. Possible values are "V", + "C", "B", "P", "I", "E" and "O". ``number`` An integer denoting the number of the item, for example: verse 1. @@ -109,13 +103,6 @@ class SongXMLBuilder(object): verse.text = etree.CDATA(content) self.lyrics.append(verse) - def dump_xml(self): - """ - Debugging aid to dump XML so that we can see what we have. - """ - return etree.tostring(self.song_xml, encoding=u'UTF-8', - xml_declaration=True, pretty_print=True) - def extract_xml(self): """ Extract our newly created XML song. @@ -123,16 +110,10 @@ class SongXMLBuilder(object): return etree.tostring(self.song_xml, encoding=u'UTF-8', xml_declaration=True) - -class SongXMLParser(object): - """ - A class to read in and parse a song's XML. - """ - log.info(u'SongXMLParser Loaded') - - def __init__(self, xml): + def get_verses(self, xml): """ - Set up our song XML parser. + Iterates through the verses in the XML and returns a list of verses + and their attributes. ``xml`` The XML of the song to be parsed. @@ -144,12 +125,6 @@ class SongXMLParser(object): self.song_xml = objectify.fromstring(xml) except etree.XMLSyntaxError: log.exception(u'Invalid xml %s', xml) - - def get_verses(self): - """ - Iterates through the verses in the XML and returns a list of verses - and their attributes. - """ xml_iter = self.song_xml.getiterator() verse_list = [] for element in xml_iter: @@ -166,191 +141,9 @@ class SongXMLParser(object): return etree.dump(self.song_xml) -#class LyricsXML(object): -# """ -# This class represents the XML in the ``lyrics`` field of a song. -# """ -# def __init__(self, song=None): -# if song: -# if song.lyrics.startswith(u'' % \ -# (verse[u'type'], verse[u'label'], verse[u'text']) -# lyrics_output = lyrics_output + \ -# u'%s' % \ -# (language[u'language'], verse_output) -# song_output = u'' + \ -# u'%s' % lyrics_output -# return song_output - - -class OpenLyricsBuilder(object): +class OpenLyrics(object): """ - This class represents the converter for song to OpenLyrics XML. - """ - def __init__(self, manager): - self.manager = manager - - def song_to_xml(self, song, pretty_print=False): - """ - Convert the song to OpenLyrics Format. - """ - song_xml_parser = SongXMLParser(song.lyrics) - verse_list = song_xml_parser.get_verses() - song_xml = objectify.fromstring( - u'') - properties = etree.SubElement(song_xml, u'properties') - titles = etree.SubElement(properties, u'titles') - self._add_text_to_element(u'title', titles, song.title) - if song.alternate_title: - self._add_text_to_element(u'title', titles, song.alternate_title) - if song.comments: - comments = etree.SubElement(properties, u'comments') - self._add_text_to_element(u'comment', comments, song.comments) - if song.copyright: - self._add_text_to_element(u'copyright', properties, song.copyright) - if song.verse_order: - self._add_text_to_element( - u'verseOrder', properties, song.verse_order) - if song.ccli_number: - self._add_text_to_element(u'ccliNo', properties, song.ccli_number) - if song.authors: - authors = etree.SubElement(properties, u'authors') - for author in song.authors: - self._add_text_to_element( - u'author', authors, author.display_name) - book = self.manager.get_object_filtered( - Book, Book.id == song.song_book_id) - if book is not None: - book = book.name - songbooks = etree.SubElement(properties, u'songbooks') - element = self._add_text_to_element( - u'songbook', songbooks, None, book) - element.set(u'entry', song.song_number) - if song.topics: - themes = etree.SubElement(properties, u'themes') - for topic in song.topics: - self._add_text_to_element(u'theme', themes, topic.name) - lyrics = etree.SubElement(song_xml, u'lyrics') - for verse in verse_list: - verse_tag = u'%s%s' % ( - verse[0][u'type'][0].lower(), verse[0][u'label']) - element = \ - self._add_text_to_element(u'verse', lyrics, None, verse_tag) - element = self._add_text_to_element(u'lines', element) - for line in unicode(verse[1]).split(u'\n'): - self._add_text_to_element(u'line', element, line) - return self._extract_xml(song_xml, pretty_print) - - def _add_text_to_element(self, tag, parent, text=None, label=None): - if label: - element = etree.Element(tag, name=unicode(label)) - else: - element = etree.Element(tag) - if text: - element.text = unicode(text) - parent.append(element) - return element - - def _extract_xml(self, xml, pretty_print): - """ - Extract our newly created XML song. - """ - return etree.tostring(xml, encoding=u'UTF-8', - xml_declaration=True, pretty_print=pretty_print) - - def _dump_xml(self, xml): - """ - Debugging aid to dump XML so that we can see what we have. - """ - return etree.tostring(xml, encoding=u'UTF-8', - xml_declaration=True, pretty_print=True) - - -class OpenLyricsParser(object): - """ - This class represents the converter for OpenLyrics XML to a song. + This class represents the converter for OpenLyrics XML to/from a song. As OpenLyrics has a rich set of different features, we cannot support them all. The following features are supported by the :class:`OpenLyricsParser`:: @@ -410,6 +203,57 @@ class OpenLyricsParser(object): def __init__(self, manager): self.manager = manager + def song_to_xml(self, song, pretty_print=False): + """ + Convert the song to OpenLyrics Format. + """ + sxml = SongXML() + verse_list = sxml.get_verses(song.lyrics) + song_xml = objectify.fromstring( + u'') + properties = etree.SubElement(song_xml, u'properties') + titles = etree.SubElement(properties, u'titles') + self._add_text_to_element(u'title', titles, song.title) + if song.alternate_title: + self._add_text_to_element(u'title', titles, song.alternate_title) + if song.comments: + comments = etree.SubElement(properties, u'comments') + self._add_text_to_element(u'comment', comments, song.comments) + if song.copyright: + self._add_text_to_element(u'copyright', properties, song.copyright) + if song.verse_order: + self._add_text_to_element( + u'verseOrder', properties, song.verse_order) + if song.ccli_number: + self._add_text_to_element(u'ccliNo', properties, song.ccli_number) + if song.authors: + authors = etree.SubElement(properties, u'authors') + for author in song.authors: + self._add_text_to_element( + u'author', authors, author.display_name) + book = self.manager.get_object_filtered( + Book, Book.id == song.song_book_id) + if book is not None: + book = book.name + songbooks = etree.SubElement(properties, u'songbooks') + element = self._add_text_to_element( + u'songbook', songbooks, None, book) + element.set(u'entry', song.song_number) + if song.topics: + themes = etree.SubElement(properties, u'themes') + for topic in song.topics: + self._add_text_to_element(u'theme', themes, topic.name) + lyrics = etree.SubElement(song_xml, u'lyrics') + for verse in verse_list: + verse_tag = u'%s%s' % ( + verse[0][u'type'][0].lower(), verse[0][u'label']) + element = \ + self._add_text_to_element(u'verse', lyrics, None, verse_tag) + element = self._add_text_to_element(u'lines', element) + for line in unicode(verse[1]).split(u'\n'): + self._add_text_to_element(u'line', element, line) + return self._extract_xml(song_xml, pretty_print) + def xml_to_song(self, xml): """ Create and save a song from OpenLyrics format xml to the database. Since @@ -441,6 +285,23 @@ class OpenLyricsParser(object): self.manager.save_object(song) return song.id + def _add_text_to_element(self, tag, parent, text=None, label=None): + if label: + element = etree.Element(tag, name=unicode(label)) + else: + element = etree.Element(tag) + if text: + element.text = unicode(text) + parent.append(element) + return element + + def _extract_xml(self, xml, pretty_print): + """ + Extract our newly created XML song. + """ + return etree.tostring(xml, encoding=u'UTF-8', + xml_declaration=True, pretty_print=pretty_print) + def _get(self, element, attribute): """ This returns the element's attribute as unicode string. @@ -562,7 +423,7 @@ class OpenLyricsParser(object): ``song`` The song object. """ - sxml = SongXMLBuilder() + sxml = SongXML() search_text = u'' temp_verse_order = [] for verse in lyrics.verse: @@ -682,3 +543,10 @@ class OpenLyricsParser(object): song.topics.append(topic) except AttributeError: pass + + def _dump_xml(self, xml): + """ + Debugging aid to dump XML so that we can see what we have. + """ + return etree.tostring(xml, encoding=u'UTF-8', + xml_declaration=True, pretty_print=True) diff --git a/openlp/plugins/songs/songsplugin.py b/openlp/plugins/songs/songsplugin.py index 545497acb..17e609fd4 100644 --- a/openlp/plugins/songs/songsplugin.py +++ b/openlp/plugins/songs/songsplugin.py @@ -31,7 +31,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import Plugin, StringContent, build_icon, translate from openlp.core.lib.db import Manager -from openlp.plugins.songs.lib import SongMediaItem, SongsTab, SongXMLParser +from openlp.plugins.songs.lib import SongMediaItem, SongsTab, SongXML from openlp.plugins.songs.lib.db import init_schema, Song from openlp.plugins.songs.lib.importer import SongFormat @@ -153,7 +153,7 @@ class SongsPlugin(Plugin): song.search_title = self.whitespace.sub(u' ', song.title.lower() + \ u' ' + song.alternate_title.lower()) lyrics = u'' - verses = SongXMLParser(song.lyrics).get_verses() + verses = SongXML().get_verses(song.lyrics) for verse in verses: lyrics = lyrics + self.whitespace.sub(u' ', verse[1]) + u' ' song.search_lyrics = lyrics.lower() From 62794614f91682fd87b2db82963433ce2f09d425 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 9 Jan 2011 18:07:17 +0100 Subject: [PATCH 17/56] clean ups --- openlp/core/ui/__init__.py | 4 ++-- openlp/plugins/songs/lib/xml.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openlp/core/ui/__init__.py b/openlp/core/ui/__init__.py index ca2123c87..c509fe023 100644 --- a/openlp/core/ui/__init__.py +++ b/openlp/core/ui/__init__.py @@ -35,11 +35,11 @@ class HideMode(object): ``Blank`` This mode is used to hide all output, specifically by covering the display with a black screen. - + ``Theme`` This mode is used to hide all output, but covers the display with the current theme background, as opposed to black. - + ``Desktop`` This mode hides all output by minimising the display, leaving the user's desktop showing. diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index 463e30d87..753383af3 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -269,7 +269,7 @@ class OpenLyrics(object): song = Song() if xml[:5] == u'').sub(u'', xml) song_xml = objectify.fromstring(xml) properties = song_xml.properties From 17a5d2c0b8d2b5e509395055243b07e8e5b581b8 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 9 Jan 2011 19:08:37 +0000 Subject: [PATCH 18/56] Theme fix --- openlp/core/ui/thememanager.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 0703402fd..fee26edad 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -379,7 +379,8 @@ class ThemeManager(QtGui.QWidget): files = QtGui.QFileDialog.getOpenFileNames(self, translate('OpenLP.ThemeManager', 'Select Theme Import File'), SettingsManager.get_last_dir(self.settingsSection), - translate('OpenLP.ThemeManager', 'Theme (*.*)')) + translate('OpenLP.ThemeManager', 'Theme v1 (*.theme);;' + 'Theme v2 (*.otz);;All Files (*.*)')) log.info(u'New Themes %s', unicode(files)) if files: for file in files: From 35da3d2926a84bc613d0bdaf2587075895ed244a Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 9 Jan 2011 19:15:40 +0000 Subject: [PATCH 19/56] Fix indentation --- openlp/core/ui/themeform.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/core/ui/themeform.py b/openlp/core/ui/themeform.py index 0155c6a4c..760e3b261 100644 --- a/openlp/core/ui/themeform.py +++ b/openlp/core/ui/themeform.py @@ -592,7 +592,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard): saveFrom = self.theme.background_filename if not self.edit_mode and \ not self.thememanager.checkIfThemeExists(self.theme.theme_name): - return + return self.accepted = True self.thememanager.saveTheme(self.theme, saveFrom, saveTo) return QtGui.QDialog.accept(self) From b52d0aafd5da669a9ee5436663e18e0558a0bbd5 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 9 Jan 2011 20:18:08 +0100 Subject: [PATCH 20/56] re.compile code from reindex tool --- openlp/plugins/songs/lib/mediaitem.py | 7 +++---- openlp/plugins/songs/lib/xml.py | 5 +++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 3f3755d14..73c8eaa10 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -351,8 +351,7 @@ class SongMediaItem(MediaManagerItem): service_item.theme = song.theme_name service_item.edit_id = item_id if song.lyrics.startswith(u'') properties = etree.SubElement(song_xml, u'properties') titles = etree.SubElement(properties, u'titles') - self._add_text_to_element(u'title', titles, song.title) + self._add_text_to_element(u'title', titles, song.title.strip()) if song.alternate_title: - self._add_text_to_element(u'title', titles, song.alternate_title) + self._add_text_to_element( + u'title', titles, song.alternate_title.strip()) if song.comments: comments = etree.SubElement(properties, u'comments') self._add_text_to_element(u'comment', comments, song.comments) From 5edde179a4a1f0e670e3ed8247d48c26197b6a7d Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Mon, 10 Jan 2011 01:46:47 +0000 Subject: [PATCH 21/56] Refactor web bibles --- openlp/core/lib/mailto/__init__.py | 4 +- openlp/core/utils/__init__.py | 32 ++++++- openlp/plugins/bibles/lib/http.py | 133 ++++++++++++----------------- 3 files changed, 88 insertions(+), 81 deletions(-) diff --git a/openlp/core/lib/mailto/__init__.py b/openlp/core/lib/mailto/__init__.py index f0e23f1b5..f05ebfdee 100644 --- a/openlp/core/lib/mailto/__init__.py +++ b/openlp/core/lib/mailto/__init__.py @@ -230,7 +230,7 @@ def open(filename): return _open(filename) -def _fix_addersses(**kwargs): +def _fix_addresses(**kwargs): for headername in (u'address', u'to', u'cc', u'bcc'): try: headervalue = kwargs[headername] @@ -260,7 +260,7 @@ def mailto_format(**kwargs): """ # @TODO: implement utf8 option - kwargs = _fix_addersses(**kwargs) + kwargs = _fix_addresses(**kwargs) parts = [] for headername in (u'to', u'cc', u'bcc', u'subject', u'body', u'attach'): if kwargs.has_key(headername): diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 54bd78ccc..4e1b4807b 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -282,8 +282,38 @@ def split_filename(path): else: return os.path.split(path) +def get_web_page(url, update_openlp=False): + """ + Attempts to download the webpage at url and returns that page or None. + + ``url`` + The URL to be downloaded. + + ``update_openlp`` + Tells OpenLP to update itself if the page is successfully downloaded. + Defaults to False. + """ + # TODO: Add proxy usage. Get proxy info from OpenLP settings, add to a + # proxy_handler, build into an opener and install the opener into urllib2. + # http://docs.python.org/library/urllib2.html + if not url: + return None + page = None + log.debug(u'Downloading URL = %s' % url) + try: + page = urllib2.urlopen(url) + log.debug(u'Downloaded URL = %s' % page.geturl()) + except urllib2.URLError: + log.exception(u'The web page could not be downloaded') + if not page: + return None + if update_openlp: + Receiver.send_message(u'openlp_process_events') + return page + from languagemanager import LanguageManager from actions import ActionList __all__ = [u'AppLocation', u'check_latest_version', u'add_actions', - u'get_filesystem_encoding', u'LanguageManager', u'ActionList'] + u'get_filesystem_encoding', u'LanguageManager', u'ActionList', + u'get_web_page'] diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index d9210a275..0d62b377c 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -23,20 +23,22 @@ # with this program; if not, write to the Free Software Foundation, Inc., 59 # # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### - +""" +The :mod:`http` module enables OpenLP to retrieve scripture from bible +websites. +""" import logging import os import re import sqlite3 import socket import urllib -import urllib2 from HTMLParser import HTMLParseError from BeautifulSoup import BeautifulSoup, NavigableString from openlp.core.lib import Receiver, translate -from openlp.core.utils import AppLocation +from openlp.core.utils import AppLocation, get_web_page from openlp.plugins.bibles.lib import SearchResults from openlp.plugins.bibles.lib.db import BibleDB, Book @@ -204,29 +206,11 @@ class BGExtract(object): url_params = urllib.urlencode( {u'search': u'%s %s' % (bookname, chapter), u'version': u'%s' % version}) - page = None - try: - page = urllib2.urlopen( - u'http://www.biblegateway.com/passage/?%s' % url_params) - log.debug(u'BibleGateway url = %s' % page.geturl()) - Receiver.send_message(u'openlp_process_events') - except urllib2.URLError: - log.exception(u'The web bible page could not be downloaded.') - send_error_message(u'download') - finally: - if not page: - return None cleaner = [(re.compile(' |
|\'\+\''), lambda match: '')] - soup = None - try: - soup = BeautifulSoup(page, markupMassage=cleaner) - except HTMLParseError: - log.exception(u'BeautifulSoup could not parse the bible page.') - Receiver.send_message(u'bibles_download_error') - send_error_message(u'parse') - finally: - if not soup: - return None + soup = get_soup_for_bible_ref( + u'http://www.biblegateway.com/passage/?%s' % url_params, cleaner) + if not soup: + return None Receiver.send_message(u'openlp_process_events') footnotes = soup.findAll(u'sup', u'footnote') if footnotes: @@ -280,35 +264,15 @@ class BSExtract(object): log.debug(u'get_bible_chapter %s,%s,%s', version, bookname, chapter) chapter_url = u'http://m.bibleserver.com/text/%s/%s%s' % \ (version, bookname, chapter) - - log.debug(u'URL: %s', chapter_url) - page = None - try: - page = urllib2.urlopen(chapter_url) - Receiver.send_message(u'openlp_process_events') - except urllib2.URLError: - log.exception(u'The web bible page could not be downloaded.') - send_error_message(u'download') - finally: - if not page: - return None - soup = None - try: - soup = BeautifulSoup(page) - except HTMLParseError: - log.exception(u'BeautifulSoup could not parse the bible page.') - send_error_message(u'parse') + soup = get_soup_for_bible_ref(chapter_url) + if not soup: return None Receiver.send_message(u'openlp_process_events') - content = None - try: - content = soup.find(u'div', u'content').find(u'div').findAll(u'div') - except: + content = soup.find(u'div', u'content').find(u'div').findAll(u'div') + if not content: log.exception(u'No verses found in the Bibleserver response.') send_error_message(u'parse') - finally: - if not content: - return None + return None verse_number = re.compile(r'v(\d{2})(\d{3})(\d{3}) verse') verses = {} for verse in content: @@ -344,21 +308,8 @@ class CWExtract(object): urlbookname = bookname.replace(u' ', u'-') chapter_url = u'http://www.biblestudytools.com/%s/%s/%s.html' % \ (version, urlbookname.lower(), chapter) - log.debug(u'URL: %s', chapter_url) - page = None - try: - page = urllib2.urlopen(chapter_url) - Receiver.send_message(u'openlp_process_events') - except urllib2.URLError: - log.exception(u'The web bible page could not be downloaded.') - send_error_message(u'download') - return None - soup = None - try: - soup = BeautifulSoup(page) - except HTMLParseError: - log.exception(u'BeautifulSoup could not parse the bible page.') - send_error_message(u'parse') + soup = get_soup_for_bible_ref(chapter_url) + if not soup: return None Receiver.send_message(u'openlp_process_events') htmlverses = soup.findAll(u'span', u'versetext') @@ -416,6 +367,8 @@ class HTTPBible(BibleDB): BibleDB.__init__(self, parent, **kwargs) self.download_source = kwargs[u'download_source'] self.download_name = kwargs[u'download_name'] + # TODO: Clean up proxy stuff. We probably want one global proxy per + # connection type (HTTP and HTTPS) at most. self.proxy_server = None self.proxy_username = None self.proxy_password = None @@ -471,7 +424,7 @@ class HTTPBible(BibleDB): book = reference[0] db_book = self.get_book(book) if not db_book: - book_details = self.lookup_book(book) + book_details = HTTPBooks.get_book(book) if not book_details: Receiver.send_message(u'openlp_error_message', { u'title': translate('BiblesPlugin', 'No Book Found'), @@ -511,12 +464,12 @@ class HTTPBible(BibleDB): log.debug(u'get_chapter %s, %s', book, chapter) log.debug(u'source = %s', self.download_source) if self.download_source.lower() == u'crosswalk': - ev = CWExtract(self.proxy_server) + handler = CWExtract(self.proxy_server) elif self.download_source.lower() == u'biblegateway': - ev = BGExtract(self.proxy_server) + handler = BGExtract(self.proxy_server) elif self.download_source.lower() == u'bibleserver': - ev = BSExtract(self.proxy_server) - return ev.get_bible_chapter(self.download_name, book, chapter) + handler = BSExtract(self.proxy_server) + return handler.get_bible_chapter(self.download_name, book, chapter) def get_books(self): """ @@ -525,12 +478,6 @@ class HTTPBible(BibleDB): return [Book.populate(name=book['name']) for book in HTTPBooks.get_books()] - def lookup_book(self, book): - """ - Look up the name of a book. - """ - return HTTPBooks.get_book(book) - def get_chapter_count(self, book): """ Return the number of chapters in a particular book. @@ -549,8 +496,38 @@ class HTTPBible(BibleDB): """ return HTTPBooks.get_verse_count(book, chapter) +def get_soup_for_bible_ref(reference_url, cleaner=None): + """ + Gets a webpage and returns a parsed and optionally cleaned soup or None. + + ``reference_url`` + The URL to obtain the soup from. + + ``cleaner`` + An optional regex to use during webpage parsing. + """ + if not reference_url: + return None + page = get_web_page(reference_url, True) + if not page: + send_error_message(u'download') + return None + soup = None + try: + if cleaner: + soup = BeautifulSoup(page, markupMassage=cleaner) + else: + soup = BeautifulSoup(page) + except HTMLParseError: + log.exception(u'BeautifulSoup could not parse the bible page.') + if not soup: + send_error_message(u'parse') + return None + Receiver.send_message(u'openlp_process_events') + return soup + def send_error_message(reason): - if reason == u'downoad': + if reason == u'download': Receiver.send_message(u'openlp_error_message', { u'title': translate('BiblePlugin.HTTPBible', 'Download Error'), u'message': translate('BiblePlugin.HTTPBible', 'There was a ' @@ -563,5 +540,5 @@ def send_error_message(reason): u'title': translate('BiblePlugin.HTTPBible', 'Parse Error'), u'message': translate('BiblePlugin.HTTPBible', 'There was a ' 'problem extracting your verse selection. If this error continues ' - 'continues to occur consider reporting a bug.') + 'to occur consider reporting a bug.') }) From 6a3be54f1df049cb56a7e75e44bc85f3258c083f Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Mon, 10 Jan 2011 16:07:27 +0100 Subject: [PATCH 22/56] removed quickMessage, added cursor_busy signal for text search --- openlp/plugins/bibles/lib/mediaitem.py | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 066563bec..c78597003 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -137,9 +137,6 @@ class BibleMediaItem(MediaManagerItem): self.quickSearchButton.setObjectName(u'quickSearchButton') self.quickSearchButtonLayout.addWidget(self.quickSearchButton) self.quickLayout.addRow(self.quickSearchButtonLayout) - self.quickMessage = QtGui.QLabel(self.quickTab) - self.quickMessage.setObjectName(u'quickMessage') - self.quickLayout.addRow(self.quickMessage) self.searchTabWidget.addTab(self.quickTab, translate('BiblesPlugin.MediaItem', 'Quick')) # Add the Advanced Search tab. @@ -231,9 +228,6 @@ class BibleMediaItem(MediaManagerItem): self.advancedSearchButtonLayout.addWidget(self.advancedSearchButton) self.advancedLayout.addLayout( self.advancedSearchButtonLayout, 7, 0, 1, 3) - self.advancedMessage = QtGui.QLabel(self.advancedTab) - self.advancedMessage.setObjectName(u'advancedMessage') - self.advancedLayout.addWidget(self.advancedMessage, 8, 0, 1, 3) self.searchTabWidget.addTab(self.advancedTab, translate('BiblesPlugin.MediaItem', 'Advanced')) # Add the search tab widget to the page layout. @@ -347,13 +341,6 @@ class BibleMediaItem(MediaManagerItem): self.configUpdated() log.debug(u'bible manager initialise complete') - def setQuickMessage(self, text): - self.quickMessage.setText(text) - self.advancedMessage.setText(text) - Receiver.send_message(u'openlp_process_events') - # Minor delay to get the events processed. - time.sleep(0.1) - def onListViewResize(self, width, height): listViewGeometry = self.listView.geometry() self.SearchProgress.setGeometry(listViewGeometry.x(), @@ -432,11 +419,13 @@ class BibleMediaItem(MediaManagerItem): verse_count = self.parent.manager.get_verse_count(bible, book, 1) if verse_count == 0: self.advancedSearchButton.setEnabled(False) - self.advancedMessage.setText( - translate('BiblesPlugin.MediaItem', 'Bible not fully loaded.')) + Receiver.send_message(u'openlp_error_message', { + u'title': translate('BiblePlugin.MediaItem', 'Error'), + u'message': translate('BiblePlugin.MediaItem', + 'Bible not fully loaded') + }) else: self.advancedSearchButton.setEnabled(True) - self.advancedMessage.setText(u'') self.adjustComboBox(1, self.chapter_count, self.advancedFromChapter) self.adjustComboBox(1, self.chapter_count, self.advancedToChapter) self.adjustComboBox(1, verse_count, self.advancedFromVerse) @@ -606,6 +595,7 @@ class BibleMediaItem(MediaManagerItem): second_bible, text) else: # We are doing a 'Text Search'. + Receiver.send_message(u'cursor_busy') bibles = self.parent.manager.get_bibles() self.search_results = self.parent.manager.verse_search(bible, second_bible, text) @@ -636,6 +626,7 @@ class BibleMediaItem(MediaManagerItem): elif self.search_results: self.displayResults(bible, second_bible) self.quickSearchButton.setEnabled(True) + Receiver.send_message(u'cursor_normal') def displayResults(self, bible, second_bible=u''): """ From 02cea00591479c964a30fd5cbe1d7fcdd0be2ce7 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Mon, 10 Jan 2011 17:02:19 +0100 Subject: [PATCH 23/56] fixed wrong indent --- openlp/plugins/bibles/lib/mediaitem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index c78597003..253cc2c62 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -423,7 +423,7 @@ class BibleMediaItem(MediaManagerItem): u'title': translate('BiblePlugin.MediaItem', 'Error'), u'message': translate('BiblePlugin.MediaItem', 'Bible not fully loaded') - }) + }) else: self.advancedSearchButton.setEnabled(True) self.adjustComboBox(1, self.chapter_count, self.advancedFromChapter) From e216356ed8221092c8bbe6897a714a3932248306 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Mon, 10 Jan 2011 17:40:47 +0000 Subject: [PATCH 24/56] Remove Theme Delete button on Golbal theme --- openlp/core/lib/mediamanageritem.py | 6 +++--- openlp/core/ui/thememanager.py | 19 +++++++++++++++++-- openlp/core/utils/__init__.py | 2 +- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 2d6bcce46..01272e438 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -266,7 +266,7 @@ class MediaManagerItem(QtGui.QWidget): """ Creates the main widget for listing items the media item is tracking """ - #Add the List widget + # Add the List widget self.listView = self.ListViewWithDnD_class(self) self.listView.uniformItemSizes = True self.listView.setSpacing(1) @@ -275,9 +275,9 @@ class MediaManagerItem(QtGui.QWidget): self.listView.setAlternatingRowColors(True) self.listView.setDragEnabled(True) self.listView.setObjectName(u'%sListView' % self.plugin.name) - #Add to pageLayout + # Add to pageLayout self.pageLayout.addWidget(self.listView) - #define and add the context menu + # define and add the context menu self.listView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) name_string = self.plugin.getString(StringContent.Name) if self.hasEditIcon: diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 590f33ff7..62744942b 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -51,7 +51,8 @@ class ThemeManager(QtGui.QWidget): self.settingsSection = u'themes' self.themeForm = ThemeForm(self) self.fileRenameForm = FileRenameForm(self) - self.serviceComboBox = self.mainwindow.ServiceManagerContents.themeComboBox + self.serviceComboBox =\ + self.mainwindow.ServiceManagerContents.themeComboBox # start with the layout self.layout = QtGui.QVBoxLayout(self) self.layout.setSpacing(0) @@ -68,7 +69,7 @@ class ThemeManager(QtGui.QWidget): u':/themes/theme_edit.png', translate('OpenLP.ThemeManager', 'Edit a theme.'), self.onEditTheme) - self.toolbar.addToolbarButton( + self.deleteToolbarAction = self.toolbar.addToolbarButton( translate('OpenLP.ThemeManager', 'Delete Theme'), u':/general/general_delete.png', translate('OpenLP.ThemeManager', 'Delete a theme.'), @@ -123,6 +124,9 @@ class ThemeManager(QtGui.QWidget): QtCore.QObject.connect(self.themeListWidget, QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.changeGlobalFromScreen) + QtCore.QObject.connect(self.themeListWidget, + QtCore.SIGNAL(u'itemClicked(QListWidgetItem *)'), + self.checkListState) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'theme_update_global'), self.changeGlobalFromTab) QtCore.QObject.connect(Receiver.get_receiver(), @@ -146,6 +150,17 @@ class ThemeManager(QtGui.QWidget): self.settingsSection + u'/global theme', QtCore.QVariant(u'')).toString()) + def checkListState(self, item): + """ + If Default theme selected remove delete button. + """ + realThemeName = unicode(item.data(QtCore.Qt.UserRole).toString()) + themeName = unicode(item.text()) + if realThemeName == themeName: + self.deleteToolbarAction.setVisible(True) + else: + self.deleteToolbarAction.setVisible(False) + def contextMenu(self, point): """ Build the Right Click Context menu and set state depending on diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 54bd78ccc..28a0b1238 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -207,7 +207,7 @@ def check_latest_version(current_version): The current version of OpenLP. """ version_string = current_version[u'full'] - #set to prod in the distribution config file. + # set to prod in the distribution config file. settings = QtCore.QSettings() settings.beginGroup(u'general') last_test = unicode(settings.value(u'last version test', From a9359a60f18a253aab2917b6804298aaf0f1f9e3 Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Mon, 10 Jan 2011 19:04:16 +0000 Subject: [PATCH 25/56] Unused import --- openlp/plugins/bibles/lib/mediaitem.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 253cc2c62..1921fbc6d 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -25,7 +25,6 @@ ############################################################################### import logging -import time from PyQt4 import QtCore, QtGui From d4f98c2169bb4fcad8c704851f16d986d20f66b4 Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Mon, 10 Jan 2011 19:07:09 +0000 Subject: [PATCH 26/56] Undefined variable typo --- openlp/core/ui/displaytagtab.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/core/ui/displaytagtab.py b/openlp/core/ui/displaytagtab.py index 3d6cd813d..154d397b9 100644 --- a/openlp/core/ui/displaytagtab.py +++ b/openlp/core/ui/displaytagtab.py @@ -59,7 +59,7 @@ class DisplayTagTab(SettingsTab): # cPickle only accepts str not unicode strings user_expands_string = str(unicode(user_expands).encode(u'utf8')) if user_expands_string: - user_tags = cPickle.loads(user_expand_string) + user_tags = cPickle.loads(user_expands_string) # If we have some user ones added them as well for t in user_tags: DisplayTags.add_html_tag(t) From 8af1756274c1838448de928160d731567238dee7 Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Mon, 10 Jan 2011 19:13:40 +0000 Subject: [PATCH 27/56] Long lines --- openlp/core/ui/servicemanager.py | 15 ++++++++------- openlp/core/ui/thememanager.py | 6 ++++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index acd775ef7..5d8d12cb5 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -371,9 +371,9 @@ class ServiceManager(QtGui.QWidget): self.saveFile() fileName = unicode(QtGui.QFileDialog.getOpenFileName(self.mainwindow, translate('OpenLP.ServiceManager', 'Open File'), - SettingsManager.get_last_dir(self.mainwindow.serviceSettingsSection), - translate('OpenLP.ServiceManager', - 'OpenLP Service Files (*.osz)'))) + SettingsManager.get_last_dir( + self.mainwindow.serviceSettingsSection), + translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)'))) if not fileName: return False SettingsManager.set_last_dir(self.mainwindow.serviceSettingsSection, @@ -461,9 +461,9 @@ class ServiceManager(QtGui.QWidget): """ fileName = unicode(QtGui.QFileDialog.getSaveFileName(self.mainwindow, translate('OpenLP.ServiceManager', 'Save Service'), - SettingsManager.get_last_dir(self.mainwindow.serviceSettingsSection), - translate('OpenLP.ServiceManager', - 'OpenLP Service Files (*.osz)'))) + SettingsManager.get_last_dir( + self.mainwindow.serviceSettingsSection), + translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)'))) if not fileName: return False if os.path.splitext(fileName)[1] == u'': @@ -951,7 +951,8 @@ class ServiceManager(QtGui.QWidget): newItem.merge(item[u'service_item']) item[u'service_item'] = newItem self.repaintServiceList(itemcount + 1, 0) - self.mainwindow.liveController.replaceServiceManagerItem(newItem) + self.mainwindow.liveController.replaceServiceManagerItem( + newItem) self.setModified(True) def addServiceItem(self, item, rebuild=False, expand=None, replace=False): diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 590f33ff7..7e929bb33 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -51,7 +51,8 @@ class ThemeManager(QtGui.QWidget): self.settingsSection = u'themes' self.themeForm = ThemeForm(self) self.fileRenameForm = FileRenameForm(self) - self.serviceComboBox = self.mainwindow.ServiceManagerContents.themeComboBox + self.serviceComboBox = \ + self.mainwindow.ServiceManagerContents.themeComboBox # start with the layout self.layout = QtGui.QVBoxLayout(self) self.layout.setSpacing(0) @@ -638,7 +639,8 @@ class ThemeManager(QtGui.QWidget): Flag to tell message lines per page need to be generated. """ log.debug(u'generateImage \n%s ', themeData) - return self.mainwindow.renderManager.generate_preview(themeData, forcePage) + return self.mainwindow.renderManager.generate_preview( + themeData, forcePage) def getPreviewImage(self, theme): """ From ac46fe92f07250a18156a440e1cc211cb0e0a97e Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Mon, 10 Jan 2011 20:19:27 +0000 Subject: [PATCH 28/56] Remove redundant unicode() --- openlp/core/ui/servicemanager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 5d8d12cb5..2d85e4b7f 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -482,7 +482,7 @@ class ServiceManager(QtGui.QWidget): zip = None fileTo = None try: - zip = zipfile.ZipFile(unicode(fileName)) + zip = zipfile.ZipFile(fileName) for file in zip.namelist(): try: ucsfile = file.decode(u'utf-8') From e2124942ccc42bb482330283e11c4cf424d096f7 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 11 Jan 2011 17:49:53 +0100 Subject: [PATCH 29/56] clean ups --- openlp/plugins/songs/lib/mediaitem.py | 2 +- openlp/plugins/songs/lib/openlyricsimport.py | 2 +- openlp/plugins/songs/lib/xml.py | 17 +++++++++-------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 5d6544346..858d7bbf2 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -448,7 +448,7 @@ class SongMediaItem(MediaManagerItem): if self.addSongFromService: editId = self.openLyrics.xml_to_song(item.xml_version) # Update service with correct song id. - if editId != 0: + if editId is not None: Receiver.send_message(u'service_item_update', u'%s:%s' % (editId, item._uuid)) diff --git a/openlp/plugins/songs/lib/openlyricsimport.py b/openlp/plugins/songs/lib/openlyricsimport.py index f11ba7642..c4610dfc0 100644 --- a/openlp/plugins/songs/lib/openlyricsimport.py +++ b/openlp/plugins/songs/lib/openlyricsimport.py @@ -70,7 +70,7 @@ class OpenLyricsImport(SongImport): parser = etree.XMLParser(remove_blank_text=True) file = etree.parse(file_path, parser) xml = unicode(etree.tostring(file)) - if self.openLyrics.xml_to_song(xml) == 0: + if self.openLyrics.xml_to_song(xml) is None: log.debug(u'File could not be imported: %s' % file_path) # Importing this song failed! For now we stop import. return False diff --git a/openlp/plugins/songs/lib/xml.py b/openlp/plugins/songs/lib/xml.py index 588ff923c..cbe313212 100644 --- a/openlp/plugins/songs/lib/xml.py +++ b/openlp/plugins/songs/lib/xml.py @@ -143,10 +143,11 @@ class SongXML(object): class OpenLyrics(object): """ - This class represents the converter for OpenLyrics XML to/from a song. + This class represents the converter for OpenLyrics XML (version 0.7) + to/from a song. As OpenLyrics has a rich set of different features, we cannot support them - all. The following features are supported by the :class:`OpenLyricsParser`:: + all. The following features are supported by the :class:`OpenLyrics`:: ** OpenLP does not support the attribute *type* and *lang*. @@ -203,7 +204,7 @@ class OpenLyrics(object): def __init__(self, manager): self.manager = manager - def song_to_xml(self, song, pretty_print=False): + def song_to_xml(self, song): """ Convert the song to OpenLyrics Format. """ @@ -253,7 +254,7 @@ class OpenLyrics(object): element = self._add_text_to_element(u'lines', element) for line in unicode(verse[1]).split(u'\n'): self._add_text_to_element(u'line', element, line) - return self._extract_xml(song_xml, pretty_print) + return self._extract_xml(song_xml) def xml_to_song(self, xml): """ @@ -266,7 +267,7 @@ class OpenLyrics(object): """ # No xml get out of here. if not xml: - return 0 + return None song = Song() if xml[:5] == u' Date: Tue, 11 Jan 2011 17:13:17 +0000 Subject: [PATCH 30/56] Increase ooo verbosity to aid debugging --- openlp/plugins/presentations/lib/impresscontroller.py | 11 +++++------ openlp/plugins/songs/lib/oooimport.py | 8 ++++---- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/openlp/plugins/presentations/lib/impresscontroller.py b/openlp/plugins/presentations/lib/impresscontroller.py index d7407b729..7c8cf593d 100644 --- a/openlp/plugins/presentations/lib/impresscontroller.py +++ b/openlp/plugins/presentations/lib/impresscontroller.py @@ -169,7 +169,7 @@ class ImpressController(PresentationController): try: return Dispatch(u'com.sun.star.ServiceManager') except pywintypes.com_error: - log.warn(u'Failed to get COM service manager. ' + log.exception(u'Failed to get COM service manager. ' u'Impress Controller has been disabled') return None @@ -257,7 +257,6 @@ class ImpressDocument(PresentationDocument): except: log.exception(u'Failed to load presentation %s' % url) return False - self.presentation = self.document.getPresentation() self.presentation.Display = \ self.controller.plugin.renderManager.screens.current_display + 1 @@ -327,8 +326,7 @@ class ImpressDocument(PresentationDocument): self.presentation = None self.document.dispose() except: - #We tried! - pass + log.exception("Closing presentation failed") self.document = None self.controller.remove_doc(self) @@ -339,13 +337,14 @@ class ImpressDocument(PresentationDocument): log.debug(u'is loaded OpenOffice') #print "is_loaded " if self.presentation is None or self.document is None: - #print "no present or document" + log.debug("is_loaded: no presentation or document") return False try: if self.document.getPresentation() is None: - #print "no getPresentation" + log.debug("getPresentation failed to find a presentation") return False except: + log.exception("getPresentation failed to find a presentation") return False return True diff --git a/openlp/plugins/songs/lib/oooimport.py b/openlp/plugins/songs/lib/oooimport.py index b467eab65..42ddfcdd1 100644 --- a/openlp/plugins/songs/lib/oooimport.py +++ b/openlp/plugins/songs/lib/oooimport.py @@ -116,7 +116,7 @@ class OooImport(SongImport): + u'socket,host=localhost,port=2002;' \ + u'urp;StarOffice.ComponentContext') except: - pass + log.exception("Failed to resolve uno connection") self.start_ooo_process() loop += 1 manager = ctx.ServiceManager @@ -143,7 +143,7 @@ class OooImport(SongImport): process.waitForStarted() self.process_started = True except: - pass + log.exception("start_ooo_process failed") def open_ooo_file(self, filepath): """ @@ -167,7 +167,7 @@ class OooImport(SongImport): self.import_wizard.incrementProgressBar( u'Processing file ' + filepath, 0) except: - pass + log.exception("open_ooo_file failed") return def close_ooo_file(self): @@ -232,4 +232,4 @@ class OooImport(SongImport): text += paratext + u'\n' songs = SongImport.process_songs_text(self.manager, text) for song in songs: - song.finish() \ No newline at end of file + song.finish() From 2feefa95f40759965c28cd0109a123733c00dfff Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Tue, 11 Jan 2011 17:44:13 +0000 Subject: [PATCH 31/56] Fixes --- openlp/core/ui/thememanager.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 62744942b..a19049487 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -156,6 +156,7 @@ class ThemeManager(QtGui.QWidget): """ realThemeName = unicode(item.data(QtCore.Qt.UserRole).toString()) themeName = unicode(item.text()) + # If default theme restrict actions if realThemeName == themeName: self.deleteToolbarAction.setVisible(True) else: From 76000d918be46c6600f3a446b16a82455cf1a4c5 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Tue, 11 Jan 2011 20:56:55 +0100 Subject: [PATCH 32/56] removed showprogress and hideprogress and added cursor_busy and cursor_normal --- openlp/core/lib/eventreceiver.py | 6 ------ openlp/plugins/bibles/lib/http.py | 4 ++-- openlp/plugins/bibles/lib/mediaitem.py | 29 -------------------------- 3 files changed, 2 insertions(+), 37 deletions(-) diff --git a/openlp/core/lib/eventreceiver.py b/openlp/core/lib/eventreceiver.py index 63ad5b796..5811ae933 100644 --- a/openlp/core/lib/eventreceiver.py +++ b/openlp/core/lib/eventreceiver.py @@ -207,12 +207,6 @@ class EventReceiver(QtCore.QObject): ``bibles_nobook`` Attempt to find book resulted in no match - ``bibles_showprogress`` - Show progress of bible verse import - - ``bibles_hideprogress`` - Hide progress of bible verse import - ``bibles_stop_import`` Stops the Bible Import diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index 54fb5237c..05880871f 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -438,7 +438,7 @@ class HTTPBible(BibleDB): book_details[u'testament_id']) book = db_book.name if BibleDB.get_verse_count(self, book, reference[1]) == 0: - Receiver.send_message(u'bibles_showprogress') + Receiver.send_message(u'cursor_busy') Receiver.send_message(u'openlp_process_events') search_results = self.get_chapter(book, reference[1]) if search_results and search_results.has_verselist(): @@ -453,7 +453,7 @@ class HTTPBible(BibleDB): self.create_chapter(db_book.id, search_results.chapter, search_results.verselist) Receiver.send_message(u'openlp_process_events') - Receiver.send_message(u'bibles_hideprogress') + Receiver.send_message(u'cursor_normal') Receiver.send_message(u'openlp_process_events') return BibleDB.get_verses(self, reference_list) diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 253cc2c62..a21a993ce 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -44,10 +44,6 @@ class BibleListView(BaseListWithDnD): self.PluginName = u'Bibles' BaseListWithDnD.__init__(self, parent) - def resizeEvent(self, event): - self.parent().onListViewResize(event.size().width(), - event.size().width()) - class BibleMediaItem(MediaManagerItem): """ @@ -257,22 +253,9 @@ class BibleMediaItem(MediaManagerItem): # Other stuff QtCore.QObject.connect(self.quickSearchEdit, QtCore.SIGNAL(u'returnPressed()'), self.onQuickSearchButton) - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'bibles_showprogress'), self.onSearchProgressShow) - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'bibles_hideprogress'), self.onSearchProgressHide) def addListViewToToolBar(self): MediaManagerItem.addListViewToToolBar(self) - # Progress Bar - self.SearchProgress = QtGui.QProgressBar(self) - self.SearchProgress.setFormat('') - self.SearchProgress.setMinimum(0) - self.SearchProgress.setMaximum(0) - self.SearchProgress.setGeometry(self.listView.geometry().left(), - self.listView.geometry().top(), 81, 23) - self.SearchProgress.setVisible(False) - self.SearchProgress.setObjectName(u'SearchProgress') def configUpdated(self): log.debug(u'configUpdated') @@ -341,18 +324,6 @@ class BibleMediaItem(MediaManagerItem): self.configUpdated() log.debug(u'bible manager initialise complete') - def onListViewResize(self, width, height): - listViewGeometry = self.listView.geometry() - self.SearchProgress.setGeometry(listViewGeometry.x(), - (listViewGeometry.y() + listViewGeometry.height()) - 23, 81, 23) - - def onSearchProgressShow(self): - self.SearchProgress.setVisible(True) - Receiver.send_message(u'openlp_process_events') - - def onSearchProgressHide(self): - self.SearchProgress.setVisible(False) - def onImportClick(self): if not hasattr(self, u'import_wizard'): self.import_wizard = BibleImportForm(self, self.parent.manager, From e0a2976fa91a03da49c4f608b5722d97d9fb40ba Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Tue, 11 Jan 2011 23:43:27 +0000 Subject: [PATCH 33/56] Fix BibleServer downloads (Bug #701651) --- openlp/core/utils/__init__.py | 10 ++++++++-- openlp/plugins/bibles/lib/http.py | 10 +++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 4e1b4807b..5274a6186 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -282,13 +282,16 @@ def split_filename(path): else: return os.path.split(path) -def get_web_page(url, update_openlp=False): +def get_web_page(url, header=None, update_openlp=False): """ Attempts to download the webpage at url and returns that page or None. ``url`` The URL to be downloaded. + ``header`` + An optional HTTP header to pass in the request to the web server. + ``update_openlp`` Tells OpenLP to update itself if the page is successfully downloaded. Defaults to False. @@ -298,10 +301,13 @@ def get_web_page(url, update_openlp=False): # http://docs.python.org/library/urllib2.html if not url: return None + req = urllib2.Request(url) + if header: + req.add_header(header[0], header[1]) page = None log.debug(u'Downloading URL = %s' % url) try: - page = urllib2.urlopen(url) + page = urllib2.urlopen(req) log.debug(u'Downloaded URL = %s' % page.geturl()) except urllib2.URLError: log.exception(u'The web page could not be downloaded') diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index 54fb5237c..2476ae65d 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -264,7 +264,8 @@ class BSExtract(object): log.debug(u'get_bible_chapter %s,%s,%s', version, bookname, chapter) chapter_url = u'http://m.bibleserver.com/text/%s/%s%s' % \ (version, bookname, chapter) - soup = get_soup_for_bible_ref(chapter_url) + header = (u'Accept-Language', u'en') + soup = get_soup_for_bible_ref(chapter_url, header) if not soup: return None Receiver.send_message(u'openlp_process_events') @@ -496,19 +497,22 @@ class HTTPBible(BibleDB): """ return HTTPBooks.get_verse_count(book, chapter) -def get_soup_for_bible_ref(reference_url, cleaner=None): +def get_soup_for_bible_ref(reference_url, header=None, cleaner=None): """ Gets a webpage and returns a parsed and optionally cleaned soup or None. ``reference_url`` The URL to obtain the soup from. + ``header`` + An optional HTTP header to pass to the bible web server. + ``cleaner`` An optional regex to use during webpage parsing. """ if not reference_url: return None - page = get_web_page(reference_url, True) + page = get_web_page(reference_url, header, True) if not page: send_error_message(u'download') return None From c32f8538d46e4e291f54faee065a188ca4b0dd1c Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Wed, 12 Jan 2011 03:25:45 +0000 Subject: [PATCH 34/56] Fix debugging patch --- openlp/plugins/songs/lib/oooimport.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openlp/plugins/songs/lib/oooimport.py b/openlp/plugins/songs/lib/oooimport.py index 42ddfcdd1..c5cca4fd6 100644 --- a/openlp/plugins/songs/lib/oooimport.py +++ b/openlp/plugins/songs/lib/oooimport.py @@ -23,7 +23,7 @@ # with this program; if not, write to the Free Software Foundation, Inc., 59 # # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### - +import logging import os from PyQt4 import QtCore @@ -31,6 +31,8 @@ from PyQt4 import QtCore from openlp.core.lib import Receiver from songimport import SongImport +log = logging.getLogger(__name__) + if os.name == u'nt': from win32com.client import Dispatch PAGE_BEFORE = 4 From 64367909ba07a7c13a74e4217b52698f9904f680 Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Wed, 12 Jan 2011 15:31:32 +0000 Subject: [PATCH 35/56] Improve bibleserver code resiliance --- openlp/plugins/bibles/lib/http.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index 2476ae65d..e7beeda29 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -269,11 +269,12 @@ class BSExtract(object): if not soup: return None Receiver.send_message(u'openlp_process_events') - content = soup.find(u'div', u'content').find(u'div').findAll(u'div') + content = soup.find(u'div', u'content') if not content: log.exception(u'No verses found in the Bibleserver response.') send_error_message(u'parse') return None + content = content.find(u'div').findAll(u'div') verse_number = re.compile(r'v(\d{1,2})(\d{3})(\d{3}) verse') verses = {} for verse in content: From 9bb2b942a015c137a97a392745b73c6204f93d51 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 12 Jan 2011 17:45:32 +0100 Subject: [PATCH 36/56] fix for merge --- openlp/plugins/songs/lib/mediaitem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 858d7bbf2..93e40f58a 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -448,7 +448,7 @@ class SongMediaItem(MediaManagerItem): if self.addSongFromService: editId = self.openLyrics.xml_to_song(item.xml_version) # Update service with correct song id. - if editId is not None: + if editId: Receiver.send_message(u'service_item_update', u'%s:%s' % (editId, item._uuid)) From af9e9641c498decbe17a1d9e78f321674ac2f0f7 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Wed, 12 Jan 2011 18:52:16 +0000 Subject: [PATCH 37/56] Fix black background on Display resizing Fixes: https://launchpad.net/bugs/696557 --- openlp/core/lib/imagemanager.py | 5 ++--- openlp/core/ui/maindisplay.py | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/openlp/core/lib/imagemanager.py b/openlp/core/lib/imagemanager.py index 0be1a01c8..dcfc50f0f 100644 --- a/openlp/core/lib/imagemanager.py +++ b/openlp/core/lib/imagemanager.py @@ -86,8 +86,7 @@ class ImageManager(QtCore.QObject): for key in self._cache.keys(): image = self._cache[key] image.dirty = True - fullpath = os.path.join(image.path, image.name) - image.image = resize_image(fullpath, + image.image = resize_image(image.path, self.width, self.height) self._cache_dirty = True # only one thread please @@ -165,4 +164,4 @@ class ImageManager(QtCore.QObject): image = self._cache[key] if image.dirty: image.image_bytes = image_to_byte(image.image) - image.dirty = False \ No newline at end of file + image.dirty = False diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index adc2cb5fa..ab69cd1e9 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -198,7 +198,7 @@ class MainDisplay(DisplayWidget): The slide text to be displayed """ log.debug(u'text to display') - # Wait for the webview to update before displayiong text. + # Wait for the webview to update before displaying text. while not self.loaded: Receiver.send_message(u'openlp_process_events') self.frame.evaluateJavaScript(u'show_text("%s")' % \ From 0a5b44c6a35588bba808d0bd28716c916f44d58c Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Wed, 12 Jan 2011 19:12:30 +0000 Subject: [PATCH 38/56] BibleGateway fix --- openlp/plugins/bibles/lib/http.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index e7beeda29..da3a1e9e5 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -208,7 +208,8 @@ class BGExtract(object): u'version': u'%s' % version}) cleaner = [(re.compile(' |
|\'\+\''), lambda match: '')] soup = get_soup_for_bible_ref( - u'http://www.biblegateway.com/passage/?%s' % url_params, cleaner) + u'http://www.biblegateway.com/passage/?%s' % url_params, + cleaner=cleaner) if not soup: return None Receiver.send_message(u'openlp_process_events') From 727f7fe7bf5163f350478cf1a3038b562a5734bb Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 12 Jan 2011 20:31:46 +0100 Subject: [PATCH 39/56] --- openlp/core/lib/mediamanageritem.py | 10 +++++----- openlp/core/lib/serviceitem.py | 1 + openlp/core/ui/slidecontroller.py | 20 ++++++++++++-------- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 2d6bcce46..6fb834e05 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -266,7 +266,7 @@ class MediaManagerItem(QtGui.QWidget): """ Creates the main widget for listing items the media item is tracking """ - #Add the List widget + # Add the List widget self.listView = self.ListViewWithDnD_class(self) self.listView.uniformItemSizes = True self.listView.setSpacing(1) @@ -275,9 +275,9 @@ class MediaManagerItem(QtGui.QWidget): self.listView.setAlternatingRowColors(True) self.listView.setDragEnabled(True) self.listView.setObjectName(u'%sListView' % self.plugin.name) - #Add to pageLayout + # Add to pageLayout self.pageLayout.addWidget(self.listView) - #define and add the context menu + # define and add the context menu self.listView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) name_string = self.plugin.getString(StringContent.Name) if self.hasEditIcon: @@ -314,7 +314,7 @@ class MediaManagerItem(QtGui.QWidget): context_menu_action( self.listView, u':/general/general_add.png', translate('OpenLP.MediaManagerItem', - '&Add to selected Service Item'), + '&Add to selected Service Item'), self.onAddEditClick)) QtCore.QObject.connect(self.listView, QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), @@ -441,7 +441,7 @@ class MediaManagerItem(QtGui.QWidget): QtGui.QMessageBox.information(self, translate('OpenLP.MediaManagerItem', 'No Items Selected'), translate('OpenLP.MediaManagerItem', - 'You must select one or more items to preview.')) + 'You must select one or more items to preview.')) else: log.debug(u'%s Preview requested', self.plugin.name) serviceItem = self.buildServiceItem() diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index f18605711..ce0907fbb 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -60,6 +60,7 @@ class ItemCapabilities(object): AddIfNewItem = 9 ProvidesOwnDisplay = 10 + class ServiceItem(object): """ The service item is a base class for the plugins to use to interact with diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 690cb9264..92b59a900 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -412,13 +412,17 @@ class SlideController(QtGui.QWidget): max_width = self.PreviewFrame.width() - self.grid.margin() * 2 self.SlidePreview.setFixedSize(QtCore.QSize(max_width, max_width / self.ratio)) - width = self.parent.ControlSplitter.sizes()[self.split] - self.PreviewListWidget.setColumnWidth(0, width) - # Sort out image heights (Songs, bibles excluded) - if self.serviceItem and not self.serviceItem.is_text(): - for framenumber in range(len(self.serviceItem.get_frames())): - self.PreviewListWidget.setRowHeight( - framenumber, width / self.ratio) + # Make sure that the frames have the correct size. + if self.serviceItem: + self.PreviewListWidget.resizeRowsToContents() + # Sort out image heights (Songs, bibles excluded) + if not self.serviceItem.is_text(): + width = self.parent.ControlSplitter.sizes()[self.split] + for framenumber in range(len(self.serviceItem.get_frames())): + self.PreviewListWidget.setRowHeight( + framenumber, width / self.ratio) + self.PreviewListWidget.setColumnWidth(0, + self.PreviewListWidget.viewport().size().width()) def onSongBarHandler(self): request = unicode(self.sender().text()) @@ -590,7 +594,7 @@ class SlideController(QtGui.QWidget): self.parent.renderManager.height) else: image = self.parent.renderManager.image_manager. \ - get_image(frame[u'title']) + get_image(frame[u'title']) label.setPixmap(QtGui.QPixmap.fromImage(image)) self.PreviewListWidget.setCellWidget(framenumber, 0, label) slideHeight = width * self.parent.renderManager.screen_ratio From 7f5293c4c8ba8fbe28913e7488868762ba2807c3 Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Thu, 13 Jan 2011 01:14:38 +0000 Subject: [PATCH 40/56] Cleanup and refactor file unicode check --- openlp/core/lib/imagemanager.py | 1 - openlp/core/ui/servicemanager.py | 12 ++++-------- openlp/core/ui/thememanager.py | 21 ++++++--------------- openlp/core/utils/__init__.py | 22 +++++++++++++++++++++- 4 files changed, 31 insertions(+), 25 deletions(-) diff --git a/openlp/core/lib/imagemanager.py b/openlp/core/lib/imagemanager.py index dcfc50f0f..02d7010be 100644 --- a/openlp/core/lib/imagemanager.py +++ b/openlp/core/lib/imagemanager.py @@ -30,7 +30,6 @@ A Thread is used to convert the image to a byte array so the user does not need to wait for the conversion to happen. """ import logging -import os import time from PyQt4 import QtCore diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 2d85e4b7f..ffc2bee25 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -37,7 +37,7 @@ from openlp.core.lib import OpenLPToolbar, ServiceItem, context_menu_action, \ Receiver, build_icon, ItemCapabilities, SettingsManager, translate, \ ThemeLevel from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm -from openlp.core.utils import AppLocation, split_filename +from openlp.core.utils import AppLocation, file_is_unicode, split_filename class ServiceManagerList(QtGui.QTreeWidget): """ @@ -484,16 +484,13 @@ class ServiceManager(QtGui.QWidget): try: zip = zipfile.ZipFile(fileName) for file in zip.namelist(): - try: - ucsfile = file.decode(u'utf-8') - except UnicodeDecodeError: + ucsfile = file_is_unicode(file) + if not ucsfile: QtGui.QMessageBox.critical( self, translate('OpenLP.ServiceManager', 'Error'), translate('OpenLP.ServiceManager', 'File is not a valid service.\n' 'The content encoding is not UTF-8.')) - log.exception(u'Filename "%s" is not valid UTF-8' % - file.decode(u'utf-8', u'replace')) continue osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile)) filePath = os.path.join(self.servicePath, @@ -515,8 +512,7 @@ class ServiceManager(QtGui.QWidget): serviceItem.set_from_service(item, self.servicePath) self.validateItem(serviceItem) self.addServiceItem(serviceItem) - if serviceItem.is_capable( - ItemCapabilities.OnLoadUpdate): + if serviceItem.is_capable(ItemCapabilities.OnLoadUpdate): Receiver.send_message(u'%s_service_load' % serviceItem.name.lower(), serviceItem) try: diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 73f1a6d8b..81e191396 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -37,7 +37,8 @@ from openlp.core.theme import Theme from openlp.core.lib import OpenLPToolbar, ThemeXML, get_text_file_string, \ build_icon, Receiver, SettingsManager, translate, check_item_selected, \ BackgroundType, BackgroundGradientType, check_directory_exists -from openlp.core.utils import AppLocation, get_filesystem_encoding +from openlp.core.utils import AppLocation, file_is_unicode, \ + get_filesystem_encoding log = logging.getLogger(__name__) @@ -475,7 +476,8 @@ class ThemeManager(QtGui.QWidget): unicode(themeName) + u'.xml') xml = get_text_file_string(xmlFile) if not xml: - return self._baseTheme() + log.debug("No theme data - using default theme") + return ThemeXML() else: return self._createThemeFromXml(xml, self.path) @@ -494,16 +496,13 @@ class ThemeManager(QtGui.QWidget): filexml = None themename = None for file in zip.namelist(): - try: - ucsfile = file.decode(u'utf-8') - except UnicodeDecodeError: + ucsfile = file_is_unicode(file) + if not ucsfile: QtGui.QMessageBox.critical( self, translate('OpenLP.ThemeManager', 'Error'), translate('OpenLP.ThemeManager', 'File is not a valid theme.\n' 'The content encoding is not UTF-8.')) - log.exception(u'Filename "%s" is not valid UTF-8' % - file.decode(u'utf-8', u'replace')) continue osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile)) theme_dir = None @@ -668,14 +667,6 @@ class ThemeManager(QtGui.QWidget): image = os.path.join(self.path, theme + u'.png') return image - def _baseTheme(self): - """ - Provide a base theme with sensible defaults - """ - log.debug(u'base theme created') - newtheme = ThemeXML() - return newtheme - def _createThemeFromXml(self, themeXml, path): """ Return a theme object using information parsed from XML diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index ccdb2afa1..75f00f298 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -317,9 +317,29 @@ def get_web_page(url, header=None, update_openlp=False): Receiver.send_message(u'openlp_process_events') return page +def file_is_unicode(filename): + """ + Checks if a file is valid unicode and returns the unicode decoded file or + None. + + ``filename`` + File to check is valid unicode. + """ + if not filename: + return None + ucsfile = None + try: + ucsfile = filename.decode(u'utf-8') + except UnicodeDecodeError: + log.exception(u'Filename "%s" is not valid UTF-8' % + filename.decode(u'utf-8', u'replace')) + if not ucsfile: + return None + return ucsfile + from languagemanager import LanguageManager from actions import ActionList __all__ = [u'AppLocation', u'check_latest_version', u'add_actions', u'get_filesystem_encoding', u'LanguageManager', u'ActionList', - u'get_web_page'] + u'get_web_page', u'file_is_unicode'] From f487464280f87594adcb9da463aa0fedfe70e753 Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Thu, 13 Jan 2011 02:28:03 +0000 Subject: [PATCH 41/56] Cleanup exceptions --- openlp/plugins/bibles/lib/csvbible.py | 2 +- openlp/plugins/bibles/lib/opensong.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/plugins/bibles/lib/csvbible.py b/openlp/plugins/bibles/lib/csvbible.py index 8b1d70128..2e9e9523b 100644 --- a/openlp/plugins/bibles/lib/csvbible.py +++ b/openlp/plugins/bibles/lib/csvbible.py @@ -72,7 +72,7 @@ class CSVBible(BibleDB): self.create_book(unicode(line[1], details['encoding']), line[2], int(line[0])) Receiver.send_message(u'openlp_process_events') - except IOError, IndexError: + except (IOError, IndexError): log.exception(u'Loading books from file failed') success = False finally: diff --git a/openlp/plugins/bibles/lib/opensong.py b/openlp/plugins/bibles/lib/opensong.py index c0b60f911..03d243390 100644 --- a/openlp/plugins/bibles/lib/opensong.py +++ b/openlp/plugins/bibles/lib/opensong.py @@ -89,7 +89,7 @@ class OpenSongBible(BibleDB): 'Importing ...')) % (db_book.name, int(chapter.attrib[u'n']))) self.session.commit() - except IOError, AttributeError: + except (IOError, AttributeError): log.exception(u'Loading bible from OpenSong file failed') success = False finally: From 74909281907a29f17bc1e324fa6267cdb03d27eb Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Thu, 13 Jan 2011 17:55:29 +0000 Subject: [PATCH 42/56] Refactor wizards --- openlp/core/lib/eventreceiver.py | 4 +- openlp/core/ui/wizard.py | 171 ++++++ openlp/core/utils/__init__.py | 21 +- .../plugins/bibles/forms/bibleimportform.py | 522 ++++++++++++++---- .../plugins/bibles/forms/bibleimportwizard.py | 391 ------------- openlp/plugins/bibles/lib/csvbible.py | 4 +- openlp/plugins/bibles/lib/http.py | 18 +- openlp/plugins/bibles/lib/mediaitem.py | 2 +- openlp/plugins/bibles/lib/openlp1.py | 6 +- openlp/plugins/bibles/lib/opensong.py | 4 +- openlp/plugins/bibles/lib/osis.py | 8 +- openlp/plugins/songs/forms/songimportform.py | 444 +++++++++++++-- .../plugins/songs/forms/songimportwizard.py | 362 ------------ openlp/plugins/songs/lib/cclifileimport.py | 2 +- openlp/plugins/songs/lib/ewimport.py | 2 +- openlp/plugins/songs/lib/olp1import.py | 2 +- openlp/plugins/songs/lib/olpimport.py | 2 +- openlp/plugins/songs/lib/oooimport.py | 6 +- openlp/plugins/songs/lib/openlyricsimport.py | 6 +- openlp/plugins/songs/lib/opensongimport.py | 2 +- openlp/plugins/songs/lib/sofimport.py | 4 +- openlp/plugins/songs/lib/songbeamerimport.py | 3 +- openlp/plugins/songs/lib/songimport.py | 4 +- .../songs/lib/test/test_opensongimport.py | 2 +- openlp/plugins/songs/lib/wowimport.py | 4 +- 25 files changed, 1029 insertions(+), 967 deletions(-) create mode 100644 openlp/core/ui/wizard.py delete mode 100644 openlp/plugins/bibles/forms/bibleimportwizard.py delete mode 100644 openlp/plugins/songs/forms/songimportwizard.py diff --git a/openlp/core/lib/eventreceiver.py b/openlp/core/lib/eventreceiver.py index 5811ae933..6fa8e624a 100644 --- a/openlp/core/lib/eventreceiver.py +++ b/openlp/core/lib/eventreceiver.py @@ -207,8 +207,8 @@ class EventReceiver(QtCore.QObject): ``bibles_nobook`` Attempt to find book resulted in no match - ``bibles_stop_import`` - Stops the Bible Import + ``openlp_stop_wizard`` + Stops a wizard before completion ``remotes_poll_request`` Waits for openlp to do something "interesting" and sends a diff --git a/openlp/core/ui/wizard.py b/openlp/core/ui/wizard.py new file mode 100644 index 000000000..3b221455b --- /dev/null +++ b/openlp/core/ui/wizard.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2011 Raoul Snyman # +# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael # +# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian # +# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, # +# Carsten Tinggaard, Frode Woldsund # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### +""" +The :mod:``wizard`` module provides generic wizard tools for OpenLP. +""" +import logging + +from PyQt4 import QtCore, QtGui + +from openlp.core.lib import build_icon, Receiver + +log = logging.getLogger(__name__) + +class OpenLPWizard(QtGui.QWizard): + """ + Generic OpenLP wizard to provide generic functionality and a unified look + and feel. + """ + def __init__(self, parent, plugin, name, image): + QtGui.QWizard.__init__(self, parent) + self.setObjectName(name) + self.openIcon = build_icon(u':/general/general_open.png') + self.deleteIcon = build_icon(u':/general/general_delete.png') + self.finishButton = self.button(QtGui.QWizard.FinishButton) + self.cancelButton = self.button(QtGui.QWizard.CancelButton) + self.setupUi(image) + self.registerFields() + self.plugin = plugin + self.customInit() + self.customSignals() + QtCore.QObject.connect(self, QtCore.SIGNAL(u'currentIdChanged(int)'), + self.onCurrentIdChanged) + + def setupUi(self, image): + """ + Set up the wizard UI + """ + self.setModal(True) + self.setWizardStyle(QtGui.QWizard.ModernStyle) + self.setOptions(QtGui.QWizard.IndependentPages | + QtGui.QWizard.NoBackButtonOnStartPage | + QtGui.QWizard.NoBackButtonOnLastPage) + self.addWelcomePage(image) + self.addCustomPages() + self.addProgressPage() + self.retranslateUi() + QtCore.QMetaObject.connectSlotsByName(self) + + def addWelcomePage(self, image): + """ + Add the opening welcome page to the wizard. + + ``image`` + A splash image for the wizard + """ + self.welcomePage = QtGui.QWizardPage() + self.welcomePage.setPixmap(QtGui.QWizard.WatermarkPixmap, + QtGui.QPixmap(image)) + self.welcomePage.setObjectName(u'WelcomePage') + self.welcomeLayout = QtGui.QVBoxLayout(self.welcomePage) + self.welcomeLayout.setObjectName(u'WelcomeLayout') + self.titleLabel = QtGui.QLabel(self.welcomePage) + self.titleLabel.setObjectName(u'TitleLabel') + self.welcomeLayout.addWidget(self.titleLabel) + self.welcomeLayout.addSpacing(40) + self.informationLabel = QtGui.QLabel(self.welcomePage) + self.informationLabel.setWordWrap(True) + self.informationLabel.setObjectName(u'InformationLabel') + self.welcomeLayout.addWidget(self.informationLabel) + self.welcomeLayout.addStretch() + self.addPage(self.welcomePage) + + def addProgressPage(self): + """ + Add the progress page for the wizard. This page informs the user how + the wizard is progressing with its task. + """ + self.progressPage = QtGui.QWizardPage() + self.progressPage.setObjectName(u'progressPage') + self.progressLayout = QtGui.QVBoxLayout(self.progressPage) + self.progressLayout.setMargin(48) + self.progressLayout.setObjectName(u'progressLayout') + self.progressLabel = QtGui.QLabel(self.progressPage) + self.progressLabel.setObjectName(u'progressLabel') + self.progressLayout.addWidget(self.progressLabel) + self.progressBar = QtGui.QProgressBar(self.progressPage) + self.progressBar.setObjectName(u'progressBar') + self.progressLayout.addWidget(self.progressBar) + self.addPage(self.progressPage) + + def exec_(self): + """ + Run the wizard. + """ + self.setDefaults() + return QtGui.QWizard.exec_(self) + + def reject(self): + """ + Stop the wizard on cancel button, close button or ESC key. + """ + log.debug(u'Wizard cancelled by user.') + if self.currentPage() == self.progressPage: + Receiver.send_message(u'openlp_stop_wizard') + self.done(QtGui.QDialog.Rejected) + + def onCurrentIdChanged(self, pageId): + """ + Perform necessary functions depending on which wizard page is active. + """ + if self.page(pageId) == self.progressPage: + self.preWizard() + self.performWizard() + self.postWizard() + + def incrementProgressBar(self, status_text, increment=1): + """ + Update the wizard progress page. + + ``status_text`` + Current status information to display. + + ``increment`` + The value to increment the progress bar by. + """ + log.debug(u'IncrementBar %s', status_text) + self.progressLabel.setText(status_text) + if increment > 0: + self.progressBar.setValue(self.progressBar.value() + increment) + Receiver.send_message(u'openlp_process_events') + + def preWizard(self): + """ + Prepare the UI for the import. + """ + self.finishButton.setVisible(False) + self.progressBar.setMinimum(0) + self.progressBar.setMaximum(1188) + self.progressBar.setValue(0) + + def postWizard(self): + """ + Clean up the UI after the import has finished. + """ + self.progressBar.setValue(self.progressBar.maximum()) + self.finishButton.setVisible(True) + self.cancelButton.setVisible(False) + Receiver.send_message(u'openlp_process_events') diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index 75f00f298..d8012f433 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -337,9 +337,28 @@ def file_is_unicode(filename): return None return ucsfile +def string_is_unicode(test_string): + """ + Makes sure a string is unicode. + + ``test_string`` + The string to confirm is unicode. + """ + return_string = u'' + if not test_string: + return return_string + if isinstance(test_string, unicode): + return_string = test_string + if not isinstance(test_string, unicode): + try: + return_string = unicode(test_string, u'utf-8') + except UnicodeError: + log.exception("Error encoding string to unicode") + return return_string + from languagemanager import LanguageManager from actions import ActionList __all__ = [u'AppLocation', u'check_latest_version', u'add_actions', u'get_filesystem_encoding', u'LanguageManager', u'ActionList', - u'get_web_page', u'file_is_unicode'] + u'get_web_page', u'file_is_unicode', u'string_is_unicode'] diff --git a/openlp/plugins/bibles/forms/bibleimportform.py b/openlp/plugins/bibles/forms/bibleimportform.py index 4590ea739..d79051126 100644 --- a/openlp/plugins/bibles/forms/bibleimportform.py +++ b/openlp/plugins/bibles/forms/bibleimportform.py @@ -23,7 +23,9 @@ # with this program; if not, write to the Free Software Foundation, Inc., 59 # # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### - +""" +The bible import functions for OpenLP +""" import csv import logging import os @@ -31,15 +33,18 @@ import os.path from PyQt4 import QtCore, QtGui -from bibleimportwizard import Ui_BibleImportWizard from openlp.core.lib import Receiver, SettingsManager, translate from openlp.core.lib.db import delete_database -from openlp.core.utils import AppLocation +from openlp.core.ui.wizard import OpenLPWizard +from openlp.core.utils import AppLocation, string_is_unicode from openlp.plugins.bibles.lib.manager import BibleFormat log = logging.getLogger(__name__) class WebDownload(object): + """ + Provides an enumeration for the web bible types available to OpenLP. + """ Unknown = -1 Crosswalk = 0 BibleGateway = 1 @@ -53,10 +58,13 @@ class WebDownload(object): @classmethod def get_name(cls, name): + """ + Get the web bible type name. + """ return cls.Names[name] -class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard): +class BibleImportForm(OpenLPWizard): """ This is the Bible Import Wizard, which allows easy importing of Bibles into OpenLP from other formats like OSIS, CSV and OpenSong. @@ -76,27 +84,42 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard): ``bibleplugin`` The Bible plugin. """ - QtGui.QWizard.__init__(self, parent) - self.setupUi(self) - self.registerFields() + self.manager = manager + self.web_bible_list = {} + OpenLPWizard.__init__(self, parent, bibleplugin, u'bibleImportWizard', + u':/wizards/wizard_importbible.bmp') + + def setupUi(self, image): + """ + Set up the UI for the bible wizard. + """ + OpenLPWizard.setupUi(self, image) + QtCore.QObject.connect(self.formatComboBox, + QtCore.SIGNAL(u'currentIndexChanged(int)'), self.selectStack, + QtCore.SLOT(u'setCurrentIndex(int)')) + + def customInit(self): + """ + Perform any custom initialisation for bible importing. + """ if BibleFormat.get_availability(BibleFormat.OpenLP1): self.openlp1DisabledLabel.hide() else: self.openlp1FileLabel.hide() self.openlp1FileEdit.hide() self.openlp1BrowseButton.hide() - self.finishButton = self.button(QtGui.QWizard.FinishButton) - self.cancelButton = self.button(QtGui.QWizard.CancelButton) - self.manager = manager - self.bibleplugin = bibleplugin self.manager.set_process_dialog(self) - self.web_bible_list = {} self.loadWebBibles() self.restart() self.selectStack.setCurrentIndex(0) + + def customSignals(self): + """ + Set up the signals used in the bible importer. + """ QtCore.QObject.connect(self.webSourceComboBox, QtCore.SIGNAL(u'currentIndexChanged(int)'), - self.onWebSourceComboBoxCurrentIndexChanged) + self.onWebSourceComboBoxIndexChanged) QtCore.QObject.connect(self.osisBrowseButton, QtCore.SIGNAL(u'clicked()'), self.onOsisBrowseButtonClicked) @@ -112,25 +135,329 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard): QtCore.QObject.connect(self.openlp1BrowseButton, QtCore.SIGNAL(u'clicked()'), self.onOpenlp1BrowseButtonClicked) - QtCore.QObject.connect(self, - QtCore.SIGNAL(u'currentIdChanged(int)'), - self.onCurrentIdChanged) - def exec_(self): + def addCustomPages(self): """ - Run the wizard. + Add the bible import specific wizard pages. """ - self.setDefaults() - return QtGui.QWizard.exec_(self) + # Select Page + self.selectPage = QtGui.QWizardPage() + self.selectPage.setObjectName(u'SelectPage') + self.selectPageLayout = QtGui.QVBoxLayout(self.selectPage) + self.selectPageLayout.setObjectName(u'SelectPageLayout') + self.formatLayout = QtGui.QFormLayout() + self.formatLayout.setObjectName(u'FormatLayout') + self.formatLabel = QtGui.QLabel(self.selectPage) + self.formatLabel.setObjectName(u'FormatLabel') + self.formatComboBox = QtGui.QComboBox(self.selectPage) + self.formatComboBox.addItems([u'', u'', u'', u'', u'']) + self.formatComboBox.setObjectName(u'FormatComboBox') + self.formatLayout.addRow(self.formatLabel, self.formatComboBox) + self.formatSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, + QtGui.QSizePolicy.Minimum) + self.formatLayout.setItem(1, QtGui.QFormLayout.LabelRole, + self.formatSpacer) + self.selectPageLayout.addLayout(self.formatLayout) + self.selectStack = QtGui.QStackedLayout() + self.selectStack.setObjectName(u'SelectStack') + self.osisWidget = QtGui.QWidget(self.selectPage) + self.osisWidget.setObjectName(u'OsisWidget') + self.osisLayout = QtGui.QFormLayout(self.osisWidget) + self.osisLayout.setMargin(0) + self.osisLayout.setObjectName(u'OsisLayout') + self.osisFileLabel = QtGui.QLabel(self.osisWidget) + self.osisFileLabel.setObjectName(u'OsisFileLabel') + self.osisFileLayout = QtGui.QHBoxLayout() + self.osisFileLayout.setObjectName(u'OsisFileLayout') + self.osisFileEdit = QtGui.QLineEdit(self.osisWidget) + self.osisFileEdit.setObjectName(u'OsisFileEdit') + self.osisFileLayout.addWidget(self.osisFileEdit) + self.osisBrowseButton = QtGui.QToolButton(self.osisWidget) + self.osisBrowseButton.setIcon(self.openIcon) + self.osisBrowseButton.setObjectName(u'OsisBrowseButton') + self.osisFileLayout.addWidget(self.osisBrowseButton) + self.osisLayout.addRow(self.osisFileLabel, self.osisFileLayout) + self.osisSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, + QtGui.QSizePolicy.Minimum) + self.osisLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.osisSpacer) + self.selectStack.addWidget(self.osisWidget) + self.csvWidget = QtGui.QWidget(self.selectPage) + self.csvWidget.setObjectName(u'CsvWidget') + self.csvLayout = QtGui.QFormLayout(self.csvWidget) + self.csvLayout.setMargin(0) + self.csvLayout.setObjectName(u'CsvLayout') + self.csvBooksLabel = QtGui.QLabel(self.csvWidget) + self.csvBooksLabel.setObjectName(u'CsvBooksLabel') + self.csvBooksLayout = QtGui.QHBoxLayout() + self.csvBooksLayout.setObjectName(u'CsvBooksLayout') + self.csvBooksEdit = QtGui.QLineEdit(self.csvWidget) + self.csvBooksEdit.setObjectName(u'CsvBooksEdit') + self.csvBooksLayout.addWidget(self.csvBooksEdit) + self.csvBooksButton = QtGui.QToolButton(self.csvWidget) + self.csvBooksButton.setIcon(self.openIcon) + self.csvBooksButton.setObjectName(u'CsvBooksButton') + self.csvBooksLayout.addWidget(self.csvBooksButton) + self.csvLayout.addRow(self.csvBooksLabel, self.csvBooksLayout) + self.csvVersesLabel = QtGui.QLabel(self.csvWidget) + self.csvVersesLabel.setObjectName(u'CsvVersesLabel') + self.csvVersesLayout = QtGui.QHBoxLayout() + self.csvVersesLayout.setObjectName(u'CsvVersesLayout') + self.csvVersesEdit = QtGui.QLineEdit(self.csvWidget) + self.csvVersesEdit.setObjectName(u'CsvVersesEdit') + self.csvVersesLayout.addWidget(self.csvVersesEdit) + self.csvVersesButton = QtGui.QToolButton(self.csvWidget) + self.csvVersesButton.setIcon(self.openIcon) + self.csvVersesButton.setObjectName(u'CsvVersesButton') + self.csvVersesLayout.addWidget(self.csvVersesButton) + self.csvLayout.addRow(self.csvVersesLabel, self.csvVersesLayout) + self.csvSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, + QtGui.QSizePolicy.Minimum) + self.csvLayout.setItem(2, QtGui.QFormLayout.LabelRole, self.csvSpacer) + self.selectStack.addWidget(self.csvWidget) + self.openSongWidget = QtGui.QWidget(self.selectPage) + self.openSongWidget.setObjectName(u'OpenSongWidget') + self.openSongLayout = QtGui.QFormLayout(self.openSongWidget) + self.openSongLayout.setMargin(0) + self.openSongLayout.setObjectName(u'OpenSongLayout') + self.openSongFileLabel = QtGui.QLabel(self.openSongWidget) + self.openSongFileLabel.setObjectName(u'OpenSongFileLabel') + self.openSongFileLayout = QtGui.QHBoxLayout() + self.openSongFileLayout.setObjectName(u'OpenSongFileLayout') + self.openSongFileEdit = QtGui.QLineEdit(self.openSongWidget) + self.openSongFileEdit.setObjectName(u'OpenSongFileEdit') + self.openSongFileLayout.addWidget(self.openSongFileEdit) + self.openSongBrowseButton = QtGui.QToolButton(self.openSongWidget) + self.openSongBrowseButton.setIcon(self.openIcon) + self.openSongBrowseButton.setObjectName(u'OpenSongBrowseButton') + self.openSongFileLayout.addWidget(self.openSongBrowseButton) + self.openSongLayout.addRow(self.openSongFileLabel, + self.openSongFileLayout) + self.openSongSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, + QtGui.QSizePolicy.Minimum) + self.openSongLayout.setItem(1, QtGui.QFormLayout.LabelRole, + self.openSongSpacer) + self.selectStack.addWidget(self.openSongWidget) + self.webTabWidget = QtGui.QTabWidget(self.selectPage) + self.webTabWidget.setObjectName(u'WebTabWidget') + self.webBibleTab = QtGui.QWidget() + self.webBibleTab.setObjectName(u'WebBibleTab') + self.webBibleLayout = QtGui.QFormLayout(self.webBibleTab) + self.webBibleLayout.setObjectName(u'WebBibleLayout') + self.webSourceLabel = QtGui.QLabel(self.webBibleTab) + self.webSourceLabel.setObjectName(u'WebSourceLabel') + self.webBibleLayout.setWidget(0, QtGui.QFormLayout.LabelRole, + self.webSourceLabel) + self.webSourceComboBox = QtGui.QComboBox(self.webBibleTab) + self.webSourceComboBox.setObjectName(u'WebSourceComboBox') + self.webSourceComboBox.addItems([u'', u'', u'']) + self.webBibleLayout.setWidget(0, QtGui.QFormLayout.FieldRole, + self.webSourceComboBox) + self.webTranslationLabel = QtGui.QLabel(self.webBibleTab) + self.webTranslationLabel.setObjectName(u'webTranslationLabel') + self.webBibleLayout.setWidget(1, QtGui.QFormLayout.LabelRole, + self.webTranslationLabel) + self.webTranslationComboBox = QtGui.QComboBox(self.webBibleTab) + self.webTranslationComboBox.setSizeAdjustPolicy( + QtGui.QComboBox.AdjustToContents) + self.webTranslationComboBox.setObjectName(u'WebTranslationComboBox') + self.webBibleLayout.setWidget(1, QtGui.QFormLayout.FieldRole, + self.webTranslationComboBox) + self.webTabWidget.addTab(self.webBibleTab, u'') + self.webProxyTab = QtGui.QWidget() + self.webProxyTab.setObjectName(u'WebProxyTab') + self.webProxyLayout = QtGui.QFormLayout(self.webProxyTab) + self.webProxyLayout.setObjectName(u'WebProxyLayout') + self.webServerLabel = QtGui.QLabel(self.webProxyTab) + self.webServerLabel.setObjectName(u'WebServerLabel') + self.webProxyLayout.setWidget(0, QtGui.QFormLayout.LabelRole, + self.webServerLabel) + self.webServerEdit = QtGui.QLineEdit(self.webProxyTab) + self.webServerEdit.setObjectName(u'WebServerEdit') + self.webProxyLayout.setWidget(0, QtGui.QFormLayout.FieldRole, + self.webServerEdit) + self.webUserLabel = QtGui.QLabel(self.webProxyTab) + self.webUserLabel.setObjectName(u'WebUserLabel') + self.webProxyLayout.setWidget(1, QtGui.QFormLayout.LabelRole, + self.webUserLabel) + self.webUserEdit = QtGui.QLineEdit(self.webProxyTab) + self.webUserEdit.setObjectName(u'WebUserEdit') + self.webProxyLayout.setWidget(1, QtGui.QFormLayout.FieldRole, + self.webUserEdit) + self.webPasswordLabel = QtGui.QLabel(self.webProxyTab) + self.webPasswordLabel.setObjectName(u'WebPasswordLabel') + self.webProxyLayout.setWidget(2, QtGui.QFormLayout.LabelRole, + self.webPasswordLabel) + self.webPasswordEdit = QtGui.QLineEdit(self.webProxyTab) + self.webPasswordEdit.setObjectName(u'WebPasswordEdit') + self.webProxyLayout.setWidget(2, QtGui.QFormLayout.FieldRole, + self.webPasswordEdit) + self.webTabWidget.addTab(self.webProxyTab, u'') + self.selectStack.addWidget(self.webTabWidget) + self.openlp1Widget = QtGui.QWidget(self.selectPage) + self.openlp1Widget.setObjectName(u'Openlp1Widget') + self.openlp1Layout = QtGui.QFormLayout(self.openlp1Widget) + self.openlp1Layout.setMargin(0) + self.openlp1Layout.setObjectName(u'Openlp1Layout') + self.openlp1FileLabel = QtGui.QLabel(self.openlp1Widget) + self.openlp1FileLabel.setObjectName(u'Openlp1FileLabel') + self.openlp1FileLayout = QtGui.QHBoxLayout() + self.openlp1FileLayout.setObjectName(u'Openlp1FileLayout') + self.openlp1FileEdit = QtGui.QLineEdit(self.openlp1Widget) + self.openlp1FileEdit.setObjectName(u'Openlp1FileEdit') + self.openlp1FileLayout.addWidget(self.openlp1FileEdit) + self.openlp1BrowseButton = QtGui.QToolButton(self.openlp1Widget) + self.openlp1BrowseButton.setIcon(self.openIcon) + self.openlp1BrowseButton.setObjectName(u'Openlp1BrowseButton') + self.openlp1FileLayout.addWidget(self.openlp1BrowseButton) + self.openlp1Layout.addRow(self.openlp1FileLabel, self.openlp1FileLayout) + self.openlp1DisabledLabel = QtGui.QLabel(self.openlp1Widget) + self.openlp1DisabledLabel.setWordWrap(True) + self.openlp1DisabledLabel.setObjectName(u'Openlp1DisabledLabel') + self.openlp1Layout.addRow(self.openlp1DisabledLabel) + self.openlp1Spacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, + QtGui.QSizePolicy.Minimum) + self.openlp1Layout.setItem(1, QtGui.QFormLayout.LabelRole, + self.openlp1Spacer) + self.selectStack.addWidget(self.openlp1Widget) + self.selectPageLayout.addLayout(self.selectStack) + self.addPage(self.selectPage) + # License Page + self.licenseDetailsPage = QtGui.QWizardPage() + self.licenseDetailsPage.setObjectName(u'LicenseDetailsPage') + self.licenseDetailsLayout = QtGui.QFormLayout(self.licenseDetailsPage) + self.licenseDetailsLayout.setObjectName(u'LicenseDetailsLayout') + self.versionNameLabel = QtGui.QLabel(self.licenseDetailsPage) + self.versionNameLabel.setObjectName(u'VersionNameLabel') + self.licenseDetailsLayout.setWidget(0, QtGui.QFormLayout.LabelRole, + self.versionNameLabel) + self.versionNameEdit = QtGui.QLineEdit(self.licenseDetailsPage) + self.versionNameEdit.setObjectName(u'VersionNameEdit') + self.licenseDetailsLayout.setWidget(0, QtGui.QFormLayout.FieldRole, + self.versionNameEdit) + self.copyrightLabel = QtGui.QLabel(self.licenseDetailsPage) + self.copyrightLabel.setObjectName(u'CopyrightLabel') + self.licenseDetailsLayout.setWidget(1, QtGui.QFormLayout.LabelRole, + self.copyrightLabel) + self.copyrightEdit = QtGui.QLineEdit(self.licenseDetailsPage) + self.copyrightEdit.setObjectName(u'CopyrightEdit') + self.licenseDetailsLayout.setWidget(1, QtGui.QFormLayout.FieldRole, + self.copyrightEdit) + self.permissionsLabel = QtGui.QLabel(self.licenseDetailsPage) + self.permissionsLabel.setObjectName(u'PermissionsLabel') + self.licenseDetailsLayout.setWidget(2, QtGui.QFormLayout.LabelRole, + self.permissionsLabel) + self.permissionsEdit = QtGui.QLineEdit(self.licenseDetailsPage) + self.permissionsEdit.setObjectName(u'PermissionsEdit') + self.licenseDetailsLayout.setWidget(2, QtGui.QFormLayout.FieldRole, + self.permissionsEdit) + self.addPage(self.licenseDetailsPage) - def reject(self): + def retranslateUi(self): """ - Stop the import on cancel button, close button or ESC key. + Allow for localisation of the bible import wizard. """ - log.debug(u'Import canceled by user.') - if self.currentPage() == self.importPage: - Receiver.send_message(u'bibles_stop_import') - self.done(QtGui.QDialog.Rejected) + self.setWindowTitle( + translate('BiblesPlugin.ImportWizardForm', 'Bible Import Wizard')) + self.titleLabel.setText( + u'%s' % \ + translate('BiblesPlugin.ImportWizardForm', + 'Welcome to the Bible Import Wizard')) + self.informationLabel.setText( + translate('BiblesPlugin.ImportWizardForm', + 'This wizard will help you to import Bibles from a ' + 'variety of formats. Click the next button below to start the ' + 'process by selecting a format to import from.')) + self.selectPage.setTitle(translate('BiblesPlugin.ImportWizardForm', + 'Select Import Source')) + self.selectPage.setSubTitle( + translate('BiblesPlugin.ImportWizardForm', + 'Select the import format, and where to import from.')) + self.formatLabel.setText( + translate('BiblesPlugin.ImportWizardForm', 'Format:')) + self.formatComboBox.setItemText(0, + translate('BiblesPlugin.ImportWizardForm', 'OSIS')) + self.formatComboBox.setItemText(1, + translate('BiblesPlugin.ImportWizardForm', 'CSV')) + self.formatComboBox.setItemText(2, + translate('BiblesPlugin.ImportWizardForm', 'OpenSong')) + self.formatComboBox.setItemText(3, + translate('BiblesPlugin.ImportWizardForm', 'Web Download')) + self.formatComboBox.setItemText(4, + translate('BiblesPlugin.ImportWizardForm', 'openlp.org 1.x')) + self.openlp1FileLabel.setText( + translate('BiblesPlugin.ImportWizardForm', 'File location:')) + self.osisFileLabel.setText( + translate('BiblesPlugin.ImportWizardForm', 'File location:')) + self.csvBooksLabel.setText( + translate('BiblesPlugin.ImportWizardForm', 'Books location:')) + self.csvVersesLabel.setText( + translate('BiblesPlugin.ImportWizardForm', 'Verse location:')) + self.openSongFileLabel.setText( + translate('BiblesPlugin.ImportWizardForm', 'Bible filename:')) + self.webSourceLabel.setText( + translate('BiblesPlugin.ImportWizardForm', 'Location:')) + self.webSourceComboBox.setItemText(0, + translate('BiblesPlugin.ImportWizardForm', 'Crosswalk')) + self.webSourceComboBox.setItemText(1, + translate('BiblesPlugin.ImportWizardForm', 'BibleGateway')) + self.webSourceComboBox.setItemText(2, + translate('BiblesPlugin.ImportWizardForm', 'Bibleserver')) + self.webTranslationLabel.setText( + translate('BiblesPlugin.ImportWizardForm', 'Bible:')) + self.webTabWidget.setTabText( + self.webTabWidget.indexOf(self.webBibleTab), + translate('BiblesPlugin.ImportWizardForm', 'Download Options')) + self.webServerLabel.setText( + translate('BiblesPlugin.ImportWizardForm', 'Server:')) + self.webUserLabel.setText( + translate('BiblesPlugin.ImportWizardForm', 'Username:')) + self.webPasswordLabel.setText( + translate('BiblesPlugin.ImportWizardForm', 'Password:')) + self.webTabWidget.setTabText( + self.webTabWidget.indexOf(self.webProxyTab), + translate('BiblesPlugin.ImportWizardForm', + 'Proxy Server (Optional)')) + self.licenseDetailsPage.setTitle( + translate('BiblesPlugin.ImportWizardForm', 'License Details')) + self.licenseDetailsPage.setSubTitle( + translate('BiblesPlugin.ImportWizardForm', + 'Set up the Bible\'s license details.')) + self.versionNameLabel.setText( + translate('BiblesPlugin.ImportWizardForm', 'Version name:')) + self.copyrightLabel.setText( + translate('BiblesPlugin.ImportWizardForm', 'Copyright:')) + self.permissionsLabel.setText( + translate('BiblesPlugin.ImportWizardForm', 'Permissions:')) + self.progressPage.setTitle( + translate('BiblesPlugin.ImportWizardForm', 'Importing')) + self.progressPage.setSubTitle( + translate('BiblesPlugin.ImportWizardForm', + 'Please wait while your Bible is imported.')) + self.progressLabel.setText( + translate('BiblesPlugin.ImportWizardForm', 'Ready.')) + self.progressBar.setFormat(u'%p%') + self.openlp1DisabledLabel.setText( + translate('BiblesPlugin.ImportWizardForm', 'The openlp.org 1.x ' + 'importer has been disabled due to a missing Python module. If ' + 'you want to use this importer, you will need to install the ' + '"python-sqlite" module.')) + # Align all QFormLayouts towards each other. + labelWidth = max(self.formatLabel.minimumSizeHint().width(), + self.osisFileLabel.minimumSizeHint().width(), + self.csvBooksLabel.minimumSizeHint().width(), + self.csvVersesLabel.minimumSizeHint().width(), + self.openSongFileLabel.minimumSizeHint().width(), + self.openlp1FileLabel.minimumSizeHint().width()) + self.formatSpacer.changeSize(labelWidth, 0, + QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + self.osisSpacer.changeSize(labelWidth, 0, + QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + self.csvSpacer.changeSize(labelWidth, 0, + QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + self.openSongSpacer.changeSize(labelWidth, 0, + QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + self.openlp1Spacer.changeSize(labelWidth, 0, + QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) def validateCurrentPage(self): """ @@ -220,10 +547,10 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard): self.versionNameEdit.setFocus() return False return True - if self.currentPage() == self.importPage: + if self.currentPage() == self.progressPage: return True - def onWebSourceComboBoxCurrentIndexChanged(self, index): + def onWebSourceComboBoxIndexChanged(self, index): """ Setup the list of Bibles when you select a different source on the web download page. @@ -279,13 +606,10 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard): u'%s (*.bible)' % translate('BiblesPlugin.ImportWizardForm', 'openlp.org 1.x bible')) - def onCurrentIdChanged(self, pageId): - if self.page(pageId) == self.importPage: - self.preImport() - self.performImport() - self.postImport() - def registerFields(self): + """ + Register the bible import wizard fields. + """ self.selectPage.registerField(u'source_format', self.formatComboBox) self.selectPage.registerField(u'osis_location', self.osisFileEdit) self.selectPage.registerField(u'csv_booksfile', self.csvBooksEdit) @@ -306,8 +630,11 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard): u'license_permissions', self.permissionsEdit) def setDefaults(self): + """ + Set default values for the wizard pages. + """ settings = QtCore.QSettings() - settings.beginGroup(self.bibleplugin.settingsSection) + settings.beginGroup(self.plugin.settingsSection) self.restart() self.finishButton.setVisible(False) self.cancelButton.setVisible(True) @@ -332,72 +659,50 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard): QtCore.QVariant(self.copyrightEdit.text())) self.setField(u'license_permissions', QtCore.QVariant(self.permissionsEdit.text())) - self.onWebSourceComboBoxCurrentIndexChanged(WebDownload.Crosswalk) + self.onWebSourceComboBoxIndexChanged(WebDownload.Crosswalk) settings.endGroup() def loadWebBibles(self): """ - Load the list of Crosswalk and BibleGateway bibles. + Load the lists of Crosswalk, BibleGateway and Bibleserver bibles. """ + filepath = AppLocation.get_directory(AppLocation.PluginsDir) + filepath = os.path.join(filepath, u'bibles', u'resources') # Load Crosswalk Bibles. - filepath = AppLocation.get_directory(AppLocation.PluginsDir) - filepath = os.path.join(filepath, u'bibles', u'resources') - books_file = None - try: - self.web_bible_list[WebDownload.Crosswalk] = {} - books_file = open( - os.path.join(filepath, u'crosswalkbooks.csv'), 'rb') - dialect = csv.Sniffer().sniff(books_file.read(1024)) - books_file.seek(0) - books_reader = csv.reader(books_file, dialect) - for line in books_reader: - ver = unicode(line[0], u'utf-8') - name = unicode(line[1], u'utf-8') - self.web_bible_list[WebDownload.Crosswalk][ver] = name.strip() - except IOError: - log.exception(u'Crosswalk resources missing') - finally: - if books_file: - books_file.close() + self.loadBibleResourceFile( + os.path.join(filepath, u'crosswalkbooks.csv'), + WebDownload.Crosswalk) # Load BibleGateway Bibles. - books_file = None - try: - self.web_bible_list[WebDownload.BibleGateway] = {} - books_file = open(os.path.join(filepath, u'biblegateway.csv'), 'r') - dialect = csv.Sniffer().sniff(books_file.read(1024)) - books_file.seek(0) - books_reader = csv.reader(books_file, dialect) - for line in books_reader: - ver = line[0] - name = line[1] - if not isinstance(ver, unicode): - ver = unicode(ver, u'utf8') - if not isinstance(name, unicode): - name = unicode(name, u'utf8') - self.web_bible_list[WebDownload.BibleGateway][ver] = \ - name.strip() - except IOError: - log.exception(u'Biblegateway resources missing') - finally: - if books_file: - books_file.close() + self.loadBibleResourceFile(os.path.join(filepath, u'biblegateway.csv'), + WebDownload.BibleGateway) # Load and Bibleserver Bibles. - filepath = AppLocation.get_directory(AppLocation.PluginsDir) - filepath = os.path.join(filepath, u'bibles', u'resources') + self.loadBibleResourceFile(os.path.join(filepath, u'bibleserver.csv'), + WebDownload.Bibleserver) + + def loadBibleResourceFile(self, file_path_name, download_type): + """ + Loads a web bible resource file. + + ``file_path_name`` + The file to load including the file's path. + + ``download_type`` + The WebDownload type this file is for. + """ + self.web_bible_list[download_type] = {} books_file = None try: - self.web_bible_list[WebDownload.Bibleserver] = {} - books_file = open( - os.path.join(filepath, u'bibleserver.csv'), 'rb') + books_file = open(file_path_name, 'rb') dialect = csv.Sniffer().sniff(books_file.read(1024)) books_file.seek(0) books_reader = csv.reader(books_file, dialect) for line in books_reader: - ver = unicode(line[0], u'utf-8') - name = unicode(line[1], u'utf-8') - self.web_bible_list[WebDownload.Bibleserver][ver] = name.strip() - except IOError, UnicodeError: - log.exception(u'Bibleserver resources missing') + ver = string_is_unicode(line[0]) + name = string_is_unicode(line[1]) + self.web_bible_list[download_type][ver] = name.strip() + except IOError: + log.exception(u'%s resources missing' % + WebDownload.get_name(download_type)) finally: if books_file: books_file.close() @@ -413,8 +718,8 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard): A editbox (QLineEdit). ``filters`` - The file extension filters. It should contain the file description as - well as the file extension. For example:: + The file extension filters. It should contain the file description + as well as the file extension. For example:: u'openlp.org 1.x bible (*.bible)' """ @@ -424,37 +729,28 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard): 'All Files') filename = QtGui.QFileDialog.getOpenFileName(self, title, os.path.dirname(SettingsManager.get_last_dir( - self.bibleplugin.settingsSection, 1)), filters) + self.plugin.settingsSection, 1)), filters) if filename: editbox.setText(filename) SettingsManager.set_last_dir( - self.bibleplugin.settingsSection, filename, 1) + self.plugin.settingsSection, filename, 1) - def incrementProgressBar(self, status_text): - log.debug(u'IncrementBar %s', status_text) - self.importProgressLabel.setText(status_text) - self.importProgressBar.setValue(self.importProgressBar.value() + 1) - Receiver.send_message(u'openlp_process_events') - - def preImport(self): + def preWizard(self): """ Prepare the UI for the import. """ + OpenLPWizard.preWizard(self) bible_type = self.field(u'source_format').toInt()[0] - self.finishButton.setVisible(False) - self.importProgressBar.setMinimum(0) - self.importProgressBar.setMaximum(1188) - self.importProgressBar.setValue(0) if bible_type == BibleFormat.WebDownload: - self.importProgressLabel.setText(translate( + self.progressLabel.setText(translate( 'BiblesPlugin.ImportWizardForm', 'Starting Registering bible...')) else: - self.importProgressLabel.setText(translate( + self.progressLabel.setText(translate( 'BiblesPlugin.ImportWizardForm', 'Starting import...')) Receiver.send_message(u'openlp_process_events') - def performImport(self): + def performWizard(self): """ Perform the actual import. """ @@ -485,7 +781,7 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard): ) elif bible_type == BibleFormat.WebDownload: # Import a bible from the web. - self.importProgressBar.setMaximum(1) + self.progressBar.setMaximum(1) download_location = self.field(u'web_location').toInt()[0] bible_version = unicode(self.webTranslationComboBox.currentText()) if download_location == WebDownload.Crosswalk: @@ -518,20 +814,14 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard): license_copyright, license_permissions) self.manager.reload_bibles() if bible_type == BibleFormat.WebDownload: - self.importProgressLabel.setText( + self.progressLabel.setText( translate('BiblesPlugin.ImportWizardForm', 'Registered ' 'bible. Please note, that verses will be downloaded on\n' 'demand and thus an internet connection is required.')) else: - self.importProgressLabel.setText(translate( + self.progressLabel.setText(translate( 'BiblesPlugin.ImportWizardForm', 'Finished import.')) else: - self.importProgressLabel.setText(translate( + self.progressLabel.setText(translate( 'BiblesPlugin.ImportWizardForm', 'Your Bible import failed.')) - delete_database(self.bibleplugin.settingsSection, importer.file) - - def postImport(self): - self.importProgressBar.setValue(self.importProgressBar.maximum()) - self.finishButton.setVisible(True) - self.cancelButton.setVisible(False) - Receiver.send_message(u'openlp_process_events') + delete_database(self.plugin.settingsSection, importer.file) diff --git a/openlp/plugins/bibles/forms/bibleimportwizard.py b/openlp/plugins/bibles/forms/bibleimportwizard.py deleted file mode 100644 index c6a6775a5..000000000 --- a/openlp/plugins/bibles/forms/bibleimportwizard.py +++ /dev/null @@ -1,391 +0,0 @@ -# -*- coding: utf-8 -*- -# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 - -############################################################################### -# OpenLP - Open Source Lyrics Projection # -# --------------------------------------------------------------------------- # -# Copyright (c) 2008-2011 Raoul Snyman # -# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael # -# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian # -# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, # -# Carsten Tinggaard, Frode Woldsund # -# --------------------------------------------------------------------------- # -# This program is free software; you can redistribute it and/or modify it # -# under the terms of the GNU General Public License as published by the Free # -# Software Foundation; version 2 of the License. # -# # -# This program is distributed in the hope that it will be useful, but WITHOUT # -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # -# more details. # -# # -# You should have received a copy of the GNU General Public License along # -# with this program; if not, write to the Free Software Foundation, Inc., 59 # -# Temple Place, Suite 330, Boston, MA 02111-1307 USA # -############################################################################### - -from PyQt4 import QtCore, QtGui - -from openlp.core.lib import build_icon, translate - -class Ui_BibleImportWizard(object): - def setupUi(self, bibleImportWizard): - bibleImportWizard.setObjectName(u'bibleImportWizard') - bibleImportWizard.setModal(True) - bibleImportWizard.setWizardStyle(QtGui.QWizard.ModernStyle) - bibleImportWizard.setOptions( - QtGui.QWizard.IndependentPages | - QtGui.QWizard.NoBackButtonOnStartPage | - QtGui.QWizard.NoBackButtonOnLastPage) - # Welcome Page - self.welcomePage = QtGui.QWizardPage() - self.welcomePage.setPixmap(QtGui.QWizard.WatermarkPixmap, - QtGui.QPixmap(u':/wizards/wizard_importbible.bmp')) - self.welcomePage.setObjectName(u'WelcomePage') - self.welcomeLayout = QtGui.QVBoxLayout(self.welcomePage) - self.welcomeLayout.setObjectName(u'WelcomeLayout') - self.titleLabel = QtGui.QLabel(self.welcomePage) - self.titleLabel.setObjectName(u'TitleLabel') - self.welcomeLayout.addWidget(self.titleLabel) - self.welcomeLayout.addSpacing(40) - self.informationLabel = QtGui.QLabel(self.welcomePage) - self.informationLabel.setWordWrap(True) - self.informationLabel.setObjectName(u'InformationLabel') - self.welcomeLayout.addWidget(self.informationLabel) - self.welcomeLayout.addStretch() - bibleImportWizard.addPage(self.welcomePage) - # Select Page - self.selectPage = QtGui.QWizardPage() - self.selectPage.setObjectName(u'SelectPage') - self.selectPageLayout = QtGui.QVBoxLayout(self.selectPage) - self.selectPageLayout.setObjectName(u'SelectPageLayout') - self.formatLayout = QtGui.QFormLayout() - self.formatLayout.setObjectName(u'FormatLayout') - self.formatLabel = QtGui.QLabel(self.selectPage) - self.formatLabel.setObjectName(u'FormatLabel') - self.formatComboBox = QtGui.QComboBox(self.selectPage) - self.formatComboBox.addItems([u'', u'', u'', u'', u'']) - self.formatComboBox.setObjectName(u'FormatComboBox') - self.formatLayout.addRow(self.formatLabel, self.formatComboBox) - self.formatSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Minimum) - self.formatLayout.setItem(1, QtGui.QFormLayout.LabelRole, - self.formatSpacer) - self.selectPageLayout.addLayout(self.formatLayout) - self.selectStack = QtGui.QStackedLayout() - self.selectStack.setObjectName(u'SelectStack') - self.osisWidget = QtGui.QWidget(self.selectPage) - self.osisWidget.setObjectName(u'OsisWidget') - self.osisLayout = QtGui.QFormLayout(self.osisWidget) - self.osisLayout.setMargin(0) - self.osisLayout.setObjectName(u'OsisLayout') - self.osisFileLabel = QtGui.QLabel(self.osisWidget) - self.osisFileLabel.setObjectName(u'OsisFileLabel') - self.osisFileLayout = QtGui.QHBoxLayout() - self.osisFileLayout.setObjectName(u'OsisFileLayout') - self.osisFileEdit = QtGui.QLineEdit(self.osisWidget) - self.osisFileEdit.setObjectName(u'OsisFileEdit') - self.osisFileLayout.addWidget(self.osisFileEdit) - self.osisBrowseButton = QtGui.QToolButton(self.osisWidget) - self.osisBrowseButton.setIcon(build_icon(u':/general/general_open.png')) - self.osisBrowseButton.setObjectName(u'OsisBrowseButton') - self.osisFileLayout.addWidget(self.osisBrowseButton) - self.osisLayout.addRow(self.osisFileLabel, self.osisFileLayout) - self.osisSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Minimum) - self.osisLayout.setItem(1, QtGui.QFormLayout.LabelRole, self.osisSpacer) - self.selectStack.addWidget(self.osisWidget) - self.csvWidget = QtGui.QWidget(self.selectPage) - self.csvWidget.setObjectName(u'CsvWidget') - self.csvLayout = QtGui.QFormLayout(self.csvWidget) - self.csvLayout.setMargin(0) - self.csvLayout.setObjectName(u'CsvLayout') - self.csvBooksLabel = QtGui.QLabel(self.csvWidget) - self.csvBooksLabel.setObjectName(u'CsvBooksLabel') - self.csvBooksLayout = QtGui.QHBoxLayout() - self.csvBooksLayout.setObjectName(u'CsvBooksLayout') - self.csvBooksEdit = QtGui.QLineEdit(self.csvWidget) - self.csvBooksEdit.setObjectName(u'CsvBooksEdit') - self.csvBooksLayout.addWidget(self.csvBooksEdit) - self.csvBooksButton = QtGui.QToolButton(self.csvWidget) - self.csvBooksButton.setIcon(build_icon(u':/general/general_open.png')) - self.csvBooksButton.setObjectName(u'CsvBooksButton') - self.csvBooksLayout.addWidget(self.csvBooksButton) - self.csvLayout.addRow(self.csvBooksLabel, self.csvBooksLayout) - self.csvVersesLabel = QtGui.QLabel(self.csvWidget) - self.csvVersesLabel.setObjectName(u'CsvVersesLabel') - self.csvVersesLayout = QtGui.QHBoxLayout() - self.csvVersesLayout.setObjectName(u'CsvVersesLayout') - self.csvVersesEdit = QtGui.QLineEdit(self.csvWidget) - self.csvVersesEdit.setObjectName(u'CsvVersesEdit') - self.csvVersesLayout.addWidget(self.csvVersesEdit) - self.csvVersesButton = QtGui.QToolButton(self.csvWidget) - self.csvVersesButton.setIcon(build_icon(u':/general/general_open.png')) - self.csvVersesButton.setObjectName(u'CsvVersesButton') - self.csvVersesLayout.addWidget(self.csvVersesButton) - self.csvLayout.addRow(self.csvVersesLabel, self.csvVersesLayout) - self.csvSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Minimum) - self.csvLayout.setItem(2, QtGui.QFormLayout.LabelRole, self.csvSpacer) - self.selectStack.addWidget(self.csvWidget) - self.openSongWidget = QtGui.QWidget(self.selectPage) - self.openSongWidget.setObjectName(u'OpenSongWidget') - self.openSongLayout = QtGui.QFormLayout(self.openSongWidget) - self.openSongLayout.setMargin(0) - self.openSongLayout.setObjectName(u'OpenSongLayout') - self.openSongFileLabel = QtGui.QLabel(self.openSongWidget) - self.openSongFileLabel.setObjectName(u'OpenSongFileLabel') - self.openSongFileLayout = QtGui.QHBoxLayout() - self.openSongFileLayout.setObjectName(u'OpenSongFileLayout') - self.openSongFileEdit = QtGui.QLineEdit(self.openSongWidget) - self.openSongFileEdit.setObjectName(u'OpenSongFileEdit') - self.openSongFileLayout.addWidget(self.openSongFileEdit) - self.openSongBrowseButton = QtGui.QToolButton(self.openSongWidget) - self.openSongBrowseButton.setIcon( - build_icon(u':/general/general_open.png')) - self.openSongBrowseButton.setObjectName(u'OpenSongBrowseButton') - self.openSongFileLayout.addWidget(self.openSongBrowseButton) - self.openSongLayout.addRow(self.openSongFileLabel, - self.openSongFileLayout) - self.openSongSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Minimum) - self.openSongLayout.setItem(1, QtGui.QFormLayout.LabelRole, - self.openSongSpacer) - self.selectStack.addWidget(self.openSongWidget) - self.webTabWidget = QtGui.QTabWidget(self.selectPage) - self.webTabWidget.setObjectName(u'WebTabWidget') - self.webBibleTab = QtGui.QWidget() - self.webBibleTab.setObjectName(u'WebBibleTab') - self.webBibleLayout = QtGui.QFormLayout(self.webBibleTab) - self.webBibleLayout.setObjectName(u'WebBibleLayout') - self.webSourceLabel = QtGui.QLabel(self.webBibleTab) - self.webSourceLabel.setObjectName(u'WebSourceLabel') - self.webBibleLayout.setWidget(0, QtGui.QFormLayout.LabelRole, - self.webSourceLabel) - self.webSourceComboBox = QtGui.QComboBox(self.webBibleTab) - self.webSourceComboBox.setObjectName(u'WebSourceComboBox') - self.webSourceComboBox.addItems([u'', u'', u'']) - self.webBibleLayout.setWidget(0, QtGui.QFormLayout.FieldRole, - self.webSourceComboBox) - self.webTranslationLabel = QtGui.QLabel(self.webBibleTab) - self.webTranslationLabel.setObjectName(u'webTranslationLabel') - self.webBibleLayout.setWidget(1, QtGui.QFormLayout.LabelRole, - self.webTranslationLabel) - self.webTranslationComboBox = QtGui.QComboBox(self.webBibleTab) - self.webTranslationComboBox.setSizeAdjustPolicy( - QtGui.QComboBox.AdjustToContents) - self.webTranslationComboBox.setObjectName(u'WebTranslationComboBox') - self.webBibleLayout.setWidget(1, QtGui.QFormLayout.FieldRole, - self.webTranslationComboBox) - self.webTabWidget.addTab(self.webBibleTab, u'') - self.webProxyTab = QtGui.QWidget() - self.webProxyTab.setObjectName(u'WebProxyTab') - self.webProxyLayout = QtGui.QFormLayout(self.webProxyTab) - self.webProxyLayout.setObjectName(u'WebProxyLayout') - self.webServerLabel = QtGui.QLabel(self.webProxyTab) - self.webServerLabel.setObjectName(u'WebServerLabel') - self.webProxyLayout.setWidget(0, QtGui.QFormLayout.LabelRole, - self.webServerLabel) - self.webServerEdit = QtGui.QLineEdit(self.webProxyTab) - self.webServerEdit.setObjectName(u'WebServerEdit') - self.webProxyLayout.setWidget(0, QtGui.QFormLayout.FieldRole, - self.webServerEdit) - self.webUserLabel = QtGui.QLabel(self.webProxyTab) - self.webUserLabel.setObjectName(u'WebUserLabel') - self.webProxyLayout.setWidget(1, QtGui.QFormLayout.LabelRole, - self.webUserLabel) - self.webUserEdit = QtGui.QLineEdit(self.webProxyTab) - self.webUserEdit.setObjectName(u'WebUserEdit') - self.webProxyLayout.setWidget(1, QtGui.QFormLayout.FieldRole, - self.webUserEdit) - self.webPasswordLabel = QtGui.QLabel(self.webProxyTab) - self.webPasswordLabel.setObjectName(u'WebPasswordLabel') - self.webProxyLayout.setWidget(2, QtGui.QFormLayout.LabelRole, - self.webPasswordLabel) - self.webPasswordEdit = QtGui.QLineEdit(self.webProxyTab) - self.webPasswordEdit.setObjectName(u'WebPasswordEdit') - self.webProxyLayout.setWidget(2, QtGui.QFormLayout.FieldRole, - self.webPasswordEdit) - self.webTabWidget.addTab(self.webProxyTab, u'') - self.selectStack.addWidget(self.webTabWidget) - self.openlp1Widget = QtGui.QWidget(self.selectPage) - self.openlp1Widget.setObjectName(u'Openlp1Widget') - self.openlp1Layout = QtGui.QFormLayout(self.openlp1Widget) - self.openlp1Layout.setMargin(0) - self.openlp1Layout.setObjectName(u'Openlp1Layout') - self.openlp1FileLabel = QtGui.QLabel(self.openlp1Widget) - self.openlp1FileLabel.setObjectName(u'Openlp1FileLabel') - self.openlp1FileLayout = QtGui.QHBoxLayout() - self.openlp1FileLayout.setObjectName(u'Openlp1FileLayout') - self.openlp1FileEdit = QtGui.QLineEdit(self.openlp1Widget) - self.openlp1FileEdit.setObjectName(u'Openlp1FileEdit') - self.openlp1FileLayout.addWidget(self.openlp1FileEdit) - self.openlp1BrowseButton = QtGui.QToolButton(self.openlp1Widget) - self.openlp1BrowseButton.setIcon( - build_icon(u':/general/general_open.png')) - self.openlp1BrowseButton.setObjectName(u'Openlp1BrowseButton') - self.openlp1FileLayout.addWidget(self.openlp1BrowseButton) - self.openlp1Layout.addRow(self.openlp1FileLabel, self.openlp1FileLayout) - self.openlp1DisabledLabel = QtGui.QLabel(self.openlp1Widget) - self.openlp1DisabledLabel.setWordWrap(True) - self.openlp1DisabledLabel.setObjectName(u'Openlp1DisabledLabel') - self.openlp1Layout.addRow(self.openlp1DisabledLabel) - self.openlp1Spacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Minimum) - self.openlp1Layout.setItem(1, QtGui.QFormLayout.LabelRole, - self.openlp1Spacer) - self.selectStack.addWidget(self.openlp1Widget) - self.selectPageLayout.addLayout(self.selectStack) - bibleImportWizard.addPage(self.selectPage) - # License Page - self.licenseDetailsPage = QtGui.QWizardPage() - self.licenseDetailsPage.setObjectName(u'LicenseDetailsPage') - self.licenseDetailsLayout = QtGui.QFormLayout(self.licenseDetailsPage) - self.licenseDetailsLayout.setObjectName(u'LicenseDetailsLayout') - self.versionNameLabel = QtGui.QLabel(self.licenseDetailsPage) - self.versionNameLabel.setObjectName(u'VersionNameLabel') - self.licenseDetailsLayout.setWidget(0, QtGui.QFormLayout.LabelRole, - self.versionNameLabel) - self.versionNameEdit = QtGui.QLineEdit(self.licenseDetailsPage) - self.versionNameEdit.setObjectName(u'VersionNameEdit') - self.licenseDetailsLayout.setWidget(0, QtGui.QFormLayout.FieldRole, - self.versionNameEdit) - self.copyrightLabel = QtGui.QLabel(self.licenseDetailsPage) - self.copyrightLabel.setObjectName(u'CopyrightLabel') - self.licenseDetailsLayout.setWidget(1, QtGui.QFormLayout.LabelRole, - self.copyrightLabel) - self.copyrightEdit = QtGui.QLineEdit(self.licenseDetailsPage) - self.copyrightEdit.setObjectName(u'CopyrightEdit') - self.licenseDetailsLayout.setWidget(1, QtGui.QFormLayout.FieldRole, - self.copyrightEdit) - self.permissionsLabel = QtGui.QLabel(self.licenseDetailsPage) - self.permissionsLabel.setObjectName(u'PermissionsLabel') - self.licenseDetailsLayout.setWidget(2, QtGui.QFormLayout.LabelRole, - self.permissionsLabel) - self.permissionsEdit = QtGui.QLineEdit(self.licenseDetailsPage) - self.permissionsEdit.setObjectName(u'PermissionsEdit') - self.licenseDetailsLayout.setWidget(2, QtGui.QFormLayout.FieldRole, - self.permissionsEdit) - bibleImportWizard.addPage(self.licenseDetailsPage) - # Progress Page - self.importPage = QtGui.QWizardPage() - self.importPage.setObjectName(u'ImportPage') - self.importLayout = QtGui.QVBoxLayout(self.importPage) - self.importLayout.setMargin(48) - self.importLayout.setObjectName(u'ImportLayout') - self.importProgressLabel = QtGui.QLabel(self.importPage) - self.importProgressLabel.setObjectName(u'ImportProgressLabel') - self.importLayout.addWidget(self.importProgressLabel) - self.importProgressBar = QtGui.QProgressBar(self.importPage) - self.importProgressBar.setObjectName(u'ImportProgressBar') - self.importLayout.addWidget(self.importProgressBar) - bibleImportWizard.addPage(self.importPage) - self.retranslateUi(bibleImportWizard) - QtCore.QMetaObject.connectSlotsByName(bibleImportWizard) - QtCore.QObject.connect(self.formatComboBox, - QtCore.SIGNAL(u'currentIndexChanged(int)'), self.selectStack, - QtCore.SLOT(u'setCurrentIndex(int)')) - - def retranslateUi(self, bibleImportWizard): - bibleImportWizard.setWindowTitle( - translate('BiblesPlugin.ImportWizardForm', 'Bible Import Wizard')) - self.titleLabel.setText( - u'%s' % \ - translate('BiblesPlugin.ImportWizardForm', - 'Welcome to the Bible Import Wizard')) - self.informationLabel.setText( - translate('BiblesPlugin.ImportWizardForm', - 'This wizard will help you to import Bibles from a ' - 'variety of formats. Click the next button below to start the ' - 'process by selecting a format to import from.')) - self.selectPage.setTitle(translate('BiblesPlugin.ImportWizardForm', - 'Select Import Source')) - self.selectPage.setSubTitle( - translate('BiblesPlugin.ImportWizardForm', - 'Select the import format, and where to import from.')) - self.formatLabel.setText( - translate('BiblesPlugin.ImportWizardForm', 'Format:')) - self.formatComboBox.setItemText(0, - translate('BiblesPlugin.ImportWizardForm', 'OSIS')) - self.formatComboBox.setItemText(1, - translate('BiblesPlugin.ImportWizardForm', 'CSV')) - self.formatComboBox.setItemText(2, - translate('BiblesPlugin.ImportWizardForm', 'OpenSong')) - self.formatComboBox.setItemText(3, - translate('BiblesPlugin.ImportWizardForm', 'Web Download')) - self.formatComboBox.setItemText(4, - translate('BiblesPlugin.ImportWizardForm', 'openlp.org 1.x')) - self.openlp1FileLabel.setText( - translate('BiblesPlugin.ImportWizardForm', 'File location:')) - self.osisFileLabel.setText( - translate('BiblesPlugin.ImportWizardForm', 'File location:')) - self.csvBooksLabel.setText( - translate('BiblesPlugin.ImportWizardForm', 'Books location:')) - self.csvVersesLabel.setText( - translate('BiblesPlugin.ImportWizardForm', 'Verse location:')) - self.openSongFileLabel.setText( - translate('BiblesPlugin.ImportWizardForm', 'Bible filename:')) - self.webSourceLabel.setText( - translate('BiblesPlugin.ImportWizardForm', 'Location:')) - self.webSourceComboBox.setItemText(0, - translate('BiblesPlugin.ImportWizardForm', 'Crosswalk')) - self.webSourceComboBox.setItemText(1, - translate('BiblesPlugin.ImportWizardForm', 'BibleGateway')) - self.webSourceComboBox.setItemText(2, - translate('BiblesPlugin.ImportWizardForm', 'Bibleserver')) - self.webTranslationLabel.setText( - translate('BiblesPlugin.ImportWizardForm', 'Bible:')) - self.webTabWidget.setTabText( - self.webTabWidget.indexOf(self.webBibleTab), - translate('BiblesPlugin.ImportWizardForm', 'Download Options')) - self.webServerLabel.setText( - translate('BiblesPlugin.ImportWizardForm', 'Server:')) - self.webUserLabel.setText( - translate('BiblesPlugin.ImportWizardForm', 'Username:')) - self.webPasswordLabel.setText( - translate('BiblesPlugin.ImportWizardForm', 'Password:')) - self.webTabWidget.setTabText( - self.webTabWidget.indexOf(self.webProxyTab), - translate('BiblesPlugin.ImportWizardForm', - 'Proxy Server (Optional)')) - self.licenseDetailsPage.setTitle( - translate('BiblesPlugin.ImportWizardForm', 'License Details')) - self.licenseDetailsPage.setSubTitle( - translate('BiblesPlugin.ImportWizardForm', - 'Set up the Bible\'s license details.')) - self.versionNameLabel.setText( - translate('BiblesPlugin.ImportWizardForm', 'Version name:')) - self.copyrightLabel.setText( - translate('BiblesPlugin.ImportWizardForm', 'Copyright:')) - self.permissionsLabel.setText( - translate('BiblesPlugin.ImportWizardForm', 'Permissions:')) - self.importPage.setTitle( - translate('BiblesPlugin.ImportWizardForm', 'Importing')) - self.importPage.setSubTitle( - translate('BiblesPlugin.ImportWizardForm', - 'Please wait while your Bible is imported.')) - self.importProgressLabel.setText( - translate('BiblesPlugin.ImportWizardForm', 'Ready.')) - self.importProgressBar.setFormat(u'%p%') - self.openlp1DisabledLabel.setText( - translate('BiblesPlugin.ImportWizardForm', 'The openlp.org 1.x ' - 'importer has been disabled due to a missing Python module. If ' - 'you want to use this importer, you will need to install the ' - '"python-sqlite" module.')) - # Align all QFormLayouts towards each other. - labelWidth = max(self.formatLabel.minimumSizeHint().width(), - self.osisFileLabel.minimumSizeHint().width(), - self.csvBooksLabel.minimumSizeHint().width(), - self.csvVersesLabel.minimumSizeHint().width(), - self.openSongFileLabel.minimumSizeHint().width(), - self.openlp1FileLabel.minimumSizeHint().width()) - self.formatSpacer.changeSize(labelWidth, 0, - QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - self.osisSpacer.changeSize(labelWidth, 0, - QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - self.csvSpacer.changeSize(labelWidth, 0, - QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - self.openSongSpacer.changeSize(labelWidth, 0, - QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - self.openlp1Spacer.changeSize(labelWidth, 0, - QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) diff --git a/openlp/plugins/bibles/lib/csvbible.py b/openlp/plugins/bibles/lib/csvbible.py index 2e9e9523b..8959167a6 100644 --- a/openlp/plugins/bibles/lib/csvbible.py +++ b/openlp/plugins/bibles/lib/csvbible.py @@ -31,7 +31,7 @@ import csv from PyQt4 import QtCore from openlp.core.lib import Receiver, translate -from db import BibleDB +from openlp.plugins.bibles.lib.db import BibleDB log = logging.getLogger(__name__) @@ -51,7 +51,7 @@ class CSVBible(BibleDB): self.booksfile = kwargs[u'booksfile'] self.versesfile = kwargs[u'versefile'] QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'bibles_stop_import'), self.stop_import) + QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import) def do_import(self): success = True diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index f5468a63a..6f6b861e9 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -387,7 +387,7 @@ class HTTPBible(BibleDB): Run the import. This method overrides the parent class method. Returns ``True`` on success, ``False`` on failure. """ - self.wizard.importProgressBar.setMaximum(2) + self.wizard.progressBar.setMaximum(2) self.wizard.incrementProgressBar('Registering bible...') self.create_meta(u'download source', self.download_source) self.create_meta(u'download name', self.download_name) @@ -532,19 +532,25 @@ def get_soup_for_bible_ref(reference_url, header=None, cleaner=None): Receiver.send_message(u'openlp_process_events') return soup -def send_error_message(reason): - if reason == u'download': +def send_error_message(error_type): + """ + Send a standard error message informing the user of an issue. + + ``error_type`` + The type of error that occured for the issue. + """ + if error_type == u'download': Receiver.send_message(u'openlp_error_message', { u'title': translate('BiblePlugin.HTTPBible', 'Download Error'), u'message': translate('BiblePlugin.HTTPBible', 'There was a ' 'problem downloading your verse selection. Please check your ' 'Internet connection, and if this error continues to occur ' - 'consider reporting a bug.') + 'please consider reporting a bug.') }) - elif reason == u'parse': + elif error_type == u'parse': Receiver.send_message(u'openlp_error_message', { u'title': translate('BiblePlugin.HTTPBible', 'Parse Error'), u'message': translate('BiblePlugin.HTTPBible', 'There was a ' 'problem extracting your verse selection. If this error continues ' - 'to occur consider reporting a bug.') + 'to occur please consider reporting a bug.') }) diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 40d76c36a..d60afccd5 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -327,7 +327,7 @@ class BibleMediaItem(MediaManagerItem): if not hasattr(self, u'import_wizard'): self.import_wizard = BibleImportForm(self, self.parent.manager, self.parent) - # If the import was not canceled then reload. + # If the import was not cancelled then reload. if self.import_wizard.exec_(): self.reloadBibles() diff --git a/openlp/plugins/bibles/lib/openlp1.py b/openlp/plugins/bibles/lib/openlp1.py index 866652e5b..2df6b1677 100644 --- a/openlp/plugins/bibles/lib/openlp1.py +++ b/openlp/plugins/bibles/lib/openlp1.py @@ -30,7 +30,7 @@ import sqlite from PyQt4 import QtCore from openlp.core.lib import Receiver, translate -from db import BibleDB +from openlp.plugins.bibles.lib.db import BibleDB log = logging.getLogger(__name__) @@ -46,7 +46,7 @@ class OpenLP1Bible(BibleDB): BibleDB.__init__(self, parent, **kwargs) self.filename = kwargs[u'filename'] QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'bibles_stop_import'), self.stop_import) + QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import) def do_import(self): """ @@ -62,7 +62,7 @@ class OpenLP1Bible(BibleDB): # Create all books. cursor.execute(u'SELECT id, testament_id, name, abbreviation FROM book') books = cursor.fetchall() - self.wizard.importProgressBar.setMaximum(len(books) + 1) + self.wizard.progressBar.setMaximum(len(books) + 1) for book in books: if self.stop_import_flag: connection.close() diff --git a/openlp/plugins/bibles/lib/opensong.py b/openlp/plugins/bibles/lib/opensong.py index 03d243390..2b3b6dfb7 100644 --- a/openlp/plugins/bibles/lib/opensong.py +++ b/openlp/plugins/bibles/lib/opensong.py @@ -30,7 +30,7 @@ from lxml import objectify from PyQt4 import QtCore from openlp.core.lib import Receiver, translate -from db import BibleDB +from openlp.plugins.bibles.lib.db import BibleDB log = logging.getLogger(__name__) @@ -48,7 +48,7 @@ class OpenSongBible(BibleDB): BibleDB.__init__(self, parent, **kwargs) self.filename = kwargs['filename'] QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'bibles_stop_import'), self.stop_import) + QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import) def do_import(self): """ diff --git a/openlp/plugins/bibles/lib/osis.py b/openlp/plugins/bibles/lib/osis.py index bf070c4bd..4a001987d 100644 --- a/openlp/plugins/bibles/lib/osis.py +++ b/openlp/plugins/bibles/lib/osis.py @@ -35,7 +35,7 @@ from PyQt4 import QtCore from openlp.core.lib import Receiver, translate from openlp.core.utils import AppLocation -from db import BibleDB +from openlp.plugins.bibles.lib.db import BibleDB log = logging.getLogger(__name__) @@ -87,7 +87,7 @@ class OSISBible(BibleDB): if fbibles: fbibles.close() QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'bibles_stop_import'), self.stop_import) + QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import) def do_import(self): """ @@ -134,9 +134,9 @@ class OSISBible(BibleDB): testament) if last_chapter == 0: if book == u'Gen': - self.wizard.importProgressBar.setMaximum(1188) + self.wizard.progressBar.setMaximum(1188) else: - self.wizard.importProgressBar.setMaximum(260) + self.wizard.progressBar.setMaximum(260) if last_chapter != chapter: if last_chapter != 0: self.session.commit() diff --git a/openlp/plugins/songs/forms/songimportform.py b/openlp/plugins/songs/forms/songimportform.py index 5776dd21a..22a7ab61f 100644 --- a/openlp/plugins/songs/forms/songimportform.py +++ b/openlp/plugins/songs/forms/songimportform.py @@ -23,19 +23,21 @@ # with this program; if not, write to the Free Software Foundation, Inc., 59 # # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### - +""" +The song import functions for OpenLP. +""" import logging import os from PyQt4 import QtCore, QtGui -from songimportwizard import Ui_SongImportWizard from openlp.core.lib import Receiver, SettingsManager, translate +from openlp.core.ui.wizard import OpenLPWizard from openlp.plugins.songs.lib.importer import SongFormat log = logging.getLogger(__name__) -class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): +class SongImportForm(OpenLPWizard): """ This is the Song Import Wizard, which allows easy importing of Songs into OpenLP from other formats like OpenLyrics, OpenSong and CCLI. @@ -52,11 +54,23 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): ``plugin`` The songs plugin. """ - QtGui.QWizard.__init__(self, parent) - self.setupUi(self) - self.registerFields() - self.finishButton = self.button(QtGui.QWizard.FinishButton) - self.cancelButton = self.button(QtGui.QWizard.CancelButton) + OpenLPWizard.__init__(self, parent, plugin, u'songImportWizard', + u':/wizards/wizard_importsong.bmp') + + def setupUi(self, image): + """ + Set up the song wizard UI. + """ + OpenLPWizard.setupUi(self, image) + self.formatStack.setCurrentIndex(0) + QtCore.QObject.connect(self.formatComboBox, + QtCore.SIGNAL(u'currentIndexChanged(int)'), + self.formatStack.setCurrentIndex) + + def customInit(self): + """ + Song wizard specific initialisation. + """ if not SongFormat.get_availability(SongFormat.OpenLP1): self.openLP1DisabledWidget.setVisible(True) self.openLP1ImportWidget.setVisible(False) @@ -66,7 +80,11 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): if not SongFormat.get_availability(SongFormat.Generic): self.genericDisabledWidget.setVisible(True) self.genericImportWidget.setVisible(False) - self.plugin = plugin + + def customSignals(self): + """ + Song wizard specific signals. + """ QtCore.QObject.connect(self.openLP2BrowseButton, QtCore.SIGNAL(u'clicked()'), self.onOpenLP2BrowseButtonClicked) @@ -118,25 +136,184 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): QtCore.QObject.connect(self.songBeamerRemoveButton, QtCore.SIGNAL(u'clicked()'), self.onSongBeamerRemoveButtonClicked) - QtCore.QObject.connect(self, - QtCore.SIGNAL(u'currentIdChanged(int)'), - self.onCurrentIdChanged) - def exec_(self): + def addCustomPages(self): """ - Run the wizard. + Add song wizard specific pages. """ - self.setDefaults() - return QtGui.QWizard.exec_(self) + # Source Page + self.sourcePage = QtGui.QWizardPage() + self.sourcePage.setObjectName(u'SourcePage') + self.sourceLayout = QtGui.QVBoxLayout(self.sourcePage) + self.sourceLayout.setObjectName(u'SourceLayout') + self.formatLayout = QtGui.QFormLayout() + self.formatLayout.setObjectName(u'FormatLayout') + self.formatLabel = QtGui.QLabel(self.sourcePage) + self.formatLabel.setObjectName(u'FormatLabel') + self.formatComboBox = QtGui.QComboBox(self.sourcePage) + self.formatComboBox.setObjectName(u'FormatComboBox') + self.formatLayout.addRow(self.formatLabel, self.formatComboBox) + self.formatSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, + QtGui.QSizePolicy.Minimum) + self.formatLayout.setItem(1, QtGui.QFormLayout.LabelRole, + self.formatSpacer) + self.sourceLayout.addLayout(self.formatLayout) + self.formatStack = QtGui.QStackedLayout() + self.formatStack.setObjectName(u'FormatStack') + # OpenLP 2.0 + self.addSingleFileSelectItem(u'openLP2') + # openlp.org 1.x + self.addSingleFileSelectItem(u'openLP1', None, True) + # OpenLyrics + self.addMultiFileSelectItem(u'openLyrics', u'OpenLyrics', True) + # Open Song + self.addMultiFileSelectItem(u'openSong', u'OpenSong') + # Words of Worship + self.addMultiFileSelectItem(u'wordsOfWorship') + # CCLI File import + self.addMultiFileSelectItem(u'ccli') + # Songs of Fellowship + self.addMultiFileSelectItem(u'songsOfFellowship', None, True) + # Generic Document/Presentation import + self.addMultiFileSelectItem(u'generic', None, True) + # EasyWorship + self.addSingleFileSelectItem(u'ew') + # Words of Worship + self.addMultiFileSelectItem(u'songBeamer') +# Commented out for future use. +# self.addSingleFileSelectItem(u'csv', u'CSV') + self.sourceLayout.addLayout(self.formatStack) + self.addPage(self.sourcePage) - def reject(self): + def retranslateUi(self): """ - Stop the import on cancel button, close button or ESC key. + Song wizard localisation. """ - log.debug(u'Import canceled by user.') - if self.currentPage() == self.importPage: - Receiver.send_message(u'songs_stop_import') - self.done(QtGui.QDialog.Rejected) + self.setWindowTitle( + translate('SongsPlugin.ImportWizardForm', 'Song Import Wizard')) + self.titleLabel.setText( + u'%s' % \ + translate('SongsPlugin.ImportWizardForm', + 'Welcome to the Song Import Wizard')) + self.informationLabel.setText( + translate('SongsPlugin.ImportWizardForm', + 'This wizard will help you to import songs from a variety of ' + 'formats. Click the next button below to start the process by ' + 'selecting a format to import from.')) + self.sourcePage.setTitle( + translate('SongsPlugin.ImportWizardForm', 'Select Import Source')) + self.sourcePage.setSubTitle( + translate('SongsPlugin.ImportWizardForm', + 'Select the import format, and where to import from.')) + self.formatLabel.setText( + translate('SongsPlugin.ImportWizardForm', 'Format:')) + self.formatComboBox.setItemText(0, + translate('SongsPlugin.ImportWizardForm', 'OpenLP 2.0')) + self.formatComboBox.setItemText(1, + translate('SongsPlugin.ImportWizardForm', 'openlp.org 1.x')) + self.formatComboBox.setItemText(2, + translate('SongsPlugin.ImportWizardForm', 'OpenLyrics')) + self.formatComboBox.setItemText(3, + translate('SongsPlugin.ImportWizardForm', 'OpenSong')) + self.formatComboBox.setItemText(4, + translate('SongsPlugin.ImportWizardForm', 'Words of Worship')) + self.formatComboBox.setItemText(5, + translate('SongsPlugin.ImportWizardForm', 'CCLI/SongSelect')) + self.formatComboBox.setItemText(6, + translate('SongsPlugin.ImportWizardForm', 'Songs of Fellowship')) + self.formatComboBox.setItemText(7, + translate('SongsPlugin.ImportWizardForm', + 'Generic Document/Presentation')) + self.formatComboBox.setItemText(8, + translate('SongsPlugin.ImportWizardForm', 'EasyWorship')) + self.formatComboBox.setItemText(9, + translate('SongsPlugin.ImportWizardForm', 'SongBeamer')) +# self.formatComboBox.setItemText(9, +# translate('SongsPlugin.ImportWizardForm', 'CSV')) + self.openLP2FilenameLabel.setText( + translate('SongsPlugin.ImportWizardForm', 'Filename:')) + self.openLP2BrowseButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Browse...')) + self.openLP1FilenameLabel.setText( + translate('SongsPlugin.ImportWizardForm', 'Filename:')) + self.openLP1BrowseButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Browse...')) + self.openLP1DisabledLabel.setText( + translate('SongsPlugin.ImportWizardForm', 'The openlp.org 1.x ' + 'importer has been disabled due to a missing Python module. If ' + 'you want to use this importer, you will need to install the ' + '"python-sqlite" module.')) + self.openLyricsAddButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Add Files...')) + self.openLyricsRemoveButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) + self.openLyricsDisabledLabel.setText( + translate('SongsPlugin.ImportWizardForm', 'The OpenLyrics ' + 'importer has not yet been developed, but as you can see, we are ' + 'still intending to do so. Hopefully it will be in the next ' + 'release.')) + self.openSongAddButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Add Files...')) + self.openSongRemoveButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) + self.wordsOfWorshipAddButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Add Files...')) + self.wordsOfWorshipRemoveButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) + self.ccliAddButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Add Files...')) + self.ccliRemoveButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) + self.songsOfFellowshipAddButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Add Files...')) + self.songsOfFellowshipRemoveButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) + self.songsOfFellowshipDisabledLabel.setText( + translate('SongsPlugin.ImportWizardForm', 'The Songs of ' + 'Fellowship importer has been disabled because OpenLP cannot ' + 'find OpenOffice.org on your computer.')) + self.genericAddButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Add Files...')) + self.genericRemoveButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) + self.genericDisabledLabel.setText( + translate('SongsPlugin.ImportWizardForm', 'The generic document/' + 'presentation importer has been disabled because OpenLP cannot ' + 'find OpenOffice.org on your computer.')) + self.ewFilenameLabel.setText( + translate('SongsPlugin.ImportWizardForm', 'Filename:')) + self.ewBrowseButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Browse...')) + self.songBeamerAddButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Add Files...')) + self.songBeamerRemoveButton.setText( + translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) +# self.csvFilenameLabel.setText( +# translate('SongsPlugin.ImportWizardForm', 'Filename:')) +# self.csvBrowseButton.setText( +# translate('SongsPlugin.ImportWizardForm', 'Browse...')) + self.progressPage.setTitle( + translate('SongsPlugin.ImportWizardForm', 'Importing')) + self.progressPage.setSubTitle( + translate('SongsPlugin.ImportWizardForm', + 'Please wait while your songs are imported.')) + self.progressLabel.setText( + translate('SongsPlugin.ImportWizardForm', 'Ready.')) + self.progressBar.setFormat( + translate('SongsPlugin.ImportWizardForm', '%p%')) + # Align all QFormLayouts towards each other. + width = max(self.formatLabel.minimumSizeHint().width(), + self.openLP2FilenameLabel.minimumSizeHint().width()) + self.formatSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed, + QtGui.QSizePolicy.Fixed) + self.openLP2FormLabelSpacer.changeSize(width, 0, + QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + self.openLP1FormLabelSpacer.changeSize(width, 0, + QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) + self.ewFormLabelSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed, + QtGui.QSizePolicy.Fixed) +# self.csvFormLabelSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed, +# QtGui.QSizePolicy.Fixed) def validateCurrentPage(self): """ @@ -247,7 +424,7 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): self.songBeamerAddButton.setFocus() return False return True - elif self.currentPage() == self.importPage: + elif self.currentPage() == self.progressPage: return True def getFileName(self, title, editbox, filters=u''): @@ -308,17 +485,26 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): os.path.split(unicode(filenames[0]))[0], 1) def getListOfFiles(self, listbox): + """ + Return a list of file from the listbox + """ files = [] for row in range(0, listbox.count()): files.append(unicode(listbox.item(row).text())) return files def removeSelectedItems(self, listbox): + """ + Remove selected listbox items + """ for item in listbox.selectedItems(): item = listbox.takeItem(listbox.row(item)) del item def onOpenLP2BrowseButtonClicked(self): + """ + Get OpenLP v2 song database file + """ self.getFileName( translate('SongsPlugin.ImportWizardForm', 'Select OpenLP 2.0 Database File'), @@ -328,6 +514,9 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): ) def onOpenLP1BrowseButtonClicked(self): + """ + Get OpenLP v1 song database file + """ self.getFileName( translate('SongsPlugin.ImportWizardForm', 'Select openlp.org 1.x Database File'), @@ -337,6 +526,9 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): ) def onOpenLyricsAddButtonClicked(self): + """ + Get OpenLyrics song database files + """ self.getFiles( translate('SongsPlugin.ImportWizardForm', 'Select OpenLyrics Files'), @@ -344,19 +536,30 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): ) def onOpenLyricsRemoveButtonClicked(self): + """ + Remove selected OpenLyrics files from the import list + """ self.removeSelectedItems(self.openLyricsFileListWidget) def onOpenSongAddButtonClicked(self): + """ + Get OpenSong song database files + """ self.getFiles( - translate('SongsPlugin.ImportWizardForm', - 'Select Open Song Files'), + translate('SongsPlugin.ImportWizardForm', 'Select Open Song Files'), self.openSongFileListWidget ) def onOpenSongRemoveButtonClicked(self): + """ + Remove selected OpenSong files from the import list + """ self.removeSelectedItems(self.openSongFileListWidget) def onWordsOfWorshipAddButtonClicked(self): + """ + Get Words of Worship song database files + """ self.getFiles( translate('SongsPlugin.ImportWizardForm', 'Select Words of Worship Files'), @@ -366,9 +569,15 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): ) def onWordsOfWorshipRemoveButtonClicked(self): + """ + Remove selected Words of Worship files from the import list + """ self.removeSelectedItems(self.wordsOfWorshipFileListWidget) def onCCLIAddButtonClicked(self): + """ + Get CCLI song database files + """ self.getFiles( translate('SongsPlugin.ImportWizardForm', 'Select CCLI Files'), @@ -376,9 +585,15 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): ) def onCCLIRemoveButtonClicked(self): + """ + Remove selected CCLI files from the import list + """ self.removeSelectedItems(self.ccliFileListWidget) def onSongsOfFellowshipAddButtonClicked(self): + """ + Get Songs of Fellowship song database files + """ self.getFiles( translate('SongsPlugin.ImportWizardForm', 'Select Songs of Fellowship Files'), @@ -388,9 +603,15 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): ) def onSongsOfFellowshipRemoveButtonClicked(self): + """ + Remove selected Songs of Fellowship files from the import list + """ self.removeSelectedItems(self.songsOfFellowshipFileListWidget) def onGenericAddButtonClicked(self): + """ + Get song database files + """ self.getFiles( translate('SongsPlugin.ImportWizardForm', 'Select Document/Presentation Files'), @@ -398,9 +619,15 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): ) def onGenericRemoveButtonClicked(self): + """ + Remove selected files from the import list + """ self.removeSelectedItems(self.genericFileListWidget) def onEWBrowseButtonClicked(self): + """ + Get EasyWorship song database files + """ self.getFileName( translate('SongsPlugin.ImportWizardForm', 'Select EasyWorship Database File'), @@ -408,6 +635,9 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): ) def onSongBeamerAddButtonClicked(self): + """ + Get SongBeamer song database files + """ self.getFiles( translate('SongsPlugin.ImportWizardForm', 'Select SongBeamer Files'), @@ -416,18 +646,21 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): ) def onSongBeamerRemoveButtonClicked(self): + """ + Remove selected SongBeamer files from the import list + """ self.removeSelectedItems(self.songBeamerFileListWidget) - def onCurrentIdChanged(self, id): - if self.page(id) == self.importPage: - self.preImport() - self.performImport() - self.postImport() - def registerFields(self): + """ + Register song import wizard fields. + """ pass def setDefaults(self): + """ + Set default form values for the song import wizard. + """ self.restart() self.finishButton.setVisible(False) self.cancelButton.setVisible(True) @@ -444,25 +677,16 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): self.songBeamerFileListWidget.clear() #self.csvFilenameEdit.setText(u'') - def incrementProgressBar(self, status_text, increment=1): - log.debug(u'IncrementBar %s', status_text) - if status_text: - self.importProgressLabel.setText(status_text) - if increment > 0: - self.importProgressBar.setValue(self.importProgressBar.value() + - increment) - Receiver.send_message(u'openlp_process_events') - - def preImport(self): - self.finishButton.setVisible(False) - self.importProgressBar.setMinimum(0) - self.importProgressBar.setMaximum(1188) - self.importProgressBar.setValue(0) - self.importProgressLabel.setText( + def preWizard(self): + """ + Perform pre import tasks + """ + OpenLPWizard.preWizard(self) + self.progressLabel.setText( translate('SongsPlugin.ImportWizardForm', 'Starting import...')) Receiver.send_message(u'openlp_process_events') - def performImport(self): + def performWizard(self): """ Perform the actual import. This method pulls in the correct importer class, and then runs the ``do_import`` method of the importer to do @@ -520,20 +744,128 @@ class SongImportForm(QtGui.QWizard, Ui_SongImportWizard): elif source_format == SongFormat.SongBeamer: # Import SongBeamer songs importer = self.plugin.importSongs(SongFormat.SongBeamer, - filenames=self.getListOfFiles( - self.songBeamerFileListWidget) + filenames=self.getListOfFiles(self.songBeamerFileListWidget) ) if importer.do_import(): # reload songs - self.importProgressLabel.setText( + self.progressLabel.setText( translate('SongsPlugin.SongImportForm', 'Finished import.')) else: - self.importProgressLabel.setText( + self.progressLabel.setText( translate('SongsPlugin.SongImportForm', 'Your song import failed.')) - def postImport(self): - self.importProgressBar.setValue(self.importProgressBar.maximum()) - self.finishButton.setVisible(True) - self.cancelButton.setVisible(False) - Receiver.send_message(u'openlp_process_events') + def addSingleFileSelectItem(self, prefix, obj_prefix=None, + can_disable=False): + if not obj_prefix: + obj_prefix = prefix + page = QtGui.QWidget() + page.setObjectName(obj_prefix + u'Page') + if can_disable: + importWidget = self.disablableWidget(page, prefix, obj_prefix) + else: + importWidget = page + importLayout = QtGui.QFormLayout(importWidget) + importLayout.setMargin(0) + if can_disable: + importLayout.setObjectName(obj_prefix + u'ImportLayout') + else: + importLayout.setObjectName(obj_prefix + u'Layout') + filenameLabel = QtGui.QLabel(importWidget) + filenameLabel.setObjectName(obj_prefix + u'FilenameLabel') + fileLayout = QtGui.QHBoxLayout() + fileLayout.setObjectName(obj_prefix + u'FileLayout') + filenameEdit = QtGui.QLineEdit(importWidget) + filenameEdit.setObjectName(obj_prefix + u'FilenameEdit') + fileLayout.addWidget(filenameEdit) + browseButton = QtGui.QToolButton(importWidget) + browseButton.setIcon(self.openIcon) + browseButton.setObjectName(obj_prefix + u'BrowseButton') + fileLayout.addWidget(browseButton) + importLayout.addRow(filenameLabel, fileLayout) + formSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, + QtGui.QSizePolicy.Minimum) + importLayout.setItem(1, QtGui.QFormLayout.LabelRole, formSpacer) + self.formatStack.addWidget(page) + setattr(self, prefix + u'Page', page) + setattr(self, prefix + u'FilenameLabel', filenameLabel) + setattr(self, prefix + u'FormLabelSpacer', formSpacer) + setattr(self, prefix + u'FileLayout', fileLayout) + setattr(self, prefix + u'FilenameEdit', filenameEdit) + setattr(self, prefix + u'BrowseButton', browseButton) + if can_disable: + setattr(self, prefix + u'ImportLayout', importLayout) + else: + setattr(self, prefix + u'Layout', importLayout) + self.formatComboBox.addItem(u'') + + def addMultiFileSelectItem(self, prefix, obj_prefix=None, + can_disable=False): + if not obj_prefix: + obj_prefix = prefix + page = QtGui.QWidget() + page.setObjectName(obj_prefix + u'Page') + if can_disable: + importWidget = self.disablableWidget(page, prefix, obj_prefix) + else: + importWidget = page + importLayout = QtGui.QVBoxLayout(importWidget) + importLayout.setMargin(0) + if can_disable: + importLayout.setObjectName(obj_prefix + u'ImportLayout') + else: + importLayout.setObjectName(obj_prefix + u'Layout') + fileListWidget = QtGui.QListWidget(importWidget) + fileListWidget.setSelectionMode( + QtGui.QAbstractItemView.ExtendedSelection) + fileListWidget.setObjectName(obj_prefix + u'FileListWidget') + importLayout.addWidget(fileListWidget) + buttonLayout = QtGui.QHBoxLayout() + buttonLayout.setObjectName(obj_prefix + u'ButtonLayout') + addButton = QtGui.QPushButton(importWidget) + addButton.setIcon(self.openIcon) + addButton.setObjectName(obj_prefix + u'AddButton') + buttonLayout.addWidget(addButton) + buttonLayout.addStretch() + removeButton = QtGui.QPushButton(importWidget) + removeButton.setIcon(self.deleteIcon) + removeButton.setObjectName(obj_prefix + u'RemoveButton') + buttonLayout.addWidget(removeButton) + importLayout.addLayout(buttonLayout) + self.formatStack.addWidget(page) + setattr(self, prefix + u'Page', page) + setattr(self, prefix + u'FileListWidget', fileListWidget) + setattr(self, prefix + u'ButtonLayout', buttonLayout) + setattr(self, prefix + u'AddButton', addButton) + setattr(self, prefix + u'RemoveButton', removeButton) + if can_disable: + setattr(self, prefix + u'ImportLayout', importLayout) + else: + setattr(self, prefix + u'Layout', importLayout) + self.formatComboBox.addItem(u'') + + def disablableWidget(self, page, prefix, obj_prefix): + layout = QtGui.QVBoxLayout(page) + layout.setMargin(0) + layout.setSpacing(0) + layout.setObjectName(obj_prefix + u'Layout') + disabledWidget = QtGui.QWidget(page) + disabledWidget.setVisible(False) + disabledWidget.setObjectName(obj_prefix + u'DisabledWidget') + disabledLayout = QtGui.QVBoxLayout(disabledWidget) + disabledLayout.setMargin(0) + disabledLayout.setObjectName(obj_prefix + u'DisabledLayout') + disabledLabel = QtGui.QLabel(disabledWidget) + disabledLabel.setWordWrap(True) + disabledLabel.setObjectName(obj_prefix + u'DisabledLabel') + disabledLayout.addWidget(disabledLabel) + layout.addWidget(disabledWidget) + importWidget = QtGui.QWidget(page) + importWidget.setObjectName(obj_prefix + u'ImportWidget') + layout.addWidget(importWidget) + setattr(self, prefix + u'Layout', layout) + setattr(self, prefix + u'DisabledWidget', disabledWidget) + setattr(self, prefix + u'DisabledLayout', disabledLayout) + setattr(self, prefix + u'DisabledLabel', disabledLabel) + setattr(self, prefix + u'ImportWidget', importWidget) + return importWidget diff --git a/openlp/plugins/songs/forms/songimportwizard.py b/openlp/plugins/songs/forms/songimportwizard.py deleted file mode 100644 index 903300d0c..000000000 --- a/openlp/plugins/songs/forms/songimportwizard.py +++ /dev/null @@ -1,362 +0,0 @@ -# -*- coding: utf-8 -*- -# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 - -############################################################################### -# OpenLP - Open Source Lyrics Projection # -# --------------------------------------------------------------------------- # -# Copyright (c) 2008-2011 Raoul Snyman # -# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael # -# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian # -# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, # -# Carsten Tinggaard, Frode Woldsund # -# --------------------------------------------------------------------------- # -# This program is free software; you can redistribute it and/or modify it # -# under the terms of the GNU General Public License as published by the Free # -# Software Foundation; version 2 of the License. # -# # -# This program is distributed in the hope that it will be useful, but WITHOUT # -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # -# more details. # -# # -# You should have received a copy of the GNU General Public License along # -# with this program; if not, write to the Free Software Foundation, Inc., 59 # -# Temple Place, Suite 330, Boston, MA 02111-1307 USA # -############################################################################### - -from PyQt4 import QtCore, QtGui - -from openlp.core.lib import build_icon, translate - -class Ui_SongImportWizard(object): - def setupUi(self, songImportWizard): - self.openIcon = build_icon(u':/general/general_open.png') - self.deleteIcon = build_icon(u':/general/general_delete.png') - songImportWizard.setObjectName(u'songImportWizard') - songImportWizard.setModal(True) - songImportWizard.setWizardStyle(QtGui.QWizard.ModernStyle) - songImportWizard.setOptions( - QtGui.QWizard.IndependentPages | - QtGui.QWizard.NoBackButtonOnStartPage | - QtGui.QWizard.NoBackButtonOnLastPage) - # Welcome Page - self.welcomePage = QtGui.QWizardPage() - self.welcomePage.setPixmap(QtGui.QWizard.WatermarkPixmap, - QtGui.QPixmap(u':/wizards/wizard_importsong.bmp')) - self.welcomePage.setObjectName(u'WelcomePage') - self.welcomeLayout = QtGui.QVBoxLayout(self.welcomePage) - self.welcomeLayout.setObjectName(u'WelcomeLayout') - self.titleLabel = QtGui.QLabel(self.welcomePage) - self.titleLabel.setObjectName(u'TitleLabel') - self.welcomeLayout.addWidget(self.titleLabel) - self.welcomeLayout.addSpacing(40) - self.informationLabel = QtGui.QLabel(self.welcomePage) - self.informationLabel.setWordWrap(True) - self.informationLabel.setObjectName(u'InformationLabel') - self.welcomeLayout.addWidget(self.informationLabel) - self.welcomeLayout.addStretch() - songImportWizard.addPage(self.welcomePage) - # Source Page - self.sourcePage = QtGui.QWizardPage() - self.sourcePage.setObjectName(u'SourcePage') - self.sourceLayout = QtGui.QVBoxLayout(self.sourcePage) - self.sourceLayout.setObjectName(u'SourceLayout') - self.formatLayout = QtGui.QFormLayout() - self.formatLayout.setObjectName(u'FormatLayout') - self.formatLabel = QtGui.QLabel(self.sourcePage) - self.formatLabel.setObjectName(u'FormatLabel') - self.formatComboBox = QtGui.QComboBox(self.sourcePage) - self.formatComboBox.setObjectName(u'FormatComboBox') - self.formatLayout.addRow(self.formatLabel, self.formatComboBox) - self.formatSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Minimum) - self.formatLayout.setItem(1, QtGui.QFormLayout.LabelRole, - self.formatSpacer) - self.sourceLayout.addLayout(self.formatLayout) - self.formatStack = QtGui.QStackedLayout() - self.formatStack.setObjectName(u'FormatStack') - # OpenLP 2.0 - self.addSingleFileSelectItem(u'openLP2') - # openlp.org 1.x - self.addSingleFileSelectItem(u'openLP1', None, True) - # OpenLyrics - self.addMultiFileSelectItem(u'openLyrics', u'OpenLyrics', True) - # Open Song - self.addMultiFileSelectItem(u'openSong', u'OpenSong') - # Words of Worship - self.addMultiFileSelectItem(u'wordsOfWorship') - # CCLI File import - self.addMultiFileSelectItem(u'ccli') - # Songs of Fellowship - self.addMultiFileSelectItem(u'songsOfFellowship', None, True) - # Generic Document/Presentation import - self.addMultiFileSelectItem(u'generic', None, True) - # EasyWorship - self.addSingleFileSelectItem(u'ew') - # Words of Worship - self.addMultiFileSelectItem(u'songBeamer') -# Commented out for future use. -# self.addSingleFileSelectItem(u'csv', u'CSV') - self.sourceLayout.addLayout(self.formatStack) - songImportWizard.addPage(self.sourcePage) - # Import Page - self.importPage = QtGui.QWizardPage() - self.importPage.setObjectName(u'ImportPage') - self.importLayout = QtGui.QVBoxLayout(self.importPage) - self.importLayout.setMargin(48) - self.importLayout.setObjectName(u'ImportLayout') - self.importProgressLabel = QtGui.QLabel(self.importPage) - self.importProgressLabel.setObjectName(u'ImportProgressLabel') - self.importLayout.addWidget(self.importProgressLabel) - self.importProgressBar = QtGui.QProgressBar(self.importPage) - self.importProgressBar.setObjectName(u'ImportProgressBar') - self.importLayout.addWidget(self.importProgressBar) - songImportWizard.addPage(self.importPage) - self.retranslateUi(songImportWizard) - self.formatStack.setCurrentIndex(0) - QtCore.QObject.connect(self.formatComboBox, - QtCore.SIGNAL(u'currentIndexChanged(int)'), - self.formatStack.setCurrentIndex) - QtCore.QMetaObject.connectSlotsByName(songImportWizard) - - def retranslateUi(self, songImportWizard): - songImportWizard.setWindowTitle( - translate('SongsPlugin.ImportWizardForm', 'Song Import Wizard')) - self.titleLabel.setText( - u'%s' % \ - translate('SongsPlugin.ImportWizardForm', - 'Welcome to the Song Import Wizard')) - self.informationLabel.setText( - translate('SongsPlugin.ImportWizardForm', - 'This wizard will help you to import songs from a variety of ' - 'formats. Click the next button below to start the process by ' - 'selecting a format to import from.')) - self.sourcePage.setTitle( - translate('SongsPlugin.ImportWizardForm', 'Select Import Source')) - self.sourcePage.setSubTitle( - translate('SongsPlugin.ImportWizardForm', - 'Select the import format, and where to import from.')) - self.formatLabel.setText( - translate('SongsPlugin.ImportWizardForm', 'Format:')) - self.formatComboBox.setItemText(0, - translate('SongsPlugin.ImportWizardForm', 'OpenLP 2.0')) - self.formatComboBox.setItemText(1, - translate('SongsPlugin.ImportWizardForm', 'openlp.org 1.x')) - self.formatComboBox.setItemText(2, - translate('SongsPlugin.ImportWizardForm', 'OpenLyrics')) - self.formatComboBox.setItemText(3, - translate('SongsPlugin.ImportWizardForm', 'OpenSong')) - self.formatComboBox.setItemText(4, - translate('SongsPlugin.ImportWizardForm', 'Words of Worship')) - self.formatComboBox.setItemText(5, - translate('SongsPlugin.ImportWizardForm', 'CCLI/SongSelect')) - self.formatComboBox.setItemText(6, - translate('SongsPlugin.ImportWizardForm', 'Songs of Fellowship')) - self.formatComboBox.setItemText(7, - translate('SongsPlugin.ImportWizardForm', - 'Generic Document/Presentation')) - self.formatComboBox.setItemText(8, - translate('SongsPlugin.ImportWizardForm', 'EasyWorship')) - self.formatComboBox.setItemText(9, - translate('SongsPlugin.ImportWizardForm', 'SongBeamer')) -# self.formatComboBox.setItemText(9, -# translate('SongsPlugin.ImportWizardForm', 'CSV')) - self.openLP2FilenameLabel.setText( - translate('SongsPlugin.ImportWizardForm', 'Filename:')) - self.openLP2BrowseButton.setText( - translate('SongsPlugin.ImportWizardForm', 'Browse...')) - self.openLP1FilenameLabel.setText( - translate('SongsPlugin.ImportWizardForm', 'Filename:')) - self.openLP1BrowseButton.setText( - translate('SongsPlugin.ImportWizardForm', 'Browse...')) - self.openLP1DisabledLabel.setText( - translate('SongsPlugin.ImportWizardForm', 'The openlp.org 1.x ' - 'importer has been disabled due to a missing Python module. If ' - 'you want to use this importer, you will need to install the ' - '"python-sqlite" module.')) - self.openLyricsAddButton.setText( - translate('SongsPlugin.ImportWizardForm', 'Add Files...')) - self.openLyricsRemoveButton.setText( - translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) - self.openLyricsDisabledLabel.setText( - translate('SongsPlugin.ImportWizardForm', 'The OpenLyrics ' - 'importer has not yet been developed, but as you can see, we are ' - 'still intending to do so. Hopefully it will be in the next ' - 'release.')) - self.openSongAddButton.setText( - translate('SongsPlugin.ImportWizardForm', 'Add Files...')) - self.openSongRemoveButton.setText( - translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) - self.wordsOfWorshipAddButton.setText( - translate('SongsPlugin.ImportWizardForm', 'Add Files...')) - self.wordsOfWorshipRemoveButton.setText( - translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) - self.ccliAddButton.setText( - translate('SongsPlugin.ImportWizardForm', 'Add Files...')) - self.ccliRemoveButton.setText( - translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) - self.songsOfFellowshipAddButton.setText( - translate('SongsPlugin.ImportWizardForm', 'Add Files...')) - self.songsOfFellowshipRemoveButton.setText( - translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) - self.songsOfFellowshipDisabledLabel.setText( - translate('SongsPlugin.ImportWizardForm', 'The Songs of ' - 'Fellowship importer has been disabled because OpenLP cannot ' - 'find OpenOffice.org on your computer.')) - self.genericAddButton.setText( - translate('SongsPlugin.ImportWizardForm', 'Add Files...')) - self.genericRemoveButton.setText( - translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) - self.genericDisabledLabel.setText( - translate('SongsPlugin.ImportWizardForm', 'The generic document/' - 'presentation importer has been disabled because OpenLP cannot ' - 'find OpenOffice.org on your computer.')) - self.ewFilenameLabel.setText( - translate('SongsPlugin.ImportWizardForm', 'Filename:')) - self.ewBrowseButton.setText( - translate('SongsPlugin.ImportWizardForm', 'Browse...')) - self.songBeamerAddButton.setText( - translate('SongsPlugin.ImportWizardForm', 'Add Files...')) - self.songBeamerRemoveButton.setText( - translate('SongsPlugin.ImportWizardForm', 'Remove File(s)')) -# self.csvFilenameLabel.setText( -# translate('SongsPlugin.ImportWizardForm', 'Filename:')) -# self.csvBrowseButton.setText( -# translate('SongsPlugin.ImportWizardForm', 'Browse...')) - self.importPage.setTitle( - translate('SongsPlugin.ImportWizardForm', 'Importing')) - self.importPage.setSubTitle( - translate('SongsPlugin.ImportWizardForm', - 'Please wait while your songs are imported.')) - self.importProgressLabel.setText( - translate('SongsPlugin.ImportWizardForm', 'Ready.')) - self.importProgressBar.setFormat( - translate('SongsPlugin.ImportWizardForm', '%p%')) - # Align all QFormLayouts towards each other. - width = max(self.formatLabel.minimumSizeHint().width(), - self.openLP2FilenameLabel.minimumSizeHint().width()) - self.formatSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Fixed) - self.openLP2FormLabelSpacer.changeSize(width, 0, - QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - self.openLP1FormLabelSpacer.changeSize(width, 0, - QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) - self.ewFormLabelSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Fixed) -# self.csvFormLabelSpacer.changeSize(width, 0, QtGui.QSizePolicy.Fixed, -# QtGui.QSizePolicy.Fixed) - - def addSingleFileSelectItem(self, prefix, obj_prefix=None, - can_disable=False): - if not obj_prefix: - obj_prefix = prefix - page = QtGui.QWidget() - page.setObjectName(obj_prefix + u'Page') - if can_disable: - importWidget = self.disablableWidget(page, prefix, obj_prefix) - else: - importWidget = page - importLayout = QtGui.QFormLayout(importWidget) - importLayout.setMargin(0) - if can_disable: - importLayout.setObjectName(obj_prefix + u'ImportLayout') - else: - importLayout.setObjectName(obj_prefix + u'Layout') - filenameLabel = QtGui.QLabel(importWidget) - filenameLabel.setObjectName(obj_prefix + u'FilenameLabel') - fileLayout = QtGui.QHBoxLayout() - fileLayout.setObjectName(obj_prefix + u'FileLayout') - filenameEdit = QtGui.QLineEdit(importWidget) - filenameEdit.setObjectName(obj_prefix + u'FilenameEdit') - fileLayout.addWidget(filenameEdit) - browseButton = QtGui.QToolButton(importWidget) - browseButton.setIcon(self.openIcon) - browseButton.setObjectName(obj_prefix + u'BrowseButton') - fileLayout.addWidget(browseButton) - importLayout.addRow(filenameLabel, fileLayout) - formSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, - QtGui.QSizePolicy.Minimum) - importLayout.setItem(1, QtGui.QFormLayout.LabelRole, formSpacer) - self.formatStack.addWidget(page) - setattr(self, prefix + u'Page', page) - setattr(self, prefix + u'FilenameLabel', filenameLabel) - setattr(self, prefix + u'FormLabelSpacer', formSpacer) - setattr(self, prefix + u'FileLayout', fileLayout) - setattr(self, prefix + u'FilenameEdit', filenameEdit) - setattr(self, prefix + u'BrowseButton', browseButton) - if can_disable: - setattr(self, prefix + u'ImportLayout', importLayout) - else: - setattr(self, prefix + u'Layout', importLayout) - self.formatComboBox.addItem(u'') - - def addMultiFileSelectItem(self, prefix, obj_prefix=None, - can_disable=False): - if not obj_prefix: - obj_prefix = prefix - page = QtGui.QWidget() - page.setObjectName(obj_prefix + u'Page') - if can_disable: - importWidget = self.disablableWidget(page, prefix, obj_prefix) - else: - importWidget = page - importLayout = QtGui.QVBoxLayout(importWidget) - importLayout.setMargin(0) - if can_disable: - importLayout.setObjectName(obj_prefix + u'ImportLayout') - else: - importLayout.setObjectName(obj_prefix + u'Layout') - fileListWidget = QtGui.QListWidget(importWidget) - fileListWidget.setSelectionMode( - QtGui.QAbstractItemView.ExtendedSelection) - fileListWidget.setObjectName(obj_prefix + u'FileListWidget') - importLayout.addWidget(fileListWidget) - buttonLayout = QtGui.QHBoxLayout() - buttonLayout.setObjectName(obj_prefix + u'ButtonLayout') - addButton = QtGui.QPushButton(importWidget) - addButton.setIcon(self.openIcon) - addButton.setObjectName(obj_prefix + u'AddButton') - buttonLayout.addWidget(addButton) - buttonLayout.addStretch() - removeButton = QtGui.QPushButton(importWidget) - removeButton.setIcon(self.deleteIcon) - removeButton.setObjectName(obj_prefix + u'RemoveButton') - buttonLayout.addWidget(removeButton) - importLayout.addLayout(buttonLayout) - self.formatStack.addWidget(page) - setattr(self, prefix + u'Page', page) - setattr(self, prefix + u'FileListWidget', fileListWidget) - setattr(self, prefix + u'ButtonLayout', buttonLayout) - setattr(self, prefix + u'AddButton', addButton) - setattr(self, prefix + u'RemoveButton', removeButton) - if can_disable: - setattr(self, prefix + u'ImportLayout', importLayout) - else: - setattr(self, prefix + u'Layout', importLayout) - self.formatComboBox.addItem(u'') - - def disablableWidget(self, page, prefix, obj_prefix): - layout = QtGui.QVBoxLayout(page) - layout.setMargin(0) - layout.setSpacing(0) - layout.setObjectName(obj_prefix + u'Layout') - disabledWidget = QtGui.QWidget(page) - disabledWidget.setVisible(False) - disabledWidget.setObjectName(obj_prefix + u'DisabledWidget') - disabledLayout = QtGui.QVBoxLayout(disabledWidget) - disabledLayout.setMargin(0) - disabledLayout.setObjectName(obj_prefix + u'DisabledLayout') - disabledLabel = QtGui.QLabel(disabledWidget) - disabledLabel.setWordWrap(True) - disabledLabel.setObjectName(obj_prefix + u'DisabledLabel') - disabledLayout.addWidget(disabledLabel) - layout.addWidget(disabledWidget) - importWidget = QtGui.QWidget(page) - importWidget.setObjectName(obj_prefix + u'ImportWidget') - layout.addWidget(importWidget) - setattr(self, prefix + u'Layout', layout) - setattr(self, prefix + u'DisabledWidget', disabledWidget) - setattr(self, prefix + u'DisabledLayout', disabledLayout) - setattr(self, prefix + u'DisabledLabel', disabledLabel) - setattr(self, prefix + u'ImportWidget', importWidget) - return importWidget diff --git a/openlp/plugins/songs/lib/cclifileimport.py b/openlp/plugins/songs/lib/cclifileimport.py index 1b8531755..2234a81b7 100644 --- a/openlp/plugins/songs/lib/cclifileimport.py +++ b/openlp/plugins/songs/lib/cclifileimport.py @@ -67,7 +67,7 @@ class CCLIFileImport(SongImport): """ log.debug(u'Starting CCLI File Import') song_total = len(self.filenames) - self.import_wizard.importProgressBar.setMaximum(song_total) + self.import_wizard.progressBar.setMaximum(song_total) song_count = 1 for filename in self.filenames: self.import_wizard.incrementProgressBar(unicode(translate( diff --git a/openlp/plugins/songs/lib/ewimport.py b/openlp/plugins/songs/lib/ewimport.py index d74cd284f..312e3b759 100644 --- a/openlp/plugins/songs/lib/ewimport.py +++ b/openlp/plugins/songs/lib/ewimport.py @@ -186,7 +186,7 @@ class EasyWorshipSongImport(SongImport): # There does not appear to be a _reliable_ way of getting the number # of songs/records, so let's use file blocks for measuring progress. total_blocks = (db_size - header_size) / (block_size * 1024) - self.import_wizard.importProgressBar.setMaximum(total_blocks) + self.import_wizard.progressBar.setMaximum(total_blocks) # Read the field description information db_file.seek(120) field_info = db_file.read(num_fields * 2) diff --git a/openlp/plugins/songs/lib/olp1import.py b/openlp/plugins/songs/lib/olp1import.py index ceaee3302..c3e1ca6b4 100644 --- a/openlp/plugins/songs/lib/olp1import.py +++ b/openlp/plugins/songs/lib/olp1import.py @@ -78,7 +78,7 @@ class OpenLP1SongImport(SongImport): cursor.execute(u'SELECT COUNT(songid) FROM songs') count = cursor.fetchone()[0] success = True - self.import_wizard.importProgressBar.setMaximum(count) + self.import_wizard.progressBar.setMaximum(count) # "cache" our list of authors cursor.execute(u'-- types int, unicode') cursor.execute(u'SELECT authorid, authorname FROM authors') diff --git a/openlp/plugins/songs/lib/olpimport.py b/openlp/plugins/songs/lib/olpimport.py index e366ddf4b..d2a00447f 100644 --- a/openlp/plugins/songs/lib/olpimport.py +++ b/openlp/plugins/songs/lib/olpimport.py @@ -146,7 +146,7 @@ class OpenLPSongImport(SongImport): source_songs = self.source_session.query(OldSong).all() song_total = len(source_songs) - self.import_wizard.importProgressBar.setMaximum(song_total) + self.import_wizard.progressBar.setMaximum(song_total) song_count = 1 for song in source_songs: self.import_wizard.incrementProgressBar(unicode(translate( diff --git a/openlp/plugins/songs/lib/oooimport.py b/openlp/plugins/songs/lib/oooimport.py index c5cca4fd6..be33cb8fb 100644 --- a/openlp/plugins/songs/lib/oooimport.py +++ b/openlp/plugins/songs/lib/oooimport.py @@ -63,11 +63,11 @@ class OooImport(SongImport): self.filenames = kwargs[u'filenames'] self.uno_connection_type = u'pipe' #u'socket' QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'song_stop_import'), self.stop_import) + QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import) def do_import(self): self.abort = False - self.import_wizard.importProgressBar.setMaximum(0) + self.import_wizard.progressBar.setMaximum(0) self.start_ooo() for filename in self.filenames: if self.abort: @@ -85,7 +85,7 @@ class OooImport(SongImport): self.process_doc() self.close_ooo_file() self.close_ooo() - self.import_wizard.importProgressBar.setMaximum(1) + self.import_wizard.progressBar.setMaximum(1) self.import_wizard.incrementProgressBar(u'', 1) return True diff --git a/openlp/plugins/songs/lib/openlyricsimport.py b/openlp/plugins/songs/lib/openlyricsimport.py index c4610dfc0..220160b1d 100644 --- a/openlp/plugins/songs/lib/openlyricsimport.py +++ b/openlp/plugins/songs/lib/openlyricsimport.py @@ -60,7 +60,7 @@ class OpenLyricsImport(SongImport): """ Imports the songs. """ - self.import_wizard.importProgressBar.setMaximum(len(self.import_source)) + self.import_wizard.progressBar.setMaximum(len(self.import_source)) for file_path in self.import_source: if self.stop_import_flag: return False @@ -68,8 +68,8 @@ class OpenLyricsImport(SongImport): 'SongsPlugin.OpenLyricsImport', 'Importing %s...')) % os.path.basename(file_path)) parser = etree.XMLParser(remove_blank_text=True) - file = etree.parse(file_path, parser) - xml = unicode(etree.tostring(file)) + parsed_file = etree.parse(file_path, parser) + xml = unicode(etree.tostring(parsed_file)) if self.openLyrics.xml_to_song(xml) is None: log.debug(u'File could not be imported: %s' % file_path) # Importing this song failed! For now we stop import. diff --git a/openlp/plugins/songs/lib/opensongimport.py b/openlp/plugins/songs/lib/opensongimport.py index 6a60fcc6c..eb16f4ba4 100644 --- a/openlp/plugins/songs/lib/opensongimport.py +++ b/openlp/plugins/songs/lib/opensongimport.py @@ -129,7 +129,7 @@ class OpenSongImport(SongImport): else: numfiles += 1 log.debug(u'Total number of files: %d', numfiles) - self.import_wizard.importProgressBar.setMaximum(numfiles) + self.import_wizard.progressBar.setMaximum(numfiles) for filename in self.filenames: if self.stop_import_flag: success = False diff --git a/openlp/plugins/songs/lib/sofimport.py b/openlp/plugins/songs/lib/sofimport.py index 3e6ee8c3a..8475b0824 100644 --- a/openlp/plugins/songs/lib/sofimport.py +++ b/openlp/plugins/songs/lib/sofimport.py @@ -89,7 +89,7 @@ class SofImport(OooImport): self.process_sof_file() self.close_ooo_file() self.close_ooo() - self.import_wizard.importProgressBar.setMaximum(1) + self.import_wizard.progressBar.setMaximum(1) self.import_wizard.incrementProgressBar(u'', 1) return True @@ -550,4 +550,4 @@ class SofImport(OooImport): return 6 if song_number == 1119: return 7 - return None \ No newline at end of file + return None diff --git a/openlp/plugins/songs/lib/songbeamerimport.py b/openlp/plugins/songs/lib/songbeamerimport.py index 12ff53428..c783793db 100644 --- a/openlp/plugins/songs/lib/songbeamerimport.py +++ b/openlp/plugins/songs/lib/songbeamerimport.py @@ -75,7 +75,6 @@ class SongBeamerImport(SongImport): The song manager for the running OpenLP installation. """ SongImport.__init__(self, master_manager) - self.master_manager = master_manager if kwargs.has_key(u'filename'): self.import_source = kwargs[u'filename'] if kwargs.has_key(u'filenames'): @@ -87,7 +86,7 @@ class SongBeamerImport(SongImport): Recieve a single file, or a list of files to import. """ if isinstance(self.import_source, list): - self.import_wizard.importProgressBar.setMaximum( + self.import_wizard.progressBar.setMaximum( len(self.import_source)) for file in self.import_source: # TODO: check that it is a valid SongBeamer file diff --git a/openlp/plugins/songs/lib/songimport.py b/openlp/plugins/songs/lib/songimport.py index 05ed320a9..c1105a578 100644 --- a/openlp/plugins/songs/lib/songimport.py +++ b/openlp/plugins/songs/lib/songimport.py @@ -55,7 +55,7 @@ class SongImport(QtCore.QObject): self.stop_import_flag = False self.set_defaults() QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'songs_stop_import'), self.stop_import) + QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import) def set_defaults(self): """ @@ -364,4 +364,4 @@ class SongImport(QtCore.QObject): if self.theme_name: print u'THEME: ' + self.theme_name if self.ccli_number: - print u'CCLI: ' + self.ccli_number \ No newline at end of file + print u'CCLI: ' + self.ccli_number diff --git a/openlp/plugins/songs/lib/test/test_opensongimport.py b/openlp/plugins/songs/lib/test/test_opensongimport.py index 27c7cca48..fd1d37e3e 100644 --- a/openlp/plugins/songs/lib/test/test_opensongimport.py +++ b/openlp/plugins/songs/lib/test/test_opensongimport.py @@ -35,7 +35,7 @@ logging.basicConfig(filename=LOG_FILENAME,level=logging.INFO) # Stubs to replace the UI functions for raw testing class wizard_stub: def __init__(self): - self.importProgressBar=progbar_stub() + self.progressBar=progbar_stub() def incrementProgressBar(self, str): pass class progbar_stub: diff --git a/openlp/plugins/songs/lib/wowimport.py b/openlp/plugins/songs/lib/wowimport.py index 1d5470f9b..d0c308413 100644 --- a/openlp/plugins/songs/lib/wowimport.py +++ b/openlp/plugins/songs/lib/wowimport.py @@ -99,7 +99,6 @@ class WowImport(SongImport): The song manager for the running OpenLP installation. """ SongImport.__init__(self, master_manager) - self.master_manager = master_manager if kwargs.has_key(u'filename'): self.import_source = kwargs[u'filename'] if kwargs.has_key(u'filenames'): @@ -112,8 +111,7 @@ class WowImport(SongImport): """ if isinstance(self.import_source, list): - self.import_wizard.importProgressBar.setMaximum( - len(self.import_source)) + self.import_wizard.progressBar.setMaximum(len(self.import_source)) for file in self.import_source: self.author = u'' self.copyright = u'' From b25e128495ef41e6354789d3754de69633847ec7 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 14 Jan 2011 15:12:28 +0000 Subject: [PATCH 43/56] Fix Transitions in Bible display bug 701353 Fix display handling on restart so correct screen mode is set Fixes: https://launchpad.net/bugs/701353 --- openlp/core/lib/htmlbuilder.py | 2 +- openlp/core/ui/slidecontroller.py | 41 ++++++++++++++++++++------ openlp/plugins/bibles/lib/mediaitem.py | 8 ++--- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/openlp/core/lib/htmlbuilder.py b/openlp/core/lib/htmlbuilder.py index 0a26382f8..86056f4b5 100644 --- a/openlp/core/lib/htmlbuilder.py +++ b/openlp/core/lib/htmlbuilder.py @@ -641,4 +641,4 @@ def build_alert_css(alertTab, width): align = u'top' alert = style % (width, align, alertTab.font_face, alertTab.font_size, alertTab.font_color, alertTab.bg_color) - return alert \ No newline at end of file + return alert diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 690cb9264..8600f9afc 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -680,8 +680,17 @@ class SlideController(QtGui.QWidget): Allow the main display to blank the main display at startup time """ log.debug(u'mainDisplaySetBackground live = %s' % self.isLive) + display_type = QtCore.QSettings().value( + self.parent.generalSettingsSection + u'/screen blank', + QtCore.QVariant(u'')).toString() if not self.display.primary: - self.onBlankDisplay(True) + # Order done to handle initial conversion + if display_type == u'themed': + self.onThemeDisplay(True) + elif display_type == u'hidden': + self.onHideDisplay(True) + else: + self.onBlankDisplay(True) def onSlideBlank(self): """ @@ -705,13 +714,15 @@ class SlideController(QtGui.QWidget): self.ThemeScreen.setChecked(False) if self.screens.display_count > 1: self.DesktopScreen.setChecked(False) - QtCore.QSettings().setValue( - self.parent.generalSettingsSection + u'/screen blank', - QtCore.QVariant(checked)) if checked: Receiver.send_message(u'maindisplay_hide', HideMode.Blank) + QtCore.QSettings().setValue( + self.parent.generalSettingsSection + u'/screen blank', + QtCore.QVariant(u'blanked')) else: Receiver.send_message(u'maindisplay_show') + QtCore.QSettings().remove( + self.parent.generalSettingsSection + u'/screen blank') self.blankPlugin(checked) def onThemeDisplay(self, checked): @@ -722,12 +733,18 @@ class SlideController(QtGui.QWidget): self.HideMenu.setDefaultAction(self.ThemeScreen) self.BlankScreen.setChecked(False) self.ThemeScreen.setChecked(checked) + if self.screens.display_count > 1: self.DesktopScreen.setChecked(False) if checked: Receiver.send_message(u'maindisplay_hide', HideMode.Theme) + QtCore.QSettings().setValue( + self.parent.generalSettingsSection + u'/screen blank', + QtCore.QVariant(u'themed')) else: Receiver.send_message(u'maindisplay_show') + QtCore.QSettings().remove( + self.parent.generalSettingsSection + u'/screen blank') self.blankPlugin(checked) def onHideDisplay(self, checked): @@ -738,12 +755,19 @@ class SlideController(QtGui.QWidget): self.HideMenu.setDefaultAction(self.DesktopScreen) self.BlankScreen.setChecked(False) self.ThemeScreen.setChecked(False) - if self.screens.display_count > 1: - self.DesktopScreen.setChecked(checked) + # On valid if more than 1 display + if self.screens.display_count <= 1: + return + self.DesktopScreen.setChecked(checked) if checked: Receiver.send_message(u'maindisplay_hide', HideMode.Screen) + QtCore.QSettings().setValue( + self.parent.generalSettingsSection + u'/screen blank', + QtCore.QVariant(u'hidden')) else: Receiver.send_message(u'maindisplay_show') + QtCore.QSettings().remove( + self.parent.generalSettingsSection + u'/screen blank') self.hidePlugin(checked) def blankPlugin(self, blank): @@ -1033,9 +1057,8 @@ class SlideController(QtGui.QWidget): if self.BlankScreen.isChecked: self.BlankScreen.setChecked(False) self.HideMenu.setDefaultAction(self.BlankScreen) - QtCore.QSettings().setValue( - self.parent.generalSettingsSection + u'/screen blank', - QtCore.QVariant(False)) + QtCore.QSettings().remove( + self.parent.generalSettingsSection + u'/screen blank') if self.ThemeScreen.isChecked: self.ThemeScreen.setChecked(False) self.HideMenu.setDefaultAction(self.ThemeScreen) diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 1921fbc6d..646c541b9 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -745,21 +745,21 @@ class BibleMediaItem(MediaManagerItem): second_copyright, second_permissions) if footer not in raw_footer: raw_footer.append(footer) - bible_text = u'%s\u00a0%s\n\n%s\u00a0%s' % (verse_text, text, + bible_text = u'%s%s\n\n%s%s' % (verse_text, text, verse_text, second_text) raw_slides.append(bible_text) bible_text = u'' # If we are 'Verse Per Slide' then create a new slide. elif self.parent.settings_tab.layout_style == 0: - bible_text = u'%s\u00a0%s' % (verse_text, text) + bible_text = u'%s%s' % (verse_text, text) raw_slides.append(bible_text) bible_text = u'' # If we are 'Verse Per Line' then force a new line. elif self.parent.settings_tab.layout_style == 1: - bible_text = u'%s %s\u00a0%s\n' % (bible_text, verse_text, text) + bible_text = u'%s %s%s\n' % (bible_text, verse_text, text) # We have to be 'Continuous'. else: - bible_text = u'%s %s\u00a0%s\n' % (bible_text, verse_text, text) + bible_text = u'%s %s%s\n' % (bible_text, verse_text, text) if not old_item: start_item = item elif self.checkTitle(item, old_item): From be9793f91b2419804ca5f16a8fbf4d23220b7a55 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 14 Jan 2011 16:47:30 +0000 Subject: [PATCH 44/56] Remove old file --- demo_theme.xml | 17 ----------------- openlp/core/ui/slidecontroller.py | 1 - 2 files changed, 18 deletions(-) delete mode 100644 demo_theme.xml diff --git a/demo_theme.xml b/demo_theme.xml deleted file mode 100644 index 118a1d7d4..000000000 --- a/demo_theme.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - openlp.org 2.0 Demo Theme - 2 - ./openlp/core/test/data_for_tests/treesbig.jpg - clBlack - - Tahoma - clWhite - 16 - -1 - $00000001 - -1 - clRed - 2 - 2 - diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 8600f9afc..1ace873ff 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -733,7 +733,6 @@ class SlideController(QtGui.QWidget): self.HideMenu.setDefaultAction(self.ThemeScreen) self.BlankScreen.setChecked(False) self.ThemeScreen.setChecked(checked) - if self.screens.display_count > 1: self.DesktopScreen.setChecked(False) if checked: From 6b2dc8a8bdd437a5f9b7d7e1123845e4812c4c96 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 14 Jan 2011 17:46:59 +0000 Subject: [PATCH 45/56] Remove blank at start of bible verse --- openlp/plugins/bibles/lib/mediaitem.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 831f41098..40deb2244 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -718,12 +718,12 @@ class BibleMediaItem(MediaManagerItem): raw_footer.append(footer) bible_text = u'%s%s\n\n%s%s' % (verse_text, text, verse_text, second_text) - raw_slides.append(bible_text) + raw_slides.append(bible_text.rstrip()) bible_text = u'' # If we are 'Verse Per Slide' then create a new slide. elif self.parent.settings_tab.layout_style == 0: bible_text = u'%s%s' % (verse_text, text) - raw_slides.append(bible_text) + raw_slides.append(bible_text.rstrip()) bible_text = u'' # If we are 'Verse Per Line' then force a new line. elif self.parent.settings_tab.layout_style == 1: @@ -741,7 +741,7 @@ class BibleMediaItem(MediaManagerItem): raw_title.append(self.formatTitle(start_item, item)) # If there are no more items we check whether we have to add bible_text. if bible_text: - raw_slides.append(bible_text) + raw_slides.append(bible_text.lstrip()) bible_text = u'' # Service Item: Capabilities if self.parent.settings_tab.layout_style == 2 and not second_bible: From ecb97881a1b15a6de48520ff6621c4395936fc41 Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Fri, 14 Jan 2011 18:58:47 +0000 Subject: [PATCH 46/56] Refactor file deleting, cleanups --- documentation/api/source/plugins/songs.rst | 3 --- openlp/core/lib/db.py | 10 +++------ openlp/core/ui/maindisplay.py | 2 ++ openlp/core/ui/servicemanager.py | 21 +++++-------------- openlp/core/ui/thememanager.py | 18 ++++++---------- openlp/core/utils/__init__.py | 17 +++++++++++++++ openlp/plugins/images/lib/mediaitem.py | 12 ++++------- .../presentations/lib/impresscontroller.py | 4 ++-- openlp/plugins/songs/lib/cclifileimport.py | 4 ---- 9 files changed, 39 insertions(+), 52 deletions(-) diff --git a/documentation/api/source/plugins/songs.rst b/documentation/api/source/plugins/songs.rst index fed9907a2..1e86ce020 100644 --- a/documentation/api/source/plugins/songs.rst +++ b/documentation/api/source/plugins/songs.rst @@ -72,9 +72,6 @@ Song Importers .. automodule:: openlp.plugins.songs.lib.cclifileimport :members: -.. autoclass:: openlp.plugins.songs.lib.cclifileimport.CCLIFileImportError - :members: - .. automodule:: openlp.plugins.songs.lib.ewimport :members: diff --git a/openlp/core/lib/db.py b/openlp/core/lib/db.py index c2e1243ce..3171730ea 100644 --- a/openlp/core/lib/db.py +++ b/openlp/core/lib/db.py @@ -34,7 +34,7 @@ from sqlalchemy import create_engine, MetaData from sqlalchemy.exceptions import InvalidRequestError from sqlalchemy.orm import scoped_session, sessionmaker -from openlp.core.utils import AppLocation +from openlp.core.utils import AppLocation, delete_file log = logging.getLogger(__name__) @@ -75,11 +75,7 @@ def delete_database(plugin_name, db_file_name=None): else: db_file_path = os.path.join( AppLocation.get_section_data_path(plugin_name), plugin_name) - try: - os.remove(db_file_path) - return True - except OSError: - return False + return delete_file(db_file_path) class BaseModel(object): """ @@ -295,4 +291,4 @@ class Manager(object): if self.is_dirty: engine = create_engine(self.db_url) if self.db_url.startswith(u'sqlite'): - engine.execute("vacuum") \ No newline at end of file + engine.execute("vacuum") diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index ab69cd1e9..273a3c4f0 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -24,6 +24,8 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### """ +The :mod:`maindisplay` module provides the functionality to display screens +and play multimedia within OpenLP. """ import logging import os diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index ffc2bee25..0b5b25e06 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -37,7 +37,8 @@ from openlp.core.lib import OpenLPToolbar, ServiceItem, context_menu_action, \ Receiver, build_icon, ItemCapabilities, SettingsManager, translate, \ ThemeLevel from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm -from openlp.core.utils import AppLocation, file_is_unicode, split_filename +from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \ + split_filename class ServiceManagerList(QtGui.QTreeWidget): """ @@ -445,11 +446,7 @@ class ServiceManager(QtGui.QWidget): file.close() if zip: zip.close() - try: - os.remove(serviceFileName) - except (IOError, OSError): - # if not present do not worry - pass + delete_file(serviceFileName) self.mainwindow.addRecentFile(fileName) self.setModified(False) return True @@ -515,11 +512,7 @@ class ServiceManager(QtGui.QWidget): if serviceItem.is_capable(ItemCapabilities.OnLoadUpdate): Receiver.send_message(u'%s_service_load' % serviceItem.name.lower(), serviceItem) - try: - if os.path.isfile(p_file): - os.remove(p_file) - except (IOError, OSError): - log.exception(u'Failed to remove osd file') + delete_file(p_file) else: QtGui.QMessageBox.critical( self, translate('OpenLP.ServiceManager', 'Error'), @@ -873,11 +866,7 @@ class ServiceManager(QtGui.QWidget): """ for file in os.listdir(self.servicePath): file_path = os.path.join(self.servicePath, file) - try: - if os.path.isfile(file_path): - os.remove(file_path) - except OSError: - log.exception(u'Failed to clean up servicePath') + delete_file(file_path) def onThemeComboBoxSelected(self, currentIndex): """ diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 81e191396..966306eb1 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -37,7 +37,7 @@ from openlp.core.theme import Theme from openlp.core.lib import OpenLPToolbar, ThemeXML, get_text_file_string, \ build_icon, Receiver, SettingsManager, translate, check_item_selected, \ BackgroundType, BackgroundGradientType, check_directory_exists -from openlp.core.utils import AppLocation, file_is_unicode, \ +from openlp.core.utils import AppLocation, delete_file, file_is_unicode, \ get_filesystem_encoding log = logging.getLogger(__name__) @@ -341,9 +341,9 @@ class ThemeManager(QtGui.QWidget): """ self.themelist.remove(theme) thumb = theme + u'.png' + delete_file(os.path.join(self.path, thumb)) + delete_file(os.path.join(self.thumbPath, thumb)) try: - os.remove(os.path.join(self.path, thumb)) - os.remove(os.path.join(self.thumbPath, thumb)) encoding = get_filesystem_encoding() shutil.rmtree(os.path.join(self.path, theme).encode(encoding)) except OSError: @@ -521,11 +521,8 @@ class ThemeManager(QtGui.QWidget): check_directory_exists(theme_dir) if os.path.splitext(ucsfile)[1].lower() in [u'.xml']: xml_data = zip.read(file) - try: - xml_data = xml_data.decode(u'utf-8') - except UnicodeDecodeError: - log.exception(u'Theme XML is not UTF-8 ' - u'encoded.') + xml_data = file_is_unicode(xml_data) + if not xml_data: break filexml = self.checkVersionAndConvert(xml_data) outfile = open(fullpath, u'w') @@ -603,10 +600,7 @@ class ThemeManager(QtGui.QWidget): theme_file = os.path.join(theme_dir, name + u'.xml') if imageTo and self.oldBackgroundImage and \ imageTo != self.oldBackgroundImage: - try: - os.remove(self.oldBackgroundImage) - except OSError: - log.exception(u'Unable to remove old theme background') + delete_file(self.oldBackgroundImage) outfile = None try: outfile = open(theme_file, u'w') diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index d8012f433..b7d95a46d 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -282,6 +282,23 @@ def split_filename(path): else: return os.path.split(path) +def delete_file(file_path_name): + """ + Deletes a file from the system. + + ``file_path_name`` + The file, including path, to delete. + """ + if not file_path_name: + return False + try: + if os.path.exists(file_path_name): + os.remove(file_path_name) + return True + except (IOError, OSError): + log.exception("Unable to delete file %s" % file_path_name) + return False + def get_web_page(url, header=None, update_openlp=False): """ Attempts to download the webpage at url and returns that page or None. diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index 063a80d02..e9f41abcd 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -32,7 +32,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ ItemCapabilities, SettingsManager, translate, check_item_selected, \ Receiver, check_directory_exists -from openlp.core.utils import AppLocation, get_images_filter +from openlp.core.utils import AppLocation, delete_file, get_images_filter log = logging.getLogger(__name__) @@ -115,12 +115,8 @@ class ImageMediaItem(MediaManagerItem): for row in row_list: text = self.listView.item(row) if text: - try: - os.remove(os.path.join(self.servicePath, - unicode(text.text()))) - except OSError: - # if not present do not worry - pass + delete_file(os.path.join(self.servicePath, + unicode(text.text()))) self.listView.takeItem(row) SettingsManager.set_list(self.settingsSection, self.settingsSection, self.getFileList()) @@ -216,4 +212,4 @@ class ImageMediaItem(MediaManagerItem): 'the image file "%s" no longer exists.')) % filename}) def onPreviewClick(self): - MediaManagerItem.onPreviewClick(self) \ No newline at end of file + MediaManagerItem.onPreviewClick(self) diff --git a/openlp/plugins/presentations/lib/impresscontroller.py b/openlp/plugins/presentations/lib/impresscontroller.py index 7c8cf593d..516c595c7 100644 --- a/openlp/plugins/presentations/lib/impresscontroller.py +++ b/openlp/plugins/presentations/lib/impresscontroller.py @@ -51,6 +51,7 @@ else: from PyQt4 import QtCore +from openlp.core.utils import delete_file from presentationcontroller import PresentationController, PresentationDocument log = logging.getLogger(__name__) @@ -292,8 +293,7 @@ class ImpressDocument(PresentationDocument): try: doc.storeToURL(urlpath, props) self.convert_thumbnail(path, idx + 1) - if os.path.exists(path): - os.remove(path) + delete_file(path) except: log.exception(u'%s - Unable to store openoffice preview' % path) diff --git a/openlp/plugins/songs/lib/cclifileimport.py b/openlp/plugins/songs/lib/cclifileimport.py index 2234a81b7..441391d02 100644 --- a/openlp/plugins/songs/lib/cclifileimport.py +++ b/openlp/plugins/songs/lib/cclifileimport.py @@ -34,9 +34,6 @@ from songimport import SongImport log = logging.getLogger(__name__) -class CCLIFileImportError(Exception): - pass - class CCLIFileImport(SongImport): """ The :class:`CCLIFileImport` class provides OpenLP with the ability to @@ -152,7 +149,6 @@ class CCLIFileImport(SongImport): """ log.debug(u'USR file text: %s', textList) - lyrics = [] self.set_defaults() for line in textList: if line.startswith(u'Title='): From 6e2cc7ebffd67cc29db81c5e8f52065b3f05cd61 Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Fri, 14 Jan 2011 21:19:41 +0000 Subject: [PATCH 47/56] Fix db committing too early (Bug #703073) --- openlp/plugins/songs/forms/editsongform.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index 86249f024..52edbdb65 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -331,7 +331,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): else: author = Author.populate(first_name=text.rsplit(u' ', 1)[0], last_name=text.rsplit(u' ', 1)[1], display_name=text) - self.manager.save_object(author) + self.manager.save_object(author, False) author_item = QtGui.QListWidgetItem( unicode(author.display_name)) author_item.setData(QtCore.Qt.UserRole, @@ -386,7 +386,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes: topic = Topic.populate(name=text) - self.manager.save_object(topic) + self.manager.save_object(topic, False) topic_item = QtGui.QListWidgetItem(unicode(topic.name)) topic_item.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id)) @@ -654,7 +654,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): def accept(self): """ - Exit Dialog and save soong if valid + Exit Dialog and save song if valid """ log.debug(u'accept') self.clearCaches() From 2428e9a46a43b70dab37298d3ea9d7b70c83b061 Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Fri, 14 Jan 2011 21:37:32 +0000 Subject: [PATCH 48/56] Fix db fix --- openlp/plugins/songs/forms/editsongform.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index 52edbdb65..0ddcdbcea 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -670,7 +670,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes: book = Book.populate(name=text, publisher=u'') - self.manager.save_object(book) + self.manager.save_object(book, False) else: return if self.saveSong(): From f6a6a7a4fc270a0ade5d6d515bd1657a37639eb5 Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Fri, 14 Jan 2011 22:17:46 +0000 Subject: [PATCH 49/56] Fix db flushing for songs --- openlp/plugins/songs/lib/db.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/plugins/songs/lib/db.py b/openlp/plugins/songs/lib/db.py index fc3aa06d1..faa0a88da 100644 --- a/openlp/plugins/songs/lib/db.py +++ b/openlp/plugins/songs/lib/db.py @@ -72,7 +72,7 @@ def init_schema(url): ``url`` The database to setup """ - session, metadata = init_db(url) + session, metadata = init_db(url, False) # Definition of the "authors" table authors_table = Table(u'authors', metadata, @@ -181,4 +181,4 @@ def init_schema(url): mapper(Topic, topics_table) metadata.create_all(checkfirst=True) - return session \ No newline at end of file + return session From ee6412e2a0b3884e3d5296b702dbb1207e8484e9 Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Sat, 15 Jan 2011 00:53:12 +0000 Subject: [PATCH 50/56] Refactor error messages --- openlp/core/ui/__init__.py | 29 ++++++++- openlp/core/ui/servicemanager.py | 12 ++-- openlp/core/ui/thememanager.py | 20 +++--- openlp/plugins/bibles/lib/mediaitem.py | 12 ++-- openlp/plugins/custom/forms/editcustomform.py | 6 +- openlp/plugins/songs/forms/authorsform.py | 26 +++----- openlp/plugins/songs/forms/editsongform.py | 22 +++---- openlp/plugins/songs/forms/editverseform.py | 5 +- openlp/plugins/songs/forms/songbookform.py | 7 +-- .../songs/forms/songmaintenanceform.py | 61 +++++++------------ openlp/plugins/songs/forms/topicsform.py | 7 +-- 11 files changed, 91 insertions(+), 116 deletions(-) diff --git a/openlp/core/ui/__init__.py b/openlp/core/ui/__init__.py index 698216365..931773b8f 100644 --- a/openlp/core/ui/__init__.py +++ b/openlp/core/ui/__init__.py @@ -26,6 +26,9 @@ """ The :mod:`ui` module provides the core user interface for OpenLP """ +from PyQt4 import QtGui + +from openlp.core.lib import translate class HideMode(object): """ @@ -48,6 +51,26 @@ class HideMode(object): Theme = 2 Screen = 3 + +def criticalErrorMessageBox(parent, message, question=False): + """ + Provides a standard critical message box for errors that OpenLP displays + to users. + + ``parent`` + The parent UI element to attach the dialog to. + + ``message`` + The message to display to the user. + """ + if question: + return QtGui.QMessageBox.critical(parent, + translate('OpenLP.Ui', 'Error'), + message, QtGui.QMessageBox.StandardButtons( + QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)) + return QtGui.QMessageBox.critical(parent, translate('OpenLP.Ui', 'Error'), + message) + from themeform import ThemeForm from filerenameform import FileRenameForm from maindisplay import MainDisplay @@ -68,6 +91,6 @@ from mediadockmanager import MediaDockManager from servicemanager import ServiceManager from thememanager import ThemeManager -__all__ = ['SplashScreen', 'AboutForm', 'SettingsForm', - 'MainDisplay', 'SlideController', 'ServiceManager', 'ThemeManager', - 'MediaDockManager', 'ServiceItemEditForm'] +__all__ = ['criticalErrorMessageBox', 'SplashScreen', 'AboutForm', + 'SettingsForm', 'MainDisplay', 'SlideController', 'ServiceManager', + 'ThemeManager', 'MediaDockManager', 'ServiceItemEditForm'] diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index ffc2bee25..229590fa5 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -36,7 +36,8 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import OpenLPToolbar, ServiceItem, context_menu_action, \ Receiver, build_icon, ItemCapabilities, SettingsManager, translate, \ ThemeLevel -from openlp.core.ui import ServiceNoteForm, ServiceItemEditForm +from openlp.core.ui import criticalErrorMessageBox, ServiceNoteForm, \ + ServiceItemEditForm from openlp.core.utils import AppLocation, file_is_unicode, split_filename class ServiceManagerList(QtGui.QTreeWidget): @@ -486,8 +487,7 @@ class ServiceManager(QtGui.QWidget): for file in zip.namelist(): ucsfile = file_is_unicode(file) if not ucsfile: - QtGui.QMessageBox.critical( - self, translate('OpenLP.ServiceManager', 'Error'), + criticalErrorMessageBox(self, translate('OpenLP.ServiceManager', 'File is not a valid service.\n' 'The content encoding is not UTF-8.')) @@ -521,10 +521,8 @@ class ServiceManager(QtGui.QWidget): except (IOError, OSError): log.exception(u'Failed to remove osd file') else: - QtGui.QMessageBox.critical( - self, translate('OpenLP.ServiceManager', 'Error'), - translate('OpenLP.ServiceManager', - 'File is not a valid service.')) + criticalErrorMessageBox(self, translate('OpenLP.ServiceManager', + 'File is not a valid service.')) log.exception(u'File contains no service data') except (IOError, NameError): log.exception(u'Problem loading a service file') diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 81e191396..ccea7faaf 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -32,7 +32,7 @@ import logging from xml.etree.ElementTree import ElementTree, XML from PyQt4 import QtCore, QtGui -from openlp.core.ui import FileRenameForm, ThemeForm +from openlp.core.ui import criticalErrorMessageBox, FileRenameForm, ThemeForm from openlp.core.theme import Theme from openlp.core.lib import OpenLPToolbar, ThemeXML, get_text_file_string, \ build_icon, Receiver, SettingsManager, translate, check_item_selected, \ @@ -359,9 +359,7 @@ class ThemeManager(QtGui.QWidget): """ item = self.themeListWidget.currentItem() if item is None: - QtGui.QMessageBox.critical(self, - translate('OpenLP.ThemeManager', 'Error'), - translate('OpenLP.ThemeManager', + criticalErrorMessageBox(self, translate('OpenLP.ThemeManager', 'You have not selected a theme.')) return theme = unicode(item.data(QtCore.Qt.UserRole).toString()) @@ -498,11 +496,9 @@ class ThemeManager(QtGui.QWidget): for file in zip.namelist(): ucsfile = file_is_unicode(file) if not ucsfile: - QtGui.QMessageBox.critical( - self, translate('OpenLP.ThemeManager', 'Error'), - translate('OpenLP.ThemeManager', - 'File is not a valid theme.\n' - 'The content encoding is not UTF-8.')) + criticalErrorMessageBox(self, + translate('OpenLP.ThemeManager', 'File is not a valid ' + 'theme.\nThe content encoding is not UTF-8.')) continue osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile)) theme_dir = None @@ -700,10 +696,8 @@ class ThemeManager(QtGui.QWidget): return False # should be the same unless default if theme != unicode(item.data(QtCore.Qt.UserRole).toString()): - QtGui.QMessageBox.critical(self, - translate('OpenLP.ThemeManager', 'Error'), - translate('OpenLP.ThemeManager', - 'You are unable to delete the default theme.')) + criticalErrorMessageBox(self, translate('OpenLP.ThemeManager', + 'You are unable to delete the default theme.')) return False # check for use in the system else where. if testPlugin: diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index d60afccd5..81dd1777b 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -534,13 +534,11 @@ class BibleMediaItem(MediaManagerItem): if item_second_bible and second_bible or not item_second_bible and \ not second_bible: self.displayResults(bible, second_bible) - elif QtGui.QMessageBox.critical(self, - translate('BiblePlugin.MediaItem', 'Error'), + elif criticalErrorMessageBox(self, translate('BiblePlugin.MediaItem', 'You cannot combine single ' 'and second bible verses. Do you want to delete your search ' 'results and start a new search?'), - QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | - QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.Yes: + True) == QtGui.QMessageBox.Yes: self.listView.clear() self.displayResults(bible, second_bible) else: @@ -584,13 +582,11 @@ class BibleMediaItem(MediaManagerItem): if item_second_bible and second_bible or not item_second_bible and \ not second_bible: self.displayResults(bible, second_bible) - elif QtGui.QMessageBox.critical(self, - translate('BiblePlugin.MediaItem', 'Error'), + elif criticalErrorMessageBox(self, translate('BiblePlugin.MediaItem', 'You cannot combine single ' 'and second bible verses. Do you want to delete your search ' 'results and start a new search?'), - QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | - QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.Yes: + True) == QtGui.QMessageBox.Yes: self.listView.clear() self.displayResults(bible, second_bible) elif self.search_results: diff --git a/openlp/plugins/custom/forms/editcustomform.py b/openlp/plugins/custom/forms/editcustomform.py index 2f005828a..794fde9e8 100644 --- a/openlp/plugins/custom/forms/editcustomform.py +++ b/openlp/plugins/custom/forms/editcustomform.py @@ -29,6 +29,7 @@ import logging from PyQt4 import QtCore, QtGui from openlp.core.lib import Receiver, translate +from openlp.core.ui import criticalErrorMessageBox from openlp.plugins.custom.lib import CustomXMLBuilder, CustomXMLParser from openlp.plugins.custom.lib.db import CustomSlide from editcustomdialog import Ui_CustomEditDialog @@ -151,8 +152,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog): """ valid, message = self._validate() if not valid: - QtGui.QMessageBox.critical(self, - translate('CustomPlugin.EditCustomForm', 'Error'), message) + criticalErrorMessageBox(self, message) return False sxml = CustomXMLBuilder() sxml.new_document() @@ -265,4 +265,4 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog): if self.slideListView.count() == 0: return False, translate('CustomPlugin.EditCustomForm', 'You need to add at least one slide') - return True, u'' \ No newline at end of file + return True, u'' diff --git a/openlp/plugins/songs/forms/authorsform.py b/openlp/plugins/songs/forms/authorsform.py index 320d3c1d3..09f361816 100644 --- a/openlp/plugins/songs/forms/authorsform.py +++ b/openlp/plugins/songs/forms/authorsform.py @@ -27,6 +27,7 @@ from PyQt4 import QtGui, QtCore from openlp.core.lib import translate +from openlp.core.ui import criticalErrorMessageBox from openlp.plugins.songs.forms.authorsdialog import Ui_AuthorsDialog class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog): @@ -79,28 +80,21 @@ class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog): def accept(self): if not self.firstNameEdit.text(): - QtGui.QMessageBox.critical( - self, translate('SongsPlugin.AuthorsForm', 'Error'), - translate('SongsPlugin.AuthorsForm', - 'You need to type in the first name of the author.')) + criticalErrorMessageBox(self, translate('SongsPlugin.AuthorsForm', + 'You need to type in the first name of the author.')) self.firstNameEdit.setFocus() return False elif not self.lastNameEdit.text(): - QtGui.QMessageBox.critical( - self, translate('SongsPlugin.AuthorsForm', 'Error'), - translate('SongsPlugin.AuthorsForm', - 'You need to type in the last name of the author.')) + criticalErrorMessageBox(self, translate('SongsPlugin.AuthorsForm', + 'You need to type in the last name of the author.')) self.lastNameEdit.setFocus() return False elif not self.displayEdit.text(): - if QtGui.QMessageBox.critical( - self, translate('SongsPlugin.AuthorsForm', 'Error'), - translate('SongsPlugin.AuthorsForm', - 'You have not set a display name for the ' - 'author, combine the first and last names?'), - QtGui.QMessageBox.StandardButtons( - QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) - ) == QtGui.QMessageBox.Yes: + if criticalErrorMessageBox(self, + translate('SongsPlugin.AuthorsForm', + 'You have not set a display name for the ' + 'author, combine the first and last names?'), + True) == QtGui.QMessageBox.Yes: self.displayEdit.setText(self.firstNameEdit.text() + \ u' ' + self.lastNameEdit.text()) return QtGui.QDialog.accept(self) diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index 86249f024..980f00076 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -30,6 +30,7 @@ import re from PyQt4 import QtCore, QtGui from openlp.core.lib import Receiver, translate +from openlp.core.ui import criticalErrorMessageBox from openlp.plugins.songs.forms import EditVerseForm from openlp.plugins.songs.lib import SongXML, VerseType from openlp.plugins.songs.lib.db import Book, Song, Author, Topic @@ -346,8 +347,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): author = self.manager.get_object(Author, item_id) if self.authorsListView.findItems(unicode(author.display_name), QtCore.Qt.MatchExactly): - QtGui.QMessageBox.warning(self, - translate('SongsPlugin.EditSongForm', 'Error'), + criticalErrorMessageBox(self, translate('SongsPlugin.EditSongForm', 'This author is ' 'already in the list.')) else: @@ -400,8 +400,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): topic = self.manager.get_object(Topic, item_id) if self.topicsListView.findItems(unicode(topic.name), QtCore.Qt.MatchExactly): - QtGui.QMessageBox.warning(self, - translate('SongsPlugin.EditSongForm', 'Error'), + criticalErrorMessageBox(self, translate('SongsPlugin.EditSongForm', 'This topic is ' 'already in the list.')) else: @@ -533,25 +532,19 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): if len(self.titleEdit.displayText()) == 0: self.songTabWidget.setCurrentIndex(0) self.titleEdit.setFocus() - QtGui.QMessageBox.critical(self, - translate('SongsPlugin.EditSongForm', 'Error'), - translate('SongsPlugin.EditSongForm', + criticalErrorMessageBox(self, translate('SongsPlugin.EditSongForm', 'You need to type in a song title.')) return False if self.verseListWidget.rowCount() == 0: self.songTabWidget.setCurrentIndex(0) self.verseListWidget.setFocus() - QtGui.QMessageBox.critical(self, - translate('SongsPlugin.EditSongForm', 'Error'), - translate('SongsPlugin.EditSongForm', + criticalErrorMessageBox(self, translate('SongsPlugin.EditSongForm', 'You need to type in at least one verse.')) return False if self.authorsListView.count() == 0: self.songTabWidget.setCurrentIndex(1) self.authorsListView.setFocus() - QtGui.QMessageBox.critical(self, - translate('SongsPlugin.EditSongForm', 'Warning'), - translate('SongsPlugin.EditSongForm', + criticalErrorMessageBox(self, translate('SongsPlugin.EditSongForm', 'You need to have an author for this song.')) return False if self.song.verse_order: @@ -578,8 +571,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): valid = verses.pop(0) for verse in verses: valid = valid + u', ' + verse - QtGui.QMessageBox.critical(self, - translate('SongsPlugin.EditSongForm', 'Error'), + criticalErrorMessageBox(self, unicode(translate('SongsPlugin.EditSongForm', 'The verse order is invalid. There is no verse ' 'corresponding to %s. Valid entries are %s.')) % \ diff --git a/openlp/plugins/songs/forms/editverseform.py b/openlp/plugins/songs/forms/editverseform.py index c01ad9726..93a259274 100644 --- a/openlp/plugins/songs/forms/editverseform.py +++ b/openlp/plugins/songs/forms/editverseform.py @@ -29,6 +29,7 @@ import logging from PyQt4 import QtCore, QtGui +from openlp.core.ui import criticalErrorMessageBox from openlp.plugins.songs.lib import VerseType, translate from editversedialog import Ui_EditVerseDialog @@ -167,9 +168,7 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog): else: value = self.getVerse()[0].split(u'\n')[1] if len(value) == 0: - QtGui.QMessageBox.critical(self, - translate('SongsPlugin.EditSongForm', 'Error'), - translate('SongsPlugin.EditSongForm', + criticalErrorMessageBox(self, translate('SongsPlugin.EditSongForm', 'You need to type some text in to the verse.')) return False QtGui.QDialog.accept(self) diff --git a/openlp/plugins/songs/forms/songbookform.py b/openlp/plugins/songs/forms/songbookform.py index 4a4a08ff6..96d4fdf1b 100644 --- a/openlp/plugins/songs/forms/songbookform.py +++ b/openlp/plugins/songs/forms/songbookform.py @@ -27,6 +27,7 @@ from PyQt4 import QtGui from openlp.core.lib import translate +from openlp.core.ui import criticalErrorMessageBox from openlp.plugins.songs.forms.songbookdialog import Ui_SongBookDialog class SongBookForm(QtGui.QDialog, Ui_SongBookDialog): @@ -49,10 +50,8 @@ class SongBookForm(QtGui.QDialog, Ui_SongBookDialog): def accept(self): if not self.nameEdit.text(): - QtGui.QMessageBox.critical( - self, translate('SongsPlugin.SongBookForm', 'Error'), - translate('SongsPlugin.SongBookForm', - 'You need to type in a name for the book.')) + criticalErrorMessageBox(self, translate('SongsPlugin.SongBookForm', + 'You need to type in a name for the book.')) self.nameEdit.setFocus() return False else: diff --git a/openlp/plugins/songs/forms/songmaintenanceform.py b/openlp/plugins/songs/forms/songmaintenanceform.py index c964c5192..4dc9361c5 100644 --- a/openlp/plugins/songs/forms/songmaintenanceform.py +++ b/openlp/plugins/songs/forms/songmaintenanceform.py @@ -23,15 +23,19 @@ # with this program; if not, write to the Free Software Foundation, Inc., 59 # # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### +import logging from PyQt4 import QtGui, QtCore from sqlalchemy.sql import and_ from openlp.core.lib import Receiver, translate +from openlp.core.ui import criticalErrorMessageBox from openlp.plugins.songs.forms import AuthorsForm, TopicsForm, SongBookForm from openlp.plugins.songs.lib.db import Author, Book, Topic, Song from songmaintenancedialog import Ui_SongMaintenanceDialog +log = logging.getLogger(__name__) + class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): """ Class documentation goes here. @@ -229,13 +233,11 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): if self.manager.save_object(author): self.resetAuthors() else: - QtGui.QMessageBox.critical(self, - translate('SongsPlugin.SongMaintenanceForm', 'Error'), + criticalErrorMessageBox(self, translate('SongsPlugin.SongMaintenanceForm', 'Could not add your author.')) else: - QtGui.QMessageBox.critical(self, - translate('SongsPlugin.SongMaintenanceForm', 'Error'), + criticalErrorMessageBox(self, translate('SongsPlugin.SongMaintenanceForm', 'This author already exists.')) @@ -246,13 +248,11 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): if self.manager.save_object(topic): self.resetTopics() else: - QtGui.QMessageBox.critical(self, - translate('SongsPlugin.SongMaintenanceForm', 'Error'), + criticalErrorMessageBox(self, translate('SongsPlugin.SongMaintenanceForm', 'Could not add your topic.')) else: - QtGui.QMessageBox.critical(self, - translate('SongsPlugin.SongMaintenanceForm', 'Error'), + criticalErrorMessageBox(self, translate('SongsPlugin.SongMaintenanceForm', 'This topic already exists.')) @@ -264,13 +264,11 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): if self.manager.save_object(book): self.resetBooks() else: - QtGui.QMessageBox.critical(self, - translate('SongsPlugin.SongMaintenanceForm', 'Error'), + criticalErrorMessageBox(self, translate('SongsPlugin.SongMaintenanceForm', 'Could not add your book.')) else: - QtGui.QMessageBox.critical(self, - translate('SongsPlugin.SongMaintenanceForm', 'Error'), + criticalErrorMessageBox(self, translate('SongsPlugin.SongMaintenanceForm', 'This book already exists.')) @@ -298,20 +296,15 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): self.resetAuthors() Receiver.send_message(u'songs_load_list') else: - QtGui.QMessageBox.critical(self, - translate('SongsPlugin.SongMaintenanceForm', - 'Error'), + criticalErrorMessageBox(self, translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.')) - elif QtGui.QMessageBox.critical(self, - translate('SongsPlugin.SongMaintenanceForm', 'Error'), + elif criticalErrorMessageBox(self, unicode(translate('SongsPlugin.SongMaintenanceForm', 'The author %s already exists. Would you like to make songs' ' with author %s use the existing author %s?')) % (author.display_name, temp_display_name, - author.display_name), QtGui.QMessageBox.StandardButtons( - QtGui.QMessageBox.No | QtGui.QMessageBox.Yes)) == \ - QtGui.QMessageBox.Yes: + author.display_name), True) == QtGui.QMessageBox.Yes: self.mergeAuthors(author) self.resetAuthors() Receiver.send_message(u'songs_load_list') @@ -321,8 +314,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): author.first_name = temp_first_name author.last_name = temp_last_name author.display_name = temp_display_name - QtGui.QMessageBox.critical(self, - translate('SongsPlugin.SongMaintenanceForm', 'Error'), + criticalErrorMessageBox(self, translate('SongsPlugin.SongMaintenanceForm', 'Could not save your modified author, because the ' 'author already exists.')) @@ -340,26 +332,20 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): if self.manager.save_object(topic): self.resetTopics() else: - QtGui.QMessageBox.critical(self, - translate('SongsPlugin.SongMaintenanceForm', - 'Error'), + criticalErrorMessageBox(self, translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.')) - elif QtGui.QMessageBox.critical(self, - translate('SongsPlugin.SongMaintenanceForm', 'Error'), + elif criticalErrorMessageBox(self, unicode(translate('SongsPlugin.SongMaintenanceForm', 'The topic %s already exists. Would you like to make songs ' 'with topic %s use the existing topic %s?')) % (topic.name, - temp_name, topic.name), QtGui.QMessageBox.StandardButtons( - QtGui.QMessageBox.No | QtGui.QMessageBox.Yes)) == \ - QtGui.QMessageBox.Yes: + temp_name, topic.name), True) == QtGui.QMessageBox.Yes: self.mergeTopics(topic) self.resetTopics() else: # We restore the topics's old name. topic.name = temp_name - QtGui.QMessageBox.critical(self, - translate('SongsPlugin.SongMaintenanceForm', 'Error'), + criticalErrorMessageBox(self, translate('SongsPlugin.SongMaintenanceForm', 'Could not save your modified topic, because it ' 'already exists.')) @@ -383,19 +369,14 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): if self.manager.save_object(book): self.resetBooks() else: - QtGui.QMessageBox.critical(self, - translate('SongsPlugin.SongMaintenanceForm', - 'Error'), + criticalErrorMessageBox(self, translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.')) - elif QtGui.QMessageBox.critical(self, - translate('SongsPlugin.SongMaintenanceForm', 'Error'), + elif criticalErrorMessageBox(self, unicode(translate('SongsPlugin.SongMaintenanceForm', 'The book %s already exists. Would you like to make songs ' 'with book %s use the existing book %s?')) % (book.name, - temp_name, book.name), QtGui.QMessageBox.StandardButtons( - QtGui.QMessageBox.No | QtGui.QMessageBox.Yes)) == \ - QtGui.QMessageBox.Yes: + temp_name, book.name), True) == QtGui.QMessageBox.Yes: self.mergeBooks(book) self.resetBooks() else: diff --git a/openlp/plugins/songs/forms/topicsform.py b/openlp/plugins/songs/forms/topicsform.py index 1ff827423..5b330b384 100644 --- a/openlp/plugins/songs/forms/topicsform.py +++ b/openlp/plugins/songs/forms/topicsform.py @@ -27,6 +27,7 @@ from PyQt4 import QtGui from openlp.core.lib import translate +from openlp.core.ui import criticalErrorMessageBox from openlp.plugins.songs.forms.topicsdialog import Ui_TopicsDialog class TopicsForm(QtGui.QDialog, Ui_TopicsDialog): @@ -48,10 +49,8 @@ class TopicsForm(QtGui.QDialog, Ui_TopicsDialog): def accept(self): if not self.nameEdit.text(): - QtGui.QMessageBox.critical( - self, translate('SongsPlugin.TopicsForm', 'Error'), - translate('SongsPlugin.TopicsForm', - 'You need to type in a topic name.')) + criticalErrorMessageBox(self, translate('SongsPlugin.TopicsForm', + 'You need to type in a topic name.')) self.nameEdit.setFocus() return False else: From 054f3a41427b04b37db3775faf243f64255f2237 Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Sat, 15 Jan 2011 00:55:38 +0000 Subject: [PATCH 51/56] Remove duplicated translate --- openlp/core/ui/__init__.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/openlp/core/ui/__init__.py b/openlp/core/ui/__init__.py index 931773b8f..9d7de0726 100644 --- a/openlp/core/ui/__init__.py +++ b/openlp/core/ui/__init__.py @@ -63,13 +63,12 @@ def criticalErrorMessageBox(parent, message, question=False): ``message`` The message to display to the user. """ + error = translate('OpenLP.Ui', 'Error') if question: - return QtGui.QMessageBox.critical(parent, - translate('OpenLP.Ui', 'Error'), - message, QtGui.QMessageBox.StandardButtons( + return QtGui.QMessageBox.critical(parent, error, message, + QtGui.QMessageBox.StandardButtons( QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)) - return QtGui.QMessageBox.critical(parent, translate('OpenLP.Ui', 'Error'), - message) + return QtGui.QMessageBox.critical(parent, error, message) from themeform import ThemeForm from filerenameform import FileRenameForm From 2c958d04cd88bb64ce383270b69ed5eb62e0d7e6 Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Sat, 15 Jan 2011 01:25:49 +0000 Subject: [PATCH 52/56] Fix docstring --- openlp/core/ui/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openlp/core/ui/__init__.py b/openlp/core/ui/__init__.py index 9d7de0726..9c43f9da6 100644 --- a/openlp/core/ui/__init__.py +++ b/openlp/core/ui/__init__.py @@ -62,6 +62,9 @@ def criticalErrorMessageBox(parent, message, question=False): ``message`` The message to display to the user. + + ``question`` + Should this message box question the user. """ error = translate('OpenLP.Ui', 'Error') if question: From e33628e049021058f246160171f363ea8093ab3d Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 15 Jan 2011 11:56:40 +0000 Subject: [PATCH 53/56] Merge fixes --- openlp/core/lib/__init__.py | 1 + openlp/core/ui/thememanager.py | 34 +++++++++++++------------- openlp/plugins/bibles/lib/mediaitem.py | 8 +++--- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index 7ad377817..76d7c0617 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -293,6 +293,7 @@ def clean_tags(text): Remove Tags from text for display """ text = text.replace(u'
', u'\n') + text = text.replace(u' ', u' ') for tag in DisplayTags.get_html_tags(): text = text.replace(tag[u'start tag'], u'') text = text.replace(tag[u'end tag'], u'') diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 81e191396..b0f3d6147 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -527,7 +527,7 @@ class ThemeManager(QtGui.QWidget): log.exception(u'Theme XML is not UTF-8 ' u'encoded.') break - filexml = self.checkVersionAndConvert(xml_data) + filexml = self._checkVersionAndConvert(xml_data) outfile = open(fullpath, u'w') outfile.write(filexml.encode(u'utf-8')) else: @@ -557,22 +557,6 @@ class ThemeManager(QtGui.QWidget): if outfile: outfile.close() - def checkVersionAndConvert(self, xml_data): - """ - Check if a theme is from OpenLP version 1 - - ``xml_data`` - Theme XML to check the version of - """ - log.debug(u'checkVersion1 ') - theme = xml_data.encode(u'ascii', u'xmlcharrefreplace') - tree = ElementTree(element=XML(theme)).getroot() - # look for old version 1 tags - if tree.find(u'BackgroundType') is None: - return xml_data - else: - return self._migrateVersion122(xml_data) - def checkIfThemeExists(self, themeName): """ Check if theme already exists and displays error message @@ -667,6 +651,22 @@ class ThemeManager(QtGui.QWidget): image = os.path.join(self.path, theme + u'.png') return image + def _checkVersionAndConvert(self, xml_data): + """ + Check if a theme is from OpenLP version 1 + + ``xml_data`` + Theme XML to check the version of + """ + log.debug(u'checkVersion1 ') + theme = xml_data.encode(u'ascii', u'xmlcharrefreplace') + tree = ElementTree(element=XML(theme)).getroot() + # look for old version 1 tags + if tree.find(u'BackgroundType') is None: + return xml_data + else: + return self._migrateVersion122(xml_data) + def _createThemeFromXml(self, themeXml, path): """ Return a theme object using information parsed from XML diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 40deb2244..20adc97fe 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -716,21 +716,21 @@ class BibleMediaItem(MediaManagerItem): second_copyright, second_permissions) if footer not in raw_footer: raw_footer.append(footer) - bible_text = u'%s%s\n\n%s%s' % (verse_text, text, + bible_text = u'%s %s\n\n%s%s' % (verse_text, text, verse_text, second_text) raw_slides.append(bible_text.rstrip()) bible_text = u'' # If we are 'Verse Per Slide' then create a new slide. elif self.parent.settings_tab.layout_style == 0: - bible_text = u'%s%s' % (verse_text, text) + bible_text = u'%s %s' % (verse_text, text) raw_slides.append(bible_text.rstrip()) bible_text = u'' # If we are 'Verse Per Line' then force a new line. elif self.parent.settings_tab.layout_style == 1: - bible_text = u'%s %s%s\n' % (bible_text, verse_text, text) + bible_text = u'%s %s %s\n' % (bible_text, verse_text, text) # We have to be 'Continuous'. else: - bible_text = u'%s %s%s\n' % (bible_text, verse_text, text) + bible_text = u'%s %s %s\n' % (bible_text, verse_text, text) if not old_item: start_item = item elif self.checkTitle(item, old_item): From 4027e4eed794163c0203b0f15467613f448bab08 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 15 Jan 2011 12:14:24 +0000 Subject: [PATCH 54/56] Missed one! --- openlp/plugins/bibles/lib/mediaitem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 20adc97fe..7ee450c8a 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -716,7 +716,7 @@ class BibleMediaItem(MediaManagerItem): second_copyright, second_permissions) if footer not in raw_footer: raw_footer.append(footer) - bible_text = u'%s %s\n\n%s%s' % (verse_text, text, + bible_text = u'%s %s\n\n%s %s' % (verse_text, text, verse_text, second_text) raw_slides.append(bible_text.rstrip()) bible_text = u'' From 284402b7b27e401f7769bd66597c991ae6bd83b2 Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Sat, 15 Jan 2011 19:24:50 +0000 Subject: [PATCH 55/56] Refactor in existing error framework --- openlp/core/ui/__init__.py | 16 ++-- openlp/core/ui/displaytagtab.py | 13 ++- openlp/core/ui/servicemanager.py | 19 ++--- openlp/core/ui/themeform.py | 13 ++- openlp/core/ui/thememanager.py | 50 ++++++------ .../plugins/bibles/forms/bibleimportform.py | 17 ++-- openlp/plugins/bibles/lib/db.py | 10 +-- openlp/plugins/bibles/lib/http.py | 28 +++---- openlp/plugins/bibles/lib/mediaitem.py | 27 +++---- openlp/plugins/custom/forms/editcustomform.py | 2 +- openlp/plugins/images/lib/mediaitem.py | 16 ++-- openlp/plugins/media/lib/mediaitem.py | 16 ++-- openlp/plugins/presentations/lib/mediaitem.py | 9 ++- openlp/plugins/songs/forms/authorsform.py | 10 +-- openlp/plugins/songs/forms/editsongform.py | 25 +++--- openlp/plugins/songs/forms/editverseform.py | 3 +- openlp/plugins/songs/forms/songbookform.py | 3 +- openlp/plugins/songs/forms/songimportform.py | 21 ++--- .../songs/forms/songmaintenanceform.py | 79 ++++++++++--------- openlp/plugins/songs/forms/topicsform.py | 2 +- 20 files changed, 190 insertions(+), 189 deletions(-) diff --git a/openlp/core/ui/__init__.py b/openlp/core/ui/__init__.py index 9c43f9da6..80124c2be 100644 --- a/openlp/core/ui/__init__.py +++ b/openlp/core/ui/__init__.py @@ -28,7 +28,7 @@ The :mod:`ui` module provides the core user interface for OpenLP """ from PyQt4 import QtGui -from openlp.core.lib import translate +from openlp.core.lib import translate, Receiver class HideMode(object): """ @@ -52,17 +52,21 @@ class HideMode(object): Screen = 3 -def criticalErrorMessageBox(parent, message, question=False): +def criticalErrorMessageBox(title=None, message=None, parent=None, + question=False): """ Provides a standard critical message box for errors that OpenLP displays to users. - ``parent`` - The parent UI element to attach the dialog to. + ``title`` + The title for the message box. ``message`` The message to display to the user. + ``parent`` + The parent UI element to attach the dialog to. + ``question`` Should this message box question the user. """ @@ -71,7 +75,9 @@ def criticalErrorMessageBox(parent, message, question=False): return QtGui.QMessageBox.critical(parent, error, message, QtGui.QMessageBox.StandardButtons( QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)) - return QtGui.QMessageBox.critical(parent, error, message) + data = {u'message': message} + data[u'title'] = title if title else error + return Receiver.send_message(u'openlp_error_message', data) from themeform import ThemeForm from filerenameform import FileRenameForm diff --git a/openlp/core/ui/displaytagtab.py b/openlp/core/ui/displaytagtab.py index 154d397b9..1c77084b9 100644 --- a/openlp/core/ui/displaytagtab.py +++ b/openlp/core/ui/displaytagtab.py @@ -34,6 +34,7 @@ import cPickle from PyQt4 import QtCore, QtGui from openlp.core.lib import SettingsTab, translate, DisplayTags +from openlp.core.ui import criticalErrorMessageBox class DisplayTagTab(SettingsTab): ''' @@ -275,12 +276,10 @@ class DisplayTagTab(SettingsTab): """ for html in DisplayTags.get_html_tags(): if self._strip(html[u'start tag']) == u'n': - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('OpenLP.DisplayTagTab', 'Update Error'), translate('OpenLP.DisplayTagTab', - 'Tag "n" already defined.'), - QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok), - QtGui.QMessageBox.Ok) + 'Tag "n" already defined.')) return # Add new tag to list tag = {u'desc': u'New Item', u'start tag': u'{n}', @@ -318,12 +317,10 @@ class DisplayTagTab(SettingsTab): for linenumber, html1 in enumerate(html_expands): if self._strip(html1[u'start tag']) == tag and \ linenumber != self.selected: - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('OpenLP.DisplayTagTab', 'Update Error'), unicode(translate('OpenLP.DisplayTagTab', - 'Tag %s already defined.')) % tag, - QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok), - QtGui.QMessageBox.Ok) + 'Tag %s already defined.')) % tag) return html[u'desc'] = unicode(self.descriptionLineEdit.text()) html[u'start html'] = unicode(self.startTagLineEdit.text()) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 229590fa5..fcc601de3 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -487,10 +487,10 @@ class ServiceManager(QtGui.QWidget): for file in zip.namelist(): ucsfile = file_is_unicode(file) if not ucsfile: - criticalErrorMessageBox(self, - translate('OpenLP.ServiceManager', - 'File is not a valid service.\n' - 'The content encoding is not UTF-8.')) + criticalErrorMessageBox( + message=translate('OpenLP.ServiceManager', + 'File is not a valid service.\n' + 'The content encoding is not UTF-8.')) continue osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile)) filePath = os.path.join(self.servicePath, @@ -521,7 +521,8 @@ class ServiceManager(QtGui.QWidget): except (IOError, OSError): log.exception(u'Failed to remove osd file') else: - criticalErrorMessageBox(self, translate('OpenLP.ServiceManager', + criticalErrorMessageBox( + message=translate('OpenLP.ServiceManager', 'File is not a valid service.')) log.exception(u'File contains no service data') except (IOError, NameError): @@ -1002,7 +1003,7 @@ class ServiceManager(QtGui.QWidget): self.mainwindow.previewController.addServiceManagerItem( self.serviceItems[item][u'service_item'], count) else: - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('OpenLP.ServiceManager', 'Missing Display Handler'), translate('OpenLP.ServiceManager', 'Your item cannot be ' 'displayed as there is no handler to display it')) @@ -1036,11 +1037,11 @@ class ServiceManager(QtGui.QWidget): self.serviceItems[item][u'service_item'], 0) self.mainwindow.liveController.PreviewListWidget.setFocus() else: - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('OpenLP.ServiceManager', 'Missing Display Handler'), translate('OpenLP.ServiceManager', 'Your item cannot be ' - 'displayed as the plugin required to display it is missing ' - 'or inactive')) + 'displayed as the plugin required to display it is missing ' + 'or inactive')) def remoteEdit(self): """ diff --git a/openlp/core/ui/themeform.py b/openlp/core/ui/themeform.py index f8236a1eb..0925023bd 100644 --- a/openlp/core/ui/themeform.py +++ b/openlp/core/ui/themeform.py @@ -31,6 +31,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import translate, BackgroundType, BackgroundGradientType, \ Receiver +from openlp.core.ui import criticalErrorMessage from openlp.core.utils import get_images_filter from themewizard import Ui_ThemeWizard @@ -567,20 +568,16 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard): self.theme.theme_name = \ unicode(self.field(u'name').toString()) if not self.theme.theme_name: - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('OpenLP.ThemeForm', 'Theme Name Missing'), translate('OpenLP.ThemeForm', - 'There is no name for this theme. Please enter one.'), - (QtGui.QMessageBox.Ok), - QtGui.QMessageBox.Ok) + 'There is no name for this theme. Please enter one.')) return if self.theme.theme_name == u'-1' or self.theme.theme_name == u'None': - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('OpenLP.ThemeForm', 'Theme Name Invalid'), translate('OpenLP.ThemeForm', - 'Invalid theme name. Please enter one.'), - (QtGui.QMessageBox.Ok), - QtGui.QMessageBox.Ok) + 'Invalid theme name. Please enter one.')) return saveFrom = None saveTo = None diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index ccea7faaf..58a150205 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -359,7 +359,7 @@ class ThemeManager(QtGui.QWidget): """ item = self.themeListWidget.currentItem() if item is None: - criticalErrorMessageBox(self, translate('OpenLP.ThemeManager', + criticalErrorMessageBox(message=translate('OpenLP.ThemeManager', 'You have not selected a theme.')) return theme = unicode(item.data(QtCore.Qt.UserRole).toString()) @@ -386,10 +386,10 @@ class ThemeManager(QtGui.QWidget): 'Your theme has been successfully exported.')) except (IOError, OSError): log.exception(u'Export Theme Failed') - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('OpenLP.ThemeManager', 'Theme Export Failed'), translate('OpenLP.ThemeManager', - 'Your theme could not be exported due to an error.')) + 'Your theme could not be exported due to an error.')) finally: if zip: zip.close() @@ -496,9 +496,10 @@ class ThemeManager(QtGui.QWidget): for file in zip.namelist(): ucsfile = file_is_unicode(file) if not ucsfile: - criticalErrorMessageBox(self, - translate('OpenLP.ThemeManager', 'File is not a valid ' - 'theme.\nThe content encoding is not UTF-8.')) + criticalErrorMessageBox( + message=translate('OpenLP.ThemeManager', + 'File is not a valid theme.\n' + 'The content encoding is not UTF-8.')) continue osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile)) theme_dir = None @@ -533,19 +534,17 @@ class ThemeManager(QtGui.QWidget): theme = self._createThemeFromXml(filexml, self.path) self.generateAndSaveImage(dir, themename, theme) else: - Receiver.send_message(u'openlp_error_message', { - u'title': translate('OpenLP.ThemeManager', - 'Validation Error'), - u'message':translate('OpenLP.ThemeManager', - 'File is not a valid theme.')}) + criticalErrorMessageBox( + translate('OpenLP.ThemeManager', 'Validation Error'), + translate('OpenLP.ThemeManager', + 'File is not a valid theme.')) log.exception(u'Theme file does not contain XML data %s' % filename) except (IOError, NameError): - Receiver.send_message(u'openlp_error_message', { - u'title': translate('OpenLP.ThemeManager', - 'Validation Error'), - u'message':translate('OpenLP.ThemeManager', - 'File is not a valid theme.')}) + criticalErrorMessageBox( + translate('OpenLP.ThemeManager', 'Validation Error'), + translate('OpenLP.ThemeManager', + 'File is not a valid theme.')) log.exception(u'Importing theme from zip failed %s' % filename) finally: if zip: @@ -578,11 +577,10 @@ class ThemeManager(QtGui.QWidget): """ theme_dir = os.path.join(self.path, themeName) if os.path.exists(theme_dir): - Receiver.send_message(u'openlp_error_message', { - u'title': translate('OpenLP.ThemeManager', - 'Validation Error'), - u'message':translate('OpenLP.ThemeManager', - 'A theme with this name already exists.')}) + criticalErrorMessageBox( + translate('OpenLP.ThemeManager', 'Validation Error'), + translate('OpenLP.ThemeManager', + 'A theme with this name already exists.')) return False return True @@ -696,19 +694,19 @@ class ThemeManager(QtGui.QWidget): return False # should be the same unless default if theme != unicode(item.data(QtCore.Qt.UserRole).toString()): - criticalErrorMessageBox(self, translate('OpenLP.ThemeManager', + criticalErrorMessageBox( + message=translate('OpenLP.ThemeManager', 'You are unable to delete the default theme.')) return False # check for use in the system else where. if testPlugin: for plugin in self.mainwindow.pluginManager.plugins: if plugin.usesTheme(theme): - Receiver.send_message(u'openlp_error_message', { - u'title': translate('OpenLP.ThemeManager', + criticalErrorMessageBox(translate('OpenLP.ThemeManager', 'Validation Error'), - u'message': unicode(translate('OpenLP.ThemeManager', + unicode(translate('OpenLP.ThemeManager', 'Theme %s is used in the %s plugin.')) % \ - (theme, plugin.name)}) + (theme, plugin.name)) return False return True diff --git a/openlp/plugins/bibles/forms/bibleimportform.py b/openlp/plugins/bibles/forms/bibleimportform.py index d79051126..d3f41804b 100644 --- a/openlp/plugins/bibles/forms/bibleimportform.py +++ b/openlp/plugins/bibles/forms/bibleimportform.py @@ -35,6 +35,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import Receiver, SettingsManager, translate from openlp.core.lib.db import delete_database +from openlp.core.ui import criticalErrorMessageBox from openlp.core.ui.wizard import OpenLPWizard from openlp.core.utils import AppLocation, string_is_unicode from openlp.plugins.bibles.lib.manager import BibleFormat @@ -468,7 +469,7 @@ class BibleImportForm(OpenLPWizard): elif self.currentPage() == self.selectPage: if self.field(u'source_format').toInt()[0] == BibleFormat.OSIS: if not self.field(u'osis_location').toString(): - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('BiblesPlugin.ImportWizardForm', 'Invalid Bible Location'), translate('BiblesPlugin.ImportWizardForm', @@ -478,7 +479,7 @@ class BibleImportForm(OpenLPWizard): return False elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV: if not self.field(u'csv_booksfile').toString(): - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('BiblesPlugin.ImportWizardForm', 'Invalid Books File'), translate('BiblesPlugin.ImportWizardForm', @@ -487,7 +488,7 @@ class BibleImportForm(OpenLPWizard): self.csvBooksEdit.setFocus() return False elif not self.field(u'csv_versefile').toString(): - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('BiblesPlugin.ImportWizardForm', 'Invalid Verse File'), translate('BiblesPlugin.ImportWizardForm', @@ -498,7 +499,7 @@ class BibleImportForm(OpenLPWizard): elif self.field(u'source_format').toInt()[0] == \ BibleFormat.OpenSong: if not self.field(u'opensong_file').toString(): - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('BiblesPlugin.ImportWizardForm', 'Invalid OpenSong Bible'), translate('BiblesPlugin.ImportWizardForm', @@ -508,7 +509,7 @@ class BibleImportForm(OpenLPWizard): return False elif self.field(u'source_format').toInt()[0] == BibleFormat.OpenLP1: if not self.field(u'openlp1_location').toString(): - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('BiblesPlugin.ImportWizardForm', 'Invalid Bible Location'), translate('BiblesPlugin.ImportWizardForm', @@ -522,7 +523,7 @@ class BibleImportForm(OpenLPWizard): license_copyright = \ unicode(self.field(u'license_copyright').toString()) if not license_version: - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('BiblesPlugin.ImportWizardForm', 'Empty Version Name'), translate('BiblesPlugin.ImportWizardForm', @@ -530,7 +531,7 @@ class BibleImportForm(OpenLPWizard): self.versionNameEdit.setFocus() return False elif not license_copyright: - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('BiblesPlugin.ImportWizardForm', 'Empty Copyright'), translate('BiblesPlugin.ImportWizardForm', @@ -539,7 +540,7 @@ class BibleImportForm(OpenLPWizard): self.copyrightEdit.setFocus() return False elif self.manager.exists(license_version): - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('BiblesPlugin.ImportWizardForm', 'Bible Exists'), translate('BiblesPlugin.ImportWizardForm', 'This Bible already exists. Please import ' diff --git a/openlp/plugins/bibles/lib/db.py b/openlp/plugins/bibles/lib/db.py index 9f4376da1..695f4b721 100644 --- a/openlp/plugins/bibles/lib/db.py +++ b/openlp/plugins/bibles/lib/db.py @@ -35,6 +35,7 @@ from sqlalchemy.orm.exc import UnmappedClassError from openlp.core.lib import Receiver, translate from openlp.core.lib.db import BaseModel, init_db, Manager +from openlp.core.ui import criticalErrorMessageBox log = logging.getLogger(__name__) @@ -354,12 +355,11 @@ class BibleDB(QtCore.QObject, Manager): verse_list.extend(verses) else: log.debug(u'OpenLP failed to find book %s', book) - Receiver.send_message(u'openlp_error_message', { - u'title': translate('BiblesPlugin', 'No Book Found'), - u'message': translate('BiblesPlugin', 'No matching book ' + criticalErrorMessageBox( + translate('BiblesPlugin', 'No Book Found'), + translate('BiblesPlugin', 'No matching book ' 'could be found in this Bible. Check that you have ' - 'spelled the name of the book correctly.') - }) + 'spelled the name of the book correctly.')) return verse_list def verse_search(self, text): diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index 6f6b861e9..b844bbe61 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -38,6 +38,7 @@ from HTMLParser import HTMLParseError from BeautifulSoup import BeautifulSoup, NavigableString from openlp.core.lib import Receiver, translate +from openlp.core.ui import criticalErrorMessageBox from openlp.core.utils import AppLocation, get_web_page from openlp.plugins.bibles.lib import SearchResults from openlp.plugins.bibles.lib.db import BibleDB, Book @@ -429,12 +430,11 @@ class HTTPBible(BibleDB): if not db_book: book_details = HTTPBooks.get_book(book) if not book_details: - Receiver.send_message(u'openlp_error_message', { - u'title': translate('BiblesPlugin', 'No Book Found'), - u'message': translate('BiblesPlugin', 'No matching ' + criticalErrorMessageBox( + translate('BiblesPlugin', 'No Book Found'), + translate('BiblesPlugin', 'No matching ' 'book could be found in this Bible. Check that you ' - 'have spelled the name of the book correctly.') - }) + 'have spelled the name of the book correctly.')) return [] db_book = self.create_book(book_details[u'name'], book_details[u'abbreviation'], @@ -540,17 +540,15 @@ def send_error_message(error_type): The type of error that occured for the issue. """ if error_type == u'download': - Receiver.send_message(u'openlp_error_message', { - u'title': translate('BiblePlugin.HTTPBible', 'Download Error'), - u'message': translate('BiblePlugin.HTTPBible', 'There was a ' + criticalErrorMessageBox( + translate('BiblePlugin.HTTPBible', 'Download Error'), + translate('BiblePlugin.HTTPBible', 'There was a ' 'problem downloading your verse selection. Please check your ' 'Internet connection, and if this error continues to occur ' - 'please consider reporting a bug.') - }) + 'please consider reporting a bug.')) elif error_type == u'parse': - Receiver.send_message(u'openlp_error_message', { - u'title': translate('BiblePlugin.HTTPBible', 'Parse Error'), - u'message': translate('BiblePlugin.HTTPBible', 'There was a ' + criticalErrorMessageBox( + translate('BiblePlugin.HTTPBible', 'Parse Error'), + translate('BiblePlugin.HTTPBible', 'There was a ' 'problem extracting your verse selection. If this error continues ' - 'to occur please consider reporting a bug.') - }) + 'to occur please consider reporting a bug.')) diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 81dd1777b..b38779680 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -389,11 +389,8 @@ class BibleMediaItem(MediaManagerItem): verse_count = self.parent.manager.get_verse_count(bible, book, 1) if verse_count == 0: self.advancedSearchButton.setEnabled(False) - Receiver.send_message(u'openlp_error_message', { - u'title': translate('BiblePlugin.MediaItem', 'Error'), - u'message': translate('BiblePlugin.MediaItem', - 'Bible not fully loaded') - }) + criticalErrorMessageBox(message=translate('BiblePlugin.MediaItem', + 'Bible not fully loaded')) else: self.advancedSearchButton.setEnabled(True) self.adjustComboBox(1, self.chapter_count, self.advancedFromChapter) @@ -534,11 +531,11 @@ class BibleMediaItem(MediaManagerItem): if item_second_bible and second_bible or not item_second_bible and \ not second_bible: self.displayResults(bible, second_bible) - elif criticalErrorMessageBox(self, - translate('BiblePlugin.MediaItem', 'You cannot combine single ' - 'and second bible verses. Do you want to delete your search ' - 'results and start a new search?'), - True) == QtGui.QMessageBox.Yes: + elif criticalErrorMessageBox( + message=translate('BiblePlugin.MediaItem', + 'You cannot combine single and second bible verses. Do you ' + 'want to delete your search results and start a new search?'), + question=True) == QtGui.QMessageBox.Yes: self.listView.clear() self.displayResults(bible, second_bible) else: @@ -582,11 +579,11 @@ class BibleMediaItem(MediaManagerItem): if item_second_bible and second_bible or not item_second_bible and \ not second_bible: self.displayResults(bible, second_bible) - elif criticalErrorMessageBox(self, - translate('BiblePlugin.MediaItem', 'You cannot combine single ' - 'and second bible verses. Do you want to delete your search ' - 'results and start a new search?'), - True) == QtGui.QMessageBox.Yes: + elif criticalErrorMessageBox( + message=translate('BiblePlugin.MediaItem', + 'You cannot combine single and second bible verses. Do you ' + 'want to delete your search results and start a new search?'), + question=True) == QtGui.QMessageBox.Yes: self.listView.clear() self.displayResults(bible, second_bible) elif self.search_results: diff --git a/openlp/plugins/custom/forms/editcustomform.py b/openlp/plugins/custom/forms/editcustomform.py index 794fde9e8..ebc917e99 100644 --- a/openlp/plugins/custom/forms/editcustomform.py +++ b/openlp/plugins/custom/forms/editcustomform.py @@ -152,7 +152,7 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog): """ valid, message = self._validate() if not valid: - criticalErrorMessageBox(self, message) + criticalErrorMessageBox(message=message) return False sxml = CustomXMLBuilder() sxml.new_document() diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index 063a80d02..64d864ff8 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -31,7 +31,8 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ ItemCapabilities, SettingsManager, translate, check_item_selected, \ - Receiver, check_directory_exists + check_directory_exists +from openlp.core.ui import criticalErrorMessageBox from openlp.core.utils import AppLocation, get_images_filter log = logging.getLogger(__name__) @@ -164,7 +165,7 @@ class ImageMediaItem(MediaManagerItem): items.remove(item) # We cannot continue, as all images do not exist. if not items: - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('ImagePlugin.MediaItem', 'Missing Image(s)'), unicode(translate('ImagePlugin.MediaItem', 'The following image(s) no longer exist: %s')) % @@ -208,12 +209,11 @@ class ImageMediaItem(MediaManagerItem): self.parent.liveController.display.directImage(name, filename) self.resetAction.setVisible(True) else: - Receiver.send_message(u'openlp_error_message', { - u'title': translate('ImagePlugin.MediaItem', - 'Live Background Error'), - u'message': unicode(translate('ImagePlugin.MediaItem', + criticalErrorMessageBox( + translate('ImagePlugin.MediaItem', 'Live Background Error'), + unicode(translate('ImagePlugin.MediaItem', 'There was a problem replacing your background, ' - 'the image file "%s" no longer exists.')) % filename}) + 'the image file "%s" no longer exists.')) % filename) def onPreviewClick(self): - MediaManagerItem.onPreviewClick(self) \ No newline at end of file + MediaManagerItem.onPreviewClick(self) diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index cc75dfc2b..0280ba937 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -30,8 +30,8 @@ import os from PyQt4 import QtCore, QtGui from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ - ItemCapabilities, SettingsManager, translate, check_item_selected, \ - Receiver + ItemCapabilities, SettingsManager, translate, check_item_selected +from openlp.core.ui import criticalErrorMessageBox log = logging.getLogger(__name__) @@ -106,12 +106,11 @@ class MediaMediaItem(MediaManagerItem): self.parent.liveController.display.video(filename, 0, True) self.resetAction.setVisible(True) else: - Receiver.send_message(u'openlp_error_message', { - u'title': translate('MediaPlugin.MediaItem', + criticalErrorMessageBox(translate('MediaPlugin.MediaItem', 'Live Background Error'), - u'message': unicode(translate('MediaPlugin.MediaItem', + unicode(translate('MediaPlugin.MediaItem', 'There was a problem replacing your background, ' - 'the media file "%s" no longer exists.')) % filename}) + 'the media file "%s" no longer exists.')) % filename) def generateSlideData(self, service_item, item=None, xmlVersion=False): if item is None: @@ -131,9 +130,8 @@ class MediaMediaItem(MediaManagerItem): return True else: # File is no longer present - QtGui.QMessageBox.critical( - self, translate('MediaPlugin.MediaItem', - 'Missing Media File'), + criticalErrorMessageBox( + translate('MediaPlugin.MediaItem', 'Missing Media File'), unicode(translate('MediaPlugin.MediaItem', 'The file %s no longer exists.')) % filename) return False diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index 1e65a3358..2c9381a70 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -31,6 +31,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ SettingsManager, translate, check_item_selected, Receiver, ItemCapabilities +from openlp.core.ui import criticalErrorMessageBox from openlp.plugins.presentations.lib import MessageListener log = logging.getLogger(__name__) @@ -180,7 +181,7 @@ class PresentationMediaItem(MediaManagerItem): filename = os.path.split(unicode(file))[1] if titles.count(filename) > 0: if not initialLoad: - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('PresentationPlugin.MediaItem', 'File Exists'), translate('PresentationPlugin.MediaItem', @@ -204,7 +205,7 @@ class PresentationMediaItem(MediaManagerItem): if initialLoad: icon = build_icon(u':/general/general_delete.png') else: - QtGui.QMessageBox.critical( + criticalErrorMessageBox( self, translate('PresentationPlugin.MediaItem', 'Unsupported File'), translate('PresentationPlugin.MediaItem', @@ -275,8 +276,8 @@ class PresentationMediaItem(MediaManagerItem): return True else: # File is no longer present - QtGui.QMessageBox.critical( - self, translate('PresentationPlugin.MediaItem', + criticalErrorMessageBox( + translate('PresentationPlugin.MediaItem', 'Missing Presentation'), unicode(translate('PresentationPlugin.MediaItem', 'The Presentation %s no longer exists.')) % filename) diff --git a/openlp/plugins/songs/forms/authorsform.py b/openlp/plugins/songs/forms/authorsform.py index 09f361816..afd3795b1 100644 --- a/openlp/plugins/songs/forms/authorsform.py +++ b/openlp/plugins/songs/forms/authorsform.py @@ -80,21 +80,21 @@ class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog): def accept(self): if not self.firstNameEdit.text(): - criticalErrorMessageBox(self, translate('SongsPlugin.AuthorsForm', + criticalErrorMessageBox(message=translate('SongsPlugin.AuthorsForm', 'You need to type in the first name of the author.')) self.firstNameEdit.setFocus() return False elif not self.lastNameEdit.text(): - criticalErrorMessageBox(self, translate('SongsPlugin.AuthorsForm', + criticalErrorMessageBox(message=translate('SongsPlugin.AuthorsForm', 'You need to type in the last name of the author.')) self.lastNameEdit.setFocus() return False elif not self.displayEdit.text(): - if criticalErrorMessageBox(self, - translate('SongsPlugin.AuthorsForm', + if criticalErrorMessageBox( + message=translate('SongsPlugin.AuthorsForm', 'You have not set a display name for the ' 'author, combine the first and last names?'), - True) == QtGui.QMessageBox.Yes: + question=True) == QtGui.QMessageBox.Yes: self.displayEdit.setText(self.firstNameEdit.text() + \ u' ' + self.lastNameEdit.text()) return QtGui.QDialog.accept(self) diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index 980f00076..a37af5280 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -347,9 +347,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): author = self.manager.get_object(Author, item_id) if self.authorsListView.findItems(unicode(author.display_name), QtCore.Qt.MatchExactly): - criticalErrorMessageBox(self, - translate('SongsPlugin.EditSongForm', 'This author is ' - 'already in the list.')) + criticalErrorMessageBox( + message=translate('SongsPlugin.EditSongForm', + 'This author is already in the list.')) else: author_item = QtGui.QListWidgetItem(unicode( author.display_name)) @@ -400,9 +400,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): topic = self.manager.get_object(Topic, item_id) if self.topicsListView.findItems(unicode(topic.name), QtCore.Qt.MatchExactly): - criticalErrorMessageBox(self, - translate('SongsPlugin.EditSongForm', 'This topic is ' - 'already in the list.')) + criticalErrorMessageBox( + message=translate('SongsPlugin.EditSongForm', + 'This topic is already in the list.')) else: topic_item = QtGui.QListWidgetItem(unicode(topic.name)) topic_item.setData(QtCore.Qt.UserRole, @@ -532,19 +532,22 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): if len(self.titleEdit.displayText()) == 0: self.songTabWidget.setCurrentIndex(0) self.titleEdit.setFocus() - criticalErrorMessageBox(self, translate('SongsPlugin.EditSongForm', + criticalErrorMessageBox( + message=translate('SongsPlugin.EditSongForm', 'You need to type in a song title.')) return False if self.verseListWidget.rowCount() == 0: self.songTabWidget.setCurrentIndex(0) self.verseListWidget.setFocus() - criticalErrorMessageBox(self, translate('SongsPlugin.EditSongForm', + criticalErrorMessageBox( + message=translate('SongsPlugin.EditSongForm', 'You need to type in at least one verse.')) return False if self.authorsListView.count() == 0: self.songTabWidget.setCurrentIndex(1) self.authorsListView.setFocus() - criticalErrorMessageBox(self, translate('SongsPlugin.EditSongForm', + criticalErrorMessageBox( + message=translate('SongsPlugin.EditSongForm', 'You need to have an author for this song.')) return False if self.song.verse_order: @@ -571,8 +574,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): valid = verses.pop(0) for verse in verses: valid = valid + u', ' + verse - criticalErrorMessageBox(self, - unicode(translate('SongsPlugin.EditSongForm', + criticalErrorMessageBox( + message=unicode(translate('SongsPlugin.EditSongForm', 'The verse order is invalid. There is no verse ' 'corresponding to %s. Valid entries are %s.')) % \ (order_names[count], valid)) diff --git a/openlp/plugins/songs/forms/editverseform.py b/openlp/plugins/songs/forms/editverseform.py index 93a259274..c10e48cb7 100644 --- a/openlp/plugins/songs/forms/editverseform.py +++ b/openlp/plugins/songs/forms/editverseform.py @@ -168,7 +168,8 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog): else: value = self.getVerse()[0].split(u'\n')[1] if len(value) == 0: - criticalErrorMessageBox(self, translate('SongsPlugin.EditSongForm', + criticalErrorMessageBox( + message=translate('SongsPlugin.EditSongForm', 'You need to type some text in to the verse.')) return False QtGui.QDialog.accept(self) diff --git a/openlp/plugins/songs/forms/songbookform.py b/openlp/plugins/songs/forms/songbookform.py index 96d4fdf1b..8341a7c4c 100644 --- a/openlp/plugins/songs/forms/songbookform.py +++ b/openlp/plugins/songs/forms/songbookform.py @@ -50,7 +50,8 @@ class SongBookForm(QtGui.QDialog, Ui_SongBookDialog): def accept(self): if not self.nameEdit.text(): - criticalErrorMessageBox(self, translate('SongsPlugin.SongBookForm', + criticalErrorMessageBox( + message=translate('SongsPlugin.SongBookForm', 'You need to type in a name for the book.')) self.nameEdit.setFocus() return False diff --git a/openlp/plugins/songs/forms/songimportform.py b/openlp/plugins/songs/forms/songimportform.py index 22a7ab61f..4cd4c6713 100644 --- a/openlp/plugins/songs/forms/songimportform.py +++ b/openlp/plugins/songs/forms/songimportform.py @@ -32,6 +32,7 @@ import os from PyQt4 import QtCore, QtGui from openlp.core.lib import Receiver, SettingsManager, translate +from openlp.core.ui import criticalErrorMessageBox from openlp.core.ui.wizard import OpenLPWizard from openlp.plugins.songs.lib.importer import SongFormat @@ -325,7 +326,7 @@ class SongImportForm(OpenLPWizard): source_format = self.formatComboBox.currentIndex() if source_format == SongFormat.OpenLP2: if self.openLP2FilenameEdit.text().isEmpty(): - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('SongsPlugin.ImportWizardForm', 'No OpenLP 2.0 Song Database Selected'), translate('SongsPlugin.ImportWizardForm', @@ -335,7 +336,7 @@ class SongImportForm(OpenLPWizard): return False elif source_format == SongFormat.OpenLP1: if self.openLP1FilenameEdit.text().isEmpty(): - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('SongsPlugin.ImportWizardForm', 'No openlp.org 1.x Song Database Selected'), translate('SongsPlugin.ImportWizardForm', @@ -345,7 +346,7 @@ class SongImportForm(OpenLPWizard): return False elif source_format == SongFormat.OpenLyrics: if self.openLyricsFileListWidget.count() == 0: - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('SongsPlugin.ImportWizardForm', 'No OpenLyrics Files Selected'), translate('SongsPlugin.ImportWizardForm', @@ -355,7 +356,7 @@ class SongImportForm(OpenLPWizard): return False elif source_format == SongFormat.OpenSong: if self.openSongFileListWidget.count() == 0: - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('SongsPlugin.ImportWizardForm', 'No OpenSong Files Selected'), translate('SongsPlugin.ImportWizardForm', @@ -365,7 +366,7 @@ class SongImportForm(OpenLPWizard): return False elif source_format == SongFormat.WordsOfWorship: if self.wordsOfWorshipFileListWidget.count() == 0: - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('SongsPlugin.ImportWizardForm', 'No Words of Worship Files Selected'), translate('SongsPlugin.ImportWizardForm', @@ -375,7 +376,7 @@ class SongImportForm(OpenLPWizard): return False elif source_format == SongFormat.CCLI: if self.ccliFileListWidget.count() == 0: - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('SongsPlugin.ImportWizardForm', 'No CCLI Files Selected'), translate('SongsPlugin.ImportWizardForm', @@ -385,7 +386,7 @@ class SongImportForm(OpenLPWizard): return False elif source_format == SongFormat.SongsOfFellowship: if self.songsOfFellowshipFileListWidget.count() == 0: - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('SongsPlugin.ImportWizardForm', 'No Songs of Fellowship File Selected'), translate('SongsPlugin.ImportWizardForm', @@ -395,7 +396,7 @@ class SongImportForm(OpenLPWizard): return False elif source_format == SongFormat.Generic: if self.genericFileListWidget.count() == 0: - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('SongsPlugin.ImportWizardForm', 'No Document/Presentation Selected'), translate('SongsPlugin.ImportWizardForm', @@ -405,7 +406,7 @@ class SongImportForm(OpenLPWizard): return False elif source_format == SongFormat.EasyWorship: if self.ewFilenameEdit.text().isEmpty(): - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('SongsPlugin.ImportWizardForm', 'No EasyWorship Song Database Selected'), translate('SongsPlugin.ImportWizardForm', @@ -415,7 +416,7 @@ class SongImportForm(OpenLPWizard): return False elif source_format == SongFormat.SongBeamer: if self.songBeamerFileListWidget.count() == 0: - QtGui.QMessageBox.critical(self, + criticalErrorMessageBox( translate('SongsPlugin.ImportWizardForm', 'No SongBeamer File Selected'), translate('SongsPlugin.ImportWizardForm', diff --git a/openlp/plugins/songs/forms/songmaintenanceform.py b/openlp/plugins/songs/forms/songmaintenanceform.py index 4dc9361c5..2203df4e7 100644 --- a/openlp/plugins/songs/forms/songmaintenanceform.py +++ b/openlp/plugins/songs/forms/songmaintenanceform.py @@ -91,15 +91,14 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): if item_id != -1: item = self.manager.get_object(item_class, item_id) if item and len(item.songs) == 0: - if QtGui.QMessageBox.warning(self, dlg_title, del_text, - QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | - QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.Yes: + if criticalErrorMessageBox(title=dlg_title, message=del_text, + question=True) == QtGui.QMessageBox.Yes: self.manager.delete_object(item_class, item.id) reset_func() else: - QtGui.QMessageBox.critical(self, dlg_title, err_text) + criticalErrorMessageBox(dlg_title, err_text) else: - QtGui.QMessageBox.critical(self, dlg_title, sel_text) + criticalErrorMessageBox(dlg_title, sel_text) def resetAuthors(self): """ @@ -233,12 +232,12 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): if self.manager.save_object(author): self.resetAuthors() else: - criticalErrorMessageBox(self, - translate('SongsPlugin.SongMaintenanceForm', + criticalErrorMessageBox( + message=translate('SongsPlugin.SongMaintenanceForm', 'Could not add your author.')) else: - criticalErrorMessageBox(self, - translate('SongsPlugin.SongMaintenanceForm', + criticalErrorMessageBox( + message=translate('SongsPlugin.SongMaintenanceForm', 'This author already exists.')) def onTopicAddButtonClick(self): @@ -248,12 +247,12 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): if self.manager.save_object(topic): self.resetTopics() else: - criticalErrorMessageBox(self, - translate('SongsPlugin.SongMaintenanceForm', + criticalErrorMessageBox( + message=translate('SongsPlugin.SongMaintenanceForm', 'Could not add your topic.')) else: - criticalErrorMessageBox(self, - translate('SongsPlugin.SongMaintenanceForm', + criticalErrorMessageBox( + message=translate('SongsPlugin.SongMaintenanceForm', 'This topic already exists.')) def onBookAddButtonClick(self): @@ -264,12 +263,12 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): if self.manager.save_object(book): self.resetBooks() else: - criticalErrorMessageBox(self, - translate('SongsPlugin.SongMaintenanceForm', + criticalErrorMessageBox( + message=translate('SongsPlugin.SongMaintenanceForm', 'Could not add your book.')) else: - criticalErrorMessageBox(self, - translate('SongsPlugin.SongMaintenanceForm', + criticalErrorMessageBox( + message=translate('SongsPlugin.SongMaintenanceForm', 'This book already exists.')) def onAuthorEditButtonClick(self): @@ -296,15 +295,15 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): self.resetAuthors() Receiver.send_message(u'songs_load_list') else: - criticalErrorMessageBox(self, - translate('SongsPlugin.SongMaintenanceForm', + criticalErrorMessageBox( + message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.')) - elif criticalErrorMessageBox(self, - unicode(translate('SongsPlugin.SongMaintenanceForm', - 'The author %s already exists. Would you like to make songs' - ' with author %s use the existing author %s?')) % - (author.display_name, temp_display_name, - author.display_name), True) == QtGui.QMessageBox.Yes: + elif criticalErrorMessageBox(message=unicode(translate( + 'SongsPlugin.SongMaintenanceForm', 'The author %s already ' + 'exists. Would you like to make songs with author %s use ' + 'the existing author %s?')) % (author.display_name, + temp_display_name, author.display_name), + question=True) == QtGui.QMessageBox.Yes: self.mergeAuthors(author) self.resetAuthors() Receiver.send_message(u'songs_load_list') @@ -314,8 +313,8 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): author.first_name = temp_first_name author.last_name = temp_last_name author.display_name = temp_display_name - criticalErrorMessageBox(self, - translate('SongsPlugin.SongMaintenanceForm', + criticalErrorMessageBox( + message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your modified author, because the ' 'author already exists.')) @@ -332,21 +331,22 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): if self.manager.save_object(topic): self.resetTopics() else: - criticalErrorMessageBox(self, - translate('SongsPlugin.SongMaintenanceForm', + criticalErrorMessageBox( + message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.')) - elif criticalErrorMessageBox(self, - unicode(translate('SongsPlugin.SongMaintenanceForm', + elif criticalErrorMessageBox( + message=unicode(translate('SongsPlugin.SongMaintenanceForm', 'The topic %s already exists. Would you like to make songs ' 'with topic %s use the existing topic %s?')) % (topic.name, - temp_name, topic.name), True) == QtGui.QMessageBox.Yes: + temp_name, topic.name), + question=True) == QtGui.QMessageBox.Yes: self.mergeTopics(topic) self.resetTopics() else: # We restore the topics's old name. topic.name = temp_name - criticalErrorMessageBox(self, - translate('SongsPlugin.SongMaintenanceForm', + criticalErrorMessageBox( + message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your modified topic, because it ' 'already exists.')) @@ -369,14 +369,15 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): if self.manager.save_object(book): self.resetBooks() else: - criticalErrorMessageBox(self, - translate('SongsPlugin.SongMaintenanceForm', + criticalErrorMessageBox( + message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.')) - elif criticalErrorMessageBox(self, - unicode(translate('SongsPlugin.SongMaintenanceForm', + elif criticalErrorMessageBox( + message=unicode(translate('SongsPlugin.SongMaintenanceForm', 'The book %s already exists. Would you like to make songs ' 'with book %s use the existing book %s?')) % (book.name, - temp_name, book.name), True) == QtGui.QMessageBox.Yes: + temp_name, book.name), + question=True) == QtGui.QMessageBox.Yes: self.mergeBooks(book) self.resetBooks() else: diff --git a/openlp/plugins/songs/forms/topicsform.py b/openlp/plugins/songs/forms/topicsform.py index 5b330b384..4ab2b63fa 100644 --- a/openlp/plugins/songs/forms/topicsform.py +++ b/openlp/plugins/songs/forms/topicsform.py @@ -49,7 +49,7 @@ class TopicsForm(QtGui.QDialog, Ui_TopicsDialog): def accept(self): if not self.nameEdit.text(): - criticalErrorMessageBox(self, translate('SongsPlugin.TopicsForm', + criticalErrorMessageBox(message=translate('SongsPlugin.TopicsForm', 'You need to type in a topic name.')) self.nameEdit.setFocus() return False From 5f94cded2b769b6b7bc98d6404091ebd68849af6 Mon Sep 17 00:00:00 2001 From: Jon Tibble Date: Sat, 15 Jan 2011 19:44:31 +0000 Subject: [PATCH 56/56] Fix previous commit --- openlp/core/ui/themeform.py | 2 +- openlp/plugins/bibles/lib/db.py | 2 +- openlp/plugins/bibles/lib/mediaitem.py | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/openlp/core/ui/themeform.py b/openlp/core/ui/themeform.py index 0925023bd..2db76063c 100644 --- a/openlp/core/ui/themeform.py +++ b/openlp/core/ui/themeform.py @@ -31,7 +31,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import translate, BackgroundType, BackgroundGradientType, \ Receiver -from openlp.core.ui import criticalErrorMessage +from openlp.core.ui import criticalErrorMessageBox from openlp.core.utils import get_images_filter from themewizard import Ui_ThemeWizard diff --git a/openlp/plugins/bibles/lib/db.py b/openlp/plugins/bibles/lib/db.py index 695f4b721..1967448cc 100644 --- a/openlp/plugins/bibles/lib/db.py +++ b/openlp/plugins/bibles/lib/db.py @@ -33,7 +33,7 @@ from sqlalchemy import Column, ForeignKey, or_, Table, types from sqlalchemy.orm import class_mapper, mapper, relation from sqlalchemy.orm.exc import UnmappedClassError -from openlp.core.lib import Receiver, translate +from openlp.core.lib import translate from openlp.core.lib.db import BaseModel, init_db, Manager from openlp.core.ui import criticalErrorMessageBox diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index b38779680..d4b1b627b 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -30,6 +30,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import MediaManagerItem, Receiver, BaseListWithDnD, \ ItemCapabilities, translate +from openlp.core.ui import criticalErrorMessageBox from openlp.plugins.bibles.forms import BibleImportForm from openlp.plugins.bibles.lib import get_reference_match