Beispiel #1
0
 def _process_formatting_tags(self, song_xml, temporary):
     """
     Process the formatting tags from the song and either add missing tags
     temporary or permanently to the formatting tag list.
     """
     if not hasattr(song_xml, u'format'):
         return
     found_tags = []
     for tag in song_xml.format.tags.getchildren():
         name = tag.get(u'name')
         if name is None:
             continue
         start_tag = u'{%s}' % name[:5]
         # Some tags have only start tag e.g. {br}
         end_tag = u'{/' + name[:5] + u'}' if hasattr(tag, 'close') else u''
         openlp_tag = {
             u'desc': name,
             u'start tag': start_tag,
             u'end tag': end_tag,
             u'start html': tag.open.text,
             # Some tags have only start html e.g. {br}
             u'end html': tag.close.text if hasattr(tag, 'close') else u'',
             u'protected': False,
         }
         # Add 'temporary' key in case the formatting tag should not be
         # saved otherwise it is supposed that formatting tag is permanent.
         if temporary:
             openlp_tag[u'temporary'] = temporary
         found_tags.append(openlp_tag)
     existing_tag_ids = [tag[u'start tag'] for tag in FormattingTags.get_html_tags()]
     new_tags = [tag for tag in found_tags if tag[u'start tag'] not in existing_tag_ids]
     FormattingTags.add_html_tags(new_tags)
     FormattingTags.save_html_tags()
 def _setup(self):
     """
     Set up the class. This method is mocked out by the tests.
     """
     self.services = FormattingTagController()
     self.tag_table_widget.itemSelectionChanged.connect(self.on_row_selected)
     self.new_button.clicked.connect(self.on_new_clicked)
     self.delete_button.clicked.connect(self.on_delete_clicked)
     self.tag_table_widget.currentCellChanged.connect(self.on_current_cell_changed)
     self.button_box.rejected.connect(self.close)
     # Forces reloading of tags from openlp configuration.
     FormattingTags.load_tags()
     self.is_deleting = False
     self.reloading = False
Beispiel #3
0
 def _setup(self):
     """
     Set up the class. This method is mocked out by the tests.
     """
     self.services = FormattingTagController()
     self.tag_table_widget.itemSelectionChanged.connect(self.on_row_selected)
     self.new_button.clicked.connect(self.on_new_clicked)
     self.delete_button.clicked.connect(self.on_delete_clicked)
     self.tag_table_widget.currentCellChanged.connect(self.on_current_cell_changed)
     self.button_box.rejected.connect(self.close)
     # Forces reloading of tags from openlp configuration.
     FormattingTags.load_tags()
     self.is_deleting = False
     self.reloading = False
 def _reloadTable(self):
     """
     Reset List for loading.
     """
     self.reloading = True
     self.tag_table_widget_read.clearContents()
     self.tag_table_widget_read.setRowCount(0)
     self.tag_table_widget.clearContents()
     self.tag_table_widget.setRowCount(0)
     self.new_button.setEnabled(True)
     self.delete_button.setEnabled(False)
     for line_number, html in enumerate(FormattingTags.get_html_tags()):
         if html["protected"]:
             line = self.tag_table_widget_read.rowCount()
             self.tag_table_widget_read.setRowCount(line + 1)
             self.tag_table_widget_read.setItem(line, 0, QtGui.QTableWidgetItem(html["desc"]))
             self.tag_table_widget_read.setItem(line, 1, QtGui.QTableWidgetItem(self._strip(html["start tag"])))
             self.tag_table_widget_read.setItem(line, 2, QtGui.QTableWidgetItem(html["start html"]))
             self.tag_table_widget_read.setItem(line, 3, QtGui.QTableWidgetItem(html["end html"]))
             self.tag_table_widget_read.resizeRowsToContents()
         else:
             line = self.tag_table_widget.rowCount()
             self.tag_table_widget.setRowCount(line + 1)
             self.tag_table_widget.setItem(line, 0, QtGui.QTableWidgetItem(html["desc"]))
             self.tag_table_widget.setItem(line, 1, QtGui.QTableWidgetItem(self._strip(html["start tag"])))
             self.tag_table_widget.setItem(line, 2, QtGui.QTableWidgetItem(html["start html"]))
             self.tag_table_widget.setItem(line, 3, QtGui.QTableWidgetItem(html["end html"]))
             self.tag_table_widget.resizeRowsToContents()
             # Permanent (persistent) tags do not have this key
             html["temporary"] = False
     self.reloading = False
