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.'
Beispiel #3
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 #4
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()
Beispiel #5
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 #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 _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 #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::

            ('{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)
    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 #10
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 #11
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 #12
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 #13
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)