initial phase of vlc and statemanagement

This commit is contained in:
Tim Bentley 2018-10-13 11:24:01 +01:00
parent c2a60fb0e9
commit 92492ab0e8
15 changed files with 4798 additions and 3029 deletions

View File

@ -37,6 +37,7 @@ from PyQt5 import QtCore, QtWidgets
from openlp.core.common import is_macosx, is_win
from openlp.core.common.applocation import AppLocation
from openlp.core.loader import loader
from openlp.core.common.i18n import LanguageManager, UiStrings, translate
from openlp.core.common.path import create_paths, copytree
from openlp.core.common.registry import Registry
@ -113,6 +114,7 @@ class OpenLP(QtWidgets.QApplication):
# Check if OpenLP has been upgrade and if a backup of data should be created
self.backup_on_upgrade(has_run_wizard, can_show_splash)
# start the main app window
loader()
self.main_window = MainWindow()
Registry().execute('bootstrap_initialise')
Registry().execute('bootstrap_post_set_up')

View File

@ -20,7 +20,7 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
The :mod:`~openlp.core.utils.actions` module provides action list classes used
The :mod:`~openlp.core.common.actions` module provides action list classes used
by the shortcuts system.
"""
import logging

38
openlp/core/loader.py Normal file
View File

@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2018 OpenLP Developers #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
The :mod:`~openlp.core.commmon.loader` module provides a bootstrap for the common modules
"""
from openlp.core.state import State
from openlp.core.ui.media import MediaController
def loader():
"""
God class to load all the components which are registered with the Registry
:return: None
"""
State().load_settings()
MediaController()

64
openlp/core/state.py Normal file
View File

@ -0,0 +1,64 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2018 OpenLP Developers #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
The :mod:`core` module provides state management
All the core functions of the OpenLP application including the GUI, settings,
logging and a plugin framework are contained within the openlp.core module.
"""
import logging
from openlp.core.lib.plugin import PluginStatus
log = logging.getLogger()
class State(object):
__instance__ = None
def __new__(cls):
"""
Re-implement the __new__ method to make sure we create a true singleton.
"""
if not cls.__instance__:
cls.__instance__ = object.__new__(cls)
cls.modules = {}
return cls.__instance__
def load_settings(self):
self.modules = {}
def save_settings(self):
pass
def add_service(self, name, order, status, dependance=None):
if name not in self.modules:
self.modules[name] = {'order': order, 'status': status, 'depemdancy': dependance}
def is_service_active(self, name):
return self.modules[name]['status'] == PluginStatus.Active
def check_active_dependency(self, name):
pass

View File

@ -78,7 +78,7 @@ class UiIcons(object):
'book': {'icon': 'fa.book'},
'bottom': {'icon': 'fa.angle-double-down'},
'box': {'icon': 'fa.briefcase'},
'clapperboard': {'icon': 'fa.chess-board'},
'clapperboard': {'icon': 'fa.film'},
'clock': {'icon': 'fa.clock-o'},
'clone': {'icon': 'fa.clone'},
'close': {'icon': 'fa.times-circle-o'},

View File

@ -57,7 +57,6 @@ from openlp.core.ui.pluginform import PluginForm
from openlp.core.ui.slidecontroller import LiveController, PreviewController
from openlp.core.ui.settingsform import SettingsForm
from openlp.core.ui.firsttimeform import FirstTimeForm
from openlp.core.ui.media import MediaController
from openlp.core.ui.printserviceform import PrintServiceForm
from openlp.core.ui.style import PROGRESSBAR_STYLE, get_library_stylesheet
from openlp.core.version import get_version
@ -501,7 +500,6 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow, LogMixin, RegistryPropert
self.copy_data = False
Settings().set_up_default_values()
self.about_form = AboutForm(self)
MediaController()
self.ws_server = websockets.WebSocketServer()
self.http_server = server.HttpServer(self)
SettingsForm(self)

View File

@ -24,10 +24,6 @@ The :mod:`~openlp.core.ui.media` module contains classes and objects for media p
"""
import logging
from PyQt5 import QtCore
from openlp.core.common.settings import Settings
log = logging.getLogger(__name__ + '.__init__')
@ -73,37 +69,37 @@ class MediaInfo(object):
media_type = MediaType()
def get_media_players():
"""
This method extracts the configured media players and overridden player
from the settings.
"""
log.debug('get_media_players')
saved_players = Settings().value('media/players')
reg_ex = QtCore.QRegExp(r'.*\[(.*)\].*')
if Settings().value('media/override player') == QtCore.Qt.Checked:
if reg_ex.exactMatch(saved_players):
overridden_player = '{text}'.format(text=reg_ex.cap(1))
else:
overridden_player = 'auto'
else:
overridden_player = ''
saved_players_list = saved_players.replace('[', '').replace(']', '').split(',') if saved_players else []
return saved_players_list, overridden_player
# def get_media_players():
# """
# This method extracts the configured media players and overridden player
# from the settings.
# """
# log.debug('get_media_players')
# saved_players = Settings().value('media/players')
# reg_ex = QtCore.QRegExp(r'.*\[(.*)\].*')
# if Settings().value('media/override player') == QtCore.Qt.Checked:
# if reg_ex.exactMatch(saved_players):
# overridden_player = '{text}'.format(text=reg_ex.cap(1))
# else:
# overridden_player = 'auto'
# else:
# overridden_player = ''
# saved_players_list = saved_players.replace('[', '').replace(']', '').split(',') if saved_players else []
# return saved_players_list, overridden_player
def set_media_players(players_list, overridden_player='auto'):
"""
This method saves the configured media players and overridden player to the settings
:param players_list: A list with all active media players.
:param overridden_player: Here an special media player is chosen for all media actions.
"""
log.debug('set_media_players')
players = ','.join(players_list)
if Settings().value('media/override player') == QtCore.Qt.Checked and overridden_player != 'auto':
players = players.replace(overridden_player, '[{text}]'.format(text=overridden_player))
Settings().setValue('media/players', players)
# def set_media_players(players_list, overridden_player='auto'):
# """
# This method saves the configured media players and overridden player to the settings
#
# :param players_list: A list with all active media players.
# :param overridden_player: Here an special media player is chosen for all media actions.
# """
# log.debug('set_media_players')
# players = ','.join(players_list)
# if Settings().value('media/override player') == QtCore.Qt.Checked and overridden_player != 'auto':
# players = players.replace(overridden_player, '[{text}]'.format(text=overridden_player))
# Settings().setValue('media/players', players)
def parse_optical_path(input_string):

