Merge lp:~tomasgroth/openlp/bugfixes19 into lp:openlp

Proposed by Tomas Groth
Status: Merged
Approved by: Tim Bentley
Approved revision: 2535
Merged at revision: 2529
Proposed branch: lp:~tomasgroth/openlp/bugfixes19
Merge into: lp:openlp
Diff against target: 290 lines (+76/-27)
8 files modified
openlp/core/common/uistrings.py (+2/-0)
openlp/core/lib/listwidgetwithdnd.py (+1/-1)
openlp/core/ui/printserviceform.py (+3/-1)
openlp/plugins/bibles/lib/mediaitem.py (+1/-1)
openlp/plugins/bibles/lib/versereferencelist.py (+21/-9)
openlp/plugins/images/lib/mediaitem.py (+2/-0)
openlp/plugins/media/lib/mediaitem.py (+6/-1)
tests/functional/openlp_plugins/images/test_lib.py (+40/-14)
To merge this branch: bzr merge lp:~tomasgroth/openlp/bugfixes19
Reviewer Review Type Date Requested Status
Tim Bentley Approve
Raoul Snyman Approve
Review via email: mp+257184@code.launchpad.net

Description of the change

Delete image thumbnails when the image is removed. Fixes bug 1446491.
Make sure we always add a blank line between verses. Fixes bug 1439311.
Normalize file path to OS standard after drag-and-drop. Fixes bug 1440571.
Make the way we display verse ranges consistent and make use of localized or custom separators. Fixes bug 1081807
Disable button for replacing live background if the webkit player is not available.

To post a comment you must log in.
Revision history for this message
Tomas Groth (tomasgroth) wrote :

lp:~tomasgroth/openlp/bugfixes19 (revision 2535)
[SUCCESS] https//ci.openlp.io/job/Branch-01-Pull/1005/
[SUCCESS] https//ci.openlp.io/job/Branch-02-Functional-Tests/928/
[SUCCESS] https//ci.openlp.io/job/Branch-03-Interface-Tests/870/
[SUCCESS] https//ci.openlp.io/job/Branch-04a-Windows_Functional_Tests/760/
[SUCCESS] https//ci.openlp.io/job/Branch-04b-Windows_Interface_Tests/358/
[SUCCESS] https//ci.openlp.io/job/Branch-05a-Code_Analysis/491/
[SUCCESS] https//ci.openlp.io/job/Branch-05b-Test_Coverage/362/

Revision history for this message
Raoul Snyman (raoul-snyman) :
review: Approve
Revision history for this message
Tim Bentley (trb143) wrote :

