diff --git a/openlp/core/common/settings.py b/openlp/core/common/settings.py index 73221e270..14c7be18d 100644 --- a/openlp/core/common/settings.py +++ b/openlp/core/common/settings.py @@ -243,7 +243,6 @@ class Settings(QtCore.QSettings): 'core/last version test': '', 'core/loop delay': 5, 'core/recent files': [], - 'core/save prompt': False, 'core/screens': '{}', 'core/screen blank': False, 'core/show splash': True, @@ -334,7 +333,6 @@ class Settings(QtCore.QSettings): 'themes/last directory export': None, 'themes/last directory import': None, 'themes/theme level': ThemeLevel.Global, - 'themes/wrap footer': False, 'themes/item transitions': False, 'user interface/live panel': True, 'user interface/live splitter geometry': QtCore.QByteArray(), @@ -401,6 +399,7 @@ class Settings(QtCore.QSettings): ('themes/last directory', 'themes/last directory', [(str_to_path, None)]), ('themes/last directory export', 'themes/last directory export', [(str_to_path, None)]), ('themes/last directory import', 'themes/last directory import', [(str_to_path, None)]), + ('themes/wrap footer', '', []), ('projector/last directory import', 'projector/last directory import', [(str_to_path, None)]), ('projector/last directory export', 'projector/last directory export', [(str_to_path, None)]), ('bibles/last directory import', 'bibles/last directory import', [(str_to_path, None)]), @@ -428,7 +427,8 @@ class Settings(QtCore.QSettings): ('media/players', '', []), ('media/override player', '', []), ('core/audio start paused', '', []), - ('core/audio repeat list', '', []) + ('core/audio repeat list', '', []), + ('core/save prompt', '', []) ] @staticmethod diff --git a/openlp/core/display/html/display.css b/openlp/core/display/html/display.css index cd9787bda..7e5094bed 100644 --- a/openlp/core/display/html/display.css +++ b/openlp/core/display/html/display.css @@ -22,6 +22,10 @@ body.checkerboard { background-size: 100%; } +body.hide-mouse { + cursor: none; +} + sup { vertical-align: super !important; font-size: smaller !important; diff --git a/openlp/core/display/html/display.js b/openlp/core/display/html/display.js index c89afdd36..1e487011e 100644 --- a/openlp/core/display/html/display.js +++ b/openlp/core/display/html/display.js @@ -384,17 +384,30 @@ var Display = { }, /** * Start up reveal and do any other initialisation + * @param {object} options - The initialisation options: + * * {bool} isDisplay - Is this a real display output + * * {bool} doItemTransitions - Transition between service items + * * {bool} hideMouse - Hide the cursor when hovering on this display */ - init: function (isDisplay=false, doItemtransitions=false) { + init: function (options) { + // Set defaults for undefined values + options = options || {}; + var isDisplay = options.isDisplay || false; + var doItemTransitions = options.doItemTransitions || false; + var hideMouse = options.hideMouse || false; + // Now continue to initialisation if (!isDisplay) { document.body.classList.add('checkerboard'); } + if (hideMouse) { + document.body.classList.add('hide-mouse'); + } Display._slidesContainer = $(".slides")[0]; Display._footerContainer = $(".footer")[0]; Display._backgroundsContainer = $(".backgrounds")[0]; Display._doTransitions = isDisplay; Reveal.initialize(Display._revealConfig); - Display.setItemTransition(doItemtransitions && isDisplay); + Display.setItemTransition(doItemTransitions && isDisplay); displayWatcher.setInitialised(true); }, /** diff --git a/openlp/core/display/window.py b/openlp/core/display/window.py index 1c47930f8..b3449f67b 100644 --- a/openlp/core/display/window.py +++ b/openlp/core/display/window.py @@ -249,8 +249,14 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties, LogMixin): """ js_is_display = str(self.is_display).lower() item_transitions = str(self.settings.value('themes/item transitions')).lower() - self.run_javascript('Display.init({is_display}, {do_item_transitions});' - .format(is_display=js_is_display, do_item_transitions=item_transitions)) + hide_mouse = str(self.settings.value('advanced/hide mouse') and self.is_display).lower() + self.run_javascript('Display.init({{' + 'isDisplay: {is_display},' + 'doItemTransitions: {do_item_transitions},' + 'hideMouse: {hide_mouse}' + '}});' + .format(is_display=js_is_display, do_item_transitions=item_transitions, + hide_mouse=hide_mouse)) wait_for(lambda: self._is_initialised) if self.scale != 1: self.set_scale(self.scale) diff --git a/openlp/core/ui/generaltab.py b/openlp/core/ui/generaltab.py index 7655d45e0..bf8be1ffd 100644 --- a/openlp/core/ui/generaltab.py +++ b/openlp/core/ui/generaltab.py @@ -125,9 +125,6 @@ class GeneralTab(SettingsTab): self.settings_group_box.setObjectName('settings_group_box') self.settings_layout = QtWidgets.QFormLayout(self.settings_group_box) self.settings_layout.setObjectName('settings_layout') - self.save_check_service_check_box = QtWidgets.QCheckBox(self.settings_group_box) - self.save_check_service_check_box.setObjectName('save_check_service_check_box') - self.settings_layout.addRow(self.save_check_service_check_box) 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) @@ -167,8 +164,6 @@ class GeneralTab(SettingsTab): self.logo_hide_on_startup_check_box.setText(translate('OpenLP.GeneralTab', 'Don\'t show logo on startup')) self.check_for_updates_check_box.setText(translate('OpenLP.GeneralTab', 'Check for updates to OpenLP')) 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 ' @@ -194,7 +189,6 @@ class GeneralTab(SettingsTab): self.number_edit.setText(self.settings.value('ccli number')) self.username_edit.setText(self.settings.value('songselect username')) self.password_edit.setText(self.settings.value('songselect password')) - self.save_check_service_check_box.setChecked(self.settings.value('save prompt')) self.auto_unblank_check_box.setChecked(self.settings.value('auto unblank')) self.click_live_slide_to_unblank_check_box.setChecked(self.settings.value('click live slide to unblank')) self.warning_check_box.setChecked(self.settings.value('blank warning')) @@ -221,7 +215,6 @@ class GeneralTab(SettingsTab): self.settings.setValue('logo file', self.logo_file_path_edit.path) self.settings.setValue('logo hide on startup', self.logo_hide_on_startup_check_box.isChecked()) self.settings.setValue('update check', self.check_for_updates_check_box.isChecked()) - self.settings.setValue('save prompt', self.save_check_service_check_box.isChecked()) self.settings.setValue('auto unblank', self.auto_unblank_check_box.isChecked()) self.settings.setValue('click live slide to unblank', self.click_live_slide_to_unblank_check_box.isChecked()) self.settings.setValue('auto preview', self.auto_preview_check_box.isChecked()) diff --git a/openlp/core/ui/themestab.py b/openlp/core/ui/themestab.py index f1ce93637..3e7cb00b5 100644 --- a/openlp/core/ui/themestab.py +++ b/openlp/core/ui/themestab.py @@ -66,9 +66,6 @@ class ThemesTab(SettingsTab): self.universal_group_box.setObjectName('universal_group_box') self.universal_group_box_layout = QtWidgets.QVBoxLayout(self.universal_group_box) self.universal_group_box_layout.setObjectName('universal_group_box_layout') - self.wrap_footer_check_box = QtWidgets.QCheckBox(self.universal_group_box) - self.wrap_footer_check_box.setObjectName('wrap_footer_check_box') - self.universal_group_box_layout.addWidget(self.wrap_footer_check_box) self.item_transitions_check_box = QtWidgets.QCheckBox(self.universal_group_box) self.item_transitions_check_box.setObjectName('item_transitions_check_box') self.universal_group_box_layout.addWidget(self.item_transitions_check_box) @@ -117,7 +114,6 @@ class ThemesTab(SettingsTab): self.tab_title_visible = UiStrings().Themes self.global_group_box.setTitle(translate('OpenLP.ThemesTab', 'Global Theme')) self.universal_group_box.setTitle(translate('OpenLP.ThemesTab', 'Universal Settings')) - self.wrap_footer_check_box.setText(translate('OpenLP.ThemesTab', '&Wrap footer text')) self.item_transitions_check_box.setText(translate('OpenLP.ThemesTab', '&Transition between service items')) self.level_group_box.setTitle(translate('OpenLP.ThemesTab', 'Theme Level')) self.song_level_radio_button.setText(translate('OpenLP.ThemesTab', 'S&ong Level')) @@ -142,7 +138,6 @@ class ThemesTab(SettingsTab): self.settings.beginGroup(self.settings_section) self.theme_level = self.settings.value('theme level') self.global_theme = self.settings.value('global theme') - self.wrap_footer_check_box.setChecked(self.settings.value('wrap footer')) self.item_transitions_check_box.setChecked(self.settings.value('item transitions')) self.settings.endGroup() if self.theme_level == ThemeLevel.Global: @@ -159,7 +154,6 @@ class ThemesTab(SettingsTab): self.settings.beginGroup(self.settings_section) self.settings.setValue('theme level', self.theme_level) self.settings.setValue('global theme', self.global_theme) - self.settings.setValue('wrap footer', self.wrap_footer_check_box.isChecked()) self.settings.setValue('item transitions', self.item_transitions_check_box.isChecked()) self.settings.endGroup() self.renderer.set_theme_level(self.theme_level) diff --git a/tests/functional/openlp_core/display/test_window.py b/tests/functional/openlp_core/display/test_window.py index ec10ec049..49b039eb5 100644 --- a/tests/functional/openlp_core/display/test_window.py +++ b/tests/functional/openlp_core/display/test_window.py @@ -37,7 +37,7 @@ from openlp.core.lib.theme import Theme from openlp.core.ui import HideMode -@patch('PyQt5.QtWidgets.QVBoxLayout') +@patch('openlp.core.display.window.QtWidgets.QVBoxLayout') @patch('openlp.core.display.webengine.WebEngineView') def test_x11_override_on(mocked_webengine, mocked_addWidget, mock_settings): """ @@ -54,7 +54,7 @@ def test_x11_override_on(mocked_webengine, mocked_addWidget, mock_settings): assert x11_bit == QtCore.Qt.X11BypassWindowManagerHint -@patch('PyQt5.QtWidgets.QVBoxLayout') +@patch('openlp.core.display.window.QtWidgets.QVBoxLayout') @patch('openlp.core.display.webengine.WebEngineView') def test_x11_override_off(mocked_webengine, mocked_addWidget, mock_settings): """ @@ -71,7 +71,7 @@ def test_x11_override_off(mocked_webengine, mocked_addWidget, mock_settings): assert x11_bit != QtCore.Qt.X11BypassWindowManagerHint -@patch('PyQt5.QtWidgets.QVBoxLayout') +@patch('openlp.core.display.window.QtWidgets.QVBoxLayout') def test_set_scale_not_initialised(mocked_addWidget, mock_settings): """ Test that the scale js is not run if the page is not initialised @@ -88,7 +88,7 @@ def test_set_scale_not_initialised(mocked_addWidget, mock_settings): display_window.run_javascript.assert_not_called() -@patch('PyQt5.QtWidgets.QVBoxLayout') +@patch('openlp.core.display.window.QtWidgets.QVBoxLayout') @patch('openlp.core.display.webengine.WebEngineView') def test_set_scale_initialised(mocked_webengine, mocked_addWidget, mock_settings): """ @@ -106,13 +106,13 @@ def test_set_scale_initialised(mocked_webengine, mocked_addWidget, mock_settings display_window.run_javascript.assert_called_once_with('Display.setScale(50.0);') -@patch('PyQt5.QtWidgets.QVBoxLayout') +@patch('openlp.core.display.window.QtWidgets.QVBoxLayout') @patch('openlp.core.display.webengine.WebEngineView') def test_after_loaded(mocked_webengine, mocked_addWidget, mock_settings): """ Test the correct steps are taken when the webview is loaded """ - # GIVEN: An initialised display window and settings for item transitions returns true + # GIVEN: An initialised display window and settings for item transitions and hide mouse returns true display_window = DisplayWindow() display_window.is_display = True mock_settings.value.return_value = True @@ -126,12 +126,43 @@ def test_after_loaded(mocked_webengine, mocked_addWidget, mock_settings): display_window.after_loaded() # THEN: The following functions should have been called - display_window.run_javascript.assert_called_once_with('Display.init(true, true);') + display_window.run_javascript.assert_called_once_with('Display.init({' + 'isDisplay: true,' + 'doItemTransitions: true,' + 'hideMouse: true' + '});') display_window.set_scale.assert_called_once_with(2) display_window.set_startup_screen.assert_called_once() -@patch('PyQt5.QtWidgets.QVBoxLayout') +@patch('openlp.core.display.window.QtWidgets.QVBoxLayout') +@patch('openlp.core.display.webengine.WebEngineView') +def test_after_loaded_hide_mouse_not_display(mocked_webengine, mocked_addWidget, mock_settings): + """ + Test the mouse is showing even if the `hide mouse` setting is set while is_display=false + """ + # GIVEN: An initialised display window and settings for item transitions and hide mouse returns true + display_window = DisplayWindow() + display_window.is_display = False + mock_settings.value.return_value = True + display_window.scale = 2 + display_window._is_initialised = True + display_window.run_javascript = MagicMock() + display_window.set_scale = MagicMock() + display_window.set_startup_screen = MagicMock() + + # WHEN: after_loaded is run + display_window.after_loaded() + + # THEN: Display.init should be called where is_display=false, do_item_transitions=true, show_mouse=false + display_window.run_javascript.assert_called_once_with('Display.init({' + 'isDisplay: false,' + 'doItemTransitions: true,' + 'hideMouse: false' + '});') + + +@patch('openlp.core.display.window.QtWidgets.QVBoxLayout') @patch('openlp.core.display.webengine.WebEngineView') @patch.object(time, 'time') def test_run_javascript_no_sync_no_wait(mock_time, mocked_webengine, mocked_addWidget, mock_settings): @@ -151,7 +182,7 @@ def test_run_javascript_no_sync_no_wait(mock_time, mocked_webengine, mocked_addW mock_time.sleep.assert_not_called() -@patch('PyQt5.QtWidgets.QVBoxLayout') +@patch('openlp.core.display.window.QtWidgets.QVBoxLayout') @patch('openlp.core.display.webengine.WebEngineView') @patch.object(time, 'time') def test_run_javascript_sync_no_wait(mock_time, mocked_webengine, mocked_addWidget, mock_settings): @@ -176,7 +207,7 @@ def test_run_javascript_sync_no_wait(mock_time, mocked_webengine, mocked_addWidg mock_time.sleep.assert_not_called() -@patch('PyQt5.QtWidgets.QVBoxLayout') +@patch('openlp.core.display.window.QtWidgets.QVBoxLayout') @patch('openlp.core.display.webengine.WebEngineView') def test_set_theme_is_display_video(mocked_webengine, mocked_addWidget, mock_settings): """ @@ -200,7 +231,7 @@ def test_set_theme_is_display_video(mocked_webengine, mocked_addWidget, mock_set is_sync=False) -@patch('PyQt5.QtWidgets.QVBoxLayout') +@patch('openlp.core.display.window.QtWidgets.QVBoxLayout') @patch('openlp.core.display.webengine.WebEngineView') def test_set_theme_not_display_video(mocked_webengine, mocked_addWidget, mock_settings): """ @@ -231,7 +262,7 @@ def test_set_theme_not_display_video(mocked_webengine, mocked_addWidget, mock_se is_sync=False) -@patch('PyQt5.QtWidgets.QVBoxLayout') +@patch('openlp.core.display.window.QtWidgets.QVBoxLayout') @patch('openlp.core.display.webengine.WebEngineView') def test_set_theme_not_display_live(mocked_webengine, mocked_addWidget, mock_settings): """ @@ -259,10 +290,10 @@ def test_set_theme_not_display_live(mocked_webengine, mocked_addWidget, mock_set is_sync=False) -@patch('PyQt5.QtWidgets.QVBoxLayout') +@patch('openlp.core.display.window.QtWidgets.QVBoxLayout') @patch('openlp.core.display.webengine.WebEngineView') -@patch('openlp.core.common.registry.Registry.execute') -@patch('openlp.core.display.screens.ScreenList') +@patch('openlp.core.display.window.Registry.execute') +@patch('openlp.core.display.window.ScreenList') def test_show_display(mocked_screenlist, mocked_registry_execute, mocked_webengine, mocked_addWidget, mock_settings): """ Test show_display function @@ -284,7 +315,7 @@ def test_show_display(mocked_screenlist, mocked_registry_execute, mocked_webengi mocked_registry_execute.assert_called_once_with('live_display_active') -@patch('PyQt5.QtWidgets.QVBoxLayout') +@patch('openlp.core.display.window.QtWidgets.QVBoxLayout') @patch('openlp.core.display.webengine.WebEngineView') @patch('openlp.core.display.window.ScreenList') def test_show_display_no_display(mocked_screenlist, mocked_webengine, mocked_addWidget, mock_settings): @@ -305,7 +336,7 @@ def test_show_display_no_display(mocked_screenlist, mocked_webengine, mocked_add assert display_window.run_javascript.call_count == 0 -@patch('PyQt5.QtWidgets.QVBoxLayout') +@patch('openlp.core.display.window.QtWidgets.QVBoxLayout') @patch('openlp.core.display.webengine.WebEngineView') def test_hide_display_to_screen(mocked_webengine, mocked_addWidget, mock_settings): """ @@ -325,7 +356,7 @@ def test_hide_display_to_screen(mocked_webengine, mocked_addWidget, mock_setting display_window.run_javascript.assert_called_once_with('Display.toTransparent();') -@patch('PyQt5.QtWidgets.QVBoxLayout') +@patch('openlp.core.display.window.QtWidgets.QVBoxLayout') @patch('openlp.core.display.webengine.WebEngineView') def test_hide_display_to_blank(mocked_webengine, mocked_addWidget, mock_settings): """ @@ -343,7 +374,7 @@ def test_hide_display_to_blank(mocked_webengine, mocked_addWidget, mock_settings display_window.run_javascript.assert_called_once_with('Display.toBlack();') -@patch('PyQt5.QtWidgets.QVBoxLayout') +@patch('openlp.core.display.window.QtWidgets.QVBoxLayout') @patch('openlp.core.display.webengine.WebEngineView') def test_hide_display_to_theme(mocked_webengine, mocked_addWidget, mock_settings): """ @@ -361,7 +392,7 @@ def test_hide_display_to_theme(mocked_webengine, mocked_addWidget, mock_settings display_window.run_javascript.assert_called_once_with('Display.toTheme();') -@patch('PyQt5.QtWidgets.QVBoxLayout') +@patch('openlp.core.display.window.QtWidgets.QVBoxLayout') @patch('openlp.core.display.webengine.WebEngineView') def test_hide_display_to_transparent(mocked_webengine, mocked_addWidget, mock_settings): """ @@ -381,7 +412,7 @@ def test_hide_display_to_transparent(mocked_webengine, mocked_addWidget, mock_se assert display_window.setVisible.call_count == 0 -@patch('PyQt5.QtWidgets.QVBoxLayout') +@patch('openlp.core.display.window.QtWidgets.QVBoxLayout') @patch('openlp.core.display.webengine.WebEngineView') def test_hide_transparent_to_screen(mocked_webengine, mocked_addWidget, mock_settings): """ @@ -400,7 +431,7 @@ def test_hide_transparent_to_screen(mocked_webengine, mocked_addWidget, mock_set display_window.setVisible.assert_called_once_with(False) -@patch('PyQt5.QtWidgets.QVBoxLayout') +@patch('openlp.core.display.window.QtWidgets.QVBoxLayout') @patch('openlp.core.display.webengine.WebEngineView') @patch('openlp.core.display.window.ScreenList') def test_hide_display_no_display(mocked_screenlist, mocked_webengine, mocked_addWidget, mock_settings): diff --git a/tests/js/test_display.js b/tests/js/test_display.js index 06695d867..f51e19779 100644 --- a/tests/js/test_display.js +++ b/tests/js/test_display.js @@ -117,7 +117,7 @@ describe("The Display object", function () { spyOn(Reveal, "initialize"); document.body.innerHTML = ""; document.body.classList = ""; - Display.init(false); + Display.init({isDisplay: false}); expect(document.body.classList.contains('checkerboard')).toEqual(true); }); @@ -125,7 +125,7 @@ describe("The Display object", function () { spyOn(Reveal, "initialize"); document.body.innerHTML = ""; document.body.classList = ""; - Display.init(true); + Display.init({isDisplay: true}); expect(document.body.classList.contains('checkerboard')).toEqual(false); }); @@ -644,7 +644,7 @@ describe("Display.setTextSlides", function () { "footer": "Public Domain" } ]; - // + // const theme = { 'display_horizontal_align': 3, 'display_vertical_align': 1 @@ -669,7 +669,7 @@ describe("Display.setTextSlides", function () { "footer": "Public Domain" } ]; - // + // const theme = { 'font_main_shadow': true, 'font_main_shadow_color': "#000", @@ -694,7 +694,7 @@ describe("Display.setTextSlides", function () { "footer": "Public Domain" } ]; - // + // const theme = { 'font_main_shadow': false, 'font_main_shadow_color': "#000", @@ -719,7 +719,7 @@ describe("Display.setTextSlides", function () { "footer": "Public Domain" } ]; - // + // const theme = { 'font_main_y': 789, 'font_main_x': 1000,