forked from openlp/openlp
initial phase of vlc and statemanagement
This commit is contained in:
parent
c2a60fb0e9
commit
92492ab0e8
@ -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')
|
||||
|
@ -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
38
openlp/core/loader.py
Normal 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
64
openlp/core/state.py
Normal 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
|
@ -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'},
|
||||
|
@ -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)
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
7091
openlp/core/ui/media/vendor/vlc.py
vendored
7091
openlp/core/ui/media/vendor/vlc.py
vendored
File diff suppressed because it is too large
Load Diff
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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):
|
||||
|
97
tests/functional/openlp_core/test_state.py
Normal file
97
tests/functional/openlp_core/test_state.py
Normal 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
|
Loading…
Reference in New Issue
Block a user