forked from openlp/openlp
Fix up some stuff around the screen list
This commit is contained in:
parent
64a245bef9
commit
c7ea4c460e
@ -23,7 +23,6 @@
|
||||
The :mod:`screen` module provides management functionality for a machines'
|
||||
displays.
|
||||
"""
|
||||
import json
|
||||
import logging
|
||||
|
||||
from PyQt5 import QtCore
|
||||
@ -90,6 +89,30 @@ class ScreenList(object):
|
||||
for screen in self.screens:
|
||||
yield screen
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Make sure we can call "len" on this object
|
||||
"""
|
||||
return len(self.screens)
|
||||
|
||||
@property
|
||||
def current(self):
|
||||
"""
|
||||
Return the first "current" desktop
|
||||
|
||||
NOTE: This is a HACK to ease the upgrade process
|
||||
"""
|
||||
# Get the first display screen
|
||||
for screen in self.screens:
|
||||
if screen.is_display:
|
||||
return screen
|
||||
# If there's no display screen, get the first primary screen
|
||||
for screen in self.screens:
|
||||
if screen.is_primary:
|
||||
return screen
|
||||
# Otherwise just return the first screen
|
||||
return self.screens[0]
|
||||
|
||||
@classmethod
|
||||
def create(cls, desktop):
|
||||
"""
|
||||
@ -100,7 +123,7 @@ class ScreenList(object):
|
||||
screen_list = cls()
|
||||
screen_list.desktop = desktop
|
||||
screen_list.screens = []
|
||||
screen_list.screen_count_changed()
|
||||
screen_list.on_screen_count_changed()
|
||||
screen_list.load_screen_settings()
|
||||
screen_list.desktop.resized.connect(screen_list.on_screen_resolution_changed)
|
||||
screen_list.desktop.screenCountChanged.connect(screen_list.on_screen_count_changed)
|
||||
@ -138,7 +161,7 @@ class ScreenList(object):
|
||||
# Add new screens.
|
||||
for number in range(self.desktop.screenCount()):
|
||||
if not self.has_screen(number):
|
||||
self.screens.append(Screen(number, self.desktop.getGeometry(number),
|
||||
self.screens.append(Screen(number, self.desktop.screenGeometry(number),
|
||||
self.desktop.primaryScreen() == number))
|
||||
# We do not want to send this message at start up.
|
||||
if changed_screen is not None:
|
||||
@ -201,7 +224,7 @@ class ScreenList(object):
|
||||
'core/monitors': '{}'
|
||||
}
|
||||
Settings.extend_default_settings(screen_settings)
|
||||
monitors = json.loads(Settings().value('core/monitors'))
|
||||
monitors = Settings().value('core/monitors')
|
||||
for screen in self.screens:
|
||||
monitor = monitors.get(screen.number)
|
||||
if monitor:
|
||||
|
@ -176,8 +176,8 @@ class ImageManager(QtCore.QObject):
|
||||
super(ImageManager, self).__init__()
|
||||
Registry().register('image_manager', self)
|
||||
current_screen = ScreenList().current
|
||||
self.width = current_screen['size'].width()
|
||||
self.height = current_screen['size'].height()
|
||||
self.width = current_screen.display_geometry.width()
|
||||
self.height = current_screen.display_geometry.height()
|
||||
self._cache = {}
|
||||
self.image_thread = ImageThread(self)
|
||||
self._conversion_queue = PriorityQueue()
|
||||
@ -190,8 +190,8 @@ class ImageManager(QtCore.QObject):
|
||||
"""
|
||||
log.debug('update_display')
|
||||
current_screen = ScreenList().current
|
||||
self.width = current_screen['size'].width()
|
||||
self.height = current_screen['size'].height()
|
||||
self.width = current_screen.display_geometry.width()
|
||||
self.height = current_screen.display_geometry.height()
|
||||
# Mark the images as dirty for a rebuild by setting the image and byte stream to None.
|
||||
for image in list(self._cache.values()):
|
||||
self._reset_image(image)
|
||||
|
@ -48,7 +48,7 @@ class OpenLPDockWidget(QtWidgets.QDockWidget):
|
||||
self.setWindowIcon(build_icon(icon))
|
||||
# Sort out the minimum width.
|
||||
screens = ScreenList()
|
||||
main_window_docbars = screens.current['size'].width() // 5
|
||||
main_window_docbars = screens.current.display_geometry.width() // 5
|
||||
if main_window_docbars > 300:
|
||||
self.setMinimumWidth(300)
|
||||
else:
|
||||
|
@ -249,7 +249,7 @@ class PdfDocument(PresentationDocument):
|
||||
self.image_files.append(image_path)
|
||||
self.num_pages = len(self.image_files)
|
||||
return True
|
||||
size = ScreenList().current['size']
|
||||
size = ScreenList().current.display_geometry
|
||||
# Generate images from PDF that will fit the frame.
|
||||
runlog = ''
|
||||
try:
|
||||
|
@ -62,19 +62,26 @@ class TestScreenList(TestCase):
|
||||
del self.screens
|
||||
del self.application
|
||||
|
||||
def test_add_desktop(self):
|
||||
def test_create_screen_list(self):
|
||||
"""
|
||||
Test the ScreenList.screen_count_changed method to check if new monitors are detected by OpenLP.
|
||||
Create the screen list
|
||||
"""
|
||||
# GIVEN: The screen list at its current size
|
||||
old_screen_count = len(self.screens.screen_list)
|
||||
# GIVEN: Mocked desktop
|
||||
mocked_desktop = MagicMock()
|
||||
mocked_desktop.screenCount.return_value = 2
|
||||
mocked_desktop.screenGeometry.side_effect = [
|
||||
QtCore.QRect(0, 0, 1024, 768),
|
||||
QtCore.QRect(1024, 0, 1024, 768)
|
||||
]
|
||||
mocked_desktop.primaryScreen.return_value = 0
|
||||
|
||||
# WHEN: We add a new screen
|
||||
self.desktop.screenCount.return_value = SCREEN['number'] + 1
|
||||
self.screens.screen_count_changed(old_screen_count)
|
||||
# WHEN: create() is called
|
||||
screen_list = ScreenList.create(mocked_desktop)
|
||||
|
||||
# THEN: The screen should have been added and the screens should be identical
|
||||
new_screen_count = len(self.screens.screen_list)
|
||||
self.assertEqual(old_screen_count + 1, new_screen_count, 'The new_screens list should be bigger')
|
||||
self.assertEqual(SCREEN, self.screens.screen_list.pop(),
|
||||
'The 2nd screen should be identical to the first screen')
|
||||
# THEN: The correct screens have been set up
|
||||
assert screen_list.screens[0].number == 0
|
||||
assert screen_list.screens[0].geometry == QtCore.QRect(0, 0, 1024, 768)
|
||||
assert screen_list.screens[0].is_primary is True
|
||||
assert screen_list.screens[1].number == 1
|
||||
assert screen_list.screens[1].geometry == QtCore.QRect(1024, 0, 1024, 768)
|
||||
assert screen_list.screens[1].is_primary is False
|
||||
|
@ -24,7 +24,7 @@ Package to test the openlp.core.ui.exeptionform package.
|
||||
"""
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
from collections import OrderedDict
|
||||
from unittest import TestCase
|
||||
from unittest.mock import call, patch
|
||||
|
||||
@ -45,40 +45,44 @@ exceptionform.VLC_VERSION = 'VLC Test'
|
||||
MAIL_ITEM_TEXT = ('**OpenLP Bug Report**\nVersion: Trunk Test\n\n--- Details of the Exception. ---\n\n'
|
||||
'Description Test\n\n --- Exception Traceback ---\nopenlp: Traceback Test\n'
|
||||
'--- System information ---\nPlatform: Nose Test\n\n--- Library Versions ---\n'
|
||||
'Python: Python Test\nQt5: Qt5 test\nPyQt5: PyQt5 Test\nQtWebkit: Webkit Test\n'
|
||||
'SQLAlchemy: SqlAlchemy Test\nSQLAlchemy Migrate: Migrate Test\nBeautifulSoup: BeautifulSoup Test\n'
|
||||
'lxml: ETree Test\nChardet: CHARDET Test\nPyEnchant: Enchant Test\nMako: Mako Test\n'
|
||||
'pyICU: ICU Test\npyUNO bridge: UNO Bridge Test\nVLC: VLC Test\n\n')
|
||||
'Python: Python Test\nQt5: Qt5 Test\nPyQt5: PyQt5 Test\n'
|
||||
'SQLAlchemy: SQLAlchemy Test\nAlembic: Alembic Test\nBeautifulSoup: BeautifulSoup Test\n'
|
||||
'lxml: ETree Test\nChardet: Chardet Test\nPyEnchant: PyEnchant Test\nMako: Mako Test\n'
|
||||
'pyICU: pyICU Test\nVLC: VLC Test\nPyUNO: UNO Bridge Test\n')
|
||||
LIBRARY_VERSIONS = OrderedDict([
|
||||
('Python', 'Python Test'),
|
||||
('Qt5', 'Qt5 Test'),
|
||||
('PyQt5', 'PyQt5 Test'),
|
||||
('SQLAlchemy', 'SQLAlchemy Test'),
|
||||
('Alembic', 'Alembic Test'),
|
||||
('BeautifulSoup', 'BeautifulSoup Test'),
|
||||
('lxml', 'ETree Test'),
|
||||
('Chardet', 'Chardet Test'),
|
||||
('PyEnchant', 'PyEnchant Test'),
|
||||
('Mako', 'Mako Test'),
|
||||
('pyICU', 'pyICU Test'),
|
||||
('VLC', 'VLC Test')
|
||||
])
|
||||
|
||||
|
||||
@patch("openlp.core.ui.exceptionform.Qt.qVersion")
|
||||
@patch("openlp.core.ui.exceptionform.QtGui.QDesktopServices.openUrl")
|
||||
@patch("openlp.core.ui.exceptionform.get_version")
|
||||
@patch("openlp.core.ui.exceptionform.sqlalchemy")
|
||||
@patch("openlp.core.ui.exceptionform.bs4")
|
||||
@patch("openlp.core.ui.exceptionform.etree")
|
||||
@patch("openlp.core.ui.exceptionform.is_linux")
|
||||
@patch("openlp.core.ui.exceptionform.platform.platform")
|
||||
@patch("openlp.core.ui.exceptionform.platform.python_version")
|
||||
@patch('openlp.core.ui.exceptionform.QtGui.QDesktopServices.openUrl')
|
||||
@patch('openlp.core.ui.exceptionform.get_version')
|
||||
@patch('openlp.core.ui.exceptionform.get_library_versions')
|
||||
@patch('openlp.core.ui.exceptionform.is_linux')
|
||||
@patch('openlp.core.ui.exceptionform.platform.platform')
|
||||
class TestExceptionForm(TestMixin, TestCase):
|
||||
"""
|
||||
Test functionality of exception form functions
|
||||
"""
|
||||
def __method_template_for_class_patches(self, __PLACEHOLDER_FOR_LOCAL_METHOD_PATCH_DECORATORS_GO_HERE__,
|
||||
mocked_python_version, mocked_platform, mocked_is_linux,
|
||||
mocked_etree, mocked_bs4, mocked_sqlalchemy, mocked_get_version,
|
||||
mocked_openlurl, mocked_qversion):
|
||||
mocked_platform, mocked_is_linux, mocked_get_library_versions,
|
||||
mocked_get_version, mocked_openlurl):
|
||||
"""
|
||||
Template so you don't have to remember the layout of class mock options for methods
|
||||
"""
|
||||
mocked_etree.__version__ = 'ETree Test'
|
||||
mocked_bs4.__version__ = 'BeautifulSoup Test'
|
||||
mocked_sqlalchemy.__version__ = 'SqlAlchemy Test'
|
||||
mocked_python_version.return_value = 'Python Test'
|
||||
mocked_platform.return_value = 'Nose Test'
|
||||
mocked_qversion.return_value = 'Qt5 test'
|
||||
mocked_is_linux.return_value = False
|
||||
mocked_get_version.return_value = 'Trunk Test'
|
||||
mocked_get_library_versions.return_value = LIBRARY_VERSIONS
|
||||
|
||||
def setUp(self):
|
||||
self.setup_application()
|
||||
@ -98,31 +102,21 @@ class TestExceptionForm(TestMixin, TestCase):
|
||||
@patch("openlp.core.ui.exceptionform.FileDialog")
|
||||
@patch("openlp.core.ui.exceptionform.QtCore.QUrl")
|
||||
@patch("openlp.core.ui.exceptionform.QtCore.QUrlQuery.addQueryItem")
|
||||
@patch("openlp.core.ui.exceptionform.Qt")
|
||||
def test_on_send_report_button_clicked(self, mocked_qt, mocked_add_query_item, mocked_qurl, mocked_file_dialog,
|
||||
mocked_ui_exception_dialog, mocked_python_version, mocked_platform,
|
||||
mocked_is_linux, mocked_etree, mocked_bs4, mocked_sqlalchemy,
|
||||
mocked_get_version, mocked_openlurl, mocked_qversion):
|
||||
def test_on_send_report_button_clicked(self, mocked_add_query_item, mocked_qurl, mocked_file_dialog,
|
||||
mocked_ui_exception_dialog, mocked_platform, mocked_is_linux,
|
||||
mocked_get_library_versions, mocked_get_version, mocked_openlurl):
|
||||
"""
|
||||
Test send report creates the proper system information text
|
||||
"""
|
||||
# GIVEN: Test environment
|
||||
mocked_etree.__version__ = 'ETree Test'
|
||||
mocked_bs4.__version__ = 'BeautifulSoup Test'
|
||||
mocked_sqlalchemy.__version__ = 'SqlAlchemy Test'
|
||||
mocked_python_version.return_value = 'Python Test'
|
||||
mocked_platform.return_value = 'Nose Test'
|
||||
mocked_qversion.return_value = 'Qt5 test'
|
||||
mocked_is_linux.return_value = False
|
||||
mocked_get_version.return_value = 'Trunk Test'
|
||||
mocked_qt.PYQT_VERSION_STR = 'PyQt5 Test'
|
||||
mocked_is_linux.return_value = False
|
||||
mocked_get_version.return_value = 'Trunk Test'
|
||||
|
||||
mocked_get_library_versions.return_value = LIBRARY_VERSIONS
|
||||
test_form = exceptionform.ExceptionForm()
|
||||
test_form.file_attachment = None
|
||||
|
||||
with patch.object(test_form, '_pyuno_import') as mock_pyuno, \
|
||||
with patch.object(test_form, '_get_pyuno_version') as mock_pyuno, \
|
||||
patch.object(test_form.exception_text_edit, 'toPlainText') as mock_traceback, \
|
||||
patch.object(test_form.description_text_edit, 'toPlainText') as mock_description:
|
||||
mock_pyuno.return_value = 'UNO Bridge Test'
|
||||
@ -136,24 +130,15 @@ class TestExceptionForm(TestMixin, TestCase):
|
||||
mocked_add_query_item.assert_called_with('body', MAIL_ITEM_TEXT)
|
||||
|
||||
@patch("openlp.core.ui.exceptionform.FileDialog.getSaveFileName")
|
||||
@patch("openlp.core.ui.exceptionform.Qt")
|
||||
def test_on_save_report_button_clicked(self, mocked_qt, mocked_save_filename, mocked_python_version,
|
||||
mocked_platform, mocked_is_linux, mocked_etree, mocked_bs4,
|
||||
mocked_sqlalchemy, mocked_get_version, mocked_openlurl,
|
||||
mocked_qversion):
|
||||
def test_on_save_report_button_clicked(self, mocked_save_filename, mocked_platform, mocked_is_linux,
|
||||
mocked_get_library_versions, mocked_get_version, mocked_openlurl):
|
||||
"""
|
||||
Test save report saves the correct information to a file
|
||||
"""
|
||||
mocked_etree.__version__ = 'ETree Test'
|
||||
mocked_bs4.__version__ = 'BeautifulSoup Test'
|
||||
mocked_sqlalchemy.__version__ = 'SqlAlchemy Test'
|
||||
mocked_python_version.return_value = 'Python Test'
|
||||
mocked_platform.return_value = 'Nose Test'
|
||||
mocked_qversion.return_value = 'Qt5 test'
|
||||
mocked_qt.PYQT_VERSION_STR = 'PyQt5 Test'
|
||||
mocked_is_linux.return_value = False
|
||||
mocked_get_version.return_value = 'Trunk Test'
|
||||
|
||||
mocked_get_library_versions.return_value = LIBRARY_VERSIONS
|
||||
with patch.object(Path, 'open') as mocked_path_open:
|
||||
test_path = Path('testfile.txt')
|
||||
mocked_save_filename.return_value = test_path, 'ext'
|
||||
@ -161,7 +146,7 @@ class TestExceptionForm(TestMixin, TestCase):
|
||||
test_form = exceptionform.ExceptionForm()
|
||||
test_form.file_attachment = None
|
||||
|
||||
with patch.object(test_form, '_pyuno_import') as mock_pyuno, \
|
||||
with patch.object(test_form, '_get_pyuno_version') as mock_pyuno, \
|
||||
patch.object(test_form.exception_text_edit, 'toPlainText') as mock_traceback, \
|
||||
patch.object(test_form.description_text_edit, 'toPlainText') as mock_description:
|
||||
mock_pyuno.return_value = 'UNO Bridge Test'
|
||||
|
@ -67,8 +67,11 @@ class TestMainWindow(TestCase, TestMixin):
|
||||
self.add_toolbar_action_patcher = patch('openlp.core.ui.mainwindow.create_action')
|
||||
self.mocked_add_toolbar_action = self.add_toolbar_action_patcher.start()
|
||||
self.mocked_add_toolbar_action.side_effect = self._create_mock_action
|
||||
with patch('openlp.core.display.screens.ScreenList.__instance__', spec=ScreenList) as mocked_screen_list:
|
||||
mocked_screen_list.current = {'number': 0, 'size': QtCore.QSize(600, 800), 'primary': True}
|
||||
mocked_desktop = MagicMock()
|
||||
mocked_desktop.screenCount.return_value = 1
|
||||
mocked_desktop.screenGeometry.return_value = QtCore.QRect(0, 0, 1024, 768)
|
||||
mocked_desktop.primaryScreen.return_value = 1
|
||||
ScreenList.create(mocked_desktop)
|
||||
self.main_window = MainWindow()
|
||||
|
||||
def tearDown(self):
|
||||
|
@ -23,7 +23,6 @@
|
||||
This module contains tests for the PdfController
|
||||
"""
|
||||
import os
|
||||
import shutil
|
||||
from tempfile import mkdtemp
|
||||
from unittest import TestCase, SkipTest
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
@ -108,7 +108,7 @@ class EasyWorshipSongImportLogger(EasyWorshipSongImport):
|
||||
self._title_assignment_list.append(title)
|
||||
|
||||
|
||||
class TestFieldDesc:
|
||||
class FakeFieldDesc:
|
||||
def __init__(self, name, field_type, size):
|
||||
self.name = name
|
||||
self.field_type = field_type
|
||||
@ -120,11 +120,11 @@ CODE_PAGE_MAPPINGS = [
|
||||
(852, 'cp1250'), (737, 'cp1253'), (775, 'cp1257'), (855, 'cp1251'), (857, 'cp1254'),
|
||||
(866, 'cp1251'), (869, 'cp1253'), (862, 'cp1255'), (874, 'cp874')]
|
||||
TEST_FIELD_DESCS = [
|
||||
TestFieldDesc('Title', FieldType.String, 50),
|
||||
TestFieldDesc('Text Percentage Bottom', FieldType.Int16, 2), TestFieldDesc('RecID', FieldType.Int32, 4),
|
||||
TestFieldDesc('Default Background', FieldType.Logical, 1), TestFieldDesc('Words', FieldType.Memo, 250),
|
||||
TestFieldDesc('Words', FieldType.Memo, 250), TestFieldDesc('BK Bitmap', FieldType.Blob, 10),
|
||||
TestFieldDesc('Last Modified', FieldType.Timestamp, 10)]
|
||||
FakeFieldDesc('Title', FieldType.String, 50),
|
||||
FakeFieldDesc('Text Percentage Bottom', FieldType.Int16, 2), FakeFieldDesc('RecID', FieldType.Int32, 4),
|
||||
FakeFieldDesc('Default Background', FieldType.Logical, 1), FakeFieldDesc('Words', FieldType.Memo, 250),
|
||||
FakeFieldDesc('Words', FieldType.Memo, 250), FakeFieldDesc('BK Bitmap', FieldType.Blob, 10),
|
||||
FakeFieldDesc('Last Modified', FieldType.Timestamp, 10)]
|
||||
TEST_FIELDS = [
|
||||
b'A Heart Like Thine\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', 32868, 2147483750,
|
||||
129, b'{\\rtf1\\ansi\\deff0\\deftab254{\\fonttbl{\\f0\\fnil\\fcharset0 Arial;}{\\f1\\fnil\\fcharset0 Verdana;}}'
|
||||
|
@ -34,9 +34,9 @@ except ImportError:
|
||||
CAN_RUN_TESTS = False
|
||||
|
||||
|
||||
class TestRecord(object):
|
||||
class FakeRecord(object):
|
||||
"""
|
||||
Microsoft Access Driver is not available on non Microsoft Systems for this reason the :class:`TestRecord` is used
|
||||
Microsoft Access Driver is not available on non Microsoft Systems for this reason the :class:`FakeRecord` is used
|
||||
to simulate a recordset that would be returned by pyobdc.
|
||||
"""
|
||||
def __init__(self, id_, field, value):
|
||||
@ -66,12 +66,12 @@ if CAN_RUN_TESTS:
|
||||
self._title_assignment_list.append(title)
|
||||
|
||||
|
||||
RECORDSET_TEST_DATA = [TestRecord(1, 'TITLE', 'Amazing Grace'),
|
||||
TestRecord(1, 'AUTHOR', 'John Newton'),
|
||||
TestRecord(1, 'CCLISONGID', '12345'),
|
||||
TestRecord(1, 'COMMENTS', 'The original version'),
|
||||
TestRecord(1, 'COPY', 'Public Domain'),
|
||||
TestRecord(
|
||||
RECORDSET_TEST_DATA = [FakeRecord(1, 'TITLE', 'Amazing Grace'),
|
||||
FakeRecord(1, 'AUTHOR', 'John Newton'),
|
||||
FakeRecord(1, 'CCLISONGID', '12345'),
|
||||
FakeRecord(1, 'COMMENTS', 'The original version'),
|
||||
FakeRecord(1, 'COPY', 'Public Domain'),
|
||||
FakeRecord(
|
||||
1, 'LYRICS',
|
||||
'Amazing grace! How&crlf;sweet the sound&crlf;That saved a wretch like me!&crlf;'
|
||||
'I once was lost,&crlf;but now am found;&crlf;Was blind, but now I see.&crlf;&crlf;'
|
||||
@ -88,8 +88,8 @@ RECORDSET_TEST_DATA = [TestRecord(1, 'TITLE', 'Amazing Grace'),
|
||||
'Shall be forever mine.&crlf;&crlf;When we\'ve been there&crlf;ten thousand years,&crlf;'
|
||||
'Bright shining as the sun,&crlf;We\'ve no less days to&crlf;sing God\'s praise&crlf;'
|
||||
'Than when we\'d first begun.&crlf;&crlf;'),
|
||||
TestRecord(2, 'TITLE', 'Beautiful Garden Of Prayer, The'),
|
||||
TestRecord(
|
||||
FakeRecord(2, 'TITLE', 'Beautiful Garden Of Prayer, The'),
|
||||
FakeRecord(
|
||||
2, 'LYRICS',
|
||||
'There\'s a garden where&crlf;Jesus is waiting,&crlf;'
|
||||
'There\'s a place that&crlf;is wondrously fair,&crlf;For it glows with the&crlf;'
|
||||
|
Loading…
Reference in New Issue
Block a user