diff --git a/openlp/core/common/settings.py b/openlp/core/common/settings.py index a812e856b..2caf04dab 100644 --- a/openlp/core/common/settings.py +++ b/openlp/core/common/settings.py @@ -141,6 +141,7 @@ class Settings(QtCore.QSettings): '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, diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index c7c84f912..2edea93cf 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -488,6 +488,7 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties): 'You must select one or more items to preview.')) else: log.debug('%s Preview requested' % self.plugin.name) + Registry().set_flag('has doubleclick added item to service', False) service_item = self.build_service_item() if service_item: service_item.from_plugin = True diff --git a/openlp/core/ui/generaltab.py b/openlp/core/ui/generaltab.py index 3abe8eb7b..463aad73f 100644 --- a/openlp/core/ui/generaltab.py +++ b/openlp/core/ui/generaltab.py @@ -209,6 +209,9 @@ class GeneralTab(SettingsTab): 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) @@ -258,6 +261,8 @@ class GeneralTab(SettingsTab): self.settings_group_box.setTitle(translate('OpenLP.GeneralTab', 'Application Settings')) self.save_check_service_check_box.setText(translate('OpenLP.GeneralTab', 'Prompt to save before starting a new service')) + self.click_live_slide_to_unblank_check_box.setText(translate('OpenLP.GeneralTab', + 'Unblank display when changing slide in Live')) self.auto_unblank_check_box.setText(translate('OpenLP.GeneralTab', 'Unblank display when sending ' 'items to Live')) self.auto_preview_check_box.setText(translate('OpenLP.GeneralTab', @@ -293,6 +298,7 @@ class GeneralTab(SettingsTab): 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')) @@ -337,6 +343,7 @@ class GeneralTab(SettingsTab): 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()) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index d9a0c8547..7121e5227 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -87,6 +87,8 @@ class DisplayController(QtWidgets.QWidget): self.is_live = False self.display = None self.controller_type = None + Registry().set_flag('has doubleclick added item to service', True) + Registry().set_flag('replace service manager item', False) def send_to_plugins(self, *args): """ @@ -796,12 +798,15 @@ class SlideController(DisplayController, RegistryProperties): def replace_service_manager_item(self, item): """ - Replacement item following a remote edit + Replacement item following a remote edit. + This action also takes place when a song that is sent to live from Service Manager is edited. :param item: The current service item """ if item == self.service_item: + Registry().set_flag('replace service manager item', True) self._process_item(item, self.preview_widget.current_slide_number()) + Registry().set_flag('replace service manager item', False) def add_service_manager_item(self, item, slide_no): """ @@ -970,9 +975,10 @@ class SlideController(DisplayController, RegistryProperties): def on_slide_unblank(self): """ - Handle the slidecontroller unblank event + Handle the slidecontroller unblank event. """ - self.on_blank_display(False) + if not Registry().get_flag('replace service manager item') is True: + self.on_blank_display(False) def on_blank_display(self, checked=None): """ @@ -1103,6 +1109,11 @@ class SlideController(DisplayController, RegistryProperties): 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. And start = Item is sent to Live. + # 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'): + if not start: + Registry().execute('slidecontroller_live_unblank') row = self.preview_widget.current_slide_number() old_selected_row = self.selected_row self.selected_row = 0 @@ -1285,6 +1296,8 @@ class SlideController(DisplayController, RegistryProperties): 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) @@ -1308,6 +1321,8 @@ class SlideController(DisplayController, RegistryProperties): 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) @@ -1362,7 +1377,7 @@ class SlideController(DisplayController, RegistryProperties): Triggered when a preview slide item is doubleclicked """ if self.service_item: - if Settings().value('advanced/double click live'): + if Settings().value('advanced/double click live') and Settings().value('core/auto unblank'): # Live and Preview have issues if we have video or presentations # playing in both at the same time. if self.service_item.is_command(): @@ -1371,8 +1386,13 @@ class SlideController(DisplayController, RegistryProperties): if self.service_item.is_media(): self.on_media_close() self.on_go_live() - else: + # If ('advanced/double click live') is not enabled, double clicking preview adds the item to Service. + # Prevent same item in preview from being sent to Service multiple times. + # Changing the preview slide resets this flag to False. + # Do note that this still allows to add item to Service multiple times if icon is clicked. + elif not Registry().get_flag('has doubleclick added item to service') is True: self.on_preview_add_to_service() + Registry().set_flag('has doubleclick added item to service', True) def on_go_live(self, field=None): """ diff --git a/openlp/plugins/presentations/lib/messagelistener.py b/openlp/plugins/presentations/lib/messagelistener.py index 097b9dc38..c12f1b0fb 100644 --- a/openlp/plugins/presentations/lib/messagelistener.py +++ b/openlp/plugins/presentations/lib/messagelistener.py @@ -26,7 +26,7 @@ import os 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 from openlp.plugins.presentations.lib.pdfcontroller import PDF_CONTROLLER_FILETYPES @@ -419,6 +419,8 @@ class MessageListener(object): 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 @@ class MessageListener(object): 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() diff --git a/tests/functional/openlp_core_ui/test_slidecontroller.py b/tests/functional/openlp_core_ui/test_slidecontroller.py index 126e67d1f..01f895daa 100644 --- a/tests/functional/openlp_core_ui/test_slidecontroller.py +++ b/tests/functional/openlp_core_ui/test_slidecontroller.py @@ -713,6 +713,52 @@ class TestSlideController(TestCase): slide_controller.theme_screen, slide_controller.blank_screen ]) + @patch('openlp.core.ui.slidecontroller.Settings') + def on_preview_double_click_unblank_display_test(self, MockedSettings): + # GIVEN: A slide controller, actions needed, settins set to True. + slide_controller = SlideController(None) + mocked_settings = MagicMock() + mocked_settings.return_value = True + MockedSettings.return_value = mocked_settings + slide_controller.service_item = MagicMock() + slide_controller.service_item.is_media = MagicMock() + slide_controller.on_media_close = MagicMock() + slide_controller.on_go_live = MagicMock() + slide_controller.on_preview_add_to_service = MagicMock() + slide_controller.media_reset = MagicMock() + Registry.create() + Registry().set_flag('has doubleclick added item to service', True) + + # WHEN: on_preview_double_click is called + slide_controller.on_preview_double_click() + + # THEN: The call to addActions should be correct + self.assertEqual(1, slide_controller.on_go_live.call_count, 'on_go_live should have been called once.') + self.assertEqual(0, slide_controller.on_preview_add_to_service.call_count, 'Should have not been called.') + + @patch('openlp.core.ui.slidecontroller.Settings') + def on_preview_double_click_add_to_service_test(self, MockedSettings): + # GIVEN: A slide controller, actions needed, settins set to False. + slide_controller = SlideController(None) + mocked_settings = MagicMock() + mocked_settings.value.return_value = False + MockedSettings.return_value = mocked_settings + slide_controller.service_item = MagicMock() + slide_controller.service_item.is_media = MagicMock() + slide_controller.on_media_close = MagicMock() + slide_controller.on_go_live = MagicMock() + slide_controller.on_preview_add_to_service = MagicMock() + slide_controller.media_reset = MagicMock() + Registry.create() + Registry().set_flag('has doubleclick added item to service', False) + + # WHEN: on_preview_double_click is called + slide_controller.on_preview_double_click() + + # THEN: The call to addActions should be correct + self.assertEqual(0, slide_controller.on_go_live.call_count, 'on_go_live Should have not been called.') + self.assertEqual(1, slide_controller.on_preview_add_to_service.call_count, 'Should have been called once.') + @patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager') @patch(u'PyQt5.QtCore.QTimer.singleShot') def test_update_preview_live(self, mocked_singleShot, mocked_image_manager):