r1492
@ -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.
|
||||
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -41,11 +41,11 @@ class AdvancedTab(SettingsTab):
|
||||
"""
|
||||
Initialise the settings tab
|
||||
"""
|
||||
generalTranslated = translate('AdvancedTab', 'Advanced')
|
||||
SettingsTab.__init__(self, parent ,u'Advanced', generalTranslated)
|
||||
advancedTranslated = translate('OpenLP.AdvancedTab', 'Advanced')
|
||||
self.default_image = u':/graphics/openlp-splash-screen.png'
|
||||
self.default_color = u'#ffffff'
|
||||
self.icon_path = u':/system/system_settings.png'
|
||||
SettingsTab.__init__(self, parent, u'Advanced', advancedTranslated)
|
||||
|
||||
def setupUi(self):
|
||||
"""
|
||||
@ -82,14 +82,6 @@ class AdvancedTab(SettingsTab):
|
||||
u'enableAutoCloseCheckBox')
|
||||
self.uiLayout.addRow(self.enableAutoCloseCheckBox)
|
||||
self.leftLayout.addWidget(self.uiGroupBox)
|
||||
self.hideMouseGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||
self.hideMouseGroupBox.setObjectName(u'hideMouseGroupBox')
|
||||
self.hideMouseLayout = QtGui.QVBoxLayout(self.hideMouseGroupBox)
|
||||
self.hideMouseLayout.setObjectName(u'hideMouseLayout')
|
||||
self.hideMouseCheckBox = QtGui.QCheckBox(self.hideMouseGroupBox)
|
||||
self.hideMouseCheckBox.setObjectName(u'hideMouseCheckBox')
|
||||
self.hideMouseLayout.addWidget(self.hideMouseCheckBox)
|
||||
self.leftLayout.addWidget(self.hideMouseGroupBox)
|
||||
self.leftLayout.addStretch()
|
||||
self.defaultImageGroupBox = QtGui.QGroupBox(self.rightColumn)
|
||||
self.defaultImageGroupBox.setObjectName(u'defaultImageGroupBox')
|
||||
@ -109,26 +101,42 @@ class AdvancedTab(SettingsTab):
|
||||
self.defaultBrowseButton.setObjectName(u'defaultBrowseButton')
|
||||
self.defaultBrowseButton.setIcon(
|
||||
build_icon(u':/general/general_open.png'))
|
||||
self.defaultRevertButton = QtGui.QToolButton(self.defaultImageGroupBox)
|
||||
self.defaultRevertButton.setObjectName(u'defaultRevertButton')
|
||||
self.defaultRevertButton.setIcon(
|
||||
build_icon(u':/general/general_revert.png'))
|
||||
self.defaultFileLayout = QtGui.QHBoxLayout()
|
||||
self.defaultFileLayout.setObjectName(u'defaultFileLayout')
|
||||
self.defaultFileLayout.addWidget(self.defaultFileEdit)
|
||||
self.defaultFileLayout.addWidget(self.defaultBrowseButton)
|
||||
self.defaultFileLayout.addWidget(self.defaultRevertButton)
|
||||
self.defaultImageLayout.addRow(self.defaultFileLabel,
|
||||
self.defaultFileLayout)
|
||||
self.rightLayout.addWidget(self.defaultImageGroupBox)
|
||||
self.hideMouseGroupBox = QtGui.QGroupBox(self.leftColumn)
|
||||
self.hideMouseGroupBox.setObjectName(u'hideMouseGroupBox')
|
||||
self.hideMouseLayout = QtGui.QVBoxLayout(self.hideMouseGroupBox)
|
||||
self.hideMouseLayout.setObjectName(u'hideMouseLayout')
|
||||
self.hideMouseCheckBox = QtGui.QCheckBox(self.hideMouseGroupBox)
|
||||
self.hideMouseCheckBox.setObjectName(u'hideMouseCheckBox')
|
||||
self.hideMouseLayout.addWidget(self.hideMouseCheckBox)
|
||||
self.rightLayout.addWidget(self.hideMouseGroupBox)
|
||||
self.rightLayout.addStretch()
|
||||
|
||||
QtCore.QObject.connect(self.defaultColorButton,
|
||||
QtCore.SIGNAL(u'pressed()'), self.onDefaultColorButtonPressed)
|
||||
QtCore.QObject.connect(self.defaultBrowseButton,
|
||||
QtCore.SIGNAL(u'pressed()'), self.onDefaultBrowseButtonPressed)
|
||||
QtCore.QObject.connect(self.defaultRevertButton,
|
||||
QtCore.SIGNAL(u'pressed()'), self.onDefaultRevertButtonPressed)
|
||||
|
||||
def retranslateUi(self):
|
||||
"""
|
||||
Setup the interface translation strings.
|
||||
"""
|
||||
self.tabTitleVisible = UiStrings().Advanced
|
||||
self.uiGroupBox.setTitle(translate('OpenLP.AdvancedTab', 'UI Settings'))
|
||||
self.uiGroupBox.setTitle(
|
||||
translate('OpenLP.AdvancedTab', 'UI Settings'))
|
||||
self.recentLabel.setText(
|
||||
translate('OpenLP.AdvancedTab',
|
||||
'Number of recent files to display:'))
|
||||
@ -150,8 +158,14 @@ class AdvancedTab(SettingsTab):
|
||||
'Default Image'))
|
||||
self.defaultColorLabel.setText(translate('OpenLP.AdvancedTab',
|
||||
'Background color:'))
|
||||
self.defaultColorButton.setToolTip(translate('OpenLP.AdvancedTab',
|
||||
'Click to select a color.'))
|
||||
self.defaultFileLabel.setText(translate('OpenLP.AdvancedTab',
|
||||
'Image file:'))
|
||||
self.defaultBrowseButton.setToolTip(translate('OpenLP.AdvancedTab',
|
||||
'Browse for an image file to display.'))
|
||||
self.defaultRevertButton.setToolTip(translate('OpenLP.AdvancedTab',
|
||||
'Revert to the default OpenLP logo.'))
|
||||
|
||||
def load(self):
|
||||
"""
|
||||
@ -232,4 +246,8 @@ class AdvancedTab(SettingsTab):
|
||||
file_filters)
|
||||
if filename:
|
||||
self.defaultFileEdit.setText(filename)
|
||||
self.defaultFileEdit.setFocus()
|
||||
self.defaultFileEdit.setFocus()
|
||||
|
||||
def onDefaultRevertButtonPressed(self):
|
||||
self.defaultFileEdit.setText(u':/graphics/openlp-splash-screen.png')
|
||||
self.defaultFileEdit.setFocus()
|
||||
|
@ -142,7 +142,8 @@ class MainDisplay(DisplayWidget):
|
||||
image_file = QtCore.QSettings().value(u'advanced/default image',
|
||||
QtCore.QVariant(u':/graphics/openlp-splash-screen.png'))\
|
||||
.toString()
|
||||
background_color = QtGui.QColor(QtCore.QSettings().value(
|
||||
background_color = QtGui.QColor()
|
||||
background_color.setNamedColor(QtCore.QSettings().value(
|
||||
u'advanced/default color',
|
||||
QtCore.QVariant(u'#ffffff')).toString())
|
||||
if not background_color.isValid():
|
||||
|
@ -46,41 +46,58 @@ http://doc.trolltech.com/4.7/richtext-html-subset.html#css-properties
|
||||
color:black;
|
||||
}
|
||||
|
||||
.item {
|
||||
color:black;
|
||||
}
|
||||
|
||||
.itemTitle {
|
||||
font-weight:600;
|
||||
font-size:large;
|
||||
color:black;
|
||||
}
|
||||
|
||||
.itemText {
|
||||
color:black;
|
||||
}
|
||||
.itemText {}
|
||||
|
||||
.itemFooter {
|
||||
font-size:8px;
|
||||
color:black;
|
||||
}
|
||||
|
||||
.itemNotes {}
|
||||
|
||||
.itemNotesTitle {
|
||||
font-weight:bold;
|
||||
font-size:12px;
|
||||
color:black;
|
||||
}
|
||||
|
||||
.itemNotesText {
|
||||
font-size:11px;
|
||||
color:black;
|
||||
}
|
||||
|
||||
.media {}
|
||||
|
||||
.mediaTitle {
|
||||
font-weight:bold;
|
||||
font-size:11px;
|
||||
}
|
||||
|
||||
.mediaText {}
|
||||
|
||||
.imageList {}
|
||||
|
||||
.customNotes {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.customNotesTitle {
|
||||
font-weight:bold;
|
||||
font-size:11px;
|
||||
color:black;
|
||||
}
|
||||
|
||||
.customNotesText {
|
||||
font-size:11px;
|
||||
color:black;
|
||||
}
|
||||
|
||||
.newPage {
|
||||
page-break-before:always;
|
||||
}
|
||||
"""
|
||||
|
||||
@ -153,86 +170,90 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
||||
"""
|
||||
Creates the html text and updates the html of *self.document*.
|
||||
"""
|
||||
html_data = html.fromstring(
|
||||
u'<title>%s</title>' % unicode(self.titleLineEdit.text()))
|
||||
html_data = self._addElement(u'html')
|
||||
self._addElement(u'head', parent=html_data)
|
||||
self._addElement(u'title', unicode(self.titleLineEdit.text()),
|
||||
html_data.head)
|
||||
css_path = os.path.join(
|
||||
AppLocation.get_data_path(), u'servicePrint.css')
|
||||
if not os.path.isfile(css_path):
|
||||
# Create default css file.
|
||||
css_file = open(css_path, u'w')
|
||||
css_file.write(DEFAULT_CSS)
|
||||
css_file.close()
|
||||
AppLocation.get_data_path(), u'service_print.css')
|
||||
custom_css = get_text_file_string(css_path)
|
||||
self._addChildToParent(
|
||||
u'style', custom_css, html_data.head, u'type', u'text/css')
|
||||
self._addChildToParent(u'body', parent=html_data)
|
||||
self._addChildToParent(u'span', unicode(self.titleLineEdit.text()),
|
||||
html_data.body, u'class', u'serviceTitle')
|
||||
if not custom_css:
|
||||
custom_css = DEFAULT_CSS
|
||||
self._addElement(u'style', custom_css, html_data.head,
|
||||
attribute=(u'type', u'text/css'))
|
||||
self._addElement(u'body', parent=html_data)
|
||||
self._addElement(u'h1', unicode(self.titleLineEdit.text()),
|
||||
html_data.body, classId=u'serviceTitle')
|
||||
for index, item in enumerate(self.serviceManager.serviceItems):
|
||||
item = item[u'service_item']
|
||||
div = self._addChildToParent(u'div', parent=html_data.body)
|
||||
# Add the title of the service item.
|
||||
item_title = self._addChildToParent(
|
||||
u'h2', parent=div, attribute=u'class', value=u'itemTitle')
|
||||
self._addChildToParent(
|
||||
u'img', parent=item_title, attribute=u'src', value=item.icon)
|
||||
self._fromstring(
|
||||
u'<span> %s</span>' % item.get_display_title(), item_title)
|
||||
if self.slideTextCheckBox.isChecked():
|
||||
# Add the text of the service item.
|
||||
if item.is_text():
|
||||
verse_def = None
|
||||
for slide in item.get_frames():
|
||||
if not verse_def or verse_def != slide[u'verseTag']:
|
||||
p = self._addChildToParent(u'p', parent=div,
|
||||
attribute=u'class', value=u'itemText')
|
||||
else:
|
||||
self._addChildToParent(u'br', parent=p)
|
||||
self._fromstring(u'<span>%s</span>' % slide[u'html'], p)
|
||||
verse_def = slide[u'verseTag']
|
||||
# Break the page before the div element.
|
||||
if index != 0 and self.pageBreakAfterText.isChecked():
|
||||
div.set(u'style', u'page-break-before:always')
|
||||
# Add the image names of the service item.
|
||||
elif item.is_image():
|
||||
ol = self._addChildToParent(u'ol', parent=div)
|
||||
for slide in range(len(item.get_frames())):
|
||||
self._addChildToParent(u'li', item.get_frame_title(slide), ol)
|
||||
# add footer
|
||||
if item.foot_text:
|
||||
self._fromstring(
|
||||
item.foot_text, div, u'class', u'itemFooter')
|
||||
# Add service items' notes.
|
||||
if self.notesCheckBox.isChecked():
|
||||
if item.notes:
|
||||
p = self._addChildToParent(u'p', parent=div)
|
||||
self._addChildToParent(u'span', unicode(
|
||||
translate('OpenLP.ServiceManager', 'Notes:')), p,
|
||||
u'class', u'itemNotesTitle')
|
||||
self._fromstring(u'<span> %s</span>' % item.notes.replace(
|
||||
u'\n', u'<br />'), p, u'class', u'itemNotesText')
|
||||
# Add play length of media files.
|
||||
if item.is_media() and self.metaDataCheckBox.isChecked():
|
||||
tme = item.media_length
|
||||
if item.end_time > 0:
|
||||
tme = item.end_time - item.start_time
|
||||
title = self._fromstring(u'<p><strong>%s</strong> </p>' %
|
||||
translate('OpenLP.ServiceManager', 'Playing time:'), div)
|
||||
self._fromstring(u'<span>%s</span>' %
|
||||
unicode(datetime.timedelta(seconds=tme)), title)
|
||||
self._addPreviewItem(html_data.body, item[u'service_item'], index)
|
||||
# Add the custom service notes:
|
||||
if self.footerTextEdit.toPlainText():
|
||||
div = self._addChildToParent(u'div', parent=html_data.body)
|
||||
self._addChildToParent(u'span', translate('OpenLP.ServiceManager',
|
||||
u'Custom Service Notes:'), div, u'class', u'customNotesTitle')
|
||||
self._addChildToParent(
|
||||
u'span', u' %s' % self.footerTextEdit.toPlainText(), div,
|
||||
u'class', u'customNotesText')
|
||||
div = self._addElement(u'div', parent=html_data.body,
|
||||
classId=u'customNotes')
|
||||
self._addElement(u'span', translate('OpenLP.ServiceManager',
|
||||
'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))
|
||||
self.previewWidget.updatePreview()
|
||||
|
||||
def _addChildToParent(self, tag, text=None, parent=None, attribute=None,
|
||||
value=None):
|
||||
def _addPreviewItem(self, body, item, index):
|
||||
div = self._addElement(u'div', classId=u'item', parent=body)
|
||||
# Add the title of the service item.
|
||||
item_title = self._addElement(u'h2', parent=div, classId=u'itemTitle')
|
||||
self._addElement(u'img', parent=item_title,
|
||||
attribute=(u'src', item.icon))
|
||||
self._addElement(u'span', u' ' + item.get_display_title(),
|
||||
item_title)
|
||||
if self.slideTextCheckBox.isChecked():
|
||||
# Add the text of the service item.
|
||||
if item.is_text():
|
||||
verse_def = None
|
||||
for slide in item.get_frames():
|
||||
if not verse_def or verse_def != slide[u'verseTag']:
|
||||
p = self._addElement(u'div', parent=div,
|
||||
classId=u'itemText')
|
||||
else:
|
||||
self._addElement(u'br', parent=p)
|
||||
self._addElement(u'p', slide[u'html'], p)
|
||||
verse_def = slide[u'verseTag']
|
||||
# Break the page before the div element.
|
||||
if index != 0 and self.pageBreakAfterText.isChecked():
|
||||
div.set(u'class', u'item newPage')
|
||||
# Add the image names of the service item.
|
||||
elif item.is_image():
|
||||
ol = self._addElement(u'ol', parent=div, classId=u'imageList')
|
||||
for slide in range(len(item.get_frames())):
|
||||
self._addElement(u'li', item.get_frame_title(slide), ol)
|
||||
# add footer
|
||||
foot_text = item.foot_text
|
||||
foot_text = foot_text.partition(u'<br>')[2]
|
||||
if foot_text:
|
||||
foot = self._addElement(u'div', foot_text, parent=div,
|
||||
classId=u'itemFooter')
|
||||
# Add service items' notes.
|
||||
if self.notesCheckBox.isChecked():
|
||||
if item.notes:
|
||||
p = self._addElement(u'div', classId=u'itemNotes', parent=div)
|
||||
self._addElement(u'span',
|
||||
translate('OpenLP.ServiceManager', 'Notes: '), p,
|
||||
classId=u'itemNotesTitle')
|
||||
notes = self._addElement(u'span',
|
||||
item.notes.replace(u'\n', u'<br />'), p,
|
||||
classId=u'itemNotesText')
|
||||
# Add play length of media files.
|
||||
if item.is_media() and self.metaDataCheckBox.isChecked():
|
||||
tme = item.media_length
|
||||
if item.end_time > 0:
|
||||
tme = item.end_time - item.start_time
|
||||
title = self._addElement(u'div', classId=u'media', parent=div)
|
||||
self._addElement(u'span', translate('OpenLP.ServiceManager',
|
||||
'Playing time: '), title, classId=u'mediaTitle')
|
||||
self._addElement(u'span', unicode(datetime.timedelta(seconds=tme)),
|
||||
title, classId=u'mediaText')
|
||||
|
||||
def _addElement(self, tag, text=None, parent=None, classId=None,
|
||||
attribute=None):
|
||||
"""
|
||||
Creates a html element. If ``text`` is given, the element's text will
|
||||
set and if a ``parent`` is given, the element is appended.
|
||||
@ -246,30 +267,22 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
||||
``parent``
|
||||
The parent element. Defaults to ``None``.
|
||||
|
||||
``attribute``
|
||||
An optional attribute, for instance ``u'class``.
|
||||
``classId``
|
||||
Value for the class attribute
|
||||
|
||||
``value``
|
||||
The value for the given ``attribute``. It does not have a meaning,
|
||||
if the attribute is left to its default.
|
||||
``attribute``
|
||||
Tuple name/value pair to add as an optional attribute
|
||||
"""
|
||||
element = html.Element(tag)
|
||||
if text is not None:
|
||||
element.text = unicode(text)
|
||||
element = html.fragment_fromstring(unicode(text), create_parent=tag)
|
||||
else:
|
||||
element = html.Element(tag)
|
||||
if parent is not None:
|
||||
parent.append(element)
|
||||
if classId is not None:
|
||||
element.set(u'class', classId)
|
||||
if attribute is not None:
|
||||
element.set(attribute, value if value is not None else u'')
|
||||
return element
|
||||
|
||||
def _fromstring(self, string, parent, attribute=None, value=None):
|
||||
"""
|
||||
This is used to create a child html element from a string.
|
||||
"""
|
||||
element = html.fromstring(string)
|
||||
if attribute is not None:
|
||||
element.set(attribute, value if value is not None else u'')
|
||||
parent.append(element)
|
||||
element.set(attribute[0], attribute[1])
|
||||
return element
|
||||
|
||||
def paintRequested(self, printer):
|
||||
@ -380,4 +393,4 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
||||
QtCore.QVariant(self.metaDataCheckBox.isChecked()))
|
||||
settings.setValue(u'print notes',
|
||||
QtCore.QVariant(self.notesCheckBox.isChecked()))
|
||||
settings.endGroup()
|
||||
settings.endGroup()
|
||||
|
@ -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)
|
||||
|
@ -110,6 +110,7 @@ class SongImport(QtCore.QObject):
|
||||
The reason, why the import failed. The string should be as
|
||||
informative as possible.
|
||||
"""
|
||||
self.set_defaults()
|
||||
if self.import_wizard is None:
|
||||
return
|
||||
if self.import_wizard.errorReportTextEdit.isHidden():
|
||||
|
BIN
resources/images/general_revert.png
Normal file
After Width: | Height: | Size: 737 B |
@ -52,6 +52,7 @@
|
||||
<file>general_open.png</file>
|
||||
<file>general_save.png</file>
|
||||
<file>general_email.png</file>
|
||||
<file>general_revert.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="slides">
|
||||
<file>slide_close.png</file>
|
||||
|