This commit is contained in:
Tim Bentley 2011-01-28 16:58:19 +00:00
commit ab092e0124
19 changed files with 354 additions and 235 deletions

View File

@ -47,13 +47,16 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
# Default dictionary based on the current locale. # Default dictionary based on the current locale.
if ENCHANT_AVAILABLE: if ENCHANT_AVAILABLE:
try: try:
self.dict = enchant.Dict() self.dictionary = enchant.Dict()
except DictNotFoundError: except DictNotFoundError:
self.dict = enchant.Dict(u'en_US') self.dictionary = enchant.Dict(u'en_US')
self.highlighter = Highlighter(self.document()) self.highlighter = Highlighter(self.document())
self.highlighter.setDict(self.dict) self.highlighter.spellingDictionary = self.dictionary
def mousePressEvent(self, event): def mousePressEvent(self, event):
"""
Handle mouse clicks within the text edit region.
"""
if event.button() == QtCore.Qt.RightButton: if event.button() == QtCore.Qt.RightButton:
# Rewrite the mouse event to a left button event so the cursor is # Rewrite the mouse event to a left button event so the cursor is
# moved to the location of the pointer. # moved to the location of the pointer.
@ -63,6 +66,9 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
QtGui.QPlainTextEdit.mousePressEvent(self, event) QtGui.QPlainTextEdit.mousePressEvent(self, event)
def contextMenuEvent(self, event): def contextMenuEvent(self, event):
"""
Provide the context menu for the text edit region.
"""
popupMenu = self.createStandardContextMenu() popupMenu = self.createStandardContextMenu()
# Select the word under the cursor. # Select the word under the cursor.
cursor = self.textCursor() cursor = self.textCursor()
@ -74,10 +80,10 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
# suggestions if it is. # suggestions if it is.
if ENCHANT_AVAILABLE and self.textCursor().hasSelection(): if ENCHANT_AVAILABLE and self.textCursor().hasSelection():
text = unicode(self.textCursor().selectedText()) text = unicode(self.textCursor().selectedText())
if not self.dict.check(text): if not self.dictionary.check(text):
spell_menu = QtGui.QMenu(translate('OpenLP.SpellTextEdit', spell_menu = QtGui.QMenu(translate('OpenLP.SpellTextEdit',
'Spelling Suggestions')) 'Spelling Suggestions'))
for word in self.dict.suggest(text): for word in self.dictionary.suggest(text):
action = SpellAction(word, spell_menu) action = SpellAction(word, spell_menu)
action.correct.connect(self.correctWord) action.correct.connect(self.correctWord)
spell_menu.addAction(action) spell_menu.addAction(action)
@ -126,28 +132,32 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
cursor.insertText(html[u'start tag']) cursor.insertText(html[u'start tag'])
cursor.insertText(html[u'end tag']) cursor.insertText(html[u'end tag'])
class Highlighter(QtGui.QSyntaxHighlighter):
class Highlighter(QtGui.QSyntaxHighlighter):
"""
Provides a text highlighter for pointing out spelling errors in text.
"""
WORDS = u'(?iu)[\w\']+' WORDS = u'(?iu)[\w\']+'
def __init__(self, *args): def __init__(self, *args):
QtGui.QSyntaxHighlighter.__init__(self, *args) QtGui.QSyntaxHighlighter.__init__(self, *args)
self.dict = None self.spellingDictionary = None
def setDict(self, dict):
self.dict = dict
def highlightBlock(self, text): def highlightBlock(self, text):
if not self.dict: """
Highlight misspelt words in a block of text
"""
if not self.spellingDictionary:
return return
text = unicode(text) text = unicode(text)
format = QtGui.QTextCharFormat() charFormat = QtGui.QTextCharFormat()
format.setUnderlineColor(QtCore.Qt.red) charFormat.setUnderlineColor(QtCore.Qt.red)
format.setUnderlineStyle(QtGui.QTextCharFormat.SpellCheckUnderline) charFormat.setUnderlineStyle(QtGui.QTextCharFormat.SpellCheckUnderline)
for word_object in re.finditer(self.WORDS, text): for word_object in re.finditer(self.WORDS, text):
if not self.dict.check(word_object.group()): if not self.spellingDictionary.check(word_object.group()):
self.setFormat(word_object.start(), self.setFormat(word_object.start(),
word_object.end() - word_object.start(), format) word_object.end() - word_object.start(), charFormat)
class SpellAction(QtGui.QAction): class SpellAction(QtGui.QAction):
""" """

View File

@ -563,10 +563,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.ServiceManagerContents.onLoadServiceClicked) self.ServiceManagerContents.onLoadServiceClicked)
QtCore.QObject.connect(self.FileSaveItem, QtCore.QObject.connect(self.FileSaveItem,
QtCore.SIGNAL(u'triggered()'), QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.onSaveServiceClicked) self.ServiceManagerContents.saveFile)
QtCore.QObject.connect(self.FileSaveAsItem, QtCore.QObject.connect(self.FileSaveAsItem,
QtCore.SIGNAL(u'triggered()'), QtCore.SIGNAL(u'triggered()'),
self.ServiceManagerContents.onSaveServiceAsClicked) self.ServiceManagerContents.saveFileAs)
# i18n set signals for languages # i18n set signals for languages
QtCore.QObject.connect(self.AutoLanguageItem, QtCore.QObject.connect(self.AutoLanguageItem,
QtCore.SIGNAL(u'toggled(bool)'), self.setAutoLanguage) QtCore.SIGNAL(u'toggled(bool)'), self.setAutoLanguage)
@ -807,15 +807,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
Hook to close the main window and display windows on exit Hook to close the main window and display windows on exit
""" """
if self.ServiceManagerContents.isModified(): if self.ServiceManagerContents.isModified():
ret = QtGui.QMessageBox.question(self, ret = self.ServiceManagerContents.saveModifiedService()
translate('OpenLP.MainWindow', 'Save Changes to Service?'),
translate('OpenLP.MainWindow', 'Your service has changed. '
'Do you want to save those changes?'),
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.Cancel |
QtGui.QMessageBox.Discard |
QtGui.QMessageBox.Save),
QtGui.QMessageBox.Save)
if ret == QtGui.QMessageBox.Save: if ret == QtGui.QMessageBox.Save:
if self.ServiceManagerContents.saveFile(): if self.ServiceManagerContents.saveFile():
self.cleanUp() self.cleanUp()
@ -847,7 +839,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.cleanUp() self.cleanUp()
event.accept() event.accept()
def cleanUp(self): def cleanUp(self):
""" """
Runs all the cleanup code before OpenLP shuts down Runs all the cleanup code before OpenLP shuts down