Beispiel #5
0
 def _reloadTable(self):
     """
     Reset List for loading.
     """
     self.reloading = True
     self.tag_table_widget_read.clearContents()
     self.tag_table_widget_read.setRowCount(0)
     self.tag_table_widget.clearContents()
     self.tag_table_widget.setRowCount(0)
     self.new_button.setEnabled(True)
     self.delete_button.setEnabled(False)
     for line_number, html in enumerate(FormattingTags.get_html_tags()):
         if html['protected']:
             line = self.tag_table_widget_read.rowCount()
             self.tag_table_widget_read.setRowCount(line + 1)
             self.tag_table_widget_read.setItem(line, 0, QtGui.QTableWidgetItem(html['desc']))
             self.tag_table_widget_read.setItem(line, 1, QtGui.QTableWidgetItem(self._strip(html['start tag'])))
             self.tag_table_widget_read.setItem(line, 2, QtGui.QTableWidgetItem(html['start html']))
             self.tag_table_widget_read.setItem(line, 3, QtGui.QTableWidgetItem(html['end html']))
             self.tag_table_widget_read.resizeRowsToContents()
         else:
             line = self.tag_table_widget.rowCount()
             self.tag_table_widget.setRowCount(line + 1)
             self.tag_table_widget.setItem(line, 0, QtGui.QTableWidgetItem(html['desc']))
             self.tag_table_widget.setItem(line, 1, QtGui.QTableWidgetItem(self._strip(html['start tag'])))
             self.tag_table_widget.setItem(line, 2, QtGui.QTableWidgetItem(html['start html']))
             self.tag_table_widget.setItem(line, 3, QtGui.QTableWidgetItem(html['end html']))
             self.tag_table_widget.resizeRowsToContents()
             # Permanent (persistent) tags do not have this key
             html['temporary'] = False
     self.reloading = False
Beispiel #6
0
def get_start_tags(raw_text):
    """
    Tests the given text for not closed formatting tags and returns a tuple consisting of three unicode strings::

        ('{st}{r}Text text text{/r}{/st}', '{st}{r}', '<strong><span style="-webkit-text-fill-color:red">')

    The first unicode string is the text, with correct closing tags. The second unicode string are OpenLP's opening
    formatting tags and the third unicode string the html opening formatting tags.

    :param raw_text: The text to test. The text must **not** contain html tags, only OpenLP formatting tags
    are allowed::
            {st}{r}Text text text
    """
    raw_tags = []
    html_tags = []
    for tag in FormattingTags.get_html_tags():
        if tag['start tag'] == '{br}':
            continue
        if raw_text.count(tag['start tag']) != raw_text.count(tag['end tag']):
            raw_tags.append((raw_text.find(tag['start tag']), tag['start tag'], tag['end tag']))
            html_tags.append((raw_text.find(tag['start tag']), tag['start html']))
    # Sort the lists, so that the tags which were opened first on the first slide (the text we are checking) will be
    # opened first on the next slide as well.
    raw_tags.sort(key=lambda tag: tag[0])
    html_tags.sort(key=lambda tag: tag[0])
    # Create a list with closing tags for the raw_text.
    end_tags = []
    start_tags = []
    for tag in raw_tags:
        start_tags.append(tag[1])
        end_tags.append(tag[2])
    end_tags.reverse()
    # Remove the indexes.
    html_tags = [tag[1] for tag in html_tags]
    return raw_text + ''.join(end_tags), ''.join(start_tags), ''.join(html_tags)
Beispiel #7
0
    def test_find_formatting_tags(self):
        """
        Test that find_formatting_tags works as expected
        """
        # GIVEN: Lyrics with formatting tags and a empty list of formatting tags
        lyrics = '{st}Amazing {r}grace{/r} how sweet the sound'
        tags = []
        FormattingTags.load_tags()

        # WHEN: Detecting active formatting tags
        active_tags = find_formatting_tags(lyrics, tags)

        # THEN: The list of active tags should contain only 'st'
        assert [
            'st'
        ] == active_tags, 'The list of active tags should contain only "st"'
Beispiel #8
0
    def _get_missing_tags(self, text):
        """
        Tests the given text for not closed formatting tags and returns a tuple
        consisting of two unicode strings::

            (u'{st}{r}', u'{/r}{/st}')

        The first unicode string are the start tags (for the next slide). The
        second unicode string are the end tags.

        ``text``
            The text to test. The text must **not** contain html tags, only
            OpenLP formatting tags are allowed::

                {st}{r}Text text text
        """
        tags = []
        for tag in FormattingTags.get_html_tags():
            if tag[u'start tag'] == u'{br}':
                continue
            if text.count(tag[u'start tag']) != text.count(tag[u'end tag']):
                tags.append((text.find(tag[u'start tag']), tag[u'start tag'], tag[u'end tag']))
        # Sort the lists, so that the tags which were opened first on the first
        # slide (the text we are checking) will be opened first on the next
        # slide as well.
        tags.sort(key=lambda tag: tag[0])
        end_tags = []
        start_tags = []
        for tag in tags:
            start_tags.append(tag[1])
            end_tags.append(tag[2])
        end_tags.reverse()
        return u''.join(start_tags), u''.join(end_tags)
