Replaceable backgrounds get the HTML treatment.

Sensible Text over video returns.

bzr-revno: 902
This commit is contained in:
Tim Bentley 2010-06-30 19:56:45 +01:00
commit b275f7ba51
5 changed files with 150 additions and 67 deletions

View File

@ -35,6 +35,7 @@ import uuid
from PyQt4 import QtGui from PyQt4 import QtGui
from openlp.core.lib import build_icon, resize_image from openlp.core.lib import build_icon, resize_image
from openlp.core.utils import AppLocation
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -92,6 +93,7 @@ class ServiceItem(object):
self.is_valid = True self.is_valid = True
self.cache = {} self.cache = {}
self.icon = None self.icon = None
self.serviceItemPath = AppLocation.get_section_data_path(u'serviceItems')
def add_capability(self, capability): def add_capability(self, capability):
""" """
@ -153,9 +155,12 @@ class ServiceItem(object):
del self.cache[len(self._display_frames)] del self.cache[len(self._display_frames)]
log.log(15, u'Formatting took %4s' % (time.time() - before)) log.log(15, u'Formatting took %4s' % (time.time() - before))
elif self.service_item_type == ServiceItemType.Image: elif self.service_item_type == ServiceItemType.Image:
for slide in self._raw_frames: for count, slide in enumerate(self._raw_frames):
slide[u'image'] = resize_image(slide[u'image'], slide[u'image'] = resize_image(slide[u'image'],
self.render_manager.width, self.render_manager.height) self.render_manager.width, self.render_manager.height)
path = os.path.join(self.serviceItemPath, self._uuid + unicode(count) + u'.png')
slide[u'image'].save(path)
slide[u'display'] = path
elif self.service_item_type == ServiceItemType.Command: elif self.service_item_type == ServiceItemType.Command:
pass pass
else: else:
@ -371,7 +376,8 @@ class ServiceItem(object):
if self.service_item_type == ServiceItemType.Text: if self.service_item_type == ServiceItemType.Text:
return self.render_individual(row) return self.render_individual(row)
else: else:
return {u'main':self._raw_frames[row][u'image'], u'trans':None} return {u'main':self._raw_frames[row][u'image'],
u'trans':None, u'display':self._raw_frames[row][u'display']}
def get_frame_title(self, row=0): def get_frame_title(self, row=0):
""" """

View File

