← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~mjthompson/openlp/mediamgr_refactor into lp:openlp

 

Martin Thompson has proposed merging lp:~mjthompson/openlp/mediamgr_refactor into lp:openlp.

Requested reviews:
    openlp.org Core (openlp-core)

Pulled all the media manager setup code from the Image plugin into the MediaManagerItem base class. It doesn't have to be reused by any plugins which inherit from it, but it has some advantages if you do.  In fact, the Bible and Song plugins I have left alone still work as they did before.  But I think some of their setupui code could be removed and replaced with a suitable call to the base class.
Also pulled some drag and drop handling code into the Plugin class, and created a base class for lists with DnD support

-- 
https://code.launchpad.net/~mjthompson/openlp/mediamgr_refactor/+merge/7861
Your team openlp.org Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/lib/__init__.py'
--- openlp/core/lib/__init__.py	2009-06-16 18:21:24 +0000
+++ openlp/core/lib/__init__.py	2009-06-24 20:15:24 +0000
@@ -74,5 +74,10 @@
 from themexmlhandler import ThemeXML
 from renderer import Renderer
 from rendermanager import RenderManager
+from mediamanageritem import MediaManagerItem
+from baselistwithdnd import BaseListWithDnD 
+from listwithpreviews import ListWithPreviews
 
-__all__ = [ 'translate', 'file_to_xml', 'str_to_bool', 'contextMenuAction', 'contextMenuSeparator']
+__all__ = [ 'translate', 'file_to_xml', 'str_to_bool',
+            'contextMenuAction', 'contextMenuSeparator','ServiceItem'
+]