Beispiel #9
0
    def _get_missing_tags(self, text):
        """
        Tests the given text for not closed formatting tags and returns a tuple consisting of two unicode strings::

            ('{st}{r}', '{/r}{/st}')

        The first unicode string are the start tags (for the next slide). The second unicode string are the end tags.

        :param text: The text to test. The text must **not** contain html tags, only OpenLP formatting tags
        are allowed::

                {st}{r}Text text text
        """
        tags = []
        for tag in FormattingTags.get_html_tags():
            if tag['start tag'] == '{br}':
                continue
            if text.count(tag['start tag']) != text.count(tag['end tag']):
                tags.append((text.find(tag['start tag']), tag['start tag'],
                             tag['end tag']))
        # Sort the lists, so that the tags which were opened first on the first slide (the text we are checking) will
        # be opened first on the next slide as well.
        tags.sort(key=lambda tag: tag[0])
        end_tags = []
        start_tags = []
        for tag in tags:
            start_tags.append(tag[1])
            end_tags.append(tag[2])
        end_tags.reverse()
        return ''.join(start_tags), ''.join(end_tags)
Beispiel #10
0
    def test_expand_chords_for_printing(self):
        """
        Test that the expanding of chords for printing works as expected.
        """
        # GIVEN: A lyrics-line with chords
        text_with_chords = '{st}[D]Amazing {r}gr[D7]ace{/r}  how [G]sweet the [D]sound  [F]{/st}'
        FormattingTags.load_tags()

        # WHEN: Expanding the chords
        text_with_expanded_chords = expand_chords_for_printing(
            text_with_chords, '{br}')

        # THEN: We should get html that looks like below
        expected_html = '<table class="line" width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td><table ' \
                        'class="segment" cellpadding="0" cellspacing="0" border="0" align="left"><tr class="chordrow">'\
                        '<td class="chord">&nbsp;</td><td class="chord">D</td></tr><tr><td class="lyrics">{st}{/st}' \
                        '</td><td class="lyrics">{st}Amazing&nbsp;{/st}</td></tr></table><table class="segment" ' \
                        'cellpadding="0" cellspacing="0" border="0" align="left"><tr class="chordrow">' \
                        '<td class="chord">&nbsp;</td><td class="chord">D7</td></tr><tr><td class="lyrics">{st}{r}gr' \
                        '{/r}{/st}</td><td class="lyrics">{r}{st}ace{/r}&nbsp;{/st}</td></tr></table><table ' \
                        'class="segment" cellpadding="0" cellspacing="0" border="0" align="left"><tr class="chordrow">'\
                        '<td class="chord">&nbsp;</td></tr><tr><td class="lyrics">{st}&nbsp;{/st}</td></tr></table>' \
                        '<table class="segment" cellpadding="0" cellspacing="0" border="0" align="left"><tr ' \
                        'class="chordrow"><td class="chord">&nbsp;</td></tr><tr><td class="lyrics">{st}how&nbsp;{/st}' \
                        '</td></tr></table><table class="segment" cellpadding="0" cellspacing="0" border="0" ' \
                        'align="left"><tr class="chordrow"><td class="chord">G</td></tr><tr><td class="lyrics">{st}' \
                        'sweet&nbsp;{/st}</td></tr></table><table class="segment" cellpadding="0" cellspacing="0" ' \
                        'border="0" align="left"><tr class="chordrow"><td class="chord">&nbsp;</td></tr><tr><td ' \
                        'class="lyrics">{st}the&nbsp;{/st}</td></tr></table><table class="segment" cellpadding="0" ' \
                        'cellspacing="0" border="0" align="left"><tr class="chordrow"><td class="chord">D</td></tr>' \
                        '<tr><td class="lyrics">{st}sound&nbsp;{/st}</td></tr></table><table class="segment" ' \
                        'cellpadding="0" cellspacing="0" border="0" align="left"><tr class="chordrow"><td ' \
                        'class="chord">&nbsp;</td></tr><tr><td class="lyrics">{st}&nbsp;{/st}</td></tr></table>' \
                        '<table class="segment" cellpadding="0" cellspacing="0" border="0" align="left"><tr ' \
                        'class="chordrow"><td class="chord">F</td></tr><tr><td class="lyrics">{st}{/st}&nbsp;</td>' \
                        '</tr></table></td></tr></table>'
        assert expected_html == text_with_expanded_chords, 'The expanded chords should look as expected!'
