From 060718be329ab527bf6509e15f19598d220863f4 Mon Sep 17 00:00:00 2001 From: Andreas Preikschat Date: Sun, 20 May 2012 20:26:24 +0200 Subject: [PATCH] (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):