=== added file 'openlp/core/lib/baselistwithdnd.py'
--- openlp/core/lib/baselistwithdnd.py	1970-01-01 00:00:00 +0000
+++ openlp/core/lib/baselistwithdnd.py	2009-06-24 20:15:24 +0000
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+"""
+OpenLP - Open Source Lyrics Projection
+Copyright (c) 2008-2009 Raoul Snyman
+Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+import types
+
+from PyQt4 import QtCore, QtGui
+from openlp.core.lib.toolbar import *
+from openlp.core.lib import translate
+
+class BaseListWithDnD(QtGui.QListView):
+
+    def __init__(self,parent=None):
+        QtGui.QListView.__init__(self,parent)
+        assert (self.PluginName) # this must be set by the class which is inheriting
+    def mouseMoveEvent(self, event):
+        """
+        Drag and drop event does not care what data is selected
+        as the recipient will use events to request the data move
+        just tell it what plugin to call
+        """
+        if event.buttons() != QtCore.Qt.LeftButton:
+            return
+        drag = QtGui.QDrag(self)
+        mimeData = QtCore.QMimeData()
+        drag.setMimeData(mimeData)
+        mimeData.setText(self.PluginName)
+        dropAction = drag.start(QtCore.Qt.CopyAction)
+        if dropAction == QtCore.Qt.CopyAction:
+            self.close()
+
+

=== renamed file 'openlp/plugins/images/lib/listwithpreviews.py' => 'openlp/core/lib/listwithpreviews.py'
--- openlp/plugins/images/lib/listwithpreviews.py	2009-06-20 10:44:12 +0000
+++ openlp/core/lib/listwithpreviews.py	2009-06-23 20:59:38 +0000
@@ -29,12 +29,36 @@
     log = logging.getLogger(u'ListWithPreviews')
     log.info(u'started')
 
-    def __init__(self):
+    def __init__(self, new_preview_function=None):
         QtCore.QAbstractListModel.__init__(self)
         # will be a list of (full filename, QPixmap, shortname) tuples
         self.items = []
         self.rowheight = 50
         self.maximagewidth = self.rowheight * 16 / 9.0;
+        if new_preview_function is not None:
+            self.make_preview=new_preview_function
+        else:
+            self.make_preview=self.preview_function
+        
+    def preview_function(self, filename):
+        if os.path.exists(filename):
+            preview = QtGui.QImage(filename)
+            w = self.maximagewidth;
+            h = self.rowheight
+            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
+            p = QtGui.QImage(w, h, QtGui.QImage.Format_ARGB32_Premultiplied)
+            p.fill(QtCore.Qt.transparent)
+            painter = QtGui.QPainter(p)
+            painter.drawImage((w-realw) / 2 , (h-realh) / 2, preview)
+        else:
+            w = self.maximagewidth;
+            h = self.rowheight
+            p = QtGui.QImage(w, h, QtGui.QImage.Format_ARGB32_Premultiplied)
+            p.fill(QtCore.Qt.transparent)
+        return p
 
     def rowCount(self, parent):
         return len(self.items)
@@ -47,23 +71,7 @@
         (prefix, shortfilename) = os.path.split(filename)
         #log.info(u'shortfilename=%s' % (shortfilename))
         # create a preview image
-        if os.path.exists(filename):
-            preview = QtGui.QImage(filename)
-            w = self.maximagewidth;
-            h = self.rowheight
-            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
-            p = QtGui.QImage(w, h, QtGui.QImage.Format_ARGB32_Premultiplied)
-            p.fill(QtCore.Qt.transparent)
-            painter = QtGui.QPainter(p)
-            painter.drawImage((w-realw) / 2 , (h-realh) / 2, preview)
-        else:
-            w = self.maximagewidth;
-            h = self.rowheight
-            p = QtGui.QImage(w, h, QtGui.QImage.Format_ARGB32_Premultiplied)
-            p.fill(QtCore.Qt.transparent)
+        p=self.make_preview(filename)
         # finally create the row
         self.items.insert(row, (filename, p, shortfilename))
         self.endInsertRows()

=== modified file 'openlp/core/lib/mediamanageritem.py'
--- openlp/core/lib/mediamanageritem.py	2009-06-07 16:33:33 +0000
+++ openlp/core/lib/mediamanageritem.py	2009-06-24 20:15:24 +0000
@@ -21,11 +21,18 @@
 
 from PyQt4 import QtCore, QtGui
 from openlp.core.lib.toolbar import *
-
+from openlp.core.lib import translate
+from imagelist import ImageList
+from listwithpreviews import ListWithPreviews
+from serviceitem import ServiceItem
 class MediaManagerItem(QtGui.QWidget):
     """
     MediaManagerItem is a helper widget for plugins.
     """
+    global log
+    log = logging.getLogger(u'MediaManagerItem')
+    log.info(u'Media Item loaded')
+
     def __init__(self, parent=None, icon=None, title=None):
         """
         Constructor to create the media manager item.
@@ -49,15 +56,9 @@
         self.retranslateUi()
         self.initialise()
 
-    def setupUi(self):
-        pass
-
     def retranslateUi(self):
         pass
 