View File

@ -108,7 +108,7 @@ class ServiceManager(QtGui.QWidget):
translate('OpenLP.ServiceManager', 'Save Service'), translate('OpenLP.ServiceManager', 'Save Service'),
u':/general/general_save.png', u':/general/general_save.png',
translate('OpenLP.ServiceManager', 'Save this service'), translate('OpenLP.ServiceManager', 'Save this service'),
self.onSaveServiceClicked) self.saveFile)
self.toolbar.addSeparator() self.toolbar.addSeparator()
self.themeLabel = QtGui.QLabel(translate('OpenLP.ServiceManager', self.themeLabel = QtGui.QLabel(translate('OpenLP.ServiceManager',
'Theme:'), self) 'Theme:'), self)
@ -361,12 +361,7 @@ class ServiceManager(QtGui.QWidget):
Create a new service. Create a new service.
""" """
if self.isModified(): if self.isModified():
result = QtGui.QMessageBox.question(self.mainwindow, result = self.saveModifiedService()
translate('OpenLP.ServiceManager', 'Save Changes'),
translate('OpenLP.ServiceManager', 'The current service has '
'been modified, would you like to save it?'),
QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard |
QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Save)
if result == QtGui.QMessageBox.Cancel: if result == QtGui.QMessageBox.Cancel:
return False return False
elif result == QtGui.QMessageBox.Save: elif result == QtGui.QMessageBox.Save:
@ -376,12 +371,7 @@ class ServiceManager(QtGui.QWidget):
def onLoadServiceClicked(self): def onLoadServiceClicked(self):
if self.isModified(): if self.isModified():
result = QtGui.QMessageBox.question(self.mainwindow, result = self.saveModifiedService()
translate('OpenLP.ServiceManager', 'Save Changes'),
translate('OpenLP.ServiceManager', 'The current service has '
'been modified, would you like to save it?'),
QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard |
QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Save)
if result == QtGui.QMessageBox.Cancel: if result == QtGui.QMessageBox.Cancel:
return False return False
elif result == QtGui.QMessageBox.Save: elif result == QtGui.QMessageBox.Save:
@ -397,11 +387,13 @@ class ServiceManager(QtGui.QWidget):
split_filename(fileName)[0]) split_filename(fileName)[0])
self.loadFile(fileName) self.loadFile(fileName)
def onSaveServiceClicked(self): def saveModifiedService(self):
self.saveFile() return QtGui.QMessageBox.question(self.mainwindow,
translate('OpenLP.ServiceManager', 'Modified Service'),
def onSaveServiceAsClicked(self): translate('OpenLP.ServiceManager', 'The current service has '
self.saveFileAs() 'been modified. Would you like to save this service?'),
QtGui.QMessageBox.Save | QtGui.QMessageBox.Discard |
QtGui.QMessageBox.Cancel, QtGui.QMessageBox.Save)
def onRecentServiceClicked(self): def onRecentServiceClicked(self):
sender = self.sender() sender = self.sender()

View File

