- improved code readability

- updated docstrings

bzr-revno: 1704
This commit is contained in:
Andreas Preikschat 2011-08-07 16:37:40 +02:00
commit ffbfd1efe9
2 changed files with 55 additions and 50 deletions

View File

@ -46,8 +46,6 @@ VERSE = u'The Lord said to {r}Noah{/r}: \n' \
'r{/pk}{o}e{/o}{pp}n{/pp} of the Lord\n' 'r{/pk}{o}e{/o}{pp}n{/pp} of the Lord\n'
FOOTER = [u'Arky Arky (Unknown)', u'Public Domain', u'CCLI 123456'] FOOTER = [u'Arky Arky (Unknown)', u'Public Domain', u'CCLI 123456']
HTML_END = u'</div></body></html>'
class Renderer(object): class Renderer(object):
""" """
Class to pull all Renderer interactions into one place. The plugins will Class to pull all Renderer interactions into one place. The plugins will
@ -85,7 +83,7 @@ class Renderer(object):
Updates the render manager's information about the current screen. Updates the render manager's information about the current screen.
""" """
log.debug(u'Update Display') log.debug(u'Update Display')
self._calculate_default(self.screens.current[u'size']) self._calculate_default()
if self.display: if self.display:
self.display.close() self.display.close()
self.display = MainDisplay(None, self.imageManager, False) self.display = MainDisplay(None, self.imageManager, False)
@ -163,7 +161,7 @@ class Renderer(object):
self.theme_data = override_theme self.theme_data = override_theme
else: else:
self.theme_data = self.themeManager.getThemeData(theme) self.theme_data = self.themeManager.getThemeData(theme)
self._calculate_default(self.screens.current[u'size']) self._calculate_default()
self._build_text_rectangle(self.theme_data) self._build_text_rectangle(self.theme_data)
# if No file do not update cache # if No file do not update cache
if self.theme_data.background_filename: if self.theme_data.background_filename:
@ -185,7 +183,7 @@ class Renderer(object):
# save value for use in format_slide # save value for use in format_slide
self.force_page = force_page self.force_page = force_page
# set the default image size for previews # set the default image size for previews
self._calculate_default(self.screens.preview[u'size']) self._calculate_default()
# build a service item to generate preview # build a service item to generate preview
serviceItem = ServiceItem() serviceItem = ServiceItem()
serviceItem.theme = theme_data serviceItem.theme = theme_data
@ -203,7 +201,7 @@ class Renderer(object):
raw_html = serviceItem.get_rendered_frame(0) raw_html = serviceItem.get_rendered_frame(0)
preview = self.display.text(raw_html) preview = self.display.text(raw_html)
# Reset the real screen size for subsequent render requests # Reset the real screen size for subsequent render requests
self._calculate_default(self.screens.current[u'size']) self._calculate_default()
return preview return preview
self.force_page = False self.force_page = False
@ -224,7 +222,7 @@ class Renderer(object):
line_end = u' ' line_end = u' '
# Bibles # Bibles
if item.is_capable(ItemCapabilities.AllowsWordSplit): if item.is_capable(ItemCapabilities.AllowsWordSplit):
pages = self._paginate_slide_words(text, line_end) pages = self._paginate_slide_words(text.split(u'\n'), line_end)
else: else:
# Clean up line endings. # Clean up line endings.
lines = self._lines_split(text) lines = self._lines_split(text)
@ -245,19 +243,16 @@ class Renderer(object):
new_pages.append(page) new_pages.append(page)
return new_pages return new_pages
def _calculate_default(self, screen): def _calculate_default(self):
""" """
Calculate the default dimentions of the screen. Calculate the default dimentions of the screen.
``screen``
The screen to calculate the default of.
""" """
log.debug(u'_calculate default %s', screen) screen_size = self.screens.current[u'size']
self.width = screen.width() self.width = screen_size.width()
self.height = screen.height() self.height = screen_size.height()
self.screen_ratio = float(self.height) / float(self.width) self.screen_ratio = float(self.height) / float(self.width)
log.debug(u'calculate default %d, %d, %f', log.debug(u'_calculate default %s, %f' % (screen_size,
self.width, self.height, self.screen_ratio) self.screen_ratio))
# 90% is start of footer # 90% is start of footer
self.footer_start = int(self.height * 0.90) self.footer_start = int(self.height * 0.90)
@ -310,17 +305,28 @@ class Renderer(object):
self.web.resize(self.page_width, self.page_height) self.web.resize(self.page_width, self.page_height)
self.web_frame = self.web.page().mainFrame() self.web_frame = self.web.page().mainFrame()
# Adjust width and height to account for shadow. outline done in css # Adjust width and height to account for shadow. outline done in css
self.page_shell = u'<!DOCTYPE html><html><head><style>' \ html = u"""<!DOCTYPE html><html><head><script>
u'*{margin:0; padding:0; border:0;} '\ function show_text(newtext) {
u'#main {position:absolute; top:0px; %s %s}</style></head><body>' \ var main = document.getElementById('main');
u'<div id="main">' % \ main.innerHTML = newtext;
// We need to be sure that the page is loaded, that is why we
// return the element's height (even though we do not use the
// returned value).
return main.offsetHeight;
}
</script><style>*{margin: 0; padding: 0; border: 0;}
#main {position: absolute; top: 0px; %s %s}</style></head><body>
<div id="main"></div></body></html>""" % \
(build_lyrics_format_css(self.theme_data, self.page_width, (build_lyrics_format_css(self.theme_data, self.page_width,
self.page_height), build_lyrics_outline_css(self.theme_data)) self.page_height), build_lyrics_outline_css(self.theme_data))
self.web.setHtml(html)
def _paginate_slide(self, lines, line_end): def _paginate_slide(self, lines, line_end):
""" """
Figure out how much text can appear on a slide, using the current Figure out how much text can appear on a slide, using the current
theme settings. theme settings.
**Note:** The smallest possible "unit" of text for a slide is one line.
If the line is too long it will be cut off when displayed.
``lines`` ``lines``
The text to be fitted on the slide split into lines. The text to be fitted on the slide split into lines.
@ -334,10 +340,8 @@ class Renderer(object):
previous_raw = u'' previous_raw = u''
separator = u'<br>' separator = u'<br>'
html_lines = map(expand_tags, lines) html_lines = map(expand_tags, lines)
html = self.page_shell + separator.join(html_lines) + HTML_END
self.web.setHtml(html)
# 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._text_fits_on_slide(separator.join(html_lines)):
html_text, previous_raw = self._binary_chop(formatted, html_text, previous_raw = self._binary_chop(formatted,
previous_html, previous_raw, html_lines, lines, separator, u'') previous_html, previous_raw, html_lines, lines, separator, u'')
else: else:
@ -347,48 +351,41 @@ class Renderer(object):
log.debug(u'_paginate_slide - End') log.debug(u'_paginate_slide - End')
return formatted return formatted
def _paginate_slide_words(self, text, line_end): def _paginate_slide_words(self, lines, line_end):
""" """
Figure out how much text can appear on a slide, using the current Figure out how much text can appear on a slide, using the current
theme settings. This version is to handle text which needs to be split theme settings.
into words to get it to fit. **Note:** The smallest possible "unit" of text for a slide is one word.
If one line is too long it will be processed word by word. This is
sometimes need for **bible** verses.
``text`` ``lines``
The words to be fitted on the slide split into lines. The text to be fitted on the slide split into lines.
``line_end`` ``line_end``
The text added after each line. Either ``u' '`` or ``u'<br>``. The text added after each line. Either ``u' '`` or ``u'<br>``.
This is needed for bibles. This is needed for **bibles**.
""" """
log.debug(u'_paginate_slide_words - Start') log.debug(u'_paginate_slide_words - Start')
formatted = [] formatted = []
previous_html = u'' previous_html = u''
previous_raw = u'' previous_raw = u''
lines = text.split(u'\n')
for line in lines: for line in lines:
line = line.strip() line = line.strip()
html_line = expand_tags(line) html_line = expand_tags(line)
html = self.page_shell + previous_html + html_line + HTML_END
self.web.setHtml(html)
# 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._text_fits_on_slide(previous_html + html_line):
# Check if there was a verse before the current one and append # Check if there was a verse before the current one and append
# it, when it fits on the page. # it, when it fits on the page.
if previous_html: if previous_html:
html = self.page_shell + previous_html + HTML_END if not self._text_fits_on_slide(previous_html):
self.web.setHtml(html)
if self.web_frame.contentsSize().height() <= \
self.page_height:
formatted.append(previous_raw) formatted.append(previous_raw)
previous_html = u'' previous_html = u''
previous_raw = u'' previous_raw = u''
html = self.page_shell + html_line + HTML_END
self.web.setHtml(html)
# Now check if the current verse will fit, if it does # Now check if the current verse will fit, if it does
# not we have to start to process the verse word by # not we have to start to process the verse word by
# word. # word.
if self.web_frame.contentsSize().height() <= \ if not self._text_fits_on_slide(html_line):
self.page_height:
previous_html = html_line + line_end previous_html = html_line + line_end
previous_raw = line + line_end previous_raw = line + line_end
continue continue
@ -445,10 +442,8 @@ class Renderer(object):
highest_index = len(html_list) - 1 highest_index = len(html_list) - 1
index = int(highest_index / 2) index = int(highest_index / 2)
while True: while True:
html = self.page_shell + previous_html + \ if self._text_fits_on_slide(
separator.join(html_list[:index + 1]).strip() + HTML_END previous_html + separator.join(html_list[:index + 1]).strip()):
self.web.setHtml(html)
if self.web_frame.contentsSize().height() > self.page_height:
# We know that it does not fit, so change/calculate the # We know that it does not fit, so change/calculate the
# new index and highest_index accordingly. # new index and highest_index accordingly.
highest_index = index highest_index = index
@ -470,10 +465,8 @@ class Renderer(object):
else: else:
continue continue
# Check if the remaining elements fit on the slide. # Check if the remaining elements fit on the slide.
html = self.page_shell + \ if not self._text_fits_on_slide(
separator.join(html_list[index + 1:]).strip() + HTML_END separator.join(html_list[index + 1:]).strip()):
self.web.setHtml(html)
if self.web_frame.contentsSize().height() <= self.page_height:
previous_html = separator.join( previous_html = separator.join(
html_list[index + 1:]).strip() + line_end html_list[index + 1:]).strip() + line_end
previous_raw = separator.join( previous_raw = separator.join(
@ -489,6 +482,18 @@ class Renderer(object):
index = int(highest_index / 2) index = int(highest_index / 2)
return previous_html, previous_raw return previous_html, previous_raw
def _text_fits_on_slide(self, text):
"""
Checks if the given ``text`` fits on a slide. If it does ``True`` is
returned, otherwise ``False``.
``text``
The text to check. It can contain HTML tags.
"""
self.web_frame.evaluateJavaScript(u'show_text("%s")' %
text.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
return self.web_frame.contentsSize().height() > self.page_height
def _words_split(self, line): def _words_split(self, line):
""" """
Split the slide up by word so can wrap better Split the slide up by word so can wrap better

View File

@ -188,7 +188,7 @@ class MainDisplay(QtGui.QGraphicsView):
while not self.webLoaded: while not self.webLoaded:
Receiver.send_message(u'openlp_process_events') Receiver.send_message(u'openlp_process_events')
self.setGeometry(self.screen[u'size']) self.setGeometry(self.screen[u'size'])
self.frame.evaluateJavaScript(u'show_text("%s")' % \ self.frame.evaluateJavaScript(u'show_text("%s")' %
slide.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"')) slide.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
return self.preview() return self.preview()