This commit is contained in:
Andreas Preikschat 2011-06-09 17:08:34 +02:00
commit 2b8bee8d0c
28 changed files with 321 additions and 154 deletions

View File

@ -133,6 +133,7 @@ class OpenLP(QtGui.QApplication):
u'general/update check', QtCore.QVariant(True)).toBool() u'general/update check', QtCore.QVariant(True)).toBool()
if update_check: if update_check:
VersionThread(self.mainWindow).start() VersionThread(self.mainWindow).start()
Receiver.send_message(u'maindisplay_blank_check')
self.mainWindow.appStartup() self.mainWindow.appStartup()
DelayStartThread(self.mainWindow).start() DelayStartThread(self.mainWindow).start()
return self.exec_() return self.exec_()

View File

@ -91,7 +91,8 @@ class MediaManagerItem(QtGui.QWidget):
Constructor to create the media manager item. Constructor to create the media manager item.
""" """
QtGui.QWidget.__init__(self, parent) QtGui.QWidget.__init__(self, parent)
self.whitespace = re.compile(r'\W+', re.UNICODE) self.hide()
self.whitespace = re.compile(r'[\W_]+', re.UNICODE)
self.plugin = plugin self.plugin = plugin
visible_title = self.plugin.getString(StringContent.VisibleName) visible_title = self.plugin.getString(StringContent.VisibleName)
self.title = unicode(visible_title[u'title']) self.title = unicode(visible_title[u'title'])
@ -390,21 +391,26 @@ class MediaManagerItem(QtGui.QWidget):
self.iconFromFile(image, thumb) self.iconFromFile(image, thumb)
return True return True
def iconFromFile(self, image, thumb): def iconFromFile(self, image_path, thumb_path):
""" """
Create a thumbnail icon from a given image. Create a thumbnail icon from a given image.
``image`` ``image_path``
The image file to create the icon from. The image file to create the icon from.
``thumb`` ``thumb_path``
The filename to save the thumbnail to The filename to save the thumbnail to.
""" """
icon = build_icon(unicode(image)) ext = os.path.splitext(thumb_path)[1].lower()
pixmap = icon.pixmap(QtCore.QSize(88, 50)) reader = QtGui.QImageReader(image_path)
ext = os.path.splitext(thumb)[1].lower() ratio = float(reader.size().width()) / float(reader.size().height())
pixmap.save(thumb, ext[1:]) reader.setScaledSize(QtCore.QSize(int(ratio * 88), 88))
return icon thumb = reader.read()
thumb.save(thumb_path, ext[1:])
if os.path.exists(thumb_path):
return build_icon(unicode(thumb_path))
# Fallback for files with animation support.
return build_icon(unicode(image_path))
def loadList(self, list): def loadList(self, list):
raise NotImplementedError(u'MediaManagerItem.loadList needs to be ' raise NotImplementedError(u'MediaManagerItem.loadList needs to be '
@ -453,7 +459,8 @@ class MediaManagerItem(QtGui.QWidget):
""" """
if QtCore.QSettings().value(u'advanced/single click preview', if QtCore.QSettings().value(u'advanced/single click preview',
QtCore.QVariant(False)).toBool() and self.quickPreviewAllowed \ QtCore.QVariant(False)).toBool() and self.quickPreviewAllowed \
and self.listView.selectedIndexes(): and self.listView.selectedIndexes() \
and self.auto_select_id == -1:
self.onPreviewClick(True) self.onPreviewClick(True)
def onPreviewClick(self, keepFocus=False): def onPreviewClick(self, keepFocus=False):

View File

@ -300,6 +300,12 @@ class Plugin(QtCore.QObject):
if self.mediaItem: if self.mediaItem:
self.mediadock.remove_dock(self.mediaItem) self.mediadock.remove_dock(self.mediaItem)
def appStartup(self):
"""
Perform tasks on application starup
"""
pass
def usesTheme(self, theme): def usesTheme(self, theme):
""" """
Called to find out if a plugin is currently using a theme. Called to find out if a plugin is currently using a theme.

View File

@ -67,7 +67,7 @@ class Renderer(object):
``theme_manager`` ``theme_manager``
The ThemeManager instance, used to get the current theme details. The ThemeManager instance, used to get the current theme details.
""" """
log.debug(u'Initilisation started') log.debug(u'Initialisation started')
self.theme_manager = theme_manager self.theme_manager = theme_manager
self.image_manager = image_manager self.image_manager = image_manager
self.screens = ScreenList.get_instance() self.screens = ScreenList.get_instance()
@ -86,6 +86,8 @@ class Renderer(object):
""" """
log.debug(u'Update Display') log.debug(u'Update Display')
self._calculate_default(self.screens.current[u'size']) self._calculate_default(self.screens.current[u'size'])
if self.display:
self.display.close()
self.display = MainDisplay(None, self.image_manager, False) self.display = MainDisplay(None, self.image_manager, False)
self.display.setup() self.display.setup()
self.bg_frame = None self.bg_frame = None
@ -241,7 +243,7 @@ class Renderer(object):
``screen`` ``screen``
The QSize of the screen. The QSize of the screen.
""" """
log.debug(u'calculate default %s', screen) log.debug(u'_calculate default %s', screen)
self.width = screen.width() self.width = screen.width()
self.height = screen.height() self.height = screen.height()
self.screen_ratio = float(self.height) / float(self.width) self.screen_ratio = float(self.height) / float(self.width)
@ -286,7 +288,7 @@ class Renderer(object):
``rect_footer`` ``rect_footer``
The footer text block. The footer text block.
""" """
log.debug(u'set_text_rectangle %s , %s' % (rect_main, rect_footer)) log.debug(u'_set_text_rectangle %s , %s' % (rect_main, rect_footer))
self._rect = rect_main self._rect = rect_main
self._rect_footer = rect_footer self._rect_footer = rect_footer
self.page_width = self._rect.width() self.page_width = self._rect.width()
@ -339,7 +341,7 @@ class Renderer(object):
# Text too long so go to next page. # Text too long so go to next page.
if self.web_frame.contentsSize().height() > self.page_height: if self.web_frame.contentsSize().height() > self.page_height:
if force_page and line_count > 0: if force_page and line_count > 0:
Receiver.send_message(u'theme_line_count', line_count) Receiver.send_message(u'theme_line_count', line_count - 1)
line_count = -1 line_count = -1
while html_text.endswith(u'<br>'): while html_text.endswith(u'<br>'):
html_text = html_text[:-4] html_text = html_text[:-4]

View File

@ -63,6 +63,7 @@ class MainDisplay(QtGui.QGraphicsView):
self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;') self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;')
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool | self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool |
QtCore.Qt.WindowStaysOnTopHint) QtCore.Qt.WindowStaysOnTopHint)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
if self.isLive: if self.isLive:
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'maindisplay_hide'), self.hideDisplay) QtCore.SIGNAL(u'maindisplay_hide'), self.hideDisplay)
@ -148,7 +149,6 @@ class MainDisplay(QtGui.QGraphicsView):
self.__hideMouse() self.__hideMouse()
# To display or not to display? # To display or not to display?
if not self.screen[u'primary']: if not self.screen[u'primary']:
self.show()
self.primary = False self.primary = False
else: else:
self.primary = True self.primary = True

View File

