Moved ScreenList to display module

This commit is contained in:
Raoul Snyman 2017-10-10 14:15:08 -07:00
parent 6165fb4992
commit 53c8337017
19 changed files with 109 additions and 121 deletions

View File

@ -33,13 +33,12 @@ import time
from datetime import datetime
from traceback import format_exception
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5 import QtCore, QtWidgets
from openlp.core.common import Registry, OpenLPMixin, AppLocation, LanguageManager, Settings, UiStrings, \
check_directory_exists, is_macosx, is_win, translate
from openlp.core.common.path import Path, copytree
from openlp.core.version import check_for_update, get_version
from openlp.core.lib import ScreenList
from openlp.core.common.path import copytree
from openlp.core.display.screens import ScreenList
from openlp.core.resources import qInitResources
from openlp.core.ui import SplashScreen
from openlp.core.ui.exceptionform import ExceptionForm
@ -47,6 +46,7 @@ from openlp.core.ui.firsttimeform import FirstTimeForm
from openlp.core.ui.firsttimelanguageform import FirstTimeLanguageForm
from openlp.core.ui.mainwindow import MainWindow
from openlp.core.ui.style import get_application_stylesheet
from openlp.core.version import check_for_update, get_version
__all__ = ['OpenLP', 'main']

View File

@ -304,7 +304,6 @@ def create_separated_list(string_list):
from .exceptions import ValidationError
from .screen import ScreenList
from .formattingtags import FormattingTags
from .plugin import PluginStatus, StringContent, Plugin
from .pluginmanager import PluginManager

View File

@ -32,7 +32,8 @@ import queue
from PyQt5 import QtCore
from openlp.core.common import Registry, Settings
from openlp.core.lib import ScreenList, resize_image, image_to_byte
from openlp.core.display.screens import ScreenList
from openlp.core.lib import resize_image, image_to_byte
log = logging.getLogger(__name__)

View File

@ -29,7 +29,8 @@ from lxml import etree, objectify
from openlp.core.common import AppLocation, de_hump
from openlp.core.common.json import OpenLPJsonDecoder, OpenLPJsonEncoder
from openlp.core.common.path import Path, str_to_path
from openlp.core.lib import str_to_bool, ScreenList, get_text_file_string
from openlp.core.display.screens import ScreenList
from openlp.core.lib import str_to_bool, get_text_file_string
log = logging.getLogger(__name__)

View File

@ -27,8 +27,9 @@ import logging
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry, Settings, UiStrings, translate, get_images_filter
from openlp.core.common.path import Path, path_to_str, str_to_path
from openlp.core.lib import SettingsTab, ScreenList
from openlp.core.common.path import Path
from openlp.core.display.screens import ScreenList
from openlp.core.lib import SettingsTab
from openlp.core.ui.lib import ColorButton, PathEdit
log = logging.getLogger(__name__)

View File

@ -28,7 +28,8 @@ import logging
from PyQt5 import QtWidgets
from openlp.core.lib import ScreenList, build_icon
from openlp.core.display.screens import ScreenList
from openlp.core.lib import build_icon
log = logging.getLogger(__name__)

View File

@ -40,7 +40,8 @@ from openlp.core.common import Registry, RegistryProperties, AppLocation, Langua
check_directory_exists, translate, is_win, is_macosx, add_actions
from openlp.core.common.actions import ActionList, CategoryOrder
from openlp.core.common.path import Path, copyfile, path_to_str, str_to_path
from openlp.core.lib import PluginManager, ImageManager, PluginStatus, ScreenList, build_icon
from openlp.core.display.screens import ScreenList
from openlp.core.lib import PluginManager, ImageManager, PluginStatus, build_icon
from openlp.core.lib.ui import create_action
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, ThemeManager, PluginForm, ShortcutListForm, \
FormattingTagForm

View File