Beispiel #11
0
    def test_service_item_load_song_and_audio_from_service(self):
        """
        Test the Service Item - adding a song slide from a saved service
        """
        # GIVEN: A new service item and a mocked add icon function
        service_item = ServiceItem(None)
        service_item.add_icon = MagicMock()
        FormattingTags.load_tags()

        # WHEN: We add a custom from a saved service
        line = convert_file_service_item(TEST_PATH,
                                         'serviceitem-song-linked-audio.osj')
        service_item.set_from_service(line, '/test/')

        # THEN: We should get back a valid service item
        assert service_item.is_valid is True, 'The new service item should be valid'
        assert 0 == len(service_item._display_frames
                        ), 'The service item should have no display frames'
        assert 7 == len(service_item.capabilities
                        ), 'There should be 7 default custom item capabilities'

        # WHEN: We render the frames of the service item
        service_item.render(True)

        # THEN: The frames should also be valid
        assert 'Amazing Grace' == service_item.get_display_title(
        ), 'The title should be "Amazing Grace"'
        assert CLEANED_VERSE[:-1] == service_item.get_frames()[0]['text'], \
            'The returned text matches the input, except the last line feed'
        assert RENDERED_VERSE.split('\n', 1)[0] == service_item.get_rendered_frame(1), \
            'The first line has been returned'
        assert 'Amazing Grace! how sweet the s' == service_item.get_frame_title(0), \
            '"Amazing Grace! how sweet the s" has been returned as the title'
        assert '’Twas grace that taught my hea' == service_item.get_frame_title(1), \
            '"’Twas grace that taught my hea" has been returned as the title'
        assert Path('/test/amazing_grace.mp3') == service_item.background_audio[0], \
            '"/test/amazing_grace.mp3" should be in the background_audio list'
Beispiel #12
0
    def test_service_item_load_custom_from_service(self):
        """
        Test the Service Item - adding a custom slide from a saved service
        """
        # GIVEN: A new service item and a mocked add icon function
        service_item = ServiceItem(None)
        service_item.add_icon = MagicMock()
        FormattingTags.load_tags()

        # WHEN: We add a custom from a saved service
        line = convert_file_service_item(TEST_PATH, 'serviceitem_custom_1.osj')
        service_item.set_from_service(line)

        # THEN: We should get back a valid service item
        assert service_item.is_valid is True, 'The new service item should be valid'
        assert_length(0, service_item._display_frames,
                      'The service item should have no display frames')
        assert_length(5, service_item.capabilities,
                      'There should be 5 default custom item capabilities')

        # WHEN: We render the frames of the service item
        service_item.render(True)

        # THEN: The frames should also be valid
        assert 'Test Custom' == service_item.get_display_title(
        ), 'The title should be "Test Custom"'
        assert CLEANED_VERSE[:-1] == service_item.get_frames()[0]['text'], \
            'The returned text matches the input, except the last line feed'
        assert RENDERED_VERSE.split('\n', 1)[0] == service_item.get_rendered_frame(1), \
            'The first line has been returned'
        assert 'Slide 1' == service_item.get_frame_title(
            0), '"Slide 1" has been returned as the title'
        assert 'Slide 2' == service_item.get_frame_title(
            1), '"Slide 2" has been returned as the title'
        assert '' == service_item.get_frame_title(
            2), 'Blank has been returned as the title of slide 3'
Beispiel #13
0
 def contextMenuEvent(self, event):
     """
     Provide the context menu for the text edit region.
     """
     popup_menu = self.createStandardContextMenu()
     # Select the word under the cursor.
     cursor = self.textCursor()
     # only select text if not already selected
     if not cursor.hasSelection():
         cursor.select(QtGui.QTextCursor.WordUnderCursor)
     self.setTextCursor(cursor)
     # Add menu with available languages.
     if ENCHANT_AVAILABLE:
         lang_menu = QtWidgets.QMenu(
             translate('OpenLP.SpellTextEdit', 'Language:'))
         for lang in enchant.list_languages():
             action = create_action(lang_menu,
                                    lang,
                                    text=lang,
                                    checked=lang == self.dictionary.tag)
             lang_menu.addAction(action)
         popup_menu.insertSeparator(popup_menu.actions()[0])
         popup_menu.insertMenu(popup_menu.actions()[0], lang_menu)
         lang_menu.triggered.connect(self.set_language)
     # Check if the selected word is misspelled and offer spelling suggestions if it is.
     if ENCHANT_AVAILABLE and self.textCursor().hasSelection():
         text = self.textCursor().selectedText()
         if not self.dictionary.check(text):
             spell_menu = QtWidgets.QMenu(
                 translate('OpenLP.SpellTextEdit', 'Spelling Suggestions'))
             for word in self.dictionary.suggest(text):
                 action = SpellAction(word, spell_menu)
                 action.correct.connect(self.correct_word)
                 spell_menu.addAction(action)
             # Only add the spelling suggests to the menu if there are suggestions.
             if spell_menu.actions():
                 popup_menu.insertMenu(popup_menu.actions()[0], spell_menu)
     tag_menu = QtWidgets.QMenu(
         translate('OpenLP.SpellTextEdit', 'Formatting Tags'))
     if self.formatting_tags_allowed:
         for html in FormattingTags.get_html_tags():
             action = SpellAction(html['desc'], tag_menu)
             action.correct.connect(self.html_tag)
             tag_menu.addAction(action)
         popup_menu.insertSeparator(popup_menu.actions()[0])
         popup_menu.insertMenu(popup_menu.actions()[0], tag_menu)
     popup_menu.exec(event.globalPos())