@ -26,14 +26,38 @@
import logging import logging
import os import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui, QtWebKit
from PyQt4.phonon import Phonon from PyQt4.phonon import Phonon
from openlp.core.lib import Receiver, resize_image from openlp.core.lib import Receiver, resize_image
from openlp.core.ui import HideMode from openlp.core.ui import HideMode
from openlp.core.utils import AppLocation
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
HTMLIMAGE = """<html>
<body>
<img src=\"file://%s\" alt\"Hello\">
</body></html>
"""
#http://www.steveheffernan.com/html5-video-player/demo-video-player.html
HTMLVIDEO = u"""<html>
<script type="text/javascript" charset="utf-8">
var video;
var bodyLoaded = function(){
video = document.getElementById("video");
video.volume = 0;
}
</script>
<body id=\"body\" onload=\"bodyLoaded();>\"
<video id=\"video\" src=\"%s\"
autoplay loop width=%s height=%s autobuffer=\"autobuffer\" preload >
your browser does not support the video tag
</video>
</body></html>
"""
class DisplayManager(QtGui.QWidget): class DisplayManager(QtGui.QWidget):
""" """
Wrapper class to hold the display widgets. Wrapper class to hold the display widgets.
@ -76,10 +100,22 @@ class DisplayManager(QtGui.QWidget):
def addAlert(self, alertMessage, location): def addAlert(self, alertMessage, location):
""" """
Handles the add Alert Message to the Displays Handles the addition of an Alert Message to the Displays
""" """
self.mainDisplay.addAlert(alertMessage, location) self.mainDisplay.addAlert(alertMessage, location)
def displayImage(self, path):
"""
Handles the addition of a background Image to the displays
"""
self.mainDisplay.displayImage(path)
def displayVideo(self, path):
"""
Handles the addition of a background Video to the displays
"""
self.mainDisplay.displayVideo(path)
def onStartVideo(self, item): def onStartVideo(self, item):
""" """
Handles the Starting of a Video and Display Management Handles the Starting of a Video and Display Management
@ -183,7 +219,7 @@ class MainDisplay(DisplayWidget):
self.primary = True self.primary = True
self.blankFrame = None self.blankFrame = None
self.frame = None self.frame = None
#Hide desktop for now untill we know where to put it #Hide desktop for now until we know where to put it
#and what size it should be. #and what size it should be.
self.setVisible(False) self.setVisible(False)
@ -198,6 +234,7 @@ class MainDisplay(DisplayWidget):
#Sort out screen locations and sizes #Sort out screen locations and sizes
self.setGeometry(self.screen[u'size']) self.setGeometry(self.screen[u'size'])
self.scene.setSceneRect(0,0,self.size().width(), self.size().height()) self.scene.setSceneRect(0,0,self.size().width(), self.size().height())
self.webView.setGeometry(0, 0, self.size().width(), self.size().height())
#Build a custom splash screen #Build a custom splash screen
self.InitialFrame = QtGui.QImage( self.InitialFrame = QtGui.QImage(
self.screen[u'size'].width(), self.screen[u'size'].width(),
@ -211,7 +248,7 @@ class MainDisplay(DisplayWidget):
(self.screen[u'size'].width() - splash_image.width()) / 2, (self.screen[u'size'].width() - splash_image.width()) / 2,
(self.screen[u'size'].height() - splash_image.height()) / 2, (self.screen[u'size'].height() - splash_image.height()) / 2,
splash_image) splash_image)
self.display_image.setPixmap(QtGui.QPixmap.fromImage(self.InitialFrame)) #self.display_image.setPixmap(QtGui.QPixmap.fromImage(self.InitialFrame))
self.repaint() self.repaint()
#Build a Black screen #Build a Black screen
painter = QtGui.QPainter() painter = QtGui.QPainter()
@ -241,9 +278,16 @@ class MainDisplay(DisplayWidget):
self.setScene(self.scene) self.setScene(self.scene)
def setupImage(self): def setupImage(self):
self.display_image = QtGui.QGraphicsPixmapItem() self.webView = QtWebKit.QWebView()
self.display_image.setZValue(2) self.page = self.webView.page()
self.scene.addItem(self.display_image) self.imageDisplay = self.page.mainFrame()
self.imageDisplay.setScrollBarPolicy(QtCore.Qt.Vertical, QtCore.Qt.ScrollBarAlwaysOff)
self.imageDisplay.setScrollBarPolicy(QtCore.Qt.Horizontal, QtCore.Qt.ScrollBarAlwaysOff)
self.proxy = QtGui.QGraphicsProxyWidget()
self.proxy.setWidget(self.webView)
self.proxy.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.FramelessWindowHint)
self.proxy.setZValue(2)
self.scene.addItem(self.proxy)
def setupText(self): def setupText(self):
#self.display_text = QtGui.QGraphicsTextItem() #self.display_text = QtGui.QGraphicsTextItem()
@ -319,7 +363,7 @@ class MainDisplay(DisplayWidget):
def addAlert(self, message, location): def addAlert(self, message, location):
""" """
Places the Alert text on the display at the correct location Places the Alert text on the display at the correct location
``messgae`` ``message``
Text to be displayed Text to be displayed
``location`` ``location``
Where on the screen the text should be. From the AlertTab Where on the screen the text should be. From the AlertTab
@ -334,7 +378,26 @@ class MainDisplay(DisplayWidget):
self.alertText.setPos(0,self.size().height() - 76) self.alertText.setPos(0,self.size().height() - 76)
self.alertText.setHtml(message) self.alertText.setHtml(message)
def frameView(self, frame, transition=False, display=True): def displayImage(self, path):
"""
Places the Image passed on the display screen
``path``
The path to the image to be displayed
"""
log.debug(u'adddisplayImage')
self.imageDisplay.setHtml(HTMLIMAGE % path)
def displayVideo(self, path):
"""
Places the Video passed on the display screen
``path``
The path to the image to be displayed
"""
log.debug(u'adddisplayVideo')
self.imageDisplay.setHtml(HTMLVIDEO %
(path, self.screen[u'size'].width(), self.screen[u'size'].height()))
def frameView(self, frame, transition=False):
""" """
Called from a slide controller to display a frame Called from a slide controller to display a frame
if the alert is in progress the alert is added on top if the alert is in progress the alert is added on top
@ -343,33 +406,44 @@ class MainDisplay(DisplayWidget):
``transition`` ``transition``
Are transitions required. Are transitions required.
""" """
log.debug(u'frameView %d' % display) log.debug(u'frameView')
if display: if transition:
if transition: if self.frame is not None:
if self.frame is not None:
self.display_text.setPixmap(
QtGui.QPixmap.fromImage(self.frame))
self.update()
self.frame = None
if frame[u'trans'] is not None:
self.display_text.setPixmap(
QtGui.QPixmap.fromImage(frame[u'trans']))
self.repaint()
self.frame = frame[u'trans']
self.display_text.setPixmap( self.display_text.setPixmap(
QtGui.QPixmap.fromImage(frame[u'main'])) QtGui.QPixmap.fromImage(self.frame))
self.display_frame = frame[u'main'] self.update()
self.frame = None
if frame[u'trans'] is not None:
self.display_text.setPixmap(
QtGui.QPixmap.fromImage(frame[u'trans']))
self.repaint() self.repaint()
else: self.frame = frame[u'trans']
if isinstance(frame, QtGui.QPixmap): self.display_text.setPixmap(
self.display_text.setPixmap(frame) QtGui.QPixmap.fromImage(frame[u'main']))
else: self.display_frame = frame[u'main']
self.display_text.setPixmap(QtGui.QPixmap.fromImage(frame)) self.repaint()
self.display_frame = frame
if not self.isVisible() and self.screens.display:
self.setVisible(True)
else: else:
self.storeText = QtGui.QPixmap.fromImage(frame[u'main']) if isinstance(frame, QtGui.QPixmap):
self.display_text.setPixmap(frame)
else:
self.display_text.setPixmap(QtGui.QPixmap.fromImage(frame))
self.display_frame = frame
if not self.isVisible() and self.screens.display:
self.setVisible(True)
def closeEvent(self, event):
"""
Shutting down cleans up background files
"""
serviceItemPath = AppLocation.get_section_data_path(u'serviceItems')
for file in os.listdir(serviceItemPath):
file_path = os.path.join(serviceItemPath, file)
try:
if os.path.isfile(file_path):
os.remove(file_path)
except OSError:
log.exception(u'Failed to clean up servicePath')
class VideoDisplay(Phonon.VideoWidget): class VideoDisplay(Phonon.VideoWidget):
""" """

