Lots of fixes:

Alerts now stack up a wait correctly
Presentations will run but issue with impress previews
Transparent themes now work
New image for media previews
This commit is contained in:
Tim Bentley 2010-01-09 09:34:06 +00:00
parent 99994d0b2a
commit 6ef3f6aadc
10 changed files with 210 additions and 185 deletions

View File

@ -136,6 +136,30 @@ def contextMenuSeparator(base):
action.setSeparator(True) action.setSeparator(True)
return action return action
def resize_image(image, width, height):
"""
Resize an image to fit on the current screen.
``image``
The image to resize.
"""
if isinstance(image, QtGui.QImage):
preview = QtGui.QImage(image)
else:
preview = QtGui.QImage(image)
preview = preview.scaled(width, height, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
realw = preview.width();
realh = preview.height()
# and move it to the centre of the preview space
newImage = QtGui.QImage(width, height, QtGui.QImage.Format_ARGB32_Premultiplied)
newImage.fill(QtCore.Qt.black)
painter = QtGui.QPainter(newImage)
painter.drawImage((width - realw) / 2, (height - realh) / 2, preview)
return newImage
class ThemeLevel(object): class ThemeLevel(object):
Global = 1 Global = 1
Service = 2 Service = 2
@ -160,6 +184,3 @@ from renderer import Renderer
from rendermanager import RenderManager from rendermanager import RenderManager
from mediamanageritem import MediaManagerItem from mediamanageritem import MediaManagerItem
from baselistwithdnd import BaseListWithDnD from baselistwithdnd import BaseListWithDnD
#__all__ = [ 'translate', 'get_text_file_string', 'str_to_bool',
# 'contextMenuAction', 'contextMenuSeparator', 'ServiceItem']

View File

@ -26,6 +26,7 @@
import logging import logging
from PyQt4 import QtGui, QtCore from PyQt4 import QtGui, QtCore
from openlp.core.lib import resize_image
class Renderer(object): class Renderer(object):
""" """
@ -90,31 +91,9 @@ class Renderer(object):
log.debug(u'set bg image %s', filename) log.debug(u'set bg image %s', filename)
self._bg_image_filename = unicode(filename) self._bg_image_filename = unicode(filename)
if self._frame: if self._frame:
self.scale_bg_image() self.bg_image = resize_image(self._bg_image_filename,
self._frame.width(),
def scale_bg_image(self): self._frame.height())
"""
Scale the background image to fit the screen.
"""
assert self._frame
preview = QtGui.QImage(self._bg_image_filename)
width = self._frame.width()
height = self._frame.height()
preview = preview.scaled(width, height, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
realwidth = preview.width()
realheight = preview.height()
# and move it to the centre of the preview space
self.bg_image = QtGui.QImage(width, height,
QtGui.QImage.Format_ARGB32_Premultiplied)
self.bg_image.fill(QtCore.Qt.black)
painter = QtGui.QPainter()
painter.begin(self.bg_image)
self.background_offsetx = (width - realwidth) / 2
self.background_offsety = (height - realheight) / 2
painter.drawImage(self.background_offsetx,
self.background_offsety, preview)
painter.end()
def set_frame_dest(self, frame_width, frame_height, preview=False): def set_frame_dest(self, frame_width, frame_height, preview=False):
""" """
@ -138,7 +117,9 @@ class Renderer(object):
self._frameOp = QtGui.QImage(frame_width, frame_height, self._frameOp = QtGui.QImage(frame_width, frame_height,
QtGui.QImage.Format_ARGB32_Premultiplied) QtGui.QImage.Format_ARGB32_Premultiplied)
if self._bg_image_filename and not self.bg_image: if self._bg_image_filename and not self.bg_image:
self.scale_bg_image() self.bg_image = resize_image(self._bg_image_filename,
self._frame.width(),
self._frame.height())
if self.bg_frame is None: if self.bg_frame is None:
self._generate_background_frame() self._generate_background_frame()
@ -276,8 +257,13 @@ class Renderer(object):
Results are cached for performance reasons. Results are cached for performance reasons.
""" """
assert(self._theme) assert(self._theme)
self.bg_frame = QtGui.QImage(self._frame.width(), self._frame.height(), if self._theme.background_mode == u'transparent':
QtGui.QImage.Format_ARGB32_Premultiplied) self.bg_frame = \
QtGui.QPixmap(self._frame.width(), self._frame.height())
self.bg_frame.fill(QtCore.Qt.transparent)
else:
self.bg_frame = QtGui.QImage(self._frame.width(), self._frame.height(),
QtGui.QImage.Format_ARGB32_Premultiplied)
log.debug(u'render background %s start', self._theme.background_type) log.debug(u'render background %s start', self._theme.background_type)
painter = QtGui.QPainter() painter = QtGui.QPainter()
painter.begin(self.bg_frame) painter.begin(self.bg_frame)
@ -422,6 +408,14 @@ class Renderer(object):
startx = x startx = x
starty = y starty = y
rightextent = None rightextent = None
self.painter = QtGui.QPainter()
self.painter.begin(self._frame)
self.painter.setRenderHint(QtGui.QPainter.Antialiasing);
if self._theme.display_slideTransition:
self.painter2 = QtGui.QPainter()
self.painter2.begin(self._frameOp)
self.painter2.setRenderHint(QtGui.QPainter.Antialiasing);
self.painter2.setOpacity(0.7)
# dont allow alignment messing with footers # dont allow alignment messing with footers
if footer: if footer:
align = 0 align = 0
@ -503,13 +497,14 @@ class Renderer(object):
if linenum == 0: if linenum == 0:
self._first_line_right_extent = rightextent self._first_line_right_extent = rightextent
# draw a box around the text - debug only # draw a box around the text - debug only
if self._debug: if self._debug:
painter = QtGui.QPainter() self.painter.setPen(QtGui.QPen(QtGui.QColor(0,255,0)))
painter.begin(self._frame) self.painter.drawRect(startx, starty, rightextent-startx, y-starty)
painter.setPen(QtGui.QPen(QtGui.QColor(0,255,0)))
painter.drawRect(startx, starty, rightextent-startx, y-starty)
painter.end()
brcorner = (rightextent, y) brcorner = (rightextent, y)
self.painter.end()
if self._theme.display_slideTransition:
self.painter2.end()
return brcorner return brcorner
def _set_theme_font(self): def _set_theme_font(self):
@ -519,6 +514,7 @@ class Renderer(object):
footer_weight = 50 footer_weight = 50
if self._theme.font_footer_weight == u'Bold': if self._theme.font_footer_weight == u'Bold':
footer_weight = 75 footer_weight = 75
#TODO Add myfont.setPixelSize((screen_height / 100) * font_size)
self.footerFont = QtGui.QFont(self._theme.font_footer_name, self.footerFont = QtGui.QFont(self._theme.font_footer_name,
self._theme.font_footer_proportion, # size self._theme.font_footer_proportion, # size
footer_weight, # weight footer_weight, # weight
@ -556,45 +552,36 @@ class Renderer(object):
Defaults to *None*. The colour to draw with. Defaults to *None*. The colour to draw with.
""" """
# setup defaults # setup defaults
painter = QtGui.QPainter()
painter.begin(self._frame)
painter.setRenderHint(QtGui.QPainter.Antialiasing);
if footer : if footer :
font = self.footerFont font = self.footerFont
else: else:
font = self.mainFont font = self.mainFont
painter.setFont(font) self.painter.setFont(font)
if color is None: if color is None:
if footer: if footer:
painter.setPen(QtGui.QColor(self._theme.font_footer_color)) self.painter.setPen(QtGui.QColor(self._theme.font_footer_color))
else: else:
painter.setPen(QtGui.QColor(self._theme.font_main_color)) self.painter.setPen(QtGui.QColor(self._theme.font_main_color))
else: else:
painter.setPen(QtGui.QColor(color)) self.painter.setPen(QtGui.QColor(color))
x, y = tlcorner x, y = tlcorner
metrics = QtGui.QFontMetrics(font) metrics = QtGui.QFontMetrics(font)
w = metrics.width(line) w = metrics.width(line)
h = metrics.height() - 2 h = metrics.height() - 2
if draw: if draw:
painter.drawText(x, y + metrics.ascent(), line) self.painter.drawText(x, y + metrics.ascent(), line)
painter.end()
if self._theme.display_slideTransition: if self._theme.display_slideTransition:
# Print 2nd image with 70% weight # Print 2nd image with 70% weight
painter = QtGui.QPainter() self.painter2.setFont(font)
painter.begin(self._frameOp)
painter.setRenderHint(QtGui.QPainter.Antialiasing);
painter.setOpacity(0.7)
painter.setFont(font)
if color is None: if color is None:
if footer: if footer:
painter.setPen(QtGui.QColor(self._theme.font_footer_color)) self.painter2.setPen(QtGui.QColor(self._theme.font_footer_color))
else: else:
painter.setPen(QtGui.QColor(self._theme.font_main_color)) self.painter2.setPen(QtGui.QColor(self._theme.font_main_color))
else: else:
painter.setPen(QtGui.QColor(color)) self.painter2.setPen(QtGui.QColor(color))
if draw: if draw:
painter.drawText(x, y + metrics.ascent(), line) self.painter2.drawText(x, y + metrics.ascent(), line)
painter.end()
return (w, h) return (w, h)
def snoop_Image(self, image, image2=None): def snoop_Image(self, image, image2=None):
@ -609,4 +596,4 @@ class Renderer(object):
""" """
image.save(u'renderer.png', u'png') image.save(u'renderer.png', u'png')
if image2: if image2:
image2.save(u'renderer2.png', u'png') image2.save(u'renderer2.png', u'png')

View File

@ -28,7 +28,7 @@ import logging
from PyQt4 import QtGui, QtCore from PyQt4 import QtGui, QtCore
from renderer import Renderer from renderer import Renderer
from openlp.core.lib import ThemeLevel from openlp.core.lib import ThemeLevel, resize_image
class RenderManager(object): class RenderManager(object):
""" """
@ -146,13 +146,13 @@ class RenderManager(object):
if self.save_bg_frame is None: if self.save_bg_frame is None:
self.save_bg_frame = self.renderer.bg_frame self.save_bg_frame = self.renderer.bg_frame
if self.override_background_changed: if self.override_background_changed:
self.renderer.bg_frame = self.resize_image( self.renderer.bg_frame = resize_image(
self.override_background) self.override_background, self.width, self.height)
self.override_background_changed = False self.override_background_changed = False
else: else:
if self.override_background_changed: if self.override_background_changed:
self.renderer.bg_frame = self.resize_image( self.renderer.bg_frame = resize_image(
self.override_background) self.override_background, self.width, self.height)
self.override_background_changed = False self.override_background_changed = False
if self.save_bg_frame: if self.save_bg_frame:
self.renderer.bg_frame = self.save_bg_frame self.renderer.bg_frame = self.save_bg_frame
@ -192,10 +192,13 @@ class RenderManager(object):
The theme to generated a preview for. The theme to generated a preview for.
""" """
log.debug(u'generate preview') log.debug(u'generate preview')
#set the defaukt image size for previews
self.calculate_default(QtCore.QSize(1024, 768)) self.calculate_default(QtCore.QSize(1024, 768))
self.renderer.set_theme(themedata) self.renderer.set_theme(themedata)
self.build_text_rectangle(themedata) self.build_text_rectangle(themedata)
self.renderer.set_frame_dest(self.width, self.height, True) self.renderer.set_frame_dest(self.width, self.height, True)
#Reset the real screen size for subsequent render requests
self.calculate_default(self.screen_list[self.current_display][u'size'])
verse = u'Amazing Grace!\n'\ verse = u'Amazing Grace!\n'\
'How sweet the sound\n'\ 'How sweet the sound\n'\
'To save a wretch like me;\n'\ 'To save a wretch like me;\n'\
@ -206,6 +209,7 @@ class RenderManager(object):
footer.append(u'Public Domain') footer.append(u'Public Domain')
footer.append(u'CCLI 123456') footer.append(u'CCLI 123456')
formatted = self.renderer.format_slide(verse, False) formatted = self.renderer.format_slide(verse, False)
#Only Render the first slide page returned
return self.renderer.generate_frame_from_lines(formatted[0], footer)[u'main'] return self.renderer.generate_frame_from_lines(formatted[0], footer)[u'main']
def format_slide(self, words): def format_slide(self, words):
@ -234,48 +238,18 @@ class RenderManager(object):
self.renderer.set_frame_dest(self.width, self.height) self.renderer.set_frame_dest(self.width, self.height)
return self.renderer.generate_frame_from_lines(main_text, footer_text) return self.renderer.generate_frame_from_lines(main_text, footer_text)
def resize_image(self, image, width=0, height=0):
"""
Resize an image to fit on the current screen.
``image``
The image to resize.
"""
preview = QtGui.QImage(image)
if width == 0:
w = self.width
h = self.height
else:
w = width
h = height
preview = preview.scaled(w, h, QtCore.Qt.KeepAspectRatio,
QtCore.Qt.SmoothTransformation)
realw = preview.width();
realh = preview.height()
# and move it to the centre of the preview space
newImage = QtGui.QImage(w, h, QtGui.QImage.Format_ARGB32_Premultiplied)
newImage.fill(QtCore.Qt.black)
painter = QtGui.QPainter(newImage)
painter.drawImage((w - realw) / 2, (h - realh) / 2, preview)
return newImage
def calculate_default(self, screen): def calculate_default(self, screen):
""" """
Calculate the default dimentions of the screen. Calculate the default dimentions of the screen.
``screen`` ``screen``
The QWidget instance of the screen. The QSize of the screen.
""" """
log.debug(u'calculate default %s', screen) log.debug(u'calculate default %s', screen)
#size fixed so reflects the preview size. self.width = screen.width()
if self.current_display == 0: self.height = screen.height()
self.width = 1024
self.height = 768
else:
self.width = screen.width()
self.height = screen.height()
self.screen_ratio = float(self.height) / float(self.width) self.screen_ratio = float(self.height) / float(self.width)
log.debug(u'calculate default %d, %d, %f', log.debug(u'calculate default %d, %d, %f',
self.width, self.height, self.screen_ratio ) self.width, self.height, self.screen_ratio )
# 90% is start of footer # 90% is start of footer
self.footer_start = int(self.height * 0.90) self.footer_start = int(self.height * 0.90)

View File

@ -30,7 +30,7 @@ import uuid
from PyQt4 import QtGui from PyQt4 import QtGui
from openlp.core.lib import build_icon, Receiver from openlp.core.lib import build_icon, Receiver, resize_image
class ServiceItemType(object): class ServiceItemType(object):
""" """
@ -111,7 +111,8 @@ class ServiceItem(object):
elif self.service_item_type == ServiceItemType.Image: elif self.service_item_type == ServiceItemType.Image:
for slide in self._raw_frames: for slide in self._raw_frames:
slide[u'image'] = \ slide[u'image'] = \
self.RenderManager.resize_image(slide[u'image']) resize_image(slide[u'image'], self.RenderManager.width,
self.RenderManager.height)
elif self.service_item_type == ServiceItemType.Command: elif self.service_item_type == ServiceItemType.Command:
pass pass
else: else:
@ -119,7 +120,7 @@ class ServiceItem(object):
def render_individual(self, row): def render_individual(self, row):
""" """
Takes an array of text and geneates an Image from the Takes an array of text and generates an Image from the
theme. It assumes the text will fit on the screen as it theme. It assumes the text will fit on the screen as it
has generated by the render method above. has generated by the render method above.
""" """
@ -309,4 +310,4 @@ class ServiceItem(object):
def request_audit(self): def request_audit(self):
if self.audit: if self.audit:
Receiver.send_message(u'songusage_live', self.audit) Receiver.send_message(u'songusage_live', self.audit)

View File

@ -90,29 +90,32 @@ class MainDisplay(DisplayWidget):
self.parent = parent self.parent = parent
self.setWindowTitle(u'OpenLP Display') self.setWindowTitle(u'OpenLP Display')
self.screens = screens self.screens = screens
self.layout = QtGui.QVBoxLayout(self) # self.layout = QtGui.QVBoxLayout(self)
self.layout.setSpacing(0) # self.layout.setSpacing(0)
self.layout.setMargin(0) # self.layout.setMargin(0)
self.layout.setObjectName(u'layout') # self.layout.setObjectName(u'layout')
self.mediaObject = Phonon.MediaObject(self) self.mediaObject = Phonon.MediaObject(self)
self.video = Phonon.VideoWidget() self.video = Phonon.VideoWidget()
self.video.setVisible(False) self.video.setVisible(False)
self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject) self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
Phonon.createPath(self.mediaObject, self.video) Phonon.createPath(self.mediaObject, self.video)
Phonon.createPath(self.mediaObject, self.audio) Phonon.createPath(self.mediaObject, self.audio)
self.layout.insertWidget(0, self.video) #self.layout.insertWidget(0, self.video)
self.display = QtGui.QLabel(self) self.display = QtGui.QLabel(self)
self.display.setScaledContents(True) self.display.setScaledContents(True)
self.layout.insertWidget(0, self.display) self.alertDisplay = QtGui.QLabel(self)
self.alertDisplay.setScaledContents(True)
#self.layout.insertWidget(0, self.display)
self.primary = True self.primary = True
self.displayBlank = False self.displayBlank = False
self.blankFrame = None self.blankFrame = None
self.frame = None self.frame = None
self.alertactive = False
self.timer_id = 0 self.timer_id = 0
self.firstTime = True self.firstTime = True
self.mediaLoaded = False self.mediaLoaded = False
self.hasTransition = False self.hasTransition = False
self.alertList = []
self.mediaBackground = False
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'alert_text'), self.displayAlert) QtCore.SIGNAL(u'alert_text'), self.displayAlert)
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
@ -130,7 +133,6 @@ class MainDisplay(DisplayWidget):
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_stop'), self.onMediaStop) QtCore.SIGNAL(u'media_stop'), self.onMediaStop)
def setup(self, screenNumber): def setup(self, screenNumber):
""" """
Sets up the screen on a particular screen. Sets up the screen on a particular screen.
@ -138,44 +140,64 @@ class MainDisplay(DisplayWidget):
""" """
log.debug(u'Setup %s for %s ' %(self.screens, screenNumber)) log.debug(u'Setup %s for %s ' %(self.screens, screenNumber))
self.setVisible(False) self.setVisible(False)
screen = self.screens[screenNumber] self.screen = self.screens[screenNumber]
if screen[u'number'] != screenNumber: if self.screen[u'number'] != screenNumber:
# We will most probably never actually hit this bit, but just in # We will most probably never actually hit this bit, but just in
# case the index in the list doesn't match the screen number, we # case the index in the list doesn't match the screen number, we
# search for it. # search for it.
for scrn in self.screens: for scrn in self.screens:
if scrn[u'number'] == screenNumber: if scrn[u'number'] == screenNumber:
screen = scrn self.screen = scrn
break break
self.setGeometry(screen[u'size']) self.setScreenGeometry()
#Build a custom splash screen #Build a custom splash screen
self.InitialFrame = QtGui.QImage( self.InitialFrame = QtGui.QImage(
screen[u'size'].width(), screen[u'size'].height(), self.screen[u'size'].width(),
self.screen[u'size'].height(),
QtGui.QImage.Format_ARGB32_Premultiplied) QtGui.QImage.Format_ARGB32_Premultiplied)
splash_image = QtGui.QImage(u':/graphics/openlp-splash-screen.png') splash_image = QtGui.QImage(u':/graphics/openlp-splash-screen.png')
painter_image = QtGui.QPainter() painter_image = QtGui.QPainter()
painter_image.begin(self.InitialFrame) painter_image.begin(self.InitialFrame)
painter_image.fillRect(self.InitialFrame.rect(), QtCore.Qt.white) painter_image.fillRect(self.InitialFrame.rect(), QtCore.Qt.white)
painter_image.drawImage( painter_image.drawImage(
(screen[u'size'].width() - splash_image.width()) / 2, (self.screen[u'size'].width() - splash_image.width()) / 2,
(screen[u'size'].height() - splash_image.height()) / 2, (self.screen[u'size'].height() - splash_image.height()) / 2,
splash_image) splash_image)
self.frameView(self.InitialFrame) self.frameView(self.InitialFrame)
#Build a Black screen #Build a Black screen
painter = QtGui.QPainter() painter = QtGui.QPainter()
self.blankFrame = QtGui.QImage( self.blankFrame = QtGui.QImage(
screen[u'size'].width(), screen[u'size'].height(), self.screen[u'size'].width(),
self.screen[u'size'].height(),
QtGui.QImage.Format_ARGB32_Premultiplied) QtGui.QImage.Format_ARGB32_Premultiplied)
painter.begin(self.blankFrame) painter.begin(self.blankFrame)
painter.fillRect(self.blankFrame.rect(), QtCore.Qt.black) painter.fillRect(self.blankFrame.rect(), QtCore.Qt.black)
#buid a blank transparent image
self.transparent = QtGui.QPixmap(self.screen[u'size'].width(),
self.screen[u'size'].height())
self.transparent.fill(QtCore.Qt.transparent)
# To display or not to display? # To display or not to display?
if not screen[u'primary']: if not self.screen[u'primary']:
self.showFullScreen() self.showFullScreen()
self.primary = False self.primary = False
else: else:
self.setVisible(False) self.setVisible(False)
self.primary = True self.primary = True
def setScreenGeometry(self):
"""
Define and set up the display sizes.
The alert displays are set to 10% of the screen as the video display
is unable to handle transparent pixmaps. This is a problem with QT.
"""
self.setGeometry(self.screen[u'size'])
self.alertScreenPosition = self.screen[u'size'].height() * 0.9
self.alertHeight = self.screen[u'size'].height() - self.alertScreenPosition
self.alertDisplay.setGeometry(
QtCore.QRect(0, self.alertScreenPosition,
self.screen[u'size'].width(),self.alertHeight))
self.video.setGeometry(self.screen[u'size'])
def resetDisplay(self): def resetDisplay(self):
if self.primary: if self.primary:
self.setVisible(False) self.setVisible(False)
@ -235,17 +257,27 @@ class MainDisplay(DisplayWidget):
display text display text
""" """
log.debug(u'display alert called %s' % text) log.debug(u'display alert called %s' % text)
self.alertList.append(text)
if self.timer_id != 0:
return
self.generateAlert()
def generateAlert(self):
log.debug(u'Generate Alert called')
if len(self.alertList) == 0:
return
text = self.alertList.pop(0)
alertTab = self.parent.settingsForm.AlertsTab alertTab = self.parent.settingsForm.AlertsTab
if isinstance(self.frame, QtGui.QImage): alertframe = \
alertframe = QtGui.QPixmap.fromImage(self.frame) QtGui.QPixmap(self.screen[u'size'].width(), self.alertHeight)
else: alertframe.fill(QtCore.Qt.transparent)
alertframe = QtGui.QPixmap.fromImage(self.frame[u'main'])
painter = QtGui.QPainter(alertframe) painter = QtGui.QPainter(alertframe)
top = alertframe.rect().height() * 0.9 painter.fillRect(alertframe.rect(), QtCore.Qt.transparent)
painter.setRenderHint(QtGui.QPainter.Antialiasing)
painter.fillRect( painter.fillRect(
QtCore.QRect( QtCore.QRect(
0, top, alertframe.rect().width(), 0, 0, alertframe.rect().width(),
alertframe.rect().height() - top), alertframe.rect().height()),
QtGui.QColor(alertTab.bg_color)) QtGui.QColor(alertTab.bg_color))
font = QtGui.QFont() font = QtGui.QFont()
font.setFamily(alertTab.font_face) font.setFamily(alertTab.font_face)
@ -253,24 +285,23 @@ class MainDisplay(DisplayWidget):
font.setPointSize(40) font.setPointSize(40)
painter.setFont(font) painter.setFont(font)
painter.setPen(QtGui.QColor(alertTab.font_color)) painter.setPen(QtGui.QColor(alertTab.font_color))
x, y = (0, top) x, y = (0, 0)
metrics = QtGui.QFontMetrics(font) metrics = QtGui.QFontMetrics(font)
painter.drawText( painter.drawText(
x, y + metrics.height() - metrics.descent() - 1, text) x, y + metrics.height() - metrics.descent() - 1, text)
painter.end() painter.end()
self.display.setPixmap(alertframe) self.alertDisplay.setPixmap(alertframe)
self.alertDisplay.setVisible(True)
# check to see if we have a timer running # check to see if we have a timer running
if self.timer_id == 0: if self.timer_id == 0:
self.timer_id = self.startTimer(int(alertTab.timeout) * 1000) self.timer_id = self.startTimer(int(alertTab.timeout) * 1000)
def timerEvent(self, event): def timerEvent(self, event):
if event.timerId() == self.timer_id: if event.timerId() == self.timer_id:
if isinstance(self.frame, QtGui.QImage): self.alertDisplay.setPixmap(self.transparent)
self.display.setPixmap(QtGui.QPixmap.fromImage(self.frame)) self.killTimer(self.timer_id)
else: self.timer_id = 0
self.display.setPixmap(QtGui.QPixmap.fromImage(self.frame[u'main'])) self.generateAlert()
self.killTimer(self.timer_id)
self.timer_id = 0
def onMediaQueue(self, message): def onMediaQueue(self, message):
log.debug(u'Queue new media message %s' % message) log.debug(u'Queue new media message %s' % message)
@ -312,4 +343,4 @@ class MainDisplay(DisplayWidget):
self.mediaObject.clearQueue() self.mediaObject.clearQueue()
self.mediaLoaded = False self.mediaLoaded = False
self.video.setVisible(False) self.video.setVisible(False)
self.display.show() self.display.show()