@ -119,6 +119,8 @@ class SlideController(QtGui.QWidget):
self.previewListWidget.isLive = self.isLive self.previewListWidget.isLive = self.isLive
self.previewListWidget.setObjectName(u'PreviewListWidget') self.previewListWidget.setObjectName(u'PreviewListWidget')
self.previewListWidget.setSelectionBehavior(1) self.previewListWidget.setSelectionBehavior(1)
self.previewListWidget.setSelectionMode(
QtGui.QAbstractItemView.SingleSelection)
self.previewListWidget.setEditTriggers( self.previewListWidget.setEditTriggers(
QtGui.QAbstractItemView.NoEditTriggers) QtGui.QAbstractItemView.NoEditTriggers)
self.previewListWidget.setHorizontalScrollBarPolicy( self.previewListWidget.setHorizontalScrollBarPolicy(

View File

@ -124,9 +124,12 @@ class BibleImportForm(OpenLPWizard):
QtCore.QObject.connect(self.osisBrowseButton, QtCore.QObject.connect(self.osisBrowseButton,
QtCore.SIGNAL(u'clicked()'), QtCore.SIGNAL(u'clicked()'),
self.onOsisBrowseButtonClicked) self.onOsisBrowseButtonClicked)
QtCore.QObject.connect(self.csvTestamentsButton,
QtCore.SIGNAL(u'clicked()'),
self.onCsvTestamentsBrowseButtonClicked)
QtCore.QObject.connect(self.csvBooksButton, QtCore.QObject.connect(self.csvBooksButton,
QtCore.SIGNAL(u'clicked()'), QtCore.SIGNAL(u'clicked()'),
self.onBooksBrowseButtonClicked) self.onCsvBooksBrowseButtonClicked)
QtCore.QObject.connect(self.csvVersesButton, QtCore.QObject.connect(self.csvVersesButton,
QtCore.SIGNAL(u'clicked()'), QtCore.SIGNAL(u'clicked()'),
self.onCsvVersesBrowseButtonClicked) self.onCsvVersesBrowseButtonClicked)
@ -187,6 +190,18 @@ class BibleImportForm(OpenLPWizard):
self.csvLayout = QtGui.QFormLayout(self.csvWidget) self.csvLayout = QtGui.QFormLayout(self.csvWidget)
self.csvLayout.setMargin(0) self.csvLayout.setMargin(0)
self.csvLayout.setObjectName(u'CsvLayout') self.csvLayout.setObjectName(u'CsvLayout')
self.csvTestamentsLabel = QtGui.QLabel(self.csvWidget)
self.csvTestamentsLabel.setObjectName(u'CsvTestamentsLabel')
self.csvTestamentsLayout = QtGui.QHBoxLayout()
self.csvTestamentsLayout.setObjectName(u'CsvTestamentsLayout')
self.csvTestamentsEdit = QtGui.QLineEdit(self.csvWidget)
self.csvTestamentsEdit.setObjectName(u'CsvTestamentsEdit')
self.csvTestamentsLayout.addWidget(self.csvTestamentsEdit)
self.csvTestamentsButton = QtGui.QToolButton(self.csvWidget)
self.csvTestamentsButton.setIcon(self.openIcon)
self.csvTestamentsButton.setObjectName(u'CsvTestamentsButton')
self.csvTestamentsLayout.addWidget(self.csvTestamentsButton)
self.csvLayout.addRow(self.csvTestamentsLabel, self.csvTestamentsLayout)
self.csvBooksLabel = QtGui.QLabel(self.csvWidget) self.csvBooksLabel = QtGui.QLabel(self.csvWidget)
self.csvBooksLabel.setObjectName(u'CsvBooksLabel') self.csvBooksLabel.setObjectName(u'CsvBooksLabel')
self.csvBooksLayout = QtGui.QHBoxLayout() self.csvBooksLayout = QtGui.QHBoxLayout()
@ -213,7 +228,7 @@ class BibleImportForm(OpenLPWizard):
self.csvLayout.addRow(self.csvVersesLabel, self.csvVersesLayout) self.csvLayout.addRow(self.csvVersesLabel, self.csvVersesLayout)
self.csvSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed, self.csvSpacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum) QtGui.QSizePolicy.Minimum)
self.csvLayout.setItem(2, QtGui.QFormLayout.LabelRole, self.csvSpacer) self.csvLayout.setItem(3, QtGui.QFormLayout.LabelRole, self.csvSpacer)
self.selectStack.addWidget(self.csvWidget) self.selectStack.addWidget(self.csvWidget)
self.openSongWidget = QtGui.QWidget(self.selectPage) self.openSongWidget = QtGui.QWidget(self.selectPage)
self.openSongWidget.setObjectName(u'OpenSongWidget') self.openSongWidget.setObjectName(u'OpenSongWidget')
@ -389,6 +404,8 @@ class BibleImportForm(OpenLPWizard):
translate('BiblesPlugin.ImportWizardForm', 'File location:')) translate('BiblesPlugin.ImportWizardForm', 'File location:'))
self.osisFileLabel.setText( self.osisFileLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'File location:')) translate('BiblesPlugin.ImportWizardForm', 'File location:'))
self.csvTestamentsLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Testaments location:'))
self.csvBooksLabel.setText( self.csvBooksLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Books location:')) translate('BiblesPlugin.ImportWizardForm', 'Books location:'))
self.csvVersesLabel.setText( self.csvVersesLabel.setText(
@ -478,7 +495,16 @@ class BibleImportForm(OpenLPWizard):
self.osisFileEdit.setFocus() self.osisFileEdit.setFocus()
return False return False
elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV: elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV:
if not self.field(u'csv_booksfile').toString(): if not self.field(u'csv_testamentsfile').toString():
answer = criticalErrorMessageBox(translate(
'BiblesPlugin.ImportWizardForm', 'No Testaments File'),
translate('BiblesPlugin.ImportWizardForm',
'You have not specified a testaments file. Do you '
'want to proceed with the import?'), question=True)
if answer == QtGui.QMessageBox.No:
self.csvTestamentsEdit.setFocus()
return False
elif not self.field(u'csv_booksfile').toString():
criticalErrorMessageBox( criticalErrorMessageBox(
translate('BiblesPlugin.ImportWizardForm', translate('BiblesPlugin.ImportWizardForm',
'Invalid Books File'), 'Invalid Books File'),
@ -572,7 +598,15 @@ class BibleImportForm(OpenLPWizard):
translate('BiblesPlugin.ImportWizardForm', 'Open OSIS File'), translate('BiblesPlugin.ImportWizardForm', 'Open OSIS File'),
self.osisFileEdit) self.osisFileEdit)
def onBooksBrowseButtonClicked(self): def onCsvTestamentsBrowseButtonClicked(self):
"""
Show the file open dialog for the testaments CSV file.
"""
self.getFileName(translate('BiblesPlugin.ImportWizardForm',
'Open Testaments CSV File'), self.csvTestamentsEdit, u'%s (*.csv)'
% translate('BiblesPlugin.ImportWizardForm', 'CSV File'))
def onCsvBooksBrowseButtonClicked(self):
""" """
Show the file open dialog for the books CSV file. Show the file open dialog for the books CSV file.
""" """
@ -613,12 +647,14 @@ class BibleImportForm(OpenLPWizard):
""" """
self.selectPage.registerField(u'source_format', self.formatComboBox) self.selectPage.registerField(u'source_format', self.formatComboBox)
self.selectPage.registerField(u'osis_location', self.osisFileEdit) self.selectPage.registerField(u'osis_location', self.osisFileEdit)
self.selectPage.registerField(
u'csv_testamentsfile', self.csvTestamentsEdit)
self.selectPage.registerField(u'csv_booksfile', self.csvBooksEdit) self.selectPage.registerField(u'csv_booksfile', self.csvBooksEdit)
self.selectPage.registerField(u'csv_versefile', self.csvVersesEdit) self.selectPage.registerField(u'csv_versefile', self.csvVersesEdit)
self.selectPage.registerField(u'opensong_file', self.openSongFileEdit) self.selectPage.registerField(u'opensong_file', self.openSongFileEdit)
self.selectPage.registerField(u'web_location', self.webSourceComboBox) self.selectPage.registerField(u'web_location', self.webSourceComboBox)
self.selectPage.registerField(u'web_biblename', self.selectPage.registerField(
self.webTranslationComboBox) u'web_biblename', self.webTranslationComboBox)
self.selectPage.registerField(u'proxy_server', self.webServerEdit) self.selectPage.registerField(u'proxy_server', self.webServerEdit)
self.selectPage.registerField(u'proxy_username', self.webUserEdit) self.selectPage.registerField(u'proxy_username', self.webUserEdit)
self.selectPage.registerField(u'proxy_password', self.webPasswordEdit) self.selectPage.registerField(u'proxy_password', self.webPasswordEdit)
@ -641,6 +677,7 @@ class BibleImportForm(OpenLPWizard):
self.cancelButton.setVisible(True) self.cancelButton.setVisible(True)
self.setField(u'source_format', QtCore.QVariant(0)) self.setField(u'source_format', QtCore.QVariant(0))
self.setField(u'osis_location', QtCore.QVariant('')) self.setField(u'osis_location', QtCore.QVariant(''))
self.setField(u'csv_testamentsfile', QtCore.QVariant(''))
self.setField(u'csv_booksfile', QtCore.QVariant('')) self.setField(u'csv_booksfile', QtCore.QVariant(''))
self.setField(u'csv_versefile', QtCore.QVariant('')) self.setField(u'csv_versefile', QtCore.QVariant(''))
self.setField(u'opensong_file', QtCore.QVariant('')) self.setField(u'opensong_file', QtCore.QVariant(''))
@ -770,7 +807,8 @@ class BibleImportForm(OpenLPWizard):
elif bible_type == BibleFormat.CSV: elif bible_type == BibleFormat.CSV:
# Import a CSV bible. # Import a CSV bible.
importer = self.manager.import_bible(BibleFormat.CSV, importer = self.manager.import_bible(BibleFormat.CSV,
name=license_version, name=license_version, testamentsfile=unicode(
self.field(u'csv_testamentsfile').toString()),
booksfile=unicode(self.field(u'csv_booksfile').toString()), booksfile=unicode(self.field(u'csv_booksfile').toString()),
versefile=unicode(self.field(u'csv_versefile').toString()) versefile=unicode(self.field(u'csv_versefile').toString())
) )
@ -795,8 +833,7 @@ class BibleImportForm(OpenLPWizard):
bible = \ bible = \
self.web_bible_list[WebDownload.Bibleserver][bible_version] self.web_bible_list[WebDownload.Bibleserver][bible_version]
importer = self.manager.import_bible( importer = self.manager.import_bible(
BibleFormat.WebDownload, BibleFormat.WebDownload, name=license_version,
name=license_version,
download_source=WebDownload.get_name(download_location), download_source=WebDownload.get_name(download_location),
download_name=bible, download_name=bible,
proxy_server=unicode(self.field(u'proxy_server').toString()), proxy_server=unicode(self.field(u'proxy_server').toString()),

View File

@ -23,7 +23,45 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
"""
The :mod:`cvsbible` modules provides a facility to import bibles from a set of
CSV files.
The module expects two mandatory files containing the books and the verses and
will accept an optional third file containing the testaments.
The format of the testament file is:
<testament_id>,<testament_name>
For example:
1,Old Testament
2,New Testament
The format of the books file is:
<book_id>,<testament_id>,<book_name>,<book_abbreviation>
For example
1,1,Genesis,Gen
2,1,Exodus,Exod
...
40,2,Matthew,Matt
The format of the verses file is:
<book_id>,<chapter_number>,<verse_number>,<verse_text>
For example:
1,1,1,"In the beginning God created the heaven and the earth."
1,1,2,"And the earth was without form, and void; and darkness...."
All CSV files are expected to use a comma (',') as the delimeter and double
quotes ('"') as the quote symbol.
"""
import logging import logging
import chardet import chardet
import csv import csv
@ -31,7 +69,7 @@ import csv
from PyQt4 import QtCore from PyQt4 import QtCore
from openlp.core.lib import Receiver, translate from openlp.core.lib import Receiver, translate
from openlp.plugins.bibles.lib.db import BibleDB from openlp.plugins.bibles.lib.db import BibleDB, Testament
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -39,68 +77,113 @@ class CSVBible(BibleDB):
""" """
This class provides a specialisation for importing of CSV Bibles. This class provides a specialisation for importing of CSV Bibles.
""" """
def __init__(self, parent, **kwargs): def __init__(self, parent, **kwargs):
""" """
Loads a Bible from a pair of CVS files passed in Loads a Bible from a set of CVS files.
This class assumes the files contain all the information and This class assumes the files contain all the information and
a clean bible is being loaded. a clean bible is being loaded.
""" """
log.info(self.__class__.__name__) log.info(self.__class__.__name__)
BibleDB.__init__(self, parent, **kwargs) BibleDB.__init__(self, parent, **kwargs)
try:
self.testamentsfile = kwargs[u'testamentsfile']
except KeyError:
self.testamentsfile = None
self.booksfile = kwargs[u'booksfile'] self.booksfile = kwargs[u'booksfile']
self.versesfile = kwargs[u'versefile'] self.versesfile = kwargs[u'versefile']
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import) QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
def setup_testaments(self):
"""
Overrides parent method so we can handle importing a testament file.
"""
if self.testamentsfile:
self.wizard.progressBar.setMinimum(0)
self.wizard.progressBar.setMaximum(2)
self.wizard.progressBar.setValue(0)
testaments_file = None
try:
details = get_file_encoding(self.testamentsfile)
testaments_file = open(self.testamentsfile, 'rb')
testaments_reader = csv.reader(testaments_file, delimiter=',',
quotechar='"')
for line in testaments_reader:
if self.stop_import_flag:
break
self.wizard.incrementProgressBar(unicode(
translate('BibleDB.Wizard',
'Importing testaments... %s')) %
unicode(line[1], details['encoding']), 0)
self.save_object(Testament.populate(
name=unicode(line[1], details['encoding'])))
Receiver.send_message(u'openlp_process_events')
except (IOError, IndexError):
log.exception(u'Loading testaments from file failed')
finally:
if testaments_file:
testaments_file.close()
self.wizard.incrementProgressBar(unicode(translate(
'BibleDB.Wizard', 'Importing testaments... done.')), 2)
else:
BibleDB.setup_testaments(self)
def do_import(self): def do_import(self):
"""
Import the bible books and verses.
"""
self.wizard.progressBar.setValue(0)
self.wizard.progressBar.setMinimum(0)
self.wizard.progressBar.setMaximum(66)
success = True success = True
books_file = None books_file = None
book_ptr = None book_list = {}
verse_file = None
# Populate the Tables # Populate the Tables
try: try:
details = get_file_encoding(self.booksfile)
books_file = open(self.booksfile, 'r') books_file = open(self.booksfile, 'r')
dialect = csv.Sniffer().sniff(books_file.read(1024)) books_reader = csv.reader(books_file, delimiter=',', quotechar='"')
books_file.seek(0)
books_reader = csv.reader(books_file, dialect)
for line in books_reader: for line in books_reader:
# cancel pressed
if self.stop_import_flag: if self.stop_import_flag:
break break
details = chardet.detect(line[1]) self.wizard.incrementProgressBar(unicode(
self.create_book(unicode(line[1], details['encoding']), translate('BibleDB.Wizard', 'Importing books... %s')) %
line[2], int(line[0])) unicode(line[2], details['encoding']))
Receiver.send_message(u'openlp_process_events') self.create_book(unicode(line[2], details['encoding']),
unicode(line[3], details['encoding']), int(line[1]))
book_list[int(line[0])] = unicode(line[2], details['encoding'])
Receiver.send_message(u'openlp_process_events')
except (IOError, IndexError): except (IOError, IndexError):
log.exception(u'Loading books from file failed') log.exception(u'Loading books from file failed')
success = False success = False
finally: finally:
if books_file: if books_file:
books_file.close() books_file.close()
if not success: if self.stop_import_flag or not success:
return False return False
self.wizard.progressBar.setValue(0)
self.wizard.progressBar.setMaximum(67)
verse_file = None
try: try:
verse_file = open(self.versesfile, 'r') book_ptr = None
dialect = csv.Sniffer().sniff(verse_file.read(1024)) details = get_file_encoding(self.versesfile)
verse_file.seek(0) verse_file = open(self.versesfile, 'rb')
verse_reader = csv.reader(verse_file, dialect) verse_reader = csv.reader(verse_file, delimiter=',', quotechar='"')
for line in verse_reader: for line in verse_reader:
if self.stop_import_flag: if self.stop_import_flag:
# cancel pressed
break break
details = chardet.detect(line[3]) if book_ptr != book_list[int(line[0])]:
if book_ptr != line[0]: book = self.get_book(book_list[int(line[0])])
book = self.get_book(line[0])
book_ptr = book.name book_ptr = book.name
self.wizard.incrementProgressBar(unicode(translate( self.wizard.incrementProgressBar(unicode(translate(
'BiblesPlugin.CSVImport', 'Importing %s %s...', 'BibleDB.Wizard', 'Importing verses from %s...',
'Importing <book name> <chapter>...')) % 'Importing verses from <book name>...')) % book.name)
(book.name, int(line[1])))
self.session.commit() self.session.commit()
self.create_verse(book.id, line[1], line[2], self.create_verse(book.id, line[1], line[2],
unicode(line[3], details['encoding'])) unicode(line[3], details['encoding']))
Receiver.send_message(u'openlp_process_events') self.wizard.incrementProgressBar(translate('BibleDB.Wizard',
'Importing verses... done.'))
Receiver.send_message(u'openlp_process_events')
self.session.commit() self.session.commit()
except IOError: except IOError:
log.exception(u'Loading verses from file failed') log.exception(u'Loading verses from file failed')
@ -112,3 +195,18 @@ class CSVBible(BibleDB):
return False return False
else: else:
return success return success
def get_file_encoding(filename):
"""
Utility function to get the file encoding.
"""
detect_file = None
try:
detect_file = open(filename, 'r')
details = chardet.detect(detect_file.read(1024))
except IOError:
log.exception(u'Error detecting file encoding')
finally:
if detect_file:
detect_file.close()
return details

View File

@ -206,10 +206,16 @@ class BibleDB(QtCore.QObject, Manager):
""" """
self.wizard = wizard self.wizard = wizard
self.create_meta(u'dbversion', u'2') self.create_meta(u'dbversion', u'2')
self.setup_testaments()
return self.name
def setup_testaments(self):
"""
Initialise the testaments section of a bible with suitable defaults.
"""
self.save_object(Testament.populate(name=u'Old Testament')) self.save_object(Testament.populate(name=u'Old Testament'))
self.save_object(Testament.populate(name=u'New Testament')) self.save_object(Testament.populate(name=u'New Testament'))
self.save_object(Testament.populate(name=u'Apocrypha')) self.save_object(Testament.populate(name=u'Apocrypha'))
return self.name
def create_book(self, name, abbrev, testament=1): def create_book(self, name, abbrev, testament=1):
""" """

View File

@ -92,7 +92,7 @@ class BibleFormat(object):
return None return None
@staticmethod @staticmethod
def list(): def get_formats_list():
""" """
Return a list of the supported Bible formats. Return a list of the supported Bible formats.
""" """

View File

@ -254,9 +254,6 @@ class BibleMediaItem(MediaManagerItem):
QtCore.QObject.connect(self.quickSearchEdit, QtCore.QObject.connect(self.quickSearchEdit,
QtCore.SIGNAL(u'returnPressed()'), self.onQuickSearchButton) QtCore.SIGNAL(u'returnPressed()'), self.onQuickSearchButton)
def addListViewToToolBar(self):
MediaManagerItem.addListViewToToolBar(self)
def configUpdated(self): def configUpdated(self):
log.debug(u'configUpdated') log.debug(u'configUpdated')
if QtCore.QSettings().value(self.settingsSection + u'/second bibles', if QtCore.QSettings().value(self.settingsSection + u'/second bibles',

View File

@ -68,9 +68,6 @@ class CustomMediaItem(MediaManagerItem):
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'custom_preview'), self.onPreviewClick) QtCore.SIGNAL(u'custom_preview'), self.onPreviewClick)
def requiredIcons(self):
MediaManagerItem.requiredIcons(self)
def initialise(self): def initialise(self):
self.loadCustomListView(self.manager.get_all_objects( self.loadCustomListView(self.manager.get_all_objects(
CustomSlide, order_by_ref=CustomSlide.title)) CustomSlide, order_by_ref=CustomSlide.title))
@ -182,4 +179,4 @@ class CustomMediaItem(MediaManagerItem):
else: else:
raw_footer.append(u'') raw_footer.append(u'')
service_item.raw_footer = raw_footer service_item.raw_footer = raw_footer
return True return True

View File

@ -96,7 +96,6 @@ class ImageMediaItem(MediaManagerItem):
def addListViewToToolBar(self): def addListViewToToolBar(self):
MediaManagerItem.addListViewToToolBar(self) MediaManagerItem.addListViewToToolBar(self)
self.listView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
self.listView.addAction(self.replaceAction) self.listView.addAction(self.replaceAction)
def addEndHeaderBar(self): def addEndHeaderBar(self):
@ -220,6 +219,3 @@ class ImageMediaItem(MediaManagerItem):
unicode(translate('ImagePlugin.MediaItem', unicode(translate('ImagePlugin.MediaItem',
'There was a problem replacing your background, ' '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)

View File

@ -84,7 +84,6 @@ class MediaMediaItem(MediaManagerItem):
def addListViewToToolBar(self): def addListViewToToolBar(self):
MediaManagerItem.addListViewToToolBar(self) MediaManagerItem.addListViewToToolBar(self)
self.listView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
self.listView.addAction(self.replaceAction) self.listView.addAction(self.replaceAction)
def addEndHeaderBar(self): def addEndHeaderBar(self):

View File

@ -278,117 +278,129 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def onAuthorEditButtonClick(self): def onAuthorEditButtonClick(self):
author_id = self._getCurrentItemId(self.authorsListWidget) author_id = self._getCurrentItemId(self.authorsListWidget)
if author_id != -1: if author_id == -1:
author = self.manager.get_object(Author, author_id) return
self.authorform.setAutoDisplayName(False) author = self.manager.get_object(Author, author_id)
self.authorform.firstNameEdit.setText(author.first_name) self.authorform.setAutoDisplayName(False)
self.authorform.lastNameEdit.setText(author.last_name) self.authorform.firstNameEdit.setText(author.first_name)
self.authorform.displayEdit.setText(author.display_name) self.authorform.lastNameEdit.setText(author.last_name)
# Save the author's first and last name as well as the display name self.authorform.displayEdit.setText(author.display_name)
# for the case that they have to be restored. # Save the author's first and last name as well as the display name
temp_first_name = author.first_name # for the case that they have to be restored.
temp_last_name = author.last_name temp_first_name = author.first_name
temp_display_name = author.display_name temp_last_name = author.last_name
if self.authorform.exec_(False): temp_display_name = author.display_name
author.first_name = unicode( if self.authorform.exec_(False):
self.authorform.firstNameEdit.text()) author.first_name = unicode(
author.last_name = unicode(self.authorform.lastNameEdit.text()) self.authorform.firstNameEdit.text())
author.display_name = unicode( author.last_name = unicode(self.authorform.lastNameEdit.text())
self.authorform.displayEdit.text()) author.display_name = unicode(
if self.checkAuthor(author, True): self.authorform.displayEdit.text())
if self.manager.save_object(author): if self.checkAuthor(author, True):
self.resetAuthors() if self.manager.save_object(author):
Receiver.send_message(u'songs_load_list')
else:
criticalErrorMessageBox(
message=translate('SongsPlugin.SongMaintenanceForm',
'Could not save your changes.'))
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),
parent=self, question=True) == QtGui.QMessageBox.Yes:
self.mergeAuthors(author)
self.resetAuthors() self.resetAuthors()
Receiver.send_message(u'songs_load_list') Receiver.send_message(u'songs_load_list')
else: else:
# We restore the author's old first and last name as well as
# his display name.
author.first_name = temp_first_name
author.last_name = temp_last_name
author.display_name = temp_display_name
criticalErrorMessageBox( criticalErrorMessageBox(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm',
'Could not save your modified author, because the ' 'Could not save your changes.'))
'author already exists.')) 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),
parent=self, question=True) == QtGui.QMessageBox.Yes:
Receiver.send_message(u'cursor_busy')
Receiver.send_message(u'openlp_process_events')
self.mergeAuthors(author)
self.resetAuthors()
Receiver.send_message(u'songs_load_list')
Receiver.send_message(u'cursor_normal')
else:
# We restore the author's old first and last name as well as
# his display name.
author.first_name = temp_first_name
author.last_name = temp_last_name
author.display_name = temp_display_name
criticalErrorMessageBox(
message=translate('SongsPlugin.SongMaintenanceForm',
'Could not save your modified author, because the '
'author already exists.'))
def onTopicEditButtonClick(self): def onTopicEditButtonClick(self):
topic_id = self._getCurrentItemId(self.topicsListWidget) topic_id = self._getCurrentItemId(self.topicsListWidget)
if topic_id != -1: if topic_id == -1:
topic = self.manager.get_object(Topic, topic_id) return
self.topicform.nameEdit.setText(topic.name) topic = self.manager.get_object(Topic, topic_id)
# Save the topic's name for the case that he has to be restored. self.topicform.nameEdit.setText(topic.name)
temp_name = topic.name # Save the topic's name for the case that he has to be restored.
if self.topicform.exec_(False): temp_name = topic.name
topic.name = unicode(self.topicform.nameEdit.text()) if self.topicform.exec_(False):
if self.checkTopic(topic, True): topic.name = unicode(self.topicform.nameEdit.text())
if self.manager.save_object(topic): if self.checkTopic(topic, True):
self.resetTopics() if self.manager.save_object(topic):
else:
criticalErrorMessageBox(
message=translate('SongsPlugin.SongMaintenanceForm',
'Could not save your changes.'))
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),
parent=self, question=True) == QtGui.QMessageBox.Yes:
self.mergeTopics(topic)
self.resetTopics() self.resetTopics()
else: else:
# We restore the topics's old name.
topic.name = temp_name
criticalErrorMessageBox( criticalErrorMessageBox(
message=translate('SongsPlugin.SongMaintenanceForm', message=translate('SongsPlugin.SongMaintenanceForm',
'Could not save your modified topic, because it ' 'Could not save your changes.'))
'already exists.')) 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),
parent=self, question=True) == QtGui.QMessageBox.Yes:
Receiver.send_message(u'cursor_busy')
Receiver.send_message(u'openlp_process_events')
self.mergeTopics(topic)
self.resetTopics()
Receiver.send_message(u'cursor_normal')
else:
# We restore the topics's old name.
topic.name = temp_name
criticalErrorMessageBox(
message=translate('SongsPlugin.SongMaintenanceForm',
'Could not save your modified topic, because it '
'already exists.'))
def onBookEditButtonClick(self): def onBookEditButtonClick(self):
book_id = self._getCurrentItemId(self.booksListWidget) book_id = self._getCurrentItemId(self.booksListWidget)
if book_id != -1: if book_id == -1:
book = self.manager.get_object(Book, book_id) return
if book.publisher is None: book = self.manager.get_object(Book, book_id)
book.publisher = u'' if book.publisher is None:
self.bookform.nameEdit.setText(book.name) book.publisher = u''
self.bookform.publisherEdit.setText(book.publisher) self.bookform.nameEdit.setText(book.name)
# Save the book's name and publisher for the case that they have to self.bookform.publisherEdit.setText(book.publisher)
# be restored. # Save the book's name and publisher for the case that they have to
temp_name = book.name # be restored.
temp_publisher = book.publisher temp_name = book.name
if self.bookform.exec_(False): temp_publisher = book.publisher
book.name = unicode(self.bookform.nameEdit.text()) if self.bookform.exec_(False):
book.publisher = unicode(self.bookform.publisherEdit.text()) book.name = unicode(self.bookform.nameEdit.text())
if self.checkBook(book, True): book.publisher = unicode(self.bookform.publisherEdit.text())
if self.manager.save_object(book): if self.checkBook(book, True):
self.resetBooks() if self.manager.save_object(book):
else:
criticalErrorMessageBox(
message=translate('SongsPlugin.SongMaintenanceForm',
'Could not save your changes.'))
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),
parent=self, question=True) == QtGui.QMessageBox.Yes:
self.mergeBooks(book)
self.resetBooks() self.resetBooks()
else: else:
# We restore the book's old name and publisher. criticalErrorMessageBox(
book.name = temp_name message=translate('SongsPlugin.SongMaintenanceForm',
book.publisher = temp_publisher 'Could not save your changes.'))
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),
parent=self, question=True) == QtGui.QMessageBox.Yes:
Receiver.send_message(u'cursor_busy')
Receiver.send_message(u'openlp_process_events')
self.mergeBooks(book)
self.resetBooks()
Receiver.send_message(u'cursor_normal')
else:
# We restore the book's old name and publisher.
book.name = temp_name
book.publisher = temp_publisher
def mergeAuthors(self, old_author): def mergeAuthors(self, old_author):
""" """