Beispiel #14
0
 def contextMenuEvent(self, event):
     """
     Provide the context menu for the text edit region.
     """
     popupMenu = self.createStandardContextMenu()
     # Select the word under the cursor.
     cursor = self.textCursor()
     # only select text if not already selected
     if not cursor.hasSelection():
         cursor.select(QtGui.QTextCursor.WordUnderCursor)
     self.setTextCursor(cursor)
     # Add menu with available languages.
     if ENCHANT_AVAILABLE:
         lang_menu = QtGui.QMenu(
             translate('OpenLP.SpellTextEdit', 'Language:'))
         for lang in enchant.list_languages():
             action = create_action(lang_menu, lang, text=lang, checked=lang == self.dictionary.tag)
             lang_menu.addAction(action)
         popupMenu.insertSeparator(popupMenu.actions()[0])
         popupMenu.insertMenu(popupMenu.actions()[0], lang_menu)
         QtCore.QObject.connect(lang_menu, QtCore.SIGNAL(u'triggered(QAction*)'), self.setLanguage)
     # Check if the selected word is misspelled and offer spelling
     # suggestions if it is.
     if ENCHANT_AVAILABLE and self.textCursor().hasSelection():
         text = self.textCursor().selectedText()
         if not self.dictionary.check(text):
             spell_menu = QtGui.QMenu(translate('OpenLP.SpellTextEdit', 'Spelling Suggestions'))
             for word in self.dictionary.suggest(text):
                 action = SpellAction(word, spell_menu)
                 action.correct.connect(self.correctWord)
                 spell_menu.addAction(action)
             # Only add the spelling suggests to the menu if there are
             # suggestions.
             if spell_menu.actions():
                 popupMenu.insertMenu(popupMenu.actions()[0], spell_menu)
     tagMenu = QtGui.QMenu(translate('OpenLP.SpellTextEdit', 'Formatting Tags'))
     if self.formattingTagsAllowed:
         for html in FormattingTags.get_html_tags():
             action = SpellAction(html[u'desc'], tagMenu)
             action.correct.connect(self.htmlTag)
             tagMenu.addAction(action)
         popupMenu.insertSeparator(popupMenu.actions()[0])
         popupMenu.insertMenu(popupMenu.actions()[0], tagMenu)
     popupMenu.exec_(event.globalPos())
Beispiel #15
0
 def html_tag(self, tag):
     """
     Replaces the selected text with word.
     """
     for html in FormattingTags.get_html_tags():
         if tag == html['desc']:
             cursor = self.textCursor()
             if self.textCursor().hasSelection():
                 text = cursor.selectedText()
                 cursor.beginEditBlock()
                 cursor.removeSelectedText()
                 cursor.insertText(html['start tag'])
                 cursor.insertText(text)
                 cursor.insertText(html['end tag'])
                 cursor.endEditBlock()
             else:
                 cursor = self.textCursor()
                 cursor.insertText(html['start tag'])
                 cursor.insertText(html['end tag'])
Beispiel #16
0
 def _add_tag_to_formatting(self, tag_name, tags_element):
     """
     Add new formatting tag to the element ``<format>`` if the tag is not present yet.
     """
     available_tags = FormattingTags.get_html_tags()
     start_tag = '{%s}' % tag_name
     for tag in available_tags:
         if tag['start tag'] == start_tag:
             # Create new formatting tag in openlyrics xml.
             element = self._add_text_to_element('tag', tags_element)
             element.set('name', tag_name)
             element_open = self._add_text_to_element('open', element)
             element_open.text = etree.CDATA(tag['start html'])
             # Check if formatting tag contains end tag. Some formatting
             # tags e.g. {br} has only start tag. If no end tag is present
             # <close> element has not to be in OpenLyrics xml.
             if tag['end tag']:
                 element_close = self._add_text_to_element('close', element)
                 element_close.text = etree.CDATA(tag['end html'])