View File

@ -30,7 +30,8 @@ import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from PyQt4.phonon import Phonon from PyQt4.phonon import Phonon
from openlp.core.lib import OpenLPToolbar, Receiver, str_to_bool, PluginConfig from openlp.core.lib import OpenLPToolbar, Receiver, str_to_bool, \
PluginConfig, resize_image
class SlideList(QtGui.QTableWidget): class SlideList(QtGui.QTableWidget):
""" """
@ -235,6 +236,9 @@ class SlideController(QtGui.QWidget):
self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject) self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
Phonon.createPath(self.mediaObject, self.video) Phonon.createPath(self.mediaObject, self.video)
Phonon.createPath(self.mediaObject, self.audio) Phonon.createPath(self.mediaObject, self.audio)
if not self.isLive:
self.video.setGeometry(QtCore.QRect(0, 0, 300, 225))
self.video.setVisible(False)
self.SlideLayout.insertWidget(0, self.video) self.SlideLayout.insertWidget(0, self.video)
# Actual preview screen # Actual preview screen
self.SlidePreview = QtGui.QLabel(self) self.SlidePreview = QtGui.QLabel(self)
@ -246,7 +250,8 @@ class SlideController(QtGui.QWidget):
self.SlidePreview.sizePolicy().hasHeightForWidth()) self.SlidePreview.sizePolicy().hasHeightForWidth())
self.SlidePreview.setSizePolicy(sizePolicy) self.SlidePreview.setSizePolicy(sizePolicy)
self.SlidePreview.setFixedSize( self.SlidePreview.setFixedSize(
QtCore.QSize(self.settingsmanager.slidecontroller_image,self.settingsmanager.slidecontroller_image / 1.3 )) QtCore.QSize(self.settingsmanager.slidecontroller_image,
self.settingsmanager.slidecontroller_image / 1.3 ))
self.SlidePreview.setFrameShape(QtGui.QFrame.Box) self.SlidePreview.setFrameShape(QtGui.QFrame.Box)
self.SlidePreview.setFrameShadow(QtGui.QFrame.Plain) self.SlidePreview.setFrameShadow(QtGui.QFrame.Plain)
self.SlidePreview.setLineWidth(1) self.SlidePreview.setLineWidth(1)
@ -257,8 +262,6 @@ class SlideController(QtGui.QWidget):
# Signals # Signals
QtCore.QObject.connect(self.PreviewListWidget, QtCore.QObject.connect(self.PreviewListWidget,
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected) QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
QtCore.QObject.connect(self.PreviewListWidget,
QtCore.SIGNAL(u'activated(QModelIndex)'), self.onSlideSelected)
if isLive: if isLive:
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'update_spin_delay'), self.receiveSpinDelay) QtCore.SIGNAL(u'update_spin_delay'), self.receiveSpinDelay)
@ -441,7 +444,9 @@ class SlideController(QtGui.QWidget):
else: else:
label = QtGui.QLabel() label = QtGui.QLabel()
label.setMargin(4) label.setMargin(4)
pixmap = self.parent.RenderManager.resize_image(frame[u'image']) pixmap = resize_image(frame[u'image'],
self.parent.RenderManager.width,
self.parent.RenderManager.height)
label.setScaledContents(True) label.setScaledContents(True)
label.setPixmap(QtGui.QPixmap.fromImage(pixmap)) label.setPixmap(QtGui.QPixmap.fromImage(pixmap))
self.PreviewListWidget.setCellWidget(framenumber, 0, label) self.PreviewListWidget.setCellWidget(framenumber, 0, label)
@ -487,11 +492,12 @@ class SlideController(QtGui.QWidget):
""" """
Blank the screen. Blank the screen.
""" """
if not self.serviceItem and self.serviceItem.is_command(): if self.serviceItem is not None:
if blanked: if self.serviceItem.is_command():
Receiver.send_message(u'%s_blank'% self.serviceItem.name.lower()) if blanked:
else: Receiver.send_message(u'%s_blank'% self.serviceItem.name.lower())
Receiver.send_message(u'%s_unblank'% self.serviceItem.name.lower()) else:
Receiver.send_message(u'%s_unblank'% self.serviceItem.name.lower())
else: else:
self.parent.mainDisplay.blankDisplay(blanked) self.parent.mainDisplay.blankDisplay(blanked)
@ -635,7 +641,7 @@ class SlideController(QtGui.QWidget):
if self.isLive: if self.isLive:
Receiver.send_message(u'%s_start' % item.name.lower(), \ Receiver.send_message(u'%s_start' % item.name.lower(), \
[item.title, item.service_item_path, [item.title, item.service_item_path,
item.get_frame_title(), slideno, self.isLive]) item.get_frame_title(), self.isLive])
else: else:
self.mediaObject.stop() self.mediaObject.stop()
self.mediaObject.clearQueue() self.mediaObject.clearQueue()
@ -663,5 +669,5 @@ class SlideController(QtGui.QWidget):
else: else:
self.mediaObject.stop() self.mediaObject.stop()
self.video.hide() self.video.hide()
self.SlidePreview.clear() self.SlidePreview.clear()
self.SlidePreview.show() self.SlidePreview.show()

