forked from openlp/openlp
Merge branch 'media_1' into 'master'
Text Over Video. See merge request openlp/openlp!119
This commit is contained in:
commit
781ff2c7ea
@ -93,6 +93,16 @@ class LanguageSelection(IntEnum):
|
||||
English = 2
|
||||
|
||||
|
||||
@unique
|
||||
class ServiceItemType(IntEnum):
|
||||
"""
|
||||
Defines the type of service item
|
||||
"""
|
||||
Text = 1
|
||||
Image = 2
|
||||
Command = 3
|
||||
|
||||
|
||||
@unique
|
||||
class PluginStatus(IntEnum):
|
||||
"""
|
||||
|
@ -29,7 +29,7 @@ from openlp.core.common.registry import Registry
|
||||
|
||||
|
||||
DO_NOT_TRACE_EVENTS = ['timerEvent', 'paintEvent', 'drag_enter_event', 'drop_event', 'on_controller_size_changed',
|
||||
'preview_size_changed', 'resizeEvent']
|
||||
'preview_size_changed', 'resizeEvent', 'eventFilter']
|
||||
|
||||
|
||||
class LogMixin(object):
|
||||
|
@ -29,15 +29,16 @@ import copy
|
||||
from PyQt5 import QtCore, QtWebChannel, QtWidgets
|
||||
|
||||
from openlp.core.common.applocation import AppLocation
|
||||
from openlp.core.common.enum import ServiceItemType
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.common.mixins import RegistryProperties
|
||||
from openlp.core.common.path import path_to_str
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.common.utils import wait_for
|
||||
from openlp.core.display.screens import ScreenList
|
||||
from openlp.core.ui import HideMode
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -128,7 +129,7 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
|
||||
super(DisplayWindow, self).__init__(parent)
|
||||
# Gather all flags for the display window
|
||||
flags = QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool | QtCore.Qt.WindowStaysOnTopHint
|
||||
if Settings().value('advanced/x11 bypass wm'):
|
||||
if self.settings.value('advanced/x11 bypass wm'):
|
||||
flags |= QtCore.Qt.X11BypassWindowManagerHint
|
||||
# Need to import this inline to get around a QtWebEngine issue
|
||||
from openlp.core.display.webengine import WebEngineView
|
||||
@ -170,7 +171,7 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
|
||||
self.update_from_screen(screen)
|
||||
self.is_display = True
|
||||
# Only make visible on single monitor setup if setting enabled.
|
||||
if len(ScreenList()) > 1 or Settings().value('core/display on monitor'):
|
||||
if len(ScreenList()) > 1 or self.settings.value('core/display on monitor'):
|
||||
self.show()
|
||||
|
||||
def deregister_display(self):
|
||||
@ -214,8 +215,8 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
|
||||
'"{image_data}");'.format(bg_color=bg_color, image_data=image_data))
|
||||
|
||||
def set_startup_screen(self):
|
||||
bg_color = Settings().value('core/logo background color')
|
||||
image = Settings().value('core/logo file')
|
||||
bg_color = self.settings.value('core/logo background color')
|
||||
image = self.settings.value('core/logo file')
|
||||
if path_to_str(image).startswith(':'):
|
||||
image = self.openlp_splash_screen_path
|
||||
image_uri = image.as_uri()
|
||||
@ -260,9 +261,7 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
|
||||
log.debug(script)
|
||||
# Wait for previous scripts to finish
|
||||
wait_for(lambda: self.__script_done)
|
||||
if not is_sync:
|
||||
self.webview.page().runJavaScript(script)
|
||||
else:
|
||||
if is_sync:
|
||||
self.__script_done = False
|
||||
self.__script_result = None
|
||||
|
||||
@ -278,6 +277,9 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
|
||||
if not wait_for(lambda: self.__script_done):
|
||||
self.__script_done = True
|
||||
return self.__script_result
|
||||
else:
|
||||
self.webview.page().runJavaScript(script)
|
||||
self.raise_()
|
||||
|
||||
def go_to_slide(self, verse):
|
||||
"""
|
||||
@ -372,18 +374,31 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
|
||||
else:
|
||||
return pixmap
|
||||
|
||||
def set_theme(self, theme, is_sync=False):
|
||||
def set_theme(self, theme, is_sync=False, service_item_type=False):
|
||||
"""
|
||||
Set the theme of the display
|
||||
"""
|
||||
# If background is transparent and this is not a display, inject checkerboard background image instead
|
||||
if theme.background_type == 'transparent' and not self.is_display:
|
||||
theme_copy = copy.deepcopy(theme)
|
||||
if self.is_display:
|
||||
if service_item_type == ServiceItemType.Text:
|
||||
if theme.background_type == 'video' or theme.background_type == 'stream':
|
||||
theme_copy.background_type = 'transparent'
|
||||
else:
|
||||
# If review Display for media so we need to display black box.
|
||||
if theme.background_type == 'stream':
|
||||
theme_copy.background_type = 'transparent'
|
||||
elif service_item_type == ServiceItemType.Command or theme.background_type == 'video' or \
|
||||
theme.background_type == 'live':
|
||||
theme_copy.background_type = 'solid'
|
||||
theme_copy.background_start_color = '#590909'
|
||||
theme_copy.background_end_color = '#590909'
|
||||
theme_copy.background_main_color = '#090909'
|
||||
theme_copy.background_footer_color = '#090909'
|
||||
# If background is transparent and this is not a display, inject checkerboard background image instead
|
||||
elif theme.background_type == 'transparent':
|
||||
theme_copy.background_type = 'image'
|
||||
theme_copy.background_filename = self.checkerboard_path
|
||||
exported_theme = theme_copy.export_theme(is_js=True)
|
||||
else:
|
||||
exported_theme = theme.export_theme(is_js=True)
|
||||
self.run_javascript('Display.setTheme({theme});'.format(theme=exported_theme), is_sync=is_sync)
|
||||
|
||||
def get_video_types(self):
|
||||
@ -398,12 +413,12 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
|
||||
"""
|
||||
if self.is_display:
|
||||
# Only make visible on single monitor setup if setting enabled.
|
||||
if len(ScreenList()) == 1 and not Settings().value('core/display on monitor'):
|
||||
if len(ScreenList()) == 1 and not self.settings.value('core/display on monitor'):
|
||||
return
|
||||
self.run_javascript('Display.show();')
|
||||
# Check if setting for hiding logo on startup is enabled.
|
||||
# If it is, display should remain hidden, otherwise logo is shown. (from def setup)
|
||||
if self.isHidden() and not Settings().value('core/logo hide on startup'):
|
||||
if self.isHidden() and not self.settings.value('core/logo hide on startup'):
|
||||
self.setVisible(True)
|
||||
self.hide_mode = None
|
||||
# Trigger actions when display is active again.
|
||||
@ -425,7 +440,7 @@ class DisplayWindow(QtWidgets.QWidget, RegistryProperties):
|
||||
log.debug('hide_display mode = {mode:d}'.format(mode=mode))
|
||||
if self.is_display:
|
||||
# Only make visible on single monitor setup if setting enabled.
|
||||
if len(ScreenList()) == 1 and not Settings().value('core/display on monitor'):
|
||||
if len(ScreenList()) == 1 and not self.settings.value('core/display on monitor'):
|
||||
return
|
||||
if mode == HideMode.Screen:
|
||||
self.setVisible(False)
|
||||
|
@ -157,6 +157,12 @@ class ItemCapabilities(object):
|
||||
|
||||
``HasMetaData``
|
||||
The item has Meta Data about item
|
||||
|
||||
``CanStream``
|
||||
The item requires to process a VLC Stream
|
||||
|
||||
``HasBackgroundVideo``
|
||||
That a video file is present with the text
|
||||
"""
|
||||
CanPreview = 1
|
||||
CanEdit = 2
|
||||
@ -181,6 +187,7 @@ class ItemCapabilities(object):
|
||||
HasThumbnails = 21
|
||||
HasMetaData = 22
|
||||
CanStream = 23
|
||||
HasBackgroundVideo = 24
|
||||
|
||||
|
||||
def get_text_file_string(text_file_path):
|
||||
|
@ -35,27 +35,19 @@ from PyQt5 import QtGui
|
||||
from openlp.core.state import State
|
||||
from openlp.core.common import ThemeLevel, md5_hash
|
||||
from openlp.core.common.applocation import AppLocation
|
||||
from openlp.core.common.enum import ServiceItemType
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.common.mixins import RegistryProperties
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.display.render import remove_tags, render_tags, render_chords_for_printing
|
||||
from openlp.core.lib import ItemCapabilities
|
||||
from openlp.core.lib.theme import BackgroundType
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ServiceItemType(object):
|
||||
"""
|
||||
Defines the type of service item
|
||||
"""
|
||||
Text = 1
|
||||
Image = 2
|
||||
Command = 3
|
||||
|
||||
|
||||
class ServiceItem(RegistryProperties):
|
||||
"""
|
||||
The service item is a base class for the plugins to use to interact with
|
||||
@ -123,12 +115,12 @@ class ServiceItem(RegistryProperties):
|
||||
the value in Settings is used when this value is missinig
|
||||
"""
|
||||
if theme_level is None:
|
||||
theme_level = Settings().value('themes/theme level')
|
||||
theme_level = self.settings.value('themes/theme level')
|
||||
theme_manager = Registry().get('theme_manager')
|
||||
# Just assume we use the global theme.
|
||||
theme = theme_manager.global_theme
|
||||
if theme_level != ThemeLevel.Global:
|
||||
service_theme = Settings().value('servicemanager/service theme')
|
||||
service_theme = self.settings.value('servicemanager/service theme')
|
||||
# Service or Song level, so assume service theme (if it exists and item in service)
|
||||
# but use song theme if level is song (and it exists)
|
||||
if service_theme and self.from_service:
|
||||
@ -136,6 +128,17 @@ class ServiceItem(RegistryProperties):
|
||||
if theme_level == ThemeLevel.Song and self.theme:
|
||||
theme = self.theme
|
||||
theme = theme_manager.get_theme_data(theme)
|
||||
# Clean up capabilities and reload from the theme.
|
||||
if self.is_text():
|
||||
if self.is_capable(ItemCapabilities.CanStream):
|
||||
self.remove_capability(ItemCapabilities.CanStream)
|
||||
if self.is_capable(ItemCapabilities.HasBackgroundVideo):
|
||||
self.remove_capability(ItemCapabilities.HasBackgroundVideo)
|
||||
if theme.background_type == BackgroundType.to_string(BackgroundType.Stream):
|
||||
self.add_capability(ItemCapabilities.CanStream)
|
||||
if theme.background_type == BackgroundType.to_string(BackgroundType.Video):
|
||||
self.video_file_name = theme.background_filename
|
||||
self.add_capability(ItemCapabilities.HasBackgroundVideo)
|
||||
return theme
|
||||
|
||||
def _new_item(self):
|
||||
@ -153,6 +156,14 @@ class ServiceItem(RegistryProperties):
|
||||
"""
|
||||
self.capabilities.append(capability)
|
||||
|
||||
def remove_capability(self, capability):
|
||||
"""
|
||||
Remove an ItemCapability from a ServiceItem
|
||||
|
||||
:param capability: The capability to remove
|
||||
"""
|
||||
self.capabilities.remove(capability)
|
||||
|
||||
def is_capable(self, capability):
|
||||
"""
|
||||
Tell the caller if a ServiceItem has a capability
|
||||
@ -433,7 +444,7 @@ class ServiceItem(RegistryProperties):
|
||||
self._create_slides()
|
||||
elif self.service_item_type == ServiceItemType.Image:
|
||||
settings_section = service_item['serviceitem']['header']['name']
|
||||
background = QtGui.QColor(Settings().value(settings_section + '/background color'))
|
||||
background = QtGui.QColor(self.settings.value(settings_section + '/background color'))
|
||||
if path:
|
||||
self.has_original_files = False
|
||||
for text_image in service_item['serviceitem']['data']:
|
||||
@ -649,6 +660,11 @@ class ServiceItem(RegistryProperties):
|
||||
if self.get_frame_path(frame=frame) in invalid_paths:
|
||||
self.remove_frame(frame)
|
||||
|
||||
def requires_media(self):
|
||||
return self.is_capable(ItemCapabilities.HasBackgroundAudio) or \
|
||||
self.is_capable(ItemCapabilities.HasBackgroundVideo) or \
|
||||
self.is_capable(ItemCapabilities.CanStream)
|
||||
|
||||
def missing_frames(self):
|
||||
"""
|
||||
Returns if there are any frames in the service item
|
||||
|
@ -51,7 +51,7 @@ class BackgroundPage(GridLayoutPage):
|
||||
self.background_label.setObjectName('background_label')
|
||||
self.layout.addWidget(self.background_label, 0, 0)
|
||||
self.background_combo_box = QtWidgets.QComboBox(self)
|
||||
self.background_combo_box.addItems(['', '', '', ''])
|
||||
self.background_combo_box.addItems(['', '', '', '', '', ''])
|
||||
self.background_combo_box.setObjectName('background_combo_box')
|
||||
self.layout.addWidget(self.background_combo_box, 0, 1, 1, 3)
|
||||
# color
|
||||
@ -130,8 +130,11 @@ class BackgroundPage(GridLayoutPage):
|
||||
self.background_combo_box.setItemText(BackgroundType.Solid, translate('OpenLP.ThemeWizard', 'Solid color'))
|
||||
self.background_combo_box.setItemText(BackgroundType.Gradient, translate('OpenLP.ThemeWizard', 'Gradient'))
|
||||
self.background_combo_box.setItemText(BackgroundType.Image, UiStrings().Image)
|
||||
self.background_combo_box.setItemText(BackgroundType.Video, UiStrings().Video)
|
||||
self.background_combo_box.setItemText(BackgroundType.Transparent,
|
||||
translate('OpenLP.ThemeWizard', 'Transparent'))
|
||||
self.background_combo_box.setItemText(BackgroundType.Stream,
|
||||
translate('OpenLP.ThemeWizard', 'Live Stream'))
|
||||
self.color_label.setText(translate('OpenLP.ThemeWizard', 'Color:'))
|
||||
self.gradient_start_label.setText(translate('OpenLP.ThemeWizard', 'Starting color:'))
|
||||
self.gradient_end_label.setText(translate('OpenLP.ThemeWizard', 'Ending color:'))
|
||||
|
@ -118,3 +118,6 @@ def format_milliseconds(milliseconds):
|
||||
minutes=minutes,
|
||||
seconds=seconds,
|
||||
millis=millis)
|
||||
|
||||
|
||||
media_empty_song = [{"title": "", "text": "", "verse": 0, "footer": ""}]
|
||||
|
@ -37,6 +37,7 @@ from openlp.core.api.http import register_endpoint
|
||||
from openlp.core.common import is_linux, is_macosx
|
||||
from openlp.core.common.i18n import translate
|
||||
from openlp.core.common.mixins import LogMixin, RegistryProperties
|
||||
from openlp.core.common.path import path_to_str
|
||||
from openlp.core.common.registry import Registry, RegistryBase
|
||||
from openlp.core.lib.serviceitem import ItemCapabilities
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
@ -104,7 +105,6 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
fedora_rpmfusion = translate('OpenLP.MediaController',
|
||||
'To install these libraries, you will need to enable the RPMFusion '
|
||||
'repository: https://rpmfusion.org/')
|
||||
message = ''
|
||||
if is_macosx():
|
||||
message = translate('OpenLP.MediaController',
|
||||
'macOS is missing VLC. Please download and install from the VLC web site: '
|
||||
@ -132,8 +132,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
except AttributeError:
|
||||
State().update_pre_conditions('media_live', False)
|
||||
State().missing_text('media_live', translate(
|
||||
'OpenLP.MediaController',
|
||||
'No Displays have been configured, so Live Media has been disabled'))
|
||||
'OpenLP.MediaController', 'No Displays have been configured, so Live Media has been disabled'))
|
||||
self.setup_display(self.preview_controller, True)
|
||||
|
||||
def display_controllers(self, controller_type):
|
||||
@ -230,6 +229,15 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
# background will always loop video.
|
||||
if service_item.is_capable(ItemCapabilities.HasBackgroundAudio):
|
||||
controller.media_info.file_info = service_item.background_audio
|
||||
else:
|
||||
if service_item.is_capable(ItemCapabilities.HasBackgroundVideo):
|
||||
controller.media_info.file_info = [service_item.video_file_name]
|
||||
service_item.media_length = self.media_length(path_to_str(service_item.video_file_name))
|
||||
controller.media_info.is_looping_playback = True
|
||||
controller.media_info.is_background = True
|
||||
elif service_item.is_capable(ItemCapabilities.CanStream):
|
||||
controller.media_info.file_info = []
|
||||
controller.media_info.is_background = True
|
||||
else:
|
||||
controller.media_info.file_info = [service_item.get_frame_path()]
|
||||
display = self._define_display(controller)
|
||||
@ -271,7 +279,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
return False
|
||||
log.debug('video media type: {tpe} '.format(tpe=str(controller.media_info.media_type)))
|
||||
autoplay = False
|
||||
if service_item.is_capable(ItemCapabilities.CanStream):
|
||||
if service_item.requires_media():
|
||||
autoplay = True
|
||||
# Preview requested
|
||||
if not controller.is_live:
|
||||
@ -437,12 +445,9 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
controller.seek_slider.blockSignals(False)
|
||||
controller.volume_slider.blockSignals(False)
|
||||
controller.media_info.is_playing = True
|
||||
if not controller.media_info.is_background:
|
||||
display = self._define_display(controller)
|
||||
if controller.is_live:
|
||||
display.setVisible(False)
|
||||
controller.preview_display.hide()
|
||||
else:
|
||||
display.setVisible(True)
|
||||
return True
|
||||
|
||||
def tick(self, controller):
|
||||
@ -537,7 +542,6 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
if controller.controller_type in self.current_media_players:
|
||||
self.current_media_players[controller.controller_type].stop(controller)
|
||||
self.current_media_players[controller.controller_type].set_visible(controller, False)
|
||||
controller.preview_display.hide()
|
||||
controller.seek_slider.setSliderPosition(0)
|
||||
total_seconds = controller.media_info.length // 1000
|
||||
total_minutes = total_seconds // 60
|
||||
|
@ -32,7 +32,6 @@ from time import sleep
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common import is_linux, is_macosx, is_win
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.display.screens import ScreenList
|
||||
from openlp.core.ui.media import MediaState, MediaType
|
||||
from openlp.core.ui.media.mediaplayer import MediaPlayer
|
||||
@ -114,10 +113,10 @@ class VlcPlayer(MediaPlayer):
|
||||
controller.vlc_widget.setFrameStyle(QtWidgets.QFrame.NoFrame)
|
||||
# creating a basic vlc instance
|
||||
command_line_options = '--no-video-title-show '
|
||||
if Settings().value('advanced/hide mouse') and live_display:
|
||||
if self.settings.value('advanced/hide mouse') and live_display:
|
||||
command_line_options += '--mouse-hide-timeout=0 '
|
||||
if Settings().value('media/vlc arguments'):
|
||||
command_line_options += Settings().value('media/vlc arguments')
|
||||
if self.settings.value('media/vlc arguments'):
|
||||
command_line_options += self.settings.value('media/vlc arguments')
|
||||
controller.vlc_instance = vlc.Instance(command_line_options)
|
||||
# creating an empty vlc media player
|
||||
controller.vlc_media_player = controller.vlc_instance.media_player_new()
|
||||
@ -176,7 +175,7 @@ class VlcPlayer(MediaPlayer):
|
||||
return False
|
||||
controller.vlc_media_player = audio_cd_tracks.item_at_index(controller.media_info.title_track)
|
||||
elif controller.media_info.media_type == MediaType.Stream:
|
||||
stream_cmd = Settings().value('media/stream command')
|
||||
stream_cmd = self.settings.value('media/stream command')
|
||||
controller.vlc_media = controller.vlc_instance.media_new_location(stream_cmd)
|
||||
else:
|
||||
controller.vlc_media = controller.vlc_instance.media_new_path(path)
|
||||
|
@ -37,6 +37,7 @@ from openlp.core.state import State
|
||||
from openlp.core.common import ThemeLevel, delete_file
|
||||
from openlp.core.common.actions import ActionList, CategoryOrder
|
||||
from openlp.core.common.applocation import AppLocation
|
||||
from openlp.core.common.enum import ServiceItemType
|
||||
from openlp.core.common.i18n import UiStrings, format_time, translate
|
||||
from openlp.core.common.json import OpenLPJSONDecoder, OpenLPJSONEncoder
|
||||
from openlp.core.common.mixins import LogMixin, RegistryProperties
|
||||
@ -45,7 +46,7 @@ from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib import build_icon
|
||||
from openlp.core.lib.exceptions import ValidationError
|
||||
from openlp.core.lib.plugin import PluginStatus
|
||||
from openlp.core.lib.serviceitem import ItemCapabilities, ServiceItem, ServiceItemType
|
||||
from openlp.core.lib.serviceitem import ItemCapabilities, ServiceItem
|
||||
from openlp.core.lib.ui import create_widget_action, critical_error_message_box, find_and_set_in_combo_box
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.ui.media import AUDIO_EXT, VIDEO_EXT
|
||||
|
@ -38,6 +38,7 @@ from openlp.core.display.screens import ScreenList
|
||||
from openlp.core.display.window import DisplayWindow
|
||||
from openlp.core.lib import ServiceItemAction, image_to_byte
|
||||
from openlp.core.lib.serviceitem import ItemCapabilities
|
||||
from openlp.core.ui.media import media_empty_song
|
||||
from openlp.core.lib.ui import create_action
|
||||
from openlp.core.ui import DisplayControllerType, HideMode
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
@ -842,6 +843,20 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
||||
self.delay_spin_box.setValue(int(item.timed_slide_interval))
|
||||
self.on_play_slides_once()
|
||||
|
||||
def _set_theme(self, service_item):
|
||||
"""
|
||||
Set up the theme from the service item.
|
||||
|
||||
:param service_item: The current service item
|
||||
"""
|
||||
# Get theme
|
||||
theme_data = service_item.get_theme_data()
|
||||
# Set theme for preview
|
||||
self.preview_display.set_theme(theme_data, service_item_type=service_item.service_item_type)
|
||||
# Set theme for displays
|
||||
for display in self.displays:
|
||||
display.set_theme(service_item.get_theme_data(), service_item_type=service_item.service_item_type)
|
||||
|
||||
def _process_item(self, service_item, slide_no):
|
||||
"""
|
||||
Loads a ServiceItem into the system from ServiceManager. Display the slide number passed.
|
||||
@ -861,26 +876,15 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
||||
'{text}_start'.format(text=service_item.name.lower()),
|
||||
[self.service_item, self.is_live, self.hide_mode(), slide_no])
|
||||
else:
|
||||
# Get theme
|
||||
theme_data = service_item.get_theme_data()
|
||||
# Set theme for preview
|
||||
self.preview_display.set_theme(theme_data)
|
||||
# Set theme for displays
|
||||
for display in self.displays:
|
||||
display.set_theme(theme_data)
|
||||
|
||||
self._set_theme(service_item)
|
||||
# Reset blanking if needed
|
||||
if old_item and self.is_live and (old_item.is_capable(ItemCapabilities.ProvidesOwnDisplay) or
|
||||
self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay)):
|
||||
self._reset_blank(self.service_item.is_capable(ItemCapabilities.ProvidesOwnDisplay))
|
||||
self.info_label.setText(self.service_item.title)
|
||||
self.slide_list = {}
|
||||
if old_item and old_item.is_capable(ItemCapabilities.HasBackgroundAudio):
|
||||
if old_item and old_item.requires_media():
|
||||
self.on_media_close()
|
||||
if self.is_live:
|
||||
self.song_menu.menu().clear()
|
||||
if self.service_item.is_capable(ItemCapabilities.HasBackgroundAudio):
|
||||
self.on_media_start(service_item)
|
||||
row = 0
|
||||
width = self.main_window.control_splitter.sizes()[self.split]
|
||||
if self.service_item.is_text():
|
||||
@ -912,7 +916,10 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
||||
self.slide_list[str(row)] = row - 1
|
||||
self.preview_widget.replace_service_item(self.service_item, width, slide_no)
|
||||
self.enable_tool_bar(self.service_item)
|
||||
if self.service_item.is_media():
|
||||
if self.service_item.is_media() or self.service_item.requires_media():
|
||||
self._set_theme(service_item)
|
||||
if self.service_item.is_command():
|
||||
self.preview_display.load_verses(media_empty_song, True)
|
||||
self.on_media_start(self.service_item)
|
||||
self.slide_selected(True)
|
||||
if self.service_item.from_service:
|
||||
|
@ -24,7 +24,6 @@ Package to test the openlp.core.display.window package.
|
||||
import sys
|
||||
import time
|
||||
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from PyQt5 import QtCore
|
||||
@ -33,25 +32,16 @@ from PyQt5 import QtCore
|
||||
sys.modules['PyQt5.QtWebEngineWidgets'] = MagicMock()
|
||||
|
||||
from openlp.core.display.window import DisplayWindow
|
||||
from tests.helpers.testmixin import TestMixin
|
||||
|
||||
|
||||
@patch('PyQt5.QtWidgets.QVBoxLayout')
|
||||
@patch('openlp.core.display.webengine.WebEngineView')
|
||||
@patch('openlp.core.display.window.Settings')
|
||||
class TestDisplayWindow(TestCase, TestMixin):
|
||||
"""
|
||||
A test suite to test the functions in DisplayWindow
|
||||
"""
|
||||
|
||||
def test_x11_override_on(self, MockSettings, mocked_webengine, mocked_addWidget):
|
||||
def test_x11_override_on(mocked_webengine, mocked_addWidget, mock_settings):
|
||||
"""
|
||||
Test that the x11 override option bit is set
|
||||
"""
|
||||
# GIVEN: x11 bypass is on
|
||||
mocked_settings = MagicMock()
|
||||
mocked_settings.value.return_value = True
|
||||
MockSettings.return_value = mocked_settings
|
||||
mock_settings.value.return_value = True
|
||||
|
||||
# WHEN: A DisplayWindow is generated
|
||||
display_window = DisplayWindow()
|
||||
@ -60,14 +50,15 @@ class TestDisplayWindow(TestCase, TestMixin):
|
||||
x11_bit = display_window.windowFlags() & QtCore.Qt.X11BypassWindowManagerHint
|
||||
assert x11_bit == QtCore.Qt.X11BypassWindowManagerHint
|
||||
|
||||
def test_x11_override_off(self, MockSettings, mocked_webengine, mocked_addWidget):
|
||||
|
||||
@patch('PyQt5.QtWidgets.QVBoxLayout')
|
||||
@patch('openlp.core.display.webengine.WebEngineView')
|
||||
def test_x11_override_off(mocked_webengine, mocked_addWidget, mock_settings):
|
||||
"""
|
||||
Test that the x11 override option bit is not set when setting if off
|
||||
"""
|
||||
# GIVEN: x11 bypass is off
|
||||
mocked_settings = MagicMock()
|
||||
mocked_settings.value.return_value = False
|
||||
MockSettings.return_value = mocked_settings
|
||||
mock_settings.value.return_value = False
|
||||
|
||||
# WHEN: A DisplayWindow is generated
|
||||
display_window = DisplayWindow()
|
||||
@ -76,7 +67,9 @@ class TestDisplayWindow(TestCase, TestMixin):
|
||||
x11_bit = display_window.windowFlags() & QtCore.Qt.X11BypassWindowManagerHint
|
||||
assert x11_bit != QtCore.Qt.X11BypassWindowManagerHint
|
||||
|
||||
def test_set_scale_not_initialised(self, MockSettings, mocked_webengine, mocked_addWidget):
|
||||
|
||||
@patch('PyQt5.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
|
||||
"""
|
||||
@ -91,7 +84,10 @@ class TestDisplayWindow(TestCase, TestMixin):
|
||||
# THEN: javascript should not be run
|
||||
display_window.run_javascript.assert_not_called()
|
||||
|
||||
def test_set_scale_initialised(self, MockSettings, mocked_webengine, mocked_addWidget):
|
||||
|
||||
@patch('PyQt5.QtWidgets.QVBoxLayout')
|
||||
@patch('openlp.core.display.webengine.WebEngineView')
|
||||
def test_set_scale_initialised(mocked_webengine, mocked_addWidget, mock_settings):
|
||||
"""
|
||||
Test that the scale js is not run if the page is not initialised
|
||||
"""
|
||||
@ -106,8 +102,11 @@ class TestDisplayWindow(TestCase, TestMixin):
|
||||
# THEN: javascript should not be run
|
||||
display_window.run_javascript.assert_called_once_with('Display.setScale(50.0);')
|
||||
|
||||
@patch.object(time, 'time')
|
||||
def test_run_javascript_no_sync_no_wait(self, MockSettings, mocked_webengine, mocked_addWidget, mock_time):
|
||||
|
||||
@patch('PyQt5.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):
|
||||
"""
|
||||
test a script is run on the webview
|
||||
"""
|
||||
@ -123,8 +122,11 @@ class TestDisplayWindow(TestCase, TestMixin):
|
||||
webengine_page.runJavaScript.assert_called_once_with('javascript to execute')
|
||||
mock_time.sleep.assert_not_called()
|
||||
|
||||
@patch.object(time, 'time')
|
||||
def test_run_javascript_sync_no_wait(self, MockSettings, mocked_webengine, mocked_addWidget, mock_time):
|
||||
|
||||
@patch('PyQt5.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):
|
||||
"""
|
||||
test a synced script is run on the webview and immediately returns a result
|
||||
"""
|
||||
|
@ -28,10 +28,11 @@ from unittest.mock import Mock, MagicMock, patch
|
||||
|
||||
from openlp.core.state import State
|
||||
from openlp.core.common import ThemeLevel, md5_hash
|
||||
from openlp.core.common.enum import ServiceItemType
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib.formattingtags import FormattingTags
|
||||
from openlp.core.lib.serviceitem import ItemCapabilities, ServiceItem, ServiceItemType
|
||||
from openlp.core.lib.serviceitem import ItemCapabilities, ServiceItem
|
||||
from tests.helpers.testmixin import TestMixin
|
||||
from tests.utils import convert_file_service_item
|
||||
from tests.utils.constants import RESOURCE_PATH
|
||||
@ -78,6 +79,7 @@ class TestServiceItem(TestCase, TestMixin):
|
||||
Registry.create()
|
||||
# Mock the renderer and its format_slide method
|
||||
mocked_renderer = MagicMock()
|
||||
Registry().register('settings', Settings())
|
||||
|
||||
def side_effect_return_arg(arg1, arg2):
|
||||
return [arg1]
|
||||
|
@ -29,7 +29,6 @@ def test_parse_optical_path_linux():
|
||||
"""
|
||||
Test that test_parse_optical_path() parses a optical path with linux device path correctly
|
||||
"""
|
||||
|
||||
# GIVEN: An optical formatted path
|
||||
org_title_track = 1
|
||||
org_audio_track = 2
|
||||
@ -58,7 +57,6 @@ def test_parse_optical_path_win():
|
||||
"""
|
||||
Test that test_parse_optical_path() parses a optical path with windows device path correctly
|
||||
"""
|
||||
|
||||
# GIVEN: An optical formatted path
|
||||
org_title_track = 1
|
||||
org_audio_track = 2
|
||||
|
@ -21,14 +21,14 @@
|
||||
"""
|
||||
Package to test the openlp.core.ui.media package.
|
||||
"""
|
||||
from unittest import TestCase
|
||||
import pytest
|
||||
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.ui import DisplayControllerType
|
||||
from openlp.core.ui.media.mediacontroller import MediaController
|
||||
from openlp.core.ui.media import ItemMediaInfo
|
||||
from tests.helpers.testmixin import TestMixin
|
||||
|
||||
from tests.utils.constants import RESOURCE_PATH
|
||||
|
||||
@ -37,256 +37,258 @@ TEST_PATH = RESOURCE_PATH / 'media'
|
||||
TEST_MEDIA = [['avi_file.avi', 61495], ['mp3_file.mp3', 134426], ['mpg_file.mpg', 9404], ['mp4_file.mp4', 188336]]
|
||||
|
||||
|
||||
class TestMediaController(TestCase, TestMixin):
|
||||
|
||||
def setUp(self):
|
||||
Registry.create()
|
||||
@pytest.yield_fixture
|
||||
def media_env(registry):
|
||||
"""Local test setup"""
|
||||
Registry().register('service_manager', MagicMock())
|
||||
media_controller = MediaController()
|
||||
yield media_controller
|
||||
|
||||
def test_resize(self):
|
||||
|
||||
def test_resize(media_env):
|
||||
"""
|
||||
Test that the resize method is called correctly
|
||||
"""
|
||||
# GIVEN: A media controller, a player and a display
|
||||
media_controller = MediaController()
|
||||
mocked_player = MagicMock()
|
||||
mocked_display = MagicMock()
|
||||
|
||||
# WHEN: resize() is called
|
||||
media_controller.resize(mocked_display, mocked_player)
|
||||
media_env.media_controller.resize(mocked_display, mocked_player)
|
||||
|
||||
# THEN: The player's resize method should be called correctly
|
||||
mocked_player.resize.assert_called_with(mocked_display)
|
||||
|
||||
def test_check_file_type_null(self):
|
||||
|
||||
def test_check_file_type_null(media_env):
|
||||
"""
|
||||
Test that we don't try to play media when no players available
|
||||
"""
|
||||
# GIVEN: A mocked UiStrings, get_used_players, controller, display and service_item
|
||||
media_controller = MediaController()
|
||||
mocked_controller = MagicMock()
|
||||
mocked_display = MagicMock()
|
||||
media_controller.media_players = MagicMock()
|
||||
media_env.media_controller.media_players = MagicMock()
|
||||
|
||||
# WHEN: calling _check_file_type when no players exists
|
||||
ret = media_controller._check_file_type(mocked_controller, mocked_display)
|
||||
ret = media_env.media_controller._check_file_type(mocked_controller, mocked_display)
|
||||
|
||||
# THEN: it should return False
|
||||
assert ret is False, '_check_file_type should return False when no media file matches.'
|
||||
|
||||
def test_check_file_video(self):
|
||||
|
||||
def test_check_file_video(media_env):
|
||||
"""
|
||||
Test that we process a file that is valid
|
||||
"""
|
||||
# GIVEN: A mocked UiStrings, get_used_players, controller, display and service_item
|
||||
media_controller = MediaController()
|
||||
mocked_controller = MagicMock()
|
||||
mocked_display = MagicMock()
|
||||
media_controller.media_players = MagicMock()
|
||||
media_env.media_controller.media_players = MagicMock()
|
||||
mocked_controller.media_info = ItemMediaInfo()
|
||||
mocked_controller.media_info.file_info = [TEST_PATH / 'mp3_file.mp3']
|
||||
media_controller.current_media_players = {}
|
||||
media_controller.vlc_player = MagicMock()
|
||||
media_env.media_controller.current_media_players = {}
|
||||
media_env.media_controller.vlc_player = MagicMock()
|
||||
|
||||
# WHEN: calling _check_file_type when no players exists
|
||||
ret = media_controller._check_file_type(mocked_controller, mocked_display)
|
||||
ret = media_env.media_controller._check_file_type(mocked_controller, mocked_display)
|
||||
|
||||
# THEN: it should return False
|
||||
assert ret is True, '_check_file_type should return True when audio file is present and matches.'
|
||||
|
||||
def test_check_file_audio(self):
|
||||
|
||||
def test_check_file_audio(media_env):
|
||||
"""
|
||||
Test that we process a file that is valid
|
||||
"""
|
||||
# GIVEN: A mocked UiStrings, get_used_players, controller, display and service_item
|
||||
media_controller = MediaController()
|
||||
mocked_controller = MagicMock()
|
||||
mocked_display = MagicMock()
|
||||
media_controller.media_players = MagicMock()
|
||||
media_env.media_controller.media_players = MagicMock()
|
||||
mocked_controller.media_info = ItemMediaInfo()
|
||||
mocked_controller.media_info.file_info = [TEST_PATH / 'mp4_file.mp4']
|
||||
media_controller.current_media_players = {}
|
||||
media_controller.vlc_player = MagicMock()
|
||||
media_env.media_controller.current_media_players = {}
|
||||
media_env.media_controller.vlc_player = MagicMock()
|
||||
|
||||
# WHEN: calling _check_file_type when no players exists
|
||||
ret = media_controller._check_file_type(mocked_controller, mocked_display)
|
||||
ret = media_env.media_controller._check_file_type(mocked_controller, mocked_display)
|
||||
|
||||
# THEN: it should return False
|
||||
assert ret is True, '_check_file_type should return True when media file is present and matches.'
|
||||
|
||||
def test_media_play_msg(self):
|
||||
|
||||
def test_media_play_msg(media_env):
|
||||
"""
|
||||
Test that the media controller responds to the request to play a loaded video
|
||||
"""
|
||||
# GIVEN: A media controller and a message with two elements
|
||||
media_controller = MediaController()
|
||||
message = (1, 2)
|
||||
|
||||
# WHEN: media_play_msg() is called
|
||||
with patch.object(media_controller, u'media_play') as mocked_media_play:
|
||||
media_controller.media_play_msg(message, False)
|
||||
with patch.object(media_env.media_controller, u'media_play') as mocked_media_play:
|
||||
media_env.media_controller.media_play_msg(message, False)
|
||||
|
||||
# THEN: The underlying method is called
|
||||
mocked_media_play.assert_called_with(1, False)
|
||||
|
||||
def test_media_pause_msg(self):
|
||||
|
||||
def test_media_pause_msg(media_env):
|
||||
"""
|
||||
Test that the media controller responds to the request to pause a loaded video
|
||||
"""
|
||||
# GIVEN: A media controller and a message with two elements
|
||||
media_controller = MediaController()
|
||||
message = (1, 2)
|
||||
|
||||
# WHEN: media_play_msg() is called
|
||||
with patch.object(media_controller, u'media_pause') as mocked_media_pause:
|
||||
media_controller.media_pause_msg(message)
|
||||
with patch.object(media_env.media_controller, u'media_pause') as mocked_media_pause:
|
||||
media_env.media_controller.media_pause_msg(message)
|
||||
|
||||
# THEN: The underlying method is called
|
||||
mocked_media_pause.assert_called_with(1)
|
||||
|
||||
def test_media_stop_msg(self):
|
||||
|
||||
def test_media_stop_msg(media_env):
|
||||
"""
|
||||
Test that the media controller responds to the request to stop a loaded video
|
||||
"""
|
||||
# GIVEN: A media controller and a message with two elements
|
||||
media_controller = MediaController()
|
||||
message = (1, 2)
|
||||
|
||||
# WHEN: media_play_msg() is called
|
||||
with patch.object(media_controller, u'media_stop') as mocked_media_stop:
|
||||
media_controller.media_stop_msg(message)
|
||||
with patch.object(media_env.media_controller, u'media_stop') as mocked_media_stop:
|
||||
media_env.media_controller.media_stop_msg(message)
|
||||
|
||||
# THEN: The underlying method is called
|
||||
mocked_media_stop.assert_called_with(1)
|
||||
|
||||
def test_media_volume_msg(self):
|
||||
|
||||
def test_media_volume_msg(media_env):
|
||||
"""
|
||||
Test that the media controller responds to the request to change the volume
|
||||
"""
|
||||
# GIVEN: A media controller and a message with two elements
|
||||
media_controller = MediaController()
|
||||
message = (1, [50])
|
||||
|
||||
# WHEN: media_play_msg() is called
|
||||
with patch.object(media_controller, u'media_volume') as mocked_media_volume:
|
||||
media_controller.media_volume_msg(message)
|
||||
with patch.object(media_env.media_controller, u'media_volume') as mocked_media_volume:
|
||||
media_env.media_controller.media_volume_msg(message)
|
||||
|
||||
# THEN: The underlying method is called
|
||||
mocked_media_volume.assert_called_with(1, 50)
|
||||
|
||||
def test_media_seek_msg(self):
|
||||
|
||||
def test_media_seek_msg(media_env):
|
||||
"""
|
||||
Test that the media controller responds to the request to seek to a particular position
|
||||
"""
|
||||
# GIVEN: A media controller and a message with two elements
|
||||
media_controller = MediaController()
|
||||
message = (1, [800])
|
||||
|
||||
# WHEN: media_play_msg() is called
|
||||
with patch.object(media_controller, u'media_seek') as mocked_media_seek:
|
||||
media_controller.media_seek_msg(message)
|
||||
with patch.object(media_env.media_controller, u'media_seek') as mocked_media_seek:
|
||||
media_env.media_controller.media_seek_msg(message)
|
||||
|
||||
# THEN: The underlying method is called
|
||||
mocked_media_seek.assert_called_with(1, 800)
|
||||
|
||||
def test_media_length(self):
|
||||
|
||||
def test_media_length(media_env):
|
||||
"""
|
||||
Test the Media Info basic functionality
|
||||
"""
|
||||
media_controller = MediaController()
|
||||
for test_data in TEST_MEDIA:
|
||||
# GIVEN: a media file
|
||||
full_path = str(TEST_PATH / test_data[0])
|
||||
|
||||
# WHEN the media data is retrieved
|
||||
results = media_controller.media_length(full_path)
|
||||
results = media_env.media_controller.media_length(full_path)
|
||||
|
||||
# THEN you can determine the run time
|
||||
assert results == test_data[1], 'The correct duration is returned for ' + test_data[0]
|
||||
|
||||
def test_on_media_play(self):
|
||||
|
||||
def test_on_media_play(media_env):
|
||||
"""
|
||||
Test the on_media_play method
|
||||
"""
|
||||
# GIVEN: A mocked live controller and a mocked media_play() method
|
||||
mocked_live_controller = MagicMock()
|
||||
Registry().register('live_controller', mocked_live_controller)
|
||||
media_controller = MediaController()
|
||||
media_controller.media_play = MagicMock()
|
||||
media_env.media_controller.media_play = MagicMock()
|
||||
|
||||
# WHEN: the on_media_play() method is called
|
||||
media_controller.on_media_play()
|
||||
media_env.media_controller.on_media_play()
|
||||
|
||||
# The mocked live controller should be called
|
||||
media_controller.media_play.assert_called_once_with(mocked_live_controller, False)
|
||||
media_env.media_controller.media_play.assert_called_once_with(mocked_live_controller, False)
|
||||
|
||||
def test_on_media_pause(self):
|
||||
|
||||
def test_on_media_pause(media_env):
|
||||
"""
|
||||
Test the on_media_pause method
|
||||
"""
|
||||
# GIVEN: A mocked live controller and a mocked media_pause() method
|
||||
mocked_live_controller = MagicMock()
|
||||
Registry().register('live_controller', mocked_live_controller)
|
||||
media_controller = MediaController()
|
||||
media_controller.media_pause = MagicMock()
|
||||
media_env.media_controller.media_pause = MagicMock()
|
||||
|
||||
# WHEN: the on_media_pause() method is called
|
||||
media_controller.on_media_pause()
|
||||
media_env.media_controller.on_media_pause()
|
||||
|
||||
# The mocked live controller should be called
|
||||
media_controller.media_pause.assert_called_once_with(mocked_live_controller)
|
||||
media_env.media_controller.media_pause.assert_called_once_with(mocked_live_controller)
|
||||
|
||||
def test_on_media_stop(self):
|
||||
|
||||
def test_on_media_stop(media_env):
|
||||
"""
|
||||
Test the on_media_stop method
|
||||
"""
|
||||
# GIVEN: A mocked live controller and a mocked media_stop() method
|
||||
mocked_live_controller = MagicMock()
|
||||
Registry().register('live_controller', mocked_live_controller)
|
||||
media_controller = MediaController()
|
||||
media_controller.media_stop = MagicMock()
|
||||
media_env.media_controller.media_stop = MagicMock()
|
||||
|
||||
# WHEN: the on_media_stop() method is called
|
||||
media_controller.on_media_stop()
|
||||
media_env.media_controller.on_media_stop()
|
||||
|
||||
# The mocked live controller should be called
|
||||
media_controller.media_stop.assert_called_once_with(mocked_live_controller)
|
||||
media_env.media_controller.media_stop.assert_called_once_with(mocked_live_controller)
|
||||
|
||||
def test_display_controllers_live(self):
|
||||
|
||||
def test_display_controllers_live(media_env):
|
||||
"""
|
||||
Test that the display_controllers() method returns the live controller when requested
|
||||
"""
|
||||
# GIVEN: A mocked live controller
|
||||
media_controller = MediaController()
|
||||
mocked_live_controller = MagicMock()
|
||||
mocked_preview_controller = MagicMock()
|
||||
Registry().register('live_controller', mocked_live_controller)
|
||||
Registry().register('preview_controller', mocked_preview_controller)
|
||||
|
||||
# WHEN: display_controllers() is called with DisplayControllerType.Live
|
||||
controller = media_controller.display_controllers(DisplayControllerType.Live)
|
||||
controller = media_env.media_controller.display_controllers(DisplayControllerType.Live)
|
||||
|
||||
# THEN: the controller should be the live controller
|
||||
assert controller is mocked_live_controller
|
||||
|
||||
def test_display_controllers_preview(self):
|
||||
|
||||
def test_display_controllers_preview(media_env):
|
||||
"""
|
||||
Test that the display_controllers() method returns the preview controller when requested
|
||||
"""
|
||||
# GIVEN: A mocked live controller
|
||||
media_controller = MediaController()
|
||||
mocked_live_controller = MagicMock()
|
||||
mocked_preview_controller = MagicMock()
|
||||
Registry().register('live_controller', mocked_live_controller)
|
||||
Registry().register('preview_controller', mocked_preview_controller)
|
||||
|
||||
# WHEN: display_controllers() is called with DisplayControllerType.Preview
|
||||
controller = media_controller.display_controllers(DisplayControllerType.Preview)
|
||||
controller = media_env.media_controller.display_controllers(DisplayControllerType.Preview)
|
||||
|
||||
# THEN: the controller should be the live controller
|
||||
assert controller is mocked_preview_controller
|
||||
|
||||
def test_set_controls_visible(self):
|
||||
|
||||
def test_set_controls_visible(media_env):
|
||||
"""
|
||||
Test that "set_controls_visible" sets the media controls on the controller to be visible or not
|
||||
"""
|
||||
@ -299,26 +301,26 @@ class TestMediaController(TestCase, TestMixin):
|
||||
# THEN: The media controls should have been set to visible
|
||||
mocked_controller.mediabar.setVisible.assert_called_once_with(True)
|
||||
|
||||
@patch('openlp.core.ui.media.mediacontroller.ItemMediaInfo')
|
||||
def test_setup_display(self, MockItemMediaInfo):
|
||||
|
||||
@patch('openlp.core.ui.media.mediacontroller.ItemMediaInfo')
|
||||
def test_setup_display(MockItemMediaInfo, media_env):
|
||||
"""
|
||||
Test that the display/controllers are set up correctly
|
||||
"""
|
||||
# GIVEN: A media controller object and some mocks
|
||||
mocked_media_info = MagicMock()
|
||||
MockItemMediaInfo.return_value = mocked_media_info
|
||||
media_controller = MediaController()
|
||||
media_controller.vlc_player = MagicMock()
|
||||
media_env.media_controller.vlc_player = MagicMock()
|
||||
mocked_display = MagicMock()
|
||||
media_controller._define_display = MagicMock(return_value=mocked_display)
|
||||
media_controller.vlc_player = MagicMock()
|
||||
media_env.media_controller._define_display = MagicMock(return_value=mocked_display)
|
||||
media_env.media_controller.vlc_player = MagicMock()
|
||||
controller = MagicMock()
|
||||
|
||||
# WHEN: setup_display() is called
|
||||
media_controller.setup_display(controller, True)
|
||||
media_env.media_controller.setup_display(controller, True)
|
||||
|
||||
# THEN: The right calls should have been made
|
||||
assert controller.media_info == mocked_media_info
|
||||
assert controller.has_audio is False
|
||||
media_controller._define_display.assert_called_once_with(controller)
|
||||
media_controller.vlc_player.setup(controller, mocked_display, False)
|
||||
media_env.media_controller._define_display.assert_called_once_with(controller)
|
||||
media_env.media_controller.vlc_player.setup(controller, mocked_display, False)
|
||||
|
@ -35,7 +35,7 @@ from tests.helpers import MockDateTime
|
||||
|
||||
@pytest.yield_fixture
|
||||
def vlc_env():
|
||||
"""An instance of OpenLP"""
|
||||
"""Local test setup"""
|
||||
if 'VLC_PLUGIN_PATH' in os.environ:
|
||||
del os.environ['VLC_PLUGIN_PATH']
|
||||
if 'openlp.core.ui.media.vendor.vlc' in sys.modules:
|
||||
@ -60,7 +60,7 @@ def test_not_osx_fix_vlc_22_plugin_path(mocked_is_macosx):
|
||||
assert 'VLC_PLUGIN_PATH' not in os.environ, 'The plugin path should NOT be in the environment variables'
|
||||
|
||||
|
||||
def test_init():
|
||||
def test_init(mock_settings):
|
||||
"""
|
||||
Test that the VLC player class initialises correctly
|
||||
"""
|
||||
@ -81,17 +81,14 @@ def test_init():
|
||||
@patch('openlp.core.ui.media.vlcplayer.is_macosx')
|
||||
@patch('openlp.core.ui.media.vlcplayer.get_vlc')
|
||||
@patch('openlp.core.ui.media.vlcplayer.QtWidgets')
|
||||
@patch('openlp.core.ui.media.vlcplayer.Settings')
|
||||
def test_setup(MockedSettings, MockedQtWidgets, mocked_get_vlc, mocked_is_macosx, mocked_is_win):
|
||||
def test_setup(MockedQtWidgets, mocked_get_vlc, mocked_is_macosx, mocked_is_win, mock_settings):
|
||||
"""
|
||||
Test the setup method
|
||||
"""
|
||||
# GIVEN: A bunch of mocked out stuff and a VlcPlayer object
|
||||
mocked_is_macosx.return_value = False
|
||||
mocked_is_win.return_value = False
|
||||
mocked_settings = MagicMock()
|
||||
mocked_settings.value.return_value = ''
|
||||
MockedSettings.return_value = mocked_settings
|
||||
mock_settings.value.return_value = ''
|
||||
mocked_qframe = MagicMock()
|
||||
mocked_qframe.winId.return_value = 2
|
||||
MockedQtWidgets.QFrame.NoFrame = 1
|
||||
@ -114,8 +111,8 @@ def test_setup(MockedSettings, MockedQtWidgets, mocked_get_vlc, mocked_is_macosx
|
||||
# THEN: The VLC widget should be set up correctly
|
||||
assert mocked_output_display.vlc_widget == mocked_qframe
|
||||
mocked_qframe.setFrameStyle.assert_called_with(1)
|
||||
mocked_settings.value.assert_any_call('advanced/hide mouse')
|
||||
mocked_settings.value.assert_any_call('media/vlc arguments')
|
||||
mock_settings.value.assert_any_call('advanced/hide mouse')
|
||||
mock_settings.value.assert_any_call('media/vlc arguments')
|
||||
mocked_vlc.Instance.assert_called_with('--no-video-title-show ')
|
||||
assert mocked_output_display.vlc_instance == mocked_instance
|
||||
mocked_instance.media_player_new.assert_called_with()
|
||||
@ -132,17 +129,14 @@ def test_setup(MockedSettings, MockedQtWidgets, mocked_get_vlc, mocked_is_macosx
|
||||
@patch('openlp.core.ui.media.vlcplayer.is_macosx')
|
||||
@patch('openlp.core.ui.media.vlcplayer.get_vlc')
|
||||
@patch('openlp.core.ui.media.vlcplayer.QtWidgets')
|
||||
@patch('openlp.core.ui.media.vlcplayer.Settings')
|
||||
def test_setup_has_audio(MockedSettings, MockedQtWidgets, mocked_get_vlc, mocked_is_macosx, mocked_is_win):
|
||||
def test_setup_has_audio(MockedQtWidgets, mocked_get_vlc, mocked_is_macosx, mocked_is_win, mock_settings):
|
||||
"""
|
||||
Test the setup method when has_audio is True
|
||||
"""
|
||||
# GIVEN: A bunch of mocked out stuff and a VlcPlayer object
|
||||
mocked_is_macosx.return_value = False
|
||||
mocked_is_win.return_value = False
|
||||
mocked_settings = MagicMock()
|
||||
mocked_settings.value.return_value = ''
|
||||
MockedSettings.return_value = mocked_settings
|
||||
mock_settings.value.return_value = ''
|
||||
mocked_qframe = MagicMock()
|
||||
mocked_qframe.winId.return_value = 2
|
||||
MockedQtWidgets.QFrame.NoFrame = 1
|
||||
@ -170,17 +164,14 @@ def test_setup_has_audio(MockedSettings, MockedQtWidgets, mocked_get_vlc, mocked
|
||||
@patch('openlp.core.ui.media.vlcplayer.is_macosx')
|
||||
@patch('openlp.core.ui.media.vlcplayer.get_vlc')
|
||||
@patch('openlp.core.ui.media.vlcplayer.QtWidgets')
|
||||
@patch('openlp.core.ui.media.vlcplayer.Settings')
|
||||
def test_setup_visible_mouse(MockedSettings, MockedQtWidgets, mocked_get_vlc, mocked_is_macosx, mocked_is_win):
|
||||
def test_setup_visible_mouse(MockedQtWidgets, mocked_get_vlc, mocked_is_macosx, mocked_is_win, mock_settings):
|
||||
"""
|
||||
Test the setup method when Settings().value("hide mouse") is False
|
||||
"""
|
||||
# GIVEN: A bunch of mocked out stuff and a VlcPlayer object
|
||||
mocked_is_macosx.return_value = False
|
||||
mocked_is_win.return_value = False
|
||||
mocked_settings = MagicMock()
|
||||
mocked_settings.value.return_value = ''
|
||||
MockedSettings.return_value = mocked_settings
|
||||
mock_settings.value.return_value = ''
|
||||
mocked_qframe = MagicMock()
|
||||
mocked_qframe.winId.return_value = 2
|
||||
MockedQtWidgets.QFrame.NoFrame = 1
|
||||
@ -208,17 +199,14 @@ def test_setup_visible_mouse(MockedSettings, MockedQtWidgets, mocked_get_vlc, mo
|
||||
@patch('openlp.core.ui.media.vlcplayer.is_macosx')
|
||||
@patch('openlp.core.ui.media.vlcplayer.get_vlc')
|
||||
@patch('openlp.core.ui.media.vlcplayer.QtWidgets')
|
||||
@patch('openlp.core.ui.media.vlcplayer.Settings')
|
||||
def test_setup_windows(MockedSettings, MockedQtWidgets, mocked_get_vlc, mocked_is_macosx, mocked_is_win):
|
||||
def test_setup_windows(MockedQtWidgets, mocked_get_vlc, mocked_is_macosx, mocked_is_win, mock_settings):
|
||||
"""
|
||||
Test the setup method when running on Windows
|
||||
"""
|
||||
# GIVEN: A bunch of mocked out stuff and a VlcPlayer object
|
||||
mocked_is_macosx.return_value = False
|
||||
mocked_is_win.return_value = True
|
||||
mocked_settings = MagicMock()
|
||||
mocked_settings.value.return_value = False
|
||||
MockedSettings.return_value = mocked_settings
|
||||
mock_settings.value.return_value = False
|
||||
mocked_qframe = MagicMock()
|
||||
mocked_qframe.winId.return_value = 2
|
||||
MockedQtWidgets.QFrame.NoFrame = 1
|
||||
@ -246,17 +234,14 @@ def test_setup_windows(MockedSettings, MockedQtWidgets, mocked_get_vlc, mocked_i
|
||||
@patch('openlp.core.ui.media.vlcplayer.is_macosx')
|
||||
@patch('openlp.core.ui.media.vlcplayer.get_vlc')
|
||||
@patch('openlp.core.ui.media.vlcplayer.QtWidgets')
|
||||
@patch('openlp.core.ui.media.vlcplayer.Settings')
|
||||
def test_setup_osx(MockedSettings, MockedQtWidgets, mocked_get_vlc, mocked_is_macosx, mocked_is_win):
|
||||
def test_setup_osx(MockedQtWidgets, mocked_get_vlc, mocked_is_macosx, mocked_is_win, mock_settings):
|
||||
"""
|
||||
Test the setup method when running on OS X
|
||||
"""
|
||||
# GIVEN: A bunch of mocked out stuff and a VlcPlayer object
|
||||
mocked_is_macosx.return_value = True
|
||||
mocked_is_win.return_value = False
|
||||
mocked_settings = MagicMock()
|
||||
mocked_settings.value.return_value = False
|
||||
MockedSettings.return_value = mocked_settings
|
||||
mock_settings.value.return_value = False
|
||||
mocked_qframe = MagicMock()
|
||||
mocked_qframe.winId.return_value = 2
|
||||
MockedQtWidgets.QFrame.NoFrame = 1
|
||||
|
@ -28,7 +28,8 @@ import PyQt5
|
||||
|
||||
from openlp.core.common import ThemeLevel
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.lib.serviceitem import ItemCapabilities, ServiceItem, ServiceItemType
|
||||
from openlp.core.common.enum import ServiceItemType
|
||||
from openlp.core.lib.serviceitem import ItemCapabilities, ServiceItem
|
||||
from openlp.core.ui.servicemanager import ServiceManager
|
||||
from openlp.core.widgets.toolbar import OpenLPToolbar
|
||||
|
||||
|
@ -27,6 +27,7 @@ from unittest.mock import MagicMock, patch
|
||||
from PyQt5 import QtGui, QtWidgets
|
||||
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib.serviceitem import ServiceItem
|
||||
from openlp.core.state import State
|
||||
from openlp.core.widgets.views import ListPreviewWidget
|
||||
@ -52,6 +53,7 @@ class TestListPreviewWidget(TestCase, TestMixin):
|
||||
self.image_manager.get_image.return_value = self.image
|
||||
Registry().register('image_manager', self.image_manager)
|
||||
self.preview_widget = ListPreviewWidget(self.main_window, 2)
|
||||
Registry().register('settings', Settings())
|
||||
|
||||
def tearDown(self):
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user