Approved

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openlp/core/common/uistrings.py'
2--- openlp/core/common/uistrings.py 2015-02-09 20:49:24 +0000
3+++ openlp/core/common/uistrings.py 2015-04-22 21:11:34 +0000
4@@ -121,6 +121,8 @@
5 self.Projectors = translate('OpenLP.Ui', 'Projectors', 'Plural')
6 self.ReplaceBG = translate('OpenLP.Ui', 'Replace Background')
7 self.ReplaceLiveBG = translate('OpenLP.Ui', 'Replace live background.')
8+ self.ReplaceLiveBGDisabled = translate('OpenLP.Ui', 'Replace live background is not available on this '
9+ 'platform in this version of OpenLP.')
10 self.ResetBG = translate('OpenLP.Ui', 'Reset Background')
11 self.ResetLiveBG = translate('OpenLP.Ui', 'Reset live background.')
12 self.Seconds = translate('OpenLP.Ui', 's', 'The abbreviated unit for seconds')
13
14=== modified file 'openlp/core/lib/listwidgetwithdnd.py'
15--- openlp/core/lib/listwidgetwithdnd.py 2015-01-18 13:39:21 +0000
16+++ openlp/core/lib/listwidgetwithdnd.py 2015-04-22 21:11:34 +0000
17@@ -95,7 +95,7 @@
18 event.accept()
19 files = []
20 for url in event.mimeData().urls():
21- local_file = url.toLocalFile()
22+ local_file = os.path.normpath(url.toLocalFile())
23 if os.path.isfile(local_file):
24 files.append(local_file)
25 elif os.path.isdir(local_file):
26
27=== modified file 'openlp/core/ui/printserviceform.py'
28--- openlp/core/ui/printserviceform.py 2015-01-18 13:39:21 +0000
29+++ openlp/core/ui/printserviceform.py 2015-04-22 21:11:34 +0000
30@@ -193,13 +193,15 @@
31 # Add the text of the service item.
32 if item.is_text():
33 verse_def = None
34+ verse_html = None
35 for slide in item.get_frames():
36- if not verse_def or verse_def != slide['verseTag']:
37+ if not verse_def or verse_def != slide['verseTag'] or verse_html == slide['html']:
38 text_div = self._add_element('div', parent=div, classId='itemText')
39 else:
40 self._add_element('br', parent=text_div)
41 self._add_element('span', slide['html'], text_div)
42 verse_def = slide['verseTag']
43+ verse_html = slide['html']
44 # Break the page before the div element.
45 if index != 0 and self.page_break_after_text.isChecked():
46 div.set('class', 'item newPage')
47
48=== modified file 'openlp/plugins/bibles/lib/mediaitem.py'
49--- openlp/plugins/bibles/lib/mediaitem.py 2015-01-18 13:39:21 +0000
50+++ openlp/plugins/bibles/lib/mediaitem.py 2015-04-22 21:11:34 +0000
51@@ -849,7 +849,7 @@
52 service_item.add_capability(ItemCapabilities.CanWordSplit)
53 service_item.add_capability(ItemCapabilities.CanEditTitle)
54 # Service Item: Title
55- service_item.title = create_separated_list(raw_title)
56+ service_item.title = '%s %s' % (verses.format_verses(), verses.format_versions())
57 # Service Item: Theme
58 if not self.settings.bible_theme:
59 service_item.theme = None
60
61=== modified file 'openlp/plugins/bibles/lib/versereferencelist.py'
62--- openlp/plugins/bibles/lib/versereferencelist.py 2015-02-13 20:19:05 +0000
63+++ openlp/plugins/bibles/lib/versereferencelist.py 2015-04-22 21:11:34 +0000
64@@ -20,6 +20,8 @@
65 # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
66 ###############################################################################
67
68+from openlp.plugins.bibles.lib import get_reference_separator
69+
70
71 class VerseReferenceList(object):
72 """
73@@ -53,29 +55,39 @@
74 self.version_list.append({'version': version, 'copyright': copyright, 'permission': permission})
75
76 def format_verses(self):
77+ verse_sep = get_reference_separator('sep_v_display')
78+ range_sep = get_reference_separator('sep_r_display')
79+ list_sep = get_reference_separator('sep_l_display')
80 result = ''
81 for index, verse in enumerate(self.verse_list):
82 if index == 0:
83- result = '%s %s:%s' % (verse['book'], verse['chapter'], verse['start'])
84+ result = '%s %s%s%s' % (verse['book'], verse['chapter'], verse_sep, verse['start'])
85 if verse['start'] != verse['end']:
86- result = '%s-%s' % (result, verse['end'])
87+ result = '%s%s%s' % (result, range_sep, verse['end'])
88 continue
89 prev = index - 1
90 if self.verse_list[prev]['version'] != verse['version']:
91 result = '%s (%s)' % (result, self.verse_list[prev]['version'])
92- result += ', '
93+ result += '%s ' % list_sep
94 if self.verse_list[prev]['book'] != verse['book']:
95- result = '%s%s %s:' % (result, verse['book'], verse['chapter'])
96+ result = '%s%s %s%s' % (result, verse['book'], verse['chapter'], verse_sep)
97 elif self.verse_list[prev]['chapter'] != verse['chapter']:
98- result = '%s%s:' % (result, verse['chapter'])
99+ result = '%s%s%s' % (result, verse['chapter'], verse_sep)
100 result += str(verse['start'])
101 if verse['start'] != verse['end']:
102- result = '%s-%s' % (result, verse['end'])
103+ result = '%s%s%s' % (result, range_sep, verse['end'])
104 if len(self.version_list) > 1:
105 result = '%s (%s)' % (result, verse['version'])
106 return result
107
108- def format_versions(self):
109+ def format_versions(self, copyright=True, permission=True):
110+ """
111+ Format a string with the bible versions used
112+
113+ :param copyright: If the copyright info should be included, default is true.
114+ :param permission: If the permission info should be included, default is true.
115+ :return: A formatted string with the bible versions used
116+ """
117 result = ''
118 for index, version in enumerate(self.version_list):
119 if index > 0:
120@@ -83,9 +95,9 @@
121 result += ';'
122 result += ' '
123 result += version['version']
124- if version['copyright'].strip():
125+ if copyright and version['copyright'].strip():
126 result += ', ' + version['copyright']
127- if version['permission'].strip():
128+ if permission and version['permission'].strip():
129 result += ', ' + version['permission']
130 result = result.rstrip()
131 if result.endswith(','):
132
133=== modified file 'openlp/plugins/images/lib/mediaitem.py'
134--- openlp/plugins/images/lib/mediaitem.py 2015-01-30 21:03:53 +0000
135+++ openlp/plugins/images/lib/mediaitem.py 2015-04-22 21:11:34 +0000
136@@ -205,6 +205,7 @@
137 images = self.manager.get_all_objects(ImageFilenames, ImageFilenames.group_id == image_group.id)
138 for image in images:
139 delete_file(os.path.join(self.service_path, os.path.split(image.filename)[1]))
140+ delete_file(self.generate_thumbnail_path(image))
141 self.manager.delete_object(ImageFilenames, image.id)
142 image_groups = self.manager.get_all_objects(ImageGroups, ImageGroups.parent_id == image_group.id)
143 for group in image_groups:
144@@ -227,6 +228,7 @@
145 item_data = row_item.data(0, QtCore.Qt.UserRole)
146 if isinstance(item_data, ImageFilenames):
147 delete_file(os.path.join(self.service_path, row_item.text(0)))
148+ delete_file(self.generate_thumbnail_path(item_data))
149 if item_data.group_id == 0:
150 self.list_view.takeTopLevelItem(self.list_view.indexOfTopLevelItem(row_item))
151 else:
152
153=== modified file 'openlp/plugins/media/lib/mediaitem.py'
154--- openlp/plugins/media/lib/mediaitem.py 2015-03-10 21:33:35 +0000
155+++ openlp/plugins/media/lib/mediaitem.py 2015-04-22 21:11:34 +0000
156@@ -91,7 +91,10 @@
157 """
158 self.on_new_prompt = translate('MediaPlugin.MediaItem', 'Select Media')
159 self.replace_action.setText(UiStrings().ReplaceBG)
160- self.replace_action.setToolTip(UiStrings().ReplaceLiveBG)
161+ if 'webkit' in get_media_players()[0]:
162+ self.replace_action.setToolTip(UiStrings().ReplaceLiveBG)
163+ else:
164+ self.replace_action.setToolTip(UiStrings().ReplaceLiveBGDisabled)
165 self.reset_action.setText(UiStrings().ResetBG)
166 self.reset_action.setToolTip(UiStrings().ResetLiveBG)
167 self.automatic = UiStrings().Automatic
168@@ -139,6 +142,8 @@
169 # Replace backgrounds do not work at present so remove functionality.
170 self.replace_action = self.toolbar.add_toolbar_action('replace_action', icon=':/slides/slide_blank.png',
171 triggers=self.on_replace_click)
172+ if 'webkit' not in get_media_players()[0]:
173+ self.replace_action.setDisabled(True)
174 self.reset_action = self.toolbar.add_toolbar_action('reset_action', icon=':/system/system_close.png',
175 visible=False, triggers=self.on_reset_click)
176 self.media_widget = QtGui.QWidget(self)
177
178=== modified file 'tests/functional/openlp_plugins/images/test_lib.py'
179--- tests/functional/openlp_plugins/images/test_lib.py 2015-01-20 07:14:58 +0000
180+++ tests/functional/openlp_plugins/images/test_lib.py 2015-04-22 21:11:34 +0000
181@@ -97,8 +97,8 @@
182 self.media_item.save_new_images_list(image_list)
183
184 # THEN: The save_object() method should not have been called
185- assert self.media_item.manager.save_object.call_count == 0, \
186- 'The save_object() method should not have been called'
187+ self.assertEquals(self.media_item.manager.save_object.call_count, 0,
188+ 'The save_object() method should not have been called')
189
190 def save_new_images_list_single_image_with_reload_test(self):
191 """
192@@ -114,7 +114,7 @@
193 self.media_item.save_new_images_list(image_list, reload_list=True)
194
195 # THEN: load_full_list() should have been called
196- assert mocked_load_full_list.call_count == 1, 'load_full_list() should have been called'
197+ self.assertEquals(mocked_load_full_list.call_count, 1, 'load_full_list() should have been called')
198
199 # CLEANUP: Remove added attribute from ImageFilenames
200 delattr(ImageFilenames, 'filename')
201@@ -132,7 +132,7 @@
202 self.media_item.save_new_images_list(image_list, reload_list=False)
203
204 # THEN: load_full_list() should not have been called
205- assert mocked_load_full_list.call_count == 0, 'load_full_list() should not have been called'
206+ self.assertEquals(mocked_load_full_list.call_count, 0, 'load_full_list() should not have been called')
207
208 def save_new_images_list_multiple_images_test(self):
209 """
210@@ -147,8 +147,8 @@
211 self.media_item.save_new_images_list(image_list, reload_list=False)
212
213 # THEN: load_full_list() should not have been called
214- assert self.media_item.manager.save_object.call_count == 3, \
215- 'load_full_list() should have been called three times'
216+ self.assertEquals(self.media_item.manager.save_object.call_count, 3,
217+ 'load_full_list() should have been called three times')
218
219 def save_new_images_list_other_objects_in_list_test(self):
220 """
221@@ -163,8 +163,8 @@
222 self.media_item.save_new_images_list(image_list, reload_list=False)
223
224 # THEN: load_full_list() should not have been called
225- assert self.media_item.manager.save_object.call_count == 2, \
226- 'load_full_list() should have been called only once'
227+ self.assertEquals(self.media_item.manager.save_object.call_count, 2,
228+ 'load_full_list() should have been called only once')
229
230 def on_reset_click_test(self):
231 """
232@@ -185,22 +185,22 @@
233 Test that recursively_delete_group() works
234 """
235 # GIVEN: An ImageGroups object and mocked functions
236- with patch('openlp.core.utils.delete_file') as mocked_delete_file:
237+ with patch('openlp.plugins.images.lib.mediaitem.delete_file') as mocked_delete_file:
238 ImageFilenames.group_id = 1
239 ImageGroups.parent_id = 1
240 self.media_item.manager = MagicMock()
241 self.media_item.manager.get_all_objects.side_effect = self._recursively_delete_group_side_effect
242- self.media_item.service_path = ""
243+ self.media_item.service_path = ''
244 test_group = ImageGroups()
245 test_group.id = 1
246
247 # WHEN: recursively_delete_group() is called
248 self.media_item.recursively_delete_group(test_group)
249
250- # THEN:
251- assert mocked_delete_file.call_count == 0, 'delete_file() should not be called'
252- assert self.media_item.manager.delete_object.call_count == 7, \
253- 'manager.delete_object() should be called exactly 7 times'
254+ # THEN: delete_file() should have been called 12 times and manager.delete_object() 7 times.
255+ self.assertEquals(mocked_delete_file.call_count, 12, 'delete_file() should have been called 12 times')
256+ self.assertEquals(self.media_item.manager.delete_object.call_count, 7,
257+ 'manager.delete_object() should be called exactly 7 times')
258
259 # CLEANUP: Remove added attribute from Image Filenames and ImageGroups
260 delattr(ImageFilenames, 'group_id')
261@@ -230,3 +230,29 @@
262 returned_object1.id = 1
263 return [returned_object1]
264 return []
265+
266+ def on_delete_click_test(self):
267+ """
268+ Test that on_delete_click() works
269+ """
270+ # GIVEN: An ImageGroups object and mocked functions
271+ with patch('openlp.plugins.images.lib.mediaitem.delete_file') as mocked_delete_file, \
272+ patch('openlp.plugins.images.lib.mediaitem.check_item_selected') as mocked_check_item_selected:
273+ mocked_check_item_selected.return_value = True
274+ test_image = ImageFilenames()
275+ test_image.id = 1
276+ test_image.group_id = 1
277+ test_image.filename = 'imagefile.png'
278+ self.media_item.manager = MagicMock()
279+ self.media_item.service_path = ''
280+ self.media_item.list_view = MagicMock()
281+ mocked_row_item = MagicMock()
282+ mocked_row_item.data.return_value = test_image
283+ mocked_row_item.text.return_value = ''
284+ self.media_item.list_view.selectedItems.return_value = [mocked_row_item]
285+
286+ # WHEN: Calling on_delete_click
287+ self.media_item.on_delete_click()
288+
289+ # THEN: delete_file should have been called twice
290+ self.assertEquals(mocked_delete_file.call_count, 2, 'delete_file() should have been called twice')