openlp/openlp/core/ui/maindisplay.py

653 lines
25 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
2010-12-26 11:04:47 +00:00
# Copyright (c) 2008-2011 Raoul Snyman #
2011-05-26 16:25:54 +00:00
# Portions copyright (c) 2008-2011 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Michael Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, #
2011-05-26 17:11:22 +00:00
# Armin Köhler, Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias #
2011-06-12 16:02:52 +00:00
# Põldaru, Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
2011-06-12 15:41:01 +00:00
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
2010-12-06 19:25:44 +00:00
"""
2011-01-14 18:58:47 +00:00
The :mod:`maindisplay` module provides the functionality to display screens
and play multimedia within OpenLP.
2010-12-06 19:25:44 +00:00
"""
import logging
import os
from PyQt4 import QtCore, QtGui, QtWebKit
from PyQt4.phonon import Phonon
from openlp.core.lib import Receiver, build_html, ServiceItem, image_to_byte, \
2011-04-22 07:06:38 +00:00
translate
2011-01-05 16:57:49 +00:00
from openlp.core.ui import HideMode, ScreenList
log = logging.getLogger(__name__)
#http://www.steveheffernan.com/html5-video-player/demo-video-player.html
#http://html5demos.com/two-videos
2011-05-06 19:55:16 +00:00
class MainDisplay(QtGui.QGraphicsView):
"""
This is the display screen.
"""
def __init__(self, parent, imageManager, live):
if live:
QtGui.QGraphicsView.__init__(self)
# Do not overwrite the parent() method.
2011-10-15 07:52:25 +00:00
self.parent = lambda: parent
else:
QtGui.QGraphicsView.__init__(self, parent)
2010-07-17 08:59:15 +00:00
self.isLive = live
self.imageManager = imageManager
2011-05-05 11:51:47 +00:00
self.screens = ScreenList.get_instance()
2011-02-12 16:07:11 +00:00
self.alertTab = None
self.hideMode = None
self.videoHide = False
self.override = {}
self.retranslateUi()
2011-04-29 11:55:49 +00:00
self.mediaObject = None
2011-08-30 20:29:29 +00:00
if live:
self.audioPlayer = AudioPlayer(self)
else:
self.audioPlayer = None
2011-04-29 11:55:49 +00:00
self.firstTime = True
self.setStyleSheet(u'border: 0px; margin: 0px; padding: 0px;')
2011-02-05 09:45:08 +00:00
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool |
2011-06-18 11:44:40 +00:00
QtCore.Qt.WindowStaysOnTopHint |
QtCore.Qt.X11BypassWindowManagerHint)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
2010-07-24 16:55:06 +00:00
if self.isLive:
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'maindisplay_hide'), self.hideDisplay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'maindisplay_show'), self.showDisplay)
2011-04-29 16:27:27 +00:00
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'openlp_phonon_creation'),
self.createMediaObject)
2010-07-11 07:45:49 +00:00
def retranslateUi(self):
"""
Setup the interface translation strings.
"""
self.setWindowTitle(translate('OpenLP.MainDisplay', 'OpenLP Display'))
2010-07-23 05:05:34 +00:00
def setup(self):
2010-08-28 15:49:51 +00:00
"""
Set up and build the output screen
"""
log.debug(u'Start MainDisplay setup (live = %s)' % self.isLive)
2010-10-01 22:47:37 +00:00
self.usePhonon = QtCore.QSettings().value(
u'media/use phonon', QtCore.QVariant(True)).toBool()
self.phononActive = False
2010-07-23 05:05:34 +00:00
self.screen = self.screens.current
self.setVisible(False)
self.setGeometry(self.screen[u'size'])
self.videoWidget = Phonon.VideoWidget(self)
self.videoWidget.setVisible(False)
self.videoWidget.setGeometry(QtCore.QRect(0, 0,
self.screen[u'size'].width(), self.screen[u'size'].height()))
2011-04-29 16:27:27 +00:00
if self.isLive:
if not self.firstTime:
2011-04-29 11:55:49 +00:00
self.createMediaObject()
log.debug(u'Setup webView')
self.webView = QtWebKit.QWebView(self)
self.webView.setGeometry(0, 0,
self.screen[u'size'].width(), self.screen[u'size'].height())
2010-07-23 05:05:34 +00:00
self.page = self.webView.page()
self.frame = self.page.mainFrame()
QtCore.QObject.connect(self.webView,
QtCore.SIGNAL(u'loadFinished(bool)'), self.isWebLoaded)
2010-09-04 19:13:26 +00:00
self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
2010-07-23 05:05:34 +00:00
self.frame.setScrollBarPolicy(QtCore.Qt.Vertical,
QtCore.Qt.ScrollBarAlwaysOff)
self.frame.setScrollBarPolicy(QtCore.Qt.Horizontal,
QtCore.Qt.ScrollBarAlwaysOff)
if self.isLive:
2010-09-04 07:48:58 +00:00
# Build the initial frame.
image_file = QtCore.QSettings().value(u'advanced/default image',
QtCore.QVariant(u':/graphics/openlp-splash-screen.png'))\
.toString()
background_color = QtGui.QColor()
background_color.setNamedColor(QtCore.QSettings().value(
u'advanced/default color',
2011-04-27 10:30:29 +00:00
QtCore.QVariant(u'#ffffff')).toString())
if not background_color.isValid():
background_color = QtCore.Qt.white
splash_image = QtGui.QImage(image_file)
self.initialFrame = QtGui.QImage(
self.screen[u'size'].width(),
self.screen[u'size'].height(),
2010-07-23 05:05:34 +00:00
QtGui.QImage.Format_ARGB32_Premultiplied)
painter_image = QtGui.QPainter()
painter_image.begin(self.initialFrame)
painter_image.fillRect(self.initialFrame.rect(), background_color)
2010-07-23 05:05:34 +00:00
painter_image.drawImage(
(self.screen[u'size'].width() - splash_image.width()) / 2,
(self.screen[u'size'].height() - splash_image.height()) / 2,
splash_image)
2010-07-23 05:05:34 +00:00
serviceItem = ServiceItem()
serviceItem.bg_image_bytes = image_to_byte(self.initialFrame)
2010-08-29 14:44:14 +00:00
self.webView.setHtml(build_html(serviceItem, self.screen,
2011-02-12 16:07:11 +00:00
self.alertTab, self.isLive, None))
self.__hideMouse()
2010-07-24 16:55:06 +00:00
# To display or not to display?
if not self.screen[u'primary']:
self.primary = False
else:
self.primary = True
log.debug(u'Finished MainDisplay setup')
2010-07-23 05:05:34 +00:00
2011-04-29 11:55:49 +00:00
def createMediaObject(self):
2011-04-29 16:27:27 +00:00
self.firstTime = False
log.debug(u'Creating Phonon objects - Start for %s', self.isLive)
2011-04-29 11:55:49 +00:00
self.mediaObject = Phonon.MediaObject(self)
self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
Phonon.createPath(self.mediaObject, self.videoWidget)
Phonon.createPath(self.mediaObject, self.audio)
QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'stateChanged(Phonon::State, Phonon::State)'),
self.videoState)
QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'finished()'),
self.videoFinished)
QtCore.QObject.connect(self.mediaObject,
QtCore.SIGNAL(u'tick(qint64)'),
self.videoTick)
2011-04-29 16:27:27 +00:00
log.debug(u'Creating Phonon objects - Finished for %s', self.isLive)
2011-04-29 11:55:49 +00:00
2010-07-11 07:45:49 +00:00
def text(self, slide):
2010-07-24 16:55:06 +00:00
"""
Add the slide text from slideController
``slide``
2010-07-24 16:55:06 +00:00
The slide text to be displayed
"""
2010-10-15 15:33:06 +00:00
log.debug(u'text to display')
# Wait for the webview to update before displaying text.
while not self.webLoaded:
Receiver.send_message(u'openlp_process_events')
self.setGeometry(self.screen[u'size'])
2011-07-30 06:33:51 +00:00
self.frame.evaluateJavaScript(u'show_text("%s")' %
2010-08-09 21:21:04 +00:00
slide.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
2010-07-11 07:45:49 +00:00
2010-08-09 21:21:04 +00:00
def alert(self, text):
2010-07-24 16:55:06 +00:00
"""
Add the alert text. If the alert was not displayed, because the screen
is not visible ``False`` is returned, otherwise ``True``.
2010-07-24 16:55:06 +00:00
``slide``
The slide text to be displayed.
2010-07-24 16:55:06 +00:00
"""
2010-10-15 15:33:06 +00:00
log.debug(u'alert to display')
if not self.isVisible():
return False
if self.height() != self.screen[u'size'].height() or \
self.videoWidget.isVisible():
2010-08-09 21:21:04 +00:00
shrink = True
js = u'show_alert("%s", "%s")' % (
text.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'),
u'top')
2010-08-09 21:21:04 +00:00
else:
2010-08-21 10:07:59 +00:00
shrink = False
js = u'show_alert("%s", "")' % (
text.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
2010-08-07 06:18:05 +00:00
height = self.frame.evaluateJavaScript(js)
if shrink:
if self.phononActive:
shrinkItem = self.webView
else:
shrinkItem = self
2010-08-07 06:18:05 +00:00
if text:
alert_height = int(height.toString())
shrinkItem.resize(self.width(), alert_height)
shrinkItem.setVisible(True)
if self.alertTab.location == 1:
shrinkItem.move(self.screen[u'size'].left(),
(self.screen[u'size'].height() - alert_height) / 2)
elif self.alertTab.location == 2:
shrinkItem.move(self.screen[u'size'].left(),
self.screen[u'size'].height() - alert_height)
2010-08-07 06:18:05 +00:00
else:
shrinkItem.setVisible(False)
self.setGeometry(self.screen[u'size'])
return True
2010-07-11 07:45:49 +00:00
2011-08-22 17:32:18 +00:00
def directImage(self, name, path, background):
2010-10-23 07:23:49 +00:00
"""
API for replacement backgrounds so Images are added directly to cache.
2010-10-23 07:23:49 +00:00
"""
2011-08-22 17:32:18 +00:00
self.imageManager.add_image(name, path, u'image', background)
if hasattr(self, u'serviceItem'):
self.override[u'image'] = name
self.override[u'theme'] = self.serviceItem.themedata.theme_name
self.image(name)
# Update the preview frame.
if self.isLive:
2011-10-15 07:52:25 +00:00
self.parent().updatePreview()
return True
return False
2010-10-23 07:23:49 +00:00
def image(self, name):
2010-07-24 16:55:06 +00:00
"""
2011-01-23 08:25:21 +00:00
Add an image as the background. The image has already been added
to the cache.
2010-07-24 16:55:06 +00:00
``Image``
The name of the image to be displayed.
2010-07-24 16:55:06 +00:00
"""
2010-10-15 15:33:06 +00:00
log.debug(u'image to display')
image = self.imageManager.get_image_bytes(name)
2010-08-07 06:18:05 +00:00
self.resetVideo()
self.displayImage(image)
def displayImage(self, image):
"""
Display an image, as is.
"""
self.setGeometry(self.screen[u'size'])
2010-08-07 06:18:05 +00:00
if image:
2010-10-23 07:23:49 +00:00
js = u'show_image("data:image/png;base64,%s");' % image
2010-08-07 06:18:05 +00:00
else:
2010-08-09 21:21:04 +00:00
js = u'show_image("");'
2010-08-07 06:18:05 +00:00
self.frame.evaluateJavaScript(js)
2010-07-11 07:45:49 +00:00
2010-07-28 17:21:32 +00:00
def resetImage(self):
2010-08-02 05:16:07 +00:00
"""
Reset the backgound image to the service item image. Used after the
image plugin has changed the background.
2010-08-02 05:16:07 +00:00
"""
2010-07-28 17:21:32 +00:00
log.debug(u'resetImage')
if hasattr(self, u'serviceItem'):
self.displayImage(self.serviceItem.bg_image_bytes)
else:
self.displayImage(None)
# clear the cache
2011-01-24 17:26:13 +00:00
self.override = {}
2010-07-28 17:21:32 +00:00
def resetVideo(self):
2010-08-02 05:16:07 +00:00
"""
Used after Video plugin has changed the background
"""
2010-07-28 17:21:32 +00:00
log.debug(u'resetVideo')
if self.phononActive:
2010-10-01 22:47:37 +00:00
self.mediaObject.stop()
self.mediaObject.clearQueue()
self.webView.setVisible(True)
self.videoWidget.setVisible(False)
self.phononActive = False
else:
self.frame.evaluateJavaScript(u'show_video("close");')
2011-01-24 17:26:13 +00:00
self.override = {}
2010-08-01 16:46:24 +00:00
def videoPlay(self):
2010-08-02 05:16:07 +00:00
"""
Responds to the request to play a loaded video
"""
2010-08-01 16:46:24 +00:00
log.debug(u'videoPlay')
if self.phononActive:
2010-10-01 22:47:37 +00:00
self.mediaObject.play()
else:
self.frame.evaluateJavaScript(u'show_video("play");')
2010-08-26 05:01:29 +00:00
# show screen
if self.isLive:
self.setVisible(True)
2010-08-01 16:46:24 +00:00
def videoPause(self):
2010-08-02 05:16:07 +00:00
"""
Responds to the request to pause a loaded video
"""
2010-08-01 16:46:24 +00:00
log.debug(u'videoPause')
if self.phononActive:
2010-10-01 22:47:37 +00:00
self.mediaObject.pause()
else:
self.frame.evaluateJavaScript(u'show_video("pause");')
2010-08-01 16:46:24 +00:00
def videoStop(self):
2010-08-02 05:16:07 +00:00
"""
Responds to the request to stop a loaded video
"""
2010-08-01 16:46:24 +00:00
log.debug(u'videoStop')
if self.phononActive:
2010-10-01 22:47:37 +00:00
self.mediaObject.stop()
else:
self.frame.evaluateJavaScript(u'show_video("stop");')
2010-08-01 16:46:24 +00:00
2010-08-04 19:09:43 +00:00
def videoVolume(self, volume):
2010-08-02 05:16:07 +00:00
"""
Changes the volume of a running video
"""
2010-08-04 19:09:43 +00:00
log.debug(u'videoVolume %d' % volume)
vol = float(volume) / float(10)
if self.phononActive:
2010-10-08 19:40:59 +00:00
self.audio.setVolume(vol)
2010-10-01 22:47:37 +00:00
else:
self.frame.evaluateJavaScript(u'show_video(null, null, %s);' %
2010-10-08 19:40:59 +00:00
str(vol))
2010-10-01 22:47:37 +00:00
def video(self, videoPath, volume, isBackground=False):
2010-08-02 05:16:07 +00:00
"""
Loads and starts a video to run with the option of sound
"""
# We request a background video but have no service Item
if isBackground and not hasattr(self, u'serviceItem'):
return None
2011-04-29 11:55:49 +00:00
if not self.mediaObject:
self.createMediaObject()
2010-07-25 08:58:08 +00:00
log.debug(u'video')
self.webLoaded = True
self.setGeometry(self.screen[u'size'])
# We are running a background theme
self.override[u'theme'] = u''
self.override[u'video'] = True
vol = float(volume) / float(10)
2010-10-01 22:47:37 +00:00
if isBackground or not self.usePhonon:
js = u'show_video("init", "%s", %s, true); show_video("play");' % \
2011-02-08 02:45:37 +00:00
(videoPath.replace(u'\\', u'\\\\'), str(vol))
2010-10-01 22:47:37 +00:00
self.frame.evaluateJavaScript(js)
else:
self.phononActive = True
2010-10-01 22:47:37 +00:00
self.mediaObject.stop()
self.mediaObject.clearQueue()
self.mediaObject.setCurrentSource(Phonon.MediaSource(videoPath))
2011-03-14 10:10:10 +00:00
# Need the timer to trigger set the trigger to 200ms
# Value taken from web documentation.
2011-03-19 12:40:33 +00:00
if self.serviceItem.end_time != 0:
self.mediaObject.setTickInterval(200)
2010-10-01 22:47:37 +00:00
self.mediaObject.play()
self.webView.setVisible(False)
self.videoWidget.setVisible(True)
2010-10-08 19:40:59 +00:00
self.audio.setVolume(vol)
2010-07-11 07:45:49 +00:00
2011-03-19 22:52:56 +00:00
def videoState(self, newState, oldState):
"""
Start the video at a predetermined point.
"""
if newState == Phonon.PlayingState \
and oldState != Phonon.PausedState \
and self.serviceItem.start_time > 0:
2011-03-14 10:10:10 +00:00
# set start time in milliseconds
2011-02-13 13:11:15 +00:00
self.mediaObject.seek(self.serviceItem.start_time * 1000)
def videoFinished(self):
"""
Blank the Video when it has finished so the final frame is not left
hanging
"""
self.videoStop()
self.hideDisplay(HideMode.Blank)
self.phononActive = False
self.videoHide = True
def videoTick(self, tick):
"""
Triggered on video tick every 200 milli seconds
"""
2011-03-19 12:40:33 +00:00
if tick > self.serviceItem.end_time * 1000:
self.videoFinished()
def isWebLoaded(self):
2010-07-25 08:58:08 +00:00
"""
Called by webView event to show display is fully loaded
"""
log.debug(u'Webloaded')
self.webLoaded = True
2010-07-17 10:25:52 +00:00
2010-07-17 08:59:15 +00:00
def preview(self):
2010-08-02 05:16:07 +00:00
"""
Generates a preview of the image displayed.
"""
2010-08-26 05:01:29 +00:00
log.debug(u'preview for %s', self.isLive)
2010-09-17 20:32:00 +00:00
Receiver.send_message(u'openlp_process_events')
# We must have a service item to preview
if self.isLive and hasattr(self, u'serviceItem'):
# Wait for the fade to finish before geting the preview.
# Important otherwise preview will have incorrect text if at all!
if self.serviceItem.themedata and \
2010-09-11 06:59:36 +00:00
self.serviceItem.themedata.display_slide_transition:
while self.frame.evaluateJavaScript(u'show_text_complete()') \
.toString() == u'false':
Receiver.send_message(u'openlp_process_events')
2010-08-07 06:18:05 +00:00
# Wait for the webview to update before geting the preview.
# Important otherwise first preview will miss the background !
while not self.webLoaded:
2010-07-17 10:25:52 +00:00
Receiver.send_message(u'openlp_process_events')
2010-09-21 17:24:01 +00:00
# if was hidden keep it hidden
2010-09-17 20:32:00 +00:00
if self.isLive:
if self.hideMode:
self.hideDisplay(self.hideMode)
else:
# Single screen active
if self.screens.display_count == 1:
# Only make visible if setting enabled
if QtCore.QSettings().value(u'general/display on monitor',
QtCore.QVariant(True)).toBool():
self.setVisible(True)
else:
self.setVisible(True)
preview = QtGui.QPixmap(self.screen[u'size'].width(),
self.screen[u'size'].height())
2010-07-11 07:45:49 +00:00
painter = QtGui.QPainter(preview)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
self.frame.render(painter)
painter.end()
return preview
def buildHtml(self, serviceItem, image=None):
2010-07-17 08:59:15 +00:00
"""
Store the serviceItem and build the new HTML from it. Add the
HTML to the display
"""
2010-07-25 08:58:08 +00:00
log.debug(u'buildHtml')
self.webLoaded = False
self.initialFrame = None
2010-07-17 08:59:15 +00:00
self.serviceItem = serviceItem
background = None
# We have an image override so keep the image till the theme changes
if self.override:
# We have an video override so allow it to be stopped
if u'video' in self.override:
Receiver.send_message(u'video_background_replaced')
self.override = {}
# We have a different theme.
2011-02-08 02:45:37 +00:00
elif self.override[u'theme'] != serviceItem.themedata.theme_name:
Receiver.send_message(u'live_theme_changed')
self.override = {}
else:
# replace the background
background = self.imageManager. \
get_image_bytes(self.override[u'image'])
2010-10-23 07:23:49 +00:00
if self.serviceItem.themedata.background_filename:
self.serviceItem.bg_image_bytes = self.imageManager. \
2010-10-23 07:23:49 +00:00
get_image_bytes(self.serviceItem.themedata.theme_name)
if image:
image_bytes = self.imageManager.get_image_bytes(image)
else:
image_bytes = None
2011-02-12 16:07:11 +00:00
html = build_html(self.serviceItem, self.screen, self.alertTab,
self.isLive, background, image_bytes)
2010-09-16 21:19:51 +00:00
log.debug(u'buildHtml - pre setHtml')
2010-07-12 19:36:42 +00:00
self.webView.setHtml(html)
2010-09-16 21:19:51 +00:00
log.debug(u'buildHtml - post setHtml')
if serviceItem.foot_text:
2010-08-09 21:21:04 +00:00
self.footer(serviceItem.foot_text)
# if was hidden keep it hidden
if self.hideMode and self.isLive:
if QtCore.QSettings().value(u'general/auto unblank',
QtCore.QVariant(False)).toBool():
Receiver.send_message(u'slidecontroller_live_unblank')
else:
self.hideDisplay(self.hideMode)
# display hidden for video end we have a new item so must be shown
if self.videoHide and self.isLive:
self.videoHide = False
self.showDisplay()
self.__hideMouse()
2010-08-09 21:21:04 +00:00
def footer(self, text):
2010-08-28 15:49:51 +00:00
"""
Display the Footer
"""
2010-08-09 21:21:04 +00:00
log.debug(u'footer')
js = u'show_footer(\'' + \
text.replace(u'\\', u'\\\\').replace(u'\'', u'\\\'') + u'\')'
2010-08-09 21:21:04 +00:00
self.frame.evaluateJavaScript(js)
2010-07-12 19:36:42 +00:00
2010-07-23 05:05:34 +00:00
def hideDisplay(self, mode=HideMode.Screen):
"""
Hide the display by making all layers transparent
Store the images so they can be replaced when required
"""
log.debug(u'hideDisplay mode = %d', mode)
if self.phononActive:
self.videoPause()
2010-07-23 05:05:34 +00:00
if mode == HideMode.Screen:
2010-08-09 21:21:04 +00:00
self.frame.evaluateJavaScript(u'show_blank("desktop");')
2010-07-23 05:05:34 +00:00
self.setVisible(False)
2010-08-05 07:49:25 +00:00
elif mode == HideMode.Blank or self.initialFrame:
2010-08-09 21:21:04 +00:00
self.frame.evaluateJavaScript(u'show_blank("black");')
2010-07-23 05:05:34 +00:00
else:
2010-08-09 21:21:04 +00:00
self.frame.evaluateJavaScript(u'show_blank("theme");')
if mode != HideMode.Screen:
if self.isHidden():
self.setVisible(True)
if self.phononActive:
self.webView.setVisible(True)
self.hideMode = mode
2010-07-23 05:05:34 +00:00
2010-07-24 19:27:25 +00:00
def showDisplay(self):
2010-07-23 05:05:34 +00:00
"""
Show the stored layers so the screen reappears as it was
originally.
Make the stored images None to release memory.
"""
log.debug(u'showDisplay')
2010-08-09 21:21:04 +00:00
self.frame.evaluateJavaScript('show_blank("show");')
2010-07-23 05:05:34 +00:00
if self.isHidden():
self.setVisible(True)
if self.phononActive:
self.webView.setVisible(False)
self.videoPlay()
self.hideMode = None
2010-07-24 16:55:06 +00:00
# Trigger actions when display is active again
if self.isLive:
Receiver.send_message(u'maindisplay_active')
def __hideMouse(self):
# Hide mouse cursor when moved over display if enabled in settings
if QtCore.QSettings().value(u'advanced/hide mouse',
QtCore.QVariant(False)).toBool():
self.setCursor(QtCore.Qt.BlankCursor)
self.frame.evaluateJavaScript('document.body.style.cursor = "none"')
else:
self.setCursor(QtCore.Qt.ArrowCursor)
self.frame.evaluateJavaScript('document.body.style.cursor = "auto"')
2011-01-17 15:38:10 +00:00
class AudioPlayer(QtCore.QObject):
"""
2010-07-06 21:59:52 +00:00
This Class will play audio only allowing components to work with a
2010-07-11 07:45:49 +00:00
soundtrack independent of the user interface.
"""
log.info(u'AudioPlayer Loaded')
def __init__(self, parent):
"""
The constructor for the display form.
``parent``
The parent widget.
"""
log.debug(u'AudioPlayer Initialisation started')
2010-07-06 21:59:52 +00:00
QtCore.QObject.__init__(self, parent)
2011-08-30 20:29:29 +00:00
self.currentIndex = -1
self.playlist = []
self.mediaObject = Phonon.MediaObject()
self.audioObject = Phonon.AudioOutput(Phonon.VideoCategory)
Phonon.createPath(self.mediaObject, self.audioObject)
QtCore.QObject.connect(self.mediaObject,
2011-08-30 20:29:29 +00:00
QtCore.SIGNAL(u'aboutToFinish()'), self.onAboutToFinish)
2011-08-30 20:29:29 +00:00
def __del__(self):
"""
Shutting down so clean up connections
"""
2011-08-30 20:29:29 +00:00
self.stop()
2010-07-07 14:44:22 +00:00
for path in self.mediaObject.outputPaths():
2010-07-08 08:14:10 +00:00
path.disconnect()
def onAboutToFinish(self):
"""
Just before the audio player finishes the current track, queue the next
item in the playlist, if there is one.
"""
self.currentIndex += 1
if len(self.playlist) > self.currentIndex:
self.mediaObject.enqueue(self.playlist[self.currentIndex])
2011-08-30 21:20:32 +00:00
def connectVolumeSlider(self, slider):
slider.setAudioOutput(self.audioObject)
2011-08-30 20:29:29 +00:00
def reset(self):
"""
2011-08-30 20:29:29 +00:00
Reset the audio player, clearing the playlist and the queue.
"""
2011-08-30 20:29:29 +00:00
self.currentIndex = -1
self.playlist = []
self.stop()
self.mediaObject.clear()
2011-08-30 20:29:29 +00:00
def play(self):
"""
2011-08-30 20:29:29 +00:00
We want to play the file so start it
"""
2011-08-30 20:29:29 +00:00
log.debug(u'AudioPlayer.play() called')
if self.currentIndex == -1:
2011-08-30 21:20:32 +00:00
self.onAboutToFinish()
self.mediaObject.play()
2011-08-30 20:29:29 +00:00
def pause(self):
"""
Pause the Audio
"""
2011-08-30 20:29:29 +00:00
log.debug(u'AudioPlayer.pause() called')
self.mediaObject.pause()
2011-08-30 20:29:29 +00:00
def stop(self):
"""
Stop the Audio and clean up
"""
2011-08-30 20:29:29 +00:00
log.debug(u'AudioPlayer.stop() called')
self.mediaObject.stop()
2011-08-30 20:29:29 +00:00
def addToPlaylist(self, filenames):
"""
Add another file to the playlist.
``filename``
The file to add to the playlist.
"""
if not isinstance(filenames, list):
filenames = [filenames]
for filename in filenames:
self.playlist.append(Phonon.MediaSource(filename))