This commit is contained in:
Tim Bentley 2009-09-16 05:59:38 +01:00
commit 74ac4adfe4
8 changed files with 124 additions and 70 deletions

View File

@ -43,7 +43,8 @@ def translate(context, text):
``text`` ``text``
The text to put into the translation tables for translation. The text to put into the translation tables for translation.
""" """
return QtGui.QApplication.translate(context, text, None, QtGui.QApplication.UnicodeUTF8) return QtGui.QApplication.translate(context, text, None,
QtGui.QApplication.UnicodeUTF8)
def file_to_xml(xmlfile): def file_to_xml(xmlfile):
""" """
@ -87,6 +88,10 @@ def buildIcon(icon):
else: else:
ButtonIcon.addPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(icon)), ButtonIcon.addPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(icon)),
QtGui.QIcon.Normal, QtGui.QIcon.Off) QtGui.QIcon.Normal, QtGui.QIcon.Off)
elif type(icon) is QtGui.QImage:
ButtonIcon = QtGui.QIcon()
ButtonIcon.addPixmap(QtGui.QPixmap.fromImage(icon),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
return ButtonIcon return ButtonIcon
def contextMenuAction(base, icon, text, slot): def contextMenuAction(base, icon, text, slot):

View File

@ -178,8 +178,16 @@ class MediaManagerItem(QtGui.QWidget):
""" """
# Add a toolbar # Add a toolbar
self.addToolbar() self.addToolbar()
#Allow the plugin to define it's own header #Allow the plugin to define buttons at start of bar
self.addStartHeaderBar() self.addStartHeaderBar()
#Add the middle of the tool bar (pre defined)
self.addMiddleHeaderBar()
#Allow the plugin to define buttons at end of bar
self.addEndHeaderBar()
#Add the list view
self.addListViewToToolBar()
def addMiddleHeaderBar(self):
# Create buttons for the toolbar # Create buttons for the toolbar
## File Button ## ## File Button ##
if self.hasFileIcon: if self.hasFileIcon:
@ -221,8 +229,8 @@ class MediaManagerItem(QtGui.QWidget):
translate(self.TranslationContext, u'Add '+self.PluginTextShort+u' To Service'), translate(self.TranslationContext, u'Add '+self.PluginTextShort+u' To Service'),
translate(self.TranslationContext, u'Add the selected item(s) to the service'), translate(self.TranslationContext, u'Add the selected item(s) to the service'),
u':/system/system_add.png', self.onAddClick, self.PluginTextShort+u'AddItem') u':/system/system_add.png', self.onAddClick, self.PluginTextShort+u'AddItem')
#Allow the plugin to define it's own header
self.addEndHeaderBar() def addListViewToToolBar(self):
#Add the List widget #Add the List widget
self.ListView = self.ListViewWithDnD_class() self.ListView = self.ListViewWithDnD_class()
self.ListView.uniformItemSizes = True self.ListView.uniformItemSizes = True

View File