-    def initialise(self):
-        pass
-
     def addToolbar(self):
         """
         A method to help developers easily add a toolbar to the media manager
@@ -106,3 +107,138 @@
         QtCore.QObject.connect(action, QtCore.SIGNAL(u'triggered()'), slot)
         return action
 
+####################################################################################################
+    ### None of the following *need* to be used, feel free to override
+    ### them cmopletely in your plugin's implementation.  Alternatively, call them from your
+    ### plugin before or after you've done etra things that you need to.
+    ### in order for them to work, you need to have setup
+    # self.TranslationContext
+    # self.PluginTextShort # eg "Image" for the image plugin
+    # self.ConfigSection - where the items in the media manager are stored
+    #   this could potentially be self.PluginTextShort.lower()
+    #
+    # self.OnNewPrompt=u'Select Image(s)'
+    # self.OnNewFileMasks=u'Images (*.jpg *jpeg *.gif *.png *.bmp)'
+    #   assumes that the new action is to load a file. If not, override onnew
+    # self.ListViewWithDnD_class - there is a base list class with DnD assigned to it (openlp.core.lib.BaseListWithDnD())
+    # each plugin needs to inherit a class from this and pass that *class* (not an instance) to here
+    # via the ListViewWithDnD_class member
+    # The assumption is that given that at least two plugins are of the form
+    # "text with an icon" then all this will help
+    # even for plugins of another sort, the setup of the right-click menu, common toolbar
+    # will help to keep things consistent and ease the creation of new plugins
+    
+    # also a set of completely consistent action anesm then exist
+    # (onPreviewClick() is always called that, rather than having the
+    # name of the plugin added in as well... I regard that as a
+    # feature, I guess others might differ!)
+    
+    def setupUi(self):
+        # Add a toolbar
+        self.addToolbar()
+        # Create buttons for the toolbar
+        ## New Song Button ##
+        self.addToolbarButton(
+            translate(self.TranslationContext, u'Load '+self.PluginTextShort),
+            translate(self.TranslationContext, u'Load item into openlp.org'),
+            u':/images/image_load.png', self.onNewClick, u'ImageNewItem')
+        ## Delete Song Button ##
+        self.addToolbarButton(
+            translate(self.TranslationContext, u'Delete '+self.PluginTextShort),
+            translate(self.TranslationContext, u'Delete the selected item'),
+            u':/images/image_delete.png', self.onDeleteClick, u'DeleteItem')
+        ## Separator Line ##
+        self.addToolbarSeparator()
+        ## Preview  Button ##
+        self.addToolbarButton(
+            translate(self.TranslationContext, u'Preview '+self.PluginTextShort),
+            translate(self.TranslationContext, u'Preview the selected item'),
+            u':/system/system_preview.png', self.onPreviewClick, u'PreviewItem')
+        ## Live  Button ##
+        self.addToolbarButton(
+            translate(self.TranslationContext, u'Go Live'),
+            translate(self.TranslationContext, u'Send the selected item live'),
+            u':/system/system_live.png', self.onLiveClick, u'LiveItem')
+        ## Add  Button ##
+        self.addToolbarButton(
+            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')
+        #Add the List widget
+        self.ListView = self.ListViewWithDnD_class()
+        self.ListView.uniformItemSizes = True
+        self.ListData = ListWithPreviews()
+        self.ListView.setModel(self.ListData)
+        self.ListView.setGeometry(QtCore.QRect(10, 100, 256, 591))
+        self.ListView.setSpacing(1)
+        self.ListView.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
+        self.ListView.setAlternatingRowColors(True)
+        self.ListView.setDragEnabled(True)
+        self.ListView.setObjectName(self.PluginTextShort+u'ListView')
+        self.PageLayout.addWidget(self.ListView)
+        #define and add the context menu
+        self.ListView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
+        self.ListView.addAction(self.contextMenuAction(
+            self.ListView, ':/system/system_preview.png',
+            translate(self.TranslationContext, u'&Preview '+self.PluginTextShort),
+            self.onPreviewClick))
+        self.ListView.addAction(self.contextMenuAction(
+            self.ListView, ':/system/system_live.png',
+            translate(self.TranslationContext, u'&Show Live'),
+            self.onLiveClick))
+        self.ListView.addAction(self.contextMenuAction(
+            self.ListView, ':/system/system_add.png',
+            translate(self.TranslationContext, u'&Add to Service'),
+            self.onAddClick))
+        QtCore.QObject.connect(self.ListView,
+           QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onPreviewClick)
+
+    def initialise(self):
+        self.loadList(self.parent.config.load_list(self.ConfigSection))
+
+    def onNewClick(self):
+        files = QtGui.QFileDialog.getOpenFileNames(None,
+            translate(self.TranslationContext, self.OnNewPrompt),
+            self.parent.config.get_last_dir(),
+            self.OnNewFileMasks)
+        log.info(u'New files(s)', unicode(files))
+        if len(files) > 0:
+            self.loadList(files)
+            dir, filename = os.path.split(unicode(files[0]))
+            self.parent.config.set_last_dir(dir)
+            self.parent.config.set_list(self.ConfigSection, self.ListData.getFileList())
+
+    def loadList(self, list):
+        for file in list:
+            self.ListData.addRow(file)
+
+    def onDeleteClick(self):
+        indexes = self.ListView.selectedIndexes()
+        for index in indexes:
+            current_row = int(index.row())
+            self.ListData.removeRow(current_row)
+        self.parent.config.set_list(self.ConfigSection, self.ListData.getFileList())
+
+    def generateSlideData(self):
+        assert (0, 'This fn needs to be defined by the plugin');
+
+    def onPreviewClick(self):
+        log.debug(self.PluginTextShort+u'Preview Requested')
+        service_item = ServiceItem(self.parent)
+        service_item.addIcon(u':/media/media_image.png')
+        self.generateSlideData(service_item)
+        self.parent.preview_controller.addServiceItem(service_item)
+
+    def onLiveClick(self):
+        log.debug(self.PluginTextShort+u' Live Requested')
+        service_item = ServiceItem(self.parent)
+        service_item.addIcon(u':/media/media_image.png')
+        self.generateSlideData(service_item)
+        self.parent.live_controller.addServiceItem(service_item)
+
+    def onAddClick(self):
+        log.debug(self.PluginTextShort+u' Add Requested')
+        service_item = ServiceItem(self.parent)
+        service_item.addIcon(u':/media/media_image.png')
+        self.generateSlideData(service_item)
+        self.parent.service_manager.addServiceItem(service_item)

=== modified file 'openlp/core/lib/plugin.py'
--- openlp/core/lib/plugin.py	2009-06-11 05:13:10 +0000
+++ openlp/core/lib/plugin.py	2009-06-24 20:15:24 +0000
@@ -21,6 +21,10 @@
 import logging
 
 from openlp.core.lib import PluginConfig
+# why does this not work???
+# from openlp.core.lib import Event,  EventType
+# so I have to do this???
+from event import Event, EventType
 
 class Plugin(object):
     """