View File

@ -61,8 +61,9 @@ class MediaMediaItem(MediaManagerItem):
def retranslateUi(self): def retranslateUi(self):
self.OnNewPrompt = self.trUtf8('Select Media') self.OnNewPrompt = self.trUtf8('Select Media')
self.OnNewFileMasks = self.trUtf8('Videos (*.avi *.mpeg *.mpg' self.OnNewFileMasks = self.trUtf8('Videos (*.avi *.mpeg *.mpg *.wmv'
'*.mp4);;Audio (*.ogg *.mp3 *.wma);;All files (*)') '*.mov *.mp4 *.flv);;Audio (*.ogg *.mp3 *.wma *.wav *.flac)'
';;All files (*)')
def requiredIcons(self): def requiredIcons(self):
MediaManagerItem.requiredIcons(self) MediaManagerItem.requiredIcons(self)
@ -84,7 +85,7 @@ class MediaMediaItem(MediaManagerItem):
for item in items: for item in items:
bitem = self.ListView.item(item.row()) bitem = self.ListView.item(item.row())
filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString()) filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString())
frame = u':/media/media_video.png' frame = u':/media/image_clapperboard.png'
(path, name) = os.path.split(filename) (path, name) = os.path.split(filename)
service_item.add_from_command(path, name, frame) service_item.add_from_command(path, name, frame)
return True return True
@ -110,4 +111,4 @@ class MediaMediaItem(MediaManagerItem):
img = self.video_get_preview() img = self.video_get_preview()
item_name.setIcon(build_icon(img)) item_name.setIcon(build_icon(img))
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file)) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
self.ListView.addItem(item_name) self.ListView.addItem(item_name)