View File

@ -314,11 +314,11 @@ class EasiSlidesImport(SongImport):
pass pass
def _listHas(self, lst, subitems): def _listHas(self, lst, subitems):
for i in subitems: for subitem in subitems:
if type(lst) == type({}) and lst.has_key(i): if isinstance(lst, dict) and lst.has_key(subitem):
lst = lst[i] lst = lst[subitem]
elif type(lst) == type([]) and i in lst: elif isinstance(lst, list) and subitem in lst:
lst = lst[i] lst = lst[subitem]
else: else:
return False return False
return True return True

View File

@ -105,7 +105,7 @@ class SongFormat(object):
return None return None
@staticmethod @staticmethod
def list(): def get_formats_list():
""" """
Return a list of the supported song formats. Return a list of the supported song formats.
""" """

View File

@ -68,9 +68,6 @@ class SongMediaItem(MediaManagerItem):
self.editItem = None self.editItem = None
self.whitespace = re.compile(r'\W+', re.UNICODE) self.whitespace = re.compile(r'\W+', re.UNICODE)
def requiredIcons(self):
MediaManagerItem.requiredIcons(self)
def addEndHeaderBar(self): def addEndHeaderBar(self):
self.addToolbarSeparator() self.addToolbarSeparator()
## Song Maintenance Button ## ## Song Maintenance Button ##

