Merge lp:~suutari-olli/openlp/force-split into lp:openlp

Proposed by Azaziah
Status: Superseded
Proposed branch: lp:~suutari-olli/openlp/force-split
Merge into: lp:openlp
Diff against target: 250 lines (+118/-11)
5 files modified
openlp/core/lib/renderer.py (+3/-3)
openlp/plugins/songs/forms/editsongform.py (+49/-0)
openlp/plugins/songs/forms/editversedialog.py (+6/-0)
openlp/plugins/songs/forms/editverseform.py (+44/-5)
tests/functional/openlp_plugins/songs/test_editverseform.py (+16/-3)
To merge this branch: bzr merge lp:~suutari-olli/openlp/force-split
Reviewer Review Type Date Requested Status
Tim Bentley Needs Fixing
Review via email: mp+294228@code.launchpad.net

This proposal supersedes a proposal from 2016-05-10.

Description of the change

- Added "Split" button for Song editor:
  This adds the currently selected Verses tag to
  the given position, thus creating a "Force split"
- Increased Optional Split limit from < 5 to < 51
- Increased test coverage

lp:~suutari-olli/openlp/force-split (revision 2665)
[←[1;32mSUCCESS←[1;m] https://ci.openlp.io/job/Branch-01-Pull/1543/
[←[1;32mSUCCESS←[1;m] https://ci.openlp.io/job/Branch-02-Functional-Tests/1454/
[←[1;32mSUCCESS←[1;m] https://ci.openlp.io/job/Branch-03-Interface-Tests/1392/
[←[1;32mSUCCESS←[1;m] https://ci.openlp.io/job/Branch-04a-Windows_Functional_Tests/1175/
[←[1;32mSUCCESS←[1;m] https://ci.openlp.io/job/Branch-04b-Windows_Interface_Tests/765/
[←[1;32mSUCCESS←[1;m] https://ci.openlp.io/job/Branch-05a-Code_Analysis/833/
[←[1;32mSUCCESS←[1;m] https://ci.openlp.io/job/Branch-05b-Test_Coverage/701/

To post a comment you must log in.
Revision history for this message
Tim Bentley (trb143) wrote : Posted in a previous version of this proposal

Cannot test as the UI is not visible.
There will be more comments when it works

review: Needs Fixing
Revision history for this message
Azaziah (suutari-olli) wrote : Posted in a previous version of this proposal

Could you explain "Cannot test as the UI is not visible." ?

I replied to the other comments, thank you for the review.

Revision history for this message
Tim Bentley (trb143) wrote : Posted in a previous version of this proposal

You have and Insert button which is not visible - simple.

Revision history for this message
Azaziah (suutari-olli) wrote : Posted in a previous version of this proposal

> You have and Insert button which is not visible - simple.

Did you read my replies to code comments?

"What do you mean? The UI is the new "Split" button found in song editor,
in both "Edit all" and "Edit" modes."

This is visible for me, if it is not visible for you, then something has gone horribly wrong.

Revision history for this message
Tim Bentley (trb143) wrote : Posted in a previous version of this proposal

Ok found it now as the button is only visible on Edit All.

All the button does is add a ---[Verse X]--- tag which is the same as the splt button does except that the split button has more options.

Why is this request needed because it would seem we have the required functionality already.

Revision history for this message
Tomas Groth (tomasgroth) wrote : Posted in a previous version of this proposal

I think the idea is to force s split inside a verse - bot correct me if I'm wrong.
If that is the idea, then the button should also be available in single verse edit.

Revision history for this message
Azaziah (suutari-olli) wrote : Posted in a previous version of this proposal

> Ok found it now as the button is only visible on Edit All.
>
> All the button does is add a ---[Verse X]--- tag which is the same as the splt
> button does except that the split button has more options.
>
> Why is this request needed because it would seem we have the required
> functionality already.

----
> All the button does is add a ---[Verse X]--- tag which is the same as the splt
> button does except that the split button has more options.

Not sure if I understand this sentence, but:

With the "Split" button, the verse will be force splitted by using the verse tag.
This is easier than selecting the verse manually and then inserting it to the required position.
A lot of people are confusing the meaning of Optional split and try to perform force splits with it.
A lot of people have requested easier way to force split verses.

> Ok found it now as the button is only visible on Edit All.

Again: This is visible for me in: Edit, Edit all & Add,
are you sure this button is not visible for you as well?

Revision history for this message
Azaziah (suutari-olli) wrote : Posted in a previous version of this proposal

> I think the idea is to force s split inside a verse - bot correct me if I'm
> wrong.
> If that is the idea, then the button should also be available in single verse
> edit.

This button is available in single verse edit, as well it is available in "Add" verse.
I believe TRB143 may has missed it or something very weird is happening.

Revision history for this message
Tim Bentley (trb143) wrote :

OK now have this working a bit.
The insert only works on the Edit All screen and is not visible on Add or Edit.

Insert adds a ---[Verse-4]--- type tag

We already have split which does the same thing but with greater functionality as it allows one to choose what they want to add.

If Insert adds based on the thing which was last used and increments the count by one.

This is now very confusing.
Split needs to be enhanced with a new option to split the current verse type not add a 2nd implementation.

Looking at the defects they were old and could predate some of the current functionality like virtual split (only used if required).

review: Needs Fixing
Revision history for this message
Azaziah (suutari-olli) wrote :

> OK now have this working a bit.
> The insert only works on the Edit All screen and is not visible on Add or
> Edit.
>
> Insert adds a ---[Verse-4]--- type tag
>
> We already have split which does the same thing but with greater functionality
> as it allows one to choose what they want to add.
>
> If Insert adds based on the thing which was last used and increments the count
> by one.
>
> This is now very confusing.
> Split needs to be enhanced with a new option to split the current verse type
> not add a 2nd implementation.
>
>
> Looking at the defects they were old and could predate some of the current
> functionality like virtual split (only used if required).

I think you are confusing "Insert" and "Split"

"Insert" is old functionality, "Split" is new functionality.

"Insert" is available only in "Edit all", "Split" is also available in "Edit" & "Add"

"Insert" adds +1 to the current verse, as it is used to add more verses.
"Insert" allows you to change the verse type you want to insert.

"Split" duplicates the active verses tag, thus creating a force split

lp:~suutari-olli/openlp/force-split updated
2666. By Azaziah

- Fixed the issue whre verse current number is not updated properly on edit single verse mode.

2667. By Azaziah

Merged trunk?

2668. By Azaziah

Merged trunk?

2669. By Azaziah

Reverted the perfectly functioning Verse split technigue and replaced it with insert [--].
This still needs to be turned into force split in renderer.py

2670. By Azaziah

- This is broken / Going to revert to older solution after this.

2671. By Azaziah

- Reverted to the working solution.

Unmerged revisions

2671. By Azaziah

- Reverted to the working solution.

2670. By Azaziah

- This is broken / Going to revert to older solution after this.

2669. By Azaziah

Reverted the perfectly functioning Verse split technigue and replaced it with insert [--].
This still needs to be turned into force split in renderer.py

2668. By Azaziah

Merged trunk?

2667. By Azaziah

Merged trunk?

2666. By Azaziah

- Fixed the issue whre verse current number is not updated properly on edit single verse mode.

2665. By Azaziah

Merged trunk (Noticed tests appear to be fixed)

2664. By Azaziah

- Improved this on Edit single verse (This now detects if the verse type is changed)

2663. By Azaziah

Added a test for def on_insert_button_clicked(self):

2662. By Azaziah

Fixed a test

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'openlp/core/lib/renderer.py'
--- openlp/core/lib/renderer.py 2016-05-15 17:33:42 +0000
+++ openlp/core/lib/renderer.py 2016-05-29 14:01:07 +0000
@@ -241,7 +241,7 @@
241 elif item.is_capable(ItemCapabilities.CanSoftBreak):241 elif item.is_capable(ItemCapabilities.CanSoftBreak):
242 pages = []242 pages = []
243 if '[---]' in text:243 if '[---]' in text:
244 # Remove two or more option slide breaks next to each other (causing infinite loop).244 # Remove two or more optional splits next to each other (causing infinite loop).
245 while '\n[---]\n[---]\n' in text:245 while '\n[---]\n[---]\n' in text:
246 text = text.replace('\n[---]\n[---]\n', '\n[---]\n')246 text = text.replace('\n[---]\n[---]\n', '\n[---]\n')
247 while ' [---]' in text:247 while ' [---]' in text:
@@ -249,8 +249,8 @@
249 while '[---] ' in text:249 while '[---] ' in text:
250 text = text.replace('[---] ', '[---]')250 text = text.replace('[---] ', '[---]')
251 count = 0251 count = 0
252 # only loop 5 times as there will never be more than 5 incorrect logical splits on a single slide.252 # only loop 50 times as there will never be more than 50 optional splits on a single slide.
253 while True and count < 5:253 while True and count < 51:
254 slides = text.split('\n[---]\n', 2)254 slides = text.split('\n[---]\n', 2)
255 # If there are (at least) two occurrences of [---] we use the first two slides (and neglect the last255 # If there are (at least) two occurrences of [---] we use the first two slides (and neglect the last
256 # for now).256 # for now).
257257
=== modified file 'openlp/plugins/songs/forms/editsongform.py'
--- openlp/plugins/songs/forms/editsongform.py 2016-04-25 11:01:32 +0000
+++ openlp/plugins/songs/forms/editsongform.py 2016-05-29 14:01:07 +0000
@@ -776,6 +776,55 @@
776 item = QtWidgets.QTableWidgetItem(entry, 0)776 item = QtWidgets.QTableWidgetItem(entry, 0)
777 item.setData(QtCore.Qt.UserRole, temp_ids[row])777 item.setData(QtCore.Qt.UserRole, temp_ids[row])
778 self.verse_list_widget.setItem(row, 0, item)778 self.verse_list_widget.setItem(row, 0, item)
779 # This code converts force splits aka. Verse tags inserted during edit to new verses from text.
780 # It is largely copied from def on_verse_edit_all_button_clicked
781 verse_list = ''
782 if self.verse_list_widget.rowCount() > 0:
783 for row in range(self.verse_list_widget.rowCount()):
784 item = self.verse_list_widget.item(row, 0)
785 field = item.data(QtCore.Qt.UserRole)
786 verse_tag = VerseType.translated_name(field[0])
787 verse_num = field[1:]
788 verse_list += '---[%s:%s]---\n' % (verse_tag, verse_num)
789 verse_list += item.text()
790 verse_list += '\n'
791 self.verse_form.set_verse(verse_list)
792 verse_list = self.verse_form.get_all_verses()
793 verse_list = str(verse_list.replace('\r\n', '\n'))
794 self.verse_list_widget.clear()
795 self.verse_list_widget.setRowCount(0)
796 for row in self.find_verse_split.split(verse_list):
797 for match in row.split('---['):
798 for count, parts in enumerate(match.split(']---\n')):
799 if count == 0:
800 if len(parts) == 0:
801 continue
802 # handling carefully user inputted versetags
803 separator = parts.find(':')
804 if separator >= 0:
805 verse_name = parts[0:separator].strip()
806 verse_num = parts[separator + 1:].strip()
807 else:
808 verse_name = parts
809 verse_num = '1'
810 verse_index = VerseType.from_loose_input(verse_name)
811 verse_tag = VerseType.tags[verse_index]
812 # Later we need to handle v1a as well.
813 regex = re.compile(r'\D*(\d+)\D*')
814 match = regex.match(verse_num)
815 if match:
816 verse_num = match.group(1)
817 else:
818 verse_num = '1'
819 verse_def = '%s%s' % (verse_tag, verse_num)
820 else:
821 if parts.endswith('\n'):
822 parts = parts.rstrip('\n')
823 item = QtWidgets.QTableWidgetItem(parts)
824 item.setData(QtCore.Qt.UserRole, verse_def)
825 self.verse_list_widget.setRowCount(self.verse_list_widget.rowCount() + 1)
826 self.verse_list_widget.setItem(self.verse_list_widget.rowCount() - 1, 0, item)
827 # Finalize edit
779 self.tag_rows()828 self.tag_rows()
780 # Check if all verse tags are used.829 # Check if all verse tags are used.
781 self.on_verse_order_text_changed(self.verse_order_edit.text())830 self.on_verse_order_text_changed(self.verse_order_edit.text())
782831
=== modified file 'openlp/plugins/songs/forms/editversedialog.py'
--- openlp/plugins/songs/forms/editversedialog.py 2015-12-31 22:46:06 +0000
+++ openlp/plugins/songs/forms/editversedialog.py 2016-05-29 14:01:07 +0000
@@ -44,6 +44,10 @@
44 self.split_button.setIcon(build_icon(':/general/general_add.png'))44 self.split_button.setIcon(build_icon(':/general/general_add.png'))
45 self.split_button.setObjectName('split_button')45 self.split_button.setObjectName('split_button')
46 self.verse_type_layout.addWidget(self.split_button)46 self.verse_type_layout.addWidget(self.split_button)
47 self.force_split_button = QtWidgets.QPushButton(edit_verse_dialog)
48 self.force_split_button.setIcon(build_icon(':/general/general_add.png'))
49 self.force_split_button.setObjectName('force_split_button')
50 self.verse_type_layout.addWidget(self.force_split_button)
47 self.verse_type_label = QtWidgets.QLabel(edit_verse_dialog)51 self.verse_type_label = QtWidgets.QLabel(edit_verse_dialog)
48 self.verse_type_label.setObjectName('verse_type_label')52 self.verse_type_label.setObjectName('verse_type_label')
49 self.verse_type_layout.addWidget(self.verse_type_label)53 self.verse_type_layout.addWidget(self.verse_type_label)
@@ -78,6 +82,8 @@
78 self.verse_type_combo_box.setItemText(VerseType.Other, VerseType.translated_names[VerseType.Other])82 self.verse_type_combo_box.setItemText(VerseType.Other, VerseType.translated_names[VerseType.Other])
79 self.split_button.setText(UiStrings().Split)83 self.split_button.setText(UiStrings().Split)
80 self.split_button.setToolTip(UiStrings().SplitToolTip)84 self.split_button.setToolTip(UiStrings().SplitToolTip)
85 self.force_split_button.setText(translate('SongsPlugin.EditVerseForm', '&Split'))
86 self.force_split_button.setToolTip(translate('SongsPlugin.EditVerseForm', 'Split the verse.'))
81 self.insert_button.setText(translate('SongsPlugin.EditVerseForm', '&Insert'))87 self.insert_button.setText(translate('SongsPlugin.EditVerseForm', '&Insert'))
82 self.insert_button.setToolTip(translate('SongsPlugin.EditVerseForm',88 self.insert_button.setToolTip(translate('SongsPlugin.EditVerseForm',
83 'Split a slide into two by inserting a verse splitter.'))89 'Split a slide into two by inserting a verse splitter.'))
8490
=== modified file 'openlp/plugins/songs/forms/editverseform.py'
--- openlp/plugins/songs/forms/editverseform.py 2016-01-09 16:26:14 +0000
+++ openlp/plugins/songs/forms/editverseform.py 2016-05-29 14:01:07 +0000
@@ -46,6 +46,7 @@
46 self.has_single_verse = False46 self.has_single_verse = False
47 self.insert_button.clicked.connect(self.on_insert_button_clicked)47 self.insert_button.clicked.connect(self.on_insert_button_clicked)
48 self.split_button.clicked.connect(self.on_split_button_clicked)48 self.split_button.clicked.connect(self.on_split_button_clicked)
49 self.force_split_button.clicked.connect(self.on_force_split_button_clicked)
49 self.verse_text_edit.cursorPositionChanged.connect(self.on_cursor_position_changed)50 self.verse_text_edit.cursorPositionChanged.connect(self.on_cursor_position_changed)
50 self.verse_type_combo_box.currentIndexChanged.connect(self.on_verse_type_combo_box_changed)51 self.verse_type_combo_box.currentIndexChanged.connect(self.on_verse_type_combo_box_changed)
5152
@@ -64,7 +65,7 @@
6465
65 def on_split_button_clicked(self):66 def on_split_button_clicked(self):
66 """67 """
67 The split button has been pressed68 The (optional) split button has been pressed
68 """69 """
69 text = self.verse_text_edit.toPlainText()70 text = self.verse_text_edit.toPlainText()
70 position = self.verse_text_edit.textCursor().position()71 position = self.verse_text_edit.textCursor().position()
@@ -76,6 +77,39 @@
76 self.verse_text_edit.insertPlainText(insert_string)77 self.verse_text_edit.insertPlainText(insert_string)
77 self.verse_text_edit.setFocus()78 self.verse_text_edit.setFocus()
7879
80 def on_force_split_button_clicked(self, verse_tag, verse_num=1):
81 """
82 The force split button has been pressed
83 Find the last used verse tag by using given position and regex.
84 Then insert the tag and create a new line if required.
85 """
86 position = self.verse_text_edit.textCursor().position()
87 text = self.verse_text_edit.toPlainText()
88 position = text.rfind('---[', 0, position)
89 # If editing single verse or ---[ not found, get value of the current verse and insert it.
90 # This will insert the verse tag if editing a single verse or all verses and no verse tag is present.
91 if self.has_single_verse or position == -1:
92 verse_type_index = self.verse_type_combo_box.currentIndex()
93 self.insert_verse(VerseType.tags[verse_type_index], self.verse_number_box.value())
94 # Find & Duplicate the currently selected verses tag and insert it.
95 else:
96 text = text[position:]
97 position = text.find(']---')
98 if position == -1:
99 return
100 text = text[:position + 4]
101 match = re.match(('---\[.*\]---'), text)
102 insert_string = match.group()
103 # Reset text & position data for checking the proper inserting place & is newline required.
104 text = self.verse_text_edit.toPlainText()
105 position = self.verse_text_edit.textCursor().position()
106 if position and text[position - 1] != '\n':
107 insert_string = '\n' + insert_string
108 if position == len(text) or text[position] != '\n':
109 insert_string += '\n'
110 self.verse_text_edit.insertPlainText(insert_string)
111 self.verse_text_edit.setFocus()
112
79 def on_insert_button_clicked(self):113 def on_insert_button_clicked(self):
80 """114 """
81 The insert button has been pressed115 The insert button has been pressed
@@ -99,13 +133,11 @@
99 """133 """
100 Adjusts the verse number SpinBox in regard to the selected verse type and the cursor's position.134 Adjusts the verse number SpinBox in regard to the selected verse type and the cursor's position.
101 """135 """
102 if self.has_single_verse:
103 return
104 position = self.verse_text_edit.textCursor().position()136 position = self.verse_text_edit.textCursor().position()
105 text = self.verse_text_edit.toPlainText()137 text = self.verse_text_edit.toPlainText()
106 verse_name = VerseType.translated_names[138 verse_name = VerseType.translated_names[
107 self.verse_type_combo_box.currentIndex()]139 self.verse_type_combo_box.currentIndex()]
108 if not text:140 if not text or self.has_single_verse:
109 return141 return
110 position = text.rfind('---[%s' % verse_name, 0, position)142 position = text.rfind('---[%s' % verse_name, 0, position)
111 if position == -1:143 if position == -1:
@@ -115,7 +147,12 @@
115 position = text.find(']---')147 position = text.find(']---')
116 if position == -1:148 if position == -1:
117 return149 return
118 text = text[:position + 4]150 # If editing a Single verse, set the text to match current verse, otherwise increase the suggested verse.
151 # This seems to only take effect when adding a split in middle of the sentence.
152 if self.has_single_verse:
153 text = text[:position]
154 else:
155 text = text[:position + 4]
119 match = VERSE_REGEX.match(text)156 match = VERSE_REGEX.match(text)
120 if match:157 if match:
121 try:158 try:
@@ -153,6 +190,7 @@
153 def get_verse(self):190 def get_verse(self):
154 """191 """
155 Extract the verse text192 Extract the verse text
193 If you are looking for the save method, check out songs\forms\editsongform.py def on_verse_edit_button_clicked
156194
157 :return: The text195 :return: The text
158 """196 """
@@ -162,6 +200,7 @@
162 def get_all_verses(self):200 def get_all_verses(self):
163 """201 """
164 Extract all the verses202 Extract all the verses
203 If you are looking for the save method, check out forms\editsongform.py def on_verse_edit_all_button_clicked
165204
166 :return: The text205 :return: The text
167 """206 """
168207
=== modified file 'tests/functional/openlp_plugins/songs/test_editverseform.py'
--- tests/functional/openlp_plugins/songs/test_editverseform.py 2015-12-31 22:46:06 +0000
+++ tests/functional/openlp_plugins/songs/test_editverseform.py 2016-05-29 14:01:07 +0000
@@ -55,16 +55,29 @@
5555
56 def update_suggested_verse_number_test(self):56 def update_suggested_verse_number_test(self):
57 """57 """
58 Test that update_suggested_verse_number() has no effect when editing a single verse58 Test that update_suggested_verse_number() does not change the verse number for force split in edit single verse.
59 """59 """
60 # GIVEN some input values60 # GIVEN some input values
61 self.edit_verse_form.has_single_verse = True61 self.edit_verse_form.has_single_verse = True
62 self.edit_verse_form.verse_type_combo_box.currentIndex = MagicMock(return_value=0)62 self.edit_verse_form.verse_type_combo_box.currentIndex = MagicMock(return_value=0)
63 self.edit_verse_form.verse_text_edit.toPlainText = MagicMock(return_value='Text')63 self.edit_verse_form.verse_text_edit.toPlainText = MagicMock(return_value='Text')
64 self.edit_verse_form.verse_number_box.setValue(3)64 self.edit_verse_form.verse_number_box.setValue(1)
6565
66 # WHEN the method is called66 # WHEN the method is called
67 self.edit_verse_form.update_suggested_verse_number()67 self.edit_verse_form.update_suggested_verse_number()
6868
69 # THEN the verse number must not be changed69 # THEN the verse number must not be changed
70 self.assertEqual(3, self.edit_verse_form.verse_number_box.value(), 'The verse number should be 3')70 self.assertEqual(1, self.edit_verse_form.verse_number_box.value(), 'The verse number should be 1')
71
72 def on_insert_button_clicked_test(self):
73 """
74 Test that insert_verse is called on def on_insert_button_clicked
75 """
76 # GIVEN required functions
77 self.edit_verse_form.insert_verse = MagicMock()
78
79 # WHEN the method is called
80 self.edit_verse_form.on_insert_button_clicked()
81
82 # THEN the verse number must not be changed
83 self.assertEqual(1, self.edit_verse_form.insert_verse.call_count, 'The insert_verse should had been called')