View File

@ -105,6 +105,7 @@ class SlideController(QtGui.QWidget):
self.isLive = isLive self.isLive = isLive
self.parent = parent self.parent = parent
self.mainDisplay = self.parent.displayManager.mainDisplay self.mainDisplay = self.parent.displayManager.mainDisplay
self.displayManager = self.parent.displayManager
self.loopList = [ self.loopList = [
u'Start Loop', u'Start Loop',
u'Loop Separator', u'Loop Separator',
@ -526,8 +527,8 @@ class SlideController(QtGui.QWidget):
# blanked = self.blankButton.isChecked() # blanked = self.blankButton.isChecked()
# else: # else:
# blanked = False # blanked = False
# Receiver.send_message(u'%s_start' % serviceItem.name.lower(), Receiver.send_message(u'%s_start' % serviceItem.name.lower(),
# [serviceItem, self.isLive, blanked, slideno]) [serviceItem, self.isLive, True, slideno])
self.slideList = {} self.slideList = {}
width = self.parent.ControlSplitter.sizes()[self.split] width = self.parent.ControlSplitter.sizes()[self.split]
#Set pointing cursor when we have somthing to point at #Set pointing cursor when we have somthing to point at
@ -781,7 +782,10 @@ class SlideController(QtGui.QWidget):
log.log( log.log(
15, u'Slide Rendering took %4s' % (time.time() - before)) 15, u'Slide Rendering took %4s' % (time.time() - before))
if self.isLive: if self.isLive:
self.mainDisplay.frameView(frame, True)#, self.canDisplay) if self.serviceItem.is_text():
self.mainDisplay.frameView(frame, True)
else:
self.displayManager.displayImage(frame[u'display'])
self.selectedRow = row self.selectedRow = row
Receiver.send_message(u'slidecontroller_%s_changed' % self.typePrefix, Receiver.send_message(u'slidecontroller_%s_changed' % self.typePrefix,
row) row)

View File

@ -170,17 +170,14 @@ class ImageMediaItem(MediaManagerItem):
return False return False
def onReplaceClick(self): def onReplaceClick(self):
if not self.ListView.selectedIndexes(): if check_item_selected(self.ListView,
QtGui.QMessageBox.information(self, translate('ImagePlugin.MediaItem',
translate('ImagePlugin.MediaItem', 'No item selected'), 'You must select an item to process.')):
translate('ImagePlugin.MediaItem', item = self.buildServiceItem()
'You must select one item')) item.render()
items = self.ListView.selectedIndexes() self.parent.live_controller.displayManager. \
for item in items: displayImage(item.get_rendered_frame(0)[u'display'])
bitem = self.ListView.item(item.row())
filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())
frame = QtGui.QImage(unicode(filename))
self.parent.maindisplay.addImageWithText(frame)
def onPreviewClick(self): def onPreviewClick(self):
MediaManagerItem.onPreviewClick(self) MediaManagerItem.onPreviewClick(self)

View File

@ -29,7 +29,8 @@ import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \ from openlp.core.lib import MediaManagerItem, BaseListWithDnD, build_icon, \
ItemCapabilities, SettingsManager, translate, check_item_selected ItemCapabilities, SettingsManager, translate, check_item_selected, \
context_menu_action
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -73,13 +74,13 @@ class MediaMediaItem(MediaManagerItem):
self.hasNewIcon = False self.hasNewIcon = False
self.hasEditIcon = False self.hasEditIcon = False
# def addListViewToToolBar(self): def addListViewToToolBar(self):
# MediaManagerItem.addListViewToToolBar(self) MediaManagerItem.addListViewToToolBar(self)
# self.ListView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) self.ListView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
# self.ListView.addAction( self.ListView.addAction(
# context_menu_action(self.ListView, u':/slides/slide_blank.png', context_menu_action(self.ListView, u':/slides/slide_blank.png',
# translate('MediaPlugin.MediaItem', 'Replace Live Background'), translate('MediaPlugin.MediaItem', 'Replace Live Background'),
# self.onReplaceClick)) self.onReplaceClick))
def addEndHeaderBar(self): def addEndHeaderBar(self):
self.ImageWidget = QtGui.QWidget(self) self.ImageWidget = QtGui.QWidget(self)
@ -92,24 +93,25 @@ class MediaMediaItem(MediaManagerItem):
self.ImageWidget.setSizePolicy(sizePolicy) self.ImageWidget.setSizePolicy(sizePolicy)
self.ImageWidget.setObjectName(u'ImageWidget') self.ImageWidget.setObjectName(u'ImageWidget')
#Replace backgrounds do not work at present so remove functionality. #Replace backgrounds do not work at present so remove functionality.
# self.blankButton = self.Toolbar.addToolbarButton( self.blankButton = self.Toolbar.addToolbarButton(
# u'Replace Background', u':/slides/slide_blank.png', u'Replace Background', u':/slides/slide_blank.png',
# translate('MediaPlugin.MediaItem', 'Replace Live Background'), translate('MediaPlugin.MediaItem', 'Replace Live Background'),
# self.onReplaceClick, False) self.onReplaceClick, False)
# Add the song widget to the page layout # Add the song widget to the page layout
self.PageLayout.addWidget(self.ImageWidget) self.PageLayout.addWidget(self.ImageWidget)
# def onReplaceClick(self): def onReplaceClick(self):
# if self.background: # if self.background:
# self.background = False # self.background = False
# Receiver.send_message(u'videodisplay_stop') # Receiver.send_message(u'videodisplay_stop')
# else: # else:
# self.background = True # self.background = True
# if not self.ListView.selectedIndexes(): if check_item_selected(self.ListView,
# QtGui.QMessageBox.information(self, translate('ImagePlugin.MediaItem',
# translate('MediaPlugin.MediaItem', 'No item selected'), 'You must select an item to process.')):
# translate('MediaPlugin.MediaItem', item = self.ListView.currentItem()
# 'You must select one item')) filename = unicode(item.data(QtCore.Qt.UserRole).toString())
self.parent.live_controller.displayManager.displayVideo(filename)
# items = self.ListView.selectedIndexes() # items = self.ListView.selectedIndexes()
# for item in items: # for item in items:
# bitem = self.ListView.item(item.row()) # bitem = self.ListView.item(item.row())