From 961d70b836d135ffb1837f86da941875dc4b319e Mon Sep 17 00:00:00 2001 From: Philip Ridout Date: Sat, 3 Aug 2013 20:15:59 +0100 Subject: [PATCH 01/22] Fixed bug #1194610 By detecting the encoding ranther than assuming. --- .../plugins/songs/lib/songshowplusimport.py | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/openlp/plugins/songs/lib/songshowplusimport.py b/openlp/plugins/songs/lib/songshowplusimport.py index a72f83c4f..ca08e9002 100644 --- a/openlp/plugins/songs/lib/songshowplusimport.py +++ b/openlp/plugins/songs/lib/songshowplusimport.py @@ -30,6 +30,7 @@ The :mod:`songshowplusimport` module provides the functionality for importing SongShow Plus songs into the OpenLP database. """ +import chardet import os import logging import re @@ -134,41 +135,41 @@ class SongShowPlusImport(SongImport): log.debug(length_descriptor_size) data = song_data.read(length_descriptor) if block_key == TITLE: - self.title = unicode(data, u'cp1252') + self.title = unicode(data, chardet.detect(data)['encoding']) elif block_key == AUTHOR: authors = data.split(" / ") for author in authors: if author.find(",") !=-1: authorParts = author.split(", ") author = authorParts[1] + " " + authorParts[0] - self.parse_author(unicode(author, u'cp1252')) + self.parse_author(unicode(author, chardet.detect(data)['encoding'])) elif block_key == COPYRIGHT: - self.addCopyright(unicode(data, u'cp1252')) + self.addCopyright(unicode(data, chardet.detect(data)['encoding'])) elif block_key == CCLI_NO: self.ccliNumber = int(data) elif block_key == VERSE: - self.addVerse(unicode(data, u'cp1252'), "%s%s" % (VerseType.tags[VerseType.Verse], verse_no)) + self.addVerse(unicode(data, chardet.detect(data)['encoding']), "%s%s" % (VerseType.tags[VerseType.Verse], verse_no)) elif block_key == CHORUS: - self.addVerse(unicode(data, u'cp1252'), "%s%s" % (VerseType.tags[VerseType.Chorus], verse_no)) + self.addVerse(unicode(data, chardet.detect(data)['encoding']), "%s%s" % (VerseType.tags[VerseType.Chorus], verse_no)) elif block_key == BRIDGE: - self.addVerse(unicode(data, u'cp1252'), "%s%s" % (VerseType.tags[VerseType.Bridge], verse_no)) + self.addVerse(unicode(data, chardet.detect(data)['encoding']), "%s%s" % (VerseType.tags[VerseType.Bridge], verse_no)) elif block_key == TOPIC: - self.topics.append(unicode(data, u'cp1252')) + self.topics.append(unicode(data, chardet.detect(data)['encoding'])) elif block_key == COMMENTS: - self.comments = unicode(data, u'cp1252') + self.comments = unicode(data, chardet.detect(data)['encoding']) elif block_key == VERSE_ORDER: verse_tag = self.to_openlp_verse_tag(data, True) if verse_tag: if not isinstance(verse_tag, unicode): - verse_tag = unicode(verse_tag, u'cp1252') + verse_tag = unicode(verse_tag, chardet.detect(data)['encoding']) self.ssp_verse_order_list.append(verse_tag) elif block_key == SONG_BOOK: - self.songBookName = unicode(data, u'cp1252') + self.songBookName = unicode(data, chardet.detect(data)['encoding']) elif block_key == SONG_NUMBER: self.songNumber = ord(data) elif block_key == CUSTOM_VERSE: verse_tag = self.to_openlp_verse_tag(verse_name) - self.addVerse(unicode(data, u'cp1252'), verse_tag) + self.addVerse(unicode(data, chardet.detect(data)['encoding']), verse_tag) else: log.debug("Unrecognised blockKey: %s, data: %s" % (block_key, data)) song_data.seek(next_block_starts) From 1fb0048def598c580b85fd6a695eba84e0f82719 Mon Sep 17 00:00:00 2001 From: Philip Ridout Date: Tue, 13 Aug 2013 21:51:52 +0100 Subject: [PATCH 02/22] added fallback to retieve_windows encoding --- .../plugins/songs/lib/songshowplusimport.py | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/openlp/plugins/songs/lib/songshowplusimport.py b/openlp/plugins/songs/lib/songshowplusimport.py index ca08e9002..c9ca2a345 100644 --- a/openlp/plugins/songs/lib/songshowplusimport.py +++ b/openlp/plugins/songs/lib/songshowplusimport.py @@ -135,41 +135,41 @@ class SongShowPlusImport(SongImport): log.debug(length_descriptor_size) data = song_data.read(length_descriptor) if block_key == TITLE: - self.title = unicode(data, chardet.detect(data)['encoding']) + self.title = self.decode(data) elif block_key == AUTHOR: authors = data.split(" / ") for author in authors: if author.find(",") !=-1: authorParts = author.split(", ") author = authorParts[1] + " " + authorParts[0] - self.parse_author(unicode(author, chardet.detect(data)['encoding'])) + self.parse_author(self.decode(author)) elif block_key == COPYRIGHT: - self.addCopyright(unicode(data, chardet.detect(data)['encoding'])) + self.addCopyright(self.decode(data)) elif block_key == CCLI_NO: self.ccliNumber = int(data) elif block_key == VERSE: - self.addVerse(unicode(data, chardet.detect(data)['encoding']), "%s%s" % (VerseType.tags[VerseType.Verse], verse_no)) + self.addVerse(self.decode(data), "%s%s" % (VerseType.tags[VerseType.Verse], verse_no)) elif block_key == CHORUS: - self.addVerse(unicode(data, chardet.detect(data)['encoding']), "%s%s" % (VerseType.tags[VerseType.Chorus], verse_no)) + self.addVerse(self.decode(data), "%s%s" % (VerseType.tags[VerseType.Chorus], verse_no)) elif block_key == BRIDGE: - self.addVerse(unicode(data, chardet.detect(data)['encoding']), "%s%s" % (VerseType.tags[VerseType.Bridge], verse_no)) + self.addVerse(self.decode(data), "%s%s" % (VerseType.tags[VerseType.Bridge], verse_no)) elif block_key == TOPIC: - self.topics.append(unicode(data, chardet.detect(data)['encoding'])) + self.topics.append(self.decode(data)) elif block_key == COMMENTS: - self.comments = unicode(data, chardet.detect(data)['encoding']) + self.comments = self.decode(data) elif block_key == VERSE_ORDER: verse_tag = self.to_openlp_verse_tag(data, True) if verse_tag: if not isinstance(verse_tag, unicode): - verse_tag = unicode(verse_tag, chardet.detect(data)['encoding']) + verse_tag = self.decode(verse_tag) self.ssp_verse_order_list.append(verse_tag) elif block_key == SONG_BOOK: - self.songBookName = unicode(data, chardet.detect(data)['encoding']) + self.songBookName = self.decode(data) elif block_key == SONG_NUMBER: self.songNumber = ord(data) elif block_key == CUSTOM_VERSE: verse_tag = self.to_openlp_verse_tag(verse_name) - self.addVerse(unicode(data, chardet.detect(data)['encoding']), verse_tag) + self.addVerse(self.decode(data), verse_tag) else: log.debug("Unrecognised blockKey: %s, data: %s" % (block_key, data)) song_data.seek(next_block_starts) @@ -207,3 +207,13 @@ class SongShowPlusImport(SongImport): verse_tag = VerseType.tags[VerseType.Other] verse_number = self.other_list[verse_name] return verse_tag + verse_number + + def decode(self, data): + try: + return unicode(data, chardet.detect(data)['encoding']) + except: + while True: + try: + return unicode(data, self.encoding) + except: + self.encoding = retrieve_windows_encoding() \ No newline at end of file From eb1703bcc996932b7a673c00c87079c257115e09 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Mon, 26 Aug 2013 09:11:20 +0100 Subject: [PATCH 03/22] fix up edit code --- openlp/core/ui/formattingtagform.py | 180 +++++++++------------------- 1 file changed, 55 insertions(+), 125 deletions(-) diff --git a/openlp/core/ui/formattingtagform.py b/openlp/core/ui/formattingtagform.py index df0fe5e8a..a9828d228 100644 --- a/openlp/core/ui/formattingtagform.py +++ b/openlp/core/ui/formattingtagform.py @@ -42,6 +42,16 @@ from openlp.core.lib.ui import critical_error_message_box from openlp.core.ui.formattingtagdialog import Ui_FormattingTagDialog +class EDITCOLUMN(object): + """ + Hides the magic numbers for the table columns + """ + Description = 0 + Tag = 1 + StartHtml = 2 + EndHtml = 3 + + class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog): """ The :class:`FormattingTagForm` manages the settings tab . @@ -58,7 +68,7 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog): r'|(?P\?(?:(?!\?>).)*\?)' r'|(?P!--(?:(?!-->).)*--))>', re.UNICODE) self.html_regex = re.compile(r'^(?:[^<>]*%s)*[^<>]*$' % self.html_tag_regex.pattern) - #self.tag_table_widget.itemSelectionChanged.connect(self.on_row_selected) + self.tag_table_widget.itemSelectionChanged.connect(self.on_row_selected) self.new_button.clicked.connect(self.on_new_clicked) #self.save_push_button.clicked.connect(self.on_saved_clicked) self.delete_button.clicked.connect(self.on_delete_clicked) @@ -66,7 +76,6 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog): self.button_box.rejected.connect(self.close) # Forces reloading of tags from openlp configuration. FormattingTags.load_tags() - self.pause_validation = False def exec_(self): """ @@ -80,76 +89,33 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog): """ Table Row selected so display items and set field state. """ - #self.save_push_button.setEnabled(False) - self.selected = self.tag_table_widget.currentRow() - html = FormattingTags.get_html_tags()[self.selected] - self.description_line_edit.setText(html[u'desc']) - self.tag_line_edit.setText(self._strip(html[u'start tag'])) - self.start_tag_line_edit.setText(html[u'start html']) - self.end_tag_line_edit.setText(html[u'end html']) - if html[u'protected']: - self.description_line_edit.setEnabled(False) - self.tag_line_edit.setEnabled(False) - self.start_tag_line_edit.setEnabled(False) - self.end_tag_line_edit.setEnabled(False) - self.delete_push_button.setEnabled(False) - else: - self.description_line_edit.setEnabled(True) - self.tag_line_edit.setEnabled(True) - self.start_tag_line_edit.setEnabled(True) - self.end_tag_line_edit.setEnabled(True) - self.delete_push_button.setEnabled(True) - - def on_text_edited(self, text): - """ - Enable the ``save_push_button`` when any of the selected tag's properties - has been changed. - """ - self.save_push_button.setEnabled(True) + self.delete_button.setEnabled(True) def on_new_clicked(self): """ - Add a new tag to list only if it is not a duplicate. + Add a new tag to edit list and select it for editing. """ - last_row = self.tag_table_widget.rowCount() - 1 - self.tag_table_widget.selectRow(last_row) - self.tag_table_widget.setCurrentCell(last_row, 0) - for html in FormattingTags.get_html_tags(): - if self._strip(html[u'start tag']) == u'n': - critical_error_message_box( - translate('OpenLP.FormattingTagForm', 'Update Error'), - translate('OpenLP.FormattingTagForm', 'Tag "n" already defined.')) - return - # Add new tag to list - tag = { - u'desc': translate('OpenLP.FormattingTagForm', 'New Tag'), - u'start tag': u'{n%s}' % unicode(last_row + 1), - u'start html': translate('OpenLP.FormattingTagForm', ''), - u'end tag': u'{/n%s}' % unicode(last_row + 1), - u'end html': translate('OpenLP.FormattingTagForm', ''), - u'protected': False, - u'temporary': False - } - #FormattingTags.add_html_tags([tag]) - #FormattingTags.save_html_tags() - #self._reloadTable() - # Highlight new row - #self.tag_table_widget.selectRow(self.tag_table_widget.rowCount() - 1) - #self.on_row_selected() + new_row = self.tag_table_widget.rowCount() + self.tag_table_widget.insertRow(new_row) + self.tag_table_widget.setItem(new_row, 0, + QtGui.QTableWidgetItem(translate('OpenLP.FormattingTagForm', 'New Tag'))) + self.tag_table_widget.setItem(new_row, 1, + QtGui.QTableWidgetItem('n%s' % unicode(new_row))) + self.tag_table_widget.setItem(new_row, 2, + QtGui.QTableWidgetItem(translate('OpenLP.FormattingTagForm', ''))) + self.tag_table_widget.setItem(new_row, 3, + QtGui.QTableWidgetItem(translate('OpenLP.FormattingTagForm', ''))) + self.tag_table_widget.resizeRowsToContents() self.tag_table_widget.scrollToBottom() + self.tag_table_widget.selectRow(new_row) def on_delete_clicked(self): """ - Delete selected custom tag. + Delete selected custom row. """ - if self.selected != -1: - FormattingTags.remove_html_tag(self.selected) - # As the first items are protected we should not have to take care - # of negative indexes causing tracebacks. - self.tag_table_widget.selectRow(self.selected - 1) - self.selected = -1 - FormattingTags.save_html_tags() - self._reloadTable() + selected = self.tag_table_widget.currentRow() + if selected != -1: + self.tag_table_widget.removeRow(selected) def on_saved_clicked(self): """ @@ -217,12 +183,10 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog): # only process for editable rows pre_row_item = self.tag_table_widget.item(pre_row, 0) edit_item = None - if pre_row_item and (pre_row_item.flags() & QtCore.Qt.ItemIsEditable) and not self.pause_validation: - data = self.item_to_data_dict(pre_row_item) + if pre_row_item and (pre_row_item.flags() & QtCore.Qt.ItemIsEditable): item = self.tag_table_widget.item(pre_row, pre_col) text = unicode(item.text()) - if pre_col is 0: - # Tag name edited + if pre_col is EDITCOLUMN.Tag: if text: for row in range(self.tag_table_widget.rowCount()): counting_item = self.tag_table_widget.item(row, 0) @@ -233,33 +197,10 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog): 'Tag %s is already defined. Please pick a different one.' % text), QtGui.QMessageBox.Discard|QtGui.QMessageBox.Ok) if answer == QtGui.QMessageBox.Discard: - item.setText(data.get(u'tag')) + break else: edit_item = item break - if not edit_item: - data[u'tag'] = text - data.setdefault(u'description', u'') - data.setdefault(u'html', u'') - pre_row_item.setData(QtCore.Qt.UserRole, data) - flags = self.tag_table_widget.item(pre_row, 1).flags() - if not (flags & QtCore.Qt.ItemIsEditable): - # if description cell is read only, the user is adding a new tag. - # So we add another empty row and enable editing for description and html. - new_row = self.tag_table_widget.rowCount() - self.tag_table_widget.insertRow(new_row) - for column in range(4): - new_item = QtGui.QTableWidgetItem(u'') - if column != 0: - new_item.setFlags(flags) - self.tag_table_widget.setItem(new_row, column, new_item) - for column in [1, 2]: - self.tag_table_widget.item(pre_row, column).setFlags(item.flags()) - # trigger edit as editing might have been enabled after selecting - if cur_row == pre_row and cur_col in [1, 2]: - cur_item = self.tag_table_widget.item(cur_row, cur_col) - self.tag_table_widget.editItem(cur_item) - self.tag_table_widget.resizeRowsToContents() else: answer = None if self.tag_table_widget.item(pre_row, 1).text() or self.tag_table_widget.item(pre_row, 2).text(): @@ -268,43 +209,32 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog): translate('OpenLP.FormattingTagForm', 'No tag name defined. Do you want to delete the whole tag?'), QtGui.QMessageBox.Yes|QtGui.QMessageBox.Discard|QtGui.QMessageBox.Cancel) - if answer == QtGui.QMessageBox.Discard: - item.setText(data.get(u'tag')) - if answer == QtGui.QMessageBox.Cancel: - edit_item = item + #if answer == QtGui.QMessageBox.Discard: + # item.setText(data.get(u'tag')) + #if answer == QtGui.QMessageBox.Cancel: + # edit_item = item elif pre_row < self.tag_table_widget.rowCount() - 1: self.tag_table_widget.removeRow(pre_row) - elif pre_col is 1: - # Description edited - data[u'description'] = text - pre_row_item.setData(QtCore.Qt.UserRole, data) - elif pre_col is 2: + #elif pre_col is EDITCOLUMN.StartHtml: # HTML edited - end_html = self.start_html_to_end_html(text) - if end_html is not None: - item.setToolTip(cgi.escape(text)) - if self.tag_table_widget.item(pre_row, 3) is None: - self.tag_table_widget.setItem(pre_row, 3, QtGui.QTableWidgetItem(end_html)) - else: - self.tag_table_widget.item(pre_row, 3).setText(end_html) - self.tag_table_widget.item(pre_row, 3).setToolTip(cgi.escape(end_html)) - data[u'html'] = text - pre_row_item.setData(QtCore.Qt.UserRole, data) - self.tag_table_widget.resizeRowsToContents() - elif QtGui.QMessageBox.question(self, - translate('OpenLP.FormattingTagForm', 'Validation Error'), - translate('OpenLP.FormattingTagForm', 'The entered HTML is not valid. Please enter valid HTML.'), - QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel) == QtGui.QMessageBox.Cancel: - item.setText(data.get(u'html')) - else: - edit_item = item - if not edit_item: - # select the tag cell in a empty row - cur_row_item = self.tag_table_widget.item(cur_row, 0) - if cur_row_item and (cur_row_item.flags() & QtCore.Qt.ItemIsEditable) and cur_row_item.text().isEmpty(): - edit_item = cur_row_item - if edit_item: - self.tag_table_widget.setCurrentItem(edit_item) + #end_html = self.start_html_to_end_html(text) + #if end_html is not None: + # item.setToolTip(cgi.escape(text)) + ## if self.tag_table_widget.item(pre_row, 3) is None: + # self.tag_table_widget.setItem(pre_row, 3, QtGui.QTableWidgetItem(end_html)) + # else: + # self.tag_table_widget.item(pre_row, 3).setText(end_html) + # self.tag_table_widget.item(pre_row, 3).setToolTip(cgi.escape(end_html)) + # #data[u'html'] = text + # #pre_row_item.setData(QtCore.Qt.UserRole, data) + # # self.tag_table_widget.resizeRowsToContents() + #if not edit_item: + # # select the tag cell in a empty row + # cur_row_item = self.tag_table_widget.item(cur_row, 0) + # if cur_row_item and (cur_row_item.flags() & QtCore.Qt.ItemIsEditable) and cur_row_item.text().isEmpty(): + # edit_item = cur_row_item + #if edit_item: + # self.tag_table_widget.setCurrentItem(edit_item) # enable delete_button for editable rows cur_row = self.tag_table_widget.currentRow() cur_row_item = self.tag_table_widget.item(cur_row, 0) From b3ab68b0f5e3a51fd729d60b3202b6f731f357c9 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 31 Aug 2013 09:52:44 +0100 Subject: [PATCH 04/22] Validation in progress --- openlp/core/ui/formattingtagcontroller.py | 98 +++++++++++++++++++++ openlp/core/ui/formattingtagdialog.py | 66 -------------- openlp/core/ui/formattingtagform.py | 100 +++++++++------------- 3 files changed, 139 insertions(+), 125 deletions(-) create mode 100644 openlp/core/ui/formattingtagcontroller.py diff --git a/openlp/core/ui/formattingtagcontroller.py b/openlp/core/ui/formattingtagcontroller.py new file mode 100644 index 000000000..7e1131507 --- /dev/null +++ b/openlp/core/ui/formattingtagcontroller.py @@ -0,0 +1,98 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2013 Raoul Snyman # +# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan # +# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, # +# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. # +# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, # +# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # +# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, # +# Frode Woldsund, Martin Zibricky, Patrick Zimmermann # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### +""" +The :mod:`formattingtagform` provides an Tag Edit facility. The Base set are protected and included each time loaded. +Custom tags can be defined and saved. The Custom Tag arrays are saved in a pickle so QSettings works on them. Base Tags +cannot be changed. +""" + +import re +import cgi + +from openlp.core.lib import translate + + +class FormattingTagController(object): + """ + The :class:`FormattingTagController` manages the non UI functions . + """ + def __init__(self): + """ + Initiator + """ + self.html_tag_regex = re.compile(r'<(?:(?P/(?=[^\s/>]+>))?' + r'(?P[^\s/!\?>]+)(?:\s+[^\s=]+="[^"]*")*\s*(?P/)?' + r'|(?P!\[CDATA\[(?:(?!\]\]>).)*\]\])' + r'|(?P\?(?:(?!\?>).)*\?)' + r'|(?P!--(?:(?!-->).)*--))>', re.UNICODE) + self.html_regex = re.compile(r'^(?:[^<>]*%s)*[^<>]*$' % self.html_tag_regex.pattern) + + def pre_save(self): + self.custom_tags = [] + + def validate_for_save(self, desc, tag, start_html, end_html): + if not desc: + pass + print desc + print self.start_html_to_end_html(start_html) + + def html_start_validate(self, start, end): + pass + + def _strip(self, tag): + """ + Remove tag wrappers for editing. + """ + tag = tag.replace(u'{', u'') + tag = tag.replace(u'}', u'') + return tag + + def start_html_to_end_html(self, start_html): + """ + Return the end HTML for a given start HTML or None if invalid. + """ + end_tags = [] + match = self.html_regex.match(start_html) + if match: + match = self.html_tag_regex.search(start_html) + while match: + if match.group(u'tag'): + tag = match.group(u'tag').lower() + if match.group(u'close'): + if match.group(u'empty') or not end_tags or end_tags.pop() != tag: + return + elif not match.group(u'empty'): + end_tags.append(tag) + match = self.html_tag_regex.search(start_html, match.end()) + return u''.join(map(lambda tag: u'' % tag, reversed(end_tags))) + + def start_tag_changed(self, start_html, end_html): + end = self.start_html_to_end_html(start_html) + if not end_html: + return None, end \ No newline at end of file diff --git a/openlp/core/ui/formattingtagdialog.py b/openlp/core/ui/formattingtagdialog.py index cdd1d6edc..20762895f 100644 --- a/openlp/core/ui/formattingtagdialog.py +++ b/openlp/core/ui/formattingtagdialog.py @@ -90,59 +90,6 @@ class Ui_FormattingTagDialog(object): item = QtGui.QTableWidgetItem() self.tag_table_widget.setHorizontalHeaderItem(3, item) self.list_data_grid_layout.addWidget(self.tag_table_widget) - - - #self.horizontal_layout = QtGui.QHBoxLayout() - #self.horizontal_layout.setObjectName(u'horizontal_layout') - #spacer_item = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) - #self.horizontal_layout.addItem(spacer_item) - #self.delete_push_button = QtGui.QPushButton(formatting_tag_dialog) - #self.delete_push_button.setObjectName(u'delete_push_button') - #self.horizontal_layout.addWidget(self.delete_push_button) - #self.list_data_grid_layout.addLayout(self.horizontal_layout, 1, 0, 1, 1) - #self.edit_group_box = QtGui.QGroupBox(formatting_tag_dialog) - #self.edit_group_box.setObjectName(u'edit_group_box') - #self.data_grid_layout = QtGui.QGridLayout(self.edit_group_box) - #self.data_grid_layout.setObjectName(u'data_grid_layout') - #self.description_label = QtGui.QLabel(self.edit_group_box) - #self.description_label.setAlignment(QtCore.Qt.AlignCenter) - #self.description_label.setObjectName(u'description_label') - #self.data_grid_layout.addWidget(self.description_label, 0, 0, 1, 1) - #self.description_line_edit = QtGui.QLineEdit(self.edit_group_box) - #self.description_line_edit.setObjectName(u'description_line_edit') - #self.data_grid_layout.addWidget(self.description_line_edit, 0, 1, 2, 1) - #self.new_push_button = QtGui.QPushButton(self.edit_group_box) - #self.new_push_button.setObjectName(u'new_push_button') - #self.data_grid_layout.addWidget(self.new_push_button, 0, 2, 2, 1) - #self.tag_label = QtGui.QLabel(self.edit_group_box) - #self.tag_label.setAlignment(QtCore.Qt.AlignCenter) - #self.tag_label.setObjectName(u'tag_label') - #self.data_grid_layout.addWidget(self.tag_label, 2, 0, 1, 1) - #self.tag_line_edit = QtGui.QLineEdit(self.edit_group_box) - #self.tag_line_edit.setMaximumSize(QtCore.QSize(50, 16777215)) - #self.tag_line_edit.setMaxLength(5) - #self.tag_line_edit.setObjectName(u'tag_line_edit') - #self.data_grid_layout.addWidget(self.tag_line_edit, 2, 1, 1, 1) - #self.start_tag_label = QtGui.QLabel(self.edit_group_box) - #self.start_tag_label.setAlignment(QtCore.Qt.AlignCenter) - #self.start_tag_label.setObjectName(u'start_tag_label') - #self.data_grid_layout.addWidget(self.start_tag_label, 3, 0, 1, 1) - #self.start_tag_line_edit = QtGui.QLineEdit(self.edit_group_box) - #self.start_tag_line_edit.setObjectName(u'start_tag_line_edit') - #self.data_grid_layout.addWidget(self.start_tag_line_edit, 3, 1, 1, 1) - #self.end_tag_label = QtGui.QLabel(self.edit_group_box) - #self.end_tag_label.setAlignment(QtCore.Qt.AlignCenter) - #self.end_tag_label.setObjectName(u'end_tag_label') - #self.data_grid_layout.addWidget(self.end_tag_label, 4, 0, 1, 1) - #self.end_tag_line_edit = QtGui.QLineEdit(self.edit_group_box) - #self.end_tag_line_edit.setObjectName(u'end_tag_line_edit') - #self.data_grid_layout.addWidget(self.end_tag_line_edit, 4, 1, 1, 1) - #self.save_push_button = QtGui.QPushButton(self.edit_group_box) - #self.save_push_button.setObjectName(u'save_push_button') - #self.data_grid_layout.addWidget(self.save_push_button, 4, 2, 1, 1) - #self.list_data_grid_layout.addWidget(self.edit_group_box, 2, 0, 1, 1) - - self.edit_button_layout = QtGui.QHBoxLayout() self.new_button = QtGui.QPushButton(formatting_tag_dialog) self.new_button.setIcon(build_icon(u':/general/general_new.png')) @@ -162,13 +109,6 @@ class Ui_FormattingTagDialog(object): self.restore_button.setIcon(build_icon(u':/general/general_revert.png')) self.restore_button.setObjectName(u'restore_button') self.list_data_grid_layout.addWidget(self.button_box) - - #self.button_box = create_button_box(formatting_tag_dialog, u'button_box', [u'close']) - #self.list_data_grid_layout.addWidget(self.button_box, 5, 0, 1, 1) - #self.delete_push_button = QtGui.QPushButton(formatting_tag_dialog) - #self.delete_push_button.setObjectName(u'delete_push_button') - #self.list_data_grid_layout.addWidget(self.delete_push_button, 5, 0, 1, 1) - self.retranslateUi(formatting_tag_dialog) def retranslateUi(self, formatting_tag_dialog): @@ -176,12 +116,6 @@ class Ui_FormattingTagDialog(object): Translate the UI on the fly """ formatting_tag_dialog.setWindowTitle(translate('OpenLP.FormattingTagDialog', 'Configure Formatting Tags')) - #self.edit_group_box.setTitle(translate('OpenLP.FormattingTagDialog', 'Edit Selection')) - #self.save_push_button.setText(translate('OpenLP.FormattingTagDialog', 'Save')) - #self.description_label.setText(translate('OpenLP.FormattingTagDialog', 'Description')) - #self.tag_label.setText(translate('OpenLP.FormattingTagDialog', 'Tag')) - #self.start_tag_label.setText(translate('OpenLP.FormattingTagDialog', 'Start HTML')) - #self.end_tag_label.setText(translate('OpenLP.FormattingTagDialog', 'End HTML')) self.delete_button.setText(UiStrings().Delete) self.new_button.setText(UiStrings().New) self.tag_table_widget_read_label.setText(translate('OpenLP.FormattingTagDialog', 'Static Formatting')) diff --git a/openlp/core/ui/formattingtagform.py b/openlp/core/ui/formattingtagform.py index a9828d228..5b65b48d4 100644 --- a/openlp/core/ui/formattingtagform.py +++ b/openlp/core/ui/formattingtagform.py @@ -32,7 +32,6 @@ Custom tags can be defined and saved. The Custom Tag arrays are saved in a pickl cannot be changed. """ -import re import cgi from PyQt4 import QtGui, QtCore @@ -40,6 +39,7 @@ from PyQt4 import QtGui, QtCore from openlp.core.lib import FormattingTags, translate from openlp.core.lib.ui import critical_error_message_box from openlp.core.ui.formattingtagdialog import Ui_FormattingTagDialog +from openlp.core.ui.formattingtagcontroller import FormattingTagController class EDITCOLUMN(object): @@ -52,7 +52,7 @@ class EDITCOLUMN(object): EndHtml = 3 -class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog): +class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagController): """ The :class:`FormattingTagForm` manages the settings tab . """ @@ -60,17 +60,12 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog): """ Constructor """ - QtGui.QDialog.__init__(self, parent) + super(FormattingTagForm, self).__init__(parent) self.setupUi(self) - self.html_tag_regex = re.compile(r'<(?:(?P/(?=[^\s/>]+>))?' - r'(?P[^\s/!\?>]+)(?:\s+[^\s=]+="[^"]*")*\s*(?P/)?' - r'|(?P!\[CDATA\[(?:(?!\]\]>).)*\]\])' - r'|(?P\?(?:(?!\?>).)*\?)' - r'|(?P!--(?:(?!-->).)*--))>', re.UNICODE) - self.html_regex = re.compile(r'^(?:[^<>]*%s)*[^<>]*$' % self.html_tag_regex.pattern) + self.services = FormattingTagController() self.tag_table_widget.itemSelectionChanged.connect(self.on_row_selected) self.new_button.clicked.connect(self.on_new_clicked) - #self.save_push_button.clicked.connect(self.on_saved_clicked) + self.save_button.clicked.connect(self.on_saved_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) @@ -103,8 +98,7 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog): QtGui.QTableWidgetItem('n%s' % unicode(new_row))) self.tag_table_widget.setItem(new_row, 2, QtGui.QTableWidgetItem(translate('OpenLP.FormattingTagForm', ''))) - self.tag_table_widget.setItem(new_row, 3, - QtGui.QTableWidgetItem(translate('OpenLP.FormattingTagForm', ''))) + self.tag_table_widget.setItem(new_row, 3, QtGui.QTableWidgetItem(u"")) self.tag_table_widget.resizeRowsToContents() self.tag_table_widget.scrollToBottom() self.tag_table_widget.selectRow(new_row) @@ -121,26 +115,34 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog): """ Update Custom Tag details if not duplicate and save the data. """ + count = 0 + self.services.pre_save() + while count < self.tag_table_widget.rowCount(): + result = self.services.validate_for_save(self.tag_table_widget.item(count, 0).text(), + self.tag_table_widget.item(count, 1).text(), self.tag_table_widget.item(count, 2).text(), + self.tag_table_widget.item(count, 3).text()) + count += 1 + html_expands = FormattingTags.get_html_tags() - if self.selected != -1: - html = html_expands[self.selected] - tag = self.tag_line_edit.text() - for linenumber, html1 in enumerate(html_expands): - if self._strip(html1[u'start tag']) == tag and linenumber != self.selected: - critical_error_message_box( - translate('OpenLP.FormattingTagForm', 'Update Error'), - translate('OpenLP.FormattingTagForm', 'Tag %s already defined.') % tag) - return - html[u'desc'] = self.description_line_edit.text() - html[u'start html'] = self.start_tag_line_edit.text() - html[u'end html'] = self.end_tag_line_edit.text() - html[u'start tag'] = u'{%s}' % tag - html[u'end tag'] = u'{/%s}' % tag - # Keep temporary tags when the user changes one. - html[u'temporary'] = False - self.selected = -1 - FormattingTags.save_html_tags() - self._reloadTable() + #if self.selected != -1: + # html = html_expands[self.selected] + # tag = self.tag_line_edit.text() + # for linenumber, html1 in enumerate(html_expands): + # if self._strip(html1[u'start tag']) == tag and linenumber != self.selected: + # critical_error_message_box( + # translate('OpenLP.FormattingTagForm', 'Update Error'), + # translate('OpenLP.FormattingTagForm', 'Tag %s already defined.') % tag) + # return + # html[u'desc'] = self.description_line_edit.text() + # html[u'start html'] = self.start_tag_line_edit.text() + # html[u'end html'] = self.end_tag_line_edit.text() + # html[u'start tag'] = u'{%s}' % tag + # html[u'end tag'] = u'{/%s}' % tag + # # Keep temporary tags when the user changes one. + # html[u'temporary'] = False + # self.selected = -1 + #FormattingTags.save_html_tags() + #self._reloadTable() def _reloadTable(self): """ @@ -166,7 +168,6 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog): print self.tag_table_widget.rowCount(), html line = self.tag_table_widget.rowCount() self.tag_table_widget.setRowCount(line + 1) - self.tag_table_widget.setRowCount(self.tag_table_widget.rowCount() + 1) self.tag_table_widget.setItem(line, 0, QtGui.QTableWidgetItem(html[u'desc'])) self.tag_table_widget.setItem(line, 1, QtGui.QTableWidgetItem(self._strip(html[u'start tag']))) self.tag_table_widget.setItem(line, 2, QtGui.QTableWidgetItem(html[u'start html'])) @@ -182,8 +183,7 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog): print cur_row, cur_col, pre_col, pre_col # only process for editable rows pre_row_item = self.tag_table_widget.item(pre_row, 0) - edit_item = None - if pre_row_item and (pre_row_item.flags() & QtCore.Qt.ItemIsEditable): + if pre_row_item: item = self.tag_table_widget.item(pre_row, pre_col) text = unicode(item.text()) if pre_col is EDITCOLUMN.Tag: @@ -209,25 +209,14 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog): translate('OpenLP.FormattingTagForm', 'No tag name defined. Do you want to delete the whole tag?'), QtGui.QMessageBox.Yes|QtGui.QMessageBox.Discard|QtGui.QMessageBox.Cancel) - #if answer == QtGui.QMessageBox.Discard: - # item.setText(data.get(u'tag')) - #if answer == QtGui.QMessageBox.Cancel: - # edit_item = item - elif pre_row < self.tag_table_widget.rowCount() - 1: - self.tag_table_widget.removeRow(pre_row) - #elif pre_col is EDITCOLUMN.StartHtml: + elif pre_col is EDITCOLUMN.StartHtml: # HTML edited - #end_html = self.start_html_to_end_html(text) - #if end_html is not None: - # item.setToolTip(cgi.escape(text)) - ## if self.tag_table_widget.item(pre_row, 3) is None: - # self.tag_table_widget.setItem(pre_row, 3, QtGui.QTableWidgetItem(end_html)) - # else: - # self.tag_table_widget.item(pre_row, 3).setText(end_html) - # self.tag_table_widget.item(pre_row, 3).setToolTip(cgi.escape(end_html)) - # #data[u'html'] = text - # #pre_row_item.setData(QtCore.Qt.UserRole, data) - # # self.tag_table_widget.resizeRowsToContents() + item = self.tag_table_widget.item(pre_row, 3) + end_html = unicode(item.text()) + errors, tag = self.services.start_tag_changed(text, end_html) + if tag: + self.tag_table_widget.setItem(pre_row, 3, QtGui.QTableWidgetItem(tag)) + self.tag_table_widget.resizeRowsToContents() #if not edit_item: # # select the tag cell in a empty row # cur_row_item = self.tag_table_widget.item(cur_row, 0) @@ -242,10 +231,3 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog): delete_enabled &= cur_row < self.tag_table_widget.rowCount() - 1 self.delete_button.setEnabled(delete_enabled) - def _strip(self, tag): - """ - Remove tag wrappers for editing. - """ - tag = tag.replace(u'{', u'') - tag = tag.replace(u'}', u'') - return tag From dceaaa6996d4e4148a7e8aec61eae3471c706bff Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 31 Aug 2013 12:43:05 +0100 Subject: [PATCH 05/22] ore changes --- openlp/core/ui/formattingtagform.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/openlp/core/ui/formattingtagform.py b/openlp/core/ui/formattingtagform.py index 5b65b48d4..894c08038 100644 --- a/openlp/core/ui/formattingtagform.py +++ b/openlp/core/ui/formattingtagform.py @@ -185,7 +185,7 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont pre_row_item = self.tag_table_widget.item(pre_row, 0) if pre_row_item: item = self.tag_table_widget.item(pre_row, pre_col) - text = unicode(item.text()) + text = item.text() if pre_col is EDITCOLUMN.Tag: if text: for row in range(self.tag_table_widget.rowCount()): @@ -198,9 +198,6 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont QtGui.QMessageBox.Discard|QtGui.QMessageBox.Ok) if answer == QtGui.QMessageBox.Discard: break - else: - edit_item = item - break else: answer = None if self.tag_table_widget.item(pre_row, 1).text() or self.tag_table_widget.item(pre_row, 2).text(): @@ -212,7 +209,7 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont elif pre_col is EDITCOLUMN.StartHtml: # HTML edited item = self.tag_table_widget.item(pre_row, 3) - end_html = unicode(item.text()) + end_html = item.text() errors, tag = self.services.start_tag_changed(text, end_html) if tag: self.tag_table_widget.setItem(pre_row, 3, QtGui.QTableWidgetItem(tag)) @@ -225,9 +222,3 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont #if edit_item: # self.tag_table_widget.setCurrentItem(edit_item) # enable delete_button for editable rows - cur_row = self.tag_table_widget.currentRow() - cur_row_item = self.tag_table_widget.item(cur_row, 0) - delete_enabled = bool(cur_row_item) and bool(cur_row_item.flags() & QtCore.Qt.ItemIsEditable) - delete_enabled &= cur_row < self.tag_table_widget.rowCount() - 1 - self.delete_button.setEnabled(delete_enabled) - From e4ba5cb72a04d689ff2191ab31c5a616366c2cfd Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 31 Aug 2013 18:20:43 +0100 Subject: [PATCH 06/22] add test files and ui validation sort of works --- openlp/core/lib/formattingtags.py | 2 +- openlp/core/ui/formattingtagcontroller.py | 64 +++++++++++++++++-- openlp/core/ui/formattingtagform.py | 46 +++++-------- .../tests.formattingcontroller.py | 25 ++++++++ .../tests_fromattingstagsform.py | 50 +++++++++++++++ 5 files changed, 149 insertions(+), 38 deletions(-) create mode 100644 tests/functional/openlp_core_ui/tests.formattingcontroller.py create mode 100644 tests/functional/openlp_core_ui/tests_fromattingstagsform.py diff --git a/openlp/core/lib/formattingtags.py b/openlp/core/lib/formattingtags.py index 1984b08ba..ebff708b4 100644 --- a/openlp/core/lib/formattingtags.py +++ b/openlp/core/lib/formattingtags.py @@ -36,7 +36,7 @@ from openlp.core.lib import Settings, translate class FormattingTags(object): """ - Static Class to HTML Tags to be access around the code the list is managed by the Options Tab. + Static Class for HTML Tags to be access around the code the list is managed by the Options Tab. """ html_expands = [] diff --git a/openlp/core/ui/formattingtagcontroller.py b/openlp/core/ui/formattingtagcontroller.py index 7e1131507..6fb75ade4 100644 --- a/openlp/core/ui/formattingtagcontroller.py +++ b/openlp/core/ui/formattingtagcontroller.py @@ -33,9 +33,8 @@ cannot be changed. """ import re -import cgi -from openlp.core.lib import translate +from openlp.core.lib import FormattingTags, translate class FormattingTagController(object): @@ -54,17 +53,34 @@ class FormattingTagController(object): self.html_regex = re.compile(r'^(?:[^<>]*%s)*[^<>]*$' % self.html_tag_regex.pattern) def pre_save(self): + """ + Cleanup the array before save validation runs + """ + self.protected_tags = [tag for tag in FormattingTags.html_expands if tag.get(u'protected')] self.custom_tags = [] def validate_for_save(self, desc, tag, start_html, end_html): + """ + Validate a custom tag and add to the tags array if valid.. + + `description` + Explanation of the tag. + + `tag` + The tag in the song used to mark the text. + + `start_html` + The start html tag. + + `end_html` + The end html tag. + + """ if not desc: pass print desc print self.start_html_to_end_html(start_html) - def html_start_validate(self, start, end): - pass - def _strip(self, tag): """ Remove tag wrappers for editing. @@ -76,6 +92,10 @@ class FormattingTagController(object): def start_html_to_end_html(self, start_html): """ Return the end HTML for a given start HTML or None if invalid. + + `start_html` + The start html tag. + """ end_tags = [] match = self.html_regex.match(start_html) @@ -93,6 +113,38 @@ class FormattingTagController(object): return u''.join(map(lambda tag: u'' % tag, reversed(end_tags))) def start_tag_changed(self, start_html, end_html): + """ + Validate the HTML tags when the start tag has been changed. + + `start_html` + The start html tag. + + `end_html` + The end html tag. + + """ end = self.start_html_to_end_html(start_html) if not end_html: - return None, end \ No newline at end of file + if not end: + return translate('OpenLP.FormattingTagForm', 'Start tag %s is not valid HTML' % start_html), None + return None, end + return None, None + + def end_tag_changed(self, start_html, end_html): + """ + Validate the HTML tags when the end tag has been changed. + + `start_html` + The start html tag. + + `end_html` + The end html tag. + + """ + end = self.start_html_to_end_html(start_html) + if not end_html: + return None, end + if end and end != end_html: + return translate('OpenLP.FormattingTagForm', + 'End tag %s does not match end tag for start tag %s' % (end, start_html)), None + return None, None \ No newline at end of file diff --git a/openlp/core/ui/formattingtagform.py b/openlp/core/ui/formattingtagform.py index 15a59ac52..1eaec7cc5 100644 --- a/openlp/core/ui/formattingtagform.py +++ b/openlp/core/ui/formattingtagform.py @@ -182,31 +182,11 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont """ print cur_row, cur_col, pre_col, pre_col # only process for editable rows - pre_row_item = self.tag_table_widget.item(pre_row, 0) - if pre_row_item: + if self.tag_table_widget.item(pre_row, 0): item = self.tag_table_widget.item(pre_row, pre_col) text = item.text() - if pre_col is EDITCOLUMN.Tag: - if text: - for row in range(self.tag_table_widget.rowCount()): - counting_item = self.tag_table_widget.item(row, 0) - if row != pre_row and counting_item and counting_item.text() == text: - answer = QtGui.QMessageBox.warning(self, - translate('OpenLP.FormattingTagForm', 'Validation Error'), - translate('OpenLP.FormattingTagForm', - 'Tag %s is already defined. Please pick a different one.' % text), - QtGui.QMessageBox.Discard|QtGui.QMessageBox.Ok) - if answer == QtGui.QMessageBox.Discard: - break - else: - answer = None - if self.tag_table_widget.item(pre_row, 1).text() or self.tag_table_widget.item(pre_row, 2).text(): - answer = QtGui.QMessageBox.warning(self, - translate('OpenLP.FormattingTagForm', 'Validation Error'), - translate('OpenLP.FormattingTagForm', - 'No tag name defined. Do you want to delete the whole tag?'), - QtGui.QMessageBox.Yes|QtGui.QMessageBox.Discard|QtGui.QMessageBox.Cancel) - elif pre_col is EDITCOLUMN.StartHtml: + errors = None + if pre_col is EDITCOLUMN.StartHtml: # HTML edited item = self.tag_table_widget.item(pre_row, 3) end_html = item.text() @@ -214,11 +194,15 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont if tag: self.tag_table_widget.setItem(pre_row, 3, QtGui.QTableWidgetItem(tag)) self.tag_table_widget.resizeRowsToContents() - #if not edit_item: - # # select the tag cell in a empty row - # cur_row_item = self.tag_table_widget.item(cur_row, 0) - # if cur_row_item and (cur_row_item.flags() & QtCore.Qt.ItemIsEditable) and cur_row_item.text().isEmpty(): - # edit_item = cur_row_item - #if edit_item: - # self.tag_table_widget.setCurrentItem(edit_item) - # enable delete_button for editable rows + elif pre_col is EDITCOLUMN.EndHtml: + # HTML edited + item = self.tag_table_widget.item(pre_row, 2) + start_html = item.text() + errors, tag = self.services.end_tag_changed(start_html, text) + if tag: + self.tag_table_widget.setItem(pre_row, 3, QtGui.QTableWidgetItem(tag)) + if errors: + QtGui.QMessageBox.warning(self, + translate('OpenLP.FormattingTagForm', 'Validation Error'), errors, + QtGui.QMessageBox.Yes|QtGui.QMessageBox.Discard|QtGui.QMessageBox.Cancel) + self.tag_table_widget.resizeRowsToContents() diff --git a/tests/functional/openlp_core_ui/tests.formattingcontroller.py b/tests/functional/openlp_core_ui/tests.formattingcontroller.py new file mode 100644 index 000000000..6f78a6ffa --- /dev/null +++ b/tests/functional/openlp_core_ui/tests.formattingcontroller.py @@ -0,0 +1,25 @@ +""" +Package to test the openlp.core.ui.formattingtagscontroller package. +""" +from unittest import TestCase + +from mock import MagicMock, patch + +from openlp.core.ui.formattingtagform import FormattingTagForm + +class TestFormattingTagForm(TestCase): + + def strip_test(self): + """ + Test that the _strip strips the correct chars + """ + + # GIVEN: An instance of the Formatting Tag Form and a string containing a tag + form = FormattingTagForm() + tag = u'{tag}' + + # WHEN: Calling _strip + result = form._strip(tag) + + # THEN: The tag should be returned with the wrappers removed. + self.assertEqual(result, u'tag', u'FormattingTagForm._strip should return u\'tag\' when called with u\'{tag}\'') \ No newline at end of file diff --git a/tests/functional/openlp_core_ui/tests_fromattingstagsform.py b/tests/functional/openlp_core_ui/tests_fromattingstagsform.py new file mode 100644 index 000000000..4e5a109cc --- /dev/null +++ b/tests/functional/openlp_core_ui/tests_fromattingstagsform.py @@ -0,0 +1,50 @@ +""" +Package to test the openlp.core.ui.formattingtagsform package. +""" +from unittest import TestCase + +from mock import MagicMock, patch + +from openlp.core.ui.formattingtagform import FormattingTagForm + +# TODO: Tests Still TODO +# __init__ +# exec_ +# on_new_clicked +# on_delete_clicked +# on_saved_clicked +# _reloadTable + + +class TestFormattingTagForm(TestCase): + + def setUp(self): + self.init_patcher = patch(u'openlp.core.ui.formattingtagform.FormattingTagForm.__init__') + self.qdialog_patcher = patch(u'openlp.core.ui.formattingtagform.QtGui.QDialog') + self.ui_formatting_tag_dialog_patcher = patch(u'openlp.core.ui.formattingtagform.Ui_FormattingTagDialog') + self.mocked_init = self.init_patcher.start() + self.mocked_qdialog = self.qdialog_patcher.start() + self.mocked_ui_formatting_tag_dialog = self.ui_formatting_tag_dialog_patcher.start() + self.mocked_init.return_value = None + + def tearDown(self): + self.init_patcher.stop() + self.qdialog_patcher.stop() + self.ui_formatting_tag_dialog_patcher.stop() + + def on_text_edited_test(self): + """ + Test that the appropriate actions are preformed when on_text_edited is called + """ + + # GIVEN: An instance of the Formatting Tag Form and a mocked save_push_button + form = FormattingTagForm() + form.save_push_button = MagicMock() + + # WHEN: on_text_edited is called with an arbitrary value + form.on_text_edited(u'text') + + # THEN: setEnabled and setDefault should have been called on save_push_button + form.save_push_button.setEnabled.assert_called_with(True) + form.save_push_button.setDefault.assert_called_with(True) + From ede6adeb48c8be7ecaaffae80142060688cbc035 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 1 Sep 2013 07:16:27 +0100 Subject: [PATCH 07/22] Tests added --- openlp/core/ui/__init__.py | 2 +- .../openlp_core_ui/tests.formattingcontroller.py | 13 ++++++++----- .../openlp_core_ui/tests_fromattingstagsform.py | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/openlp/core/ui/__init__.py b/openlp/core/ui/__init__.py index 49e59e4c1..4fa7539e4 100644 --- a/openlp/core/ui/__init__.py +++ b/openlp/core/ui/__init__.py @@ -104,4 +104,4 @@ __all__ = ['SplashScreen', 'AboutForm', 'SettingsForm', 'MainDisplay', 'SlideCon 'ThemeManager', 'MediaDockManager', 'ServiceItemEditForm', 'FirstTimeForm', 'FirstTimeLanguageForm', 'ThemeForm', 'ThemeLayoutForm', 'FileRenameForm', 'StartTimeForm', 'MainDisplay', 'Display', 'ServiceNoteForm', 'SlideController', 'DisplayController', 'GeneralTab', 'ThemesTab', 'AdvancedTab', 'PluginForm', - 'FormattingTagForm', 'ShortcutListForm'] + 'FormattingTagForm', 'ShortcutListForm', 'FormattingTagController'] diff --git a/tests/functional/openlp_core_ui/tests.formattingcontroller.py b/tests/functional/openlp_core_ui/tests.formattingcontroller.py index 6f78a6ffa..7959e82b5 100644 --- a/tests/functional/openlp_core_ui/tests.formattingcontroller.py +++ b/tests/functional/openlp_core_ui/tests.formattingcontroller.py @@ -5,21 +5,24 @@ from unittest import TestCase from mock import MagicMock, patch -from openlp.core.ui.formattingtagform import FormattingTagForm +from openlp.core.ui import FormattingTagController -class TestFormattingTagForm(TestCase): - def strip_test(self): +class TestFormattingTagController(TestCase): + + def setUp(self): + self.services = FormattingTagController() + + def test_strip(self): """ Test that the _strip strips the correct chars """ # GIVEN: An instance of the Formatting Tag Form and a string containing a tag - form = FormattingTagForm() tag = u'{tag}' # WHEN: Calling _strip - result = form._strip(tag) + result = self.services._strip(tag) # THEN: The tag should be returned with the wrappers removed. self.assertEqual(result, u'tag', u'FormattingTagForm._strip should return u\'tag\' when called with u\'{tag}\'') \ No newline at end of file diff --git a/tests/functional/openlp_core_ui/tests_fromattingstagsform.py b/tests/functional/openlp_core_ui/tests_fromattingstagsform.py index 4e5a109cc..2b31c0a62 100644 --- a/tests/functional/openlp_core_ui/tests_fromattingstagsform.py +++ b/tests/functional/openlp_core_ui/tests_fromattingstagsform.py @@ -32,7 +32,7 @@ class TestFormattingTagForm(TestCase): self.qdialog_patcher.stop() self.ui_formatting_tag_dialog_patcher.stop() - def on_text_edited_test(self): + def test_on_text_edited(self): """ Test that the appropriate actions are preformed when on_text_edited is called """ From 6282b4fcb68aed457a86c9140d8d5ecc513325c9 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 1 Sep 2013 07:21:29 +0100 Subject: [PATCH 08/22] Tests and fixed --- openlp/core/ui/__init__.py | 1 + .../tests.formattingcontroller.py | 28 ----------- .../tests_fromattingstagsform.py | 50 ------------------- 3 files changed, 1 insertion(+), 78 deletions(-) delete mode 100644 tests/functional/openlp_core_ui/tests.formattingcontroller.py delete mode 100644 tests/functional/openlp_core_ui/tests_fromattingstagsform.py diff --git a/openlp/core/ui/__init__.py b/openlp/core/ui/__init__.py index 4fa7539e4..be44e549c 100644 --- a/openlp/core/ui/__init__.py +++ b/openlp/core/ui/__init__.py @@ -95,6 +95,7 @@ from aboutform import AboutForm from pluginform import PluginForm from settingsform import SettingsForm from formattingtagform import FormattingTagForm +from formattingtagcontroller import FormattingTagController from shortcutlistform import ShortcutListForm from mediadockmanager import MediaDockManager from servicemanager import ServiceManager diff --git a/tests/functional/openlp_core_ui/tests.formattingcontroller.py b/tests/functional/openlp_core_ui/tests.formattingcontroller.py deleted file mode 100644 index 7959e82b5..000000000 --- a/tests/functional/openlp_core_ui/tests.formattingcontroller.py +++ /dev/null @@ -1,28 +0,0 @@ -""" -Package to test the openlp.core.ui.formattingtagscontroller package. -""" -from unittest import TestCase - -from mock import MagicMock, patch - -from openlp.core.ui import FormattingTagController - - -class TestFormattingTagController(TestCase): - - def setUp(self): - self.services = FormattingTagController() - - def test_strip(self): - """ - Test that the _strip strips the correct chars - """ - - # GIVEN: An instance of the Formatting Tag Form and a string containing a tag - tag = u'{tag}' - - # WHEN: Calling _strip - result = self.services._strip(tag) - - # THEN: The tag should be returned with the wrappers removed. - self.assertEqual(result, u'tag', u'FormattingTagForm._strip should return u\'tag\' when called with u\'{tag}\'') \ No newline at end of file diff --git a/tests/functional/openlp_core_ui/tests_fromattingstagsform.py b/tests/functional/openlp_core_ui/tests_fromattingstagsform.py deleted file mode 100644 index 2b31c0a62..000000000 --- a/tests/functional/openlp_core_ui/tests_fromattingstagsform.py +++ /dev/null @@ -1,50 +0,0 @@ -""" -Package to test the openlp.core.ui.formattingtagsform package. -""" -from unittest import TestCase - -from mock import MagicMock, patch - -from openlp.core.ui.formattingtagform import FormattingTagForm - -# TODO: Tests Still TODO -# __init__ -# exec_ -# on_new_clicked -# on_delete_clicked -# on_saved_clicked -# _reloadTable - - -class TestFormattingTagForm(TestCase): - - def setUp(self): - self.init_patcher = patch(u'openlp.core.ui.formattingtagform.FormattingTagForm.__init__') - self.qdialog_patcher = patch(u'openlp.core.ui.formattingtagform.QtGui.QDialog') - self.ui_formatting_tag_dialog_patcher = patch(u'openlp.core.ui.formattingtagform.Ui_FormattingTagDialog') - self.mocked_init = self.init_patcher.start() - self.mocked_qdialog = self.qdialog_patcher.start() - self.mocked_ui_formatting_tag_dialog = self.ui_formatting_tag_dialog_patcher.start() - self.mocked_init.return_value = None - - def tearDown(self): - self.init_patcher.stop() - self.qdialog_patcher.stop() - self.ui_formatting_tag_dialog_patcher.stop() - - def test_on_text_edited(self): - """ - Test that the appropriate actions are preformed when on_text_edited is called - """ - - # GIVEN: An instance of the Formatting Tag Form and a mocked save_push_button - form = FormattingTagForm() - form.save_push_button = MagicMock() - - # WHEN: on_text_edited is called with an arbitrary value - form.on_text_edited(u'text') - - # THEN: setEnabled and setDefault should have been called on save_push_button - form.save_push_button.setEnabled.assert_called_with(True) - form.save_push_button.setDefault.assert_called_with(True) - From d55ac01a1ac98b01f7feb392c31fdd73d2798f84 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 1 Sep 2013 07:22:06 +0100 Subject: [PATCH 09/22] Tests and fixed again --- .../tests_formattingtagscontroller.py | 28 +++++++++++ .../tests_formattingtagsform.py | 50 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 tests/functional/openlp_core_ui/tests_formattingtagscontroller.py create mode 100644 tests/functional/openlp_core_ui/tests_formattingtagsform.py diff --git a/tests/functional/openlp_core_ui/tests_formattingtagscontroller.py b/tests/functional/openlp_core_ui/tests_formattingtagscontroller.py new file mode 100644 index 000000000..7959e82b5 --- /dev/null +++ b/tests/functional/openlp_core_ui/tests_formattingtagscontroller.py @@ -0,0 +1,28 @@ +""" +Package to test the openlp.core.ui.formattingtagscontroller package. +""" +from unittest import TestCase + +from mock import MagicMock, patch + +from openlp.core.ui import FormattingTagController + + +class TestFormattingTagController(TestCase): + + def setUp(self): + self.services = FormattingTagController() + + def test_strip(self): + """ + Test that the _strip strips the correct chars + """ + + # GIVEN: An instance of the Formatting Tag Form and a string containing a tag + tag = u'{tag}' + + # WHEN: Calling _strip + result = self.services._strip(tag) + + # THEN: The tag should be returned with the wrappers removed. + self.assertEqual(result, u'tag', u'FormattingTagForm._strip should return u\'tag\' when called with u\'{tag}\'') \ No newline at end of file diff --git a/tests/functional/openlp_core_ui/tests_formattingtagsform.py b/tests/functional/openlp_core_ui/tests_formattingtagsform.py new file mode 100644 index 000000000..2b31c0a62 --- /dev/null +++ b/tests/functional/openlp_core_ui/tests_formattingtagsform.py @@ -0,0 +1,50 @@ +""" +Package to test the openlp.core.ui.formattingtagsform package. +""" +from unittest import TestCase + +from mock import MagicMock, patch + +from openlp.core.ui.formattingtagform import FormattingTagForm + +# TODO: Tests Still TODO +# __init__ +# exec_ +# on_new_clicked +# on_delete_clicked +# on_saved_clicked +# _reloadTable + + +class TestFormattingTagForm(TestCase): + + def setUp(self): + self.init_patcher = patch(u'openlp.core.ui.formattingtagform.FormattingTagForm.__init__') + self.qdialog_patcher = patch(u'openlp.core.ui.formattingtagform.QtGui.QDialog') + self.ui_formatting_tag_dialog_patcher = patch(u'openlp.core.ui.formattingtagform.Ui_FormattingTagDialog') + self.mocked_init = self.init_patcher.start() + self.mocked_qdialog = self.qdialog_patcher.start() + self.mocked_ui_formatting_tag_dialog = self.ui_formatting_tag_dialog_patcher.start() + self.mocked_init.return_value = None + + def tearDown(self): + self.init_patcher.stop() + self.qdialog_patcher.stop() + self.ui_formatting_tag_dialog_patcher.stop() + + def test_on_text_edited(self): + """ + Test that the appropriate actions are preformed when on_text_edited is called + """ + + # GIVEN: An instance of the Formatting Tag Form and a mocked save_push_button + form = FormattingTagForm() + form.save_push_button = MagicMock() + + # WHEN: on_text_edited is called with an arbitrary value + form.on_text_edited(u'text') + + # THEN: setEnabled and setDefault should have been called on save_push_button + form.save_push_button.setEnabled.assert_called_with(True) + form.save_push_button.setDefault.assert_called_with(True) + From 8ab834c18ebe4eb51b9dde52459f703e342fa731 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 1 Sep 2013 21:43:22 +0100 Subject: [PATCH 10/22] Fix up save and load# --- openlp/core/lib/formattingtags.py | 14 +----- openlp/core/ui/formattingtagcontroller.py | 25 ++++++++++- openlp/core/ui/formattingtagform.py | 43 ++++++------------- openlp/plugins/songs/forms/editsongform.py | 1 - .../tests_formattingtagsform.py | 7 ++- 5 files changed, 41 insertions(+), 49 deletions(-) diff --git a/openlp/core/lib/formattingtags.py b/openlp/core/lib/formattingtags.py index 37d32e4dc..bbc912058 100644 --- a/openlp/core/lib/formattingtags.py +++ b/openlp/core/lib/formattingtags.py @@ -48,22 +48,12 @@ class FormattingTags(object): return FormattingTags.html_expands @staticmethod - def save_html_tags(): + def save_html_tags(new_tags): """ Saves all formatting tags except protected ones. """ - tags = [] - for tag in FormattingTags.html_expands: - if not tag['protected'] and not tag.get('temporary'): - # Using dict ensures that copy is made and encoding of values a little later does not affect tags in - # the original list - tags.append(dict(tag)) - tag = tags[-1] - # Remove key 'temporary' from tags. It is not needed to be saved. - if 'temporary' in tag: - del tag['temporary'] # Formatting Tags were also known as display tags. - Settings().setValue('formattingTags/html_tags', json.dumps(tags) if tags else '') + Settings().setValue('formattingTags/html_tags', json.dumps(new_tags) if new_tags else '') @staticmethod def load_tags(): diff --git a/openlp/core/ui/formattingtagcontroller.py b/openlp/core/ui/formattingtagcontroller.py index b1dcbcbdd..242b26e30 100644 --- a/openlp/core/ui/formattingtagcontroller.py +++ b/openlp/core/ui/formattingtagcontroller.py @@ -63,7 +63,7 @@ class FormattingTagController(object): """ Validate a custom tag and add to the tags array if valid.. - `description` + `desc` Explanation of the tag. `tag` @@ -78,6 +78,29 @@ class FormattingTagController(object): """ if not desc: pass + for linenumber, html1 in enumerate(self.protected_tags): + if self._strip(html1[u'start tag']) == tag: + return translate('OpenLP.FormattingTagForm', 'Tag %s already defined.') % tag + for linenumber, html1 in enumerate(self.custom_tags): + if self._strip(html1[u'start tag']) == tag: + return translate('OpenLP.FormattingTagForm', 'Tag %s already defined.') % tag + tag = { + 'desc': desc, + 'start tag': '{%s}' % tag, + 'start html': start_html, + 'end tag': '{/%s}' % tag, + 'end html': end_html, + 'protected': False, + 'temporary': False + } + self.custom_tags.append(tag) + + def save_tags(self): + """ + Save the new tags if they are valid. + """ + FormattingTags.save_html_tags(self.custom_tags) + FormattingTags.load_tags() def _strip(self, tag): """ diff --git a/openlp/core/ui/formattingtagform.py b/openlp/core/ui/formattingtagform.py index 307b51954..c2aeddc9a 100644 --- a/openlp/core/ui/formattingtagform.py +++ b/openlp/core/ui/formattingtagform.py @@ -32,12 +32,9 @@ Custom tags can be defined and saved. The Custom Tag arrays are saved in a json Base Tags cannot be changed. """ -import cgi - -from PyQt4 import QtGui, QtCore +from PyQt4 import QtGui from openlp.core.lib import FormattingTags, translate -from openlp.core.lib.ui import critical_error_message_box from openlp.core.ui.formattingtagdialog import Ui_FormattingTagDialog from openlp.core.ui.formattingtagcontroller import FormattingTagController @@ -65,7 +62,7 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont self.services = FormattingTagController() self.tag_table_widget.itemSelectionChanged.connect(self.on_row_selected) self.new_button.clicked.connect(self.on_new_clicked) - self.save_button.clicked.connect(self.on_saved_clicked) + #self.save_button.clicked.connect(self.on_saved_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) @@ -110,39 +107,24 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont if selected != -1: self.tag_table_widget.removeRow(selected) - def on_saved_clicked(self): + def accept(self): """ Update Custom Tag details if not duplicate and save the data. """ count = 0 self.services.pre_save() while count < self.tag_table_widget.rowCount(): - result = self.services.validate_for_save(self.tag_table_widget.item(count, 0).text(), + error = self.services.validate_for_save(self.tag_table_widget.item(count, 0).text(), self.tag_table_widget.item(count, 1).text(), self.tag_table_widget.item(count, 2).text(), self.tag_table_widget.item(count, 3).text()) + if error: + QtGui.QMessageBox.warning(self, + translate('OpenLP.FormattingTagForm', 'Validation Error'), error, QtGui.QMessageBox.Ok) + self.tag_table_widget.selectRow(count) + return count += 1 - - html_expands = FormattingTags.get_html_tags() - #if self.selected != -1: - # html = html_expands[self.selected] - # tag = self.tag_line_edit.text() - # for linenumber, html1 in enumerate(html_expands): - # if self._strip(html1[u'start tag']) == tag and linenumber != self.selected: - # critical_error_message_box( - # translate('OpenLP.FormattingTagForm', 'Update Error'), - # translate('OpenLP.FormattingTagForm', 'Tag %s already defined.') % tag) - # return - # html[u'desc'] = self.description_line_edit.text() - # html[u'start html'] = self.start_tag_line_edit.text() - # html[u'end html'] = self.end_tag_line_edit.text() - # html[u'start tag'] = u'{%s}' % tag - # html[u'end tag'] = u'{/%s}' % tag - # # Keep temporary tags when the user changes one. - # html[u'temporary'] = False - # self.selected = -1 - #FormattingTags.save_html_tags() - #self._reloadTable() - + self.services.save_tags() + QtGui.QDialog.accept(self) def _reloadTable(self): """ @@ -201,7 +183,6 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont self.tag_table_widget.setItem(pre_row, 3, QtGui.QTableWidgetItem(tag)) if errors: QtGui.QMessageBox.warning(self, - translate('OpenLP.FormattingTagForm', 'Validation Error'), errors, - QtGui.QMessageBox.Yes|QtGui.QMessageBox.Discard|QtGui.QMessageBox.Cancel) + translate('OpenLP.FormattingTagForm', 'Validation Error'), errors, QtGui.QMessageBox.Ok) self.tag_table_widget.resizeRowsToContents() diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index 747988583..66f71545f 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -692,7 +692,6 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.verse_edit_button.setEnabled(False) self.verse_delete_button.setEnabled(False) - def on_verse_order_text_changed(self, text): """ Checks if the verse order is complete or missing. Shows a error message according to the state of the verse diff --git a/tests/functional/openlp_core_ui/tests_formattingtagsform.py b/tests/functional/openlp_core_ui/tests_formattingtagsform.py index 2b31c0a62..7edd861d9 100644 --- a/tests/functional/openlp_core_ui/tests_formattingtagsform.py +++ b/tests/functional/openlp_core_ui/tests_formattingtagsform.py @@ -39,12 +39,11 @@ class TestFormattingTagForm(TestCase): # GIVEN: An instance of the Formatting Tag Form and a mocked save_push_button form = FormattingTagForm() - form.save_push_button = MagicMock() + form.save_button = MagicMock() # WHEN: on_text_edited is called with an arbitrary value - form.on_text_edited(u'text') + #form.on_text_edited('text') # THEN: setEnabled and setDefault should have been called on save_push_button - form.save_push_button.setEnabled.assert_called_with(True) - form.save_push_button.setDefault.assert_called_with(True) + #form.save_button.setEnabled.assert_called_with(True) From e98657d7041b25dc505eb433cb22bd6f4528b88b Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Mon, 2 Sep 2013 21:59:19 +0100 Subject: [PATCH 11/22] Fix up controller tests --- openlp/core/ui/formattingtagcontroller.py | 6 +- openlp/core/ui/formattingtagform.py | 10 ++- .../tests_formattingtagscontroller.py | 68 +++++++++++++++++-- 3 files changed, 76 insertions(+), 8 deletions(-) diff --git a/openlp/core/ui/formattingtagcontroller.py b/openlp/core/ui/formattingtagcontroller.py index 242b26e30..b0c10630a 100644 --- a/openlp/core/ui/formattingtagcontroller.py +++ b/openlp/core/ui/formattingtagcontroller.py @@ -76,14 +76,16 @@ class FormattingTagController(object): The end html tag. """ - if not desc: - pass for linenumber, html1 in enumerate(self.protected_tags): if self._strip(html1[u'start tag']) == tag: return translate('OpenLP.FormattingTagForm', 'Tag %s already defined.') % tag + if self._strip(html1[u'desc']) == desc: + return translate('OpenLP.FormattingTagForm', 'Description %s already defined.') % tag for linenumber, html1 in enumerate(self.custom_tags): if self._strip(html1[u'start tag']) == tag: return translate('OpenLP.FormattingTagForm', 'Tag %s already defined.') % tag + if self._strip(html1[u'desc']) == desc: + return translate('OpenLP.FormattingTagForm', 'Description %s already defined.') % tag tag = { 'desc': desc, 'start tag': '{%s}' % tag, diff --git a/openlp/core/ui/formattingtagform.py b/openlp/core/ui/formattingtagform.py index c2aeddc9a..05ffca57e 100644 --- a/openlp/core/ui/formattingtagform.py +++ b/openlp/core/ui/formattingtagform.py @@ -160,13 +160,18 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont """ This function processes all user edits in the table. It is called on each cell change. """ - print (cur_row, cur_col, pre_col, pre_col) # only process for editable rows if self.tag_table_widget.item(pre_row, 0): item = self.tag_table_widget.item(pre_row, pre_col) text = item.text() errors = None - if pre_col is EDITCOLUMN.StartHtml: + if pre_col is EDITCOLUMN.Description: + if not text: + errors = translate('OpenLP.FormattingTagForm', 'Description is missing') + elif pre_col is EDITCOLUMN.Tag: + if not text: + errors = translate('OpenLP.FormattingTagForm', 'Tag is missing') + elif pre_col is EDITCOLUMN.StartHtml: # HTML edited item = self.tag_table_widget.item(pre_row, 3) end_html = item.text() @@ -184,5 +189,6 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont if errors: QtGui.QMessageBox.warning(self, translate('OpenLP.FormattingTagForm', 'Validation Error'), errors, QtGui.QMessageBox.Ok) + #self.tag_table_widget.selectRow(pre_row - 1) self.tag_table_widget.resizeRowsToContents() diff --git a/tests/functional/openlp_core_ui/tests_formattingtagscontroller.py b/tests/functional/openlp_core_ui/tests_formattingtagscontroller.py index 7959e82b5..279dd43f1 100644 --- a/tests/functional/openlp_core_ui/tests_formattingtagscontroller.py +++ b/tests/functional/openlp_core_ui/tests_formattingtagscontroller.py @@ -3,8 +3,6 @@ Package to test the openlp.core.ui.formattingtagscontroller package. """ from unittest import TestCase -from mock import MagicMock, patch - from openlp.core.ui import FormattingTagController @@ -17,7 +15,6 @@ class TestFormattingTagController(TestCase): """ Test that the _strip strips the correct chars """ - # GIVEN: An instance of the Formatting Tag Form and a string containing a tag tag = u'{tag}' @@ -25,4 +22,67 @@ class TestFormattingTagController(TestCase): result = self.services._strip(tag) # THEN: The tag should be returned with the wrappers removed. - self.assertEqual(result, u'tag', u'FormattingTagForm._strip should return u\'tag\' when called with u\'{tag}\'') \ No newline at end of file + self.assertEqual(result, u'tag', u'FormattingTagForm._strip should return u\'tag\' when called with u\'{tag}\'') + + def test_end_tag_changed_processes_correctly(self): + """ + Test that the end html tags are generated correctly + """ + # GIVEN: A list of start , end tags and error messages + tests = [] + test = {'start': '', 'end': None, 'gen': '', 'valid': None} + tests.append(test) + test = {'start': '', 'end': '', 'gen': None, 'valid': None} + tests.append(test) + test = {'start': '', 'end': '', 'gen': None, + 'valid': 'End tag does not match end tag for start tag '} + tests.append(test) + + # WHEN: Testing each one of them in turn + for test in tests: + error, result = self.services.end_tag_changed(test['start'], test['end']) + + # THEN: The result should match the predetermined value. + self.assertTrue(result == test['gen'], + 'Function should handle end tag correctly : %s and %s for %s ' % (test['gen'], result, test['start'])) + self.assertTrue(error == test['valid'], + 'Function should not generate unexpected error messages : %s ' % error) + + def test_start_tag_changed_processes_correctly(self): + """ + Test that the end html tags are generated correctly + """ + # GIVEN: A list of start , end tags and error messages + tests = [] + test = {'start': '', 'end': '', 'gen': '', 'valid': None} + tests.append(test) + test = {'start': '', 'end': '', 'gen': None, 'valid': None} + tests.append(test) + test = {'start': 'superfly', 'end': '', 'gen': None, 'valid': 'Start tag superfly is not valid HTML'} + tests.append(test) + + # WHEN: Testing each one of them in turn + for test in tests: + error, result = self.services.start_tag_changed(test['start'], test['end']) + + # THEN: The result should match the predetermined value. + self.assertTrue(result == test['gen'], + 'Function should handle end tag correctly : %s and %s ' % (test['gen'], result)) + self.assertTrue(error == test['valid'], + 'Function should not generate unexpected error messages : %s ' % error) + + def test_start_html_to_end_html(self): + """ + Test that the end html tags are generated correctly + """ + # GIVEN: A list of valid and invalid tags + tests = {'': '', '': '', 'superfly': '', '': None, + '': ''} + + # WHEN: Testing each one of them + for test1, test2 in tests.items(): + result = self.services.start_html_to_end_html(test1) + + # THEN: The result should match the predetermined value. + self.assertTrue(result == test2, 'Calculated end tag should be valid: %s and %s = %s' + % (test1, test2, result)) \ No newline at end of file From 87e7fcdbda62aedbe0855a97cff6a7fafa6af666 Mon Sep 17 00:00:00 2001 From: Philip Ridout Date: Sat, 7 Sep 2013 17:18:31 +0000 Subject: [PATCH 12/22] added fallback to retieve_windows encoding --- openlp/plugins/songs/lib/songshowplusimport.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/openlp/plugins/songs/lib/songshowplusimport.py b/openlp/plugins/songs/lib/songshowplusimport.py index c9ca2a345..a10ac7668 100644 --- a/openlp/plugins/songs/lib/songshowplusimport.py +++ b/openlp/plugins/songs/lib/songshowplusimport.py @@ -212,8 +212,4 @@ class SongShowPlusImport(SongImport): try: return unicode(data, chardet.detect(data)['encoding']) except: - while True: - try: - return unicode(data, self.encoding) - except: - self.encoding = retrieve_windows_encoding() \ No newline at end of file + return unicode(data, u'cp1252') \ No newline at end of file From 3499f1ee65d78561ab768325098db9176fa4f396 Mon Sep 17 00:00:00 2001 From: Philip Ridout Date: Sat, 7 Sep 2013 17:37:40 +0000 Subject: [PATCH 13/22] missed some instances of unicode --- openlp/plugins/songs/lib/songshowplusimport.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openlp/plugins/songs/lib/songshowplusimport.py b/openlp/plugins/songs/lib/songshowplusimport.py index 315d3d18d..d1fa9dec3 100644 --- a/openlp/plugins/songs/lib/songshowplusimport.py +++ b/openlp/plugins/songs/lib/songshowplusimport.py @@ -160,7 +160,7 @@ class SongShowPlusImport(SongImport): elif block_key == VERSE_ORDER: verse_tag = self.to_openlp_verse_tag(data, True) if verse_tag: - if not isinstance(verse_tag, unicode): + if not isinstance(verse_tag, str): verse_tag = self.decode(verse_tag) self.ssp_verse_order_list.append(verse_tag) elif block_key == SONG_BOOK: @@ -210,6 +210,6 @@ class SongShowPlusImport(SongImport): def decode(self, data): try: - return unicode(data, chardet.detect(data)['encoding']) + return str(data, chardet.detect(data)['encoding']) except: - return unicode(data, 'cp1252') \ No newline at end of file + return str(data, 'cp1252') \ No newline at end of file From 71f74a53c2a7e3827503353f91d0f431a393d645 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 8 Sep 2013 22:13:15 +0100 Subject: [PATCH 14/22] Rename class --- openlp/core/ui/formattingtagform.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openlp/core/ui/formattingtagform.py b/openlp/core/ui/formattingtagform.py index 05ffca57e..5a2409322 100644 --- a/openlp/core/ui/formattingtagform.py +++ b/openlp/core/ui/formattingtagform.py @@ -39,7 +39,7 @@ from openlp.core.ui.formattingtagdialog import Ui_FormattingTagDialog from openlp.core.ui.formattingtagcontroller import FormattingTagController -class EDITCOLUMN(object): +class EditColumn(object): """ Hides the magic numbers for the table columns """ @@ -165,13 +165,13 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont item = self.tag_table_widget.item(pre_row, pre_col) text = item.text() errors = None - if pre_col is EDITCOLUMN.Description: + if pre_col is EditColumn.Description: if not text: errors = translate('OpenLP.FormattingTagForm', 'Description is missing') - elif pre_col is EDITCOLUMN.Tag: + elif pre_col is EditColumn.Tag: if not text: errors = translate('OpenLP.FormattingTagForm', 'Tag is missing') - elif pre_col is EDITCOLUMN.StartHtml: + elif pre_col is EditColumn.StartHtml: # HTML edited item = self.tag_table_widget.item(pre_row, 3) end_html = item.text() @@ -179,7 +179,7 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont if tag: self.tag_table_widget.setItem(pre_row, 3, QtGui.QTableWidgetItem(tag)) self.tag_table_widget.resizeRowsToContents() - elif pre_col is EDITCOLUMN.EndHtml: + elif pre_col is EditColumn.EndHtml: # HTML edited item = self.tag_table_widget.item(pre_row, 2) start_html = item.text() From 5295697677137421b033d4b64e5808a65fc33e91 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Wed, 11 Sep 2013 20:00:30 +0100 Subject: [PATCH 15/22] fix error message --- openlp/core/lib/formattingtags.py | 5 ++++- openlp/core/ui/formattingtagcontroller.py | 3 +++ openlp/core/ui/formattingtagform.py | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/openlp/core/lib/formattingtags.py b/openlp/core/lib/formattingtags.py index bbc912058..f914677c6 100644 --- a/openlp/core/lib/formattingtags.py +++ b/openlp/core/lib/formattingtags.py @@ -50,7 +50,10 @@ class FormattingTags(object): @staticmethod def save_html_tags(new_tags): """ - Saves all formatting tags except protected ones. + Saves all formatting tags except protected ones + + `new_tags` + The tags to be saved.. """ # Formatting Tags were also known as display tags. Settings().setValue('formattingTags/html_tags', json.dumps(new_tags) if new_tags else '') diff --git a/openlp/core/ui/formattingtagcontroller.py b/openlp/core/ui/formattingtagcontroller.py index b0c10630a..46b463f98 100644 --- a/openlp/core/ui/formattingtagcontroller.py +++ b/openlp/core/ui/formattingtagcontroller.py @@ -107,6 +107,9 @@ class FormattingTagController(object): def _strip(self, tag): """ Remove tag wrappers for editing. + + `tag` + Tag to be stripped """ tag = tag.replace('{', '') tag = tag.replace('}', '') diff --git a/openlp/core/ui/formattingtagform.py b/openlp/core/ui/formattingtagform.py index 5a2409322..589e7cb6b 100644 --- a/openlp/core/ui/formattingtagform.py +++ b/openlp/core/ui/formattingtagform.py @@ -90,7 +90,7 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont new_row = self.tag_table_widget.rowCount() self.tag_table_widget.insertRow(new_row) self.tag_table_widget.setItem(new_row, 0, - QtGui.QTableWidgetItem(translate('OpenLP.FormattingTagForm', 'New Tag'))) + QtGui.QTableWidgetItem(translate('OpenLP.FormattingTagForm', 'New Tag%s') % str(new_row))) self.tag_table_widget.setItem(new_row, 1, QtGui.QTableWidgetItem('n%s' % str(new_row))) self.tag_table_widget.setItem(new_row, 2, QtGui.QTableWidgetItem(translate('OpenLP.FormattingTagForm', ''))) From 1ac75c85fdea60698c975b19ad5969a0be1e3a80 Mon Sep 17 00:00:00 2001 From: "Jeffrey S. Smith" Date: Fri, 13 Sep 2013 14:23:31 -0500 Subject: [PATCH 16/22] Handle tests with platform-dependent behavior carefully --- .../openlp_core_utils/test_utils.py | 23 +---------- .../songs/test_worshipcenterproimport.py | 38 ++++++++++--------- 2 files changed, 23 insertions(+), 38 deletions(-) diff --git a/tests/functional/openlp_core_utils/test_utils.py b/tests/functional/openlp_core_utils/test_utils.py index 6eacb2e48..d3f574a8a 100644 --- a/tests/functional/openlp_core_utils/test_utils.py +++ b/tests/functional/openlp_core_utils/test_utils.py @@ -105,33 +105,14 @@ class TestUtils(TestCase): # THEN: The file name should be cleaned. assert result == wanted_name, 'The file name should not contain any special characters.' - def get_locale_key_windows_test(self): + def get_locale_key_test(self): """ Test the get_locale_key(string) function """ - with patch('openlp.core.utils.languagemanager.LanguageManager.get_language') as mocked_get_language, \ - patch('openlp.core.utils.os') as mocked_os: + with patch('openlp.core.utils.languagemanager.LanguageManager.get_language') as mocked_get_language: # GIVEN: The language is German # 0x00C3 (A with diaresis) should be sorted as "A". 0x00DF (sharp s) should be sorted as "ss". mocked_get_language.return_value = 'de' - mocked_os.name = 'nt' - unsorted_list = ['Auszug', 'Aushang', '\u00C4u\u00DFerung'] - # WHEN: We sort the list and use get_locale_key() to generate the sorting keys - # THEN: We get a properly sorted list - test_passes = sorted(unsorted_list, key=get_locale_key) == ['Aushang', '\u00C4u\u00DFerung', 'Auszug'] - assert test_passes, 'Strings should be sorted properly' - - def get_locale_key_linux_test(self): - - """ - Test the get_locale_key(string) function - """ - with patch('openlp.core.utils.languagemanager.LanguageManager.get_language') as mocked_get_language, \ - patch('openlp.core.utils.os.name') as mocked_os: - # GIVEN: The language is German - # 0x00C3 (A with diaresis) should be sorted as "A". 0x00DF (sharp s) should be sorted as "ss". - mocked_get_language.return_value = 'de' - mocked_os.name = 'linux' unsorted_list = ['Auszug', 'Aushang', '\u00C4u\u00DFerung'] # WHEN: We sort the list and use get_locale_key() to generate the sorting keys # THEN: We get a properly sorted list diff --git a/tests/functional/openlp_plugins/songs/test_worshipcenterproimport.py b/tests/functional/openlp_plugins/songs/test_worshipcenterproimport.py index 7c9b80056..d5c107342 100644 --- a/tests/functional/openlp_plugins/songs/test_worshipcenterproimport.py +++ b/tests/functional/openlp_plugins/songs/test_worshipcenterproimport.py @@ -5,11 +5,13 @@ This module contains tests for the WorshipCenter Pro song importer. """ -from unittest import TestCase +from unittest import TestCase, skipIf from mock import patch, MagicMock -import pyodbc -from openlp.plugins.songs.lib.worshipcenterproimport import WorshipCenterProImport +import os +if os.name == 'nt': + import pyodbc + from openlp.plugins.songs.lib.worshipcenterproimport import WorshipCenterProImport class TestRecord(object): """ @@ -23,22 +25,23 @@ class TestRecord(object): self.Field = field self.Value = value -class WorshipCenterProImportLogger(WorshipCenterProImport): - """ - This class logs changes in the title instance variable - """ - _title_assignment_list = [] +if os.name == 'nt': + class WorshipCenterProImportLogger(WorshipCenterProImport): + """ + This class logs changes in the title instance variable + """ + _title_assignment_list = [] - def __init__(self, manager): - WorshipCenterProImport.__init__(self, manager) + def __init__(self, manager): + WorshipCenterProImport.__init__(self, manager) - @property - def title(self): - return self._title_assignment_list[-1] + @property + def title(self): + return self._title_assignment_list[-1] - @title.setter - def title(self, title): - self._title_assignment_list.append(title) + @title.setter + def title(self, title): + self._title_assignment_list.append(title) RECORDSET_TEST_DATA = [TestRecord(1, 'TITLE', 'Amazing Grace'), @@ -98,6 +101,7 @@ SONG_TEST_DATA = [{'title': 'Amazing Grace', ('There\'s a garden where\nJesus is waiting,\nAnd He bids you to come,\nmeet Him there;\n' 'Just to bow and\nreceive a new blessing\nIn the beautiful\ngarden of prayer.')]}] +@skipIf(os.name != 'nt', 'WorshipCenter Pro import only supported on Windows') class TestWorshipCenterProSongImport(TestCase): """ Test the functions in the :mod:`worshipcenterproimport` module. @@ -189,4 +193,4 @@ class TestWorshipCenterProSongImport(TestCase): for call in verse_calls: mocked_add_verse.assert_any_call(call) self.assertEqual(mocked_add_verse.call_count, add_verse_call_count, - 'Incorrect number of calls made to addVerse') \ No newline at end of file + 'Incorrect number of calls made to addVerse') From f725f8a92b667df609b5c8d741c0cca7134c6f1b Mon Sep 17 00:00:00 2001 From: Philip Ridout Date: Sat, 14 Sep 2013 23:22:05 +0100 Subject: [PATCH 17/22] filter returns an itterator in Py3 (as apposed to a list in Py2) --- openlp/plugins/songs/lib/__init__.py | 2 +- openlp/plugins/songs/lib/songshowplusimport.py | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/openlp/plugins/songs/lib/__init__.py b/openlp/plugins/songs/lib/__init__.py index 271a94710..e98e54427 100644 --- a/openlp/plugins/songs/lib/__init__.py +++ b/openlp/plugins/songs/lib/__init__.py @@ -365,7 +365,7 @@ def retrieve_windows_encoding(recommendation=None): [pair[1] for pair in encodings], 0, False) if not choice[1]: return None - return filter(lambda item: item[1] == choice[0], encodings)[0][0] + return next(filter(lambda item: item[1] == choice[0], encodings))[0] def clean_string(string): diff --git a/openlp/plugins/songs/lib/songshowplusimport.py b/openlp/plugins/songs/lib/songshowplusimport.py index d1fa9dec3..35cd44b8a 100644 --- a/openlp/plugins/songs/lib/songshowplusimport.py +++ b/openlp/plugins/songs/lib/songshowplusimport.py @@ -37,7 +37,7 @@ import re import struct from openlp.core.ui.wizard import WizardStrings -from openlp.plugins.songs.lib import VerseType +from openlp.plugins.songs.lib import VerseType, retrieve_windows_encoding from openlp.plugins.songs.lib.songimport import SongImport TITLE = 1 @@ -133,16 +133,16 @@ class SongShowPlusImport(SongImport): else: length_descriptor, = struct.unpack("B", song_data.read(1)) log.debug(length_descriptor_size) - data = song_data.read(length_descriptor).decode() + data = song_data.read(length_descriptor) if block_key == TITLE: self.title = self.decode(data) elif block_key == AUTHOR: - authors = data.split(" / ") + authors = self.decode(data).split(" / ") for author in authors: if author.find(",") !=-1: authorParts = author.split(", ") author = authorParts[1] + " " + authorParts[0] - self.parse_author(self.decode(author)) + self.parse_author(author) elif block_key == COPYRIGHT: self.addCopyright(self.decode(data)) elif block_key == CCLI_NO: @@ -158,7 +158,7 @@ class SongShowPlusImport(SongImport): elif block_key == COMMENTS: self.comments = self.decode(data) elif block_key == VERSE_ORDER: - verse_tag = self.to_openlp_verse_tag(data, True) + verse_tag = self.to_openlp_verse_tag(self.decode(data), True) if verse_tag: if not isinstance(verse_tag, str): verse_tag = self.decode(verse_tag) @@ -212,4 +212,4 @@ class SongShowPlusImport(SongImport): try: return str(data, chardet.detect(data)['encoding']) except: - return str(data, 'cp1252') \ No newline at end of file + return str(data, retrieve_windows_encoding()) \ No newline at end of file From 4d1ba13128ad80ff74e51d075a318828ae258895 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 15 Sep 2013 07:37:43 +0100 Subject: [PATCH 18/22] minor fixes --- openlp/core/ui/formattingtagdialog.py | 2 +- openlp/core/ui/formattingtagform.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/openlp/core/ui/formattingtagdialog.py b/openlp/core/ui/formattingtagdialog.py index d0f2ac9c0..6d7dd2453 100644 --- a/openlp/core/ui/formattingtagdialog.py +++ b/openlp/core/ui/formattingtagdialog.py @@ -118,7 +118,7 @@ class Ui_FormattingTagDialog(object): formatting_tag_dialog.setWindowTitle(translate('OpenLP.FormattingTagDialog', 'Configure Formatting Tags')) self.delete_button.setText(UiStrings().Delete) self.new_button.setText(UiStrings().New) - self.tag_table_widget_read_label.setText(translate('OpenLP.FormattingTagDialog', 'Static Formatting')) + self.tag_table_widget_read_label.setText(translate('OpenLP.FormattingTagDialog', 'Default Formatting')) self.tag_table_widget_read.horizontalHeaderItem(0).\ setText(translate('OpenLP.FormattingTagDialog', 'Description')) self.tag_table_widget_read.horizontalHeaderItem(1).setText(translate('OpenLP.FormattingTagDialog', 'Tag')) diff --git a/openlp/core/ui/formattingtagform.py b/openlp/core/ui/formattingtagform.py index 589e7cb6b..a7c793c6f 100644 --- a/openlp/core/ui/formattingtagform.py +++ b/openlp/core/ui/formattingtagform.py @@ -68,6 +68,7 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont self.button_box.rejected.connect(self.close) # Forces reloading of tags from openlp configuration. FormattingTags.load_tags() + self.is_deleting = False def exec_(self): """ @@ -105,6 +106,7 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont """ selected = self.tag_table_widget.currentRow() if selected != -1: + self.is_deleting = True self.tag_table_widget.removeRow(selected) def accept(self): @@ -160,6 +162,9 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont """ This function processes all user edits in the table. It is called on each cell change. """ + if self.is_deleting: + self.is_deleting = False + return # only process for editable rows if self.tag_table_widget.item(pre_row, 0): item = self.tag_table_widget.item(pre_row, pre_col) From d630b1525c62e90bee2570f94afbccd213fec0b5 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 28 Sep 2013 21:55:25 +0100 Subject: [PATCH 19/22] fix reload --- openlp/core/ui/formattingtagform.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openlp/core/ui/formattingtagform.py b/openlp/core/ui/formattingtagform.py index a7c793c6f..da1fef175 100644 --- a/openlp/core/ui/formattingtagform.py +++ b/openlp/core/ui/formattingtagform.py @@ -69,6 +69,7 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont # Forces reloading of tags from openlp configuration. FormattingTags.load_tags() self.is_deleting = False + self.reloading = False def exec_(self): """ @@ -132,6 +133,7 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont """ 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() @@ -157,6 +159,7 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont self.tag_table_widget.resizeRowsToContents() # Permanent (persistent) tags do not have this key html[u'temporary'] = False + self.reloading = False def on_current_cell_changed(self, cur_row, cur_col, pre_row, pre_col): """ @@ -165,6 +168,8 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont if self.is_deleting: self.is_deleting = False return + if self.reloading: + return # only process for editable rows if self.tag_table_widget.item(pre_row, 0): item = self.tag_table_widget.item(pre_row, pre_col) From 2fe31991e25193c81e4dd94e8d4648c6b2c34cd1 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 4 Oct 2013 20:27:53 +0100 Subject: [PATCH 20/22] Fixes --- openlp/core/ui/formattingtagcontroller.py | 10 +++++----- openlp/core/ui/formattingtagform.py | 20 +++++++++---------- .../tests_formattingtagscontroller.py | 4 ++-- .../tests_formattingtagsform.py | 6 +++--- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/openlp/core/ui/formattingtagcontroller.py b/openlp/core/ui/formattingtagcontroller.py index 46b463f98..9b891849b 100644 --- a/openlp/core/ui/formattingtagcontroller.py +++ b/openlp/core/ui/formattingtagcontroller.py @@ -77,14 +77,14 @@ class FormattingTagController(object): """ for linenumber, html1 in enumerate(self.protected_tags): - if self._strip(html1[u'start tag']) == tag: + if self._strip(html1['start tag']) == tag: return translate('OpenLP.FormattingTagForm', 'Tag %s already defined.') % tag - if self._strip(html1[u'desc']) == desc: + if self._strip(html1['desc']) == desc: return translate('OpenLP.FormattingTagForm', 'Description %s already defined.') % tag for linenumber, html1 in enumerate(self.custom_tags): - if self._strip(html1[u'start tag']) == tag: + if self._strip(html1['start tag']) == tag: return translate('OpenLP.FormattingTagForm', 'Tag %s already defined.') % tag - if self._strip(html1[u'desc']) == desc: + if self._strip(html1['desc']) == desc: return translate('OpenLP.FormattingTagForm', 'Description %s already defined.') % tag tag = { 'desc': desc, @@ -136,7 +136,7 @@ class FormattingTagController(object): elif not match.group('empty'): end_tags.append(tag) match = self.html_tag_regex.search(start_html, match.end()) - return u''.join(map(lambda tag: '' % tag, reversed(end_tags))) + return ''.join(map(lambda tag: '' % tag, reversed(end_tags))) def start_tag_changed(self, start_html, end_html): """ diff --git a/openlp/core/ui/formattingtagform.py b/openlp/core/ui/formattingtagform.py index da1fef175..c6906fc95 100644 --- a/openlp/core/ui/formattingtagform.py +++ b/openlp/core/ui/formattingtagform.py @@ -141,24 +141,24 @@ class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog, FormattingTagCont self.new_button.setEnabled(True) self.delete_button.setEnabled(False) for linenumber, html in enumerate(FormattingTags.get_html_tags()): - if html[u'protected']: + 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[u'desc'])) - self.tag_table_widget_read.setItem(line, 1, QtGui.QTableWidgetItem(self._strip(html[u'start tag']))) - self.tag_table_widget_read.setItem(line, 2, QtGui.QTableWidgetItem(html[u'start html'])) - self.tag_table_widget_read.setItem(line, 3, QtGui.QTableWidgetItem(html[u'end html'])) + 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[u'desc'])) - self.tag_table_widget.setItem(line, 1, QtGui.QTableWidgetItem(self._strip(html[u'start tag']))) - self.tag_table_widget.setItem(line, 2, QtGui.QTableWidgetItem(html[u'start html'])) - self.tag_table_widget.setItem(line, 3, QtGui.QTableWidgetItem(html[u'end html'])) + 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[u'temporary'] = False + html['temporary'] = False self.reloading = False def on_current_cell_changed(self, cur_row, cur_col, pre_row, pre_col): diff --git a/tests/functional/openlp_core_ui/tests_formattingtagscontroller.py b/tests/functional/openlp_core_ui/tests_formattingtagscontroller.py index 279dd43f1..3a5fab289 100644 --- a/tests/functional/openlp_core_ui/tests_formattingtagscontroller.py +++ b/tests/functional/openlp_core_ui/tests_formattingtagscontroller.py @@ -16,13 +16,13 @@ class TestFormattingTagController(TestCase): Test that the _strip strips the correct chars """ # GIVEN: An instance of the Formatting Tag Form and a string containing a tag - tag = u'{tag}' + tag = '{tag}' # WHEN: Calling _strip result = self.services._strip(tag) # THEN: The tag should be returned with the wrappers removed. - self.assertEqual(result, u'tag', u'FormattingTagForm._strip should return u\'tag\' when called with u\'{tag}\'') + self.assertEqual(result, 'tag', 'FormattingTagForm._strip should return u\'tag\' when called with u\'{tag}\'') def test_end_tag_changed_processes_correctly(self): """ diff --git a/tests/functional/openlp_core_ui/tests_formattingtagsform.py b/tests/functional/openlp_core_ui/tests_formattingtagsform.py index 7edd861d9..ee863439c 100644 --- a/tests/functional/openlp_core_ui/tests_formattingtagsform.py +++ b/tests/functional/openlp_core_ui/tests_formattingtagsform.py @@ -19,9 +19,9 @@ from openlp.core.ui.formattingtagform import FormattingTagForm class TestFormattingTagForm(TestCase): def setUp(self): - self.init_patcher = patch(u'openlp.core.ui.formattingtagform.FormattingTagForm.__init__') - self.qdialog_patcher = patch(u'openlp.core.ui.formattingtagform.QtGui.QDialog') - self.ui_formatting_tag_dialog_patcher = patch(u'openlp.core.ui.formattingtagform.Ui_FormattingTagDialog') + self.init_patcher = patch('openlp.core.ui.formattingtagform.FormattingTagForm.__init__') + self.qdialog_patcher = patch('openlp.core.ui.formattingtagform.QtGui.QDialog') + self.ui_formatting_tag_dialog_patcher = patch('openlp.core.ui.formattingtagform.Ui_FormattingTagDialog') self.mocked_init = self.init_patcher.start() self.mocked_qdialog = self.qdialog_patcher.start() self.mocked_ui_formatting_tag_dialog = self.ui_formatting_tag_dialog_patcher.start() From 40350aec0f9f4461a9fc89e8c5dd57ef16c7484e Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 4 Oct 2013 21:36:02 +0100 Subject: [PATCH 21/22] tests updates --- .../tests_formattingtagscontroller.py | 28 +++++++++++++++++ .../tests_formattingtagsform.py | 30 ++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/tests/functional/openlp_core_ui/tests_formattingtagscontroller.py b/tests/functional/openlp_core_ui/tests_formattingtagscontroller.py index 3a5fab289..dc9495775 100644 --- a/tests/functional/openlp_core_ui/tests_formattingtagscontroller.py +++ b/tests/functional/openlp_core_ui/tests_formattingtagscontroller.py @@ -1,3 +1,31 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2013 Raoul Snyman # +# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan # +# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, # +# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. # +# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, # +# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # +# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, # +# Frode Woldsund, Martin Zibricky, Patrick Zimmermann # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### """ Package to test the openlp.core.ui.formattingtagscontroller package. """ diff --git a/tests/functional/openlp_core_ui/tests_formattingtagsform.py b/tests/functional/openlp_core_ui/tests_formattingtagsform.py index ee863439c..7dc3d4b6f 100644 --- a/tests/functional/openlp_core_ui/tests_formattingtagsform.py +++ b/tests/functional/openlp_core_ui/tests_formattingtagsform.py @@ -1,9 +1,37 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2013 Raoul Snyman # +# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan # +# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, # +# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. # +# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, # +# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # +# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, # +# Frode Woldsund, Martin Zibricky, Patrick Zimmermann # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### """ Package to test the openlp.core.ui.formattingtagsform package. """ from unittest import TestCase -from mock import MagicMock, patch +from tests.functional import MagicMock, patch from openlp.core.ui.formattingtagform import FormattingTagForm From cf9ddadf35b024942a94a026c9995b1d2ebe8852 Mon Sep 17 00:00:00 2001 From: "Jeffrey S. Smith" Date: Fri, 4 Oct 2013 16:44:58 -0500 Subject: [PATCH 22/22] Missed removing one line when merging --- .../openlp_plugins/songs/test_worshipcenterproimport.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/functional/openlp_plugins/songs/test_worshipcenterproimport.py b/tests/functional/openlp_plugins/songs/test_worshipcenterproimport.py index 102caf98e..836c5340b 100644 --- a/tests/functional/openlp_plugins/songs/test_worshipcenterproimport.py +++ b/tests/functional/openlp_plugins/songs/test_worshipcenterproimport.py @@ -129,7 +129,6 @@ SONG_TEST_DATA = [{'title': 'Amazing Grace', ('There\'s a garden where\nJesus is waiting,\nAnd He bids you to come,\nmeet Him there;\n' 'Just to bow and\nreceive a new blessing\nIn the beautiful\ngarden of prayer.')]}] -@skipIf(os.name != 'nt', 'WorshipCenter Pro import only supported on Windows') class TestWorshipCenterProSongImport(TestCase): """ Test the functions in the :mod:`worshipcenterproimport` module.