Beispiel #17
0
 def html_tag(self, tag):
     """
     Replaces the selected text with word.
     """
     for html in FormattingTags.get_html_tags():
         if tag == html['desc']:
             cursor = self.textCursor()
             if self.textCursor().hasSelection():
                 text = cursor.selectedText()
                 cursor.beginEditBlock()
                 cursor.removeSelectedText()
                 cursor.insertText(html['start tag'])
                 cursor.insertText(text)
                 cursor.insertText(html['end tag'])
                 cursor.endEditBlock()
             else:
                 cursor = self.textCursor()
                 cursor.insertText(html['start tag'])
                 cursor.insertText(html['end tag'])
Beispiel #18
0
    def _process_formatting_tags(self, song_xml, temporary):
        """
        Process the formatting tags from the song and either add missing tags temporary or permanently to the
        formatting tag list.

        :param song_xml: The song XML
        :param temporary: Is the song temporary?
        """
        if not hasattr(song_xml, 'format'):
            return
        found_tags = []
        for tag in song_xml.format.tags.getchildren():
            name = tag.get('name')
            if name is None:
                continue
            start_tag = '{{{name}}}'.format(name=name[:5])
            # Some tags have only start tag e.g. {br}
            end_tag = '{{/{name}}}'.format(
                name=name[:5]) if hasattr(tag, 'close') else ''
            openlp_tag = {
                'desc': name,
                'start tag': start_tag,
                'end tag': end_tag,
                'start html': tag.open.text,
                # Some tags have only start html e.g. {br}
                'end html': tag.close.text if hasattr(tag, 'close') else '',
                'protected': False,
                # Add 'temporary' key in case the formatting tag should not be saved otherwise it is supposed that
                # formatting tag is permanent.
                'temporary': temporary
            }
            found_tags.append(openlp_tag)
        existing_tag_ids = [
            tag['start tag'] for tag in FormattingTags.get_html_tags()
        ]
        new_tags = [
            tag for tag in found_tags
            if tag['start tag'] not in existing_tag_ids
        ]
        # Do not save an empty list.
        if new_tags:
            FormattingTags.add_html_tags(new_tags)
            if not temporary:
                custom_tags = [
                    tag for tag in FormattingTags.get_html_tags()
                    if not tag['protected'] and not tag['temporary']
                ]
                FormattingTags.save_html_tags(custom_tags)
Beispiel #19
0
    def _add_tag_to_formatting(self, tag_name, tags_element):
        """
        Add new formatting tag to the element ``<format>`` if the tag is not present yet.

        :param tag_name: The tag_name
        :param tags_element: Some tag elements
        """
        available_tags = FormattingTags.get_html_tags()
        start_tag = '{%s}' % tag_name
        for tag in available_tags:
            if tag['start tag'] == start_tag:
                # Create new formatting tag in openlyrics xml.
                element = self._add_text_to_element('tag', tags_element)
                element.set('name', tag_name)
                element_open = self._add_text_to_element('open', element)
                element_open.text = etree.CDATA(tag['start html'])
                # Check if formatting tag contains end tag. Some formatting
                # tags e.g. {br} has only start tag. If no end tag is present
                # <close> element has not to be in OpenLyrics xml.
                if tag['end tag']:
                    element_close = self._add_text_to_element('close', element)
                    element_close.text = etree.CDATA(tag['end html'])
Beispiel #20
0
    def _add_tag_to_formatting(self, tag_name, tags_element):
        """
        Add new formatting tag to the element ``<format>`` if the tag is not present yet.

        :param tag_name: The tag_name
        :param tags_element: Some tag elements
        """
        available_tags = FormattingTags.get_html_tags()
        start_tag = "{%s}" % tag_name
        for tag in available_tags:
            if tag["start tag"] == start_tag:
                # Create new formatting tag in openlyrics xml.
                element = self._add_text_to_element("tag", tags_element)
                element.set("name", tag_name)
                element_open = self._add_text_to_element("open", element)
                element_open.text = etree.CDATA(tag["start html"])
                # Check if formatting tag contains end tag. Some formatting
                # tags e.g. {br} has only start tag. If no end tag is present
                # <close> element has not to be in OpenLyrics xml.
                if tag["end tag"]:
                    element_close = self._add_text_to_element("close", element)
                    element_close.text = etree.CDATA(tag["end html"])