View File

@ -66,31 +66,34 @@ class OooImport(SongImport):
QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import) QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
def do_import(self): def do_import(self):
self.abort = False self.stop_import_flag = False
self.import_wizard.progressBar.setMaximum(0) self.import_wizard.progressBar.setMaximum(0)
self.start_ooo() self.start_ooo()
for filename in self.filenames: for filename in self.filenames:
if self.abort: if self.stop_import_flag:
self.import_wizard.incrementProgressBar(u'Import cancelled', 0) self.import_wizard.incrementProgressBar(u'Import cancelled', 0)
return return
filename = unicode(filename) filename = unicode(filename)
if os.path.isfile(filename): if os.path.isfile(filename):
self.open_ooo_file(filename) self.open_ooo_file(filename)
if self.document: if self.document:
if self.document.supportsService( self.process_ooo_document()
"com.sun.star.presentation.PresentationDocument"):
self.process_pres()
if self.document.supportsService(
"com.sun.star.text.TextDocument"):
self.process_doc()
self.close_ooo_file() self.close_ooo_file()
self.close_ooo() self.close_ooo()
self.import_wizard.progressBar.setMaximum(1) self.import_wizard.progressBar.setMaximum(1)
self.import_wizard.incrementProgressBar(u'', 1) self.import_wizard.incrementProgressBar(u'', 1)
return True return True
def stop_import(self): def process_ooo_document(self):
self.abort = True """
Handle the import process for OpenOffice files. This method facilitates
allowing subclasses to handle specific types of OpenOffice files.
"""
if self.document.supportsService(
"com.sun.star.presentation.PresentationDocument"):
self.process_pres()
if self.document.supportsService("com.sun.star.text.TextDocument"):
self.process_doc()
def start_ooo(self): def start_ooo(self):
""" """
@ -180,7 +183,7 @@ class OooImport(SongImport):
slides = doc.getDrawPages() slides = doc.getDrawPages()
text = u'' text = u''
for slide_no in range(slides.getCount()): for slide_no in range(slides.getCount()):
if self.abort: if self.stop_import_flag:
self.import_wizard.incrementProgressBar(u'Import cancelled', 0) self.import_wizard.incrementProgressBar(u'Import cancelled', 0)
return return
slide = slides.getByIndex(slide_no) slide = slides.getByIndex(slide_no)

