Merge lp:~raoul-snyman/openlp/bug-1533246 into lp:openlp

Proposed by Raoul Snyman
Status: Merged
Merged at revision: 2614
Proposed branch: lp:~raoul-snyman/openlp/bug-1533246
Merge into: lp:openlp
Diff against target: 327 lines (+189/-37)
3 files modified
openlp/core/common/settings.py (+15/-30)
openlp/core/ui/shortcutlistform.py (+10/-2)
tests/interfaces/openlp_core_ui/test_shortcutlistform.py (+164/-5)
To merge this branch: bzr merge lp:~raoul-snyman/openlp/bug-1533246
Reviewer Review Type Date Requested Status
David Wales (community) Approve
Tim Bentley Approve
Review via email: mp+285229@code.launchpad.net

This proposal supersedes a proposal from 2016-02-04.

Description of the change

Fixed a problem with the shortcuts.
Also tried to make the alternate clear button on the shortcuts dialog a little less weird.

Add this to your merge proposal:
--------------------------------
lp:~raoul-snyman/openlp/bug-1533246 (revision 2616)
[SUCCESS] https://ci.openlp.io/job/Branch-01-Pull/1275/
[SUCCESS] https://ci.openlp.io/job/Branch-02-Functional-Tests/1199/
[SUCCESS] https://ci.openlp.io/job/Branch-03-Interface-Tests/1138/
[SUCCESS] https://ci.openlp.io/job/Branch-04a-Windows_Functional_Tests/974/
[FAILURE] https://ci.openlp.io/job/Branch-04b-Windows_Interface_Tests/566/
Stopping after failure

To post a comment you must log in.
Revision history for this message
David Wales (daviewales) wrote : Posted in a previous version of this proposal

Starting on line 197, there is a repeated comment which says:

# WHEN: The even is handled

But should say

# WHEN: The event is handled

Running this search and replace on the code should fix it if you use vim:

%s/ even / event /g

Alternatively, I'm sure you know how to use the search and replace in your favourite editor.

