From febf2615b5dc04b3fe89e5235383cc9c84ba77e4 Mon Sep 17 00:00:00 2001 From: robbie jackson Date: Sat, 20 Feb 2021 21:32:16 +0000 Subject: [PATCH] Fix setting custom geometry --- openlp/core/display/screens.py | 4 + openlp/core/display/window.py | 2 + openlp/core/widgets/widgets.py | 34 ++-- .../openlp_core/widgets/test_widgets.py | 157 ++++++++++++++++++ tests/openlp_core/widgets/test_widgets.py | 1 + 5 files changed, 186 insertions(+), 12 deletions(-) create mode 100644 tests/functional/openlp_core/widgets/test_widgets.py diff --git a/openlp/core/display/screens.py b/openlp/core/display/screens.py index ad5fc70fa..30f1c24fe 100644 --- a/openlp/core/display/screens.py +++ b/openlp/core/display/screens.py @@ -46,7 +46,11 @@ class Screen(object): :param int number: The Qt number of this screen :param QRect geometry: The geometry of this screen as a QRect object + In this geometry the top and left values are the coordinates of the extended desktop scheme + for example, where the left value increases as a mouse moves right from one screen to the next :param QRect custom_geometry: The custom geometry of this screen as a QRect object + The custom geometry left and top values are relative to that particular screen, + so left = 0, top = 0 refers to the top left of that screen. :param bool is_primary: Whether or not this screen is the primary screen :param bool is_display: Whether or not this screen should be used to display lyrics """ diff --git a/openlp/core/display/window.py b/openlp/core/display/window.py index 8ca547fd4..89f2d65fc 100644 --- a/openlp/core/display/window.py +++ b/openlp/core/display/window.py @@ -107,6 +107,8 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties, LogMixin): self.__script_done = True self.__script_result = None if screen and screen.is_display: + # use log_debug to set up function wrapping before registering functions + self.log_debug('registering live display show/hide functions') Registry().register_function('live_display_hide', self.hide_display) Registry().register_function('live_display_show', self.show_display) self.update_from_screen(screen) diff --git a/openlp/core/widgets/widgets.py b/openlp/core/widgets/widgets.py index 804fbf422..82ccf58c4 100644 --- a/openlp/core/widgets/widgets.py +++ b/openlp/core/widgets/widgets.py @@ -190,7 +190,12 @@ class ScreenButton(QtWidgets.QPushButton): super().__init__(parent) self.setObjectName('screen_{number}_button'.format(number=screen.number)) self.setCheckable(True) - self.setText(str(screen)) + if isinstance(screen.geometry, QtCore.QRect): + screen_size_text = translate('OpenLP.ScreenButton', + f'({screen.geometry.width()} x {screen.geometry.height()} pixels)') + self.setText(str(screen) + '\n' + screen_size_text) + else: + self.setText(str(screen)) self.screen = screen @@ -291,10 +296,11 @@ class ScreenSelectionWidget(QtWidgets.QWidget): self.custom_geometry_button.toggled.connect(self.width_spin_box.setEnabled) self.identify_button.clicked.connect(self.on_identify_button_clicked) - self._setup_spin_box(self.left_spin_box, 0, 9999, 0) - self._setup_spin_box(self.top_spin_box, 0, 9999, 0) - self._setup_spin_box(self.width_spin_box, 0, 9999, 0) - self._setup_spin_box(self.height_spin_box, 0, 9999, 0) + self._setup_spin_box(self.left_spin_box, -99999, 99999, 0) + self._setup_spin_box(self.top_spin_box, -99999, 99999, 0) + self._setup_spin_box(self.width_spin_box, -99999, 99999, 0) + self._setup_spin_box(self.height_spin_box, -99999, 99999, 0) + self.retranslate_ui() def retranslate_ui(self): @@ -432,11 +438,15 @@ class ScreenSelectionWidget(QtWidgets.QWidget): self.display_group_box.setChecked(screen.is_display) self.full_screen_radio_button.setChecked(screen.custom_geometry is None) self.custom_geometry_button.setChecked(screen.custom_geometry is not None) - self._setup_spin_box(self.left_spin_box, screen.display_geometry.y(), screen.display_geometry.right(), - screen.display_geometry.x()) - self._setup_spin_box(self.top_spin_box, screen.display_geometry.y(), screen.display_geometry.bottom(), - screen.display_geometry.y()) - self._setup_spin_box(self.width_spin_box, 0, screen.display_geometry.width(), screen.display_geometry.width()) - self._setup_spin_box(self.height_spin_box, 0, screen.display_geometry.height(), - screen.display_geometry.height()) + if isinstance(screen.custom_geometry, QtCore.QRect): + self.left_spin_box.setValue(screen.custom_geometry.x()) + self.top_spin_box.setValue(screen.custom_geometry.y()) + self.width_spin_box.setValue(screen.custom_geometry.width()) + self.height_spin_box.setValue(screen.custom_geometry.height()) + else: + self.left_spin_box.setValue(0) + self.top_spin_box.setValue(0) + self.width_spin_box.setValue(screen.geometry.width()) + self.height_spin_box.setValue(screen.geometry.height()) + self.current_screen = screen diff --git a/tests/functional/openlp_core/widgets/test_widgets.py b/tests/functional/openlp_core/widgets/test_widgets.py new file mode 100644 index 000000000..431570e53 --- /dev/null +++ b/tests/functional/openlp_core/widgets/test_widgets.py @@ -0,0 +1,157 @@ +# -*- coding: utf-8 -*- + +########################################################################## +# OpenLP - Open Source Lyrics Projection # +# ---------------------------------------------------------------------- # +# Copyright (c) 2008-2021 OpenLP Developers # +# ---------------------------------------------------------------------- # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +########################################################################## +""" +Package to test the screens tab functionality (primarily ScreenSelectionWidget and ScreenButton classes) +within openlp/core/widgets/widgets.py +""" + +import pytest + +from unittest.mock import MagicMock, patch + +from PyQt5 import QtWidgets, QtCore, QtTest + +from openlp.core.widgets.widgets import ScreenSelectionWidget + + +@pytest.fixture() +def form(settings): + test_form = ScreenSelectionWidget() + return test_form + + +def mocked_screens(customGeometry): + screen0 = MagicMock() + screen0.number = 0 + screen0.is_display = True + screen0.is_primary = False + screen0.geometry = QtCore.QRect(-271, -1080, 1920, 1080) + screen0.custom_geometry = customGeometry + screen0.__str__.return_value = "Screen 1" + screen1 = MagicMock() + screen1.number = 1 + screen1.is_display = False + screen1.is_primary = True + screen1.geometry = QtCore.QRect(0, 0, 1366, 768) + screen1.custom_geometry = customGeometry + screen1.__str__.return_value = "Screen 2" + return [screen0, screen1] + + +@patch('openlp.core.display.screens.ScreenList') +def test_screen_buttons_show_pixels(mocked_screenList, form): + ''' + Test that the screen buttons show the screen sizes in pixels + ''' + # GIVEN: A mocked extended desktop configuration + + mocked_screenList.return_value = mocked_screens(None) + form.screens = mocked_screenList() + + # WHEN: When I go into screen settings for the display screen + ScreenSelectionWidget.load(form) + + # THEN: The screen buttons should show the correct size of that screen + screen_0_button = form.findChild(QtWidgets.QPushButton, 'screen_0_button') + screen_1_button = form.findChild(QtWidgets.QPushButton, 'screen_1_button') + assert '1920' in str(screen_0_button.text()) + assert '1080' in str(screen_0_button.text()) + assert '1366' in str(screen_1_button.text()) + assert '768' in str(screen_1_button.text()) + + +@patch('openlp.core.display.screens.ScreenList') +def test_spinboxes_no_previous_custom_geometry(mocked_screenList, form): + """ + Test screen custom geometry can be changed from None + """ + # GIVEN: A mocked extended desktop configuration + + mocked_screenList.return_value = mocked_screens(None) + form.screens = mocked_screenList() + + # WHEN: When I go into screen settings for the display screen and set the custom geometry + ScreenSelectionWidget.load(form) + QtTest.QTest.mouseClick(form.custom_geometry_button, QtCore.Qt.LeftButton) + QtTest.QTest.keyClick(form.left_spin_box, QtCore.Qt.Key_Up) + QtTest.QTest.keyClick(form.top_spin_box, QtCore.Qt.Key_Up) + QtTest.QTest.keyClick(form.width_spin_box, QtCore.Qt.Key_Down) + QtTest.QTest.keyClick(form.height_spin_box, QtCore.Qt.Key_Down) + + # THEN: The spin boxes should show the correct values + assert form.left_spin_box.value() == 1 + assert form.top_spin_box.value() == 1 + assert form.width_spin_box.value() == 1919 + assert form.height_spin_box.value() == 1079 + + +@patch('openlp.core.display.screens.ScreenList') +def test_spinboxes_with_previous_custom_geometry(mocked_screenList, form): + """ + Test screen existing custom geometry can be changed + """ + # GIVEN: A mocked extended desktop configuration + + testGeometry = QtCore.QRect(1, 1, 1919, 1079) + mocked_screenList.return_value = mocked_screens(testGeometry) + form.screens = mocked_screenList() + + # WHEN: When I go into screen settings for the display screen and update the custom geometry + ScreenSelectionWidget.load(form) + QtTest.QTest.mouseClick(form.custom_geometry_button, QtCore.Qt.LeftButton) + QtTest.QTest.keyClick(form.left_spin_box, QtCore.Qt.Key_Up) + QtTest.QTest.keyClick(form.top_spin_box, QtCore.Qt.Key_Up) + QtTest.QTest.keyClick(form.width_spin_box, QtCore.Qt.Key_Down) + QtTest.QTest.keyClick(form.height_spin_box, QtCore.Qt.Key_Down) + + # THEN: The spin boxes should show the updated values + assert form.left_spin_box.value() == 2 + assert form.top_spin_box.value() == 2 + assert form.width_spin_box.value() == 1918 + assert form.height_spin_box.value() == 1078 + + +@patch('openlp.core.display.screens.ScreenList') +def test_spinboxes_going_outside_screen_geometry(mocked_screenList, form): + """ + Test screen existing custom geometry can be increased beyond the bounds of the screen + """ + # GIVEN: A mocked extended desktop configuration + + testGeometry = QtCore.QRect(1, 1, 1919, 1079) + mocked_screenList.return_value = mocked_screens(testGeometry) + form.screens = mocked_screenList() + + # WHEN: When I go into screen settings for the display screen and + # update the custom geometry to be outside the screen coordinates + ScreenSelectionWidget.load(form) + QtTest.QTest.mouseClick(form.custom_geometry_button, QtCore.Qt.LeftButton) + for _ in range(2): + QtTest.QTest.keyClick(form.left_spin_box, QtCore.Qt.Key_Down) + QtTest.QTest.keyClick(form.top_spin_box, QtCore.Qt.Key_Down) + QtTest.QTest.keyClick(form.width_spin_box, QtCore.Qt.Key_Up) + QtTest.QTest.keyClick(form.height_spin_box, QtCore.Qt.Key_Up) + + # THEN: The spin boxes should show the updated values + assert form.left_spin_box.value() == -1 + assert form.top_spin_box.value() == -1 + assert form.width_spin_box.value() == 1921 + assert form.height_spin_box.value() == 1081 diff --git a/tests/openlp_core/widgets/test_widgets.py b/tests/openlp_core/widgets/test_widgets.py index ddc9472c4..07e45f4a6 100644 --- a/tests/openlp_core/widgets/test_widgets.py +++ b/tests/openlp_core/widgets/test_widgets.py @@ -191,6 +191,7 @@ def test_screen_button_initialisation(): # GIVEN: A mocked screen object screen_mock = MagicMock(spec=Screen) screen_mock.number = 0 + screen_mock.geometry = None screen_mock.__str__.return_value = 'Mocked Screen Object' # WHEN: initialising the ScreenButton object