From 060718be329ab527bf6509e15f19598d220863f4 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 20 May 2012 20:26:24 +0200 Subject: [PATCH 01/12] (experimental) attempt to imporve renderer (to be fixed) --- openlp/core/lib/renderer.py | 165 +++++++++++-------------- openlp/core/lib/serviceitem.py | 10 +- openlp/core/ui/slidecontroller.py | 2 +- openlp/core/ui/themeform.py | 1 + openlp/core/ui/themestab.py | 12 +- openlp/plugins/custom/lib/mediaitem.py | 10 +- 6 files changed, 88 insertions(+), 112 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index 8694ca6b6..624b30120 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -59,12 +59,12 @@ class Renderer(object): """ Initialise the renderer. - ``imageManager`` - A imageManager instance which takes care of e. g. caching and resizing - images. + ``imageManager`` + A imageManager instance which takes care of e. g. caching and + resizing images. - ``themeManager`` - The themeManager instance, used to get the current theme details. + ``themeManager`` + The themeManager instance, used to get the current theme details. """ log.debug(u'Initialisation started') self.themeManager = themeManager @@ -73,54 +73,85 @@ class Renderer(object): self.service_theme = u'' self.theme_level = u'' self.override_background = None - self.theme_data = None self.bg_frame = None self.force_page = False self.display = MainDisplay(None, self.imageManager, False, self) self.display.setup() + self.theme_dimensions = {} + self._calculate_default() def update_display(self): """ Updates the renderer's information about the current screen. """ log.debug(u'Update Display') - self._calculate_default() if self.display: self.display.close() self.display = MainDisplay(None, self.imageManager, False, self) self.display.setup() self.bg_frame = None - self.theme_data = None + self._calculate_default() - def set_global_theme(self, global_theme, theme_level=ThemeLevel.Global): + def set_theme(self, theme_name): + """ + """ + if theme_name not in self.theme_dimensions: + theme_data = self.themeManager.getThemeData(theme_name) + main_rect = self.get_main_rectangle(theme_data) + footer_rect = self.get_footer_rectangle(theme_data) + self.theme_dimensions[theme_name] = [theme_data, main_rect, footer_rect] + else: + theme_data, main_rect, footer_rect = self.theme_dimensions[theme_name] + # if No file do not update cache + if theme_data.background_filename: + self.imageManager.add_image(theme_data.theme_name, + theme_data.background_filename, u'theme', + QtGui.QColor(theme_data.background_border_color)) + + def post_render(self, override_theme_data): + """ + """ + # Just assume we use the global theme. + theme_to_use = self.global_theme + if self.theme_level == ThemeLevel.Service: + # When the theme level is at Service and we actually have a service + # theme then use it. + if self.service_theme: + theme_to_use = self.service_theme + elif self.theme_level == ThemeLevel.Song and self.item_theme: + theme_to_use = self.item_theme + theme_data, main_rect, footer_rect = self.theme_dimensions[theme_to_use] + if override_theme_data: + theme_data = override_theme_data + self._set_text_rectangle(theme_data, main_rect, footer_rect) + return theme_data, self._rect, self._rect_footer + + def set_theme_level(self, theme_level): + """ + """ + self.theme_level = theme_level + + def set_global_theme(self, global_theme_name): """ Set the global-level theme and the theme level. ``global_theme`` The global-level theme to be set. - - ``theme_level`` - Defaults to ``ThemeLevel.Global``. The theme level, can be - ``ThemeLevel.Global``, ``ThemeLevel.Service`` or - ``ThemeLevel.Song``. """ - self.global_theme = global_theme - self.theme_level = theme_level - self.global_theme_data = \ - self.themeManager.getThemeData(self.global_theme) - self.theme_data = None + self.set_theme(global_theme_name) + self.global_theme = global_theme_name - def set_service_theme(self, service_theme): + def set_service_theme(self, service_theme_name): """ Set the service-level theme. ``service_theme`` The service-level theme to be set. """ - self.service_theme = service_theme - self.theme_data = None + self.set_theme(service_theme_name) + self.service_theme = service_theme_name - def set_override_theme(self, override_theme, override_levels=False): + def set_override_theme(self, override_theme_name): """ Set the appropriate theme depending on the theme level. Called by the service item when building a display frame @@ -128,47 +159,9 @@ class Renderer(object): ``override_theme`` The name of the song-level theme. None means the service item wants to use the given value. - - ``override_levels`` - Used to force the theme data passed in to be used. """ - log.debug(u'set override theme to %s', override_theme) - theme_level = self.theme_level - if override_levels: - theme_level = ThemeLevel.Song - if theme_level == ThemeLevel.Global: - theme = self.global_theme - elif theme_level == ThemeLevel.Service: - if self.service_theme == u'': - theme = self.global_theme - else: - theme = self.service_theme - else: - # Images have a theme of -1 - if override_theme and override_theme != -1: - theme = override_theme - elif theme_level == ThemeLevel.Song or \ - theme_level == ThemeLevel.Service: - if self.service_theme == u'': - theme = self.global_theme - else: - theme = self.service_theme - else: - theme = self.global_theme - log.debug(u'theme is now %s', theme) - # Force the theme to be the one passed in. - if override_levels: - self.theme_data = override_theme - else: - 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)) - return self._rect, self._rect_footer + self.set_theme(override_theme_name) + self.item_theme = override_theme_name def generate_preview(self, theme_data, force_page=False): """ @@ -183,11 +176,10 @@ class Renderer(object): log.debug(u'generate preview') # save value for use in format_slide self.force_page = force_page - # set the default image size for previews - self._calculate_default() # build a service item to generate preview serviceItem = ServiceItem() - serviceItem.theme = theme_data + serviceItem.theme = theme_data.theme_name + #self.set_override_theme(theme_data) if self.force_page: # make big page for theme edit dialog to get line count serviceItem.add_from_text(u'', VERSE_FOR_LINE_COUNT) @@ -196,14 +188,12 @@ class Renderer(object): serviceItem.add_from_text(u'', VERSE) serviceItem.renderer = self serviceItem.raw_footer = FOOTER - serviceItem.render(True) + serviceItem.render(theme_data) if not self.force_page: self.display.buildHtml(serviceItem) raw_html = serviceItem.get_rendered_frame(0) self.display.text(raw_html) preview = self.display.preview() - # Reset the real screen size for subsequent render requests - self._calculate_default() return preview self.force_page = False @@ -303,32 +293,19 @@ class Renderer(object): # 90% is start of footer self.footer_start = int(self.height * 0.90) - def _build_text_rectangle(self, theme): - """ - Builds a text block using the settings in ``theme`` - and the size of the display screen.height. - Note the system has a 10 pixel border round the screen - ``theme`` - The theme to build a text block for. - """ - log.debug(u'_build_text_rectangle') - main_rect = self.get_main_rectangle(theme) - footer_rect = self.get_footer_rectangle(theme) - self._set_text_rectangle(main_rect, footer_rect) - - def get_main_rectangle(self, theme): + def get_main_rectangle(self, theme_data): """ Calculates the placement and size of the main rectangle. - ``theme`` + ``theme_data`` The theme information """ - if not theme.font_main_override: - return QtCore.QRect(10, 0, self.width - 20, self.footer_start) + if not theme_data.font_main_override: + return QtCore.QRect(10, 0, self.width, self.footer_start) else: - return QtCore.QRect(theme.font_main_x, theme.font_main_y, - theme.font_main_width - 1, theme.font_main_height - 1) + return QtCore.QRect(theme_data.font_main_x, theme_data.font_main_y, + theme_data.font_main_width - 1, theme_data.font_main_height - 1) def get_footer_rectangle(self, theme): """ @@ -345,7 +322,7 @@ class Renderer(object): theme.font_footer_y, theme.font_footer_width - 1, theme.font_footer_height - 1) - def _set_text_rectangle(self, rect_main, rect_footer): + def _set_text_rectangle(self, theme_data, rect_main, rect_footer): """ Sets the rectangle within which text should be rendered. @@ -360,9 +337,9 @@ class Renderer(object): self._rect_footer = rect_footer self.page_width = self._rect.width() self.page_height = self._rect.height() - if self.theme_data.font_main_shadow: - self.page_width -= int(self.theme_data.font_main_shadow_size) - self.page_height -= int(self.theme_data.font_main_shadow_size) + if theme_data.font_main_shadow: + self.page_width -= int(theme_data.font_main_shadow_size) + self.page_height -= int(theme_data.font_main_shadow_size) self.web = QtWebKit.QWebView() self.web.setVisible(False) self.web.resize(self.page_width, self.page_height) @@ -380,8 +357,8 @@ class Renderer(object):
""" % \ - (build_lyrics_format_css(self.theme_data, self.page_width, - self.page_height), build_lyrics_outline_css(self.theme_data)) + (build_lyrics_format_css(theme_data, self.page_width, + self.page_height), build_lyrics_outline_css(theme_data)) self.web.setHtml(html) self.empty_height = self.web_frame.contentsSize().height() diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 36314ac7f..734144172 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -164,13 +164,14 @@ class ServiceItem(object): obtains the display information from the renderer. At this point all slides are built for the given display size. """ + import time + import datetime + start = time.time() log.debug(u'Render called') self._display_frames = [] self.bg_image_bytes = None - theme = self.theme if self.theme else None - self.main, self.footer = \ - self.renderer.set_override_theme(theme, use_override) - self.themedata = self.renderer.theme_data + self.renderer.set_override_theme(self.theme) + self.themedata, self.main, self.footer = self.renderer.post_render(use_override) if self.service_item_type == ServiceItemType.Text: log.debug(u'Formatting slides') for slide in self._raw_frames: @@ -196,6 +197,7 @@ class ServiceItem(object): if self.raw_footer is None: self.raw_footer = [] self.foot_text = u'
'.join(filter(None, self.raw_footer)) + print unicode(datetime.timedelta(seconds=(time.time() - start))) def add_from_image(self, path, title, background=None): """ diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 1dc005aa6..1d4a2c721 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -863,7 +863,7 @@ class SlideController(Controller): image = self.imageManager.get_image(frame[u'title']) label.setPixmap(QtGui.QPixmap.fromImage(image)) self.previewListWidget.setCellWidget(framenumber, 0, label) - slideHeight = width * self.parent().renderer.screen_ratio + slideHeight = width * (1 / self.ratio) row += 1 self.slideList[unicode(row)] = row - 1 text.append(unicode(row)) diff --git a/openlp/core/ui/themeform.py b/openlp/core/ui/themeform.py index f8c061851..5d8e4ed5a 100644 --- a/openlp/core/ui/themeform.py +++ b/openlp/core/ui/themeform.py @@ -250,6 +250,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard): Generate layout preview and display the form. """ self.updateTheme() + screen_size = self.screens.current[u'size'] width = self.thememanager.mainwindow.renderer.width height = self.thememanager.mainwindow.renderer.height pixmap = QtGui.QPixmap(width, height) diff --git a/openlp/core/ui/themestab.py b/openlp/core/ui/themestab.py index f763a9e74..567308115 100644 --- a/openlp/core/ui/themestab.py +++ b/openlp/core/ui/themestab.py @@ -151,8 +151,8 @@ class ThemesTab(SettingsTab): settings.setValue(u'theme level', QtCore.QVariant(self.theme_level)) settings.setValue(u'global theme', QtCore.QVariant(self.global_theme)) settings.endGroup() - self.mainwindow.renderer.set_global_theme( - self.global_theme, self.theme_level) + self.mainwindow.renderer.set_global_theme(self.global_theme) + self.mainwindow.renderer.set_theme_level(self.theme_level) Receiver.send_message(u'theme_update_global', self.global_theme) def postSetUp(self): @@ -169,8 +169,8 @@ class ThemesTab(SettingsTab): def onDefaultComboBoxChanged(self, value): self.global_theme = unicode(self.DefaultComboBox.currentText()) - self.mainwindow.renderer.set_global_theme( - self.global_theme, self.theme_level) + self.mainwindow.renderer.set_global_theme(self.global_theme) + self.mainwindow.renderer.set_theme_level(self.theme_level) self.__previewGlobalTheme() def updateThemeList(self, theme_list): @@ -189,8 +189,8 @@ class ThemesTab(SettingsTab): self.DefaultComboBox.clear() self.DefaultComboBox.addItems(theme_list) find_and_set_in_combo_box(self.DefaultComboBox, self.global_theme) - self.mainwindow.renderer.set_global_theme( - self.global_theme, self.theme_level) + self.mainwindow.renderer.set_global_theme(self.global_theme) + self.mainwindow.renderer.set_theme_level(self.theme_level) if self.global_theme is not u'': self.__previewGlobalTheme() diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py index af2f261ca..814cdf14a 100644 --- a/openlp/plugins/custom/lib/mediaitem.py +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -197,9 +197,6 @@ class CustomMediaItem(MediaManagerItem): def generateSlideData(self, service_item, item=None, xmlVersion=False, remote=False): - raw_footer = [] - slide = None - theme = None item_id = self._getIdOfItemToGenerate(item, self.remoteCustom) service_item.add_capability(ItemCapabilities.CanEdit) service_item.add_capability(ItemCapabilities.CanPreview) @@ -207,6 +204,7 @@ class CustomMediaItem(MediaManagerItem): service_item.add_capability(ItemCapabilities.CanSoftBreak) customSlide = self.plugin.manager.get_object(CustomSlide, item_id) title = customSlide.title + service_item.title = title credit = customSlide.credits service_item.edit_id = item_id theme = customSlide.theme_name @@ -215,15 +213,13 @@ class CustomMediaItem(MediaManagerItem): customXML = CustomXMLParser(customSlide.text) verseList = customXML.get_verses() raw_slides = [verse[1] for verse in verseList] - service_item.title = title for slide in raw_slides: service_item.add_from_text(slide[:30], slide) if QtCore.QSettings().value(self.settingsSection + u'/display footer', QtCore.QVariant(True)).toBool() or credit: - raw_footer.append(title + u' ' + credit) + service_item.raw_footer.append(u' '.join([title, credit])) else: - raw_footer.append(u'') - service_item.raw_footer = raw_footer + service_item.raw_footer.append(u'') return True def onSearchTextButtonClicked(self): From a5fa986bdd20844ad2ea395eb8eadd17e8f0ddc6 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 20 May 2012 21:11:27 +0200 Subject: [PATCH 02/12] continued work --- openlp/core/lib/renderer.py | 62 +++++++++++++++++++++++----------- openlp/core/lib/serviceitem.py | 22 ++++++++---- openlp/core/ui/themeform.py | 1 - openlp/core/ui/thememanager.py | 4 +-- 4 files changed, 60 insertions(+), 29 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index 624b30120..16efcf9ea 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -77,8 +77,10 @@ class Renderer(object): self.force_page = False self.display = MainDisplay(None, self.imageManager, False, self) self.display.setup() - self.theme_dimensions = {} + self._theme_dimensions = {} self._calculate_default() + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'theme_update_global'), self.set_global_theme) def update_display(self): """ @@ -92,23 +94,29 @@ class Renderer(object): self.bg_frame = None self._calculate_default() - def set_theme(self, theme_name): + def update_theme(self): + self._theme_dimensions = {} + + def _set_theme(self, theme_name): """ + Helper method to save theme names and theme data. """ - if theme_name not in self.theme_dimensions: + if theme_name not in self._theme_dimensions: theme_data = self.themeManager.getThemeData(theme_name) main_rect = self.get_main_rectangle(theme_data) footer_rect = self.get_footer_rectangle(theme_data) - self.theme_dimensions[theme_name] = [theme_data, main_rect, footer_rect] + self._theme_dimensions[theme_name] = \ + [theme_data, main_rect, footer_rect] else: - theme_data, main_rect, footer_rect = self.theme_dimensions[theme_name] + theme_data, main_rect, footer_rect = \ + self._theme_dimensions[theme_name] # if No file do not update cache if theme_data.background_filename: self.imageManager.add_image(theme_data.theme_name, theme_data.background_filename, u'theme', QtGui.QColor(theme_data.background_border_color)) - def post_render(self, override_theme_data): + def post_render(self, override_theme_data=None): """ """ # Just assume we use the global theme. @@ -120,35 +128,44 @@ class Renderer(object): theme_to_use = self.service_theme elif self.theme_level == ThemeLevel.Song and self.item_theme: theme_to_use = self.item_theme - theme_data, main_rect, footer_rect = self.theme_dimensions[theme_to_use] - if override_theme_data: + if override_theme_data is None: + theme_data, main_rect, footer_rect = \ + self._theme_dimensions[theme_to_use] + else: + # Ignore everything and use own theme data. theme_data = override_theme_data + main_rect = self.get_main_rectangle(override_theme_data) + footer_rect = self.get_footer_rectangle(override_theme_data) self._set_text_rectangle(theme_data, main_rect, footer_rect) return theme_data, self._rect, self._rect_footer def set_theme_level(self, theme_level): """ + Sets the theme level. + + ``theme_level`` + The theme level to be used. """ self.theme_level = theme_level def set_global_theme(self, global_theme_name): """ - Set the global-level theme and the theme level. + Set the global-level theme name. - ``global_theme`` - The global-level theme to be set. + ``global_theme_name`` + The global-level theme's name. """ - self.set_theme(global_theme_name) + self._set_theme(global_theme_name) self.global_theme = global_theme_name def set_service_theme(self, service_theme_name): """ Set the service-level theme. - ``service_theme`` - The service-level theme to be set. + ``service_theme_name`` + The service level theme's name. """ - self.set_theme(service_theme_name) + self._set_theme(service_theme_name) self.service_theme = service_theme_name def set_override_theme(self, override_theme_name): @@ -160,7 +177,7 @@ class Renderer(object): The name of the song-level theme. None means the service item wants to use the given value. """ - self.set_theme(override_theme_name) + self._set_theme(override_theme_name) self.item_theme = override_theme_name def generate_preview(self, theme_data, force_page=False): @@ -178,8 +195,6 @@ class Renderer(object): self.force_page = force_page # build a service item to generate preview serviceItem = ServiceItem() - serviceItem.theme = theme_data.theme_name - #self.set_override_theme(theme_data) if self.force_page: # make big page for theme edit dialog to get line count serviceItem.add_from_text(u'', VERSE_FOR_LINE_COUNT) @@ -188,7 +203,16 @@ class Renderer(object): serviceItem.add_from_text(u'', VERSE) serviceItem.renderer = self serviceItem.raw_footer = FOOTER - serviceItem.render(theme_data) + # if No file do not update cache + if theme_data.background_filename: + self.imageManager.add_image(theme_data.theme_name, + theme_data.background_filename, u'theme', + QtGui.QColor(theme_data.background_border_color)) + theme_data, main, footer = self.post_render(theme_data) + serviceItem.themedata = theme_data + serviceItem.main = main + serviceItem.footer = footer + serviceItem.render(True) if not self.force_page: self.display.buildHtml(serviceItem) raw_html = serviceItem.get_rendered_frame(0) diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 734144172..a9f2b4e47 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -28,7 +28,7 @@ The :mod:`serviceitem` provides the service item functionality including the type and capability of an item. """ - +import time import cgi import datetime import logging @@ -39,6 +39,9 @@ from openlp.core.lib import build_icon, clean_tags, expand_tags, translate log = logging.getLogger(__name__) +COUNT = 0 +TIME_ = datetime.timedelta() + class ServiceItemType(object): """ Defines the type of service item @@ -158,20 +161,19 @@ class ServiceItem(object): self.icon = icon self.iconic_representation = build_icon(icon) - def render(self, use_override=False): + def render(self, provides_own_theme_data=False): """ The render method is what generates the frames for the screen and obtains the display information from the renderer. At this point all slides are built for the given display size. """ - import time - import datetime start = time.time() log.debug(u'Render called') self._display_frames = [] self.bg_image_bytes = None - self.renderer.set_override_theme(self.theme) - self.themedata, self.main, self.footer = self.renderer.post_render(use_override) + if not provides_own_theme_data: + self.renderer.set_override_theme(self.theme) + self.themedata, self.main, self.footer = self.renderer.post_render() if self.service_item_type == ServiceItemType.Text: log.debug(u'Formatting slides') for slide in self._raw_frames: @@ -197,7 +199,13 @@ class ServiceItem(object): if self.raw_footer is None: self.raw_footer = [] self.foot_text = u'
'.join(filter(None, self.raw_footer)) - print unicode(datetime.timedelta(seconds=(time.time() - start))) + global COUNT + COUNT += 1 + global TIME_ + TIME_ += datetime.timedelta(seconds=(time.time() - start)) + print u'%s (average %s)' % ( + unicode(datetime.timedelta(seconds=(time.time() - start))), + unicode(TIME_ / COUNT)) def add_from_image(self, path, title, background=None): """ diff --git a/openlp/core/ui/themeform.py b/openlp/core/ui/themeform.py index 5d8e4ed5a..f8c061851 100644 --- a/openlp/core/ui/themeform.py +++ b/openlp/core/ui/themeform.py @@ -250,7 +250,6 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard): Generate layout preview and display the form. """ self.updateTheme() - screen_size = self.screens.current[u'size'] width = self.thememanager.mainwindow.renderer.width height = self.thememanager.mainwindow.renderer.height pixmap = QtGui.QPixmap(width, height) diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 665c435b9..6d8778ef3 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -247,8 +247,7 @@ class ThemeManager(QtGui.QWidget): QtCore.QSettings().setValue( self.settingsSection + u'/global theme', QtCore.QVariant(self.global_theme)) - Receiver.send_message(u'theme_update_global', - self.global_theme) + Receiver.send_message(u'theme_update_global', self.global_theme) self._pushThemes() def onAddTheme(self): @@ -667,6 +666,7 @@ class ThemeManager(QtGui.QWidget): u'theme', QtGui.QColor(theme.background_border_color)) self.mainwindow.imageManager.process_updates() self.loadThemes() + #self.mainwindow.renderer.update_theme() def _writeTheme(self, theme, image_from, image_to): """ From c15ac3a84e22c7900755a9ffac01c8e6b45753c7 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 23 May 2012 18:14:03 +0200 Subject: [PATCH 03/12] last fixes --- openlp/core/lib/renderer.py | 54 +++++++++++++++++++++++++--------- openlp/core/lib/serviceitem.py | 7 +++-- openlp/core/ui/thememanager.py | 8 +++-- 3 files changed, 50 insertions(+), 19 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index 16efcf9ea..d2c8d0a5e 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -70,7 +70,7 @@ class Renderer(object): self.themeManager = themeManager self.imageManager = imageManager self.screens = ScreenList.get_instance() - self.service_theme = u'' + self.service_theme_name = u'' self.theme_level = u'' self.override_background = None self.bg_frame = None @@ -94,12 +94,31 @@ class Renderer(object): self.bg_frame = None self._calculate_default() - def update_theme(self): - self._theme_dimensions = {} + def update_theme(self, theme_name, old_theme_name=None): + """ + This method updates the theme in ``_theme_dimensions`` when a theme + has been edited or renamed. + + ``theme_name`` + The current theme name. + + ``old_theme_name`` + The old theme name. Has only to be passed, when the theme has been + renamed. Defaults to *None*. + """ + if old_theme_name is not None and \ + old_theme_name in self._theme_dimensions: + del self._theme_dimensions[old_theme_name] + if theme_name in self._theme_dimensions: + del self._theme_dimensions[theme_name] + self._set_theme(theme_name) def _set_theme(self, theme_name): """ Helper method to save theme names and theme data. + + ``theme_name`` + The theme name. """ if theme_name not in self._theme_dimensions: theme_data = self.themeManager.getThemeData(theme_name) @@ -116,18 +135,25 @@ class Renderer(object): theme_data.background_filename, u'theme', QtGui.QColor(theme_data.background_border_color)) - def post_render(self, override_theme_data=None): + def pre_render(self, override_theme_data=None): """ + Set up the theme to be used before rendering an item. + + ``override_theme_data`` + The theme data should be passed, when we want to use our own theme + data, regardless of the theme level. This should for example be used + in the theme manager. **Note**, this is **not** to be mixed up with + the ``set_item_theme`` method. """ # Just assume we use the global theme. - theme_to_use = self.global_theme + theme_to_use = self.global_theme_name if self.theme_level == ThemeLevel.Service: # When the theme level is at Service and we actually have a service # theme then use it. - if self.service_theme: - theme_to_use = self.service_theme - elif self.theme_level == ThemeLevel.Song and self.item_theme: - theme_to_use = self.item_theme + if self.service_theme_name: + theme_to_use = self.service_theme_name + elif self.theme_level == ThemeLevel.Song and self.item_theme_name: + theme_to_use = self.item_theme_name if override_theme_data is None: theme_data, main_rect, footer_rect = \ self._theme_dimensions[theme_to_use] @@ -156,7 +182,7 @@ class Renderer(object): The global-level theme's name. """ self._set_theme(global_theme_name) - self.global_theme = global_theme_name + self.global_theme_name = global_theme_name def set_service_theme(self, service_theme_name): """ @@ -166,9 +192,9 @@ class Renderer(object): The service level theme's name. """ self._set_theme(service_theme_name) - self.service_theme = service_theme_name + self.service_theme_name = service_theme_name - def set_override_theme(self, override_theme_name): + def set_item_theme(self, item_theme_name): """ Set the appropriate theme depending on the theme level. Called by the service item when building a display frame @@ -177,8 +203,8 @@ class Renderer(object): The name of the song-level theme. None means the service item wants to use the given value. """ - self._set_theme(override_theme_name) - self.item_theme = override_theme_name + self._set_theme(item_theme_name) + self.item_theme_name = item_theme_name def generate_preview(self, theme_data, force_page=False): """ diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index a9f2b4e47..037a8df5e 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -166,14 +166,17 @@ class ServiceItem(object): The render method is what generates the frames for the screen and obtains the display information from the renderer. At this point all slides are built for the given display size. + + ``provides_own_theme_data`` + """ start = time.time() log.debug(u'Render called') self._display_frames = [] self.bg_image_bytes = None if not provides_own_theme_data: - self.renderer.set_override_theme(self.theme) - self.themedata, self.main, self.footer = self.renderer.post_render() + self.renderer.set_item_theme(self.theme) + self.themedata, self.main, self.footer = self.renderer.pre_render() if self.service_item_type == ServiceItemType.Text: log.debug(u'Formatting slides') for slide in self._raw_frames: diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 6d8778ef3..075cd80ac 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -283,6 +283,8 @@ class ThemeManager(QtGui.QWidget): if plugin.usesTheme(old_theme_name): plugin.renameTheme(old_theme_name, new_theme_name) self.loadThemes() + self.mainwindow.renderer.update_theme( + new_theme_name, old_theme_name) def onCopyTheme(self): """ @@ -319,9 +321,8 @@ class ThemeManager(QtGui.QWidget): Loads the settings for the theme that is to be edited and launches the theme editing form so the user can make their changes. """ - if check_item_selected(self.themeListWidget, - translate('OpenLP.ThemeManager', - 'You must select a theme to edit.')): + if check_item_selected(self.themeListWidget, translate( + 'OpenLP.ThemeManager', 'You must select a theme to edit.')): item = self.themeListWidget.currentItem() theme = self.getThemeData( unicode(item.data(QtCore.Qt.UserRole).toString())) @@ -330,6 +331,7 @@ class ThemeManager(QtGui.QWidget): self.themeForm.theme = theme self.themeForm.exec_(True) self.old_background_image = None + self.mainwindow.renderer.update_theme(theme.theme_name) def onDeleteTheme(self): """ From 27454060389705f73623d1901489baa1946ae497 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 23 May 2012 18:28:35 +0200 Subject: [PATCH 04/12] removed test code --- openlp/core/lib/serviceitem.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 037a8df5e..16ab874e3 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -28,7 +28,6 @@ The :mod:`serviceitem` provides the service item functionality including the type and capability of an item. """ -import time import cgi import datetime import logging @@ -39,9 +38,6 @@ from openlp.core.lib import build_icon, clean_tags, expand_tags, translate log = logging.getLogger(__name__) -COUNT = 0 -TIME_ = datetime.timedelta() - class ServiceItemType(object): """ Defines the type of service item @@ -170,7 +166,6 @@ class ServiceItem(object): ``provides_own_theme_data`` """ - start = time.time() log.debug(u'Render called') self._display_frames = [] self.bg_image_bytes = None @@ -202,13 +197,6 @@ class ServiceItem(object): if self.raw_footer is None: self.raw_footer = [] self.foot_text = u'
'.join(filter(None, self.raw_footer)) - global COUNT - COUNT += 1 - global TIME_ - TIME_ += datetime.timedelta(seconds=(time.time() - start)) - print u'%s (average %s)' % ( - unicode(datetime.timedelta(seconds=(time.time() - start))), - unicode(TIME_ / COUNT)) def add_from_image(self, path, title, background=None): """ From 1604d863ebfa274e2a0aca8972b21af8986a6cf6 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 23 May 2012 18:46:54 +0200 Subject: [PATCH 05/12] clean ups --- openlp/core/lib/renderer.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index 033e3cf7c..50ede0eac 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -70,10 +70,10 @@ class Renderer(object): self.themeManager = themeManager self.imageManager = imageManager self.screens = ScreenList() + self.theme_level = ThemeLevel.Global self.service_theme_name = u'' - self.theme_level = u'' - self.override_background = None - self.bg_frame = None + self.service_theme_name = u'' + self.item_theme_name = u'' self.force_page = False self.display = MainDisplay(None, self.imageManager, False, self) self.display.setup() @@ -91,7 +91,6 @@ class Renderer(object): self.display.close() self.display = MainDisplay(None, self.imageManager, False, self) self.display.setup() - self.bg_frame = None self._calculate_default() def update_theme(self, theme_name, old_theme_name=None): @@ -343,7 +342,6 @@ class Renderer(object): # 90% is start of footer self.footer_start = int(self.height * 0.90) - def get_main_rectangle(self, theme_data): """ Calculates the placement and size of the main rectangle. @@ -357,25 +355,28 @@ class Renderer(object): return QtCore.QRect(theme_data.font_main_x, theme_data.font_main_y, theme_data.font_main_width - 1, theme_data.font_main_height - 1) - def get_footer_rectangle(self, theme): + def get_footer_rectangle(self, theme_data): """ Calculates the placement and size of the footer rectangle. - ``theme`` - The theme information + ``theme_data`` + The theme data. """ - if not theme.font_footer_override: + if not theme_data.font_footer_override: return QtCore.QRect(10, self.footer_start, self.width - 20, self.height - self.footer_start) else: - return QtCore.QRect(theme.font_footer_x, - theme.font_footer_y, theme.font_footer_width - 1, - theme.font_footer_height - 1) + return QtCore.QRect(theme_data.font_footer_x, + theme_data.font_footer_y, theme_data.font_footer_width - 1, + theme_data.font_footer_height - 1) def _set_text_rectangle(self, theme_data, rect_main, rect_footer): """ Sets the rectangle within which text should be rendered. + ``theme_data`` + The theme data. + ``rect_main`` The main text block. From 8a90476f8947f513b52179a919357da06f06ad38 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 23 May 2012 18:53:08 +0200 Subject: [PATCH 06/12] added missing line --- openlp/core/lib/serviceitem.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 16ab874e3..1831cd618 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -28,6 +28,7 @@ The :mod:`serviceitem` provides the service item functionality including the type and capability of an item. """ + import cgi import datetime import logging From 28930a9c32ee0e1445ab740c619682e6a20b67c1 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 23 May 2012 18:55:41 +0200 Subject: [PATCH 07/12] added missing docstring --- openlp/core/lib/serviceitem.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 1831cd618..16d3bbdc0 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -165,7 +165,10 @@ class ServiceItem(object): slides are built for the given display size. ``provides_own_theme_data`` - + This switch disables the usage of the item's theme. However, this is + disabled by default. If this is used, it has to be taken care, that + the renderer knows the correct theme data. However, this is needed + for the theme manager. """ log.debug(u'Render called') self._display_frames = [] From 45a9b5f6156099e25499d3951cf5107e5a9cd7f7 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Wed, 23 May 2012 23:02:34 +0200 Subject: [PATCH 08/12] clean ups --- openlp/core/lib/renderer.py | 10 +++++++--- openlp/core/ui/thememanager.py | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index 50ede0eac..268571f7b 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -93,7 +93,7 @@ class Renderer(object): self.display.setup() self._calculate_default() - def update_theme(self, theme_name, old_theme_name=None): + def update_theme(self, theme_name, old_theme_name=None, only_delete=False): """ This method updates the theme in ``_theme_dimensions`` when a theme has been edited or renamed. @@ -104,13 +104,17 @@ class Renderer(object): ``old_theme_name`` The old theme name. Has only to be passed, when the theme has been renamed. Defaults to *None*. + + ``only_delete`` + a """ if old_theme_name is not None and \ old_theme_name in self._theme_dimensions: del self._theme_dimensions[old_theme_name] if theme_name in self._theme_dimensions: del self._theme_dimensions[theme_name] - self._set_theme(theme_name) + if not only_delete: + self._set_theme(theme_name) def _set_theme(self, theme_name): """ @@ -233,7 +237,7 @@ class Renderer(object): self.imageManager.add_image(theme_data.theme_name, theme_data.background_filename, u'theme', QtGui.QColor(theme_data.background_border_color)) - theme_data, main, footer = self.post_render(theme_data) + theme_data, main, footer = self.pre_render(theme_data) serviceItem.themedata = theme_data serviceItem.main = main serviceItem.footer = footer diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 075cd80ac..4200babf7 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -349,6 +349,7 @@ class ThemeManager(QtGui.QWidget): # As we do not reload the themes, push out the change. Reload the # list as the internal lists and events need to be triggered. self._pushThemes() + self.mainwindow.renderer.update_theme(theme, only_delete=True) def deleteTheme(self, theme): """ @@ -668,7 +669,6 @@ class ThemeManager(QtGui.QWidget): u'theme', QtGui.QColor(theme.background_border_color)) self.mainwindow.imageManager.process_updates() self.loadThemes() - #self.mainwindow.renderer.update_theme() def _writeTheme(self, theme, image_from, image_to): """ From 71e8a7a2ebad43e0039728963c5e571a5b2344b1 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Thu, 24 May 2012 20:00:43 +0200 Subject: [PATCH 09/12] fixes and doc string --- openlp/core/lib/renderer.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index 268571f7b..930cefbc3 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -92,6 +92,7 @@ class Renderer(object): self.display = MainDisplay(None, self.imageManager, False, self) self.display.setup() self._calculate_default() + self._theme_dimensions = {} def update_theme(self, theme_name, old_theme_name=None, only_delete=False): """ @@ -106,7 +107,8 @@ class Renderer(object): renamed. Defaults to *None*. ``only_delete`` - a + Only remove the given ``theme_name`` from the ``_theme_dimensions`` + list. This can be used when a theme is permanently deleted. """ if old_theme_name is not None and \ old_theme_name in self._theme_dimensions: @@ -150,14 +152,21 @@ class Renderer(object): """ # Just assume we use the global theme. theme_to_use = self.global_theme_name - if self.theme_level == ThemeLevel.Service: + # The theme level is either set to Service or Item. Use the service + # theme if one is set. We also have to use the service theme, even when + # the theme level is set to Item, because the item does not necessarily + # have to have a theme. + if self.theme_level != ThemeLevel.Global: # When the theme level is at Service and we actually have a service # theme then use it. if self.service_theme_name: theme_to_use = self.service_theme_name - elif self.theme_level == ThemeLevel.Song and self.item_theme_name: + # If we have Item level and have an item theme then use it. + if self.theme_level == ThemeLevel.Song and self.item_theme_name: theme_to_use = self.item_theme_name if override_theme_data is None: + if theme_to_use not in self._theme_dimensions: + self._set_theme(theme_to_use) theme_data, main_rect, footer_rect = \ self._theme_dimensions[theme_to_use] else: From fc577afda22a270adba7dbf6b13119de647003a0 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Thu, 24 May 2012 21:05:15 +0200 Subject: [PATCH 10/12] little clean up, doc string --- openlp/core/lib/renderer.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index 930cefbc3..0fc04e6e0 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -87,11 +87,11 @@ class Renderer(object): Updates the renderer's information about the current screen. """ log.debug(u'Update Display') + self._calculate_default() if self.display: self.display.close() self.display = MainDisplay(None, self.imageManager, False, self) self.display.setup() - self._calculate_default() self._theme_dimensions = {} def update_theme(self, theme_name, old_theme_name=None, only_delete=False): @@ -208,12 +208,11 @@ class Renderer(object): def set_item_theme(self, item_theme_name): """ - Set the appropriate theme depending on the theme level. - Called by the service item when building a display frame + Set the item-level theme. **Note**, this has to be done for each item we + are rendering. - ``override_theme`` - The name of the song-level theme. None means the service - item wants to use the given value. + ``item_theme_name`` + The item theme's name. """ self._set_theme(item_theme_name) self.item_theme_name = item_theme_name From ad3edd4e10f9d7858818ece6a94dededf4dfbd5e Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Mon, 4 Jun 2012 12:51:50 +0200 Subject: [PATCH 11/12] changed attributes to camelCase --- openlp/core/lib/renderer.py | 10 +++++----- openlp/core/lib/serviceitem.py | 2 +- openlp/plugins/songs/forms/editsongform.py | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index ddd5f1978..7b598e0b0 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -55,7 +55,7 @@ class Renderer(object): """ log.info(u'Renderer Loaded') - def __init__(self, image_manager, themeManager): + def __init__(self, image_manager, theme_manager): """ Initialise the renderer. @@ -63,11 +63,11 @@ class Renderer(object): A image_manager instance which takes care of e. g. caching and resizing images. - ``themeManager`` - The themeManager instance, used to get the current theme details. + ``theme_manager`` + The theme_manager instance, used to get the current theme details. """ log.debug(u'Initialisation started') - self.themeManager = themeManager + self.theme_manager = theme_manager self.image_manager = image_manager self.screens = ScreenList() self.theme_level = ThemeLevel.Global @@ -126,7 +126,7 @@ class Renderer(object): The theme name. """ if theme_name not in self._theme_dimensions: - theme_data = self.themeManager.getThemeData(theme_name) + theme_data = self.theme_manager.getThemeData(theme_name) main_rect = self.get_main_rectangle(theme_data) footer_rect = self.get_footer_rectangle(theme_data) self._theme_dimensions[theme_name] = \ diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 635d754ff..5ee8e6167 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -216,7 +216,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.addImage(title, path, u'image', + self.renderer.image_manager.addImage(title, path, u'image', self.image_border) self._new_item() diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index 61043f805..5dea45625 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -97,7 +97,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.onVerseOrderTextChanged) QtCore.QObject.connect(self.themeAddButton, QtCore.SIGNAL(u'clicked()'), - self.mediaitem.plugin.renderer.themeManager.onAddTheme) + self.mediaitem.plugin.renderer.theme_manager.onAddTheme) QtCore.QObject.connect(self.maintenanceButton, QtCore.SIGNAL(u'clicked()'), self.onMaintenanceButtonClicked) QtCore.QObject.connect(self.audioAddFromFileButton, From f17f0dc8cf3bc650f9df2a3f1cc62c245b936dc6 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Fri, 8 Jun 2012 15:27:40 +0200 Subject: [PATCH 12/12] removed print statement, clean up --- openlp/core/lib/renderer.py | 1 - openlp/plugins/custom/lib/mediaitem.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index 7b598e0b0..74cdafd82 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -152,7 +152,6 @@ class Renderer(object): """ # Just assume we use the global theme. theme_to_use = self.global_theme_name - print self.global_theme_name # The theme level is either set to Service or Item. Use the service # theme if one is set. We also have to use the service theme, even when # the theme level is set to Item, because the item does not necessarily diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py index 814cdf14a..d36cb6400 100644 --- a/openlp/plugins/custom/lib/mediaitem.py +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -204,7 +204,6 @@ class CustomMediaItem(MediaManagerItem): service_item.add_capability(ItemCapabilities.CanSoftBreak) customSlide = self.plugin.manager.get_object(CustomSlide, item_id) title = customSlide.title - service_item.title = title credit = customSlide.credits service_item.edit_id = item_id theme = customSlide.theme_name @@ -213,6 +212,7 @@ class CustomMediaItem(MediaManagerItem): customXML = CustomXMLParser(customSlide.text) verseList = customXML.get_verses() raw_slides = [verse[1] for verse in verseList] + service_item.title = title for slide in raw_slides: service_item.add_from_text(slide[:30], slide) if QtCore.QSettings().value(self.settingsSection + u'/display footer',