@ -655,7 +655,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
# Give all the plugins a chance to perform some tasks at startup # Give all the plugins a chance to perform some tasks at startup
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
for plugin in self.pluginManager.plugins: for plugin in self.pluginManager.plugins:
if hasattr(plugin, u'appStartup'): if plugin.isActive():
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
plugin.appStartup() plugin.appStartup()
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
@ -678,13 +678,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
def blankCheck(self): def blankCheck(self):
""" """
Check and display message if screen blank on setup. Check and display message if screen blank on setup.
Triggered by delay thread.
""" """
settings = QtCore.QSettings() settings = QtCore.QSettings()
self.liveController.mainDisplaySetBackground()
if settings.value(u'%s/screen blank' % self.generalSettingsSection, if settings.value(u'%s/screen blank' % self.generalSettingsSection,
QtCore.QVariant(False)).toBool(): QtCore.QVariant(False)).toBool():
self.liveController.mainDisplaySetBackground() if settings.value(u'%s/blank warning' % self.generalSettingsSection,
if settings.value(u'blank warning',
QtCore.QVariant(False)).toBool(): QtCore.QVariant(False)).toBool():
QtGui.QMessageBox.question(self, QtGui.QMessageBox.question(self,
translate('OpenLP.MainWindow', translate('OpenLP.MainWindow',

View File

@ -132,6 +132,7 @@ class PluginForm(QtGui.QDialog, Ui_PluginViewDialog):
Receiver.send_message(u'cursor_busy') Receiver.send_message(u'cursor_busy')
self.activePlugin.toggleStatus(PluginStatus.Active) self.activePlugin.toggleStatus(PluginStatus.Active)
Receiver.send_message(u'cursor_normal') Receiver.send_message(u'cursor_normal')
self.activePlugin.appStartup()
else: else:
self.activePlugin.toggleStatus(PluginStatus.Inactive) self.activePlugin.toggleStatus(PluginStatus.Inactive)
status_text = unicode( status_text = unicode(

View File

@ -106,7 +106,7 @@ class ScreenList(object):
""" """
# Do not log at start up. # Do not log at start up.
if changed_screen != -1: if changed_screen != -1:
log.info(u'screen_count_changed %d' % number) log.info(u'screen_count_changed %d' % self.desktop.numScreens())
# Remove unplugged screens. # Remove unplugged screens.
for screen in copy.deepcopy(self.screen_list): for screen in copy.deepcopy(self.screen_list):
if screen[u'number'] == self.desktop.numScreens(): if screen[u'number'] == self.desktop.numScreens():
@ -243,6 +243,7 @@ class ScreenList(object):
height = settings.value(u'height', height = settings.value(u'height',
QtCore.QVariant(self.current[u'size'].height())).toInt()[0] QtCore.QVariant(self.current[u'size'].height())).toInt()[0]
self.override[u'size'] = QtCore.QRect(x, y, width, height) self.override[u'size'] = QtCore.QRect(x, y, width, height)
self.override[u'primary'] = False
settings.endGroup() settings.endGroup()
if override_display: if override_display:
self.set_override_display() self.set_override_display()

View File

@ -959,6 +959,7 @@ class ServiceManager(QtGui.QWidget):
treewidgetitem.setToolTip(0, serviceitem.notes) treewidgetitem.setToolTip(0, serviceitem.notes)
treewidgetitem.setData(0, QtCore.Qt.UserRole, treewidgetitem.setData(0, QtCore.Qt.UserRole,
QtCore.QVariant(item[u'order'])) QtCore.QVariant(item[u'order']))
treewidgetitem.setSelected(item[u'selected'])
# Add the children to their parent treewidgetitem. # Add the children to their parent treewidgetitem.
for count, frame in enumerate(serviceitem.get_frames()): for count, frame in enumerate(serviceitem.get_frames()):
child = QtGui.QTreeWidgetItem(treewidgetitem) child = QtGui.QTreeWidgetItem(treewidgetitem)
@ -1030,16 +1031,35 @@ class ServiceManager(QtGui.QWidget):
# force reset of renderer as theme data has changed # force reset of renderer as theme data has changed
self.mainwindow.renderer.themedata = None self.mainwindow.renderer.themedata = None
if self.serviceItems: if self.serviceItems:
for item in self.serviceItems:
item[u'selected'] = False
serviceIterator = QtGui.QTreeWidgetItemIterator(
self.serviceManagerList)
selectedItem = None
while serviceIterator.value():
if serviceIterator.value().isSelected():
selectedItem = serviceIterator.value()
serviceIterator += 1
if selectedItem is not None:
if selectedItem.parent() is None:
pos = selectedItem.data(0, QtCore.Qt.UserRole).toInt()[0]
else:
pos = selectedItem.parent().data(0, QtCore.Qt.UserRole). \
toInt()[0]
self.serviceItems[pos - 1][u'selected'] = True
tempServiceItems = self.serviceItems tempServiceItems = self.serviceItems
self.serviceManagerList.clear() self.serviceManagerList.clear()
self.serviceItems = [] self.serviceItems = []
self.isNew = True self.isNew = True
for item in tempServiceItems: for item in tempServiceItems:
self.addServiceItem( self.addServiceItem(
item[u'service_item'], False, expand=item[u'expanded']) item[u'service_item'], False, expand=item[u'expanded'],
repaint=False, selected=item[u'selected'])
# Set to False as items may have changed rendering # Set to False as items may have changed rendering
# does not impact the saved song so True may also be valid # does not impact the saved song so True may also be valid
self.setModified() self.setModified()
# Repaint it once only at the end
self.repaintServiceList(-1, -1)
Receiver.send_message(u'cursor_normal') Receiver.send_message(u'cursor_normal')
def serviceItemUpdate(self, message): def serviceItemUpdate(self, message):
@ -1069,7 +1089,7 @@ class ServiceManager(QtGui.QWidget):
self.setModified() self.setModified()
def addServiceItem(self, item, rebuild=False, expand=None, replace=False, def addServiceItem(self, item, rebuild=False, expand=None, replace=False,
repaint=True): repaint=True, selected=False):
""" """
Add a Service item to the list Add a Service item to the list
@ -1097,17 +1117,17 @@ class ServiceManager(QtGui.QWidget):
for inditem in item: for inditem in item:
self.serviceItems.append({u'service_item': inditem, self.serviceItems.append({u'service_item': inditem,
u'order': len(self.serviceItems) + 1, u'order': len(self.serviceItems) + 1,
u'expanded': expand}) u'expanded': expand, u'selected': selected})
else: else:
self.serviceItems.append({u'service_item': item, self.serviceItems.append({u'service_item': item,
u'order': len(self.serviceItems) + 1, u'order': len(self.serviceItems) + 1,
u'expanded': expand}) u'expanded': expand, u'selected': selected})
if repaint: if repaint:
self.repaintServiceList(len(self.serviceItems) - 1, -1) self.repaintServiceList(len(self.serviceItems) - 1, -1)
else: else:
self.serviceItems.insert(self.dropPosition, self.serviceItems.insert(self.dropPosition,
{u'service_item': item, u'order': self.dropPosition, {u'service_item': item, u'order': self.dropPosition,
u'expanded': expand}) u'expanded': expand, u'selected': selected})
self.repaintServiceList(self.dropPosition, -1) self.repaintServiceList(self.dropPosition, -1)
# if rebuilding list make sure live is fixed. # if rebuilding list make sure live is fixed.
if rebuild: if rebuild:

View File

@ -59,6 +59,7 @@ class SlideController(QtGui.QWidget):
""" """
QtGui.QWidget.__init__(self, parent) QtGui.QWidget.__init__(self, parent)
self.isLive = isLive self.isLive = isLive
self.display = None
self.screens = ScreenList.get_instance() self.screens = ScreenList.get_instance()
self.ratio = float(self.screens.current[u'size'].width()) / \ self.ratio = float(self.screens.current[u'size'].width()) / \
float(self.screens.current[u'size'].height()) float(self.screens.current[u'size'].height())
@ -422,6 +423,8 @@ class SlideController(QtGui.QWidget):
screen previews. screen previews.
""" """
# rebuild display as screen size changed # rebuild display as screen size changed
if self.display:
self.display.close()
self.display = MainDisplay(self, self.image_manager, self.isLive) self.display = MainDisplay(self, self.image_manager, self.isLive)
self.display.alertTab = self.alertTab self.display.alertTab = self.alertTab
self.display.setup() self.display.setup()
@ -742,8 +745,10 @@ class SlideController(QtGui.QWidget):
self.onThemeDisplay(True) self.onThemeDisplay(True)
elif display_type == u'hidden': elif display_type == u'hidden':
self.onHideDisplay(True) self.onHideDisplay(True)
else: elif display_type == u'blanked':
self.onBlankDisplay(True) self.onBlankDisplay(True)
else:
Receiver.send_message(u'maindisplay_show')
def onSlideBlank(self): def onSlideBlank(self):
""" """

View File

@ -202,7 +202,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
Updates the lines on a page on the wizard Updates the lines on a page on the wizard
""" """
self.mainLineCountLabel.setText(unicode(translate('OpenLP.ThemeForm', self.mainLineCountLabel.setText(unicode(translate('OpenLP.ThemeForm',
'(%d lines per slide)')) % int(lines)) '(approximately %d lines per slide)')) % int(lines))
def resizeEvent(self, event=None): def resizeEvent(self, event=None):
""" """

View File

@ -69,7 +69,6 @@ class VersionThread(QtCore.QThread):
Run the thread. Run the thread.
""" """
time.sleep(1) time.sleep(1)
Receiver.send_message(u'maindisplay_blank_check')
app_version = get_application_version() app_version = get_application_version()
version = check_latest_version(app_version) version = check_latest_version(app_version)
remote_version = {} remote_version = {}

View File

@ -77,6 +77,8 @@ class LanguageManager(object):
AppLocation.LanguageDir)) AppLocation.LanguageDir))
file_names = trans_dir.entryList(QtCore.QStringList(u'*.qm'), file_names = trans_dir.entryList(QtCore.QStringList(u'*.qm'),
QtCore.QDir.Files, QtCore.QDir.Name) QtCore.QDir.Files, QtCore.QDir.Name)
# Remove qm files from the list which start with "qt_".
file_names = file_names.filter(QtCore.QRegExp("^(?!qt_)"))
for name in file_names: for name in file_names:
file_names.replaceInStrings(name, trans_dir.filePath(name)) file_names.replaceInStrings(name, trans_dir.filePath(name))
return file_names return file_names

View File

@ -115,6 +115,8 @@ class BibleUpgradeForm(OpenLPWizard):
self.stop_import_flag = True self.stop_import_flag = True
if not self.currentPage() == self.progressPage: if not self.currentPage() == self.progressPage:
self.done(QtGui.QDialog.Rejected) self.done(QtGui.QDialog.Rejected)
else:
self.postWizard()
def onCurrentIdChanged(self, pageId): def onCurrentIdChanged(self, pageId):
""" """
@ -127,14 +129,6 @@ class BibleUpgradeForm(OpenLPWizard):
elif self.page(pageId) == self.selectPage and self.maxBibles == 0: elif self.page(pageId) == self.selectPage and self.maxBibles == 0:
self.next() self.next()
def onFinishButton(self):
"""
Some cleanup while finishing
"""
for number, filename in enumerate(self.files):
if number in self.success and self.success[number] == True:
delete_file(os.path.join(self.path, filename[0]))
def onBackupBrowseButtonClicked(self): def onBackupBrowseButtonClicked(self):
""" """
Show the file open dialog for the OSIS file. Show the file open dialog for the OSIS file.
@ -180,8 +174,6 @@ class BibleUpgradeForm(OpenLPWizard):
""" """
Set up the signals used in the bible importer. Set up the signals used in the bible importer.
""" """
QtCore.QObject.connect(self.finishButton,
QtCore.SIGNAL(u'clicked()'), self.onFinishButton)
QtCore.QObject.connect(self.backupBrowseButton, QtCore.QObject.connect(self.backupBrowseButton,
QtCore.SIGNAL(u'clicked()'), self.onBackupBrowseButtonClicked) QtCore.SIGNAL(u'clicked()'), self.onBackupBrowseButtonClicked)
QtCore.QObject.connect(self.noBackupCheckBox, QtCore.QObject.connect(self.noBackupCheckBox,
@ -536,7 +528,7 @@ class BibleUpgradeForm(OpenLPWizard):
""" """
Perform the actual upgrade. Perform the actual upgrade.
""" """
include_webbible = False self.include_webbible = False
proxy_server = None proxy_server = None
if self.maxBibles == 0: if self.maxBibles == 0:
self.progressLabel.setText( self.progressLabel.setText(
@ -578,19 +570,19 @@ class BibleUpgradeForm(OpenLPWizard):
name = unicode(self.versionNameEdit[biblenumber].text()) name = unicode(self.versionNameEdit[biblenumber].text())
self.newbibles[number] = BibleDB(self.mediaItem, path=self.path, self.newbibles[number] = BibleDB(self.mediaItem, path=self.path,
name=name) name=name)
self.newbibles[number].register(self.plugin.upgrade_wizard)
metadata = oldbible.get_metadata() metadata = oldbible.get_metadata()
webbible = False webbible = False
meta_data = {} meta_data = {}
for meta in metadata: for meta in metadata:
meta_data[meta[u'key']] = meta[u'value'] meta_data[meta[u'key']] = meta[u'value']
if not meta[u'key'] == u'Version': if not meta[u'key'] == u'Version' and not meta[u'key'] == \
u'dbversion':
self.newbibles[number].create_meta(meta[u'key'], self.newbibles[number].create_meta(meta[u'key'],
meta[u'value']) meta[u'value'])
else:
self.newbibles[number].create_meta(meta[u'key'], name)
if meta[u'key'] == u'download source': if meta[u'key'] == u'download source':
webbible = True webbible = True
include_webbible = True self.include_webbible = True
if meta.has_key(u'proxy server'): if meta.has_key(u'proxy server'):
proxy_server = meta[u'proxy server'] proxy_server = meta[u'proxy server']
if webbible: if webbible:
@ -602,12 +594,11 @@ class BibleUpgradeForm(OpenLPWizard):
handler = BSExtract(proxy_server) handler = BSExtract(proxy_server)
books = handler.get_books_from_http(meta_data[u'download name']) books = handler.get_books_from_http(meta_data[u'download name'])
if not books: if not books:
log.exception(u'Upgrading books from %s - download '\ log.error(u'Upgrading books from %s - download '\
u'name: "%s" failed' % ( u'name: "%s" failed' % (
meta_data[u'download source'], meta_data[u'download source'],
meta_data[u'download name'])) meta_data[u'download name']))
delete_database(self.path, delete_database(self.path, clean_filename(name))
clean_filename(self.newbibles[number].get_name()))
del self.newbibles[number] del self.newbibles[number]
critical_error_message_box( critical_error_message_box(
translate('BiblesPlugin.UpgradeWizardForm', translate('BiblesPlugin.UpgradeWizardForm',
@ -626,16 +617,15 @@ class BibleUpgradeForm(OpenLPWizard):
bible = BiblesResourcesDB.get_webbible( bible = BiblesResourcesDB.get_webbible(
meta_data[u'download name'], meta_data[u'download name'],
meta_data[u'download source'].lower()) meta_data[u'download source'].lower())
if bible[u'language_id']: if bible and bible[u'language_id']:
language_id = bible[u'language_id'] language_id = bible[u'language_id']
self.newbibles[number].create_meta(u'language_id', self.newbibles[number].create_meta(u'language_id',
language_id) language_id)
else: else:
language_id = self.newbibles[number].get_language(name) language_id = self.newbibles[number].get_language(name)
if not language_id: if not language_id:
log.exception(u'Upgrading from "%s" failed' % filename[0]) log.warn(u'Upgrading from "%s" failed' % filename[0])
delete_database(self.path, delete_database(self.path, clean_filename(name))
clean_filename(self.newbibles[number].get_name()))
del self.newbibles[number] del self.newbibles[number]
self.incrementProgressBar(unicode(translate( self.incrementProgressBar(unicode(translate(
'BiblesPlugin.UpgradeWizardForm', 'BiblesPlugin.UpgradeWizardForm',
@ -657,27 +647,42 @@ class BibleUpgradeForm(OpenLPWizard):
book_ref_id = self.newbibles[number].\ book_ref_id = self.newbibles[number].\
get_book_ref_id_by_name(book, len(books), language_id) get_book_ref_id_by_name(book, len(books), language_id)
if not book_ref_id: if not book_ref_id:
log.exception(u'Upgrading books from %s - download '\ log.warn(u'Upgrading books from %s - download '\
u'name: "%s" aborted by user' % ( u'name: "%s" aborted by user' % (
meta_data[u'download source'], meta_data[u'download source'],
meta_data[u'download name'])) meta_data[u'download name']))
delete_database(self.path, delete_database(self.path, clean_filename(name))
clean_filename(self.newbibles[number].get_name()))
del self.newbibles[number] del self.newbibles[number]
bible_failed = True bible_failed = True
break break
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id) book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
self.newbibles[number].create_book(book, book_ref_id, db_book = self.newbibles[number].create_book(book,
book_details[u'testament_id']) book_ref_id, book_details[u'testament_id'])
# Try to import still downloaded verses
oldbook = oldbible.get_book(book)
if oldbook:
verses = oldbible.get_verses(oldbook[u'id'])
if not verses:
log.warn(u'No verses found to import for book '
u'"%s"', book)
continue
for verse in verses:
if self.stop_import_flag:
bible_failed = True
break
self.newbibles[number].create_verse(db_book.id,
int(verse[u'chapter']),
int(verse[u'verse']), unicode(verse[u'text']))
Receiver.send_message(u'openlp_process_events')
self.newbibles[number].session.commit()
else: else:
language_id = self.newbibles[number].get_object(BibleMeta, language_id = self.newbibles[number].get_object(BibleMeta,
u'language_id') u'language_id')
if not language_id: if not language_id:
language_id = self.newbibles[number].get_language(name) language_id = self.newbibles[number].get_language(name)
if not language_id: if not language_id:
log.exception(u'Upgrading books from "%s" failed' % name) log.warn(u'Upgrading books from "%s" failed' % name)
delete_database(self.path, delete_database(self.path, clean_filename(name))
clean_filename(self.newbibles[number].get_name()))
del self.newbibles[number] del self.newbibles[number]
self.incrementProgressBar(unicode(translate( self.incrementProgressBar(unicode(translate(
'BiblesPlugin.UpgradeWizardForm', 'BiblesPlugin.UpgradeWizardForm',
@ -701,10 +706,9 @@ class BibleUpgradeForm(OpenLPWizard):
get_book_ref_id_by_name(book[u'name'], len(books), get_book_ref_id_by_name(book[u'name'], len(books),
language_id) language_id)
if not book_ref_id: if not book_ref_id:
log.exception(u'Upgrading books from %s " '\ log.warn(u'Upgrading books from %s " '\
'failed - aborted by user' % name) 'failed - aborted by user' % name)
delete_database(self.path, delete_database(self.path, clean_filename(name))
clean_filename(self.newbibles[number].get_name()))
del self.newbibles[number] del self.newbibles[number]
bible_failed = True bible_failed = True
break break
@ -713,7 +717,7 @@ class BibleUpgradeForm(OpenLPWizard):
book_ref_id, book_details[u'testament_id']) book_ref_id, book_details[u'testament_id'])
verses = oldbible.get_verses(book[u'id']) verses = oldbible.get_verses(book[u'id'])
if not verses: if not verses:
log.exception(u'No verses found to import for book ' log.warn(u'No verses found to import for book '
u'"%s"', book[u'name']) u'"%s"', book[u'name'])
self.newbibles[number].delete_book(db_book) self.newbibles[number].delete_book(db_book)
continue continue
@ -727,6 +731,8 @@ class BibleUpgradeForm(OpenLPWizard):
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
self.newbibles[number].session.commit() self.newbibles[number].session.commit()
if not bible_failed: if not bible_failed:
self.newbibles[number].create_meta(u'Version', name)
delete_file(os.path.join(self.path, filename[0]))
self.incrementProgressBar(unicode(translate( self.incrementProgressBar(unicode(translate(
'BiblesPlugin.UpgradeWizardForm', 'BiblesPlugin.UpgradeWizardForm',
'Upgrading Bible %s of %s: "%s"\n' 'Upgrading Bible %s of %s: "%s"\n'
@ -739,10 +745,13 @@ class BibleUpgradeForm(OpenLPWizard):
'Upgrading Bible %s of %s: "%s"\nFailed')) % 'Upgrading Bible %s of %s: "%s"\nFailed')) %
(number + 1, self.maxBibles, name), (number + 1, self.maxBibles, name),
self.progressBar.maximum() - self.progressBar.value()) self.progressBar.maximum() - self.progressBar.value())
delete_database(self.path, delete_database(self.path, clean_filename(name))
clean_filename(name))
number += 1 number += 1
self.mediaItem.reloadBibles()
def postWizard(self):
"""
Clean up the UI after the import has finished.
"""
successful_import = 0 successful_import = 0
failed_import = 0 failed_import = 0
for number, filename in enumerate(self.files): for number, filename in enumerate(self.files):
@ -757,7 +766,7 @@ class BibleUpgradeForm(OpenLPWizard):
else: else:
failed_import_text = u'' failed_import_text = u''
if successful_import > 0: if successful_import > 0:
if include_webbible: if self.include_webbible:
self.progressLabel.setText(unicode( self.progressLabel.setText(unicode(
translate('BiblesPlugin.UpgradeWizardForm', 'Upgrading ' translate('BiblesPlugin.UpgradeWizardForm', 'Upgrading '
'Bible(s): %s successful%s\nPlease note, that verses from ' 'Bible(s): %s successful%s\nPlease note, that verses from '
@ -773,3 +782,4 @@ class BibleUpgradeForm(OpenLPWizard):
self.progressLabel.setText( self.progressLabel.setText(
translate('BiblesPlugin.UpgradeWizardForm', 'Upgrade ' translate('BiblesPlugin.UpgradeWizardForm', 'Upgrade '
'failed.')) 'failed.'))
OpenLPWizard.postWizard(self)

View File

@ -381,6 +381,7 @@ class BibleDB(QtCore.QObject, Manager):
""" """
log.debug(u'BibleDB.get_verses("%s")', reference_list) log.debug(u'BibleDB.get_verses("%s")', reference_list)
verse_list = [] verse_list = []
book_error = False
for book_id, chapter, start_verse, end_verse in reference_list: for book_id, chapter, start_verse, end_verse in reference_list:
db_book = self.get_book_by_book_ref_id(book_id) db_book = self.get_book_by_book_ref_id(book_id)
if db_book: if db_book:
@ -398,7 +399,8 @@ class BibleDB(QtCore.QObject, Manager):
verse_list.extend(verses) verse_list.extend(verses)
else: else:
log.debug(u'OpenLP failed to find book with id "%s"', book_id) log.debug(u'OpenLP failed to find book with id "%s"', book_id)
if show_error: book_error = True
if book_error and show_error:
critical_error_message_box( critical_error_message_box(
translate('BiblesPlugin', 'No Book Found'), translate('BiblesPlugin', 'No Book Found'),
translate('BiblesPlugin', 'No matching book ' translate('BiblesPlugin', 'No matching book '
@ -1043,6 +1045,28 @@ class OldBibleDB(QtCore.QObject, Manager):
else: else:
return None return None
def get_book(self, name):
"""
Return a book by name or abbreviation.
``name``
The name or abbreviation of the book.
"""
if not isinstance(name, unicode):
name = unicode(name)
books = self.run_sql(u'SELECT id, testament_id, name, '
u'abbreviation FROM book WHERE LOWER(name) = ? OR '
u'LOWER(abbreviation) = ?', (name.lower(), name.lower()))
if books:
return {
u'id': books[0][0],
u'testament_id': books[0][1],
u'name': unicode(books[0][2]),
u'abbreviation': unicode(books[0][3])
}
else:
return None
def get_books(self): def get_books(self):
""" """
Returns the books of the Bible. Returns the books of the Bible.

View File

@ -72,9 +72,8 @@ class BGExtract(object):
log.debug(u'BGExtract.get_bible_chapter("%s", "%s", "%s")', version, log.debug(u'BGExtract.get_bible_chapter("%s", "%s", "%s")', version,
bookname, chapter) bookname, chapter)
urlbookname = urllib.quote(bookname.encode("utf-8")) urlbookname = urllib.quote(bookname.encode("utf-8"))
url_params = urllib.urlencode( url_params = u'search=%s+%s&version=%s' % (urlbookname, chapter,
{u'search': u'%s %s' % (urlbookname, chapter), version)
u'version': u'%s' % version})
cleaner = [(re.compile('&nbsp;|<br />|\'\+\''), lambda match: '')] cleaner = [(re.compile('&nbsp;|<br />|\'\+\''), lambda match: '')]
soup = get_soup_for_bible_ref( soup = get_soup_for_bible_ref(
u'http://www.biblegateway.com/passage/?%s' % url_params, u'http://www.biblegateway.com/passage/?%s' % url_params,
@ -97,7 +96,7 @@ class BGExtract(object):
verse_list = {} verse_list = {}
# Cater for inconsistent mark up in the first verse of a chapter. # Cater for inconsistent mark up in the first verse of a chapter.
first_verse = verses.find(u'versenum') first_verse = verses.find(u'versenum')
if first_verse: if first_verse and len(first_verse.contents):
verse_list[1] = unicode(first_verse.contents[0]) verse_list[1] = unicode(first_verse.contents[0])
for verse in verses(u'sup', u'versenum'): for verse in verses(u'sup', u'versenum'):
raw_verse_num = verse.next raw_verse_num = verse.next
@ -110,7 +109,7 @@ class BGExtract(object):
try: try:
clean_verse_num = int(str(raw_verse_num)) clean_verse_num = int(str(raw_verse_num))
except ValueError: except ValueError:
log.exception(u'Illegal verse number in %s %s %s:%s', log.warn(u'Illegal verse number in %s %s %s:%s',
version, bookname, chapter, unicode(raw_verse_num)) version, bookname, chapter, unicode(raw_verse_num))
if clean_verse_num: if clean_verse_num:
verse_text = raw_verse_num.next verse_text = raw_verse_num.next
@ -140,16 +139,17 @@ class BGExtract(object):
""" """
log.debug(u'BGExtract.get_books_from_http("%s")', version) log.debug(u'BGExtract.get_books_from_http("%s")', version)
url_params = urllib.urlencode( url_params = urllib.urlencode(
{u'search': 'Bible-List', u'version': u'%s' % version}) {u'action': 'getVersionInfo', u'vid': u'%s' % version})
reference_url = u'http://www.biblegateway.com/passage/?%s' % url_params reference_url = u'http://www.biblegateway.com/versions/?%s#books' % \
url_params
page = get_web_page(reference_url) page = get_web_page(reference_url)
if not page: if not page:
send_error_message(u'download') send_error_message(u'download')
return None return None
page_source = page.read() page_source = page.read()
page_source = unicode(page_source, 'utf8') page_source = unicode(page_source, 'utf8')
page_source_temp = re.search(u'<table id="booklist".*?>.*?</table>', \ page_source_temp = re.search(u'<table .*?class="infotable".*?>.*?'\
page_source, re.DOTALL) u'</table>', page_source, re.DOTALL)
if page_source_temp: if page_source_temp:
soup = page_source_temp.group(0) soup = page_source_temp.group(0)
else: else:
@ -157,15 +157,17 @@ class BGExtract(object):
try: try:
soup = BeautifulSoup(soup) soup = BeautifulSoup(soup)
except HTMLParseError: except HTMLParseError:
log.exception(u'BeautifulSoup could not parse the Bible page.') log.error(u'BeautifulSoup could not parse the Bible page.')
send_error_message(u'parse')
return None
if not soup: if not soup:
send_error_message(u'parse') send_error_message(u'parse')
return None return None
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
content = soup.find(u'table', {u'id': u'booklist'}) content = soup.find(u'table', {u'class': u'infotable'})
content = content.findAll(u'tr') content = content.findAll(u'tr')
if not content: if not content:
log.exception(u'No books found in the Biblegateway response.') log.error(u'No books found in the Biblegateway response.')
send_error_message(u'parse') send_error_message(u'parse')
return None return None
books = [] books = []
@ -200,9 +202,10 @@ class BSExtract(object):
""" """
log.debug(u'BSExtract.get_bible_chapter("%s", "%s", "%s")', version, log.debug(u'BSExtract.get_bible_chapter("%s", "%s", "%s")', version,
bookname, chapter) bookname, chapter)
urlversion = urllib.quote(version.encode("utf-8"))
urlbookname = urllib.quote(bookname.encode("utf-8")) urlbookname = urllib.quote(bookname.encode("utf-8"))
chapter_url = u'http://m.bibleserver.com/text/%s/%s%s' % \ chapter_url = u'http://m.bibleserver.com/text/%s/%s%d' % \
(version, urlbookname, chapter) (urlversion, urlbookname, chapter)
header = (u'Accept-Language', u'en') header = (u'Accept-Language', u'en')
soup = get_soup_for_bible_ref(chapter_url, header) soup = get_soup_for_bible_ref(chapter_url, header)
if not soup: if not soup:
@ -210,7 +213,7 @@ class BSExtract(object):
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
content = soup.find(u'div', u'content') content = soup.find(u'div', u'content')
if not content: if not content:
log.exception(u'No verses found in the Bibleserver response.') log.error(u'No verses found in the Bibleserver response.')
send_error_message(u'parse') send_error_message(u'parse')
return None return None
content = content.find(u'div').findAll(u'div') content = content.find(u'div').findAll(u'div')
@ -231,14 +234,15 @@ class BSExtract(object):
The version of the Bible like NIV for New International Version The version of the Bible like NIV for New International Version
""" """
log.debug(u'BSExtract.get_books_from_http("%s")', version) log.debug(u'BSExtract.get_books_from_http("%s")', version)
urlversion = urllib.quote(version.encode("utf-8"))
chapter_url = u'http://m.bibleserver.com/overlay/selectBook?'\ chapter_url = u'http://m.bibleserver.com/overlay/selectBook?'\
'translation=%s' % (version) 'translation=%s' % (urlversion)
soup = get_soup_for_bible_ref(chapter_url) soup = get_soup_for_bible_ref(chapter_url)
if not soup: if not soup:
return None return None
content = soup.find(u'ul') content = soup.find(u'ul')
if not content: if not content:
log.exception(u'No books found in the Bibleserver response.') log.error(u'No books found in the Bibleserver response.')
send_error_message(u'parse') send_error_message(u'parse')
return None return None
content = content.findAll(u'li') content = content.findAll(u'li')
@ -282,7 +286,7 @@ class CWExtract(object):
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
htmlverses = soup.findAll(u'span', u'versetext') htmlverses = soup.findAll(u'span', u'versetext')
if not htmlverses: if not htmlverses:
log.debug(u'No verses found in the CrossWalk response.') log.error(u'No verses found in the CrossWalk response.')
send_error_message(u'parse') send_error_message(u'parse')
return None return None
verses = {} verses = {}
@ -334,7 +338,7 @@ class CWExtract(object):
content = soup.find(u'div', {u'class': u'Body'}) content = soup.find(u'div', {u'class': u'Body'})
content = content.find(u'ul', {u'class': u'parent'}) content = content.find(u'ul', {u'class': u'parent'})
if not content: if not content:
log.exception(u'No books found in the Crosswalk response.') log.error(u'No books found in the Crosswalk response.')
send_error_message(u'parse') send_error_message(u'parse')
return None return None
content = content.findAll(u'li') content = content.findAll(u'li')

View File

@ -675,9 +675,32 @@ class BibleMediaItem(MediaManagerItem):
second_bible, text) second_bible, text)
if second_bible and self.search_results: if second_bible and self.search_results:
text = [] text = []
new_search_results = []
count = 0
passage_not_found = False
for verse in self.search_results: for verse in self.search_results:
text.append((verse.book.name, verse.chapter, verse.verse, db_book = bibles[second_bible].get_book_by_book_ref_id(
verse.book.book_reference_id)
if not db_book:
log.debug(u'Passage "%s %d:%d" not found in Second '
u'Bible' % (verse.book.name, verse.chapter,
verse.verse)) verse.verse))
passage_not_found = True
count += 1
continue
new_search_results.append(verse)
text.append((verse.book.book_reference_id, verse.chapter,
verse.verse, verse.verse))
if passage_not_found:
QtGui.QMessageBox.information(self,
translate('BiblePlugin.MediaItem', 'Information'),
unicode(translate('BiblePlugin.MediaItem',
'The second Bibles does not contain all the verses '
'that are in the main Bible. Only verses found in both '
'Bibles will be shown. %d verses have not been '
'included in the results.')) % count,
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.search_results = new_search_results
self.second_search_results = \ self.second_search_results = \
bibles[second_bible].get_verses(text) bibles[second_bible].get_verses(text)
if not self.quickLockButton.isChecked(): if not self.quickLockButton.isChecked():
@ -960,7 +983,7 @@ class BibleMediaItem(MediaManagerItem):
Search for some Bible verses (by reference). Search for some Bible verses (by reference).
""" """
bible = unicode(self.quickVersionComboBox.currentText()) bible = unicode(self.quickVersionComboBox.currentText())
search_results = self.plugin.manager.get_verses(bible, string, False) search_results = self.plugin.manager.get_verses(bible, string, False, False)
results = [] results = []
if search_results: if search_results:
versetext = u' '.join([verse.text for verse in search_results]) versetext = u' '.join([verse.text for verse in search_results])

View File

@ -115,7 +115,6 @@ class EditCustomForm(QtGui.QDialog, Ui_CustomEditDialog):
def accept(self): def accept(self):
log.debug(u'accept') log.debug(u'accept')
if self.saveCustom(): if self.saveCustom():
Receiver.send_message(u'custom_load_list')
QtGui.QDialog.accept(self) QtGui.QDialog.accept(self)
def saveCustom(self): def saveCustom(self):

View File

@ -109,7 +109,7 @@ class CustomMediaItem(MediaManagerItem):
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'custom_edit_clear'), self.onRemoteEditClear) QtCore.SIGNAL(u'custom_edit_clear'), self.onRemoteEditClear)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'custom_load_list'), self.initialise) QtCore.SIGNAL(u'custom_load_list'), self.loadList)
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)
@ -129,14 +129,6 @@ class CustomMediaItem(MediaManagerItem):
self.searchTextEdit.setCurrentSearchType(QtCore.QSettings().value( self.searchTextEdit.setCurrentSearchType(QtCore.QSettings().value(
u'%s/last search type' % self.settingsSection, u'%s/last search type' % self.settingsSection,
QtCore.QVariant(CustomSearch.Titles)).toInt()[0]) QtCore.QVariant(CustomSearch.Titles)).toInt()[0])
# Called to redisplay the custom list screen edith from a search
# or from the exit of the Custom edit dialog. If remote editing is
# active trigger it and clean up so it will not update again.
if self.remoteTriggered == u'L':
self.onAddClick()
if self.remoteTriggered == u'P':
self.onPreviewClick()
self.onRemoteEditClear()
def loadList(self, custom_slides): def loadList(self, custom_slides):
# Sort out what custom we want to select after loading the list. # Sort out what custom we want to select after loading the list.
@ -155,11 +147,20 @@ class CustomMediaItem(MediaManagerItem):
if custom_slide.id == self.auto_select_id: if custom_slide.id == self.auto_select_id:
self.listView.setCurrentItem(custom_name) self.listView.setCurrentItem(custom_name)
self.auto_select_id = -1 self.auto_select_id = -1
# Called to redisplay the custom list screen edith from a search
# or from the exit of the Custom edit dialog. If remote editing is
# active trigger it and clean up so it will not update again.
if self.remoteTriggered == u'L':
self.onAddClick()
if self.remoteTriggered == u'P':
self.onPreviewClick()
self.onRemoteEditClear()
def onNewClick(self): def onNewClick(self):
self.edit_custom_form.loadCustom(0) self.edit_custom_form.loadCustom(0)
self.edit_custom_form.exec_() self.edit_custom_form.exec_()
self.initialise() self.onClearTextButtonClick()
self.onSelectionChange()
def onRemoteEditClear(self): def onRemoteEditClear(self):
self.remoteTriggered = None self.remoteTriggered = None
@ -179,6 +180,8 @@ class CustomMediaItem(MediaManagerItem):
self.remoteTriggered = remote_type self.remoteTriggered = remote_type
self.edit_custom_form.loadCustom(custom_id, (remote_type == u'P')) self.edit_custom_form.loadCustom(custom_id, (remote_type == u'P'))
self.edit_custom_form.exec_() self.edit_custom_form.exec_()
self.auto_select_id = -1
self.onSearchTextButtonClick()
def onEditClick(self): def onEditClick(self):
""" """
@ -189,7 +192,8 @@ class CustomMediaItem(MediaManagerItem):
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
self.edit_custom_form.loadCustom(item_id, False) self.edit_custom_form.loadCustom(item_id, False)
self.edit_custom_form.exec_() self.edit_custom_form.exec_()
self.initialise() self.auto_select_id = -1
self.onSearchTextButtonClick()
def onDeleteClick(self): def onDeleteClick(self):
""" """

View File

@ -125,7 +125,7 @@ class ImpressController(PresentationController):
try: try:
uno_instance = get_uno_instance(resolver) uno_instance = get_uno_instance(resolver)
except: except:
log.exception(u'Unable to find running instance ') log.warn(u'Unable to find running instance ')
self.start_process() self.start_process()
loop += 1 loop += 1
try: try:
@ -136,7 +136,7 @@ class ImpressController(PresentationController):
"com.sun.star.frame.Desktop", uno_instance) "com.sun.star.frame.Desktop", uno_instance)
return desktop return desktop
except: except:
log.exception(u'Failed to get UNO desktop') log.warn(u'Failed to get UNO desktop')
return None return None
def get_com_desktop(self): def get_com_desktop(self):
@ -151,7 +151,7 @@ class ImpressController(PresentationController):
try: try:
desktop = self.manager.createInstance(u'com.sun.star.frame.Desktop') desktop = self.manager.createInstance(u'com.sun.star.frame.Desktop')
except AttributeError: except AttributeError:
log.exception(u'Failure to find desktop - Impress may have closed') log.warn(u'Failure to find desktop - Impress may have closed')
return desktop if desktop else None return desktop if desktop else None
def get_com_servicemanager(self): def get_com_servicemanager(self):
@ -162,7 +162,7 @@ class ImpressController(PresentationController):
try: try:
return Dispatch(u'com.sun.star.ServiceManager') return Dispatch(u'com.sun.star.ServiceManager')
except pywintypes.com_error: except pywintypes.com_error:
log.exception(u'Failed to get COM service manager. ' log.warn(u'Failed to get COM service manager. '
u'Impress Controller has been disabled') u'Impress Controller has been disabled')
return None return None
@ -180,7 +180,7 @@ class ImpressController(PresentationController):
else: else:
desktop = self.get_com_desktop() desktop = self.get_com_desktop()
except: except:
log.exception(u'Failed to find an OpenOffice desktop to terminate') log.warn(u'Failed to find an OpenOffice desktop to terminate')
if not desktop: if not desktop:
return return
docs = desktop.getComponents() docs = desktop.getComponents()
@ -191,7 +191,7 @@ class ImpressController(PresentationController):
desktop.terminate() desktop.terminate()
log.debug(u'OpenOffice killed') log.debug(u'OpenOffice killed')
except: except:
log.exception(u'Failed to terminate OpenOffice') log.warn(u'Failed to terminate OpenOffice')
class ImpressDocument(PresentationDocument): class ImpressDocument(PresentationDocument):
@ -244,7 +244,7 @@ class ImpressDocument(PresentationDocument):
self.document = desktop.loadComponentFromURL(url, u'_blank', self.document = desktop.loadComponentFromURL(url, u'_blank',
0, properties) 0, properties)
except: except:
log.exception(u'Failed to load presentation %s' % url) log.warn(u'Failed to load presentation %s' % url)
return False return False
if os.name == u'nt': if os.name == u'nt':
# As we can't start minimized the Impress window gets in the way. # As we can't start minimized the Impress window gets in the way.
@ -323,7 +323,7 @@ class ImpressDocument(PresentationDocument):
self.presentation = None self.presentation = None
self.document.dispose() self.document.dispose()
except: except:
log.exception("Closing presentation failed") log.warn("Closing presentation failed")
self.document = None self.document = None
self.controller.remove_doc(self) self.controller.remove_doc(self)
@ -341,7 +341,7 @@ class ImpressDocument(PresentationDocument):
log.debug("getPresentation failed to find a presentation") log.debug("getPresentation failed to find a presentation")
return False return False
except: except:
log.exception("getPresentation failed to find a presentation") log.warn("getPresentation failed to find a presentation")
return False return False
return True return True

View File

@ -77,7 +77,7 @@ class PresentationPlugin(Plugin):
try: try:
self.controllers[controller].start_process() self.controllers[controller].start_process()
except: except:
log.exception(u'Failed to start controller process') log.warn(u'Failed to start controller process')
self.controllers[controller].available = False self.controllers[controller].available = False
self.mediaItem.buildFileMaskString() self.mediaItem.buildFileMaskString()
@ -128,7 +128,7 @@ class PresentationPlugin(Plugin):
try: try:
__import__(modulename, globals(), locals(), []) __import__(modulename, globals(), locals(), [])
except ImportError: except ImportError:
log.exception(u'Failed to import %s on path %s', log.warn(u'Failed to import %s on path %s',
modulename, path) modulename, path)
controller_classes = PresentationController.__subclasses__() controller_classes = PresentationController.__subclasses__()
for controller_class in controller_classes: for controller_class in controller_classes:

View File

@ -696,7 +696,6 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.clearCaches() self.clearCaches()
if self._validate_song(): if self._validate_song():
self.saveSong() self.saveSong()
Receiver.send_message(u'songs_load_list')
self.song = None self.song = None
QtGui.QDialog.accept(self) QtGui.QDialog.accept(self)

View File

@ -32,6 +32,9 @@ from openlp.core.lib import translate
from db import Author from db import Author
from ui import SongStrings from ui import SongStrings
WHITESPACE = re.compile(r'[\W_]+', re.UNICODE)
APOSTROPHE = re.compile(u'[\'`ʻ]', re.UNICODE)
class VerseType(object): class VerseType(object):
""" """
VerseType provides an enumeration for the tags that may be associated VerseType provides an enumeration for the tags that may be associated
@ -246,6 +249,12 @@ def retrieve_windows_encoding(recommendation=None):
return None return None
return filter(lambda item: item[1] == choice[0], encodings)[0][0] return filter(lambda item: item[1] == choice[0], encodings)[0][0]
def clean_string(string):
"""
Strips punctuation from the passed string to assist searching
"""
return WHITESPACE.sub(u' ', APOSTROPHE.sub(u'', string)).lower()
def clean_song(manager, song): def clean_song(manager, song):
""" """
Cleans the search title, rebuilds the search lyrics, adds a default author Cleans the search title, rebuilds the search lyrics, adds a default author
@ -262,9 +271,8 @@ def clean_song(manager, song):
if song.alternate_title is None: if song.alternate_title is None:
song.alternate_title = u'' song.alternate_title = u''
song.alternate_title = song.alternate_title.strip() song.alternate_title = song.alternate_title.strip()
whitespace = re.compile(r'\W+', re.UNICODE) song.search_title = clean_string(song.title) + u'@' + \
song.search_title = (whitespace.sub(u' ', song.title).strip() + u'@' + clean_string(song.alternate_title)
whitespace.sub(u' ', song.alternate_title).strip()).strip().lower()
# Only do this, if we the song is a 1.9.4 song (or older). # Only do this, if we the song is a 1.9.4 song (or older).
if song.lyrics.find(u'<lyrics language="en">') != -1: if song.lyrics.find(u'<lyrics language="en">') != -1:
# Remove the old "language" attribute from lyrics tag (prior to 1.9.5). # Remove the old "language" attribute from lyrics tag (prior to 1.9.5).
@ -273,8 +281,8 @@ def clean_song(manager, song):
song.lyrics = song.lyrics.replace( song.lyrics = song.lyrics.replace(
u'<lyrics language="en">', u'<lyrics>') u'<lyrics language="en">', u'<lyrics>')
verses = SongXML().get_verses(song.lyrics) verses = SongXML().get_verses(song.lyrics)
lyrics = u' '.join([whitespace.sub(u' ', verse[1]) for verse in verses]) song.search_lyrics = u' '.join([clean_string(verse[1])
song.search_lyrics = lyrics.lower() for verse in verses])
# We need a new and clean SongXML instance. # We need a new and clean SongXML instance.
sxml = SongXML() sxml = SongXML()
# Rebuild the song's verses, to remove any wrong verse names (for # Rebuild the song's verses, to remove any wrong verse names (for
@ -316,6 +324,11 @@ def clean_song(manager, song):
if order not in compare_order: if order not in compare_order:
song.verse_order = u'' song.verse_order = u''
break break
else:
verses = SongXML().get_verses(song.lyrics)
song.search_lyrics = u' '.join([clean_string(verse[1])
for verse in verses])
# The song does not have any author, add one. # The song does not have any author, add one.
if not song.authors: if not song.authors:
name = SongStrings.AuthorUnknown name = SongStrings.AuthorUnknown

View File

@ -38,7 +38,8 @@ from openlp.core.lib.searchedit import SearchEdit
from openlp.core.lib.ui import UiStrings from openlp.core.lib.ui import UiStrings
from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \ from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \
SongImportForm, SongExportForm SongImportForm, SongExportForm
from openlp.plugins.songs.lib import OpenLyrics, SongXML, VerseType from openlp.plugins.songs.lib import OpenLyrics, SongXML, VerseType, \
clean_string
from openlp.plugins.songs.lib.db import Author, Song from openlp.plugins.songs.lib.db import Author, Song
from openlp.plugins.songs.lib.ui import SongStrings from openlp.plugins.songs.lib.ui import SongStrings
@ -181,13 +182,14 @@ class SongMediaItem(MediaManagerItem):
elif search_type == SongSearch.Titles: elif search_type == SongSearch.Titles:
log.debug(u'Titles Search') log.debug(u'Titles Search')
search_results = self.plugin.manager.get_all_objects(Song, search_results = self.plugin.manager.get_all_objects(Song,
Song.search_title.like(u'%' + self.whitespace.sub(u' ', Song.search_title.like(u'%' + clean_string(search_keywords) +
search_keywords.lower()) + u'%')) u'%'))
self.displayResultsSong(search_results) self.displayResultsSong(search_results)
elif search_type == SongSearch.Lyrics: elif search_type == SongSearch.Lyrics:
log.debug(u'Lyrics Search') log.debug(u'Lyrics Search')
search_results = self.plugin.manager.get_all_objects(Song, search_results = self.plugin.manager.get_all_objects(Song,
Song.search_lyrics.like(u'%' + search_keywords.lower() + u'%')) Song.search_lyrics.like(u'%' + clean_string(search_keywords) +
u'%'))
self.displayResultsSong(search_results) self.displayResultsSong(search_results)
elif search_type == SongSearch.Authors: elif search_type == SongSearch.Authors:
log.debug(u'Authors Search') log.debug(u'Authors Search')
@ -198,16 +200,16 @@ class SongMediaItem(MediaManagerItem):
elif search_type == SongSearch.Themes: elif search_type == SongSearch.Themes:
log.debug(u'Theme Search') log.debug(u'Theme Search')
search_results = self.plugin.manager.get_all_objects(Song, search_results = self.plugin.manager.get_all_objects(Song,
Song.theme_name.like(u'%' + self.whitespace.sub(u' ', Song.theme_name.like(u'%' + search_keywords + u'%'))
search_keywords) + u'%'))
self.displayResultsSong(search_results) self.displayResultsSong(search_results)
self.check_search_result() self.check_search_result()
def searchEntire(self, search_keywords): def searchEntire(self, search_keywords):
return self.plugin.manager.get_all_objects(Song, return self.plugin.manager.get_all_objects(Song,
or_(Song.search_title.like(u'%' + self.whitespace.sub(u' ', or_(Song.search_title.like(u'%' + clean_string(search_keywords)
search_keywords.lower()) + u'%'), + u'%'),
Song.search_lyrics.like(u'%' + search_keywords.lower() + u'%'), Song.search_lyrics.like(u'%' + clean_string(search_keywords)
+ u'%'),
Song.comments.like(u'%' + search_keywords.lower() + u'%'))) Song.comments.like(u'%' + search_keywords.lower() + u'%')))
def onSongListLoad(self): def onSongListLoad(self):
@ -300,6 +302,9 @@ class SongMediaItem(MediaManagerItem):
log.debug(u'onNewClick') log.debug(u'onNewClick')
self.edit_song_form.newSong() self.edit_song_form.newSong()
self.edit_song_form.exec_() self.edit_song_form.exec_()
self.onClearTextButtonClick()
self.onSelectionChange()
self.auto_select_id = -1
def onSongMaintenanceClick(self): def onSongMaintenanceClick(self):
self.song_maintenance_form.exec_() self.song_maintenance_form.exec_()
@ -324,6 +329,8 @@ class SongMediaItem(MediaManagerItem):
self.remoteTriggered = remote_type self.remoteTriggered = remote_type
self.edit_song_form.loadSong(song_id, (remote_type == u'P')) self.edit_song_form.loadSong(song_id, (remote_type == u'P'))
self.edit_song_form.exec_() self.edit_song_form.exec_()
self.auto_select_id = -1
self.onSongListLoad()
def onEditClick(self): def onEditClick(self):
""" """
@ -335,6 +342,8 @@ class SongMediaItem(MediaManagerItem):
item_id = (self.editItem.data(QtCore.Qt.UserRole)).toInt()[0] item_id = (self.editItem.data(QtCore.Qt.UserRole)).toInt()[0]
self.edit_song_form.loadSong(item_id, False) self.edit_song_form.loadSong(item_id, False)
self.edit_song_form.exec_() self.edit_song_form.exec_()
self.auto_select_id = -1
self.onSongListLoad()
self.editItem = None self.editItem = None
def onDeleteClick(self): def onDeleteClick(self):

View File

@ -30,6 +30,7 @@ import os
from PyQt4 import QtCore from PyQt4 import QtCore
from openlp.core.utils import get_uno_command, get_uno_instance from openlp.core.utils import get_uno_command, get_uno_instance
from openlp.core.lib import translate
from songimport import SongImport from songimport import SongImport
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -39,8 +40,10 @@ if os.name == u'nt':
PAGE_BEFORE = 4 PAGE_BEFORE = 4
PAGE_AFTER = 5 PAGE_AFTER = 5
PAGE_BOTH = 6 PAGE_BOTH = 6
NoConnectException = Exception
else: else:
import uno import uno
from com.sun.star.connection import NoConnectException
from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH
class OooImport(SongImport): class OooImport(SongImport):
@ -57,7 +60,17 @@ class OooImport(SongImport):
self.process_started = False self.process_started = False
def do_import(self): def do_import(self):
if not isinstance(self.import_source, list):
return
try:
self.start_ooo() self.start_ooo()
except NoConnectException as exc:
self.log_error(
self.import_source[0],
translate('SongsPlugin.SongImport',
'Unable to open OpenOffice.org or LibreOffice'))
log.error(exc)
return
self.import_wizard.progressBar.setMaximum(len(self.import_source)) self.import_wizard.progressBar.setMaximum(len(self.import_source))
for filename in self.import_source: for filename in self.import_source:
if self.stop_import_flag: if self.stop_import_flag:
@ -68,6 +81,13 @@ class OooImport(SongImport):
if self.document: if self.document:
self.process_ooo_document() self.process_ooo_document()
self.close_ooo_file() self.close_ooo_file()
else:
self.log_error(self.filepath,
translate('SongsPlugin.SongImport',
'Unable to open file'))
else:
self.log_error(self.filepath,
translate('SongsPlugin.SongImport', 'File not found'))
self.close_ooo() self.close_ooo()
def process_ooo_document(self): def process_ooo_document(self):
@ -99,13 +119,16 @@ class OooImport(SongImport):
while uno_instance is None and loop < 5: while uno_instance is None and loop < 5:
try: try:
uno_instance = get_uno_instance(resolver) uno_instance = get_uno_instance(resolver)
except: except NoConnectException:
log.exception("Failed to resolve uno connection") log.exception("Failed to resolve uno connection")
self.start_ooo_process() self.start_ooo_process()
loop += 1 loop += 1
else:
manager = uno_instance.ServiceManager manager = uno_instance.ServiceManager
self.desktop = manager.createInstanceWithContext( self.desktop = manager.createInstanceWithContext(
"com.sun.star.frame.Desktop", uno_instance) "com.sun.star.frame.Desktop", uno_instance)
return
raise
def start_ooo_process(self): def start_ooo_process(self):
try: try:
@ -145,8 +168,8 @@ class OooImport(SongImport):
else: else:
self.import_wizard.incrementProgressBar( self.import_wizard.incrementProgressBar(
u'Processing file ' + filepath, 0) u'Processing file ' + filepath, 0)
except: except AttributeError:
log.exception("open_ooo_file failed") log.exception("open_ooo_file failed: %s", url)
return return
def close_ooo_file(self): def close_ooo_file(self):

View File

@ -31,21 +31,27 @@
# http://www.oooforum.org/forum/viewtopic.phtml?t=14409 # http://www.oooforum.org/forum/viewtopic.phtml?t=14409
# http://wiki.services.openoffice.org/wiki/Python # http://wiki.services.openoffice.org/wiki/Python
import logging
import os import os
import re import re
from oooimport import OooImport from oooimport import OooImport
log = logging.getLogger(__name__)
if os.name == u'nt': if os.name == u'nt':
BOLD = 150.0 BOLD = 150.0
ITALIC = 2 ITALIC = 2
from oooimport import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH from oooimport import PAGE_BEFORE, PAGE_AFTER, PAGE_BOTH
RuntimeException = Exception
else: else:
try: try:
from com.sun.star.awt.FontWeight import BOLD from com.sun.star.awt.FontWeight import BOLD
from com.sun.star.awt.FontSlant import ITALIC from com.sun.star.awt.FontSlant import ITALIC
from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, \ from com.sun.star.style.BreakType import PAGE_BEFORE, PAGE_AFTER, \
PAGE_BOTH PAGE_BOTH
from com.sun.star.uno import RuntimeException
except ImportError: except ImportError:
pass pass
@ -86,6 +92,7 @@ class SofImport(OooImport):
""" """
self.blanklines = 0 self.blanklines = 0
self.new_song() self.new_song()
try:
paragraphs = self.document.getText().createEnumeration() paragraphs = self.document.getText().createEnumeration()
while paragraphs.hasMoreElements(): while paragraphs.hasMoreElements():
if self.stop_import_flag: if self.stop_import_flag:
@ -93,9 +100,10 @@ class SofImport(OooImport):
paragraph = paragraphs.nextElement() paragraph = paragraphs.nextElement()
if paragraph.supportsService("com.sun.star.text.Paragraph"): if paragraph.supportsService("com.sun.star.text.Paragraph"):
self.process_paragraph(paragraph) self.process_paragraph(paragraph)
if self.song: except RuntimeException as exc:
self.finish() log.exception(u'Error processing file: %s', exc)
self.song = False if not self.finish():
self.log_error(self.filepath)
def process_paragraph(self, paragraph): def process_paragraph(self, paragraph):
""" """

View File

@ -102,6 +102,13 @@ psvince.dll
the install will fail. The dll can be obtained from here: the install will fail. The dll can be obtained from here:
http://www.vincenzo.net/isxkb/index.php?title=PSVince) http://www.vincenzo.net/isxkb/index.php?title=PSVince)
Mako
Mako Templates for Python. This package is required for building the
remote plugin. It can be installed by going to your
python_directory\scripts\.. and running "easy_install Mako". If you do not
have easy_install, the Mako package can be obtained here:
http://www.makotemplates.org/download.html
""" """
import os import os
@ -194,7 +201,8 @@ def write_version_file():
code = bzr.wait() code = bzr.wait()
if code != 0: if code != 0:
raise Exception(u'Error running bzr log') raise Exception(u'Error running bzr log')
latest = output.split(u':')[0] outputAscii = unicode(output, errors='ignore')
latest = outputAscii.split(u':')[0]
versionstring = latest == revision and tag or u'%s-bzr%s' % (tag, latest) versionstring = latest == revision and tag or u'%s-bzr%s' % (tag, latest)
f = open(os.path.join(dist_path, u'.version'), u'w') f = open(os.path.join(dist_path, u'.version'), u'w')
f.write(versionstring) f.write(versionstring)