diff --git a/documentation/manual/source/dualmonitors.rst b/documentation/manual/source/dualmonitors.rst index 3e1a8d210..7e39edb45 100644 --- a/documentation/manual/source/dualmonitors.rst +++ b/documentation/manual/source/dualmonitors.rst @@ -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 ----------------- diff --git a/documentation/manual/source/pics/configureadvanced.png b/documentation/manual/source/pics/configureadvanced.png index f31812f93..44908e828 100644 Binary files a/documentation/manual/source/pics/configureadvanced.png and b/documentation/manual/source/pics/configureadvanced.png differ diff --git a/documentation/manual/source/pics/configurealerts.png b/documentation/manual/source/pics/configurealerts.png index ac46801dc..a15de9e5d 100644 Binary files a/documentation/manual/source/pics/configurealerts.png and b/documentation/manual/source/pics/configurealerts.png differ diff --git a/documentation/manual/source/pics/configurebibles.png b/documentation/manual/source/pics/configurebibles.png index cd44ee4af..ab8bc1930 100644 Binary files a/documentation/manual/source/pics/configurebibles.png and b/documentation/manual/source/pics/configurebibles.png differ diff --git a/documentation/manual/source/pics/configurecustom.png b/documentation/manual/source/pics/configurecustom.png index 3db5c4989..33514de18 100644 Binary files a/documentation/manual/source/pics/configurecustom.png and b/documentation/manual/source/pics/configurecustom.png differ diff --git a/documentation/manual/source/pics/configuregeneral.png b/documentation/manual/source/pics/configuregeneral.png index b1bae76e0..18a89474e 100644 Binary files a/documentation/manual/source/pics/configuregeneral.png and b/documentation/manual/source/pics/configuregeneral.png differ diff --git a/documentation/manual/source/pics/configuremedia.png b/documentation/manual/source/pics/configuremedia.png index cc9e11a38..9179873ea 100644 Binary files a/documentation/manual/source/pics/configuremedia.png and b/documentation/manual/source/pics/configuremedia.png differ diff --git a/documentation/manual/source/pics/configurepresentations.png b/documentation/manual/source/pics/configurepresentations.png index 4960aa8e5..4f8a98bc7 100644 Binary files a/documentation/manual/source/pics/configurepresentations.png and b/documentation/manual/source/pics/configurepresentations.png differ diff --git a/documentation/manual/source/pics/configureremotes.png b/documentation/manual/source/pics/configureremotes.png index 9eb22131c..d8801aa78 100644 Binary files a/documentation/manual/source/pics/configureremotes.png and b/documentation/manual/source/pics/configureremotes.png differ diff --git a/documentation/manual/source/pics/configuresongs.png b/documentation/manual/source/pics/configuresongs.png index 19796f3b5..9da70deb2 100644 Binary files a/documentation/manual/source/pics/configuresongs.png and b/documentation/manual/source/pics/configuresongs.png differ diff --git a/documentation/manual/source/pics/configurethemes.png b/documentation/manual/source/pics/configurethemes.png index c8241ddaf..8696cfd7e 100644 Binary files a/documentation/manual/source/pics/configurethemes.png and b/documentation/manual/source/pics/configurethemes.png differ diff --git a/documentation/manual/source/troubleshooting.rst b/documentation/manual/source/troubleshooting.rst index 1d200ed8e..6f5f21a74 100644 --- a/documentation/manual/source/troubleshooting.rst +++ b/documentation/manual/source/troubleshooting.rst @@ -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. + + + diff --git a/openlp/core/lib/theme.py b/openlp/core/lib/theme.py index 698f0d644..7f2204c67 100644 --- a/openlp/core/lib/theme.py +++ b/openlp/core/lib/theme.py @@ -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) \ No newline at end of file + self.display_slide_transition) diff --git a/openlp/core/ui/advancedtab.py b/openlp/core/ui/advancedtab.py index 94bcb0801..b6dd1cb27 100644 --- a/openlp/core/ui/advancedtab.py +++ b/openlp/core/ui/advancedtab.py @@ -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() \ No newline at end of file + self.defaultFileEdit.setFocus() + + def onDefaultRevertButtonPressed(self): + self.defaultFileEdit.setText(u':/graphics/openlp-splash-screen.png') + self.defaultFileEdit.setFocus() diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index c413ec8c9..7843284b3 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -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(): diff --git a/openlp/core/ui/printserviceform.py b/openlp/core/ui/printserviceform.py index 42b773198..bb87cf32f 100644 --- a/openlp/core/ui/printserviceform.py +++ b/openlp/core/ui/printserviceform.py @@ -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'%s' % 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' %s' % 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'%s' % 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' %s' % item.notes.replace( - u'\n', u'
'), 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'

%s

' % - translate('OpenLP.ServiceManager', 'Playing time:'), div) - self._fromstring(u'%s' % - 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'
')[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'
'), 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() \ No newline at end of file + settings.endGroup() diff --git a/openlp/core/ui/themeform.py b/openlp/core/ui/themeform.py index ebba45e7c..019ab5bfe 100644 --- a/openlp/core/ui/themeform.py +++ b/openlp/core/ui/themeform.py @@ -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 \ No newline at end of file + return field diff --git a/openlp/plugins/songs/lib/__init__.py b/openlp/plugins/songs/lib/__init__.py index 4f95791b3..249a76a38 100644 --- a/openlp/plugins/songs/lib/__init__.py +++ b/openlp/plugins/songs/lib/__init__.py @@ -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: diff --git a/openlp/plugins/songs/lib/opensongimport.py b/openlp/plugins/songs/lib/opensongimport.py index ab8f8c9fa..365f20268 100644 --- a/openlp/plugins/songs/lib/opensongimport.py +++ b/openlp/plugins/songs/lib/opensongimport.py @@ -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) diff --git a/openlp/plugins/songs/lib/songimport.py b/openlp/plugins/songs/lib/songimport.py index 3c7ab8885..78275d210 100644 --- a/openlp/plugins/songs/lib/songimport.py +++ b/openlp/plugins/songs/lib/songimport.py @@ -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(): diff --git a/resources/images/general_revert.png b/resources/images/general_revert.png new file mode 100644 index 000000000..47d7415e2 Binary files /dev/null and b/resources/images/general_revert.png differ diff --git a/resources/images/openlp-2.qrc b/resources/images/openlp-2.qrc index 0d3191eff..364a75810 100644 --- a/resources/images/openlp-2.qrc +++ b/resources/images/openlp-2.qrc @@ -52,6 +52,7 @@ general_open.png general_save.png general_email.png + general_revert.png slide_close.png