review: Needs Fixing
Revision history for this message
Tim Bentley (trb143) :
review: Approve
Revision history for this message
David Wales (daviewales) :
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/settings.py'
2--- openlp/core/common/settings.py 2016-01-10 16:01:43 +0000
3+++ openlp/core/common/settings.py 2016-02-05 19:02:39 +0000
4@@ -252,68 +252,56 @@
5 'shortcuts/blankScreen': [QtGui.QKeySequence(QtCore.Qt.Key_Period)],
6 'shortcuts/collapse': [QtGui.QKeySequence(QtCore.Qt.Key_Minus)],
7 'shortcuts/desktopScreen': [QtGui.QKeySequence(QtCore.Qt.Key_D)],
8- 'shortcuts/delete': [QtGui.QKeySequence(QtGui.QKeySequence.Delete),
9- QtGui.QKeySequence(QtCore.Qt.Key_Delete)],
10+ 'shortcuts/delete': [QtGui.QKeySequence(QtGui.QKeySequence.Delete)],
11 'shortcuts/down': [QtGui.QKeySequence(QtCore.Qt.Key_Down)],
12 'shortcuts/editSong': [],
13 'shortcuts/escapeItem': [QtGui.QKeySequence(QtCore.Qt.Key_Escape)],
14 'shortcuts/expand': [QtGui.QKeySequence(QtCore.Qt.Key_Plus)],
15 'shortcuts/exportThemeItem': [],
16- 'shortcuts/fileNewItem': [QtGui.QKeySequence(QtGui.QKeySequence.New),
17- QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_N)],
18- 'shortcuts/fileSaveAsItem': [QtGui.QKeySequence(QtGui.QKeySequence.SaveAs),
19- QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.SHIFT + QtCore.Qt.Key_S)],
20- 'shortcuts/fileExitItem': [QtGui.QKeySequence(QtGui.QKeySequence.Quit),
21- QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_F4)],
22- 'shortcuts/fileSaveItem': [QtGui.QKeySequence(QtGui.QKeySequence.Save),
23- QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_S)],
24- 'shortcuts/fileOpenItem': [QtGui.QKeySequence(QtGui.QKeySequence.Open),
25- QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_O)],
26+ 'shortcuts/fileNewItem': [QtGui.QKeySequence(QtGui.QKeySequence.New)],
27+ 'shortcuts/fileSaveAsItem': [QtGui.QKeySequence(QtGui.QKeySequence.SaveAs)],
28+ 'shortcuts/fileExitItem': [QtGui.QKeySequence(QtGui.QKeySequence.Quit)],
29+ 'shortcuts/fileSaveItem': [QtGui.QKeySequence(QtGui.QKeySequence.Save)],
30+ 'shortcuts/fileOpenItem': [QtGui.QKeySequence(QtGui.QKeySequence.Open)],
31 'shortcuts/goLive': [],
32 'shortcuts/importThemeItem': [],
33 'shortcuts/importBibleItem': [],
34- 'shortcuts/listViewBiblesDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.Delete),
35- QtGui.QKeySequence(QtCore.Qt.Key_Delete)],
36+ 'shortcuts/listViewBiblesDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.Delete)],
37 'shortcuts/listViewBiblesPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Return),
38 QtGui.QKeySequence(QtCore.Qt.Key_Enter)],
39 'shortcuts/listViewBiblesLiveItem': [QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Return),
40 QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Enter)],
41 'shortcuts/listViewBiblesServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
42 QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
43- 'shortcuts/listViewCustomDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.Delete),
44- QtGui.QKeySequence(QtCore.Qt.Key_Delete)],
45+ 'shortcuts/listViewCustomDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.Delete)],
46 'shortcuts/listViewCustomPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Return),
47 QtGui.QKeySequence(QtCore.Qt.Key_Enter)],
48 'shortcuts/listViewCustomLiveItem': [QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Return),
49 QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Enter)],
50 'shortcuts/listViewCustomServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
51 QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
52- 'shortcuts/listViewImagesDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.Delete),
53- QtGui.QKeySequence(QtCore.Qt.Key_Delete)],
54+ 'shortcuts/listViewImagesDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.Delete)],
55 'shortcuts/listViewImagesPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Return),
56 QtGui.QKeySequence(QtCore.Qt.Key_Enter)],
57 'shortcuts/listViewImagesLiveItem': [QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Return),
58 QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Enter)],
59 'shortcuts/listViewImagesServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
60 QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
61- 'shortcuts/listViewMediaDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.Delete),
62- QtGui.QKeySequence(QtCore.Qt.Key_Delete)],
63+ 'shortcuts/listViewMediaDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.Delete)],
64 'shortcuts/listViewMediaPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Return),
65 QtGui.QKeySequence(QtCore.Qt.Key_Enter)],
66 'shortcuts/listViewMediaLiveItem': [QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Return),
67 QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Enter)],
68 'shortcuts/listViewMediaServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
69 QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
70- 'shortcuts/listViewPresentationsDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.Delete),
71- QtGui.QKeySequence(QtCore.Qt.Key_Delete)],
72+ 'shortcuts/listViewPresentationsDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.Delete)],
73 'shortcuts/listViewPresentationsPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Return),
74 QtGui.QKeySequence(QtCore.Qt.Key_Enter)],
75 'shortcuts/listViewPresentationsLiveItem': [QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Return),
76 QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Enter)],
77 'shortcuts/listViewPresentationsServiceItem': [QtGui.QKeySequence(QtCore.Qt.Key_Plus),
78 QtGui.QKeySequence(QtCore.Qt.Key_Equal)],
79- 'shortcuts/listViewSongsDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.Delete),
80- QtGui.QKeySequence(QtCore.Qt.Key_Delete)],
81+ 'shortcuts/listViewSongsDeleteItem': [QtGui.QKeySequence(QtGui.QKeySequence.Delete)],
82 'shortcuts/listViewSongsPreviewItem': [QtGui.QKeySequence(QtCore.Qt.Key_Return),
83 QtGui.QKeySequence(QtCore.Qt.Key_Enter)],
84 'shortcuts/listViewSongsLiveItem': [QtGui.QKeySequence(QtCore.Qt.SHIFT + QtCore.Qt.Key_Return),
85@@ -337,8 +325,7 @@
86 'shortcuts/nextService': [QtGui.QKeySequence(QtCore.Qt.Key_Right)],
87 'shortcuts/newService': [],
88 'shortcuts/offlineHelpItem': [QtGui.QKeySequence(QtGui.QKeySequence.HelpContents)],
89- 'shortcuts/onlineHelpItem': [QtGui.QKeySequence(QtGui.QKeySequence.HelpContents),
90- QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_F1)],
91+ 'shortcuts/onlineHelpItem': [QtGui.QKeySequence(QtGui.QKeySequence.HelpContents)],
92 'shortcuts/openService': [],
93 'shortcuts/saveService': [],
94 'shortcuts/previousItem_live': [QtGui.QKeySequence(QtCore.Qt.Key_Up),
95@@ -351,12 +338,10 @@
96 'shortcuts/previousService': [QtGui.QKeySequence(QtCore.Qt.Key_Left)],
97 'shortcuts/previousItem_preview': [QtGui.QKeySequence(QtCore.Qt.Key_Up),
98 QtGui.QKeySequence(QtCore.Qt.Key_PageUp)],
99- 'shortcuts/printServiceItem': [QtGui.QKeySequence(QtGui.QKeySequence.Print),
100- QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_P)],
101+ 'shortcuts/printServiceItem': [QtGui.QKeySequence(QtGui.QKeySequence.Print)],
102 'shortcuts/songExportItem': [],
103 'shortcuts/songUsageStatus': [QtGui.QKeySequence(QtCore.Qt.Key_F4)],
104- 'shortcuts/searchShortcut': [QtGui.QKeySequence(QtGui.QKeySequence.Find),
105- QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_F)],
106+ 'shortcuts/searchShortcut': [QtGui.QKeySequence(QtGui.QKeySequence.Find)],
107 'shortcuts/settingsShortcutsItem': [],
108 'shortcuts/settingsImportItem': [],
109 'shortcuts/settingsPluginListItem': [QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_F7)],
110
111=== modified file 'openlp/core/ui/shortcutlistform.py'
112--- openlp/core/ui/shortcutlistform.py 2016-01-09 16:26:14 +0000
113+++ openlp/core/ui/shortcutlistform.py 2016-02-05 19:02:39 +0000
114@@ -320,9 +320,17 @@
115 """
116 if not toggled:
117 return
118- self.on_primary_push_button_clicked(False)
119- self.on_alternate_push_button_clicked(False)
120+ action = self._current_item_action()
121+ shortcuts = self._action_shortcuts(action)
122 self.refresh_shortcut_list()
123+ primary_button_text = ''
124+ alternate_button_text = ''
125+ if shortcuts:
126+ primary_button_text = self.get_shortcut_string(shortcuts[0], for_display=True)
127+ if len(shortcuts) == 2:
128+ alternate_button_text = self.get_shortcut_string(shortcuts[1], for_display=True)
129+ self.primary_push_button.setText(primary_button_text)
130+ self.alternate_push_button.setText(alternate_button_text)
131
132 def save(self):
133 """
134
135=== modified file 'tests/interfaces/openlp_core_ui/test_shortcutlistform.py'
136--- tests/interfaces/openlp_core_ui/test_shortcutlistform.py 2015-12-31 22:46:06 +0000
137+++ tests/interfaces/openlp_core_ui/test_shortcutlistform.py 2016-02-05 19:02:39 +0000
138@@ -24,11 +24,12 @@
139 """
140 from unittest import TestCase
141
142-from PyQt5 import QtWidgets
143+from PyQt5 import QtCore, QtGui, QtWidgets
144
145 from openlp.core.common import Registry
146 from openlp.core.ui.shortcutlistform import ShortcutListForm
147-from tests.interfaces import patch
148+
149+from tests.interfaces import MagicMock, patch
150 from tests.helpers.testmixin import TestMixin
151
152
153@@ -59,13 +60,171 @@
154 button = QtWidgets.QPushButton()
155 checked = True
156 enabled = True
157- text = "new!"
158+ text = 'new!'
159
160 # WHEN: Call the method.
161 with patch('PyQt5.QtWidgets.QPushButton.setChecked') as mocked_check_method:
162 self.form._adjust_button(button, checked, enabled, text)
163
164 # THEN: The button should be changed.
165- self.assertEqual(button.text(), text, "The text should match.")
166+ self.assertEqual(button.text(), text, 'The text should match.')
167 mocked_check_method.assert_called_once_with(True)
168- self.assertEqual(button.isEnabled(), enabled, "The button should be disabled.")
169+ self.assertEqual(button.isEnabled(), enabled, 'The button should be disabled.')
170+
171+ def space_key_press_event_test(self):
172+ """
173+ Test the keyPressEvent when the spacebar was pressed
174+ """
175+ # GIVEN: A key event that is a space
176+ mocked_event = MagicMock()
177+ mocked_event.key.return_value = QtCore.Qt.Key_Space
178+
179+ # WHEN: The event is handled
180+ with patch.object(self.form, 'keyReleaseEvent') as mocked_key_release_event:
181+ self.form.keyPressEvent(mocked_event)
182+
183+ # THEN: The key should be released
184+ mocked_key_release_event.assert_called_with(mocked_event)
185+ self.assertEqual(0, mocked_event.accept.call_count)
186+
187+ def primary_push_button_checked_key_press_event_test(self):
188+ """
189+ Test the keyPressEvent when the primary push button is checked
190+ """
191+ # GIVEN: The primary push button is checked
192+ with patch.object(self.form, 'keyReleaseEvent') as mocked_key_release_event, \
193+ patch.object(self.form.primary_push_button, 'isChecked') as mocked_is_checked:
194+ mocked_is_checked.return_value = True
195+ mocked_event = MagicMock()
196+
197+ # WHEN: The event is handled
198+ self.form.keyPressEvent(mocked_event)
199+
200+ # THEN: The key should be released
201+ mocked_key_release_event.assert_called_with(mocked_event)
202+ self.assertEqual(0, mocked_event.accept.call_count)
203+
204+ def alternate_push_button_checked_key_press_event_test(self):
205+ """
206+ Test the keyPressEvent when the alternate push button is checked
207+ """
208+ # GIVEN: The primary push button is checked
209+ with patch.object(self.form, 'keyReleaseEvent') as mocked_key_release_event, \
210+ patch.object(self.form.alternate_push_button, 'isChecked') as mocked_is_checked:
211+ mocked_is_checked.return_value = True
212+ mocked_event = MagicMock()
213+
214+ # WHEN: The event is handled
215+ self.form.keyPressEvent(mocked_event)
216+
217+ # THEN: The key should be released
218+ mocked_key_release_event.assert_called_with(mocked_event)
219+ self.assertEqual(0, mocked_event.accept.call_count)
220+
221+ def escape_key_press_event_test(self):
222+ """
223+ Test the keyPressEvent when the escape key was pressed
224+ """
225+ # GIVEN: A key event that is an escape
226+ mocked_event = MagicMock()
227+ mocked_event.key.return_value = QtCore.Qt.Key_Escape
228+
229+ # WHEN: The event is handled
230+ with patch.object(self.form, 'close') as mocked_close:
231+ self.form.keyPressEvent(mocked_event)
232+
233+ # THEN: The key should be released
234+ mocked_event.accept.assert_called_with()
235+ mocked_close.assert_called_with()
236+
237+ def on_default_radio_button_not_toggled_test(self):
238+ """
239+ Test that the default radio button method exits early when the button is not toggled
240+ """
241+ # GIVEN: A not-toggled custom radio button
242+ with patch.object(self.form, '_current_item_action') as mocked_current_item_action:
243+
244+ # WHEN: The clicked method is called
245+ self.form.on_default_radio_button_clicked(False)
246+
247+ # THEN: The method should exit early (i.e. the rest of the methods are not called)
248+ self.assertEqual(0, mocked_current_item_action.call_count)
249+
250+ def on_default_radio_button_clicked_no_action_test(self):
251+ """
252+ Test that nothing happens when an action hasn't been selected and you click the default radio button
253+ """
254+ # GIVEN: Some mocked out methods, a current action, and some shortcuts
255+ with patch.object(self.form, '_current_item_action') as mocked_current_item_action, \
256+ patch.object(self.form, '_action_shortcuts') as mocked_action_shortcuts:
257+ mocked_current_item_action.return_value = None
258+
259+ # WHEN: The default radio button is clicked
260+ self.form.on_default_radio_button_clicked(True)
261+
262+ # THEN: The method should exit early (i.e. the rest of the methods are not called)
263+ mocked_current_item_action.assert_called_with()
264+ self.assertEqual(0, mocked_action_shortcuts.call_count)
265+
266+ def on_default_radio_button_clicked_test(self):
267+ """
268+ Test that the values are copied across correctly when the default radio button is selected
269+ """
270+ # GIVEN: Some mocked out methods, a current action, and some shortcuts
271+ with patch.object(self.form, '_current_item_action') as mocked_current_item_action, \
272+ patch.object(self.form, '_action_shortcuts') as mocked_action_shortcuts, \
273+ patch.object(self.form, 'refresh_shortcut_list') as mocked_refresh_shortcut_list, \
274+ patch.object(self.form, 'get_shortcut_string') as mocked_get_shortcut_string, \
275+ patch.object(self.form.primary_push_button, 'setText') as mocked_set_text:
276+ mocked_action = MagicMock()
277+ mocked_action.default_shortcuts = [QtCore.Qt.Key_Escape]
278+ mocked_current_item_action.return_value = mocked_action
279+ mocked_action_shortcuts.return_value = [QtCore.Qt.Key_Escape]
280+ mocked_get_shortcut_string.return_value = 'Esc'
281+
282+ # WHEN: The default radio button is clicked
283+ self.form.on_default_radio_button_clicked(True)
284+
285+ # THEN: The shorcuts should be copied across
286+ mocked_current_item_action.assert_called_with()
287+ mocked_action_shortcuts.assert_called_with(mocked_action)
288+ mocked_refresh_shortcut_list.assert_called_with()
289+ mocked_set_text.assert_called_with('Esc')
290+
291+ def on_custom_radio_button_not_toggled_test(self):
292+ """
293+ Test that the custom radio button method exits early when the button is not toggled
294+ """
295+ # GIVEN: A not-toggled custom radio button
296+ with patch.object(self.form, '_current_item_action') as mocked_current_item_action:
297+
298+ # WHEN: The clicked method is called
299+ self.form.on_custom_radio_button_clicked(False)
300+
301+ # THEN: The method should exit early (i.e. the rest of the methods are not called)
302+ self.assertEqual(0, mocked_current_item_action.call_count)
303+
304+ def on_custom_radio_button_clicked_test(self):
305+ """
306+ Test that the values are copied across correctly when the custom radio button is selected
307+ """
308+ # GIVEN: Some mocked out methods, a current action, and some shortcuts
309+ with patch.object(self.form, '_current_item_action') as mocked_current_item_action, \
310+ patch.object(self.form, '_action_shortcuts') as mocked_action_shortcuts, \
311+ patch.object(self.form, 'refresh_shortcut_list') as mocked_refresh_shortcut_list, \
312+ patch.object(self.form, 'get_shortcut_string') as mocked_get_shortcut_string, \
313+ patch.object(self.form.primary_push_button, 'setText') as mocked_set_text:
314+ mocked_action = MagicMock()
315+ mocked_current_item_action.return_value = mocked_action
316+ mocked_action_shortcuts.return_value = [QtCore.Qt.Key_Escape]
317+ mocked_get_shortcut_string.return_value = 'Esc'
318+
319+ # WHEN: The custom radio button is clicked
320+ self.form.on_custom_radio_button_clicked(True)
321+
322+ # THEN: The shorcuts should be copied across
323+ mocked_current_item_action.assert_called_with()
324+ mocked_action_shortcuts.assert_called_with(mocked_action)
325+ mocked_refresh_shortcut_list.assert_called_with()
326+ mocked_set_text.assert_called_with('Esc')
327+