Beispiel #21
0
def get_start_tags(raw_text):
    """
    Tests the given text for not closed formatting tags and returns a tuple consisting of three unicode strings::

        ('{st}{r}Text text text{/r}{/st}', '{st}{r}', '<strong><span style="-webkit-text-fill-color:red">')

    The first unicode string is the text, with correct closing tags. The second unicode string are OpenLP's opening
    formatting tags and the third unicode string the html opening formatting tags.

    :param raw_text: The text to test. The text must **not** contain html tags, only OpenLP formatting tags
    are allowed::
            {st}{r}Text text text
    """
    raw_tags = []
    html_tags = []
    for tag in FormattingTags.get_html_tags():
        if tag['start tag'] == '{br}':
            continue
        if raw_text.count(tag['start tag']) != raw_text.count(tag['end tag']):
            raw_tags.append((raw_text.find(tag['start tag']), tag['start tag'],
                             tag['end tag']))
            html_tags.append(
                (raw_text.find(tag['start tag']), tag['start html']))
    # Sort the lists, so that the tags which were opened first on the first slide (the text we are checking) will be
    # opened first on the next slide as well.
    raw_tags.sort(key=lambda tag: tag[0])
    html_tags.sort(key=lambda tag: tag[0])
    # Create a list with closing tags for the raw_text.
    end_tags = []
    start_tags = []
    for tag in raw_tags:
        start_tags.append(tag[1])
        end_tags.append(tag[2])
    end_tags.reverse()
    # Remove the indexes.
    html_tags = [tag[1] for tag in html_tags]
    return raw_text + ''.join(end_tags), ''.join(start_tags), ''.join(
        html_tags)
    def get_html_tags_no_user_tags_test(self):
        """
        Test the FormattingTags class' get_html_tags static method.
        """
        with patch('openlp.core.lib.translate') as mocked_translate, \
                patch('openlp.core.lib.settings') as mocked_settings, \
                patch('openlp.core.lib.formattingtags.json') as mocked_json:
            # GIVEN: Our mocked modules and functions.
            mocked_translate.side_effect = lambda module, string_to_translate, comment: string_to_translate
            mocked_settings.value.return_value = ''
            mocked_json.load.return_value = []

            # WHEN: Get the display tags.
            FormattingTags.load_tags()
            old_tags_list = copy.deepcopy(FormattingTags.get_html_tags())
            FormattingTags.load_tags()
            new_tags_list = FormattingTags.get_html_tags()

            # THEN: Lists should be identical.
            assert old_tags_list == new_tags_list, 'The formatting tag lists should be identical.'
    def test_get_html_tags_no_user_tags(self):
        """
        Test the FormattingTags class' get_html_tags static method.
        """
        with patch('openlp.core.lib.translate') as mocked_translate, \
                patch('openlp.core.common.settings') as mocked_settings, \
                patch('openlp.core.lib.formattingtags.json') as mocked_json:
            # GIVEN: Our mocked modules and functions.
            mocked_translate.side_effect = lambda module, string_to_translate, comment: string_to_translate
            mocked_settings.value.return_value = ''
            mocked_json.load.return_value = []

            # WHEN: Get the display tags.
            FormattingTags.load_tags()
            old_tags_list = copy.deepcopy(FormattingTags.get_html_tags())
            FormattingTags.load_tags()
            new_tags_list = FormattingTags.get_html_tags()

            # THEN: Lists should be identical.
            assert old_tags_list == new_tags_list, 'The formatting tag lists should be identical.'
Beispiel #24
0
    def _process_formatting_tags(self, song_xml, temporary):
        """
        Process the formatting tags from the song and either add missing tags temporary or permanently to the
        formatting tag list.

        :param song_xml: The song XML
        :param temporary: Is the song temporary?
        """
        if not hasattr(song_xml, "format"):
            return
        found_tags = []
        for tag in song_xml.format.tags.getchildren():
            name = tag.get("name")
            if name is None:
                continue
            start_tag = "{%s}" % name[:5]
            # Some tags have only start tag e.g. {br}
            end_tag = "{/" + name[:5] + "}" if hasattr(tag, "close") else ""
            openlp_tag = {
                "desc": name,
                "start tag": start_tag,
                "end tag": end_tag,
                "start html": tag.open.text,
                # Some tags have only start html e.g. {br}
                "end html": tag.close.text if hasattr(tag, "close") else "",
                "protected": False,
                # Add 'temporary' key in case the formatting tag should not be saved otherwise it is supposed that
                # formatting tag is permanent.
                "temporary": temporary,
            }
            found_tags.append(openlp_tag)
        existing_tag_ids = [tag["start tag"] for tag in FormattingTags.get_html_tags()]
        new_tags = [tag for tag in found_tags if tag["start tag"] not in existing_tag_ids]
        # Do not save an empty list.
        if new_tags:
            FormattingTags.add_html_tags(new_tags)
            if not temporary:
                custom_tags = [
                    tag for tag in FormattingTags.get_html_tags() if not tag["protected"] and not tag["temporary"]
                ]
                FormattingTags.save_html_tags(custom_tags)