@ -33,8 +33,8 @@ from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry, RegistryProperties, Settings, SlideLimits, UiStrings, translate, \
RegistryMixin, OpenLPMixin
from openlp.core.common.actions import ActionList, CategoryOrder
from openlp.core.lib import ItemCapabilities, ServiceItem, ImageSource, ServiceItemAction, ScreenList, build_icon, \
build_html
from openlp.core.display.screens import ScreenList
from openlp.core.lib import ItemCapabilities, ServiceItem, ImageSource, ServiceItemAction, build_icon, build_html
from openlp.core.lib.ui import create_action
from openlp.core.ui.lib.toolbar import OpenLPToolbar
from openlp.core.ui.lib.listpreviewwidget import ListPreviewWidget
@ -76,33 +76,6 @@ NON_TEXT_MENU = [
]
class DisplayController(QtWidgets.QWidget):
"""
Controller is a general display controller widget.
"""
def __init__(self, parent):
"""
Set up the general Controller.
"""
super(DisplayController, self).__init__(parent)
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):
"""
This is the generic function to send signal for control widgets, created from within other plugins
This function is needed to catch the current controller
:param args: Arguments to send to the plugins
"""
sender = self.sender().objectName() if self.sender().objectName() else self.sender().text()
controller = self
Registry().execute('{text}'.format(text=sender), [controller, args])
class InfoLabel(QtWidgets.QLabel):
"""
InfoLabel is a subclassed QLabel. Created to provide the ablilty to add a ellipsis if the text is cut off. Original
@ -131,7 +104,7 @@ class InfoLabel(QtWidgets.QLabel):
super().setText(text)
class SlideController(DisplayController, RegistryProperties):
class SlideController(QtWidgets.QWidget, RegistryProperties):
"""
SlideController is the slide controller widget. This widget is what the
user uses to control the displaying of verses/slides/etc on the screen.
@ -141,14 +114,32 @@ class SlideController(DisplayController, RegistryProperties):
Set up the Slide Controller.
"""
super(SlideController, self).__init__(parent)
self.is_live = False
self.controller_type = None
self.displays = []
Registry().set_flag('has doubleclick added item to service', True)
Registry().set_flag('replace service manager item', False)
def post_set_up(self):
"""
Call by bootstrap functions
"""
self.initialise()
self.setup_displays()
self.screen_size_changed()
def setup_displays(self):
"""
Set up the display
"""
if self.displays:
# Delete any existing displays
del self.displays[:]
for screen in self.screens:
display = DisplayWindow(self)
display.resize(screen.current['size'])
# display.media_watcher.progress.connect(self.on_audio_time_remaining)
def initialise(self):
"""
Initialise the UI elements of the controller
@ -371,6 +362,7 @@ class SlideController(DisplayController, RegistryProperties):
self.slide_layout.setSpacing(0)
self.slide_layout.setContentsMargins(0, 0, 0, 0)
self.slide_layout.setObjectName('SlideLayout')
# Set up the preview display
self.preview_display = DisplayWindow(self)
self.slide_layout.insertWidget(0, self.preview_display)
self.preview_display.hide()
@ -441,9 +433,9 @@ class SlideController(DisplayController, RegistryProperties):
getattr(self,
'slidecontroller_{t}_previous'.format(t=self.type_prefix)).connect(self.on_slide_selected_previous)
if self.is_live:
getattr(self, 'mediacontroller_live_play').connect(self.media_controller.on_media_play)
getattr(self, 'mediacontroller_live_pause').connect(self.media_controller.on_media_pause)
getattr(self, 'mediacontroller_live_stop').connect(self.media_controller.on_media_stop)
self.mediacontroller_live_play.connect(self.media_controller.on_media_play)
self.mediacontroller_live_pause.connect(self.media_controller.on_media_pause)
self.mediacontroller_live_stop.connect(self.media_controller.on_media_stop)
def _slide_shortcut_activated(self):
"""
@ -508,6 +500,17 @@ class SlideController(DisplayController, RegistryProperties):
# Reset the shortcut.
self.current_shortcut = ''
def send_to_plugins(self, *args):
"""
This is the generic function to send signal for control widgets, created from within other plugins
This function is needed to catch the current controller
:param args: Arguments to send to the plugins
"""
sender = self.sender().objectName() if self.sender().objectName() else self.sender().text()
controller = self
Registry().execute('{text}'.format(text=sender), [controller, args])
def set_live_hot_keys(self, parent=None):
"""
Set the live hotkeys
@ -579,14 +582,11 @@ class SlideController(DisplayController, RegistryProperties):
Settings dialog has changed the screen size of adjust output and screen previews.
"""
# rebuild display as screen size changed
if self.display:
self.display.close()
self.display = DisplayWindow(self)
self.display.setup()
if self.displays:
for display in self.displays:
display.resize(self.screens.current['size'])
if self.is_live:
self.__add_actions_to_widget(self.display)
if self.display.audio_player:
self.display.audio_player.position_changed.connect(self.on_audio_time_remaining)
# The SlidePreview's ratio.
try:
self.ratio = self.screens.current['size'].width() / self.screens.current['size'].height()
@ -598,7 +598,7 @@ class SlideController(DisplayController, RegistryProperties):
self.preview_display.setup()
service_item = ServiceItem()
self.preview_display.webview.setHtml(build_html(service_item, self.preview_display.screen, None, self.is_live,
plugins=self.plugin_manager.plugins))
plugins=self.plugin_manager.plugins))
self.media_controller.setup_display(self.preview_display, True)
if self.service_item:
self.refresh_service_item()

View File

@ -37,7 +37,7 @@ import time
from PyQt5 import QtCore
from openlp.core.common import Registry, delete_file, get_uno_command, get_uno_instance, is_win
from openlp.core.lib import ScreenList
from openlp.core.display.screens import ScreenList
from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument, \
TextType

View File

@ -28,7 +28,7 @@ from subprocess import check_output, CalledProcessError
from openlp.core.common import AppLocation, check_binary_exists
from openlp.core.common import Settings, is_win
from openlp.core.common.path import which
from openlp.core.lib import ScreenList
from openlp.core.display.screens import ScreenList
from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument
if is_win():
@ -131,7 +131,6 @@ class PdfController(PresentationController):
elif (application_path / 'mutool.exe').is_file():
self.mutoolbin = application_path / 'mutool.exe'
else:
DEVNULL = open(os.devnull, 'wb')
# First try to find mudraw
self.mudrawbin = which('mudraw')
# if mudraw isn't installed, try mutool

View File

@ -25,11 +25,9 @@ This module is for controlling powerpoint. PPT API documentation:
2010: https://msdn.microsoft.com/en-us/library/office/ff743835%28v=office.14%29.aspx
2013: https://msdn.microsoft.com/en-us/library/office/ff743835.aspx
"""
import os
import logging
import time
from openlp.core.common import is_win, Settings
from openlp.core.common import is_win
if is_win():
from win32com.client import Dispatch
@ -40,8 +38,8 @@ if is_win():
import pywintypes
from openlp.core.common import Registry, UiStrings, trace_error_handler
from openlp.core.lib import ScreenList
from openlp.core.common import Registry, Settings, UiStrings, trace_error_handler
from openlp.core.display.screens import ScreenList
from openlp.core.lib.ui import critical_error_message_box, translate
from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument

