diff --git a/openlp/core/lib/imagemanager.py b/openlp/core/lib/imagemanager.py index 47a7ed3f6..1e2a3a698 100644 --- a/openlp/core/lib/imagemanager.py +++ b/openlp/core/lib/imagemanager.py @@ -163,143 +163,144 @@ class ImageManager(QtCore.QObject): def __init__(self): QtCore.QObject.__init__(self) - current_screen = ScreenList().current - self.width = current_screen[u'size'].width() - self.height = current_screen[u'size'].height() + currentScreen = ScreenList().current + self.width = currentScreen[u'size'].width() + self.height = currentScreen[u'size'].height() self._cache = {} - self._imageThread = ImageThread(self) - self._conversion_queue = PriorityQueue() + self.imageThread = ImageThread(self) + self._conversionQueue = PriorityQueue() + self.stopManager = False QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'config_updated'), self.process_updates) + QtCore.SIGNAL(u'config_updated'), self.processUpdates) - def update_display(self): + def updateDisplay(self): """ Screen has changed size so rebuild the cache to new size. """ - log.debug(u'update_display') - current_screen = ScreenList().current - self.width = current_screen[u'size'].width() - self.height = current_screen[u'size'].height() + log.debug(u'updateDisplay') + currentScreen = ScreenList().current + self.width = currentScreen[u'size'].width() + self.height = currentScreen[u'size'].height() # Mark the images as dirty for a rebuild by setting the image and byte # stream to None. for image in self._cache.values(): - self._reset_image(image) + self._resetImage(image) - def update_images(self, image_type, background): + def updateImages(self, imageType, background): """ Border has changed so update all the images affected. """ - log.debug(u'update_images') + log.debug(u'updateImages') # Mark the images as dirty for a rebuild by setting the image and byte # stream to None. for image in self._cache.values(): - if image.source == image_type: + if image.source == imageType: image.background = background - self._reset_image(image) + self._resetImage(image) - def update_image(self, name, image_type, background): + def updateImage(self, name, imageType, background): """ Border has changed so update the image affected. """ - log.debug(u'update_images') + log.debug(u'updateImage') # Mark the images as dirty for a rebuild by setting the image and byte # stream to None. for image in self._cache.values(): - if image.source == image_type and image.name == name: + if image.source == imageType and image.name == name: image.background = background - self._reset_image(image) + self._resetImage(image) - def _reset_image(self, image): + def _resetImage(self, image): image.image = None image.image_bytes = None - self._conversion_queue.modify_priority(image, Priority.Normal) + self._conversionQueue.modify_priority(image, Priority.Normal) - def process_updates(self): + def processUpdates(self): """ Flush the queue to updated any data to update """ # We want only one thread. - if not self._imageThread.isRunning(): - self._imageThread.start() + if not self.imageThread.isRunning(): + self.imageThread.start() - def get_image(self, name): + def getImage(self, name): """ Return the ``QImage`` from the cache. If not present wait for the background thread to process it. """ - log.debug(u'get_image %s' % name) + log.debug(u'getImage %s' % name) image = self._cache[name] if image.image is None: - self._conversion_queue.modify_priority(image, Priority.High) + self._conversionQueue.modify_priority(image, Priority.High) # make sure we are running and if not give it a kick - self.process_updates() + self.processUpdates() while image.image is None: - log.debug(u'get_image - waiting') + log.debug(u'getImage - waiting') time.sleep(0.1) elif image.image_bytes is None: # Set the priority to Low, because the image was requested but the # byte stream was not generated yet. However, we only need to do # this, when the image was generated before it was requested # (otherwise this is already taken care of). - self._conversion_queue.modify_priority(image, Priority.Low) + self._conversionQueue.modify_priority(image, Priority.Low) return image.image - def get_image_bytes(self, name): + def getImageBytes(self, name): """ Returns the byte string for an image. If not present wait for the background thread to process it. """ - log.debug(u'get_image_bytes %s' % name) + log.debug(u'getImageBytes %s' % name) image = self._cache[name] if image.image_bytes is None: - self._conversion_queue.modify_priority(image, Priority.Urgent) + self._conversionQueue.modify_priority(image, Priority.Urgent) # make sure we are running and if not give it a kick - self.process_updates() + self.processUpdates() while image.image_bytes is None: - log.debug(u'get_image_bytes - waiting') + log.debug(u'getImageBytes - waiting') time.sleep(0.1) return image.image_bytes - def del_image(self, name): + def deleteImage(self, name): """ Delete the Image from the cache. """ - log.debug(u'del_image %s' % name) + log.debug(u'deleteImage %s' % name) if name in self._cache: - self._conversion_queue.remove(self._cache[name]) + self._conversionQueue.remove(self._cache[name]) del self._cache[name] - def add_image(self, name, path, source, background): + def addImage(self, name, path, source, background): """ Add image to cache if it is not already there. """ - log.debug(u'add_image %s:%s' % (name, path)) + log.debug(u'addImage %s:%s' % (name, path)) if not name in self._cache: image = Image(name, path, source, background) self._cache[name] = image - self._conversion_queue.put( + self._conversionQueue.put( (image.priority, image.secondary_priority, image)) else: log.debug(u'Image in cache %s:%s' % (name, path)) # We want only one thread. - if not self._imageThread.isRunning(): - self._imageThread.start() + if not self.imageThread.isRunning(): + self.imageThread.start() def _process(self): """ Controls the processing called from a ``QtCore.QThread``. """ log.debug(u'_process - started') - while not self._conversion_queue.empty(): - self._process_cache() + while not self._conversionQueue.empty() and not self.stopManager: + self._processCache() log.debug(u'_process - ended') - def _process_cache(self): + def _processCache(self): """ Actually does the work. """ - log.debug(u'_process_cache') - image = self._conversion_queue.get()[2] + log.debug(u'_processCache') + image = self._conversionQueue.get()[2] # Generate the QImage for the image. if image.image is None: image.image = resize_image(image.path, self.width, self.height, @@ -307,14 +308,14 @@ class ImageManager(QtCore.QObject): # Set the priority to Lowest and stop here as we need to process # more important images first. if image.priority == Priority.Normal: - self._conversion_queue.modify_priority(image, Priority.Lowest) + self._conversionQueue.modify_priority(image, Priority.Lowest) return # For image with high priority we set the priority to Low, as the # byte stream might be needed earlier the byte stream of image with # Normal priority. We stop here as we need to process more important # images first. elif image.priority == Priority.High: - self._conversion_queue.modify_priority(image, Priority.Low) + self._conversionQueue.modify_priority(image, Priority.Low) return # Generate the byte stream for the image. if image.image_bytes is None: diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index aa39e779b..e782585d0 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -109,6 +109,7 @@ class Renderer(object): self.global_theme_data = \ self.themeManager.getThemeData(self.global_theme) self.theme_data = None + self._cache_background_image(self.global_theme_data) def set_service_theme(self, service_theme): """ @@ -119,6 +120,21 @@ class Renderer(object): """ self.service_theme = service_theme self.theme_data = None + self._cache_background_image(self.themeManager.getThemeData + (service_theme)) + + def _cache_background_image(self, temp_theme): + """ + Adds a background image to the image cache if necessary. + + ``temp_theme`` + The theme object containing the theme data. + """ + # if No file do not update cache + if temp_theme.background_filename: + self.imageManager.addImage(temp_theme.theme_name, + temp_theme.background_filename, u'theme', + QtGui.QColor(temp_theme.background_border_color)) def set_override_theme(self, override_theme, override_levels=False): """ @@ -163,11 +179,7 @@ class Renderer(object): self.theme_data = self.themeManager.getThemeData(theme) self._calculate_default() self._build_text_rectangle(self.theme_data) - # if No file do not update cache - if self.theme_data.background_filename: - self.imageManager.add_image(self.theme_data.theme_name, - self.theme_data.background_filename, u'theme', - QtGui.QColor(self.theme_data.background_border_color)) + self._cache_background_image(self.theme_data) return self._rect, self._rect_footer def generate_preview(self, theme_data, force_page=False): @@ -192,7 +204,7 @@ class Renderer(object): # make big page for theme edit dialog to get line count serviceItem.add_from_text(u'', VERSE_FOR_LINE_COUNT) else: - self.imageManager.del_image(theme_data.theme_name) + self.imageManager.deleteImage(theme_data.theme_name) serviceItem.add_from_text(u'', VERSE) serviceItem.renderer = self serviceItem.raw_footer = FOOTER diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 36314ac7f..0cf5626ff 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -211,7 +211,7 @@ class ServiceItem(object): self.image_border = background self.service_item_type = ServiceItemType.Image self._raw_frames.append({u'title': title, u'path': path}) - self.renderer.imageManager.add_image(title, path, u'image', + self.renderer.imageManager.addImage(title, path, u'image', self.image_border) self._new_item() diff --git a/openlp/core/lib/theme.py b/openlp/core/lib/theme.py index a5dcf881f..686de4c6c 100644 --- a/openlp/core/lib/theme.py +++ b/openlp/core/lib/theme.py @@ -444,6 +444,20 @@ class ThemeXML(object): element.appendChild(child) return child + def set_default_header_footer(self): + """ + Set the header and footer size into the current primary screen. + 10 px on each side is removed to allow for a border. + """ + from openlp.core.ui import ScreenList + current_screen = ScreenList().current + self.font_main_y = 0 + self.font_main_width = current_screen[u'size'].width() - 20 + self.font_main_height = current_screen[u'size'].height() * 9 / 10 + self.font_footer_width = current_screen[u'size'].width() - 20 + self.font_footer_y = current_screen[u'size'].height() * 9 / 10 + self.font_footer_height = current_screen[u'size'].height() / 10 + def dump_xml(self): """ Dump the XML to file used for debugging diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 92df089c3..be30fac40 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -278,7 +278,7 @@ class MainDisplay(Display): """ API for replacement backgrounds so Images are added directly to cache. """ - self.imageManager.add_image(name, path, u'image', background) + self.imageManager.addImage(name, path, u'image', background) if hasattr(self, u'serviceItem'): self.override[u'image'] = name self.override[u'theme'] = self.serviceItem.themedata.theme_name @@ -298,7 +298,7 @@ class MainDisplay(Display): The name of the image to be displayed. """ log.debug(u'image to display') - image = self.imageManager.get_image_bytes(name) + image = self.imageManager.getImageBytes(name) self.controller.mediaController.video_reset(self.controller) self.displayImage(image) @@ -383,14 +383,14 @@ class MainDisplay(Display): else: # replace the background background = self.imageManager. \ - get_image_bytes(self.override[u'image']) + getImageBytes(self.override[u'image']) self.setTransparency(self.serviceItem.themedata.background_type == BackgroundType.to_string(BackgroundType.Transparent)) if self.serviceItem.themedata.background_filename: self.serviceItem.bg_image_bytes = self.imageManager. \ - get_image_bytes(self.serviceItem.themedata.theme_name) + getImageBytes(self.serviceItem.themedata.theme_name) if image: - image_bytes = self.imageManager.get_image_bytes(image) + image_bytes = self.imageManager.getImageBytes(image) else: image_bytes = None html = build_html(self.serviceItem, self.screen, self.isLive, diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 0f28bd4bb..380423432 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -30,6 +30,7 @@ import os import sys import shutil from tempfile import gettempdir +import time from datetime import datetime from PyQt4 import QtCore, QtGui @@ -1122,7 +1123,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): """ log.debug(u'screenChanged') Receiver.send_message(u'cursor_busy') - self.imageManager.update_display() + self.imageManager.updateDisplay() self.renderer.update_display() self.previewController.screenSizeChanged() self.liveController.screenSizeChanged() @@ -1141,6 +1142,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): return # If we just did a settings import, close without saving changes. if self.settingsImported: + self.cleanUp(False) event.accept() if self.serviceManagerContents.isModified(): ret = self.serviceManagerContents.saveModifiedService() @@ -1163,8 +1165,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): translate('OpenLP.MainWindow', 'Are you sure you want to close OpenLP?'), QtGui.QMessageBox.StandardButtons( - QtGui.QMessageBox.Yes | - QtGui.QMessageBox.No), + QtGui.QMessageBox.Yes | QtGui.QMessageBox.No), QtGui.QMessageBox.Yes) if ret == QtGui.QMessageBox.Yes: self.cleanUp() @@ -1175,21 +1176,29 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.cleanUp() event.accept() - def cleanUp(self): + def cleanUp(self, save_settings=True): """ - Runs all the cleanup code before OpenLP shuts down + Runs all the cleanup code before OpenLP shuts down. + + ``save_settings`` + Switch to prevent saving settings. Defaults to **True**. """ + self.imageManager.stopManager = True + while self.imageManager.imageThread.isRunning(): + time.sleep(0.1) # Clean temporary files used by services self.serviceManagerContents.cleanUp() - if Settings().value(u'advanced/save current plugin', - QtCore.QVariant(False)).toBool(): - Settings().setValue(u'advanced/current media plugin', + if save_settings: + if Settings().value(u'advanced/save current plugin', + QtCore.QVariant(False)).toBool(): + Settings().setValue(u'advanced/current media plugin', QtCore.QVariant(self.mediaToolBox.currentIndex())) # Call the cleanup method to shutdown plugins. log.info(u'cleanup plugins') self.pluginManager.finalise_plugins() - # Save settings - self.saveSettings() + if save_settings: + # Save settings + self.saveSettings() # Close down the display if self.liveController.display: self.liveController.display.close() diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index e11396d4b..eaf682f92 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -860,8 +860,8 @@ class SlideController(Controller): # If current slide set background to image if framenumber == slideno: self.serviceItem.bg_image_bytes = \ - self.imageManager.get_image_bytes(frame[u'title']) - image = self.imageManager.get_image(frame[u'title']) + self.imageManager.getImageBytes(frame[u'title']) + image = self.imageManager.getImage(frame[u'title']) label.setPixmap(QtGui.QPixmap.fromImage(image)) self.previewListWidget.setCellWidget(framenumber, 0, label) slideHeight = width * self.parent().renderer.screen_ratio diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 733599672..e38321e1e 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -258,6 +258,7 @@ class ThemeManager(QtGui.QWidget): editing form for the user to make their customisations. """ theme = ThemeXML() + theme.set_default_header_footer() self.themeForm.theme = theme self.themeForm.exec_() @@ -664,9 +665,9 @@ class ThemeManager(QtGui.QWidget): self._writeTheme(theme, image_from, image_to) if theme.background_type == \ BackgroundType.to_string(BackgroundType.Image): - self.mainwindow.imageManager.update_image(theme.theme_name, + self.mainwindow.imageManager.updateImage(theme.theme_name, u'theme', QtGui.QColor(theme.background_border_color)) - self.mainwindow.imageManager.process_updates() + self.mainwindow.imageManager.processUpdates() self.loadThemes() def _writeTheme(self, theme, image_from, image_to): diff --git a/openlp/plugins/images/imageplugin.py b/openlp/plugins/images/imageplugin.py index 832fb9097..e148f5625 100644 --- a/openlp/plugins/images/imageplugin.py +++ b/openlp/plugins/images/imageplugin.py @@ -97,4 +97,4 @@ class ImagePlugin(Plugin): """ background = QtGui.QColor(Settings().value(self.settingsSection + u'/background color', QtCore.QVariant(u'#000000'))) - self.liveController.imageManager.update_images(u'image', background) + self.liveController.imageManager.updateImages(u'image', background) diff --git a/openlp/plugins/remotes/html/index.html b/openlp/plugins/remotes/html/index.html index c2aa38b05..fc8b37441 100644 --- a/openlp/plugins/remotes/html/index.html +++ b/openlp/plugins/remotes/html/index.html @@ -164,7 +164,7 @@ ${search} -