forked from openlp/openlp
Replaceable backgrounds get the HTML treatment.
Sensible Text over video returns. bzr-revno: 902
This commit is contained in:
commit
b275f7ba51
@ -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):
|
||||||
"""
|
"""
|
||||||
|
@ -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):
|
||||||
"""
|
"""
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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())
|
||||||
|
Loading…
Reference in New Issue
Block a user