View File

@ -169,8 +169,12 @@ class ImpressController(PresentationController):
for idx in range(pages.getCount()): for idx in range(pages.getCount()):
page = pages.getByIndex(idx) page = pages.getByIndex(idx)
doc.getCurrentController().setCurrentPage(page) doc.getCurrentController().setCurrentPage(page)
doc.storeToURL(thumbdir + u'/' + self.thumbnailprefix + path = u'%s/%s%s.png'% (thumbdir, self.thumbnailprefix,
unicode(idx+1) + u'.png', props) unicode(idx+1))
try:
doc.storeToURL(path , props)
except:
log.exception(u'%s\nUnable to store preview' % path)
def create_property(self, name, value): def create_property(self, name, value):
if os.name == u'nt': if os.name == u'nt':
@ -230,7 +234,11 @@ class ImpressController(PresentationController):
if self.presentation: if self.presentation:
self.presentation.end() self.presentation.end()
self.presentation = None self.presentation = None
self.document.dispose() try:
self.document.dispose()
except:
#We tried!
pass
self.document = None self.document = None
def is_loaded(self): def is_loaded(self):
@ -305,4 +313,4 @@ class ImpressController(PresentationController):
if os.path.isfile(path): if os.path.isfile(path):
return path return path
else: else:
return None return None

