forked from openlp/openlp
Fix tests
This commit is contained in:
parent
e49beeb2c4
commit
51178b2ede
@ -172,5 +172,5 @@ class Registry(object):
|
||||
log.exception('Exception for function %s', function)
|
||||
else:
|
||||
trace_error_handler(log)
|
||||
log.error("Event %s not called by not registered" % event)
|
||||
log.error("Event %s called but not registered" % event)
|
||||
return results
|
||||
|
@ -99,11 +99,10 @@ from .formattingtagcontroller import FormattingTagController
|
||||
from .shortcutlistform import ShortcutListForm
|
||||
from .mediadockmanager import MediaDockManager
|
||||
from .servicemanager import ServiceManager
|
||||
from .thememanagerhelper import ThemeManagerHelper
|
||||
from .thememanager import ThemeManager
|
||||
|
||||
__all__ = ['SplashScreen', 'AboutForm', 'SettingsForm', 'MainDisplay', 'SlideController', 'ServiceManager',
|
||||
'ThemeManager', 'MediaDockManager', 'ServiceItemEditForm', 'FirstTimeForm', 'FirstTimeLanguageForm', 'ThemeForm',
|
||||
'ThemeLayoutForm', 'FileRenameForm', 'StartTimeForm', 'MainDisplay', 'Display', 'ServiceNoteForm',
|
||||
'SlideController', 'DisplayController', 'GeneralTab', 'ThemesTab', 'AdvancedTab', 'PluginForm',
|
||||
'FormattingTagForm', 'ShortcutListForm', 'FormattingTagController', 'ThemeManagerHelper']
|
||||
'FormattingTagForm', 'ShortcutListForm', 'FormattingTagController']
|
||||
|
@ -35,7 +35,7 @@ import os
|
||||
import datetime
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.common import Registry, Settings, UiStrings, translate
|
||||
from openlp.core.common import Registry, RegistryMixin, Settings, UiStrings, translate
|
||||
from openlp.core.lib import OpenLPToolbar
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.ui.media import MediaState, MediaInfo, MediaType, get_media_players, set_media_players
|
||||
@ -99,7 +99,7 @@ class MediaController(object):
|
||||
Constructor
|
||||
"""
|
||||
Registry().register('media_controller', self)
|
||||
Registry().register_function('bootstrap_initialise', self.check_available_media_players)
|
||||
Registry().register_function('bootstrap_initialise', self.bootstrap_initialise)
|
||||
self.media_players = {}
|
||||
self.display_controllers = {}
|
||||
self.current_media_players = {}
|
||||
@ -134,20 +134,22 @@ class MediaController(object):
|
||||
"""
|
||||
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 not item in self.audio_extensions_list:
|
||||
self.audio_extensions_list.append(item)
|
||||
self.service_manager.supported_suffixes(item[2:])
|
||||
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.extend(item)
|
||||
self.service_manager.supported_suffixes(item[2:])
|
||||
suffix_list.append(item[2:])
|
||||
self.service_manager.supported_suffixes(suffix_list)
|
||||
|
||||
def register_players(self, player):
|
||||
"""
|
||||
@ -159,7 +161,7 @@ class MediaController(object):
|
||||
"""
|
||||
self.media_players[player.name] = player
|
||||
|
||||
def check_available_media_players(self):
|
||||
def bootstrap_initialise(self):
|
||||
"""
|
||||
Check to see if we have any media Player's available.
|
||||
"""
|
||||
@ -169,27 +171,28 @@ class MediaController(object):
|
||||
if filename.endswith('player.py') and not filename == 'mediaplayer.py':
|
||||
path = os.path.join(controller_dir, filename)
|
||||
if os.path.isfile(path):
|
||||
modulename = 'openlp.core.ui.media.' + os.path.splitext(filename)[0]
|
||||
log.debug('Importing controller %s', modulename)
|
||||
module_name = 'openlp.core.ui.media.' + os.path.splitext(filename)[0]
|
||||
log.debug('Importing controller %s', module_name)
|
||||
try:
|
||||
__import__(modulename, globals(), locals(), [])
|
||||
__import__(module_name, globals(), locals(), [])
|
||||
# On some platforms importing vlc.py might cause
|
||||
# also OSError exceptions. (e.g. Mac OS X)
|
||||
except (ImportError, OSError):
|
||||
log.warn('Failed to import %s on path %s', modulename, path)
|
||||
log.warn('Failed to import %s on path %s', module_name, path)
|
||||
player_classes = MediaPlayer.__subclasses__()
|
||||
for player_class in player_classes:
|
||||
player = player_class(self)
|
||||
self.register_players(player)
|
||||
if not self.media_players:
|
||||
return False
|
||||
savedPlayers, overriddenPlayer = get_media_players()
|
||||
invalid_media_players = [mediaPlayer for mediaPlayer in savedPlayers
|
||||
if not mediaPlayer in self.media_players or not self.media_players[mediaPlayer].check_available()]
|
||||
saved_players, overridden_player = get_media_players()
|
||||
invalid_media_players = \
|
||||
[mediaPlayer for mediaPlayer in saved_players if not mediaPlayer in self.media_players or
|
||||
not self.media_players[mediaPlayer].check_available()]
|
||||
if invalid_media_players:
|
||||
for invalidPlayer in invalid_media_players:
|
||||
savedPlayers.remove(invalidPlayer)
|
||||
set_media_players(savedPlayers, overriddenPlayer)
|
||||
saved_players.remove(invalidPlayer)
|
||||
set_media_players(saved_players, overridden_player)
|
||||
self._set_active_players()
|
||||
self._generate_extensions_lists()
|
||||
return True
|
||||
@ -270,14 +273,17 @@ class MediaController(object):
|
||||
# Build a Media ToolBar
|
||||
controller.mediabar = OpenLPToolbar(controller)
|
||||
controller.mediabar.add_toolbar_action('playbackPlay', text='media_playback_play',
|
||||
icon=':/slides/media_playback_start.png',
|
||||
tooltip=translate('OpenLP.SlideController', 'Start playing media.'), triggers=controller.send_to_plugins)
|
||||
icon=':/slides/media_playback_start.png',
|
||||
tooltip=translate('OpenLP.SlideController', 'Start playing media.'),
|
||||
triggers=controller.send_to_plugins)
|
||||
controller.mediabar.add_toolbar_action('playbackPause', text='media_playback_pause',
|
||||
icon=':/slides/media_playback_pause.png',
|
||||
tooltip=translate('OpenLP.SlideController', 'Pause playing media.'), triggers=controller.send_to_plugins)
|
||||
icon=':/slides/media_playback_pause.png',
|
||||
tooltip=translate('OpenLP.SlideController', 'Pause playing media.'),
|
||||
triggers=controller.send_to_plugins)
|
||||
controller.mediabar.add_toolbar_action('playbackStop', text='media_playback_stop',
|
||||
icon=':/slides/media_playback_stop.png',
|
||||
tooltip=translate('OpenLP.SlideController', 'Stop playing media.'), triggers=controller.send_to_plugins)
|
||||
icon=':/slides/media_playback_stop.png',
|
||||
tooltip=translate('OpenLP.SlideController', 'Stop playing media.'),
|
||||
triggers=controller.send_to_plugins)
|
||||
# Build the seek_slider.
|
||||
controller.seek_slider = MediaSlider(QtCore.Qt.Horizontal, self, controller)
|
||||
controller.seek_slider.setMaximum(1000)
|
||||
@ -445,11 +451,11 @@ class MediaController(object):
|
||||
if not self._check_file_type(controller, display, service_item):
|
||||
# Media could not be loaded correctly
|
||||
critical_error_message_box(translate('MediaPlugin.MediaItem', 'Unsupported File'),
|
||||
translate('MediaPlugin.MediaItem', 'Unsupported File'))
|
||||
translate('MediaPlugin.MediaItem', 'Unsupported File'))
|
||||
return False
|
||||
if not self.media_play(controller):
|
||||
critical_error_message_box(translate('MediaPlugin.MediaItem', 'Unsupported File'),
|
||||
translate('MediaPlugin.MediaItem', 'Unsupported File'))
|
||||
translate('MediaPlugin.MediaItem', 'Unsupported File'))
|
||||
return False
|
||||
service_item.set_media_length(controller.media_info.length)
|
||||
self.media_stop(controller)
|
||||
|
@ -37,8 +37,7 @@ from openlp.core.ui.media import MediaState
|
||||
|
||||
class MediaPlayer(object):
|
||||
"""
|
||||
This is the base class media Player class to provide OpenLP with a
|
||||
pluggable media display framework.
|
||||
This is the base class media Player class to provide OpenLP with a pluggable media display framework.
|
||||
"""
|
||||
|
||||
def __init__(self, parent, name='media_player'):
|
||||
|
@ -80,12 +80,12 @@ class PhononPlayer(MediaPlayer):
|
||||
self.parent = parent
|
||||
self.additional_extensions = ADDITIONAL_EXT
|
||||
mimetypes.init()
|
||||
for mimetype in Phonon.BackendCapabilities.availableMimeTypes():
|
||||
mimetype = str(mimetype)
|
||||
if mimetype.startswith('audio/'):
|
||||
self._addToList(self.audio_extensions_list, mimetype)
|
||||
elif mimetype.startswith('video/'):
|
||||
self._addToList(self.video_extensions_list, mimetype)
|
||||
for mime_type in Phonon.BackendCapabilities.availableMimeTypes():
|
||||
mime_type = str(mime_type)
|
||||
if mime_type.startswith('audio/'):
|
||||
self._addToList(self.audio_extensions_list, mime_type)
|
||||
elif mime_type.startswith('video/'):
|
||||
self._addToList(self.video_extensions_list, mime_type)
|
||||
|
||||
def _addToList(self, mimetype_list, mimetype):
|
||||
"""
|
||||
@ -144,14 +144,14 @@ class PhononPlayer(MediaPlayer):
|
||||
self.volume(display, volume)
|
||||
return True
|
||||
|
||||
def media_state_wait(self, display, mediaState):
|
||||
def media_state_wait(self, display, media_state):
|
||||
"""
|
||||
Wait for the video to change its state
|
||||
Wait no longer than 5 seconds.
|
||||
"""
|
||||
start = datetime.now()
|
||||
current_state = display.media_object.state()
|
||||
while current_state != mediaState:
|
||||
while current_state != media_state:
|
||||
current_state = display.media_object.state()
|
||||
if current_state == Phonon.ErrorState:
|
||||
return False
|
||||
@ -172,8 +172,7 @@ class PhononPlayer(MediaPlayer):
|
||||
"""
|
||||
controller = display.controller
|
||||
start_time = 0
|
||||
if display.media_object.state() != Phonon.PausedState and \
|
||||
controller.media_info.start_time > 0:
|
||||
if display.media_object.state() != Phonon.PausedState and controller.media_info.start_time > 0:
|
||||
start_time = controller.media_info.start_time
|
||||
display.media_object.play()
|
||||
if not self.media_state_wait(display, Phonon.PlayingState):
|
||||
@ -262,8 +261,8 @@ class PhononPlayer(MediaPlayer):
|
||||
Return some info about this player
|
||||
"""
|
||||
return(translate('Media.player', 'Phonon is a media player which '
|
||||
'interacts with the operating system to provide media capabilities.') +
|
||||
'<br/> <strong>' + translate('Media.player', 'Audio') +
|
||||
'</strong><br/>' + str(self.audio_extensions_list) +
|
||||
'<br/><strong>' + translate('Media.player', 'Video') +
|
||||
'</strong><br/>' + str(self.video_extensions_list) + '<br/>')
|
||||
'interacts with the operating system to provide media capabilities.') +
|
||||
'<br/> <strong>' + translate('Media.player', 'Audio') +
|
||||
'</strong><br/>' + str(self.audio_extensions_list) +
|
||||
'<br/><strong>' + translate('Media.player', 'Video') +
|
||||
'</strong><br/>' + str(self.video_extensions_list) + '<br/>')
|
||||
|
@ -39,13 +39,13 @@ from openlp.core.ui.media import get_media_players, set_media_players
|
||||
|
||||
class MediaQCheckBox(QtGui.QCheckBox):
|
||||
"""
|
||||
MediaQCheckBox adds an extra property, playerName to the QCheckBox class.
|
||||
MediaQCheckBox adds an extra property, player_name to the QCheckBox class.
|
||||
"""
|
||||
def set_player_name(self, name):
|
||||
"""
|
||||
Set the player name
|
||||
"""
|
||||
self.playerName = name
|
||||
self.player_name = name
|
||||
|
||||
|
||||
class PlayerTab(SettingsTab):
|
||||
@ -113,9 +113,9 @@ class PlayerTab(SettingsTab):
|
||||
self.ordering_button_layout.setObjectName('ordering_button_layout')
|
||||
self.ordering_button_layout.addStretch(1)
|
||||
self.ordering_up_button = create_button(self, 'ordering_up_button', role='up',
|
||||
click=self.on_up_button_clicked)
|
||||
click=self.on_up_button_clicked)
|
||||
self.ordering_down_button = create_button(self, 'ordering_down_button', role='down',
|
||||
click=self.on_down_button_clicked)
|
||||
click=self.on_down_button_clicked)
|
||||
self.ordering_button_layout.addWidget(self.ordering_up_button)
|
||||
self.ordering_button_layout.addWidget(self.ordering_down_button)
|
||||
self.ordering_button_layout.addStretch(1)
|
||||
@ -135,8 +135,8 @@ class PlayerTab(SettingsTab):
|
||||
self.background_color_group_box.setTitle(UiStrings().BackgroundColor)
|
||||
self.background_color_label.setText(UiStrings().DefaultColor)
|
||||
self.information_label.setText(translate('OpenLP.PlayerTab',
|
||||
'Visible background for videos with aspect ratio different to screen.'))
|
||||
self.retranslatePlayers()
|
||||
'Visible background for videos with aspect ratio different to screen.'))
|
||||
self.retranslate_players()
|
||||
|
||||
def on_background_color_button_clicked(self):
|
||||
"""
|
||||
@ -151,7 +151,7 @@ class PlayerTab(SettingsTab):
|
||||
"""
|
||||
Add or remove players depending on their status
|
||||
"""
|
||||
player = self.sender().playerName
|
||||
player = self.sender().player_name
|
||||
if check_state == QtCore.Qt.Checked:
|
||||
if player not in self.used_players:
|
||||
self.used_players.append(player)
|
||||
@ -249,9 +249,9 @@ class PlayerTab(SettingsTab):
|
||||
else:
|
||||
checkbox.setChecked(False)
|
||||
self.update_player_list()
|
||||
self.retranslatePlayers()
|
||||
self.retranslate_players()
|
||||
|
||||
def retranslatePlayers(self):
|
||||
def retranslate_players(self):
|
||||
"""
|
||||
Translations for players is dependent on their setup as well
|
||||
"""
|
||||
|
@ -118,35 +118,35 @@ class VlcPlayer(MediaPlayer):
|
||||
"""
|
||||
Set up the media player
|
||||
"""
|
||||
display.vlcWidget = QtGui.QFrame(display)
|
||||
display.vlcWidget.setFrameStyle(QtGui.QFrame.NoFrame)
|
||||
display.vlc_widget = QtGui.QFrame(display)
|
||||
display.vlc_widget.setFrameStyle(QtGui.QFrame.NoFrame)
|
||||
# creating a basic vlc instance
|
||||
command_line_options = '--no-video-title-show'
|
||||
if not display.has_audio:
|
||||
command_line_options += ' --no-audio --no-video-title-show'
|
||||
if Settings().value('advanced/hide mouse') and display.controller.is_live:
|
||||
command_line_options += ' --mouse-hide-timeout=0'
|
||||
display.vlcInstance = vlc.Instance(command_line_options)
|
||||
display.vlc_instance = vlc.Instance(command_line_options)
|
||||
# creating an empty vlc media player
|
||||
display.vlcMediaPlayer = display.vlcInstance.media_player_new()
|
||||
display.vlcWidget.resize(display.size())
|
||||
display.vlcWidget.raise_()
|
||||
display.vlcWidget.hide()
|
||||
display.vlc_media_player = display.vlc_instance.media_player_new()
|
||||
display.vlc_widget.resize(display.size())
|
||||
display.vlc_widget.raise_()
|
||||
display.vlc_widget.hide()
|
||||
# The media player has to be 'connected' to the QFrame.
|
||||
# (otherwise a video would be displayed in it's own window)
|
||||
# This is platform specific!
|
||||
# You have to give the id of the QFrame (or similar object)
|
||||
# to vlc, different platforms have different functions for this.
|
||||
win_id = int(display.vlcWidget.winId())
|
||||
win_id = int(display.vlc_widget.winId())
|
||||
if sys.platform == "win32":
|
||||
display.vlcMediaPlayer.set_hwnd(win_id)
|
||||
display.vlc_media_player.set_hwnd(win_id)
|
||||
elif sys.platform == "darwin":
|
||||
# We have to use 'set_nsobject' since Qt4 on OSX uses Cocoa
|
||||
# framework and not the old Carbon.
|
||||
display.vlcMediaPlayer.set_nsobject(win_id)
|
||||
display.vlc_media_player.set_nsobject(win_id)
|
||||
else:
|
||||
# for Linux using the X Server
|
||||
display.vlcMediaPlayer.set_xwindow(win_id)
|
||||
display.vlc_media_player.set_xwindow(win_id)
|
||||
self.has_own_widget = True
|
||||
|
||||
def check_available(self):
|
||||
@ -165,18 +165,18 @@ class VlcPlayer(MediaPlayer):
|
||||
file_path = str(controller.media_info.file_info.absoluteFilePath())
|
||||
path = os.path.normcase(file_path)
|
||||
# create the media
|
||||
display.vlcMedia = display.vlcInstance.media_new_path(path)
|
||||
display.vlc_media = display.vlc_instance.media_new_path(path)
|
||||
# put the media in the media player
|
||||
display.vlcMediaPlayer.set_media(display.vlcMedia)
|
||||
display.vlc_media_player.set_media(display.vlc_media)
|
||||
# parse the metadata of the file
|
||||
display.vlcMedia.parse()
|
||||
display.vlc_media.parse()
|
||||
self.volume(display, volume)
|
||||
# We need to set media_info.length during load because we want
|
||||
# to avoid start and stop the video twice. Once for real playback
|
||||
# and once to just get media length.
|
||||
#
|
||||
# Media plugin depends on knowing media length before playback.
|
||||
controller.media_info.length = int(display.vlcMediaPlayer.get_media().get_duration() / 1000)
|
||||
controller.media_info.length = int(display.vlc_media_player.get_media().get_duration() / 1000)
|
||||
return True
|
||||
|
||||
def media_state_wait(self, display, media_state):
|
||||
@ -185,8 +185,8 @@ class VlcPlayer(MediaPlayer):
|
||||
Wait no longer than 60 seconds. (loading an iso file needs a long time)
|
||||
"""
|
||||
start = datetime.now()
|
||||
while not media_state == display.vlcMedia.get_state():
|
||||
if display.vlcMedia.get_state() == vlc.State.Error:
|
||||
while not media_state == display.vlc_media.get_state():
|
||||
if display.vlc_media.get_state() == vlc.State.Error:
|
||||
return False
|
||||
self.application.process_events()
|
||||
if (datetime.now() - start).seconds > 60:
|
||||
@ -197,7 +197,7 @@ class VlcPlayer(MediaPlayer):
|
||||
"""
|
||||
Resize the player
|
||||
"""
|
||||
display.vlcWidget.resize(display.size())
|
||||
display.vlc_widget.resize(display.size())
|
||||
|
||||
def play(self, display):
|
||||
"""
|
||||
@ -207,25 +207,25 @@ class VlcPlayer(MediaPlayer):
|
||||
start_time = 0
|
||||
if self.state != MediaState.Paused and controller.media_info.start_time > 0:
|
||||
start_time = controller.media_info.start_time
|
||||
display.vlcMediaPlayer.play()
|
||||
display.vlc_media_player.play()
|
||||
if not self.media_state_wait(display, vlc.State.Playing):
|
||||
return False
|
||||
self.volume(display, controller.media_info.volume)
|
||||
if start_time > 0:
|
||||
self.seek(display, controller.media_info.start_time * 1000)
|
||||
controller.media_info.length = int(display.vlcMediaPlayer.get_media().get_duration() / 1000)
|
||||
controller.media_info.length = int(display.vlc_media_player.get_media().get_duration() / 1000)
|
||||
controller.seek_slider.setMaximum(controller.media_info.length * 1000)
|
||||
self.state = MediaState.Playing
|
||||
display.vlcWidget.raise_()
|
||||
display.vlc_widget.raise_()
|
||||
return True
|
||||
|
||||
def pause(self, display):
|
||||
"""
|
||||
Pause the current item
|
||||
"""
|
||||
if display.vlcMedia.get_state() != vlc.State.Playing:
|
||||
if display.vlc_media.get_state() != vlc.State.Playing:
|
||||
return
|
||||
display.vlcMediaPlayer.pause()
|
||||
display.vlc_media_player.pause()
|
||||
if self.media_state_wait(display, vlc.State.Paused):
|
||||
self.state = MediaState.Paused
|
||||
|
||||
@ -233,7 +233,7 @@ class VlcPlayer(MediaPlayer):
|
||||
"""
|
||||
Stop the current item
|
||||
"""
|
||||
display.vlcMediaPlayer.stop()
|
||||
display.vlc_media_player.stop()
|
||||
self.state = MediaState.Stopped
|
||||
|
||||
def volume(self, display, vol):
|
||||
@ -241,21 +241,21 @@ class VlcPlayer(MediaPlayer):
|
||||
Set the volume
|
||||
"""
|
||||
if display.has_audio:
|
||||
display.vlcMediaPlayer.audio_set_volume(vol)
|
||||
display.vlc_media_player.audio_set_volume(vol)
|
||||
|
||||
def seek(self, display, seek_value):
|
||||
"""
|
||||
Go to a particular position
|
||||
"""
|
||||
if display.vlcMediaPlayer.is_seekable():
|
||||
display.vlcMediaPlayer.set_time(seek_value)
|
||||
if display.vlc_media_player.is_seekable():
|
||||
display.vlc_media_player.set_time(seek_value)
|
||||
|
||||
def reset(self, display):
|
||||
"""
|
||||
Reset the player
|
||||
"""
|
||||
display.vlcMediaPlayer.stop()
|
||||
display.vlcWidget.setVisible(False)
|
||||
display.vlc_media_player.stop()
|
||||
display.vlc_widget.setVisible(False)
|
||||
self.state = MediaState.Off
|
||||
|
||||
def set_visible(self, display, status):
|
||||
@ -263,23 +263,23 @@ class VlcPlayer(MediaPlayer):
|
||||
Set the visibility
|
||||
"""
|
||||
if self.has_own_widget:
|
||||
display.vlcWidget.setVisible(status)
|
||||
display.vlc_widget.setVisible(status)
|
||||
|
||||
def update_ui(self, display):
|
||||
"""
|
||||
Update the UI
|
||||
"""
|
||||
# Stop video if playback is finished.
|
||||
if display.vlcMedia.get_state() == vlc.State.Ended:
|
||||
if display.vlc_media.get_state() == vlc.State.Ended:
|
||||
self.stop(display)
|
||||
controller = display.controller
|
||||
if controller.media_info.end_time > 0:
|
||||
if display.vlcMediaPlayer.get_time() > controller.media_info.end_time * 1000:
|
||||
if display.vlc_media_player.get_time() > controller.media_info.end_time * 1000:
|
||||
self.stop(display)
|
||||
self.set_visible(display, False)
|
||||
if not controller.seek_slider.isSliderDown():
|
||||
controller.seek_slider.blockSignals(True)
|
||||
controller.seek_slider.setSliderPosition(display.vlcMediaPlayer.get_time())
|
||||
controller.seek_slider.setSliderPosition(display.vlc_media_player.get_time())
|
||||
controller.seek_slider.blockSignals(False)
|
||||
|
||||
def get_info(self):
|
||||
@ -287,8 +287,8 @@ class VlcPlayer(MediaPlayer):
|
||||
Return some information about this player
|
||||
"""
|
||||
return(translate('Media.player', 'VLC is an external player which '
|
||||
'supports a number of different formats.') +
|
||||
'<br/> <strong>' + translate('Media.player', 'Audio') +
|
||||
'</strong><br/>' + str(AUDIO_EXT) + '<br/><strong>' +
|
||||
translate('Media.player', 'Video') + '</strong><br/>' +
|
||||
str(VIDEO_EXT) + '<br/>')
|
||||
'supports a number of different formats.') +
|
||||
'<br/> <strong>' + translate('Media.player', 'Audio') +
|
||||
'</strong><br/>' + str(AUDIO_EXT) + '<br/><strong>' +
|
||||
translate('Media.player', 'Video') + '</strong><br/>' +
|
||||
str(VIDEO_EXT) + '<br/>')
|
@ -376,9 +376,9 @@ class WebkitPlayer(MediaPlayer):
|
||||
else:
|
||||
is_visible = "hidden"
|
||||
if controller.media_info.is_flash:
|
||||
display.frame.evaluateJavaScript('show_flash("setVisible", null, null, "%s");' % (is_visible))
|
||||
display.frame.evaluateJavaScript('show_flash("setVisible", null, null, "%s");' % is_visible)
|
||||
else:
|
||||
display.frame.evaluateJavaScript('show_video("setVisible", null, null, null, "%s");' % (is_visible))
|
||||
display.frame.evaluateJavaScript('show_video("setVisible", null, null, null, "%s");' % is_visible)
|
||||
|
||||
def update_ui(self, display):
|
||||
"""
|
||||
@ -412,9 +412,9 @@ class WebkitPlayer(MediaPlayer):
|
||||
Return some information about this player
|
||||
"""
|
||||
return(translate('Media.player', 'Webkit is a media player which runs '
|
||||
'inside a web browser. This player allows text over video to be '
|
||||
'rendered.') +
|
||||
'<br/> <strong>' + translate('Media.player', 'Audio') +
|
||||
'</strong><br/>' + str(AUDIO_EXT) + '<br/><strong>' +
|
||||
translate('Media.player', 'Video') + '</strong><br/>' +
|
||||
str(VIDEO_EXT) + '<br/>')
|
||||
'inside a web browser. This player allows text over video to be '
|
||||
'rendered.') +
|
||||
'<br/> <strong>' + translate('Media.player', 'Audio') +
|
||||
'</strong><br/>' + str(AUDIO_EXT) + '<br/><strong>' +
|
||||
translate('Media.player', 'Video') + '</strong><br/>' +
|
||||
str(VIDEO_EXT) + '<br/>')
|
||||
|
@ -30,7 +30,6 @@
|
||||
The service manager sets up, loads, saves and manages services.
|
||||
"""
|
||||
import html
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import zipfile
|
||||
@ -38,8 +37,6 @@ import json
|
||||
from tempfile import mkstemp
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.common import Registry, AppLocation, Settings, ThemeLevel, OpenLPMixin, RegistryMixin, \
|
||||
@ -291,7 +288,7 @@ class Ui_ServiceManager(object):
|
||||
self.service_manager_list.down,
|
||||
self.service_manager_list.expand,
|
||||
self.service_manager_list.collapse
|
||||
])
|
||||
])
|
||||
Registry().register_function('theme_update_list', self.update_theme_list)
|
||||
Registry().register_function('config_screen_changed', self.regenerate_service_items)
|
||||
Registry().register_function('theme_update_global', self.theme_change)
|
||||
@ -330,7 +327,6 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
self.service_has_all_original_files = True
|
||||
|
||||
def bootstrap_initialise(self):
|
||||
print(self)
|
||||
self.setup_ui(self)
|
||||
# Need to use event as called across threads and UI is updated
|
||||
QtCore.QObject.connect(self, QtCore.SIGNAL('servicemanager_set_item'), self.on_set_item)
|
||||
@ -387,15 +383,16 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
"""
|
||||
self.suffixes = []
|
||||
|
||||
def supported_suffixes(self, suffix):
|
||||
def supported_suffixes(self, suffix_list):
|
||||
"""
|
||||
Adds Suffixes supported to the master list. Called from Plugins.
|
||||
|
||||
``suffix``
|
||||
New Suffix to be supported
|
||||
``suffix_list``
|
||||
New Suffix's to be supported
|
||||
"""
|
||||
if not suffix in self.suffixes:
|
||||
self.suffixes.append(suffix)
|
||||
for suffix in suffix_list:
|
||||
if not suffix in self.suffixes:
|
||||
self.suffixes.append(suffix)
|
||||
|
||||
def on_new_service_clicked(self, field=None):
|
||||
"""
|
||||
@ -482,12 +479,12 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
temp_file, temp_file_name = mkstemp('.osz', 'openlp_')
|
||||
# We don't need the file handle.
|
||||
os.close(temp_file)
|
||||
log.debug(temp_file_name)
|
||||
self.log_debug(temp_file_name)
|
||||
path_file_name = str(self.file_name())
|
||||
path, file_name = os.path.split(path_file_name)
|
||||
base_name = os.path.splitext(file_name)[0]
|
||||
service_file_name = '%s.osj' % base_name
|
||||
log.debug('ServiceManager.save_file - %s', path_file_name)
|
||||
self.log_debug('ServiceManager.save_file - %s', path_file_name)
|
||||
Settings().setValue(self.main_window.service_manager_settings_section + '/last directory', path)
|
||||
service = []
|
||||
write_list = []
|
||||
@ -540,11 +537,11 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
for file_item in write_list:
|
||||
file_size = os.path.getsize(file_item)
|
||||
total_size += file_size
|
||||
log.debug('ServiceManager.save_file - ZIP contents size is %i bytes' % total_size)
|
||||
self.log_debug('ServiceManager.save_file - ZIP contents size is %i bytes' % total_size)
|
||||
service_content = json.dumps(service)
|
||||
# Usual Zip file cannot exceed 2GiB, file with Zip64 cannot be extracted using unzip in UNIX.
|
||||
allow_zip_64 = (total_size > 2147483648 + len(service_content))
|
||||
log.debug('ServiceManager.save_file - allowZip64 is %s' % allow_zip_64)
|
||||
self.log_debug('ServiceManager.save_file - allowZip64 is %s' % allow_zip_64)
|
||||
zip_file = None
|
||||
success = True
|
||||
self.main_window.increment_progress_bar()
|
||||
@ -567,7 +564,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
shutil.copy(audio_from, save_file)
|
||||
zip_file.write(audio_from, audio_to)
|
||||
except IOError:
|
||||
log.exception('Failed to save service to disk: %s', temp_file_name)
|
||||
self.log_exception('Failed to save service to disk: %s', temp_file_name)
|
||||
self.main_window.error_message(translate('OpenLP.ServiceManager', 'Error Saving File'),
|
||||
translate('OpenLP.ServiceManager', 'There was an error saving your file.'))
|
||||
success = False
|
||||
@ -596,12 +593,12 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
temp_file, temp_file_name = mkstemp('.oszl', 'openlp_')
|
||||
# We don't need the file handle.
|
||||
os.close(temp_file)
|
||||
log.debug(temp_file_name)
|
||||
self.log_debug(temp_file_name)
|
||||
path_file_name = str(self.file_name())
|
||||
path, file_name = os.path.split(path_file_name)
|
||||
base_name = os.path.splitext(file_name)[0]
|
||||
service_file_name = '%s.osj' % base_name
|
||||
log.debug('ServiceManager.save_file - %s', path_file_name)
|
||||
self.log_debug('ServiceManager.save_file - %s', path_file_name)
|
||||
Settings().setValue(self.main_window.service_manager_settings_section + '/last directory', path)
|
||||
service = []
|
||||
self.application.set_busy_cursor()
|
||||
@ -622,7 +619,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
# First we add service contents.
|
||||
zip_file.writestr(service_file_name, service_content)
|
||||
except IOError:
|
||||
log.exception('Failed to save service to disk: %s', temp_file_name)
|
||||
self.log_exception('Failed to save service to disk: %s', temp_file_name)
|
||||
self.main_window.error_message(translate('OpenLP.ServiceManager', 'Error Saving File'),
|
||||
translate('OpenLP.ServiceManager', 'There was an error saving your file.'))
|
||||
success = False
|
||||
@ -686,7 +683,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
self.set_file_name(file_name)
|
||||
self.decide_save_method()
|
||||
|
||||
def decide_save_method(self):
|
||||
def decide_save_method(self, field=None):
|
||||
"""
|
||||
Determine which type of save method to use.
|
||||
"""
|
||||
@ -715,14 +712,14 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
try:
|
||||
ucs_file = zip_info.filename
|
||||
except UnicodeDecodeError:
|
||||
log.exception('file_name "%s" is not valid UTF-8' % zip_info.file_name)
|
||||
self.log_exception('file_name "%s" is not valid UTF-8' % zip_info.file_name)
|
||||
critical_error_message_box(message=translate('OpenLP.ServiceManager',
|
||||
'File is not a valid service.\n The content encoding is not UTF-8.'))
|
||||
continue
|
||||
os_file = ucs_file.replace('/', os.path.sep)
|
||||
if not os_file.startswith('audio'):
|
||||
os_file = os.path.split(os_file)[1]
|
||||
log.debug('Extract file: %s', os_file)
|
||||
self.log_debug('Extract file: %s', os_file)
|
||||
zip_info.filename = os_file
|
||||
zip_file.extract(zip_info, self.service_path)
|
||||
if os_file.endswith('osj') or os_file.endswith('osd'):
|
||||
@ -759,19 +756,19 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
Settings().setValue('servicemanager/last file', file_name)
|
||||
else:
|
||||
critical_error_message_box(message=translate('OpenLP.ServiceManager', 'File is not a valid service.'))
|
||||
log.error('File contains no service data')
|
||||
self.log_error('File contains no service data')
|
||||
except (IOError, NameError, zipfile.BadZipfile):
|
||||
log.exception('Problem loading service file %s' % file_name)
|
||||
self.log_exception('Problem loading service file %s' % file_name)
|
||||
critical_error_message_box(message=translate('OpenLP.ServiceManager',
|
||||
'File could not be opened because it is corrupt.'))
|
||||
except zipfile.BadZipfile:
|
||||
if os.path.getsize(file_name) == 0:
|
||||
log.exception('Service file is zero sized: %s' % file_name)
|
||||
self.log_exception('Service file is zero sized: %s' % file_name)
|
||||
QtGui.QMessageBox.information(self, translate('OpenLP.ServiceManager', 'Empty File'),
|
||||
translate('OpenLP.ServiceManager', 'This service file does not contain '
|
||||
'any data.'))
|
||||
else:
|
||||
log.exception('Service file is cannot be extracted as zip: %s' % file_name)
|
||||
self.log_exception('Service file is cannot be extracted as zip: %s' % file_name)
|
||||
QtGui.QMessageBox.information(self, translate('OpenLP.ServiceManager', 'Corrupt File'),
|
||||
translate('OpenLP.ServiceManager',
|
||||
'This file is either corrupt or it is not an OpenLP 2 service file.'))
|
||||
@ -881,7 +878,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
if self.start_time_form.exec_():
|
||||
self.repaint_service_list(item, -1)
|
||||
|
||||
def toggle_auto_play_slides_once(self):
|
||||
def toggle_auto_play_slides_once(self, field=None):
|
||||
"""
|
||||
Toggle Auto play slide once. Inverts auto play once option for the item
|
||||
"""
|
||||
@ -896,7 +893,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
self.main_window.general_settings_section + '/loop delay')
|
||||
self.set_modified()
|
||||
|
||||
def toggle_auto_play_slides_loop(self):
|
||||
def toggle_auto_play_slides_loop(self, field=None):
|
||||
"""
|
||||
Toggle Auto play slide loop.
|
||||
"""
|
||||
@ -1059,7 +1056,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
return
|
||||
self.service_manager_list.setCurrentItem(item_after)
|
||||
|
||||
def on_collapse_all(self):
|
||||
def on_collapse_all(self, field=None):
|
||||
"""
|
||||
Collapse all the service items.
|
||||
"""
|
||||
@ -1074,7 +1071,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
pos = item.data(0, QtCore.Qt.UserRole)
|
||||
self.service_items[pos - 1]['expanded'] = False
|
||||
|
||||
def on_expand_all(self):
|
||||
def on_expand_all(self, field=None):
|
||||
"""
|
||||
Collapse all the service items.
|
||||
"""
|
||||
@ -1089,7 +1086,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
pos = item.data(0, QtCore.Qt.UserRole)
|
||||
self.service_items[pos - 1]['expanded'] = True
|
||||
|
||||
def on_service_top(self):
|
||||
def on_service_top(self, field=None):
|
||||
"""
|
||||
Move the current ServiceItem to the top of the list.
|
||||
"""
|
||||
@ -1101,7 +1098,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
self.repaint_service_list(0, child)
|
||||
self.set_modified()
|
||||
|
||||
def on_service_up(self):
|
||||
def on_service_up(self, field=None):
|
||||
"""
|
||||
Move the current ServiceItem one position up in the list.
|
||||
"""
|
||||
@ -1113,7 +1110,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
self.repaint_service_list(item - 1, child)
|
||||
self.set_modified()
|
||||
|
||||
def on_service_down(self):
|
||||
def on_service_down(self, field=None):
|
||||
"""
|
||||
Move the current ServiceItem one position down in the list.
|
||||
"""
|
||||
@ -1125,7 +1122,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
self.repaint_service_list(item + 1, child)
|
||||
self.set_modified()
|
||||
|
||||
def on_service_end(self):
|
||||
def on_service_end(self, field=None):
|
||||
"""
|
||||
Move the current ServiceItem to the bottom of the list.
|
||||
"""
|
||||
@ -1229,7 +1226,6 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
"""
|
||||
Empties the service_path of temporary files on system exit.
|
||||
"""
|
||||
log.debug('Cleaning up service_path')
|
||||
for file_name in os.listdir(self.service_path):
|
||||
file_path = os.path.join(self.service_path, file_name)
|
||||
delete_file(file_path)
|
||||
@ -1240,7 +1236,6 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
"""
|
||||
Set the theme for the current service.
|
||||
"""
|
||||
log.debug('on_theme_combo_box_selected')
|
||||
self.service_theme = self.theme_combo_box.currentText()
|
||||
self.renderer.set_service_theme(self.service_theme)
|
||||
Settings().setValue(self.main_window.service_manager_settings_section + '/service theme', self.service_theme)
|
||||
@ -1250,7 +1245,6 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
"""
|
||||
The theme may have changed in the settings dialog so make sure the theme combo box is in the correct state.
|
||||
"""
|
||||
log.debug('theme_change')
|
||||
visible = self.renderer.theme_level == ThemeLevel.Global
|
||||
self.theme_label.setVisible(visible)
|
||||
self.theme_combo_box.setVisible(visible)
|
||||
@ -1260,7 +1254,6 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
Rebuild the service list as things have changed and a repaint is the easiest way to do this.
|
||||
"""
|
||||
self.application.set_busy_cursor()
|
||||
log.debug('regenerate_service_items')
|
||||
# force reset of renderer as theme data has changed
|
||||
self.service_has_all_original_files = True
|
||||
if self.service_items:
|
||||
@ -1412,7 +1405,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
'is missing or inactive'))
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def remote_edit(self):
|
||||
def remote_edit(self, field=None):
|
||||
"""
|
||||
Triggers a remote edit to a plugin to allow item to be edited.
|
||||
"""
|
||||
@ -1423,7 +1416,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
if new_item:
|
||||
self.add_service_item(new_item, replace=True)
|
||||
|
||||
def create_custom(self):
|
||||
def create_custom(self, field=None):
|
||||
"""
|
||||
Saves the current text item as a custom slide
|
||||
"""
|
||||
@ -1543,7 +1536,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage
|
||||
self.renderer.set_service_theme(self.service_theme)
|
||||
self.regenerate_service_items()
|
||||
|
||||
def on_theme_change_action(self):
|
||||
def on_theme_change_action(self, field=None):
|
||||
"""
|
||||
Handles theme change events
|
||||
"""
|
||||
|
@ -51,7 +51,7 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
||||
Initialise the settings form
|
||||
"""
|
||||
Registry().register('settings_form', self)
|
||||
Registry().register_function('bootstrap_post_set_up', self.post_set_up)
|
||||
Registry().register_function('bootstrap_post_set_up', self.bootstrap_post_set_up)
|
||||
super(SettingsForm, self).__init__(parent)
|
||||
self.processes = []
|
||||
self.setupUi(self)
|
||||
@ -117,7 +117,7 @@ class SettingsForm(QtGui.QDialog, Ui_SettingsDialog):
|
||||
self.stacked_layout.widget(tabIndex).cancel()
|
||||
return QtGui.QDialog.reject(self)
|
||||
|
||||
def post_set_up(self):
|
||||
def bootstrap_post_set_up(self):
|
||||
"""
|
||||
Run any post-setup code for the tabs on the form
|
||||
"""
|
||||
|
@ -42,22 +42,19 @@ from openlp.core.lib import FileDialog, ImageSource, OpenLPToolbar, get_text_fil
|
||||
check_item_selected, create_thumb, validate_thumb
|
||||
from openlp.core.lib.theme import ThemeXML, BackgroundType
|
||||
from openlp.core.lib.ui import critical_error_message_box, create_widget_action
|
||||
from openlp.core.ui import FileRenameForm, ThemeForm, ThemeManagerHelper
|
||||
from openlp.core.ui import FileRenameForm, ThemeForm
|
||||
from openlp.core.utils import delete_file, get_locale_key, get_filesystem_encoding
|
||||
|
||||
|
||||
class ThemeManager(RegistryMixin, OpenLPMixin, QtGui.QWidget, ThemeManagerHelper):
|
||||
class Ui_ThemeManager(object):
|
||||
"""
|
||||
Manages the orders of Theme.
|
||||
UI part of the Theme Manager
|
||||
"""
|
||||
def __init__(self, parent=None):
|
||||
def setup_ui(self, widget):
|
||||
"""
|
||||
Constructor
|
||||
Define the UI
|
||||
"""
|
||||
super(ThemeManager, self).__init__(parent)
|
||||
self.settings_section = 'themes'
|
||||
self.theme_form = ThemeForm(self)
|
||||
self.file_rename_form = FileRenameForm()
|
||||
|
||||
# start with the layout
|
||||
self.layout = QtGui.QVBoxLayout(self)
|
||||
self.layout.setSpacing(0)
|
||||
@ -128,7 +125,18 @@ class ThemeManager(RegistryMixin, OpenLPMixin, QtGui.QWidget, ThemeManagerHelper
|
||||
# Signals
|
||||
self.theme_list_widget.doubleClicked.connect(self.change_global_from_screen)
|
||||
self.theme_list_widget.currentItemChanged.connect(self.check_list_state)
|
||||
Registry().register_function('theme_update_global', self.change_global_from_tab)
|
||||
|
||||
|
||||
class ThemeManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ThemeManager):
|
||||
"""
|
||||
Manages the orders of Theme.
|
||||
"""
|
||||
def __init__(self, parent=None):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
super(ThemeManager, self).__init__(parent)
|
||||
self.settings_section = 'themes'
|
||||
# Variables
|
||||
self.theme_list = []
|
||||
self.old_background_image = None
|
||||
@ -137,7 +145,7 @@ class ThemeManager(RegistryMixin, OpenLPMixin, QtGui.QWidget, ThemeManagerHelper
|
||||
"""
|
||||
process the bootstrap initialise setup request
|
||||
"""
|
||||
self.log_debug('initialise called')
|
||||
self.setup_ui(self)
|
||||
self.global_theme = Settings().value(self.settings_section + '/global theme')
|
||||
self.build_theme_path()
|
||||
self.load_first_time_themes()
|
||||
@ -146,8 +154,21 @@ class ThemeManager(RegistryMixin, OpenLPMixin, QtGui.QWidget, ThemeManagerHelper
|
||||
"""
|
||||
process the bootstrap post setup request
|
||||
"""
|
||||
self.theme_form = ThemeForm(self)
|
||||
self.theme_form.path = self.path
|
||||
self.file_rename_form = FileRenameForm()
|
||||
Registry().register_function('theme_update_global', self.change_global_from_tab)
|
||||
self._push_themes()
|
||||
|
||||
def build_theme_path(self):
|
||||
"""
|
||||
Set up the theme path variables
|
||||
"""
|
||||
self.path = AppLocation.get_section_data_path(self.settings_section)
|
||||
check_directory_exists(self.path)
|
||||
self.thumb_path = os.path.join(self.path, 'thumbnails')
|
||||
check_directory_exists(self.thumb_path)
|
||||
|
||||
def check_list_state(self, item, field=None):
|
||||
"""
|
||||
If Default theme selected remove delete button.
|
||||
|
@ -1,50 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2014 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan #
|
||||
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
|
||||
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
|
||||
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
|
||||
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
|
||||
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
|
||||
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# 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 Theme Controller helps manages adding, deleteing and modifying of themes.
|
||||
"""
|
||||
import os
|
||||
|
||||
from openlp.core.common import AppLocation, check_directory_exists
|
||||
|
||||
|
||||
class ThemeManagerHelper(object):
|
||||
"""
|
||||
Manages the non ui theme functions.
|
||||
"""
|
||||
def build_theme_path(self):
|
||||
"""
|
||||
Set up the theme path variables
|
||||
"""
|
||||
self.log_debug('build theme path called')
|
||||
self.path = AppLocation.get_section_data_path(self.settings_section)
|
||||
check_directory_exists(self.path)
|
||||
self.thumb_path = os.path.join(self.path, 'thumbnails')
|
||||
check_directory_exists(self.thumb_path)
|
||||
self.theme_form.path = self.path
|
@ -94,7 +94,7 @@ class MediaMediaItem(MediaManagerItem):
|
||||
self.reset_action.setToolTip(UiStrings().ResetLiveBG)
|
||||
self.automatic = UiStrings().Automatic
|
||||
self.display_type_label.setText(translate('MediaPlugin.MediaItem', 'Use Player:'))
|
||||
self.rebuild_players()
|
||||
#self.rebuild_players()
|
||||
|
||||
def required_icons(self):
|
||||
"""
|
||||
@ -112,9 +112,9 @@ class MediaMediaItem(MediaManagerItem):
|
||||
def add_end_header_bar(self):
|
||||
# Replace backgrounds do not work at present so remove functionality.
|
||||
self.replace_action = self.toolbar.add_toolbar_action('replace_action', icon=':/slides/slide_blank.png',
|
||||
triggers=self.onReplaceClick)
|
||||
triggers=self.on_replace_click)
|
||||
self.reset_action = self.toolbar.add_toolbar_action('reset_action', icon=':/system/system_close.png',
|
||||
visible=False, triggers=self.onResetClick)
|
||||
visible=False, triggers=self.on_reset_click)
|
||||
self.media_widget = QtGui.QWidget(self)
|
||||
self.media_widget.setObjectName('media_widget')
|
||||
self.display_layout = QtGui.QFormLayout(self.media_widget)
|
||||
@ -128,16 +128,16 @@ class MediaMediaItem(MediaManagerItem):
|
||||
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.overridePlayerChanged)
|
||||
self.display_type_combo_box.currentIndexChanged.connect(self.override_player_changed)
|
||||
|
||||
def overridePlayerChanged(self, index):
|
||||
def override_player_changed(self, index):
|
||||
player = get_media_players()[0]
|
||||
if index == 0:
|
||||
set_media_players(player)
|
||||
else:
|
||||
set_media_players(player, player[index-1])
|
||||
|
||||
def onResetClick(self):
|
||||
def on_reset_click(self):
|
||||
"""
|
||||
Called to reset the Live background with the media selected,
|
||||
"""
|
||||
@ -150,12 +150,13 @@ class MediaMediaItem(MediaManagerItem):
|
||||
"""
|
||||
self.reset_action.setVisible(False)
|
||||
|
||||
def onReplaceClick(self):
|
||||
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.')):
|
||||
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):
|
||||
@ -168,14 +169,16 @@ class MediaMediaItem(MediaManagerItem):
|
||||
self.reset_action.setVisible(True)
|
||||
else:
|
||||
critical_error_message_box(UiStrings().LiveBGError,
|
||||
translate('MediaPlugin.MediaItem', 'There was no display item to amend.'))
|
||||
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 "%s" no longer exists.') % filename)
|
||||
translate('MediaPlugin.MediaItem',
|
||||
'There was a problem replacing your background, '
|
||||
'the media file "%s" no longer exists.') % filename)
|
||||
|
||||
def generate_slide_data(self, service_item, item=None, xml_version=False, remote=False,
|
||||
context=ServiceItemContext.Live):
|
||||
context=ServiceItemContext.Live):
|
||||
"""
|
||||
Generate the slide data. Needs to be implemented by the plugin.
|
||||
"""
|
||||
@ -211,16 +214,16 @@ class MediaMediaItem(MediaManagerItem):
|
||||
def initialise(self):
|
||||
self.list_view.clear()
|
||||
self.list_view.setIconSize(QtCore.QSize(88, 50))
|
||||
self.servicePath = os.path.join(AppLocation.get_section_data_path(self.settings_section), 'thumbnails')
|
||||
check_directory_exists(self.servicePath)
|
||||
self.service_path = os.path.join(AppLocation.get_section_data_path(self.settings_section), 'thumbnails')
|
||||
check_directory_exists(self.service_path)
|
||||
self.load_list(Settings().value(self.settings_section + '/media files'))
|
||||
self.populateDisplayTypes()
|
||||
self.populate_display_types()
|
||||
|
||||
def rebuild_players(self):
|
||||
"""
|
||||
Rebuild the tab in the media manager when changes are made in the settings.
|
||||
"""
|
||||
self.populateDisplayTypes()
|
||||
self.populate_display_types()
|
||||
self.on_new_file_masks = translate('MediaPlugin.MediaItem', 'Videos (%s);;Audio (%s);;%s (*)') % (
|
||||
' '.join(self.media_controller.video_extensions_list),
|
||||
' '.join(self.media_controller.audio_extensions_list), UiStrings().AllFiles)
|
||||
@ -228,25 +231,25 @@ class MediaMediaItem(MediaManagerItem):
|
||||
def display_setup(self):
|
||||
self.media_controller.setup_display(self.display_controller.preview_display, False)
|
||||
|
||||
def populateDisplayTypes(self):
|
||||
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 overridePlayerChanged Signals while combo box creation
|
||||
# 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()
|
||||
usedPlayers, overridePlayer = get_media_players()
|
||||
used_players, override_player = get_media_players()
|
||||
media_players = self.media_controller.media_players
|
||||
currentIndex = 0
|
||||
for player in usedPlayers:
|
||||
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 overridePlayer == player:
|
||||
currentIndex = len(self.display_type_combo_box)
|
||||
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(currentIndex)
|
||||
if overridePlayer:
|
||||
self.display_type_combo_box.setCurrentIndex(current_index)
|
||||
if override_player:
|
||||
self.media_widget.show()
|
||||
else:
|
||||
self.media_widget.hide()
|
||||
@ -257,7 +260,7 @@ class MediaMediaItem(MediaManagerItem):
|
||||
Remove a media item from the list.
|
||||
"""
|
||||
if check_item_selected(self.list_view,
|
||||
translate('MediaPlugin.MediaItem', 'You must select a media file to delete.')):
|
||||
translate('MediaPlugin.MediaItem', 'You must select a media file to delete.')):
|
||||
row_list = [item.row() for item in self.list_view.selectedIndexes()]
|
||||
row_list.sort(reverse=True)
|
||||
for row in row_list:
|
||||
@ -266,25 +269,25 @@ class MediaMediaItem(MediaManagerItem):
|
||||
|
||||
def load_list(self, media, target_group=None):
|
||||
# Sort the media by its filename considering language specific characters.
|
||||
media.sort(key=lambda filename: get_locale_key(os.path.split(str(filename))[1]))
|
||||
media.sort(key=lambda file_name: get_locale_key(os.path.split(str(file_name))[1]))
|
||||
for track in media:
|
||||
track_info = QtCore.QFileInfo(track)
|
||||
if not os.path.exists(track):
|
||||
filename = os.path.split(str(track))[1]
|
||||
item_name = QtGui.QListWidgetItem(filename)
|
||||
file_name = os.path.split(str(track))[1]
|
||||
item_name = QtGui.QListWidgetItem(file_name)
|
||||
item_name.setIcon(ERROR_ICON)
|
||||
item_name.setData(QtCore.Qt.UserRole, track)
|
||||
elif track_info.isFile():
|
||||
filename = os.path.split(str(track))[1]
|
||||
item_name = QtGui.QListWidgetItem(filename)
|
||||
if '*.%s' % (filename.split('.')[-1].lower()) in self.media_controller.audio_extensions_list:
|
||||
file_name = os.path.split(str(track))[1]
|
||||
item_name = QtGui.QListWidgetItem(file_name)
|
||||
if '*.%s' % (file_name.split('.')[-1].lower()) in self.media_controller.audio_extensions_list:
|
||||
item_name.setIcon(AUDIO_ICON)
|
||||
else:
|
||||
item_name.setIcon(VIDEO_ICON)
|
||||
item_name.setData(QtCore.Qt.UserRole, track)
|
||||
else:
|
||||
filename = os.path.split(str(track))[1]
|
||||
item_name = QtGui.QListWidgetItem(filename)
|
||||
file_name = os.path.split(str(track))[1]
|
||||
item_name = QtGui.QListWidgetItem(file_name)
|
||||
item_name.setIcon(build_icon(DVD_ICON))
|
||||
item_name.setData(QtCore.Qt.UserRole, track)
|
||||
item_name.setToolTip(track)
|
||||
@ -302,7 +305,7 @@ class MediaMediaItem(MediaManagerItem):
|
||||
media = [x for x in media if os.path.splitext(x)[1] in extension]
|
||||
return media
|
||||
|
||||
def search(self, string, showError):
|
||||
def search(self, string, show_error):
|
||||
files = Settings().value(self.settings_section + '/media files')
|
||||
results = []
|
||||
string = string.lower()
|
||||
|
@ -25,7 +25,6 @@ class TestServiceManager(TestCase):
|
||||
with patch('openlp.core.lib.PluginManager'):
|
||||
self.main_window = MainWindow()
|
||||
self.service_manager = Registry().get('service_manager')
|
||||
self.event_was_called = False
|
||||
|
||||
def tearDown(self):
|
||||
"""
|
||||
@ -306,33 +305,17 @@ class TestServiceManager(TestCase):
|
||||
self.service_manager.auto_start_action.setVisible.assert_called_with(True), \
|
||||
'The action should be set visible.'
|
||||
|
||||
def click_on_new_service_test1(self):
|
||||
def click_on_new_service_test(self):
|
||||
"""
|
||||
Test the on_new_service event handler
|
||||
Test the on_new_service event handler is called by the UI
|
||||
"""
|
||||
# GIVEN: An initial form
|
||||
self.service_manager.setup_ui(self.service_manager)
|
||||
|
||||
# WHEN displaying the UI and pressing cancel
|
||||
new_service = self.service_manager.toolbar.actions['newService']
|
||||
self.service_manager.on_new_service_clicked = self.dummy_event()
|
||||
new_service.trigger()
|
||||
assert self.event_was_called is True, 'The on_new_service_clicked method should have been called'
|
||||
|
||||
def click_on_new_service_test2(self):
|
||||
"""
|
||||
Test the on_new_service event handler
|
||||
"""
|
||||
# GIVEN: An initial form
|
||||
self.service_manager.setup_ui(self.service_manager)
|
||||
|
||||
# WHEN displaying the UI and pressing cancel
|
||||
new_service = self.service_manager.toolbar.actions['newService']
|
||||
mocked_event = MagicMock()
|
||||
self.service_manager.on_new_service_clicked = mocked_event
|
||||
new_service.trigger()
|
||||
print(mocked_event.call_count)
|
||||
assert self.event_was_called == 1, 'The on_new_service_clicked method should have been called'
|
||||
self.service_manager.setup_ui(self.service_manager)
|
||||
|
||||
def dummy_event(self):
|
||||
self.event_was_called = True
|
||||
# WHEN displaying the UI and pressing cancel
|
||||
new_service = self.service_manager.toolbar.actions['newService']
|
||||
new_service.trigger()
|
||||
|
||||
assert mocked_event.call_count == 1, 'The on_new_service_clicked method should have been called once'
|
||||
|
@ -27,20 +27,23 @@
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
Interface tests to test the thememanagerhelper class and related methods.
|
||||
Interface tests to test the themeManager class and related methods.
|
||||
"""
|
||||
import os
|
||||
from unittest import TestCase
|
||||
from tempfile import mkstemp
|
||||
|
||||
from openlp.core.common import Settings
|
||||
from openlp.core.ui import ThemeManagerHelper
|
||||
from PyQt4 import QtGui, QtTest, QtCore
|
||||
|
||||
from openlp.core.common import Registry, Settings
|
||||
from openlp.core.lib import ScreenList
|
||||
from openlp.core.ui import ThemeManager
|
||||
from tests.functional import patch, MagicMock
|
||||
|
||||
|
||||
class TestThemeManagerHelper(TestCase):
|
||||
class TestThemeManager(TestCase):
|
||||
"""
|
||||
Test the functions in the ThemeManagerHelp[er module
|
||||
Test the functions in the ThemeManager module
|
||||
"""
|
||||
def setUp(self):
|
||||
"""
|
||||
@ -48,8 +51,8 @@ class TestThemeManagerHelper(TestCase):
|
||||
"""
|
||||
fd, self.ini_file = mkstemp('.ini')
|
||||
Settings().set_filename(self.ini_file)
|
||||
self.helper = ThemeManagerHelper()
|
||||
self.helper.settings_section = "themes"
|
||||
Registry.create()
|
||||
self.theme_manager = ThemeManager()
|
||||
|
||||
def tearDown(self):
|
||||
"""
|
||||
@ -58,29 +61,29 @@ class TestThemeManagerHelper(TestCase):
|
||||
os.unlink(self.ini_file)
|
||||
os.unlink(Settings().fileName())
|
||||
|
||||
def test_initialise(self):
|
||||
def initialise_test(self):
|
||||
"""
|
||||
Test the thememanagerhelper initialise - basic test
|
||||
Test the thememanager initialise - basic test
|
||||
"""
|
||||
# GIVEN: A new a call to initialise
|
||||
self.theme_manager.build_theme_path = MagicMock()
|
||||
self.theme_manager.load_first_time_themes = MagicMock()
|
||||
Settings().setValue('themes/global theme', 'my_theme')
|
||||
self.helper.build_theme_path = MagicMock()
|
||||
self.helper.load_first_time_themes = MagicMock()
|
||||
|
||||
# WHEN: the initialistion is run
|
||||
self.helper.initialise()
|
||||
self.theme_manager.bootstrap_initialise()
|
||||
|
||||
# THEN:
|
||||
self.assertEqual(1, self.helper.build_theme_path.call_count,
|
||||
self.assertEqual(1, self.theme_manager.build_theme_path.call_count,
|
||||
'The function build_theme_path should have been called')
|
||||
self.assertEqual(1, self.helper.load_first_time_themes.call_count,
|
||||
self.assertEqual(1, self.theme_manager.load_first_time_themes.call_count,
|
||||
'The function load_first_time_themes should have been called only once')
|
||||
self.assertEqual(self.helper.global_theme, 'my_theme',
|
||||
self.assertEqual(self.theme_manager.global_theme, 'my_theme',
|
||||
'The global theme should have been set to my_theme')
|
||||
|
||||
def test_build_theme_path(self):
|
||||
def build_theme_path_test(self):
|
||||
"""
|
||||
Test the thememanagerhelper build_theme_path - basic test
|
||||
Test the thememanager build_theme_path - basic test
|
||||
"""
|
||||
# GIVEN: A new a call to initialise
|
||||
with patch('openlp.core.common.applocation.check_directory_exists') as mocked_check_directory_exists:
|
||||
@ -88,12 +91,12 @@ class TestThemeManagerHelper(TestCase):
|
||||
mocked_check_directory_exists.return_value = True
|
||||
Settings().setValue('themes/global theme', 'my_theme')
|
||||
|
||||
self.helper.theme_form = MagicMock()
|
||||
#self.helper.load_first_time_themes = MagicMock()
|
||||
self.theme_manager.theme_form = MagicMock()
|
||||
self.theme_manager.load_first_time_themes = MagicMock()
|
||||
|
||||
# WHEN: the build_theme_path is run
|
||||
self.helper.build_theme_path()
|
||||
self.theme_manager.build_theme_path()
|
||||
|
||||
# THEN:
|
||||
self.assertEqual(self.helper.path, self.helper.theme_form.path,
|
||||
'The theme path and the main path should be the same value')
|
||||
# THEN:
|
||||
self.assertEqual(self.theme_manager.path, self.theme_manager.theme_form.path,
|
||||
'The theme path and the main path should be the same value')
|
Loading…
Reference in New Issue
Block a user