@ -51,9 +51,9 @@ class Renderer(object):
self._theme = None self._theme = None
self._bg_image_filename = None self._bg_image_filename = None
self._frame = None self._frame = None
self._bg_frame = None self.bg_frame = None
self.bg_image = None self.bg_image = None
self._bg_frame_small = None #self.bg_frame_small = None
def set_debug(self, debug): def set_debug(self, debug):
""" """
@ -73,7 +73,7 @@ class Renderer(object):
""" """
log.debug(u'set theme') log.debug(u'set theme')
self._theme = theme self._theme = theme
self._bg_frame = None self.bg_frame = None
self.bg_image = None self.bg_image = None
self.theme_name = theme.theme_name self.theme_name = theme.theme_name
self._set_theme_font() self._set_theme_font()
@ -131,14 +131,14 @@ class Renderer(object):
Defaults to *False*. Whether or not to generate a preview. Defaults to *False*. Whether or not to generate a preview.
""" """
if preview == True: if preview == True:
self._bg_frame = None self.bg_frame = None
log.debug(u'set frame dest (frame) w %d h %d', frame_width, log.debug(u'set frame dest (frame) w %d h %d', frame_width,
frame_height) frame_height)
self._frame = QtGui.QImage(frame_width, frame_height, self._frame = QtGui.QImage(frame_width, frame_height,
QtGui.QImage.Format_ARGB32_Premultiplied) QtGui.QImage.Format_ARGB32_Premultiplied)
if self._bg_image_filename is not None and self.bg_image is None: if self._bg_image_filename is not None and self.bg_image is None:
self.scale_bg_image() self.scale_bg_image()
if self._bg_frame is None: if self.bg_frame is None:
self._generate_background_frame() self._generate_background_frame()
def format_slide(self, words, footer): def format_slide(self, words, footer):
@ -257,7 +257,7 @@ class Renderer(object):
if footer_lines is not None: if footer_lines is not None:
bbox1 = self._render_lines_unaligned(footer_lines, True) bbox1 = self._render_lines_unaligned(footer_lines, True)
# reset the frame. first time do not worry about what you paint on. # reset the frame. first time do not worry about what you paint on.
self._frame = QtGui.QImage(self._bg_frame) self._frame = QtGui.QImage(self.bg_frame)
x, y = self._correctAlignment(self._rect, bbox) x, y = self._correctAlignment(self._rect, bbox)
bbox = self._render_lines_unaligned(lines, False, (x, y), True) bbox = self._render_lines_unaligned(lines, False, (x, y), True)
if footer_lines is not None: if footer_lines is not None:
@ -272,11 +272,11 @@ 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(), self.bg_frame = QtGui.QImage(self._frame.width(), self._frame.height(),
QtGui.QImage.Format_ARGB32_Premultiplied) 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)
if self._theme.background_mode == u'transparent': if self._theme.background_mode == u'transparent':
painter.fillRect(self._frame.rect(), QtCore.Qt.transparent) painter.fillRect(self._frame.rect(), QtCore.Qt.transparent)
else: else:
@ -321,8 +321,8 @@ class Renderer(object):
if self.bg_image is not None: if self.bg_image is not None:
painter.drawImage(0, 0, self.bg_image) painter.drawImage(0, 0, self.bg_image)
painter.end() painter.end()
self._bg_frame_small = self._bg_frame.scaled(QtCore.QSize(280, 210), # self.bg_frame_small = self.bg_frame.scaled(QtCore.QSize(280, 210),
QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation) # QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
log.debug(u'render background End') log.debug(u'render background End')
def _correctAlignment(self, rect, bbox): def _correctAlignment(self, rect, bbox):

View File

@ -62,14 +62,11 @@ class ServiceItem(object):
self.items = [] self.items = []
self.iconic_representation = None self.iconic_representation = None
self.raw_slides = None self.raw_slides = None
self.frame_titles = []
self.command_files = []
self.frames = [] self.frames = []
self.raw_footer = None self.raw_footer = None
self.theme = None self.theme = None
self.service_item_path = None self.service_item_path = None
self.service_item_type = None self.service_item_type = None
#log.debug(u'Service item created for %s ', self.shortname)
self.service_frames = [] self.service_frames = []
def addIcon(self, icon): def addIcon(self, icon):
@ -96,12 +93,19 @@ class ServiceItem(object):
self.RenderManager.set_override_theme(None) self.RenderManager.set_override_theme(None)
else: else:
self.RenderManager.set_override_theme(self.theme) self.RenderManager.set_override_theme(self.theme)
firstTime = True
for slide in self.service_frames: for slide in self.service_frames:
formated = self.RenderManager.format_slide(slide[u'raw_slide']) formated = self.RenderManager.format_slide(slide[u'raw_slide'])
for format in formated: for format in formated:
frame = None
if firstTime:
frame = self.RenderManager.generate_slide(format, frame = self.RenderManager.generate_slide(format,
self.raw_footer) self.raw_footer)
self.frames.append({u'title': slide[u'title'], firstTime = False
lines = u''
for line in format:
lines += line + u'\n'
self.frames.append({u'title': slide[u'title'],u'text':lines,
u'image': frame}) u'image': frame})
elif self.service_item_type == ServiceType.Command: elif self.service_item_type == ServiceType.Command:
self.frames = self.service_frames self.frames = self.service_frames
@ -113,6 +117,17 @@ class ServiceItem(object):
else: else:
log.error(u'Invalid value renderer :%s' % self.service_item_type) log.error(u'Invalid value renderer :%s' % self.service_item_type)
def render_individual(self, row):
log.debug(u'render individual')
if self.theme == None:
self.RenderManager.set_override_theme(None)
else:
self.RenderManager.set_override_theme(self.theme)
format = self.frames[row][u'text'].split(u'\n')
frame = self.RenderManager.generate_slide(format,
self.raw_footer)
return frame
def add_from_image(self, path, frame_title, image): def add_from_image(self, path, frame_title, image):
""" """
Add an image slide to the service item. Add an image slide to the service item.
@ -128,7 +143,7 @@ class ServiceItem(object):
""" """
self.service_item_type = ServiceType.Image self.service_item_type = ServiceType.Image
self.service_item_path = path self.service_item_path = path
self.service_frames.append({u'title': frame_title, u'image': image}) self.service_frames.append({u'title': frame_title, u'text':None, u'image': image})
def add_from_text(self, frame_title, raw_slide): def add_from_text(self, frame_title, raw_slide):
""" """