View File

@ -47,7 +47,7 @@ class Controller(object):
log.debug(u'Live = %s, addHandler %s' % (self.isLive, file)) log.debug(u'Live = %s, addHandler %s' % (self.isLive, file))
self.controller = controller self.controller = controller
if self.controller.is_loaded(): if self.controller.is_loaded():
self.shutdown(None) self.shutdown()
self.controller.load_presentation(file) self.controller.load_presentation(file)
if self.isLive: if self.isLive:
self.controller.start_presentation() self.controller.start_presentation()
@ -73,55 +73,51 @@ class Controller(object):
self.controller.goto_slide(int(slide) + 1) self.controller.goto_slide(int(slide) + 1)
self.controller.poll_slidenumber(live) self.controller.poll_slidenumber(live)
def first(self, message): def first(self):
""" """
Based on the handler passed at startup triggers the first slide Based on the handler passed at startup triggers the first slide
""" """
log.debug(u'Live = %s, first' % self.isLive) log.debug(u'Live = %s, first' % self.isLive)
print "first ", message
if not self.isLive: if not self.isLive:
return return
self.activate() self.activate()
self.controller.start_presentation() self.controller.start_presentation()
self.controller.poll_slidenumber(self.isLive) self.controller.poll_slidenumber(self.isLive)
def last(self, message): def last(self):
""" """
Based on the handler passed at startup triggers the first slide Based on the handler passed at startup triggers the first slide
""" """
log.debug(u'Live = %s, last' % self.isLive) log.debug(u'Live = %s, last' % self.isLive)
print "last ", message
if not self.isLive: if not self.isLive:
return return
self.activate() self.activate()
self.controller.goto_slide(self.controller.get_slide_count()) self.controller.goto_slide(self.controller.get_slide_count())
self.controller.poll_slidenumber(self.isLive) self.controller.poll_slidenumber(self.isLive)
def next(self, message): def next(self):
""" """
Based on the handler passed at startup triggers the next slide event Based on the handler passed at startup triggers the next slide event
""" """
log.debug(u'Live = %s, next' % self.isLive) log.debug(u'Live = %s, next' % self.isLive)
print "next ", message
if not self.isLive: if not self.isLive:
return return
self.activate() self.activate()
self.controller.next_step() self.controller.next_step()
self.controller.poll_slidenumber(self.isLive) self.controller.poll_slidenumber(self.isLive)
def previous(self, message): def previous(self):
""" """
Based on the handler passed at startup triggers the previous slide event Based on the handler passed at startup triggers the previous slide event
""" """
log.debug(u'Live = %s, previous' % self.isLive) log.debug(u'Live = %s, previous' % self.isLive)
if not self.isLive: if not self.isLive:
return return
print "previous ", message
self.activate() self.activate()
self.controller.previous_step() self.controller.previous_step()
self.controller.poll_slidenumber(self.isLive) self.controller.poll_slidenumber(self.isLive)
def shutdown(self, message): def shutdown(self):
""" """
Based on the handler passed at startup triggers slide show to shut down Based on the handler passed at startup triggers slide show to shut down
""" """
@ -159,7 +155,6 @@ class MessageListener(object):
self.controllers = controllers self.controllers = controllers
self.previewHandler = Controller(False) self.previewHandler = Controller(False)
self.liveHandler = Controller(True) self.liveHandler = Controller(True)
self.isLive = None
# messages are sent from core.ui.slidecontroller # messages are sent from core.ui.slidecontroller
QtCore.QObject.connect(Receiver.get_receiver(), QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentations_start'), self.startup) QtCore.SIGNAL(u'presentations_start'), self.startup)
@ -202,36 +197,36 @@ class MessageListener(object):
else: else:
self.previewHandler.slide(slide, live) self.previewHandler.slide(slide, live)
def first(self, message): def first(self, isLive):
if self.isLive: if isLive:
self.liveHandler.first(message) self.liveHandler.first()
else: else:
self.previewHandler.first(message) self.previewHandler.first()
def last(self, message): def last(self, isLive):
if self.isLive: if isLive:
self.liveHandler.last(message) self.liveHandler.last()
else: else:
self.previewHandler.last(message) self.previewHandler.last()
def next(self, message): def next(self, isLive):
if self.isLive: if isLive:
self.liveHandler.next(message) self.liveHandler.next()
else: else:
self.previewHandler.next(message) self.previewHandler.next()
def previous(self, message): def previous(self, isLive):
if self.isLive: if isLive:
self.liveHandler.previous(message) self.liveHandler.previous()
else: else:
self.previewHandler.previous(message) self.previewHandler.previous()
def shutdown(self, message): def shutdown(self, isLive):
if self.isLive: if isLive:
self.liveHandler.shutdown(message) self.liveHandler.shutdown()
Receiver.send_message(u'live_slide_show') Receiver.send_message(u'live_slide_show')
else: else:
self.previewHandler.shutdown(message) self.previewHandler.shutdown()
def blank(self): def blank(self):
if self.isLive: if self.isLive:
@ -268,4 +263,4 @@ class MessageListener(object):
return message[0], file, message[4] return message[0], file, message[4]
def timeout(self): def timeout(self):
self.controller.poll_slidenumber(self.is_live) self.controller.poll_slidenumber(self.is_live)

View File

@ -108,6 +108,7 @@
<file>media_video.png</file> <file>media_video.png</file>
<file>media_time.png</file> <file>media_time.png</file>
<file>media_stop.png</file> <file>media_stop.png</file>
<file>image_clapperboard.png</file>
</qresource> </qresource>
<qresource prefix="messagebox" > <qresource prefix="messagebox" >
<file>messagebox_critical.png</file> <file>messagebox_critical.png</file>