View File

@ -39,10 +39,10 @@ from openlp.core.lib.serviceitem import ItemCapabilities
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.ui import DisplayControllerType
from openlp.core.ui.icons import UiIcons
from openlp.core.ui.media import MediaState, MediaInfo, MediaType, get_media_players, set_media_players, \
parse_optical_path
from openlp.core.ui.media import MediaState, MediaInfo, MediaType, parse_optical_path
from openlp.core.ui.media.endpoint import media_endpoint
from openlp.core.ui.media.mediaplayer import MediaPlayer
from openlp.core.ui.media.vlcplayer import VlcPlayer
from openlp.core.ui.media.vendor.mediainfoWrapper import MediaInfoWrapper
from openlp.core.widgets.toolbar import OpenLPToolbar
@ -110,7 +110,9 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
Constructor
"""
super(MediaController, self).__init__(parent)
self.media_players = {}
def setup(self):
self.media_players = None
self.display_controllers = {}
self.current_media_players = {}
# Timer for video state
@ -134,70 +136,63 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
Registry().register_function('songs_hide', self.media_hide)
Registry().register_function('songs_blank', self.media_blank)
Registry().register_function('songs_unblank', self.media_unblank)
Registry().register_function('mediaitem_media_rebuild', self._set_active_players)
# Registry().register_function('mediaitem_media_rebuild', self._set_active_players)
Registry().register_function('mediaitem_suffixes', self._generate_extensions_lists)
register_endpoint(media_endpoint)
def _set_active_players(self):
"""
Set the active players and available media files
"""
saved_players = get_media_players()[0]
for player in list(self.media_players.keys()):
self.media_players[player].is_active = player in saved_players
def _generate_extensions_lists(self):
"""
Set the active players and available media files
"""
suffix_list = []
self.audio_extensions_list = []
for player in list(self.media_players.values()):
if player.is_active:
for item in player.audio_extensions_list:
if item not in self.audio_extensions_list:
self.audio_extensions_list.append(item)
suffix_list.append(item[2:])
if self.media_players.is_active:
for item in self.media_players.audio_extensions_list:
if item not in self.audio_extensions_list:
self.audio_extensions_list.append(item)
suffix_list.append(item[2:])
self.video_extensions_list = []
for player in list(self.media_players.values()):
if player.is_active:
for item in player.video_extensions_list:
if item not in self.video_extensions_list:
self.video_extensions_list.append(item)
suffix_list.append(item[2:])
if self.media_players.is_active:
for item in self.media_players.video_extensions_list:
if item not in self.video_extensions_list:
self.video_extensions_list.append(item)
suffix_list.append(item[2:])
self.service_manager.supported_suffixes(suffix_list)
def register_players(self, player):
"""
Register each media Player (Webkit, Phonon, etc) and store
for later use
:param player: Individual player class which has been enabled
"""
self.media_players[player.name] = player
# def register_players(self):
# """
# Register each media Player (Webkit, Phonon, etc) and store
# for later use
#
# :param player: Individual player class which has been enabled
# """
# self.media_players = VlcPlayer(self)
def bootstrap_initialise(self):
"""
Check to see if we have any media Player's available.
"""
controller_dir = os.path.join('core', 'ui', 'media')
# Find all files that do not begin with '.' (lp:#1738047) and end with player.py
glob_pattern = os.path.join(controller_dir, '[!.]*player.py')
extension_loader(glob_pattern, ['mediaplayer.py'])
player_classes = MediaPlayer.__subclasses__()
for player_class in player_classes:
self.register_players(player_class(self))
if not self.media_players:
return False
saved_players, overridden_player = get_media_players()
invalid_media_players = \
[media_player for media_player in saved_players if media_player not in self.media_players or
not self.media_players[media_player].check_available()]
if invalid_media_players:
for invalidPlayer in invalid_media_players:
saved_players.remove(invalidPlayer)
set_media_players(saved_players, overridden_player)
self._set_active_players()
# controller_dir = os.path.join('core', 'ui', 'media')
# # Find all files that do not begin with '.' (lp:#1738047) and end with player.py
# glob_pattern = os.path.join(controller_dir, '[!.]*player.py')
# extension_loader(glob_pattern, ['mediaplayer.py'])
# player_classes = MediaPlayer.__subclasses__()
# for player_class in player_classes:
# self.register_players(player_class(self))
# if not self.media_players:
# return False
# saved_players, overridden_player = get_media_players()
# invalid_media_players = \
# [media_player for media_player in saved_players if media_player not in self.media_players or
# not self.media_players[media_player].check_available()]
# if invalid_media_players:
# for invalidPlayer in invalid_media_players:
# saved_players.remove(invalidPlayer)
# set_media_players(saved_players, overridden_player)
# self._set_active_players()
# self.register_players()
self.setup()
self.media_players = VlcPlayer(self)
self._generate_extensions_lists()
return True
@ -235,35 +230,35 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
if self.display_controllers[DisplayControllerType.Preview].media_info.can_loop_playback:
self.media_play(self.display_controllers[DisplayControllerType.Preview], True)
def get_media_display_css(self):
"""
Add css style sheets to htmlbuilder
"""
css = ''
for player in list(self.media_players.values()):
if player.is_active:
css += player.get_media_display_css()
return css
def get_media_display_javascript(self):
"""
Add javascript functions to htmlbuilder
"""
js = ''
for player in list(self.media_players.values()):
if player.is_active:
js += player.get_media_display_javascript()
return js
def get_media_display_html(self):
"""
Add html code to htmlbuilder
"""
html = ''
for player in list(self.media_players.values()):
if player.is_active:
html += player.get_media_display_html()
return html
# def get_media_display_css(self):
# """
# Add css style sheets to htmlbuilder
# """
# css = ''
# for player in list(self.media_players.values()):
# if player.is_active:
# css += player.get_media_display_css()
# return css
#
# def get_media_display_javascript(self):
# """
# Add javascript functions to htmlbuilder
# """
# js = ''
# for player in list(self.media_players.values()):
# if player.is_active:
# js += player.get_media_display_javascript()
# return js
#
# def get_media_display_html(self):
# """
# Add html code to htmlbuilder
# """
# html = ''
# for player in list(self.media_players.values()):
# if player.is_active:
# html += player.get_media_display_html()
# return html
def register_controller(self, controller):
"""
@ -344,16 +339,12 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
"""
# clean up possible running old media files
self.finalise()
# update player status
self._set_active_players()
display.has_audio = True
if display.is_live and preview:
return
if preview:
display.has_audio = False
for player in list(self.media_players.values()):
if player.is_active:
player.setup(display)
self.media_players.setup(display)
def set_controls_visible(self, controller, value):
"""
@ -366,8 +357,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
controller.mediabar.setVisible(value)
if controller.is_live and controller.display:
if self.current_media_players and value:
if self.current_media_players[controller.controller_type] != self.media_players['webkit']:
controller.display.set_transparency(False)
controller.display.set_transparency(False)
@staticmethod
def resize(display, player):
@ -507,47 +497,34 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
# When called from mediaitem display is None
if display is None:
display = controller.preview_display
# Find vlc player
used_players = get_media_players()[0]
vlc_player = None
for title in used_players:
player = self.media_players[title]
if player.name == 'vlc':
vlc_player = player
if vlc_player is None:
critical_error_message_box(translate('MediaPlugin.MediaItem', 'VLC player required'),
translate('MediaPlugin.MediaItem',
'VLC player required for playback of optical devices'))
return False
vlc_player.load(display)
self.resize(display, vlc_player)
self.current_media_players[controller.controller_type] = vlc_player
self.media_players.load(display)
self.resize(display, self.media_players)
self.current_media_players[controller.controller_type] = self.media_players
if audio_track == -1 and subtitle_track == -1:
controller.media_info.media_type = MediaType.CD
else:
controller.media_info.media_type = MediaType.DVD
return True
@staticmethod
def _get_used_players(service_item):
def _get_used_players(self, service_item):
"""
Find the player for a given service item
:param service_item: where the information is about the media and required player
:return: player description
"""
used_players = get_media_players()[0]
return self.media_players
# If no player, we can't play
if not used_players:
return False
default_player = [used_players[0]]
if service_item.processor and service_item.processor != UiStrings().Automatic:
# check to see if the player is usable else use the default one.
if service_item.processor.lower() not in used_players:
used_players = default_player
else:
used_players = [service_item.processor.lower()]
return used_players
# if not used_players:
# return False
# default_player = [used_players]
# if service_item.processor and service_item.processor != UiStrings().Automatic:
# # check to see if the player is usable else use the default one.
# if service_item.processor.lower() not in used_players:
# used_players = default_player
# else:
# used_players = [service_item.processor.lower()]
# return used_players
def _check_file_type(self, controller, display, service_item):
"""
@ -557,35 +534,30 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
:param display: Which display to use
:param service_item: The ServiceItem containing the details to be played.
"""
used_players = self._get_used_players(service_item)
if controller.media_info.file_info.isFile():
suffix = '*.%s' % controller.media_info.file_info.suffix().lower()
for title in used_players:
if not title:
continue
player = self.media_players[title]
if suffix in player.video_extensions_list:
if not controller.media_info.is_background or controller.media_info.is_background and \
player.can_background:
self.resize(display, player)
if player.load(display):
self.current_media_players[controller.controller_type] = player
controller.media_info.media_type = MediaType.Video
return True
if suffix in player.audio_extensions_list:
if player.load(display):
self.current_media_players[controller.controller_type] = player
controller.media_info.media_type = MediaType.Audio
return True
else:
for title in used_players:
player = self.media_players[title]
if player.can_folder:
player = self.media_players
if suffix in player.video_extensions_list:
if not controller.media_info.is_background or controller.media_info.is_background and \
player.can_background:
self.resize(display, player)
if player.load(display):
self.current_media_players[controller.controller_type] = player
controller.media_info.media_type = MediaType.Video
return True
if suffix in player.audio_extensions_list:
if player.load(display):
self.current_media_players[controller.controller_type] = player
controller.media_info.media_type = MediaType.Audio
return True
else:
player = self.media_players
if player.can_folder:
self.resize(display, player)
if player.load(display):
self.current_media_players[controller.controller_type] = player
controller.media_info.media_type = MediaType.Video
return True
# no valid player found
return False

View File

@ -32,7 +32,6 @@ from openlp.core.common.settings import Settings
from openlp.core.lib.settingstab import SettingsTab
from openlp.core.lib.ui import create_button
from openlp.core.ui.icons import UiIcons
from openlp.core.ui.media import get_media_players, set_media_players
from openlp.core.widgets.buttons import ColorButton

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,6 @@ from openlp.core.projectors.tab import ProjectorTab
from openlp.core.ui.advancedtab import AdvancedTab
from openlp.core.ui.generaltab import GeneralTab
from openlp.core.ui.themestab import ThemesTab
from openlp.core.ui.media import PlayerTab
from openlp.core.ui.settingsdialog import Ui_SettingsDialog
log = logging.getLogger(__name__)
@ -59,7 +58,6 @@ class SettingsForm(QtWidgets.QDialog, Ui_SettingsDialog, RegistryProperties):
self.themes_tab = None
self.projector_tab = None
self.advanced_tab = None
self.player_tab = None
self.api_tab = None
def exec(self):
@ -75,7 +73,6 @@ class SettingsForm(QtWidgets.QDialog, Ui_SettingsDialog, RegistryProperties):
self.insert_tab(self.general_tab)
self.insert_tab(self.themes_tab)
self.insert_tab(self.advanced_tab)
self.insert_tab(self.player_tab)
self.insert_tab(self.projector_tab)
self.insert_tab(self.api_tab)
for plugin in self.plugin_manager.plugins:
@ -159,14 +156,11 @@ class SettingsForm(QtWidgets.QDialog, Ui_SettingsDialog, RegistryProperties):
self.projector_tab = ProjectorTab(self)
# Advanced tab
self.advanced_tab = AdvancedTab(self)
# Advanced tab
self.player_tab = PlayerTab(self)
# Api tab
self.api_tab = ApiTab(self)
self.general_tab.post_set_up()
self.themes_tab.post_set_up()
self.advanced_tab.post_set_up()
self.player_tab.post_set_up()
self.api_tab.post_set_up()
for plugin in self.plugin_manager.plugins:
if plugin.settings_tab:

View File

@ -194,7 +194,7 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties):
image = self.image_manager.get_image(frame['image'], ImageSource.CommandPlugins)
pixmap = QtGui.QPixmap.fromImage(image)
else:
pixmap = QtGui.QPixmap(frame['image'])
pixmap = frame['image'].pixmap(80, 80)
else:
image = self.image_manager.get_image(frame['path'], ImageSource.ImagePlugin)
pixmap = QtGui.QPixmap.fromImage(image)

View File

@ -37,7 +37,7 @@ from openlp.core.lib.serviceitem import ItemCapabilities, ServiceItem
from openlp.core.lib.ui import create_widget_action, critical_error_message_box, create_horizontal_adjusting_combo_box
from openlp.core.ui import DisplayControllerType
from openlp.core.ui.icons import UiIcons
from openlp.core.ui.media import get_media_players, set_media_players, parse_optical_path, format_milliseconds
from openlp.core.ui.media import parse_optical_path, format_milliseconds
from openlp.core.ui.media.vlcplayer import get_vlc
if get_vlc() is not None:
@ -81,7 +81,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
self.has_search = True
self.media_object = None
# self.display_controller = DisplayController(self.parent())
Registry().register_function('video_background_replaced', self.video_background_replaced)
# Registry().register_function('video_background_replaced', self.video_background_replaced)
Registry().register_function('mediaitem_media_rebuild', self.rebuild_players)
# Allow DnD from the desktop
self.list_view.activateDnD()
@ -92,20 +92,16 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
to another language.
"""
self.on_new_prompt = translate('MediaPlugin.MediaItem', 'Select Media')
self.replace_action.setText(UiStrings().ReplaceBG)
self.replace_action_context.setText(UiStrings().ReplaceBG)
if 'webkit' in get_media_players()[0]:
self.replace_action.setToolTip(UiStrings().ReplaceLiveBG)
self.replace_action_context.setToolTip(UiStrings().ReplaceLiveBG)
else:
self.replace_action.setToolTip(UiStrings().ReplaceLiveBGDisabled)
self.replace_action_context.setToolTip(UiStrings().ReplaceLiveBGDisabled)
self.reset_action.setText(UiStrings().ResetBG)
self.reset_action.setToolTip(UiStrings().ResetLiveBG)
self.reset_action_context.setText(UiStrings().ResetBG)
self.reset_action_context.setToolTip(UiStrings().ResetLiveBG)
self.automatic = UiStrings().Automatic
self.display_type_label.setText(translate('MediaPlugin.MediaItem', 'Use Player:'))
# self.replace_action.setText(UiStrings().ReplaceBG)
# self.replace_action_context.setText(UiStrings().ReplaceBG)
# self.replace_action.setToolTip(UiStrings().ReplaceLiveBGDisabled)
# self.replace_action_context.setToolTip(UiStrings().ReplaceLiveBGDisabled)
# self.reset_action.setText(UiStrings().ResetBG)
# self.reset_action.setToolTip(UiStrings().ResetLiveBG)
# self.reset_action_context.setText(UiStrings().ResetBG)
# self.reset_action_context.setToolTip(UiStrings().ResetLiveBG)
# self.automatic = UiStrings().Automatic
# self.display_type_label.setText(translate('MediaPlugin.MediaItem', 'Use Player:'))
def required_icons(self):
"""
@ -121,21 +117,15 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
Creates the main widget for listing items.
"""
MediaManagerItem.add_list_view_to_toolbar(self)
self.list_view.addAction(self.replace_action)
# self.list_view.addAction(self.replace_action)
def add_start_header_bar(self):
"""
Adds buttons to the start of the header bar.
"""
if 'vlc' in get_media_players()[0]:
disable_optical_button_text = False
optical_button_text = translate('MediaPlugin.MediaItem', 'Load CD/DVD')
optical_button_tooltip = translate('MediaPlugin.MediaItem', 'Load CD/DVD')
else:
disable_optical_button_text = True
optical_button_text = translate('MediaPlugin.MediaItem', 'Load CD/DVD')
optical_button_tooltip = translate('MediaPlugin.MediaItem',
'CD/DVD playback is only supported if VLC is installed and enabled.')
disable_optical_button_text = False
optical_button_text = translate('MediaPlugin.MediaItem', 'Load CD/DVD')
optical_button_tooltip = translate('MediaPlugin.MediaItem', 'Load CD/DVD')
self.load_optical = self.toolbar.add_toolbar_action('load_optical', icon=UiIcons().optical,
text=optical_button_text,
tooltip=optical_button_tooltip,
@ -148,94 +138,30 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
Adds buttons to the end of the header bar.
"""
# Replace backgrounds do not work at present so remove functionality.
self.replace_action = self.toolbar.add_toolbar_action('replace_action', icon=UiIcons().theme,
triggers=self.on_replace_click)
if 'webkit' not in get_media_players()[0]:
self.replace_action.setDisabled(True)
if hasattr(self, 'replace_action_context'):
self.replace_action_context.setDisabled(True)
self.reset_action = self.toolbar.add_toolbar_action('reset_action', icon=UiIcons().close,
visible=False, triggers=self.on_reset_click)
self.media_widget = QtWidgets.QWidget(self)
self.media_widget.setObjectName('media_widget')
self.display_layout = QtWidgets.QFormLayout(self.media_widget)
self.display_layout.setContentsMargins(self.display_layout.spacing(), self.display_layout.spacing(),
self.display_layout.spacing(), self.display_layout.spacing())
self.display_layout.setObjectName('display_layout')
self.display_type_label = QtWidgets.QLabel(self.media_widget)
self.display_type_label.setObjectName('display_type_label')
self.display_type_combo_box = create_horizontal_adjusting_combo_box(
self.media_widget, 'display_type_combo_box')
self.display_type_label.setBuddy(self.display_type_combo_box)
self.display_layout.addRow(self.display_type_label, self.display_type_combo_box)
# self.replace_action = self.toolbar.add_toolbar_action('replace_action', icon=UiIcons().theme,
# triggers=self.on_replace_click)
# if 'webkit' not in get_media_players()[0]:
# self.replace_action.setDisabled(True)
# if hasattr(self, 'replace_action_context'):
# self.replace_action_context.setDisabled(True)
# self.reset_action = self.toolbar.add_toolbar_action('reset_action', icon=UiIcons().close,
# visible=False, triggers=self.on_reset_click)
# self.media_widget = QtWidgets.QWidget(self)
# self.media_widget.setObjectName('media_widget')
# self.display_layout = QtWidgets.QFormLayout(self.media_widget)
# self.display_layout.setContentsMargins(self.display_layout.spacing(), self.display_layout.spacing(),
# self.display_layout.spacing(), self.display_layout.spacing())
# self.display_layout.setObjectName('display_layout')
# self.display_type_label = QtWidgets.QLabel(self.media_widget)
# self.display_type_label.setObjectName('display_type_label')
# self.display_type_combo_box = create_horizontal_adjusting_combo_box(
# self.media_widget, 'display_type_combo_box')
# self.display_type_label.setBuddy(self.display_type_combo_box)
# self.display_layout.addRow(self.display_type_label, self.display_type_combo_box)
# Add the Media widget to the page layout.
self.page_layout.addWidget(self.media_widget)
self.display_type_combo_box.currentIndexChanged.connect(self.override_player_changed)
def add_custom_context_actions(self):
create_widget_action(self.list_view, separator=True)
self.replace_action_context = create_widget_action(
self.list_view, text=UiStrings().ReplaceBG, icon=':/slides/slide_theme.png',
triggers=self.on_replace_click)
self.reset_action_context = create_widget_action(
self.list_view, text=UiStrings().ReplaceLiveBG, icon=UiIcons().close,
visible=False, triggers=self.on_reset_click)
@staticmethod
def override_player_changed(index):
"""
The Player has been overridden
:param index: Index
"""
player = get_media_players()[0]
if index == 0:
set_media_players(player)
else:
set_media_players(player, player[index - 1])
def on_reset_click(self):
"""
Called to reset the Live background with the media selected,
"""
self.media_controller.media_reset(self.live_controller)
self.reset_action.setVisible(False)
self.reset_action_context.setVisible(False)
def video_background_replaced(self):
"""
Triggered by main display on change of service item.
"""
self.reset_action.setVisible(False)
self.reset_action_context.setVisible(False)
def on_replace_click(self):
"""
Called to replace Live background with the media selected.
"""
if check_item_selected(self.list_view,
translate('MediaPlugin.MediaItem',
'You must select a media file to replace the background with.')):
item = self.list_view.currentItem()
filename = item.data(QtCore.Qt.UserRole)
if os.path.exists(filename):
service_item = ServiceItem()
service_item.title = 'webkit'
service_item.processor = 'webkit'
(path, name) = os.path.split(filename)
service_item.add_from_command(path, name, CLAPPERBOARD)
if self.media_controller.video(DisplayControllerType.Live, service_item, video_behind_text=True):
self.reset_action.setVisible(True)
self.reset_action_context.setVisible(True)
else:
critical_error_message_box(UiStrings().LiveBGError,
translate('MediaPlugin.MediaItem',
'There was no display item to amend.'))
else:
critical_error_message_box(UiStrings().LiveBGError,
translate('MediaPlugin.MediaItem',
'There was a problem replacing your background, '
'the media file "{name}" no longer exists.').format(name=filename))
# self.page_layout.addWidget(self.media_widget)
# self.display_type_combo_box.currentIndexChanged.connect(self.override_player_changed)
pass
def generate_slide_data(self, service_item, item=None, xml_version=False, remote=False,
context=ServiceItemContext.Service):
@ -282,7 +208,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
return False
(path, name) = os.path.split(filename)
service_item.title = name
service_item.processor = self.display_type_combo_box.currentText()
service_item.processor = 'vlc'
service_item.add_from_command(path, name, CLAPPERBOARD)
# Only get start and end times if going to a service
if not self.media_controller.media_length(service_item):
@ -310,37 +236,13 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
"""
Rebuild the tab in the media manager when changes are made in the settings.
"""
self.populate_display_types()
# self.populate_display_types()
self.on_new_file_masks = translate('MediaPlugin.MediaItem',
'Videos ({video});;Audio ({audio});;{files} '
'(*)').format(video=' '.join(self.media_controller.video_extensions_list),
audio=' '.join(self.media_controller.audio_extensions_list),
files=UiStrings().AllFiles)
def populate_display_types(self):
"""
Load the combobox with the enabled media players, allowing user to select a specific player if settings allow.
"""
# block signals to avoid unnecessary override_player_changed Signals while combo box creation
self.display_type_combo_box.blockSignals(True)
self.display_type_combo_box.clear()
used_players, override_player = get_media_players()
media_players = self.media_controller.media_players
current_index = 0
for player in used_players:
# load the drop down selection
self.display_type_combo_box.addItem(media_players[player].original_name)
if override_player == player:
current_index = len(self.display_type_combo_box)
if self.display_type_combo_box.count() > 1:
self.display_type_combo_box.insertItem(0, self.automatic)
self.display_type_combo_box.setCurrentIndex(current_index)
if override_player:
self.media_widget.show()
else:
self.media_widget.hide()
self.display_type_combo_box.blockSignals(False)
def on_delete_click(self):
"""
Remove a media item from the list.

View File

@ -142,23 +142,23 @@ class MediaPlugin(Plugin):
self.media_controller.finalise()
Plugin.finalise(self)
def get_display_css(self):
"""
Add css style sheets to htmlbuilder.
"""
return self.media_controller.get_media_display_css()
def get_display_javascript(self):
"""
Add javascript functions to htmlbuilder.
"""
return self.media_controller.get_media_display_javascript()
def get_display_html(self):
"""
Add html code to htmlbuilder.
"""
return self.media_controller.get_media_display_html()
# def get_display_css(self):
# """
# Add css style sheets to htmlbuilder.
# """
# return self.media_controller.get_media_display_css()
#
# def get_display_javascript(self):
# """
# Add javascript functions to htmlbuilder.
# """
# return self.media_controller.get_media_display_javascript()
#
# def get_display_html(self):
# """
# Add html code to htmlbuilder.
# """
# return self.media_controller.get_media_display_html()
def process_check_binary(program_path):

View File

@ -0,0 +1,97 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2018 OpenLP Developers #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from unittest import TestCase
from unittest.mock import MagicMock, patch
from openlp.core.state import State
from openlp.core.common.registry import Registry
from openlp.core.lib.plugin import PluginStatus
from tests.helpers.testmixin import TestMixin
"""
Test the Status class.
"""
class TestState(TestCase, TestMixin):
"""
Test the Server Class used to check if OpenLP is running.
"""
def setUp(self):
Registry.create()
self.state = State()
def tearDown(self):
pass
def test_add_service(self):
# GIVEN a new state
State().load_settings()
# WHEN I add a new service
State().add_service("test", 1, PluginStatus.Active)
# THEN I have a saved service
assert len(State().modules) == 1
def test_add_service_multiple(self):
# GIVEN a new state
State().load_settings()
# WHEN I add a new service twice
State().add_service("test", 1, PluginStatus.Active)
State().add_service("test", 1, PluginStatus.Active)
# THEN I have a single saved service
assert len(State().modules) == 1
def test_add_service_multiple_depend(self):
# GIVEN a new state
State().load_settings()
# WHEN I add a new service twice
State().add_service("test", 1, PluginStatus.Active)
State().add_service("test1", 1, PluginStatus.Active, "test")
# THEN I have a single saved service
assert len(State().modules) == 2
def test_active_service(self):
# GIVEN a new state
State().load_settings()
# WHEN I add a new service which is Active
State().add_service("test", 1, PluginStatus.Active)
# THEN I have a single saved service
assert State().is_service_active('test') is True
def test_inactive_service(self):
# GIVEN a new state
State().load_settings()
# WHEN I add a new service which is Inactive
State().add_service("test", 1, PluginStatus.Inactive)
# THEN I have a single saved service
assert State().is_service_active('test') is False