View File

@ -40,16 +40,18 @@ class SettingsManager(object):
if mainwindow_docbars > 300: if mainwindow_docbars > 300:
self.mainwindow_left = 300 self.mainwindow_left = 300
self.mainwindow_right = 300 self.mainwindow_right = 300
else:
self.mainwindow_left = mainwindow_docbars
self.mainwindow_right = mainwindow_docbars
self.mainwindow_left = int( ConfigHelper.get_config( #self.mainwindow_left = int( ConfigHelper.get_config(
u'user interface', u'mediamanager left', self.mainwindow_left)) # u'user interface', u'mediamanager left', self.mainwindow_left))
self.mainwindow_right = int( ConfigHelper.get_config( #self.mainwindow_right = int( ConfigHelper.get_config(
u'user interface', u'mediamanager right', self.mainwindow_right)) # u'user interface', u'mediamanager right', self.mainwindow_right))
print self.mainwindow_left, self.mainwindow_right
self.slidecontroller = (self.width - (self.mainwindow_left + self.mainwindow_right) - 100 ) / 2 self.slidecontroller = (self.width - (
self.mainwindow_left + self.mainwindow_right) - 100 ) / 2
self.slidecontroller_image = self.slidecontroller - 50 self.slidecontroller_image = self.slidecontroller - 50
print self.width, mainwindow_docbars, self.slidecontroller, self.slidecontroller_image
self.showMediaManager = str_to_bool( ConfigHelper.get_config( self.showMediaManager = str_to_bool( ConfigHelper.get_config(
u'user interface', u'display mediamanager', True)) u'user interface', u'display mediamanager', True))

View File