Beispiel #25
0
    def _process_formatting_tags(self, song_xml, temporary):
        """
        Process the formatting tags from the song and either add missing tags temporary or permanently to the
        formatting tag list.

        :param song_xml: The song XML
        :param temporary: Is the song temporary?
        """
        if not hasattr(song_xml, 'format'):
            return
        found_tags = []
        for tag in song_xml.format.tags.getchildren():
            name = tag.get('name')
            if name is None:
                continue
            start_tag = '{%s}' % name[:5]
            # Some tags have only start tag e.g. {br}
            end_tag = '{/' + name[:5] + '}' if hasattr(tag, 'close') else ''
            openlp_tag = {
                'desc': name,
                'start tag': start_tag,
                'end tag': end_tag,
                'start html': tag.open.text,
                # Some tags have only start html e.g. {br}
                'end html': tag.close.text if hasattr(tag, 'close') else '',
                'protected': False,
                # Add 'temporary' key in case the formatting tag should not be saved otherwise it is supposed that
                # formatting tag is permanent.
                'temporary': temporary
            }
            found_tags.append(openlp_tag)
        existing_tag_ids = [tag['start tag'] for tag in FormattingTags.get_html_tags()]
        new_tags = [tag for tag in found_tags if tag['start tag'] not in existing_tag_ids]
        # Do not save an empty list.
        if new_tags:
            FormattingTags.add_html_tags(new_tags)
            if not temporary:
                custom_tags = [tag for tag in FormattingTags.get_html_tags()
                               if not tag['protected'] and not tag['temporary']]
                FormattingTags.save_html_tags(custom_tags)
Beispiel #26
0
 def __init__(self, manager):
     self.manager = manager
     FormattingTags.load_tags()
Beispiel #27
0
 def save_tags(self):
     """
     Save the new tags if they are valid.
     """
     FormattingTags.save_html_tags(self.custom_tags)
     FormattingTags.load_tags()
Beispiel #28
0
 def __init__(self, manager):
     self.manager = manager
     FormattingTags.load_tags()
    def get_html_tags_with_user_tags_test(self):
        """
        FormattingTags class - test the get_html_tags(), add_html_tags() and remove_html_tag() methods.
        """
        with patch('openlp.core.lib.translate') as mocked_translate, \
                patch('openlp.core.lib.settings') as mocked_settings, \
                patch('openlp.core.lib.formattingtags.json') as mocked_json:
            # GIVEN: Our mocked modules and functions.
            mocked_translate.side_effect = lambda module, string_to_translate: string_to_translate
            mocked_settings.value.return_value = ''
            mocked_json.loads.side_effect = [[], [TAG]]

            # WHEN: Get the display tags.
            FormattingTags.load_tags()
            old_tags_list = copy.deepcopy(FormattingTags.get_html_tags())

            # WHEN: Add our tag and get the tags again.
            FormattingTags.load_tags()
            FormattingTags.add_html_tags([TAG])
            new_tags_list = copy.deepcopy(FormattingTags.get_html_tags())

            # THEN: Lists should not be identical.
            assert old_tags_list != new_tags_list, 'The lists should be different.'

            # THEN: Added tag and last tag should be the same.
            new_tag = new_tags_list.pop()
            assert TAG == new_tag, 'Tags should be identical.'

            # WHEN: Remove the new tag.
            FormattingTags.remove_html_tag(len(new_tags_list))

            # THEN: The lists should now be identical.
            assert old_tags_list == FormattingTags.get_html_tags(), 'The lists should be identical.'
    def test_get_html_tags_with_user_tags(self):
        """
        FormattingTags class - test the get_html_tags(), add_html_tags() and remove_html_tag() methods.
        """
        with patch('openlp.core.lib.translate') as mocked_translate, \
                patch('openlp.core.common.settings') as mocked_settings, \
                patch('openlp.core.lib.formattingtags.json') as mocked_json:
            # GIVEN: Our mocked modules and functions.
            mocked_translate.side_effect = lambda module, string_to_translate: string_to_translate
            mocked_settings.value.return_value = ''
            mocked_json.loads.side_effect = [[], [TAG]]

            # WHEN: Get the display tags.
            FormattingTags.load_tags()
            old_tags_list = copy.deepcopy(FormattingTags.get_html_tags())

            # WHEN: Add our tag and get the tags again.
            FormattingTags.load_tags()
            FormattingTags.add_html_tags([TAG])
            new_tags_list = copy.deepcopy(FormattingTags.get_html_tags())

            # THEN: Lists should not be identical.
            assert old_tags_list != new_tags_list, 'The lists should be different.'

            # THEN: Added tag and last tag should be the same.
            new_tag = new_tags_list.pop()
            assert TAG == new_tag, 'Tags should be identical.'

            # WHEN: Remove the new tag.
            FormattingTags.remove_html_tag(len(new_tags_list))

            # THEN: The lists should now be identical.
            assert old_tags_list == FormattingTags.get_html_tags(), 'The lists should be identical.'
 def save_tags(self):
     """
     Save the new tags if they are valid.
     """
     FormattingTags.save_html_tags(self.custom_tags)
     FormattingTags.load_tags()