View File

@ -39,9 +39,7 @@ from oooimport import OooImport
if os.name == u'nt': if os.name == u'nt':
BOLD = 150.0 BOLD = 150.0
ITALIC = 2 ITALIC = 2
PAGE_BEFORE = 4 from oooimport import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH
PAGE_AFTER = 5
PAGE_BOTH = 6
else: else:
try: try:
from com.sun.star.awt.FontWeight import BOLD from com.sun.star.awt.FontWeight import BOLD
@ -75,23 +73,11 @@ class SofImport(OooImport):
""" """
OooImport.__init__(self, master_manager, **kwargs) OooImport.__init__(self, master_manager, **kwargs)
def do_import(self): def process_ooo_document(self):
self.abort = False """
self.start_ooo() Handle the import process for SoF files.
for filename in self.filenames: """
if self.abort: self.process_sof_file()
self.import_wizard.incrementProgressBar(u'Import cancelled', 0)
return
filename = unicode(filename)
if os.path.isfile(filename):
self.open_ooo_file(filename)
if self.document:
self.process_sof_file()
self.close_ooo_file()
self.close_ooo()
self.import_wizard.progressBar.setMaximum(1)
self.import_wizard.incrementProgressBar(u'', 1)
return True
def process_sof_file(self): def process_sof_file(self):
""" """
@ -101,7 +87,7 @@ class SofImport(OooImport):
self.new_song() self.new_song()
paragraphs = self.document.getText().createEnumeration() paragraphs = self.document.getText().createEnumeration()
while paragraphs.hasMoreElements(): while paragraphs.hasMoreElements():
if self.abort: if self.stop_import_flag:
self.import_wizard.incrementProgressBar(u'Import cancelled', 0) self.import_wizard.incrementProgressBar(u'Import cancelled', 0)
return return
paragraph = paragraphs.nextElement() paragraph = paragraphs.nextElement()
@ -318,7 +304,6 @@ class SofImport(OooImport):
self.currentverse = u'' self.currentverse = u''
self.is_chorus = False self.is_chorus = False
def uncap_text(self, text): def uncap_text(self, text):
""" """
Words in the title are in all capitals, so we lowercase them. Words in the title are in all capitals, so we lowercase them.

View File

@ -227,7 +227,7 @@ class SongImport(QtCore.QObject):
self.versecounts[versetag[0]] = int(versetag[1:]) self.versecounts[versetag[0]] = int(versetag[1:])
self.verses.append([versetag, versetext.rstrip(), lang]) self.verses.append([versetag, versetext.rstrip(), lang])
self.verse_order_list.append(versetag) self.verse_order_list.append(versetag)
if versetag.startswith(u'V') and self.contains_verse(u'C1'): if versetag.startswith(u'V') and u'C1' in self.verse_order_list:
self.verse_order_list.append(u'C1') self.verse_order_list.append(u'C1')
def repeat_verse(self): def repeat_verse(self):
@ -236,9 +236,6 @@ class SongImport(QtCore.QObject):
""" """
self.verse_order_list.append(self.verse_order_list[-1]) self.verse_order_list.append(self.verse_order_list[-1])
def contains_verse(self, versetag):
return versetag in self.verse_order_list
def check_complete(self): def check_complete(self):
""" """
Check the mandatory fields are entered (i.e. title and a verse) Check the mandatory fields are entered (i.e. title and a verse)