View File

@ -19,8 +19,6 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
import os
import logging
import zipfile
import re
@ -34,7 +32,7 @@ if is_win():
from ctypes.wintypes import RECT
from openlp.core.common import AppLocation
from openlp.core.lib import ScreenList
from openlp.core.display.screens import ScreenList
from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument

View File

@ -28,7 +28,7 @@ from unittest.mock import MagicMock
from PyQt5 import QtCore, QtWidgets
from openlp.core.common import Registry
from openlp.core.lib import ScreenList
from openlp.core.display.screens import ScreenList
SCREEN = {
'primary': False,

View File

@ -31,7 +31,8 @@ from unittest.mock import patch
from PyQt5 import QtGui
from openlp.core.common import Registry
from openlp.core.lib import ImageManager, ScreenList
from openlp.core.display.screens import ScreenList
from openlp.core.lib import ImageManager
from openlp.core.lib.imagemanager import Priority
from tests.helpers.testmixin import TestMixin
@ -152,8 +153,8 @@ class TestImageManager(TestCase, TestMixin):
# Allow the queue to process.
self.lock.release()
# Request some "data".
image_bytes = self.image_manager.get_image_bytes(TEST_PATH, image4)
image_object = self.image_manager.get_image(TEST_PATH, image3)
self.image_manager.get_image_bytes(TEST_PATH, image4)
self.image_manager.get_image(TEST_PATH, image3)
# Now the mocked methods/functions do not have to sleep anymore.
self.sleep_time = 0
# Wait for the queue to finish.

View File

@ -30,10 +30,10 @@ from unittest.mock import MagicMock, patch
from PyQt5 import QtCore, QtGui
from openlp.plugins.presentations.lib.pdfcontroller import PdfController, PdfDocument
from openlp.core.common import Settings
from openlp.core.common.path import Path
from openlp.core.lib import ScreenList
from openlp.core.display.screens import ScreenList
from openlp.plugins.presentations.lib.pdfcontroller import PdfController, PdfDocument
from tests.utils.constants import TEST_RESOURCES_PATH
from tests.helpers.testmixin import TestMixin

View File

@ -24,7 +24,7 @@ This module contains tests for the pptviewcontroller module of the Presentations
"""
import shutil
from tempfile import mkdtemp
from unittest import TestCase
from unittest import TestCase, skipIf
from unittest.mock import MagicMock, patch
from openlp.plugins.presentations.lib.pptviewcontroller import PptviewDocument, PptviewController
@ -34,9 +34,6 @@ from openlp.core.common.path import Path
from tests.helpers.testmixin import TestMixin
from tests.utils.constants import TEST_RESOURCES_PATH
if is_win():
from ctypes import cdll
class TestPptviewController(TestCase, TestMixin):
"""
@ -73,25 +70,23 @@ class TestPptviewController(TestCase, TestMixin):
self.assertEqual('Powerpoint Viewer', controller.name,
'The name of the presentation controller should be correct')
def test_check_available(self):
@skipIf(not is_win(), 'Not Windows')
@patch('openlp.plugins.presentations.lib.pptviewcontroller.cdll.LoadLibrary')
def test_check_available(self, mocked_load_library):
"""
Test check_available / check_installed
"""
# GIVEN: A mocked dll loader and a controller
with patch('ctypes.cdll.LoadLibrary') as mocked_load_library:
mocked_process = MagicMock()
mocked_process.CheckInstalled.return_value = True
mocked_load_library.return_value = mocked_process
controller = PptviewController(plugin=self.mock_plugin)
mocked_process = MagicMock()
mocked_process.CheckInstalled.return_value = True
mocked_load_library.return_value = mocked_process
controller = PptviewController(plugin=self.mock_plugin)
# WHEN: check_available is called
available = controller.check_available()
# WHEN: check_available is called
available = controller.check_available()
# THEN: On windows it should return True, on other platforms False
if is_win():
self.assertTrue(available, 'check_available should return True on windows.')
else:
self.assertFalse(available, 'check_available should return False when not on windows.')
# THEN: On windows it should return True, on other platforms False
assert available is True, 'check_available should return True on windows.'
class TestPptviewDocument(TestCase):
@ -102,7 +97,6 @@ class TestPptviewDocument(TestCase):
"""
Set up the patches and mocks need for all tests.
"""
self.os_isdir_patcher = patch('openlp.plugins.presentations.lib.pptviewcontroller.os.path.isdir')
self.pptview_document_create_thumbnails_patcher = patch(
'openlp.plugins.presentations.lib.pptviewcontroller.PptviewDocument.create_thumbnails')
self.pptview_document_stop_presentation_patcher = patch(
@ -113,7 +107,6 @@ class TestPptviewDocument(TestCase):
'openlp.plugins.presentations.lib.pptviewcontroller.PresentationDocument._setup')
self.screen_list_patcher = patch('openlp.plugins.presentations.lib.pptviewcontroller.ScreenList')
self.rect_patcher = MagicMock()
self.mock_os_isdir = self.os_isdir_patcher.start()
self.mock_pptview_document_create_thumbnails = self.pptview_document_create_thumbnails_patcher.start()
self.mock_pptview_document_stop_presentation = self.pptview_document_stop_presentation_patcher.start()
self.mock_presentation_document_get_temp_folder = self.presentation_document_get_temp_folder_patcher.start()
@ -129,7 +122,6 @@ class TestPptviewDocument(TestCase):
"""
Stop the patches
"""
self.os_isdir_patcher.stop()
self.pptview_document_create_thumbnails_patcher.stop()
self.pptview_document_stop_presentation_patcher.stop()
self.presentation_document_get_temp_folder_patcher.stop()
@ -138,45 +130,40 @@ class TestPptviewDocument(TestCase):
self.screen_list_patcher.stop()
shutil.rmtree(self.temp_folder)
@skipIf(not is_win(), 'Not Windows')
def test_load_presentation_succesfull(self):
"""
Test the PptviewDocument.load_presentation() method when the PPT is successfully opened
"""
# GIVEN: A reset mocked_os
self.mock_os_isdir.reset()
# WHEN: The temporary directory exists and OpenPPT returns successfully (not -1)
self.mock_os_isdir.return_value = True
self.mock_controller.process.OpenPPT.return_value = 0
instance = PptviewDocument(self.mock_controller, self.mock_presentation)
instance.file_path = 'test\path.ppt'
if is_win():
result = instance.load_presentation()
# WHEN: The temporary directory exists and OpenPPT returns successfully (not -1)
result = instance.load_presentation()
# THEN: PptviewDocument.load_presentation should return True
self.assertTrue(result)
# THEN: PptviewDocument.load_presentation should return True
self.assertTrue(result)
def test_load_presentation_un_succesfull(self):
@skipIf(not is_win(), 'Not Windows')
@patch('openlp.plugins.presentations.lib.pptviewcontroller.os.makedirs')
def test_load_presentation_un_succesfull(self, mock_makedirs):
"""
Test the PptviewDocument.load_presentation() method when the temporary directory does not exist and the PPT is
not successfully opened
"""
# GIVEN: A reset mock_os_isdir
self.mock_os_isdir.reset()
self.mock_controller.process.OpenPPT.return_value = -1
instance = PptviewDocument(self.mock_controller, self.mock_presentation)
instance.file_path = 'test\path.ppt'
# WHEN: The temporary directory does not exist and OpenPPT returns unsuccessfully (-1)
with patch('openlp.plugins.presentations.lib.pptviewcontroller.os.makedirs') as mock_makedirs:
self.mock_os_isdir.return_value = False
self.mock_controller.process.OpenPPT.return_value = -1
instance = PptviewDocument(self.mock_controller, self.mock_presentation)
instance.file_path = 'test\path.ppt'
if is_win():
result = instance.load_presentation()
result = instance.load_presentation()
# THEN: The temp folder should be created and PptviewDocument.load_presentation should return False
mock_makedirs.assert_called_once_with(self.temp_folder)
self.assertFalse(result)
# THEN: The temp folder should be created and PptviewDocument.load_presentation should return False
mock_makedirs.assert_called_once_with(self.temp_folder)
assert result is False
def test_create_titles_and_notes(self):
"""

View File

@ -28,7 +28,8 @@ from unittest.mock import MagicMock, patch
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import Registry
from openlp.core.lib import ScreenList, ServiceItem, ItemCapabilities
from openlp.core.display.screens import ScreenList
from openlp.core.lib import ServiceItem, ItemCapabilities
from openlp.core.ui.mainwindow import MainWindow
from tests.helpers.testmixin import TestMixin
@ -46,17 +47,17 @@ class TestServiceManager(TestCase, TestMixin):
ScreenList.create(self.app.desktop())
Registry().register('application', MagicMock())
# Mock classes and methods used by mainwindow.
with patch('openlp.core.ui.mainwindow.SettingsForm') as mocked_settings_form, \
patch('openlp.core.ui.mainwindow.ImageManager') as mocked_image_manager, \
patch('openlp.core.ui.mainwindow.LiveController') as mocked_live_controller, \
patch('openlp.core.ui.mainwindow.PreviewController') as mocked_preview_controller, \
patch('openlp.core.ui.mainwindow.OpenLPDockWidget') as mocked_dock_widget, \
patch('openlp.core.ui.mainwindow.QtWidgets.QToolBox') as mocked_q_tool_box_class, \
patch('openlp.core.ui.mainwindow.QtWidgets.QMainWindow.addDockWidget') as mocked_add_dock_method, \
patch('openlp.core.ui.mainwindow.ThemeManager') as mocked_theme_manager, \
patch('openlp.core.ui.mainwindow.ProjectorManager') as mocked_projector_manager, \
patch('openlp.core.ui.mainwindow.websockets.WebSocketServer') as mocked_websocketserver, \
patch('openlp.core.ui.mainwindow.server.HttpServer') as mocked_httpserver:
with patch('openlp.core.ui.mainwindow.SettingsForm'), \
patch('openlp.core.ui.mainwindow.ImageManager'), \
patch('openlp.core.ui.mainwindow.LiveController'), \
patch('openlp.core.ui.mainwindow.PreviewController'), \
patch('openlp.core.ui.mainwindow.OpenLPDockWidget'), \
patch('openlp.core.ui.mainwindow.QtWidgets.QToolBox'), \
patch('openlp.core.ui.mainwindow.QtWidgets.QMainWindow.addDockWidget'), \
patch('openlp.core.ui.mainwindow.ThemeManager'), \
patch('openlp.core.ui.mainwindow.ProjectorManager'), \
patch('openlp.core.ui.mainwindow.websockets.WebSocketServer'), \
patch('openlp.core.ui.mainwindow.server.HttpServer'):
self.main_window = MainWindow()
self.service_manager = Registry().get('service_manager')

View File

@ -28,8 +28,8 @@ from unittest.mock import MagicMock, patch
from PyQt5 import QtCore, QtTest
from openlp.core.common import Registry
from openlp.core.display.screens import ScreenList
from openlp.core.ui import settingsform
from openlp.core.lib import ScreenList
from tests.helpers.testmixin import TestMixin