@ -166,7 +166,7 @@ class SlideController(QtGui.QWidget):
self.Toolbar.setSizePolicy(sizeToolbarPolicy) self.Toolbar.setSizePolicy(sizeToolbarPolicy)
# Screen preview area # Screen preview area
self.PreviewFrame = QtGui.QFrame(self.Splitter) self.PreviewFrame = QtGui.QFrame(self.Splitter)
self.PreviewFrame.setGeometry(QtCore.QRect(0, 0, self.settingsmanager.slidecontroller_image, 225)) self.PreviewFrame.setGeometry(QtCore.QRect(0, 0, 300, 225))
self.PreviewFrame.setSizePolicy(QtGui.QSizePolicy( self.PreviewFrame.setSizePolicy(QtGui.QSizePolicy(
QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum)) QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum))
self.PreviewFrame.setFrameShape(QtGui.QFrame.StyledPanel) self.PreviewFrame.setFrameShape(QtGui.QFrame.StyledPanel)
@ -293,12 +293,15 @@ class SlideController(QtGui.QWidget):
self.PreviewListWidget.setColumnWidth(0, slide_width) self.PreviewListWidget.setColumnWidth(0, slide_width)
for framenumber, frame in enumerate(self.serviceitem.frames): for framenumber, frame in enumerate(self.serviceitem.frames):
self.PreviewListWidget.setRowCount(self.PreviewListWidget.rowCount() + 1) self.PreviewListWidget.setRowCount(self.PreviewListWidget.rowCount() + 1)
pixmap = self.parent.RenderManager.resize_image(frame[u'image'], slide_width, slide_height)
item = QtGui.QTableWidgetItem() item = QtGui.QTableWidgetItem()
label = QtGui.QLabel() label = QtGui.QLabel()
label.setMargin(8) label.setMargin(8)
if frame[u'text'] == None:
pixmap = self.parent.RenderManager.resize_image(frame[u'image'], slide_width, slide_height)
label.setScaledContents(True) label.setScaledContents(True)
label.setPixmap(QtGui.QPixmap.fromImage(pixmap)) label.setPixmap(QtGui.QPixmap.fromImage(pixmap))
else:
label.setText(frame[u'text'])
self.PreviewListWidget.setCellWidget(framenumber, 0, label) self.PreviewListWidget.setCellWidget(framenumber, 0, label)
self.PreviewListWidget.setItem(framenumber, 0, item) self.PreviewListWidget.setItem(framenumber, 0, item)
self.PreviewListWidget.setRowHeight(framenumber, slide_height) self.PreviewListWidget.setRowHeight(framenumber, slide_height)
@ -336,9 +339,12 @@ class SlideController(QtGui.QWidget):
row = self.PreviewListWidget.currentRow() row = self.PreviewListWidget.currentRow()
if row > -1 and row < self.PreviewListWidget.rowCount(): if row > -1 and row < self.PreviewListWidget.rowCount():
label = self.PreviewListWidget.cellWidget(row, 0) label = self.PreviewListWidget.cellWidget(row, 0)
smallframe = label.pixmap()
frame = self.serviceitem.frames[row][u'image'] frame = self.serviceitem.frames[row][u'image']
self.SlidePreview.setPixmap(smallframe) before = time.time()
if frame == None:
frame = self.serviceitem.render_individual(row)
self.SlidePreview.setPixmap(QtGui.QPixmap.fromImage(frame))
log.info(u'Slide Rendering took %4s' % (time.time() - before))
if self.isLive: if self.isLive:
self.parent.mainDisplay.frameView(frame) self.parent.mainDisplay.frameView(frame)

View File