@@ -66,6 +70,9 @@
         A method used to render something to the screen, given the current theme
         and screen number.
     """
+    global log
+    log = logging.getLogger(u'Plugin')
+    log.info(u'loaded')
 
     def __init__(self, name=None, version=None, plugin_helpers=None):
         """
@@ -95,6 +102,7 @@
         self.render_manager = plugin_helpers[u'render']
         self.service_manager = plugin_helpers[u'service']
         self.settings= plugin_helpers[u'settings']
+        self.dnd_id=None
 
     def check_pre_conditions(self):
         """
@@ -138,7 +146,23 @@
         """
         Handle the event contained in the event object.
         """
-        pass
+    def handle_event(self, event):
+        """
+        Handle the event contained in the event object.  If you want
+        to use this default behaviour, you must set self.dnd_id equal
+        to that sent by the dnd source - eg the MediaItem
+        """
+        # default behaviour - can be overridden if desired
+        log.debug(u'Handle event called with event %s with payload %s'%(event.event_type, event.payload))
+        if event.event_type == EventType.LoadServiceItem and event.payload == self.dnd_id:
+            log.debug(u'Load Service Item received')
+            self.media_item.onAddClick()
+        if event.event_type == EventType.PreviewShow and event.payload == self.dnd_id:
+            log.debug(u'Load Preview Item received')
+            self.media_item.onPreviewClick()
+        if event.event_type == EventType.LiveShow and event.payload == self.dnd_id:
+            log.debug(u'Load Live Show Item received')
+            self.media_item.onLiveClick()
 
     def about(self):
         """

=== modified file 'openlp/core/test/test_render.py'
--- openlp/core/test/test_render.py	2009-06-16 18:21:24 +0000
+++ openlp/core/test/test_render.py	2009-06-22 20:44:35 +0000
@@ -50,10 +50,10 @@
         self.app=None
     def write_to_file(self, pixmap, name):
         im=pixmap.toImage()
