merged with lp:~trb143/openlp/beta1
@ -1,3 +1,5 @@
|
||||
.. _dualmonitors:
|
||||
|
||||
==================
|
||||
Dual Monitor Setup
|
||||
==================
|
||||
@ -32,6 +34,14 @@ projector hooked up to your computer as the second monitor. With the option of
|
||||
extending your desktop across the second monitor, or your operating system's
|
||||
equivalent.
|
||||
|
||||
**Special Note For Projectors Using USB Connections**
|
||||
|
||||
Users have reported experiencing difficulties when using a projector with a USB
|
||||
connection, as third party software is often required to properly configure
|
||||
dual monitors. If possible, it is best to use a direct output (VGA, DVI, HDMI,
|
||||
S-Video) from your machine's video card. If a USB connection is your only option
|
||||
please consult the manufacturer's manual for instructions on a proper setup.
|
||||
|
||||
Microsoft Windows
|
||||
-----------------
|
||||
|
||||
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 81 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 195 KiB |
@ -175,3 +175,23 @@ only download the section you search for. If you do not have an internet
|
||||
connection where you intend to use OpenLP you will need another scripture
|
||||
source. For more information about acquiring Bibles please see :ref:`bibleimporter`.
|
||||
|
||||
OpenLP is using a large amount of RAM when showing a presentation
|
||||
-----------------------------------------------------------------
|
||||
|
||||
OpenLP uses a large amount of RAM when showing a presentation due to the way it
|
||||
handles presentations. OpenLP itself is unable to show those presentations or
|
||||
load the presentation files, so it interacts with the presentation through
|
||||
either Microsoft PowerPoint or LibreOffice Impress. In order to show the slides
|
||||
in the slide controller, OpenLP requests that the presentation application
|
||||
export the slides to images, and then uses those images as slides. This results
|
||||
in a large amount of RAM being used, especially in presentations with more than
|
||||
about 20 slides.
|
||||
|
||||
OpenLP is not displaying correctly, or is not on the correct screen
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Please read the documentation on :ref:`dualmonitors`. It is very important to
|
||||
have dual monitors setup properly for OpenLP to function as expected.
|
||||
|
||||
|
||||
|
||||
|
@ -214,26 +214,24 @@ class Renderer(object):
|
||||
``line_break``
|
||||
Add line endings after each line of text used for bibles.
|
||||
"""
|
||||
|
||||
log.debug(u'format slide')
|
||||
# clean up line endings
|
||||
lines = self._lines_split(text)
|
||||
# Songs and Custom
|
||||
if item.is_capable(ItemCapabilities.AllowsVirtualSplit):
|
||||
# Do not forget the line breaks !
|
||||
slides = text.split(u'\n[---]\n')
|
||||
pages = []
|
||||
for slide in slides:
|
||||
lines = self._lines(slide)
|
||||
new_pages = self._paginate_slide(lines, line_break,
|
||||
self.force_page)
|
||||
pages.extend([page for page in new_pages])
|
||||
# Bibles
|
||||
elif item.is_capable(ItemCapabilities.AllowsWordSplit):
|
||||
pages = self._paginate_slide_words(text, line_break)
|
||||
# Theme preview "service items".
|
||||
else:
|
||||
pages = self._paginate_slide(lines, line_break, self.force_page)
|
||||
pages = self._paginate_slide(lines, line_break, self.force_page)
|
||||
if len(pages) > 1:
|
||||
# Songs and Custom
|
||||
if item.is_capable(ItemCapabilities.AllowsVirtualSplit):
|
||||
# Do not forget the line breaks !
|
||||
slides = text.split(u'\n[---]\n')
|
||||
pages = []
|
||||
for slide in slides:
|
||||
lines = self._lines(slide)
|
||||
new_pages = self._paginate_slide(lines, line_break,
|
||||
self.force_page)
|
||||
pages.extend([page for page in new_pages])
|
||||
# Bibles
|
||||
elif item.is_capable(ItemCapabilities.AllowsWordSplit):
|
||||
pages = self._paginate_slide_words(text, line_break)
|
||||
return pages
|
||||
|
||||
def _calculate_default(self, screen):
|
||||
@ -256,6 +254,7 @@ class Renderer(object):
|
||||
"""
|
||||
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.
|
||||
@ -365,8 +364,6 @@ class Renderer(object):
|
||||
Add line endings after each line of text used for bibles.
|
||||
|
||||
"""
|
||||
# TODO: Make sure spaces are striped so that they will not confuse
|
||||
# rendering. for instance when the style is set to Verse per Line:
|
||||
# In the beginning ...
|
||||
# <space> <!-- here we could have added the second verse -->
|
||||
# <new slide>
|
||||
@ -378,7 +375,7 @@ class Renderer(object):
|
||||
formatted = []
|
||||
previous_html = u''
|
||||
previous_raw = u''
|
||||
lines = self._lines(text, u'[---]')
|
||||
lines = self._lines(text)
|
||||
for line in lines:
|
||||
styled_line = expand_tags(line)
|
||||
html = self.page_shell + previous_html + styled_line + HTML_END
|
||||
@ -392,7 +389,8 @@ class Renderer(object):
|
||||
HTML_END
|
||||
self.web.setHtml(html)
|
||||
# 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:
|
||||
previous_raw = previous_raw.rstrip(u'<br>')
|
||||
formatted.append(previous_raw)
|
||||
previous_html = u''
|
||||
@ -409,26 +407,26 @@ class Renderer(object):
|
||||
log.debug(u'_paginate_slide_words - End')
|
||||
return formatted
|
||||
|
||||
def _lines(self, words, split=u'n[---]n'):
|
||||
def _lines(self, text):
|
||||
"""
|
||||
Split the slide up by physical line
|
||||
"""
|
||||
# this parse we do not want to use this so remove it
|
||||
#words = words.replace(split, u'')
|
||||
verses_text = words.split(u'\n')
|
||||
verses_text = text.split(u'\n')
|
||||
text = []
|
||||
for verse in verses_text:
|
||||
lines = verse.split(u'\n')
|
||||
text.extend([line for line in lines])
|
||||
|
||||
return text
|
||||
|
||||
def _words_split(self, words):
|
||||
def _words_split(self, line):
|
||||
"""
|
||||
Split the slide up by word so can wrap better
|
||||
"""
|
||||
# this parse we are to be wordy
|
||||
words = words.replace(u'\n', u' ')
|
||||
verses_text = words.split(u' ')
|
||||
line = line.replace(u'\n', u' ')
|
||||
verses_text = line.split(u' ')
|
||||
text = []
|
||||
for verse in verses_text:
|
||||
lines = verse.split(u' ')
|
||||
@ -440,10 +438,11 @@ class Renderer(object):
|
||||
Split the slide up by physical line
|
||||
"""
|
||||
# this parse we do not want to use this so remove it
|
||||
text = text.replace(u'\n[---]', u'')
|
||||
lines = text.split(u'\n')
|
||||
real_lines = []
|
||||
for line in lines:
|
||||
line = line.replace(u' [---]', u'[---]')
|
||||
line = line.replace(u'[---]', u'')
|
||||
sub_lines = line.split(u'\n')
|
||||
real_lines.extend([sub_line for sub_line in sub_lines])
|
||||
return real_lines
|
||||
|
@ -637,4 +637,4 @@ class ThemeXML(object):
|
||||
self.font_footer_shadow_size)
|
||||
self.add_display(self.display_horizontal_align,
|
||||
self.display_vertical_align,
|
||||
self.display_slide_transition)
|
||||
self.display_slide_transition)
|
||||
|
@ -191,7 +191,7 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
||||
div = self._addElement(u'div', parent=html_data.body,
|
||||
classId=u'customNotes')
|
||||
self._addElement(u'span', translate('OpenLP.ServiceManager',
|
||||
u'Custom Service Notes: '), div, classId=u'customNotesTitle')
|
||||
'Custom Service Notes: '), div, classId=u'customNotesTitle')
|
||||
self._addElement(u'span', self.footerTextEdit.toPlainText(), div,
|
||||
classId=u'customNotesText')
|
||||
self.document.setHtml(html.tostring(html_data))
|
||||
|
@ -56,6 +56,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
self.setupUi(self)
|
||||
self.registerFields()
|
||||
self.updateThemeAllowed = True
|
||||
self.temp_background_filename = u''
|
||||
QtCore.QObject.connect(self.backgroundComboBox,
|
||||
QtCore.SIGNAL(u'currentIndexChanged(int)'),
|
||||
self.onBackgroundComboBoxCurrentIndexChanged)
|
||||
@ -279,6 +280,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
Run the wizard.
|
||||
"""
|
||||
log.debug(u'Editing theme %s' % self.theme.theme_name)
|
||||
self.temp_background_filename = u''
|
||||
self.updateThemeAllowed = False
|
||||
self.setDefaults()
|
||||
self.updateThemeAllowed = True
|
||||
@ -432,6 +434,16 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
# do not allow updates when screen is building for the first time.
|
||||
if self.updateThemeAllowed:
|
||||
self.theme.background_type = BackgroundType.to_string(index)
|
||||
if self.theme.background_type != \
|
||||
BackgroundType.to_string(BackgroundType.Image) and \
|
||||
self.temp_background_filename == u'':
|
||||
self.temp_background_filename = self.theme.background_filename
|
||||
self.theme.background_filename = u''
|
||||
if self.theme.background_type == \
|
||||
BackgroundType.to_string(BackgroundType.Image) and \
|
||||
self.temp_background_filename != u'':
|
||||
self.theme.background_filename = self.temp_background_filename
|
||||
self.temp_background_filename = u''
|
||||
self.setBackgroundPageValues()
|
||||
|
||||
def onGradientComboBoxCurrentIndexChanged(self, index):
|
||||
@ -589,4 +601,4 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
|
||||
QtGui.QColor(field), self)
|
||||
if new_color.isValid():
|
||||
field = new_color.name()
|
||||
return field
|
||||
return field
|
||||
|
@ -278,24 +278,29 @@ def clean_song(manager, song):
|
||||
# List for later comparison.
|
||||
compare_order = []
|
||||
for verse in verses:
|
||||
type = VerseType.Tags[VerseType.from_loose_input(verse[0][u'type'])]
|
||||
verse_type = VerseType.Tags[VerseType.from_loose_input(
|
||||
verse[0][u'type'])]
|
||||
sxml.add_verse_to_lyrics(
|
||||
type,
|
||||
verse_type,
|
||||
verse[0][u'label'],
|
||||
verse[1],
|
||||
verse[0][u'lang'] if verse[0].has_key(u'lang') else None
|
||||
)
|
||||
compare_order.append((u'%s%s' % (type, verse[0][u'label'])).upper())
|
||||
compare_order.append((u'%s%s' % (verse_type, verse[0][u'label'])
|
||||
).upper())
|
||||
if verse[0][u'label'] == u'1':
|
||||
compare_order.append(verse_type.upper())
|
||||
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
|
||||
# Rebuild the verse order, to convert translated verse tags, which might
|
||||
# have been added prior to 1.9.5.
|
||||
order = song.verse_order.strip().split()
|
||||
new_order = []
|
||||
for verse_def in order:
|
||||
new_order.append((u'%s%s' % (
|
||||
VerseType.Tags[VerseType.from_loose_input(verse_def[0])],
|
||||
verse_def[1:])).upper()
|
||||
)
|
||||
verse_type = VerseType.Tags[VerseType.from_loose_input(verse_def[0])]
|
||||
if len(verse_def) > 1:
|
||||
new_order.append((u'%s%s' % (verse_type, verse_def[1:])).upper())
|
||||
else:
|
||||
new_order.append(verse_type.upper())
|
||||
song.verse_order = u' '.join(new_order)
|
||||
# Check if the verse order contains tags for verses which do not exist.
|
||||
for order in new_order:
|
||||
|
@ -193,7 +193,10 @@ class OpenSongImport(SongImport):
|
||||
verse_num = u'1'
|
||||
# for the case where song has several sections with same marker
|
||||
inst = 1
|
||||
lyrics = unicode(root.lyrics)
|
||||
if u'lyrics' in fields:
|
||||
lyrics = unicode(root.lyrics)
|
||||
else:
|
||||
lyrics = u''
|
||||
for this_line in lyrics.split(u'\n'):
|
||||
# remove comments
|
||||
semicolon = this_line.find(u';')
|
||||
@ -214,7 +217,7 @@ class OpenSongImport(SongImport):
|
||||
# have we got any digits?
|
||||
# If so, verse number is everything from the digits
|
||||
# to the end (even if there are some alpha chars on the end)
|
||||
match = re.match(u'(.*)(\d+.*)', content)
|
||||
match = re.match(u'(\D*)(\d+.*)', content)
|
||||
if match is not None:
|
||||
verse_tag = match.group(1)
|
||||
verse_num = match.group(2)
|
||||
@ -223,12 +226,13 @@ class OpenSongImport(SongImport):
|
||||
# the verse tag
|
||||
verse_tag = content
|
||||
verse_num = u'1'
|
||||
verse_index = VerseType.from_loose_input(verse_tag)
|
||||
verse_tag = VerseType.Tags[verse_index]
|
||||
inst = 1
|
||||
if [verse_tag, verse_num, inst] in our_verse_order \
|
||||
and verses.has_key(verse_tag) \
|
||||
and verses[verse_tag].has_key(verse_num):
|
||||
inst = len(verses[verse_tag][verse_num]) + 1
|
||||
our_verse_order.append([verse_tag, verse_num, inst])
|
||||
continue
|
||||
# number at start of line.. it's verse number
|
||||
if this_line[0].isdigit():
|
||||
@ -241,6 +245,7 @@ class OpenSongImport(SongImport):
|
||||
verses[verse_tag][verse_num] = {}
|
||||
if not verses[verse_tag][verse_num].has_key(inst):
|
||||
verses[verse_tag][verse_num][inst] = []
|
||||
our_verse_order.append([verse_tag, verse_num, inst])
|
||||
# Tidy text and remove the ____s from extended words
|
||||
this_line = self.tidy_text(this_line)
|
||||
this_line = this_line.replace(u'_', u'')
|
||||
@ -252,6 +257,8 @@ class OpenSongImport(SongImport):
|
||||
verse_def = u'%s%s' % (verse_tag, verse_num)
|
||||
lines = u'\n'.join(verses[verse_tag][verse_num][inst])
|
||||
self.add_verse(lines, verse_def)
|
||||
if not self.verses:
|
||||
self.add_verse('')
|
||||
# figure out the presentation order, if present
|
||||
if u'presentation' in fields and root.presentation:
|
||||
order = unicode(root.presentation)
|
||||
@ -259,7 +266,7 @@ class OpenSongImport(SongImport):
|
||||
# and then split into a list on the whitespace
|
||||
order = order.lower().split()
|
||||
for verse_def in order:
|
||||
match = re.match(u'(.*)(\d+.*)', verse_def)
|
||||
match = re.match(u'(\D*)(\d+.*)', verse_def)
|
||||
if match is not None:
|
||||
verse_tag = match.group(1)
|
||||
verse_num = match.group(2)
|
||||
|