← Back to team overview

openlp-core team mailing list archive

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

 

Azaziah has proposed merging lp:~suutari-olli/openlp/click-slide-to-go-live-from-blank into lp:openlp.

Requested reviews:
  Tomas Groth (tomasgroth)
Related bugs:
  Bug #1531691 in OpenLP: "Song is sent back to live after edit if blanked"
  https://bugs.launchpad.net/openlp/+bug/1531691

For more details, see:
https://code.launchpad.net/~suutari-olli/openlp/click-slide-to-go-live-from-blank/+merge/290824

In this re-proposal:

Added 3 tests for checking display is re-blanked if it was blanked before re-processing edited Live item.

Also fixed the issue where Next/Previous slide does not unblank display for PowerPoint/Impress.


lp:~suutari-olli/openlp/click-slide-to-go-live-from-blank (revision 2634)
[←[1;32mSUCCESS←[1;m] https://ci.openlp.io/job/Branch-01-Pull/1361/
[←[1;32mSUCCESS←[1;m] https://ci.openlp.io/job/Branch-02-Functional-Tests/1280/
[←[1;32mSUCCESS←[1;m] https://ci.openlp.io/job/Branch-03-Interface-Tests/1219/
[←[1;32mSUCCESS←[1;m] https://ci.openlp.io/job/Branch-04a-Windows_Functional_Tests/1052/
[←[1;32mSUCCESS←[1;m] https://ci.openlp.io/job/Branch-04b-Windows_Interface_Tests/643/
[←[1;32mSUCCESS←[1;m] https://ci.openlp.io/job/Branch-05a-Code_Analysis/710/
[←[1;32mSUCCESS←[1;m] https://ci.openlp.io/job/Branch-05b-Test_Coverage/578/



-------------------------------------------------------------------------

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.


-- 
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/common/settings.py'
--- openlp/core/common/settings.py	2016-03-20 15:00:15 +0000
+++ openlp/core/common/settings.py	2016-04-03 16:06:05 +0000
@@ -142,6 +142,7 @@
         'core/auto preview': False,
         'core/audio start paused': True,
         'core/auto unblank': False,
+        'core/click live slide to unblank': False,
         'core/blank warning': False,
         'core/ccli number': '',
         'core/has run wizard': False,

=== modified file 'openlp/core/ui/generaltab.py'
--- openlp/core/ui/generaltab.py	2016-01-16 20:13:41 +0000
+++ openlp/core/ui/generaltab.py	2016-04-03 16:06:05 +0000
@@ -173,6 +173,9 @@
         self.auto_unblank_check_box = QtWidgets.QCheckBox(self.settings_group_box)
         self.auto_unblank_check_box.setObjectName('auto_unblank_check_box')
         self.settings_layout.addRow(self.auto_unblank_check_box)
+        self.click_live_slide_to_unblank_check_box = QtWidgets.QCheckBox(self.settings_group_box)
+        self.click_live_slide_to_unblank_check_box.setObjectName('click_live_slide_to_unblank_')
+        self.settings_layout.addRow(self.click_live_slide_to_unblank_check_box)
         self.auto_preview_check_box = QtWidgets.QCheckBox(self.settings_group_box)
         self.auto_preview_check_box.setObjectName('auto_preview_check_box')
         self.settings_layout.addRow(self.auto_preview_check_box)
@@ -217,6 +220,8 @@
         self.save_check_service_check_box.setText(translate('OpenLP.GeneralTab',
                                                   'Prompt to save before starting a new service'))
         self.auto_unblank_check_box.setText(translate('OpenLP.GeneralTab', 'Unblank display when adding new live item'))
+        self.click_live_slide_to_unblank_check_box.setText(translate('OpenLP.GeneralTab',
+                                                           'Unblank display when changing slide in live'))
         self.auto_preview_check_box.setText(translate('OpenLP.GeneralTab',
                                                       'Automatically preview next item in service'))
         self.timeout_label.setText(translate('OpenLP.GeneralTab', 'Timed slide interval:'))
@@ -250,6 +255,7 @@
         self.password_edit.setText(settings.value('songselect password'))
         self.save_check_service_check_box.setChecked(settings.value('save prompt'))
         self.auto_unblank_check_box.setChecked(settings.value('auto unblank'))
+        self.click_live_slide_to_unblank_check_box.setChecked(settings.value('click live slide to unblank'))
         self.display_on_monitor_check.setChecked(self.screens.display)
         self.warning_check_box.setChecked(settings.value('blank warning'))
         self.auto_open_check_box.setChecked(settings.value('auto open'))
@@ -287,6 +293,7 @@
         settings.setValue('update check', self.check_for_updates_check_box.isChecked())
         settings.setValue('save prompt', self.save_check_service_check_box.isChecked())
         settings.setValue('auto unblank', self.auto_unblank_check_box.isChecked())
+        settings.setValue('click live slide to unblank', self.click_live_slide_to_unblank_check_box.isChecked())
         settings.setValue('auto preview', self.auto_preview_check_box.isChecked())
         settings.setValue('loop delay', self.timeout_spin_box.value())
         settings.setValue('ccli number', self.number_edit.displayText())

=== modified file 'openlp/core/ui/slidecontroller.py'
--- openlp/core/ui/slidecontroller.py	2016-03-31 16:34:22 +0000
+++ openlp/core/ui/slidecontroller.py	2016-04-03 16:06:05 +0000
@@ -789,11 +789,28 @@
     def replace_service_manager_item(self, item):
         """
         Replacement item following a remote edit
+        This action  also takes place when a song that is sent to live from Service Manager is edited.
+        If display is blanked, this will update the song and then re-blank the display.
+        As result, lyrics are flashed on screen for a very short time before re-blanking happens. (Bug)
+        This happens only when Automatic unblanking is enabled when new item is sen to Live,
+        if it's not enabled they won't flash.
 
         :param item: The current service item
         """
         if item == self.service_item:
-            self._process_item(item, self.preview_widget.current_slide_number())
+            if not self.hide_mode():
+                self._process_item(item, self.preview_widget.current_slide_number())
+            # "isChecked" method is required for checking blanks, on_xx_display(False) does not work.
+            elif self.hide_mode():
+                if self.blank_screen.isChecked():
+                    self._process_item(item, self.preview_widget.current_slide_number())
+                    self.on_blank_display(True)
+                elif self.theme_screen.isChecked():
+                    self._process_item(item, self.preview_widget.current_slide_number())
+                    self.on_theme_display(True)
+                elif self.desktop_screen.isChecked():
+                    self._process_item(item, self.preview_widget.current_slide_number())
+                    self.on_hide_display(True)
 
     def add_service_manager_item(self, item, slide_no):
         """
@@ -1090,6 +1107,14 @@
                 self.log_debug('Could not get lock in slide_selected after waiting %f, skip to avoid deadlock.'
                                % timeout)
             return
+        # If "click live slide to unblank" is enabled, unblank the display.
+        # Note: If this if statement is placed at the bottom of this function instead of top slide transitions are lost.
+        if self.is_live and Settings().value('core/click live slide to unblank'):
+            # With this display stays blanked when "auto unblank" setting is not enabled and new item is sent to Live.
+            if not Settings().value('core/auto unblank') and start:
+                ()
+            else:
+                Registry().execute('slidecontroller_live_unblank')
         row = self.preview_widget.current_slide_number()
         old_selected_row = self.selected_row
         self.selected_row = 0
@@ -1258,6 +1283,8 @@
             self.play_slides_once.setText(UiStrings().PlaySlidesToEnd)
             self.play_slides_menu.setDefaultAction(self.play_slides_loop)
             self.play_slides_once.setChecked(False)
+            if Settings().value('core/click live slide to unblank'):
+                Registry().execute('slidecontroller_live_unblank')
         else:
             self.play_slides_loop.setIcon(build_icon(':/media/media_time.png'))
             self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop)
@@ -1281,6 +1308,8 @@
             self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop)
             self.play_slides_menu.setDefaultAction(self.play_slides_once)
             self.play_slides_loop.setChecked(False)
+            if Settings().value('core/click live slide to unblank'):
+                Registry().execute('slidecontroller_live_unblank')
         else:
             self.play_slides_once.setIcon(build_icon(':/media/media_time'))
             self.play_slides_once.setText(UiStrings().PlaySlidesToEnd)
@@ -1342,7 +1371,8 @@
                     Registry().execute('%s_stop' % self.service_item.name.lower(), [self.service_item, self.is_live])
                 if self.service_item.is_media():
                     self.on_media_close()
-                self.on_go_live()
+                if Settings().value('core/auto unblank'):
+                    self.on_go_live()
             else:
                 self.on_preview_add_to_service()
 

=== modified file 'openlp/plugins/presentations/lib/messagelistener.py'
--- openlp/plugins/presentations/lib/messagelistener.py	2016-02-05 20:11:36 +0000
+++ openlp/plugins/presentations/lib/messagelistener.py	2016-04-03 16:06:05 +0000
@@ -26,7 +26,7 @@
 
 from PyQt5 import QtCore
 
-from openlp.core.common import Registry
+from openlp.core.common import Registry, Settings
 from openlp.core.ui import HideMode
 from openlp.core.lib import ServiceItemContext, ServiceItem
 from openlp.plugins.presentations.lib.pdfcontroller import PDF_CONTROLLER_FILETYPES
@@ -419,6 +419,8 @@
         is_live = message[1]
         if is_live:
             self.live_handler.next()
+            if Settings().value('core/click live slide to unblank'):
+                Registry().execute('slidecontroller_live_unblank')
         else:
             self.preview_handler.next()
 
@@ -431,6 +433,8 @@
         is_live = message[1]
         if is_live:
             self.live_handler.previous()
+            if Settings().value('core/click live slide to unblank'):
+                Registry().execute('slidecontroller_live_unblank')
         else:
             self.preview_handler.previous()
 

=== modified file 'tests/functional/openlp_core_ui/test_slidecontroller.py'
--- tests/functional/openlp_core_ui/test_slidecontroller.py	2016-02-27 14:25:31 +0000
+++ tests/functional/openlp_core_ui/test_slidecontroller.py	2016-04-03 16:06:05 +0000
@@ -538,6 +538,103 @@
         mocked_preview_widget.current_slide_number.assert_called_with()
         mocked_process_item.assert_called_once_with(mocked_item, 7)
 
+    def replace_service_manager_item_on_blank_display_test(self):
+        """
+        Test that when the service item is replaced, display remains blanked if it was blanked.
+        """
+        # GIVEN: A slide controller and a new item to add, blanked display.
+        mocked_item = MagicMock()
+        mocked_preview_widget = MagicMock()
+        mocked_preview_widget.current_slide_number = MagicMock()
+        mocked_process_item = MagicMock()
+        slide_controller = SlideController(None)
+        slide_controller.preview_widget = mocked_preview_widget
+        slide_controller._process_item = mocked_process_item
+        slide_controller.service_item = mocked_item
+        slide_controller.hide_menu = MagicMock()
+        slide_controller.hide_mode = MagicMock()
+        slide_controller.hide_mode.return_value = True
+        slide_controller.blank_screen = MagicMock()
+        slide_controller.blank_screen.isChecked = MagicMock()
+        slide_controller.blank_screen.isChecked.return_value = True
+        slide_controller.on_blank_display = mocked_item
+        slide_controller.theme_screen = MagicMock()
+        slide_controller.desktop_screen = MagicMock()
+        slide_controller.log_debug = MagicMock()
+
+        # WHEN: The service item is replaced
+        slide_controller.replace_service_manager_item(mocked_item)
+
+        # THEN: The display should remain blanked
+        slide_controller.on_blank_display.assert_called_once_with(True)
+
+    def replace_service_manager_item_on_theme_display_test(self):
+        """
+        Test that when the service item is replaced, display remains blanked if it was blanked.
+        """
+        # GIVEN: A slide controller and a new item to add, blanked display.
+        mocked_item = MagicMock()
+        mocked_preview_widget = MagicMock()
+        mocked_preview_widget.current_slide_number = MagicMock()
+        mocked_process_item = MagicMock()
+        slide_controller = SlideController(None)
+        slide_controller.preview_widget = mocked_preview_widget
+        slide_controller._process_item = mocked_process_item
+        slide_controller.service_item = mocked_item
+        slide_controller.hide_menu = MagicMock()
+        slide_controller.hide_mode = MagicMock()
+        slide_controller.hide_mode.return_value = True
+        slide_controller.blank_screen = MagicMock()
+        slide_controller.blank_screen.isChecked = MagicMock()
+        slide_controller.blank_screen.isChecked.return_value = False
+        slide_controller.theme_screen = MagicMock()
+        slide_controller.theme_screen.isChecked = MagicMock()
+        slide_controller.theme_screen.isChecked.return_value = True
+        slide_controller.on_theme_display = mocked_item
+        slide_controller.desktop_screen = MagicMock()
+        slide_controller.log_debug = MagicMock()
+
+        # WHEN: The service item is replaced
+        slide_controller.replace_service_manager_item(mocked_item)
+
+        # THEN: The display should remain blanked
+        slide_controller.on_theme_display.assert_called_once_with(True)
+
+    def replace_service_manager_item_on_hide_display_test(self):
+        """
+        Test that when the service item is replaced, display remains blanked if it was blanked.
+        """
+        # GIVEN: A slide controller and a new item to add, blanked display.
+        mocked_item = MagicMock()
+        mocked_preview_widget = MagicMock()
+        mocked_preview_widget.current_slide_number = MagicMock()
+        mocked_process_item = MagicMock()
+        slide_controller = SlideController(None)
+        slide_controller.preview_widget = mocked_preview_widget
+        slide_controller._process_item = mocked_process_item
+        slide_controller.service_item = mocked_item
+        slide_controller.hide_menu = MagicMock()
+        slide_controller.hide_mode = MagicMock()
+        slide_controller.hide_mode.return_value = True
+        slide_controller.blank_screen = MagicMock()
+        slide_controller.blank_screen.isChecked = MagicMock()
+        slide_controller.blank_screen.isChecked.return_value = False
+        slide_controller.theme_screen = MagicMock()
+        slide_controller.theme_screen.isChecked = MagicMock()
+        slide_controller.theme_screen.isChecked.return_value = False
+        slide_controller.on_theme_display = mocked_item
+        slide_controller.desktop_screen = MagicMock()
+        slide_controller.desktop_screen.isChecked = MagicMock()
+        slide_controller.desktop_screen.isChecked.return_value = True
+        slide_controller.on_hide_display = MagicMock()
+        slide_controller.log_debug = MagicMock()
+
+        # WHEN: The service item is replaced
+        slide_controller.replace_service_manager_item(mocked_item)
+
+        # THEN: The display should remain blanked
+        slide_controller.on_hide_display.assert_called_once_with(True)
+
     def on_slide_blank_test(self):
         """
         Test on_slide_blank


Follow ups