@ -28,16 +28,16 @@ import tempfile
try: try:
import gst import gst
except: except:
NOGST = True
log = logging.getLogger(u'MediaMediaItemSetup') log = logging.getLogger(u'MediaMediaItemSetup')
log.warning(u'Can\'t generate Videos previews - import gst failed'); log.warning(u'Can\'t generate Videos previews - import gst failed');
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, translate from openlp.core.lib import MediaManagerItem, ServiceItem, translate, \
BaseListWithDnD, buildIcon
from openlp.plugins.media.lib import MediaTab from openlp.plugins.media.lib import MediaTab, FileListData
from openlp.plugins.media.lib import FileListData
from openlp.core.lib import MediaManagerItem, ServiceItem, translate, BaseListWithDnD, buildIcon
class MediaListView(BaseListWithDnD): class MediaListView(BaseListWithDnD):
def __init__(self, parent=None): def __init__(self, parent=None):
@ -70,16 +70,28 @@ class MediaMediaItem(MediaManagerItem):
MediaManagerItem.__init__(self, parent, icon, title) MediaManagerItem.__init__(self, parent, icon, title)
def video_get_preview(self, filename): def video_get_preview(self, filename):
"""Gets a preview of the first frame of a video file using if NOGST:
GSTREAMER (non-portable??? - Can't figure out how to do with #
Phonon - returns a QImage""" # For now cross platform is an icon. Phonon does not support
# individual frame access (yet?) and GStreamer is not available
# on Windows
#
image = QtGui.QPixmap(u':/media/media_video.png').toImage()
return image
else:
"""
Gets a preview of the first frame of a video file using GSTREAMER
(non-portable) - returns a QImage
"""
try: try:
# Define your pipeline, just as you would at the command prompt. # Define your pipeline, just as you would at the command
# This is much easier than trying to create and link each gstreamer element in Python. # prompt. This is much easier than trying to create and link
# This is great for pipelines that end with a filesink (i.e. there is no audible or visual output) # each gstreamer element in Python. This is great for
# pipelines that end with a filesink (i.e. there is no audible
# or visual output)
log.info ("Video preview %s"%( filename)) log.info ("Video preview %s"%( filename))
outfile=tempfile.NamedTemporaryFile(suffix='.png') outfile = tempfile.NamedTemporaryFile(suffix='.png')
cmd=u'filesrc location="%s" ! decodebin ! ffmpegcolorspace ! pngenc ! filesink location="%s"'% (filename, outfile.name) cmd = u'filesrc location="%s" ! decodebin ! ffmpegcolorspace ! pngenc ! filesink location="%s"'% (filename, outfile.name)
pipe = gst.parse_launch(cmd) pipe = gst.parse_launch(cmd)
# Get a reference to the pipeline's bus # Get a reference to the pipeline's bus
bus = pipe.get_bus() bus = pipe.get_bus()
@ -87,10 +99,12 @@ class MediaMediaItem(MediaManagerItem):
# Set the pipeline's state to PLAYING # Set the pipeline's state to PLAYING
pipe.set_state(gst.STATE_PLAYING) pipe.set_state(gst.STATE_PLAYING)
# Listen to the pipeline's bus indefinitely until we receive a EOS (end of stream) message. # Listen to the pipeline's bus indefinitely until we receive a
# This is a super important step, or the pipeline might not work as expected. For example, # EOS (end of stream) message. This is a super important step,
# in my example pipeline above, the pngenc will not export an actual image unless you have # or the pipeline might not work as expected. For example, in
# this line of code. It just exports a 0 byte png file. So... don't forget this step. # my example pipeline above, the pngenc will not export an
# actual image unless you have this line of code. It just
# exports a 0 byte png file. So... don't forget this step.
bus.poll(gst.MESSAGE_EOS, -1) bus.poll(gst.MESSAGE_EOS, -1)
img = QtGui.QImage(outfile.name) img = QtGui.QImage(outfile.name)
outfile.close() outfile.close()
@ -99,8 +113,6 @@ class MediaMediaItem(MediaManagerItem):
return img return img
except: except:
log.info("Can't generate video preview for some reason"); log.info("Can't generate video preview for some reason");
import sys
print sys.exc_info()
return None return None
def generateSlideData(self, service_item): def generateSlideData(self, service_item):
@ -127,7 +139,8 @@ class MediaMediaItem(MediaManagerItem):
pass pass
def initialise(self): def initialise(self):
self.ListView.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) self.ListView.setSelectionMode(
QtGui.QAbstractItemView.ExtendedSelection)
self.ListView.setIconSize(QtCore.QSize(88,50)) self.ListView.setIconSize(QtCore.QSize(88,50))
self.loadList(self.parent.config.load_list(self.ConfigSection)) self.loadList(self.parent.config.load_list(self.ConfigSection))
@ -137,14 +150,15 @@ class MediaMediaItem(MediaManagerItem):
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
row = self.ListView.row(item) row = self.ListView.row(item)
self.ListView.takeItem(row) self.ListView.takeItem(row)
self.parent.config.set_list(self.ConfigSection, self.ListData.getFileList()) self.parent.config.set_list(
self.ConfigSection, self.ListData.getFileList())
def loadList(self, list): def loadList(self, list):
for file in list: for file in list:
(path, filename) = os.path.split(unicode(file)) (path, filename) = os.path.split(unicode(file))
item_name = QtGui.QListWidgetItem(filename) item_name = QtGui.QListWidgetItem(filename)
img = self.video_get_preview(file) img = self.video_get_preview(file)
#item_name.setIcon(buildIcon(file)) item_name.setIcon(buildIcon(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

@ -49,6 +49,10 @@
<file>import_remove.png</file> <file>import_remove.png</file>
<file>import_load.png</file> <file>import_load.png</file>
</qresource> </qresource>
<qresource prefix="audit" >
<file>audit_start.png</file>
<file>audit_stop.png</file>
</qresource>
<qresource prefix="exports" > <qresource prefix="exports" >
<file>export_selectall.png</file> <file>export_selectall.png</file>
<file>export_remove.png</file> <file>export_remove.png</file>