-        testpathname=os.path.join(u'test_results", name+".bmp')
+        testpathname=os.path.join(u'test_results', name+'.bmp')
         if os.path.exists(testpathname):
             os.unlink(testpathname)
-        im.save(testpathname, "bmp')
+        im.save(testpathname, 'bmp')
         return im
     # xxx quitting the app still leaves it hanging aroudn so we die
     # when trying to start another one.  Not quitting doesn't help
@@ -218,4 +218,4 @@
     t.setup_method(None)
     t.test_easy()
     t.test_splits()
-    t.teardown_method(None)
\ No newline at end of file
+    t.teardown_method(None)

=== modified file 'openlp/plugins/images/imageplugin.py'
--- openlp/plugins/images/imageplugin.py	2009-06-20 10:44:12 +0000
+++ openlp/plugins/images/imageplugin.py	2009-06-24 20:15:24 +0000
@@ -37,6 +37,7 @@
         self.icon = QtGui.QIcon()
         self.icon.addPixmap(QtGui.QPixmap(u':/media/media_image.png'),
             QtGui.QIcon.Normal, QtGui.QIcon.Off)
+        self.dnd_id = u'Image' # passed with drag and drop messages
 
     def get_media_manager_item(self):
         # Create the MediaManagerItem object
@@ -46,17 +47,3 @@
     def initialise(self):
         log.info(u'Plugin Initialising')
 
-    def handle_event(self, event):
-        """
-        Handle the event contained in the event object.
-        """
-        log.debug(u'Handle event called with event %s with payload %s'%(event.event_type, event.payload))
-        if event.event_type == EventType.LoadServiceItem and event.payload == 'Image':
-            log.debug(u'Load Service Item received')
-            self.media_item.onImageAddClick()
-        if event.event_type == EventType.PreviewShow and event.payload == 'Image':
-            log.debug(u'Load Preview Item received')
-            self.media_item.onImagePreviewClick()
-        if event.event_type == EventType.LiveShow and event.payload == 'Image':
-            log.debug(u'Load Live Show Item received')
-            self.media_item.onImageLiveClick()

=== modified file 'openlp/plugins/images/lib/__init__.py'
--- openlp/plugins/images/lib/__init__.py	2009-06-20 10:44:12 +0000
+++ openlp/plugins/images/lib/__init__.py	2009-06-23 20:53:06 +0000
@@ -17,5 +17,6 @@
 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 Place, Suite 330, Boston, MA 02111-1307 USA
 """
+
 from listwithpreviews import ListWithPreviews
 from mediaitem import ImageMediaItem

=== modified file 'openlp/plugins/images/lib/mediaitem.py'
--- openlp/plugins/images/lib/mediaitem.py	2009-06-20 10:44:12 +0000
+++ openlp/plugins/images/lib/mediaitem.py	2009-06-24 20:15:24 +0000
@@ -22,30 +22,17 @@
 
 from PyQt4 import QtCore, QtGui
 
-from openlp.core.lib import MediaManagerItem,  ServiceItem,  translate
-from openlp.plugins.images.lib import ListWithPreviews
-
-class ImageList(QtGui.QListView):
-
-    def __init__(self,parent=None,name=None):
-        QtGui.QListView.__init__(self,parent)
-
-    def mouseMoveEvent(self, event):
-        """
-        Drag and drop event does not care what data is selected
-        as the recepient will use events to request the data move
-        just tell it what plugin to call
-        """
-        if event.buttons() != QtCore.Qt.LeftButton:
-            return
-        drag = QtGui.QDrag(self)
-        mimeData = QtCore.QMimeData()
-        drag.setMimeData(mimeData)
-        mimeData.setText(u'Image')
-        dropAction = drag.start(QtCore.Qt.CopyAction)
-        if dropAction == QtCore.Qt.CopyAction:
-            self.close()
-
+# from openlp.plugins.images.lib import ListWithPreviews
+from listwithpreviews import ListWithPreviews
+from openlp.core.lib import MediaManagerItem, ServiceItem, translate, BaseListWithDnD
+
+# We have to explicitly create separate classes for each plugin
+# in order for DnD to the Service manager to work correctly.
+class ImageListView(BaseListWithDnD):
+    def __init__(self, parent=None):
+        self.PluginName = u'Image'
+        BaseListWithDnD.__init__(self, parent)
+        
 class ImageMediaItem(MediaManagerItem):
     """
     This is the custom media manager item for images.
@@ -55,120 +42,23 @@
     log.info(u'Image Media Item loaded')
 
     def __init__(self, parent, icon, title):
+        self.TranslationContext = u'ImagePlugin'
+        self.PluginTextShort =u'Image'
+        self.ConfigSection=u'images'
+        self.OnNewPrompt=u'Select Image(s)'
+        self.OnNewFileMasks=u'Images (*.jpg *jpeg *.gif *.png *.bmp)'
+        # this next is a class, not an instance of a class - it will
+        # be instanced by the base MediaManagerItem
+        self.ListViewWithDnD_class=ImageListView 
         MediaManagerItem.__init__(self, parent, icon, title)
 
-    def setupUi(self):
-        # Add a toolbar
-        self.addToolbar()
-        # Create buttons for the toolbar
-        ## New Song Button ##
-        self.addToolbarButton(
-            translate(u'ImageMediaItem', u'Load Image'),
-            translate(u'ImageMediaItem', u'Load images into openlp.org'),
-            u':/images/image_load.png', self.onImagesNewClick, u'ImageNewItem')
-        ## Delete Song Button ##
-        self.addToolbarButton(
-            translate(u'ImageMediaItem', u'Delete Image'),
-            translate(u'ImageMediaItem', u'Delete the selected image'),
-            u':/images/image_delete.png', self.onImageDeleteClick, u'ImageDeleteItem')
-        ## Separator Line ##
-        self.addToolbarSeparator()
-        ## Preview Song Button ##
-        self.addToolbarButton(
-            translate(u'ImageMediaItem', u'Preview Song'),
-            translate(u'ImageMediaItem', u'Preview the selected image'),
-            u':/system/system_preview.png', self.onImagePreviewClick, u'ImagePreviewItem')
-        ## Live Song Button ##
-        self.addToolbarButton(
-            translate(u'ImageMediaItem', u'Go Live'),
-            translate(u'ImageMediaItem', u'Send the selected image live'),
-            u':/system/system_live.png', self.onImageLiveClick, u'ImageLiveItem')
-        ## Add Song Button ##
-        self.addToolbarButton(
-            translate(u'ImageMediaItem', u'Add Image To Service'),
-            translate(u'ImageMediaItem', u'Add the selected image(s) to the service'),
-            u':/system/system_add.png', self.onImageAddClick, u'ImageAddItem')
-        #Add the Image List widget
-        self.ImageListView = ImageList()
-        self.ImageListView.uniformItemSizes = True
-        self.ImageListData = ListWithPreviews()
-        self.ImageListView.setModel(self.ImageListData)
-        self.ImageListView.setGeometry(QtCore.QRect(10, 100, 256, 591))
-        self.ImageListView.setSpacing(1)
-        self.ImageListView.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
-        self.ImageListView.setAlternatingRowColors(True)
-        self.ImageListView.setDragEnabled(True)
-        self.ImageListView.setObjectName(u'ImageListView')
-        self.PageLayout.addWidget(self.ImageListView)
-        #define and add the context menu
-        self.ImageListView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
-        self.ImageListView.addAction(self.contextMenuAction(
-            self.ImageListView, ':/system/system_preview.png',
-            translate(u'ImageMediaItem', u'&Preview Image'),
-            self.onImagePreviewClick))
-        self.ImageListView.addAction(self.contextMenuAction(
-            self.ImageListView, ':/system/system_live.png',
-            translate(u'ImageMediaItem', u'&Show Live'),
-            self.onImageLiveClick))
-        self.ImageListView.addAction(self.contextMenuAction(
-            self.ImageListView, ':/system/system_add.png',
-            translate(u'ImageMediaItem', u'&Add to Service'),
-            self.onImageAddClick))
-        QtCore.QObject.connect(self.ImageListView,
-           QtCore.SIGNAL(u'doubleClicked(QModelIndex)'), self.onImagePreviewClick)
-
-    def initialise(self):
-        self.loadImageList(self.parent.config.load_list(u'images'))
-
-    def onImagesNewClick(self):
-        files = QtGui.QFileDialog.getOpenFileNames(None,
-            translate(u'ImageMediaItem', u'Select Image(s)'),
-            self.parent.config.get_last_dir(),
-            u'Images (*.jpg *jpeg *.gif *.png *.bmp)')
-        log.info(u'New image(s)', unicode(files))
-        if len(files) > 0:
-            self.loadImageList(files)
-            dir, filename = os.path.split(unicode(files[0]))
-            self.parent.config.set_last_dir(dir)
-            self.parent.config.set_list(u'images', self.ImageListData.getFileList())
-
-    def loadImageList(self, list):
-        for image in list:
-            self.ImageListData.addRow(image)
-
-    def onImageDeleteClick(self):
-        indexes = self.ImageListView.selectedIndexes()
-        for index in indexes:
-            current_row = int(index.row())
-            self.ImageListData.removeRow(current_row)
-        self.parent.config.set_list(u'images', self.ImageListData.getFileList())
 
     def generateSlideData(self, service_item):
-        indexes = self.ImageListView.selectedIndexes()
+        indexes = self.ListView.selectedIndexes()
         service_item.title = u'Image(s)'
         for index in indexes:
-            filename = self.ImageListData.getFilename(index)
+            filename = self.ListData.getFilename(index)
             frame = QtGui.QImage(unicode(filename))
             (path, name) = os.path.split(filename)
             service_item.add_from_image(path,  name, frame)
 
-    def onImagePreviewClick(self):
-        log.debug(u'Image Preview Requested')
-        service_item = ServiceItem(self.parent)
-        service_item.addIcon(u':/media/media_image.png')
-        self.generateSlideData(service_item)
-        self.parent.preview_controller.addServiceItem(service_item)
-
-    def onImageLiveClick(self):
-        log.debug(u'Image Live Requested')
-        service_item = ServiceItem(self.parent)
-        service_item.addIcon(u':/media/media_image.png')
-        self.generateSlideData(service_item)
-        self.parent.live_controller.addServiceItem(service_item)
-
-    def onImageAddClick(self):
-        log.debug(u'Image Add Requested')
-        service_item = ServiceItem(self.parent)
-        service_item.addIcon(u':/media/media_image.png')
-        self.generateSlideData(service_item)
-        self.parent.service_manager.addServiceItem(service_item)

=== added file 'openlp/plugins/media/video_render.py'
--- openlp/plugins/media/video_render.py	1970-01-01 00:00:00 +0000
+++ openlp/plugins/media/video_render.py	2009-06-22 20:44:35 +0000
@@ -0,0 +1,70 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+"""
+OpenLP - Open Source Lyrics Projection
+Copyright (c) 2008 Raoul Snyman
+Portions copyright (c) 2008 Martin Thompson, Tim Bentley,
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; version 2 of the License.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+import os
+from PyQt4 import QtCore, QtGui
+
+# xxx this needs a try, except once we've decided what to do if it fails
+from PyQt4.phonon import Phonon
+
+# from openlp.core.lib import Plugin, MediaManagerItem, SettingsTab
+# from openlp.plugins.media.lib import MediaTab,MediaMediaItem
+
+"""Renders a video to some surface or other """
+
+class w(QtGui.QMainWindow):
+    def __init__(self, parent=None):
+        super(QtGui.QMainWindow, self).__init__(parent)
+        self.resize(640,480)
+        self.setWindowTitle(u'simple media player')
+        self.show()
+
+if __name__==u'__main__':
+    app = QtGui.QApplication([])
+#     widget = QtGui.QWidget()
+#     widget.resize(320, 240)
+#     widget.setWindowTitle(u'simple')
+#     widget.show()
+#     QCore.QCoreApplication.setApplicationName(u'OpenLP')
+    mainwindow=w()
+    widget=QtGui.QWidget(mainwindow)
+    mainwindow.setCentralWidget(widget)
+    widget.setLayout(QtGui.QVBoxLayout(widget))
+#     videofile=u'r-128.rm'
+    videofile=u'/extra_space/Download/coa360download56Kbps240x160.mpg'
+    source=Phonon.MediaSource(videofile)
+
+    media=Phonon.MediaObject(widget)
+    media.setCurrentSource(source)
+
+    video=Phonon.VideoWidget(widget)
+    audio=Phonon.AudioOutput(Phonon.MusicCategory)
+#     controller=Phonon.MediaController(media)
+    Phonon.createPath(media, video);
+    Phonon.createPath(media, audio);
+#     player=Phonon.VideoPlayer(Phonon.VideoCategory, widget)
+    slider=Phonon.SeekSlider(media, mainwindow)
+    widget.layout().addWidget(slider)
+    widget.layout().addWidget(video)
+    slider.show()
+    
+    video.show()
+    media.play()
+    app.exec_()
+

=== modified file 'openlp/plugins/songs/test/test_song_text.py'
--- openlp/plugins/songs/test/test_song_text.py	2009-06-16 18:21:24 +0000
+++ openlp/plugins/songs/test/test_song_text.py	2009-06-22 20:44:35 +0000
@@ -24,7 +24,7 @@
 if "" == __ThisDir__ :
     __ThisDir__ = os.path.abspath(u'.')
 
-sys.path.append(os.path.abspath(u'%s/../../../.."%__ThisDir__))
+sys.path.append(os.path.abspath(u'%s/../../../..'%__ThisDir__))
 
 from openlp.plugins.songs.lib.songxml import *
 
@@ -35,26 +35,26 @@
         """OpenSong: parse CCLI example"""
         global __ThisDir__
         s = Song()
-        s.from_ccli_text_file(u'%s/data_text/CCLI example.txt"%(__ThisDir__))
-        assert(s.get_title() == "Song Title Here')
-        assert(s.get_author_list(True) == "Author, artist name')
-        assert(s.get_copyright() == "1996 Publisher Info')
-        assert(s.get_song_cclino() == "1234567')
+        s.from_ccli_text_file(u'%s/data_text/CCLI example.txt'%(__ThisDir__))
+        assert(s.get_title() == 'Song Title Here')
+        assert(s.get_author_list(True) == 'Author, artist name')
+        assert(s.get_copyright() == '1996 Publisher Info')
+        assert(s.get_song_cclino() == '1234567')
         assert(s.get_number_of_slides() == 4)
         
     def test_file2(self):
         """OpenSong: parse PåEnFjern (danish)"""
         global __ThisDir__
         s = Song()
-        s.from_ccli_text_file(u'%s/data_text/PåEnFjern.txt"%(__ThisDir__))
-        assert(s.get_title() == "På en fjern ensom høj')
-        assert(s.get_author_list(True) == "Georg Bennard')
-        assert(s.get_copyright() == "')
-        assert(s.get_song_cclino() == "')
+        s.from_ccli_text_file(u'%s/data_text/PåEnFjern.txt'%(__ThisDir__))
+        assert(s.get_title() == 'På en fjern ensom høj')
+        assert(s.get_author_list(True) == 'Georg Bennard')
+        assert(s.get_copyright() == '')
+        assert(s.get_song_cclino() == '')
         assert(s.get_number_of_slides() == 8)
 
 if '__main__' == __name__:
     # for local debugging
     r = Test_Text()
     r.test_file1()
-    r.test_file2()
\ No newline at end of file
+    r.test_file2()


Follow ups