diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index b9fbcf138..b10a13cde 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -43,7 +43,8 @@ def translate(context, text): ``text`` 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): """ @@ -87,6 +88,10 @@ def buildIcon(icon): else: ButtonIcon.addPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(icon)), 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 def contextMenuAction(base, icon, text, slot): diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 7557348ca..b8e299211 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -178,8 +178,16 @@ class MediaManagerItem(QtGui.QWidget): """ # Add a toolbar self.addToolbar() - #Allow the plugin to define it's own header + #Allow the plugin to define buttons at start of bar 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 ## File Button ## 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 the selected item(s) to the service'), 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 self.ListView = self.ListViewWithDnD_class() self.ListView.uniformItemSizes = True diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index ba4adbd53..967fc6be4 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -51,9 +51,9 @@ class Renderer(object): self._theme = None self._bg_image_filename = None self._frame = None - self._bg_frame = None + self.bg_frame = None self.bg_image = None - self._bg_frame_small = None + #self.bg_frame_small = None def set_debug(self, debug): """ @@ -73,7 +73,7 @@ class Renderer(object): """ log.debug(u'set theme') self._theme = theme - self._bg_frame = None + self.bg_frame = None self.bg_image = None self.theme_name = theme.theme_name self._set_theme_font() @@ -131,14 +131,14 @@ class Renderer(object): Defaults to *False*. Whether or not to generate a preview. """ if preview == True: - self._bg_frame = None + self.bg_frame = None log.debug(u'set frame dest (frame) w %d h %d', frame_width, frame_height) self._frame = QtGui.QImage(frame_width, frame_height, QtGui.QImage.Format_ARGB32_Premultiplied) if self._bg_image_filename is not None and self.bg_image is None: self.scale_bg_image() - if self._bg_frame is None: + if self.bg_frame is None: self._generate_background_frame() def format_slide(self, words, footer): @@ -257,7 +257,7 @@ class Renderer(object): if footer_lines is not None: bbox1 = self._render_lines_unaligned(footer_lines, True) # 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) bbox = self._render_lines_unaligned(lines, False, (x, y), True) if footer_lines is not None: @@ -272,11 +272,11 @@ class Renderer(object): Results are cached for performance reasons. """ 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) log.debug(u'render background %s start', self._theme.background_type) painter = QtGui.QPainter() - painter.begin(self._bg_frame) + painter.begin(self.bg_frame) if self._theme.background_mode == u'transparent': painter.fillRect(self._frame.rect(), QtCore.Qt.transparent) else: @@ -321,8 +321,8 @@ class Renderer(object): if self.bg_image is not None: painter.drawImage(0, 0, self.bg_image) painter.end() - self._bg_frame_small = self._bg_frame.scaled(QtCore.QSize(280, 210), - QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation) +# self.bg_frame_small = self.bg_frame.scaled(QtCore.QSize(280, 210), +# QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation) log.debug(u'render background End') def _correctAlignment(self, rect, bbox): diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 60f6a0fb4..40ddbd9da 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -62,14 +62,11 @@ class ServiceItem(object): self.items = [] self.iconic_representation = None self.raw_slides = None - self.frame_titles = [] - self.command_files = [] self.frames = [] self.raw_footer = None self.theme = None self.service_item_path = None self.service_item_type = None - #log.debug(u'Service item created for %s ', self.shortname) self.service_frames = [] def addIcon(self, icon): @@ -96,12 +93,19 @@ class ServiceItem(object): self.RenderManager.set_override_theme(None) else: self.RenderManager.set_override_theme(self.theme) + firstTime = True for slide in self.service_frames: formated = self.RenderManager.format_slide(slide[u'raw_slide']) for format in formated: - frame = self.RenderManager.generate_slide(format, - self.raw_footer) - self.frames.append({u'title': slide[u'title'], + frame = None + if firstTime: + frame = self.RenderManager.generate_slide(format, + self.raw_footer) + 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}) elif self.service_item_type == ServiceType.Command: self.frames = self.service_frames @@ -113,6 +117,17 @@ class ServiceItem(object): else: 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): """ Add an image slide to the service item. @@ -128,7 +143,7 @@ class ServiceItem(object): """ self.service_item_type = ServiceType.Image 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): """ diff --git a/openlp/core/lib/settingsmanager.py b/openlp/core/lib/settingsmanager.py index 55fcaf6d2..464b42410 100644 --- a/openlp/core/lib/settingsmanager.py +++ b/openlp/core/lib/settingsmanager.py @@ -40,16 +40,18 @@ class SettingsManager(object): if mainwindow_docbars > 300: self.mainwindow_left = 300 self.mainwindow_right = 300 + else: + self.mainwindow_left = mainwindow_docbars + self.mainwindow_right = mainwindow_docbars - self.mainwindow_left = int( ConfigHelper.get_config( - u'user interface', u'mediamanager left', self.mainwindow_left)) - self.mainwindow_right = int( ConfigHelper.get_config( - u'user interface', u'mediamanager right', self.mainwindow_right)) - print self.mainwindow_left, self.mainwindow_right + #self.mainwindow_left = int( ConfigHelper.get_config( + # u'user interface', u'mediamanager left', self.mainwindow_left)) + #self.mainwindow_right = int( ConfigHelper.get_config( + # u'user interface', u'mediamanager right', 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 - print self.width, mainwindow_docbars, self.slidecontroller, self.slidecontroller_image self.showMediaManager = str_to_bool( ConfigHelper.get_config( u'user interface', u'display mediamanager', True)) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 95189da6f..f64d58af5 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -166,7 +166,7 @@ class SlideController(QtGui.QWidget): self.Toolbar.setSizePolicy(sizeToolbarPolicy) # Screen preview area 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( QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum)) self.PreviewFrame.setFrameShape(QtGui.QFrame.StyledPanel) @@ -293,12 +293,15 @@ class SlideController(QtGui.QWidget): self.PreviewListWidget.setColumnWidth(0, slide_width) for framenumber, frame in enumerate(self.serviceitem.frames): self.PreviewListWidget.setRowCount(self.PreviewListWidget.rowCount() + 1) - pixmap = self.parent.RenderManager.resize_image(frame[u'image'], slide_width, slide_height) item = QtGui.QTableWidgetItem() label = QtGui.QLabel() label.setMargin(8) - label.setScaledContents(True) - label.setPixmap(QtGui.QPixmap.fromImage(pixmap)) + if frame[u'text'] == None: + pixmap = self.parent.RenderManager.resize_image(frame[u'image'], slide_width, slide_height) + label.setScaledContents(True) + label.setPixmap(QtGui.QPixmap.fromImage(pixmap)) + else: + label.setText(frame[u'text']) self.PreviewListWidget.setCellWidget(framenumber, 0, label) self.PreviewListWidget.setItem(framenumber, 0, item) self.PreviewListWidget.setRowHeight(framenumber, slide_height) @@ -336,9 +339,12 @@ class SlideController(QtGui.QWidget): row = self.PreviewListWidget.currentRow() if row > -1 and row < self.PreviewListWidget.rowCount(): label = self.PreviewListWidget.cellWidget(row, 0) - smallframe = label.pixmap() 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: self.parent.mainDisplay.frameView(frame) diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index 8b95d2eb8..ca82ff956 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -28,16 +28,16 @@ import tempfile try: import gst except: + NOGST = True log = logging.getLogger(u'MediaMediaItemSetup') log.warning(u'Can\'t generate Videos previews - import gst failed'); 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 FileListData -from openlp.core.lib import MediaManagerItem, ServiceItem, translate, BaseListWithDnD, buildIcon +from openlp.plugins.media.lib import MediaTab, FileListData class MediaListView(BaseListWithDnD): def __init__(self, parent=None): @@ -70,38 +70,50 @@ class MediaMediaItem(MediaManagerItem): MediaManagerItem.__init__(self, parent, icon, title) def video_get_preview(self, filename): - """Gets a preview of the first frame of a video file using - GSTREAMER (non-portable??? - Can't figure out how to do with - Phonon - returns a QImage""" - try: - # Define your pipeline, just as you would at the command prompt. - # This is much easier than trying to create and link 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)) - outfile=tempfile.NamedTemporaryFile(suffix='.png') - cmd=u'filesrc location="%s" ! decodebin ! ffmpegcolorspace ! pngenc ! filesink location="%s"'% (filename, outfile.name) - pipe = gst.parse_launch(cmd) - # Get a reference to the pipeline's bus - bus = pipe.get_bus() + if NOGST: + # + # 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: + # Define your pipeline, just as you would at the command + # prompt. This is much easier than trying to create and link + # 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)) + outfile = tempfile.NamedTemporaryFile(suffix='.png') + cmd = u'filesrc location="%s" ! decodebin ! ffmpegcolorspace ! pngenc ! filesink location="%s"'% (filename, outfile.name) + pipe = gst.parse_launch(cmd) + # Get a reference to the pipeline's bus + bus = pipe.get_bus() - # Set the pipeline's state to PLAYING - pipe.set_state(gst.STATE_PLAYING) + # Set the pipeline's state to PLAYING + pipe.set_state(gst.STATE_PLAYING) - # Listen to the pipeline's bus indefinitely until we receive a EOS (end of stream) message. - # This is a super important step, or the pipeline might not work as expected. For example, - # in 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) - img = QtGui.QImage(outfile.name) - outfile.close() + # Listen to the pipeline's bus indefinitely until we receive a + # EOS (end of stream) message. This is a super important step, + # or the pipeline might not work as expected. For example, in + # 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) + img = QtGui.QImage(outfile.name) + outfile.close() # os.unlink(outfile.name) - pipe.set_state(gst.STATE_NULL) - return img - except: - log.info("Can't generate video preview for some reason"); - import sys - print sys.exc_info() - return None + pipe.set_state(gst.STATE_NULL) + return img + except: + log.info("Can't generate video preview for some reason"); + return None def generateSlideData(self, service_item): indexes = self.ListView.selectedIndexes() @@ -127,7 +139,8 @@ class MediaMediaItem(MediaManagerItem): pass def initialise(self): - self.ListView.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) + self.ListView.setSelectionMode( + QtGui.QAbstractItemView.ExtendedSelection) self.ListView.setIconSize(QtCore.QSize(88,50)) 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] row = self.ListView.row(item) 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): for file in list: (path, filename) = os.path.split(unicode(file)) item_name = QtGui.QListWidgetItem(filename) 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)) self.ListView.addItem(item_name) diff --git a/resources/images/openlp-2.qrc b/resources/images/openlp-2.qrc index 83c88c3e5..096c27dfe 100644 --- a/resources/images/openlp-2.qrc +++ b/resources/images/openlp-2.qrc @@ -49,6 +49,10 @@ import_remove.png import_load.png + + audit_start.png + audit_stop.png + export_selectall.png export_remove.png