Merge lp:~suutari-olli/openlp/click-slide-to-go-live-from-blank into lp:openlp

Proposed by Azaziah on 2016-03-15
Status: Superseded
Proposed branch: lp:~suutari-olli/openlp/click-slide-to-go-live-from-blank
Merge into: lp:openlp
Diff against target: 235 lines (+137/-2)
4 files modified
openlp/core/common/settings.py (+1/-0)
openlp/core/ui/generaltab.py (+7/-0)
openlp/core/ui/slidecontroller.py (+32/-2)
tests/functional/openlp_core_ui/test_slidecontroller.py (+97/-0)
To merge this branch: bzr merge lp:~suutari-olli/openlp/click-slide-to-go-live-from-blank
Reviewer Review Type Date Requested Status
Tomas Groth 2016-03-15 Needs Fixing on 2016-03-15
Review via email: mp+289026@code.launchpad.net

This proposal has been superseded by a proposal from 2016-04-01.

Description of the change

This branch introduces the functionality of unblanking
display from Blank to Black/Theme/Desktop for:

a) Clicking slide in “Live panel”
b) Next/Previous shortcuts (Green arrows)
c) Go to verse x.
d) When starting automatic playback (To end or Loop)
Also added “Unblank display when changing slide in Live” to advanced
options tab for disabling/enabling this behavior for a-c.

Additionally this branch also includes fix for bug
https://bugs.launchpad.net/openlp/+bug/1531691
Do note that this branch does not fix this for Escape item blanking,
creating yet an another Escape exclusive bug.

The only reason Escape item has been a good alternative for other
blank to methods is the functionality of resuming Live by clicking
slides and the fact it worked in single screen scenarios.
I can’t see any reason why it should not be removed after this branch
is merged since the single screen issue was already fixed earlier.

Test coverage is not yet increased.
If it must be done, what has to be tested?

--------------------------------
lp:~suutari-olli/openlp/click-slide-to-go-live-from-blank (revision 2630)
[←[1;32mSUCCESS←[1;m] https://ci.openlp.io/job/Branch-01-Pull/1318/
[←[1;32mSUCCESS←[1;m] https://ci.openlp.io/job/Branch-02-Functional-Tests/1240/
[←[1;32mSUCCESS←[1;m] https://ci.openlp.io/job/Branch-03-Interface-Tests/1179/
[←[1;32mSUCCESS←[1;m] https://ci.openlp.io/job/Branch-04a-Windows_Functional_Tests/1014/
[←[1;32mSUCCESS←[1;m] https://ci.openlp.io/job/Branch-04b-Windows_Interface_Tests/605/
[←[1;32mSUCCESS←[1;m] https://ci.openlp.io/job/Branch-05a-Code_Analysis/672/
[←[1;31mFAILURE←[1;m] https://ci.openlp.io/job/Branch-05b-Test_Coverage/540/

To post a comment you must log in.
2631. By Azaziah on 2016-03-15

Removed duplicate: self.on_hide_display(True)
(Was trying to create/test a test but failed and forgot to take it away)

Tomas Groth (tomasgroth) wrote :

Just tested a bit.
You have introduced the "Click live slide to unblank" setting, but a "Unblank display when adding new item" also exists in the general tab. You should probably move yours to be under the exiting one to keep similar settings in the same place. Currently your code doesn't honor the "Unblank display when adding new item", which it will have to do. As it is now the item goes live no matter if the setting is enabled or not.
Also the new setting should be "false" as default, this is new behavior, so users should enabled it if they want it.
Also added a code-comment below.

review: Needs Fixing
2632. By Azaziah on 2016-03-15

In this merge:
- Moved setting for controlling unblanking behaviour to General options tab.
- Removed it from advanced tab
- Changed default setting to "no"
- Looped playback (once or to end) is now linked to this setting
- Unblanking slides on click -.- no longer unblanks display when sending new items live if
  "Unblank display when sending new item to live" is not enabled. -.-
- Doubleclicking preview -.- ^^
- Improved some comments

To do:
Test(s)?

Azaziah (suutari-olli) wrote :

Hi Tomas and thank you for your comments!

"Unblank display when adding new item" also exists in the general tab. You should probably move yours to be under the exiting one to keep similar settings in the same place. Currently your code doesn't honor the "Unblank display when adding new item

# Done and Done, now also honoring double clicking preview

Also the new setting should be "false" as default, this is new behavior, so users should enabled it if they want it.

# Done
# Currently this is default behavior for Escape item and probably easier
to use than our current blank to modes. I think this and some other settings
should eventually be changed to be more user friendly by default.

Tomas Groth (tomasgroth) wrote :

Looks good now. As you mention in one of your source-comments the previous slide is shortly visible when display is unblanked. Don't know if it can be helped.
Added a comment to the code below.
Besides that, you need tests :)

review: Needs Fixing
Azaziah (suutari-olli) wrote :

Thanks again,

if by previous slide being shortly visible you mean it happens once you change slide inside the Live Panel
and the transition effect is applied, yes that can be changed. I've heard people complaining there's no transition effects when unblanking or changing items so maybe it should be left as it is since it would mean loosing effects.

If you were talking about this happening on song edit:
Think it would be possible but would require quite a effort,
maybe we can let it pass for the time being, it's still mostly fixed.

I really suck at writing tests, is one enough for a rookie?

I also replied to the code comment.

2633. By Azaziah on 2016-04-01

Added 3 tests for replacing Live item from service manager while display is blanked. (One for each)

2634. By Azaziah on 2016-04-01

Merged to trunk (1.4.2016)

2635. By Azaziah on 2016-04-01

- Fixed issue where PPT/Impress is not unblanked on "Previous/Next" (Green arrows).

2636. By Azaziah on 2016-04-03

Changed Live to live (lowercaps) for controlling this setting to match other settings.

2637. By Azaziah on 2016-04-10

Merged trunk on 11.4.2016

2638. By Azaziah on 2016-04-12

Merged trunk on 13.4.16

2639. By Azaziah on 2016-04-13

Changed spelling of live back to Live (Capitalized) on settings.

2640. By Azaziah on 2016-04-17

- Fixed bug 1462420 - Double clicking Preview adds item to Service countless times
  (Added hidden setting for controlling this, it is set to True once double clicking
  has added item to Service and gets reset to False once new item is sent to preview.

2641. By Azaziah on 2016-04-17

Fixed bug 1462420 (Double click on the preview duplicated the element in the service manger)
- Added a hidden setting for controlling this behaviour.
 It is reset if any item is sent to preview from library.
 Sending the same item to service multiple times is still possible by using the "Add icon"

2642. By Azaziah on 2016-04-17

Turned the new setting into question.

2643. By Azaziah on 2016-04-17

Made a better fix for fixing bug where display is unblanked on editing current live item.
This now sets a hidden setting to true while processing Live item and then changes it back to false.
Display is thus not unblanked at all during the process. (Old fix showed the edited slide for a small time)

Downside: All the new tests were based on the old method and thus they were removed.

2644. By Azaziah on 2016-04-17

Made a better fix for fixing bug where display is unblanked on editing current live item.
This now sets a hidden setting to true while processing Live item and then changes it back to false.
Display is thus not unblanked at all during the process. (Old fix showed the edited slide for a small time)

Downside: All the new tests were based on the old method and thus they were removed.

2645. By Azaziah on 2016-04-17

- Removed _ from end of one setting name.
- Fixed ident on replace_service_manager

2646. By Azaziah on 2016-04-20

- Added two tests for checking if doubleclicking preview should add item to service or send it to live.

2647. By Azaziah on 2016-04-20

Noticed I had removed one test from end of the file, added it back.

2648. By Azaziah on 2016-04-27

Added this to program startup code, should replace_service_manager_item ever crash the program.

Settings().setValue('core/is live item edited and replaced', False)

2649. By Azaziah on 2016-06-13

merged trunk on 14.6.16

2650. By Azaziah on 2016-06-26

- Turned the two new hidden settings into registry flags

2651. By Azaziah on 2016-06-26

Comment cleanup / Improvements

2652. By Azaziah on 2016-06-26

- Merged trunk on 27.6.16

2653. By Azaziah on 2016-07-14

- Tried to make the new text work with the registry changes but failed.
 > Test is broken, do not merge!

2654. By Azaziah on 2016-07-14

Merged trunk on 14.7.16

2655. By Azaziah on 2016-07-14

pep8 fixes, test still broken.

2656. By Azaziah on 2016-07-16

Fixed the tests.

2657. By Azaziah on 2016-07-16

- Reduced comments
- Removed unrequired reg_value from test.

2658. By Azaziah on 2016-07-17

- Fixed the issue where items sent to Preview from Service may cause tracebacks.

2659. By Azaziah on 2016-07-17

- Moved the 2nd new registry flag from one init to an another init which also has the 1st

2660. By Azaziah on 2016-07-17

- Moved them to another init since something broke

2661. By Azaziah on 2016-07-17

- removed one unrequired if statement.

2662. By Azaziah on 2016-07-31

- Merged trunk on 31.7.16

2663. By Azaziah on 2016-08-09

- Merged trunk on 10/8/16.

2664. By Azaziah on 2016-08-10

- Merged trunk and resolved conflict that was created by ui-messages-part-1 branch.

Unmerged revisions

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-03-15 21:34:58 +0000
3+++ openlp/core/common/settings.py 2016-04-01 13:12:45 +0000
4@@ -141,6 +141,7 @@
5 'core/auto preview': False,
6 'core/audio start paused': True,
7 'core/auto unblank': False,
8+ 'core/click live slide to unblank': False,
9 'core/blank warning': False,
10 'core/ccli number': '',
11 'core/has run wizard': False,
12
13=== modified file 'openlp/core/ui/generaltab.py'
14--- openlp/core/ui/generaltab.py 2016-01-16 20:13:41 +0000
15+++ openlp/core/ui/generaltab.py 2016-04-01 13:12:45 +0000
16@@ -173,6 +173,9 @@
17 self.auto_unblank_check_box = QtWidgets.QCheckBox(self.settings_group_box)
18 self.auto_unblank_check_box.setObjectName('auto_unblank_check_box')
19 self.settings_layout.addRow(self.auto_unblank_check_box)
20+ self.click_live_slide_to_unblank_check_box = QtWidgets.QCheckBox(self.settings_group_box)
21+ self.click_live_slide_to_unblank_check_box.setObjectName('click_live_slide_to_unblank_')
22+ self.settings_layout.addRow(self.click_live_slide_to_unblank_check_box)
23 self.auto_preview_check_box = QtWidgets.QCheckBox(self.settings_group_box)
24 self.auto_preview_check_box.setObjectName('auto_preview_check_box')
25 self.settings_layout.addRow(self.auto_preview_check_box)
26@@ -217,6 +220,8 @@
27 self.save_check_service_check_box.setText(translate('OpenLP.GeneralTab',
28 'Prompt to save before starting a new service'))
29 self.auto_unblank_check_box.setText(translate('OpenLP.GeneralTab', 'Unblank display when adding new live item'))
30+ self.click_live_slide_to_unblank_check_box.setText(translate('OpenLP.GeneralTab',
31+ 'Unblank display when changing slide in Live'))
32 self.auto_preview_check_box.setText(translate('OpenLP.GeneralTab',
33 'Automatically preview next item in service'))
34 self.timeout_label.setText(translate('OpenLP.GeneralTab', 'Timed slide interval:'))
35@@ -250,6 +255,7 @@
36 self.password_edit.setText(settings.value('songselect password'))
37 self.save_check_service_check_box.setChecked(settings.value('save prompt'))
38 self.auto_unblank_check_box.setChecked(settings.value('auto unblank'))
39+ self.click_live_slide_to_unblank_check_box.setChecked(settings.value('click live slide to unblank'))
40 self.display_on_monitor_check.setChecked(self.screens.display)
41 self.warning_check_box.setChecked(settings.value('blank warning'))
42 self.auto_open_check_box.setChecked(settings.value('auto open'))
43@@ -287,6 +293,7 @@
44 settings.setValue('update check', self.check_for_updates_check_box.isChecked())
45 settings.setValue('save prompt', self.save_check_service_check_box.isChecked())
46 settings.setValue('auto unblank', self.auto_unblank_check_box.isChecked())
47+ settings.setValue('click live slide to unblank', self.click_live_slide_to_unblank_check_box.isChecked())
48 settings.setValue('auto preview', self.auto_preview_check_box.isChecked())
49 settings.setValue('loop delay', self.timeout_spin_box.value())
50 settings.setValue('ccli number', self.number_edit.displayText())
51
52=== modified file 'openlp/core/ui/slidecontroller.py'
53--- openlp/core/ui/slidecontroller.py 2016-03-31 16:34:22 +0000
54+++ openlp/core/ui/slidecontroller.py 2016-04-01 13:12:45 +0000
55@@ -789,11 +789,28 @@
56 def replace_service_manager_item(self, item):
57 """
58 Replacement item following a remote edit
59+ This action also takes place when a song that is sent to live from Service Manager is edited.
60+ If display is blanked, this will update the song and then re-blank the display.
61+ As result, lyrics are flashed on screen for a very short time before re-blanking happens. (Bug)
62+ This happens only when Automatic unblanking is enabled when new item is sen to Live,
63+ if it's not enabled they won't flash.
64
65 :param item: The current service item
66 """
67 if item == self.service_item:
68- self._process_item(item, self.preview_widget.current_slide_number())
69+ if not self.hide_mode():
70+ self._process_item(item, self.preview_widget.current_slide_number())
71+ # "isChecked" method is required for checking blanks, on_xx_display(False) does not work.
72+ elif self.hide_mode():
73+ if self.blank_screen.isChecked():
74+ self._process_item(item, self.preview_widget.current_slide_number())
75+ self.on_blank_display(True)
76+ elif self.theme_screen.isChecked():
77+ self._process_item(item, self.preview_widget.current_slide_number())
78+ self.on_theme_display(True)
79+ elif self.desktop_screen.isChecked():
80+ self._process_item(item, self.preview_widget.current_slide_number())
81+ self.on_hide_display(True)
82
83 def add_service_manager_item(self, item, slide_no):
84 """
85@@ -1090,6 +1107,14 @@
86 self.log_debug('Could not get lock in slide_selected after waiting %f, skip to avoid deadlock.'
87 % timeout)
88 return
89+ # If "click live slide to unblank" is enabled, unblank the display.
90+ # Note: If this if statement is placed at the bottom of this function instead of top slide transitions are lost.
91+ if self.is_live and Settings().value('core/click live slide to unblank'):
92+ # With this display stays blanked when "auto unblank" setting is not enabled and new item is sent to Live.
93+ if not Settings().value('core/auto unblank') and start:
94+ ()
95+ else:
96+ Registry().execute('slidecontroller_live_unblank')
97 row = self.preview_widget.current_slide_number()
98 old_selected_row = self.selected_row
99 self.selected_row = 0
100@@ -1258,6 +1283,8 @@
101 self.play_slides_once.setText(UiStrings().PlaySlidesToEnd)
102 self.play_slides_menu.setDefaultAction(self.play_slides_loop)
103 self.play_slides_once.setChecked(False)
104+ if Settings().value('core/click live slide to unblank'):
105+ Registry().execute('slidecontroller_live_unblank')
106 else:
107 self.play_slides_loop.setIcon(build_icon(':/media/media_time.png'))
108 self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop)
109@@ -1281,6 +1308,8 @@
110 self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop)
111 self.play_slides_menu.setDefaultAction(self.play_slides_once)
112 self.play_slides_loop.setChecked(False)
113+ if Settings().value('core/click live slide to unblank'):
114+ Registry().execute('slidecontroller_live_unblank')
115 else:
116 self.play_slides_once.setIcon(build_icon(':/media/media_time'))
117 self.play_slides_once.setText(UiStrings().PlaySlidesToEnd)
118@@ -1342,7 +1371,8 @@
119 Registry().execute('%s_stop' % self.service_item.name.lower(), [self.service_item, self.is_live])
120 if self.service_item.is_media():
121 self.on_media_close()
122- self.on_go_live()
123+ if Settings().value('core/auto unblank'):
124+ self.on_go_live()
125 else:
126 self.on_preview_add_to_service()
127
128
129=== modified file 'tests/functional/openlp_core_ui/test_slidecontroller.py'
130--- tests/functional/openlp_core_ui/test_slidecontroller.py 2016-02-27 14:25:31 +0000
131+++ tests/functional/openlp_core_ui/test_slidecontroller.py 2016-04-01 13:12:45 +0000
132@@ -538,6 +538,103 @@
133 mocked_preview_widget.current_slide_number.assert_called_with()
134 mocked_process_item.assert_called_once_with(mocked_item, 7)
135
136+ def replace_service_manager_item_on_blank_display_test(self):
137+ """
138+ Test that when the service item is replaced, display remains blanked if it was blanked.
139+ """
140+ # GIVEN: A slide controller and a new item to add, blanked display.
141+ mocked_item = MagicMock()
142+ mocked_preview_widget = MagicMock()
143+ mocked_preview_widget.current_slide_number = MagicMock()
144+ mocked_process_item = MagicMock()
145+ slide_controller = SlideController(None)
146+ slide_controller.preview_widget = mocked_preview_widget
147+ slide_controller._process_item = mocked_process_item
148+ slide_controller.service_item = mocked_item
149+ slide_controller.hide_menu = MagicMock()
150+ slide_controller.hide_mode = MagicMock()
151+ slide_controller.hide_mode.return_value = True
152+ slide_controller.blank_screen = MagicMock()
153+ slide_controller.blank_screen.isChecked = MagicMock()
154+ slide_controller.blank_screen.isChecked.return_value = True
155+ slide_controller.on_blank_display = mocked_item
156+ slide_controller.theme_screen = MagicMock()
157+ slide_controller.desktop_screen = MagicMock()
158+ slide_controller.log_debug = MagicMock()
159+
160+ # WHEN: The service item is replaced
161+ slide_controller.replace_service_manager_item(mocked_item)
162+
163+ # THEN: The display should remain blanked
164+ slide_controller.on_blank_display.assert_called_once_with(True)
165+
166+ def replace_service_manager_item_on_theme_display_test(self):
167+ """
168+ Test that when the service item is replaced, display remains blanked if it was blanked.
169+ """
170+ # GIVEN: A slide controller and a new item to add, blanked display.
171+ mocked_item = MagicMock()
172+ mocked_preview_widget = MagicMock()
173+ mocked_preview_widget.current_slide_number = MagicMock()
174+ mocked_process_item = MagicMock()
175+ slide_controller = SlideController(None)
176+ slide_controller.preview_widget = mocked_preview_widget
177+ slide_controller._process_item = mocked_process_item
178+ slide_controller.service_item = mocked_item
179+ slide_controller.hide_menu = MagicMock()
180+ slide_controller.hide_mode = MagicMock()
181+ slide_controller.hide_mode.return_value = True
182+ slide_controller.blank_screen = MagicMock()
183+ slide_controller.blank_screen.isChecked = MagicMock()
184+ slide_controller.blank_screen.isChecked.return_value = False
185+ slide_controller.theme_screen = MagicMock()
186+ slide_controller.theme_screen.isChecked = MagicMock()
187+ slide_controller.theme_screen.isChecked.return_value = True
188+ slide_controller.on_theme_display = mocked_item
189+ slide_controller.desktop_screen = MagicMock()
190+ slide_controller.log_debug = MagicMock()
191+
192+ # WHEN: The service item is replaced
193+ slide_controller.replace_service_manager_item(mocked_item)
194+
195+ # THEN: The display should remain blanked
196+ slide_controller.on_theme_display.assert_called_once_with(True)
197+
198+ def replace_service_manager_item_on_hide_display_test(self):
199+ """
200+ Test that when the service item is replaced, display remains blanked if it was blanked.
201+ """
202+ # GIVEN: A slide controller and a new item to add, blanked display.
203+ mocked_item = MagicMock()
204+ mocked_preview_widget = MagicMock()
205+ mocked_preview_widget.current_slide_number = MagicMock()
206+ mocked_process_item = MagicMock()
207+ slide_controller = SlideController(None)
208+ slide_controller.preview_widget = mocked_preview_widget
209+ slide_controller._process_item = mocked_process_item
210+ slide_controller.service_item = mocked_item
211+ slide_controller.hide_menu = MagicMock()
212+ slide_controller.hide_mode = MagicMock()
213+ slide_controller.hide_mode.return_value = True
214+ slide_controller.blank_screen = MagicMock()
215+ slide_controller.blank_screen.isChecked = MagicMock()
216+ slide_controller.blank_screen.isChecked.return_value = False
217+ slide_controller.theme_screen = MagicMock()
218+ slide_controller.theme_screen.isChecked = MagicMock()
219+ slide_controller.theme_screen.isChecked.return_value = False
220+ slide_controller.on_theme_display = mocked_item
221+ slide_controller.desktop_screen = MagicMock()
222+ slide_controller.desktop_screen.isChecked = MagicMock()
223+ slide_controller.desktop_screen.isChecked.return_value = True
224+ slide_controller.on_hide_display = MagicMock()
225+ slide_controller.log_debug = MagicMock()
226+
227+ # WHEN: The service item is replaced
228+ slide_controller.replace_service_manager_item(mocked_item)
229+
230+ # THEN: The display should remain blanked
231+ slide_controller.on_hide_display.assert_called_once_with(True)
232+
233 def on_slide_blank_test(self):
234 """
235 Test on_slide_blank