← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~trb143/openlp/servicing into lp:openlp

 

Tim Bentley has proposed merging lp:~trb143/openlp/servicing into lp:openlp.

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

Add Drag and drop from Custom plugin to ServiceManager
Improve rendering of images for all code sections so they look nice.


Note 
Prints in Renderer/RenderManager are to review performance of the Renderer.
-- 
https://code.launchpad.net/~trb143/openlp/servicing/+merge/6402
Your team openlp.org Core is subscribed to branch lp:openlp.
=== modified file 'openlp.pyw'
--- openlp.pyw	2009-05-04 13:48:12 +0000
+++ openlp.pyw	2009-05-11 05:09:43 +0000
@@ -26,7 +26,7 @@
 from openlp.core.lib import Receiver
 
 logging.basicConfig(level=logging.DEBUG,
-                format=u'%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
+                format=u'%(asctime)s %(msecs)d %(name)-12s %(levelname)-8s %(message)s',
                 datefmt=u'%m-%d %H:%M:%S',
                 filename=u'openlp.log',
                 filemode=u'w')

=== modified file 'openlp/core/lib/event.py'
--- openlp/core/lib/event.py	2009-04-06 18:45:45 +0000
+++ openlp/core/lib/event.py	2009-05-09 07:01:33 +0000
@@ -35,6 +35,7 @@
     AfterLoadService   = 2
     BeforeSaveService  = 3
     AfterSaveService   = 4
+    LoadServiceItem   = 5
     # Preview events
     PreviewBeforeLoad  = 11
     PreviewAfterLoad   = 12

=== modified file 'openlp/core/lib/renderer.py'
--- openlp/core/lib/renderer.py	2009-05-04 13:48:12 +0000
+++ openlp/core/lib/renderer.py	2009-05-11 05:09:43 +0000
@@ -19,8 +19,9 @@
 """
 import logging
 import os,  os.path
-
 import sys
+
+from datetime import *
 from PyQt4 import QtGui, QtCore, Qt
 
 from copy import copy
@@ -95,6 +96,7 @@
         self.img=QtGui.QPixmap.fromImage(i.scaled(QtCore.QSize(neww, newh), Qt.Qt.KeepAspectRatio))
 
     def set_paint_dest(self, p):
+        log.debug(u'set paint dest (frame) w %d h %d',p.width(), p.height())
         self._paint=p
         if self._bg_image_filename is not None:
             self.scale_bg_image()
@@ -128,6 +130,7 @@
         assert(self._theme)
         assert(self._paint)
         log.debug(u'render background %s ', self._theme.background_type)
+        bef = datetime.now()
         p=QtGui.QPainter()
         p.begin(self._paint)
         if self._theme.background_type == u'solid':
@@ -172,6 +175,10 @@
             else:
                 p.fillRect(self._paint.rect(), QtGui.QColor(u'#000000'))
         p.end()
+        aft = datetime.now()
+        print "background time", bef, aft, aft-bef
+
+        log.debug(u'render background finish')
 
     def split_set_of_lines(self, lines, footer):
 
@@ -250,7 +257,7 @@
 
     def render_lines(self, lines, footer_lines=None):
         """render a set of lines according to the theme, return bounding box"""
-        log.debug(u'_render_lines %s', lines)
+        log.debug(u'render_lines - Start')
 
         bbox=self._render_lines_unaligned(lines, False) # Main font
         if footer_lines is not None:
@@ -263,7 +270,7 @@
 
         if footer_lines is not None:
             bbox=self._render_lines_unaligned(footer_lines, True, (self._rect_footer.left(), self._rect_footer.top()) )
-
+        log.debug(u'render_lines- Finish')
         return bbox
 
     def _render_lines_unaligned(self, lines,  footer,  tlcorner=(0,0)):
@@ -274,13 +281,11 @@
         than a screenful (eg. by using split_set_of_lines)
 
         Returns the bounding box of the text as QRect"""
-        log.debug(u'render lines unaligned %s', lines)
+        log.debug(u'render lines unaligned Start')
         x, y=tlcorner
         brx=x
         bry=y
         for line in lines:
-            #if (line == ''):
-            #   continue
             # render after current bottom, but at original left edge
             # keep track of right edge to see which is biggest
             (thisx, bry) = self._render_single_line(line, footer, (x,bry))
@@ -293,8 +298,7 @@
             p.setPen(QtGui.QPen(QtGui.QColor(0,0,255)))
             p.drawRect(retval)
             p.end()
-
-
+        log.debug(u'render lines unaligned Finish')
         return  retval
 
     def _render_single_line(self, line, footer, tlcorner=(0,0)):
@@ -396,16 +400,16 @@
             p.end()
 
         brcorner=(rightextent,y)
+        log.debug(u'Render single line Finish')
         return brcorner
 
     # xxx this is what to override for an SDL version
     def _get_extent_and_render(self, line, footer,  tlcorner=(0,0), draw=False, color=None):
         """Find bounding box of text  - as render_single_line.
         If draw is set, actually draw the text to the current DC as well
-
         return width and height of text as a tuple (w,h)"""
         # setup defaults
-        log.debug(u'_get_extent_and_render %s %s %s ', [line], tlcorner, draw)
+        #log.debug(u'_get_extent_and_render %s %s %s ', [line], tlcorner, draw)
         p=QtGui.QPainter()
         p.begin(self._paint)
         # 'twould be more efficient to set this once when theme changes

=== modified file 'openlp/core/lib/rendermanager.py'
--- openlp/core/lib/rendermanager.py	2009-05-04 13:48:12 +0000
+++ openlp/core/lib/rendermanager.py	2009-05-11 05:09:43 +0000
@@ -18,12 +18,31 @@
 Place, Suite 330, Boston, MA 02111-1307 USA
 """
 import logging
-import time
 import os,  os.path
 import sys
+
+from datetime import *
 from PyQt4 import QtGui, QtCore, Qt
 from renderer import  Renderer
 
+import sys
+import linecache
+
+def traceit(frame, event, arg):
+    if event == "line":
+        lineno = frame.f_lineno
+        filename = frame.f_globals["__file__"]
+        if (filename.endswith(".pyc") or
+            filename.endswith(".pyo")):
+            filename = filename[:-1]
+        name = frame.f_globals["__name__"]
+        line = linecache.getline(filename, lineno)
+        if name.startswith("openlp"):
+            print "%s:%s: %s" % (name, lineno, line.rstrip())
+    return traceit
+
+
+
 class RenderManager:
     """
     Class to pull all Renderer interactions into one place.
@@ -51,6 +70,7 @@
             self.theme = self.default_theme
         log.debug(u'theme is now %s',  self.theme)
         self.themedata = self.theme_manager.getThemeData(self.theme)
+        self.calculate_default(self.screen_list[self.current_display]['size'])
         self.renderer.set_theme(self.themedata)
         self.build_text_rectangle(self.themedata)
 
@@ -74,7 +94,7 @@
         self.renderer.set_text_rectangle(main_rect,footer_rect)
 
     def generate_preview(self, themedata):
-        log.debug(u'generate preview ')
+        log.debug(u'generate preview')
         self.calculate_default(QtCore.QSize(800,600))
         self.renderer.set_theme(themedata)
         self.build_text_rectangle(themedata)
@@ -102,11 +122,18 @@
 
     def generate_slide(self,main_text, footer_text):
         log.debug(u'generate slide')
+        #sys.settrace(traceit)
+
         self.calculate_default(self.screen_list[self.current_display]['size'])
 
+        bef = datetime.now()
         frame = QtGui.QPixmap(self.width, self.height)
+        aft = datetime.now()
+        print "framebuild time", bef, aft, aft-bef
+
         self.renderer.set_paint_dest(frame)
         answer=self.renderer.render_lines(main_text, footer_text)
+        #sys.settrace()
         return frame
 
     def calculate_default(self, screen):

=== modified file 'openlp/core/lib/serviceitem.py'
--- openlp/core/lib/serviceitem.py	2009-05-04 13:48:12 +0000
+++ openlp/core/lib/serviceitem.py	2009-05-11 05:09:43 +0000
@@ -44,7 +44,6 @@
         self.items = []
         self.iconic_representation = None
         self.raw_slides = None
-        self.format_slides = []
         self.frames = []
         self.raw_footer = None
         self.theme = None
@@ -74,11 +73,11 @@
         else:
             self.render_manager.set_override_theme(self.theme)
         log.debug(u'Formatting slides')
-        for slide in self.raw_slides:
-            self.format_slides.append(self.render_manager.format_slide(slide, False))
-        log.debug(u'Rendering slides')
-        for slide in self.format_slides:
-            self.frames.append(self.render_manager.generate_slide(slide, self.raw_footer))
+        if len(self.frames) == 0 :
+            for slide in self.raw_slides:
+                formated = self.render_manager.format_slide(slide, False)
+                frame = self.render_manager.generate_slide(formated, self.raw_footer)
+                self.frames.append({u'formatted': formated, u'image': frame})
 
 
     def get_parent_node(self):

=== modified file 'openlp/core/ui/mainwindow.py'
--- openlp/core/ui/mainwindow.py	2009-05-04 08:15:48 +0000
+++ openlp/core/ui/mainwindow.py	2009-05-09 07:01:33 +0000
@@ -92,6 +92,7 @@
         self.ThemeManagerContents.eventManager = self.EventManager
         self.ThemeManagerContents.renderManager = self.RenderManager
         self.ServiceManagerContents.renderManager = self.RenderManager
+        self.ServiceManagerContents.eventManager = self.EventManager
         self.ThemeManagerContents.serviceManager = self.ServiceManagerContents
         self.ThemeManagerContents.loadThemes()
 

=== modified file 'openlp/core/ui/servicemanager.py'
--- openlp/core/ui/servicemanager.py	2009-05-04 08:15:48 +0000
+++ openlp/core/ui/servicemanager.py	2009-05-11 05:09:43 +0000
@@ -18,101 +18,97 @@
 Place, Suite 330, Boston, MA 02111-1307 USA
 """
 import os
+import logging
 
 from time import sleep
 from copy import deepcopy
 
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
+from PyQt4 import QtCore, QtGui
 
-# from openlp.core.resources import *
-# from openlp.core.ui import AboutForm, AlertForm, SettingsForm, SlideController
 from openlp.core.lib import OpenLPToolbar
 from openlp.core.lib import ServiceItem
 from openlp.core.lib import RenderManager
 from openlp.core import translate
-
-# from openlp.core import PluginManager
-import logging
-
-class ServiceData(QAbstractItemModel):
-    """
-    Tree of items for an order of service.
-    Includes methods for reading and writing the contents to an OOS file
-    Root contains a list of ServiceItems
-    """
-    global log
-    log=logging.getLogger(u'ServiceData')
-    def __init__(self):
-        QAbstractItemModel.__init__(self)
-        self.items=[]
-        log.info("Starting")
-
-    def clearItems(self):
-        self.items = []
-
-    def columnCount(self, parent):
-        return 1; # always only a single column (for now)
-
-    def rowCount(self, parent):
-        return len(self.items)
-
-    def insertRow(self, row, service_item):
-        self.beginInsertRows(QModelIndex(),row,row)
-        log.info("insert row %s:%s" % (row,service_item))
-        self.items.insert(row, service_item)
-        log.info("Items: %s" % self.items)
-        self.endInsertRows()
-
-    def removeRow(self, row):
-        self.beginRemoveRows(QModelIndex(), row,row)
-        self.items.pop(row)
-        self.endRemoveRows()
-
-    def addRow(self, item):
-        self.insertRow(len(self.items), item)
-
-    def index(self, row, col, parent = QModelIndex()):
-        return self.createIndex(row,col)
-
-    def parent(self, index=QModelIndex()):
-        return QModelIndex() # no children as yet
-
-    def data(self, index, role):
-        """
-        Called by the service manager to draw us in the service window
-        """
-        log.debug(u'data %s %d', index, role)
-        row=index.row()
-        if row > len(self.items): # if the last row is selected and deleted, we then get called with an empty row!
-            return QVariant()
-        item=self.items[row]
-        if role==Qt.DisplayRole:
-            retval= item.title + u':' + item.shortname
-        elif role == Qt.DecorationRole:
-            retval = item.iconic_representation
-        elif role == Qt.ToolTipRole:
-            retval= None
-        else:
-            retval= None
-        if retval == None:
-            retval=QVariant()
-#         log.info("Returning"+ str(retval))
-        if type(retval) is not type(QVariant):
-            return QVariant(retval)
-        else:
-            return retval
-
-    def __iter__(self):
-        for i in self.items:
-            yield i
-
-    def item(self, row):
-        log.info("Get Item:%d -> %s" %(row, str(self.items)))
-        return self.items[row]
-
-
-class ServiceManager(QWidget):
+from openlp.core.lib import Event, EventType, EventManager
+
+#class ServiceData(QtCore.QAbstractItemModel):
+#    """
+#    Tree of items for an order of service.
+#    Includes methods for reading and writing the contents to an OOS file
+#    Root contains a list of ServiceItems
+#    """
+#    global log
+#    log=logging.getLogger(u'ServiceData')
+#    def __init__(self):
+#        QtCore.QAbstractItemModel.__init__(self)
+#        self.items=[]
+#        log.info("Starting")
+#
+#    def clearItems(self):
+#        self.items = []
+#
+#    def columnCount(self, parent=None):
+#        return 1; # always only a single column (for now)
+#
+#    def rowCount(self, parent=None):
+#        return len(self.items)
+#
+#    def insertRow(self, row, service_item):
+#        self.beginInsertRows(QtCore.QModelIndex(),row,row)
+#        log.info("insert row %s:%s" % (row,service_item))
+#        self.items.insert(row, service_item)
+#        log.info("Items: %s" % self.items)
+#        self.endInsertRows()
+#
+#    def removeRow(self, row):
+#        self.beginRemoveRows(QtCore.QModelIndex(), row,row)
+#        self.items.pop(row)
+#        self.endRemoveRows()
+#
+#    def addRow(self, service_item):
+#        self.insertRow(len(self.items), service_item)
+#
+#    def index(self, row, col, parent = QtCore.QModelIndex()):
+#        return self.createIndex(row,col)
+#
+#    def parent(self, index=QtCore.QModelIndex()):
+#        return QtCore.QModelIndex() # no children as yet
+#
+#    def data(self, index, role):
+#        """
+#        Called by the service manager to draw us in the service window
+#        """
+#        log.debug(u'data %s %d', index, role)
+#        row = index.row()
+#        if row > len(self.items): # if the last row is selected and deleted, we then get called with an empty row!
+#            return QtCore.QVariant()
+#        item = self.items[row]
+#        if role == QtCore.Qt.DisplayRole:
+#            retval= item.title + u':' + item.shortname
+#        elif role == QtCore.Qt.DecorationRole:
+#            retval = item.iconic_representation
+#        elif role == QtCore.Qt.ToolTipRole:
+#            retval = None
+#        else:
+#            retval = None
+#        if retval == None:
+#            retval = QtCore.QVariant()
+##         log.info("Returning"+ str(retval))
+#        if type(retval) is not type(QtCore.QVariant):
+#            return QtCore.QVariant(retval)
+#        else:
+#            return retval
+#
+#    def __iter__(self):
+#        for i in self.items:
+#            yield i
+#
+#    def item(self, row):
+#        log.info("Get Item:%d -> %s" %(row, str(self.items)))
+#        return self.items[row]
+
+
+class ServiceManager(QtGui.QWidget):
 
     """Manages the orders of service.  Currently this involves taking
     text strings from plugins and adding them to an OOS file. In
@@ -124,48 +120,52 @@
     log=logging.getLogger(u'ServiceManager')
 
     def __init__(self, parent):
-        QWidget.__init__(self)
+        QtGui.QWidget.__init__(self)
         self.parent=parent
-        self.Layout = QVBoxLayout(self)
+        self.Layout = QtGui.QVBoxLayout(self)
         self.Layout.setSpacing(0)
         self.Layout.setMargin(0)
         self.Toolbar = OpenLPToolbar(self)
-        self.Toolbar.addToolbarButton("Move to top", ":/services/service_top.png",
-            translate(u'ServiceManager', u'Move to start'), self.onServiceTop)
-        self.Toolbar.addToolbarButton("Move up", ":/services/service_up.png",
+        self.Toolbar.addToolbarButton(u'Move to top', u':/services/service_top.png',
+            translate(u'ServiceManager', u'Move to top'), self.onServiceTop)
+        self.Toolbar.addToolbarButton(u'Move up', u':/services/service_up.png',
             translate(u'ServiceManager', u'Move up order'), self.onServiceUp)
-        self.Toolbar.addToolbarButton("Move down", ":/services/service_down.png",
+        self.Toolbar.addToolbarButton(u'Move down', u':/services/service_down.png',
             translate(u'ServiceManager', u'Move down order'), self.onServiceDown)
-        self.Toolbar.addToolbarButton("Move to bottom", ":/services/service_bottom.png",
+        self.Toolbar.addToolbarButton(u'Move to bottom', u':/services/service_bottom.png',
             translate(u'ServiceManager', u'Move to end'), self.onServiceEnd)
         self.Toolbar.addSeparator()
-        self.Toolbar.addToolbarButton("New Service", ":/services/service_new.png",
+        self.Toolbar.addToolbarButton(u'New Service', u':/services/service_new.png',
             translate(u'ServiceManager', u'Create a new Service'), self.onNewService)
-        self.Toolbar.addToolbarButton("Delete From Service", ":/services/service_delete.png",
+        self.Toolbar.addToolbarButton(u'Delete From Service', u':/services/service_delete.png',
             translate(u'ServiceManager', u'Delete From Service'), self.onDeleteFromService)
         self.Toolbar.addSeparator()
-        self.Toolbar.addToolbarButton("Save Service", ":/services/service_save.png",
+        self.Toolbar.addToolbarButton(u'Save Service', u':/services/service_save.png',
             translate(u'ServiceManager', u'Save Service'), self.onSaveService)
-        self.Toolbar.addToolbarButton("Load Service", ":/services/service_open.png",
+        self.Toolbar.addToolbarButton(u'Load Service', u':/services/service_open.png',
             translate(u'ServiceManager', u'Load Existing'), self.onLoadService)
 
         self.Toolbar.addSeparator()
-        self.ThemeComboBox = QComboBox(self.Toolbar)
-        self.ThemeComboBox.setSizeAdjustPolicy(QComboBox.AdjustToContents)
-        self.ThemeWidget = QWidgetAction(self.Toolbar)
+        self.ThemeComboBox = QtGui.QComboBox(self.Toolbar)
+        self.ThemeComboBox.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents)
+        self.ThemeWidget = QtGui.QWidgetAction(self.Toolbar)
         self.ThemeWidget.setDefaultWidget(self.ThemeComboBox)
         self.Toolbar.addAction(self.ThemeWidget)
-
         self.Layout.addWidget(self.Toolbar)
 
-        self.TreeView = QTreeView(self)
-        self.service_data=ServiceData()
-        self.TreeView.setModel(self.service_data)
-        self.TreeView.setAlternatingRowColors(True)
-        self.Layout.addWidget(self.TreeView)
-
-        QObject.connect(self.ThemeComboBox,
-            SIGNAL("activated(int)"), self.onThemeComboBoxSelected)
+        self.serviceManagerList = QtGui.QTreeWidget(self)
+        self.serviceManagerList.setEditTriggers(QtGui.QAbstractItemView.CurrentChanged|QtGui.QAbstractItemView.DoubleClicked|QtGui.QAbstractItemView.EditKeyPressed)
+        self.serviceManagerList.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
+        self.serviceManagerList.setAlternatingRowColors(True)
+        self.serviceManagerList.setObjectName("serviceManagerList")
+        self.serviceManagerList .__class__.dragEnterEvent=self.dragEnterEvent
+        self.serviceManagerList .__class__.dragMoveEvent=self.dragEnterEvent
+        self.serviceManagerList .__class__.dropEvent =self.dropEvent
+
+        self.Layout.addWidget(self.serviceManagerList)
+
+        QtCore.QObject.connect(self.ThemeComboBox,
+            QtCore.SIGNAL("activated(int)"), self.onThemeComboBoxSelected)
 
     def onServiceTop(self):
         pass
@@ -191,40 +191,36 @@
     def onLoadService(self):
         Pass
 
-
-
-
     def onThemeComboBoxSelected(self, currentIndex):
         self.renderManager.default_theme = self.ThemeComboBox.currentText()
 
     def addServiceItem(self, item):
-        """Adds service item"""
-        log.info("addServiceItem")
-        indexes=self.TreeView.selectedIndexes()
-        assert len(indexes) <= 1 # can only have one selected index in this view
-        if indexes == []:
-            log.info("No row")
-            row = None
-            selected_item = None
-        else:
-            row=indexes[0].row()
-            # if currently selected is of correct type, add it to it
-            log.info("row:%d"%row)
-            selected_item=self.service_data.item(row)
-
-        if type(selected_item) == type(item):
-            log.info("Add to existing item")
-            selected_item.add(item)
-        else:
-            log.info("Create new item")
-            if row is None:
-                self.service_data.addRow(item)
-            else:
-                self.service_data.insertRow(row+1, item)
-
-    def removeServiceItem(self):
-        """Remove currently selected item"""
-        pass
+        treewidgetitem = QtGui.QTreeWidgetItem(self.serviceManagerList)
+        treewidgetitem.setText(0,item.title + u':' + item.shortname)
+        treewidgetitem.setIcon(0,item.iconic_representation)
+        treewidgetitem.setExpanded(True)
+        item.render()
+        for frame in item.frames:
+            treewidgetitem1 = QtGui.QTreeWidgetItem(treewidgetitem)
+            text = frame[u'formatted'][0]
+            treewidgetitem1.setText(0,text[:10])
+            #treewidgetitem1.setIcon(0,frame[u'image'])
+
+    def dragEnterEvent(self, event):
+        """
+        Accept Drag events
+        """
+        event.accept()
+
+    def dropEvent(self, event):
+        """
+        Handle the release of the event and trigger the plugin
+        to add the data
+        """
+        link=event.mimeData()
+        if link.hasText():
+            plugin = event.mimeData().text()
+            self.eventManager.post_event(Event(EventType.LoadServiceItem, plugin))
 
     def oos_as_text(self):
         text=[]
@@ -247,6 +243,9 @@
         oosfile.close()
 
     def updateThemeList(self, theme_list):
+        """
+        Called from ThemeManager when the Themes have changed
+        """
         self.ThemeComboBox.clear()
         for theme in theme_list:
             self.ThemeComboBox.addItem(theme)

=== modified file 'openlp/core/ui/slidecontroller.py'
--- openlp/core/ui/slidecontroller.py	2009-05-04 13:48:12 +0000
+++ openlp/core/ui/slidecontroller.py	2009-05-11 05:09:43 +0000
@@ -20,13 +20,12 @@
 import logging
 import os
 
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
+from PyQt4 import QtCore, QtGui
 
 from openlp.core.lib import OpenLPToolbar
 from openlp.core import translate
 
-class SlideData(QAbstractListModel):
+class SlideData(QtCore.QAbstractListModel):
     """
     Tree of items for an order of Theme.
     Includes methods for reading and writing the contents to an OOS file
@@ -36,13 +35,13 @@
     log=logging.getLogger(u'SlideData')
 
     def __init__(self):
-        QAbstractListModel.__init__(self)
+        QtCore.QAbstractListModel.__init__(self)
         self.items=[]
         self.rowheight=50
         self.maximagewidth=self.rowheight*16/9.0;
         log.info(u'Starting')
 
-    def clearItems(self):
+    def clear(self):
         self.items=[]
 
     def columnCount(self, parent):
@@ -51,36 +50,36 @@
     def rowCount(self, parent=None):
         return len(self.items)
 
-    def insertRow(self, row, frame):
-        self.beginInsertRows(QModelIndex(),row,row)
+    def insertRow(self, row, frame, framenumber):
+        self.beginInsertRows(QtCore.QModelIndex(),row,row)
         log.info(u'insert row %d' % row)
         # create a preview image
-        frame1 = frame.scaled(QSize(350,260))
-        self.items.insert(row,(frame1))
+        frame1 = frame.scaled(QtCore.QSize(350,260),  QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)
+        self.items.insert(row,(frame1, framenumber))
         log.info(u'Items: %s' % self.items)
         self.endInsertRows()
 
     def removeRow(self, row):
-        self.beginRemoveRows(QModelIndex(), row,row)
+        self.beginRemoveRows(QtCore.QModelIndex(), row,row)
         self.items.pop(row)
         self.endRemoveRows()
 
-    def addRow(self, frame):
-        self.insertRow(len(self.items), frame)
+    def addRow(self, frame, framenumber):
+        self.insertRow(len(self.items), frame, framenumber)
 
     def data(self, index, role):
         row=index.row()
         if row > len(self.items): # if the last row is selected and deleted, we then get called with an empty row!
-            return QVariant()
+            return QtCore.QVariant()
 #        if role==Qt.DisplayRole:
 #            retval= self.items[row][1]
-        if role == Qt.DecorationRole:
-            retval= self.items[row]#[0]
+        if role == QtCore.Qt.DecorationRole:
+            retval= self.items[row][0]
         else:
-            retval= QVariant()
+            retval= QtCore.QVariant()
 #         log.info("Returning"+ str(retval))
-        if type(retval) is not type(QVariant):
-            return QVariant(retval)
+        if type(retval) is not type(QtCore.QVariant):
+            return QtCore.QVariant(retval)
         else:
             return retval
 
@@ -101,75 +100,84 @@
         return filelist
 
 
-class SlideController(QWidget):
+class SlideController(QtGui.QWidget):
     global log
     log=logging.getLogger(u'SlideController')
 
     def __init__(self, control_splitter, isLive):
-        QWidget.__init__(self)
+        QtGui.QWidget.__init__(self)
         self.isLive = isLive
-        self.Panel = QWidget(control_splitter)
-        self.Splitter = QSplitter(self.Panel)
-        self.Splitter.setOrientation(Qt.Vertical)
+        self.Panel = QtGui.QWidget(control_splitter)
+        self.Splitter = QtGui.QSplitter(self.Panel)
+        self.Splitter.setOrientation(QtCore.Qt.Vertical)
 
-        self.PanelLayout = QVBoxLayout(self.Panel)
+        self.PanelLayout = QtGui.QVBoxLayout(self.Panel)
         self.PanelLayout.addWidget(self.Splitter)
         self.PanelLayout.setSpacing(50)
         self.PanelLayout.setMargin(0)
 
-        self.Controller = QScrollArea(self.Splitter)
+        self.Controller = QtGui.QScrollArea(self.Splitter)
         self.Controller.setWidgetResizable(True)
 
-        self.PreviewListView = QListView(self.Splitter)
+        self.PreviewListView = QtGui.QListView(self.Splitter)
+        self.PreviewListView.setEditTriggers(QtGui.QAbstractItemView.CurrentChanged)
         self.PreviewListView.setAlternatingRowColors(True)
         self.PreviewListData = SlideData()
         self.PreviewListView.setModel(self.PreviewListData)
+        self.PreviewListView.setSelectionRectVisible(True)
 
-        self.Controller.setGeometry(QRect(0, 0, 828, 536))
+        self.Controller.setGeometry(QtCore.QRect(0, 0, 828, 536))
         self.Controller.setWidget(self.PreviewListView)
 
         self.Toolbar = OpenLPToolbar(self.Splitter)
-        sizeToolbarPolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
+        sizeToolbarPolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
         sizeToolbarPolicy.setHorizontalStretch(0)
         sizeToolbarPolicy.setVerticalStretch(0)
         sizeToolbarPolicy.setHeightForWidth(self.Toolbar.sizePolicy().hasHeightForWidth())
 
         if self.isLive:
-            self.Toolbar.addToolbarButton("First Slide", ":/slides/slide_first.png",
+            self.Toolbar.addToolbarButton(u'First Slide', u':/slides/slide_first.png',
             translate(u'SlideController', u'Move to first'), self.onSlideSelectedFirst)
-        self.Toolbar.addToolbarButton("Last Slide", ":/slides/slide_previous.png",
+        self.Toolbar.addToolbarButton(u'Last Slide', u':/slides/slide_previous.png',
             translate(u'SlideController', u'Move to previous'), self.onSlideSelectedPrevious)
-        self.Toolbar.addToolbarButton("First Slide", ":/slides/slide_next.png",
+        self.Toolbar.addToolbarButton(u'First Slide', u':/slides/slide_next.png',
             translate(u'SlideController', u'Move to next'), self.onSlideSelectedNext)
         if self.isLive:
-            self.Toolbar.addToolbarButton("Last Slide", ":/slides/slide_last.png",
+            self.Toolbar.addToolbarButton(u'Last Slide', u':/slides/slide_last.png',
                 translate(u'SlideController', u'Move to last'), self.onSlideSelectedLast)
             self.Toolbar.addSeparator()
-            self.Toolbar.addToolbarButton("Close Sscreen", ":/slides/slide_close.png",
+            self.Toolbar.addToolbarButton(u'Close Screen', u':/slides/slide_close.png',
                 translate(u'SlideController', u'Close Screen'), self.onBlankScreen)
 
         self.Toolbar.setSizePolicy(sizeToolbarPolicy)
 
-        self.SlidePreview = QLabel(self.Splitter)
-        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
+        self.SlidePreview = QtGui.QLabel(self.Splitter)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
         sizePolicy.setHorizontalStretch(0)
         sizePolicy.setVerticalStretch(0)
         sizePolicy.setHeightForWidth(self.SlidePreview.sizePolicy().hasHeightForWidth())
         self.SlidePreview.setSizePolicy(sizePolicy)
-        self.SlidePreview.setMinimumSize(QSize(250, 190))
-        self.SlidePreview.setFrameShape(QFrame.WinPanel)
-        self.SlidePreview.setFrameShadow(QFrame.Sunken)
+        self.SlidePreview.setMinimumSize(QtCore.QSize(250, 190))
+        self.SlidePreview.setFrameShape(QtGui.QFrame.WinPanel)
+        self.SlidePreview.setFrameShadow(QtGui.QFrame.Sunken)
         self.SlidePreview.setLineWidth(1)
         self.SlidePreview.setScaledContents(True)
-        self.SlidePreview.setObjectName("SlidePreview")
-
-        QObject.connect(self.PreviewListView,
-            SIGNAL("clicked(QModelIndex)"), self.onSlideSelected)
+        self.SlidePreview.setObjectName(u'SlidePreview')
+
+        QtCore.QObject.connect(self.PreviewListView,
+            QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected)
+        QtCore.QObject.connect(self.PreviewListView,
+            QtCore.SIGNAL(u'clicked(QListViewItem)'), self.onCurrentItemChanged)
+
+
+
+    def onCurrentItemChanged(self, current, previous):
+        print u'Method slideControllerList currentItemChanged called', current, previous
 
     def onSlideSelectedFirst(self):
         row = self.PreviewListData.createIndex(0, 0)
         if row.isValid():
-            self.PreviewListView.selectionModel().setCurrentIndex(row, QItemSelectionModel.SelectCurrent)
+            self.PreviewListView.selectionModel().setCurrentIndex(row, QtGui.QItemSelectionModel.SelectCurrent)
             self.onSlideSelected(row)
 
     def onSlideSelectedNext(self):
@@ -182,10 +190,9 @@
                 rowNumber = index.row() + 1
         row = self.PreviewListData.createIndex(rowNumber , 0)
         if row.isValid():
-            self.PreviewListView.selectionModel().setCurrentIndex(row, QItemSelectionModel.SelectCurrent)
+            self.PreviewListView.selectionModel().setCurrentIndex(row, QtGui.QItemSelectionModel.SelectCurrent)
             self.onSlideSelected(row)
 
-
     def onSlideSelectedPrevious(self):
         indexes = self.PreviewListView.selectedIndexes()
         rowNumber = 0
@@ -196,13 +203,13 @@
                 rowNumber  = index.row() - 1
         row = self.PreviewListData.createIndex(rowNumber , 0)
         if row.isValid():
-            self.PreviewListView.selectionModel().setCurrentIndex(row, QItemSelectionModel.SelectCurrent)
+            self.PreviewListView.selectionModel().setCurrentIndex(row, QtGui.QItemSelectionModel.SelectCurrent)
             self.onSlideSelected(row)
 
     def onSlideSelectedLast(self):
         row = self.PreviewListData.createIndex(self.PreviewListData.rowCount() - 1 , 0)
         if row.isValid():
-            self.PreviewListView.selectionModel().setCurrentIndex(row, QItemSelectionModel.SelectCurrent)
+            self.PreviewListView.selectionModel().setCurrentIndex(row, QtGui.QItemSelectionModel.SelectCurrent)
             self.onSlideSelected(row)
 
     def onBlankScreen(self):
@@ -213,21 +220,25 @@
         self.previewFrame(frame)
 
     def previewFrame(self, frame):
-        self.SlidePreview.setPixmap(frame)
+        self.SlidePreview.setPixmap(frame[0])
         if self.isLive:
-            self.mainDisplay.frameView(frame)
+            no = frame[1]
+            LiveFrame = self.serviceitem.frames[no][u'image']
+            self.mainDisplay.frameView(LiveFrame)
 
     def addServiceItem(self, serviceitem):
         log.debug(u'addServiceItem')
         self.serviceitem = serviceitem
         self.serviceitem.render()
-        self.PreviewListData.clearItems()
+        self.PreviewListData.clear()
+        framenumber = 0
         for frame in self.serviceitem.frames:
-            self.PreviewListData.addRow(frame)
+            self.PreviewListData.addRow(frame[u'image'], framenumber)
+            framenumber += 1
 
         row = self.PreviewListData.createIndex(0, 0)
         if row.isValid():
-            self.PreviewListView.selectionModel().setCurrentIndex(row, QItemSelectionModel.SelectCurrent)
+            self.PreviewListView.selectionModel().setCurrentIndex(row, QtGui.QItemSelectionModel.SelectCurrent)
             self.onSlideSelected(row)
 
     def render(self):

=== modified file 'openlp/core/ui/test/test_service_manager.py'
--- openlp/core/ui/test/test_service_manager.py	2009-03-04 21:57:18 +0000
+++ openlp/core/ui/test/test_service_manager.py	2009-05-09 07:01:33 +0000
@@ -25,7 +25,7 @@
 mypath=os.path.split(os.path.abspath(__file__))[0]
 sys.path.insert(0,(os.path.join(mypath, '..','..', '..','..')))
 from openlp.core.ui import ServiceManager
-from openlp.plugins.images import ImageServiceItem
+from openlp.plugins.images.lib import ImageServiceItem
 
 import logging
 logging.basicConfig(filename="test_service_manager.log",level=logging.INFO, filemode="w")
@@ -47,7 +47,7 @@
                 app = QtGui.QApplication([])
         except UnboundLocalError:
             app = QtGui.QApplication([])
-            
+
 
     def teardown_class(self):
         pass
@@ -84,7 +84,7 @@
         assert lines[0].startswith("# <openlp.plugins.images.imageserviceitem.ImageServiceItem object")
         assert lines[1] == "test.gif"
         log.info("done")
-        
+
     def test_2items_as_separate_items(self):
         # If nothing is selected when item is added, a new base service item is added
         log.info("test_2items_as_separate_items")
@@ -105,7 +105,7 @@
         assert lines[3] == "test2.gif"
         assert lines[4] == "test3.gif"
         log.info("done")
-        
+
     def test_2items_merged(self):
         # If the first object is selected when item is added it should be extended
         log.info("test_2items_merged")
@@ -134,7 +134,7 @@
     #  move to top, bottom
     #  new and save as
     #  deleting items
-    
+
 if __name__=="__main__":
 
     t=TestServiceManager_base()

=== modified file 'openlp/core/ui/thememanager.py'
--- openlp/core/ui/thememanager.py	2009-05-04 08:15:48 +0000
+++ openlp/core/ui/thememanager.py	2009-05-11 05:09:43 +0000
@@ -72,7 +72,7 @@
             preview = QPixmap(str(filename))
             width = self.maximagewidth
             height = self.rowheight
-            preview = preview.scaled(width, height, Qt.KeepAspectRatio)
+            preview = preview.scaled(width, height, Qt.KeepAspectRatio, Qt.SmoothTransformation)
             realwidth = preview.width()
             realheight = preview.height()
             # and move it to the centre of the preview space

=== modified file 'openlp/plugins/custom/customplugin.py'
--- openlp/plugins/custom/customplugin.py	2009-04-10 06:06:41 +0000
+++ openlp/plugins/custom/customplugin.py	2009-05-09 07:01:33 +0000
@@ -60,3 +60,6 @@
         if event.event_type == EventType.ThemeListChanged:
             log.debug(u'New Theme request received')
             self.edit_custom_form.loadThemes(self.theme_manager.getThemes())
+        if event.event_type == EventType.LoadServiceItem and event.payload == 'Custom':
+            log.debug(u'Load Service Item received')
+            self.media_item.onCustomAddClick()

=== modified file 'openlp/plugins/custom/lib/mediaitem.py'
--- openlp/plugins/custom/lib/mediaitem.py	2009-05-04 13:48:12 +0000
+++ openlp/plugins/custom/lib/mediaitem.py	2009-05-09 07:01:33 +0000
@@ -109,6 +109,8 @@
         self.CustomListView.setAlternatingRowColors(True)
         self.CustomListData = TextListData()
         self.CustomListView.setModel(self.CustomListData)
+        self.CustomListView.setDragEnabled(True)
+        self.CustomListView .__class__.mouseMoveEvent =self.onMouseMoveEvent
 
         self.PageLayout.addWidget(self.CustomListView)
 
@@ -233,3 +235,27 @@
             service_item.title = title
             service_item.raw_slides = raw_slides
             service_item.raw_footer = raw_footer
+
+    def onMouseMoveEvent(self, event):
+        """
+        Drag and drop eventDo 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
+
+        items = self.CustomListView.selectedIndexes()
+        if items == []:
+            return
+
+        drag = QtGui.QDrag(self)
+        mimeData = QtCore.QMimeData()
+        drag.setMimeData(mimeData)
+        for item in items:
+            mimeData.setText(u'Custom')
+
+        dropAction = drag.start(QtCore.Qt.CopyAction)
+
+        if dropAction == QtCore.Qt.CopyAction:
+            self.close()

=== modified file 'openlp/plugins/images/__init__.py'
--- openlp/plugins/images/__init__.py	2009-03-07 09:21:27 +0000
+++ openlp/plugins/images/__init__.py	2009-05-11 05:09:43 +0000
@@ -18,6 +18,6 @@
 Place, Suite 330, Boston, MA 02111-1307 USA
 """
 
-from imageplugin import ImagePlugin
-from imageserviceitem import ImageServiceItem
+#from imageplugin import ImagePlugin
+#from imageserviceitem import ImageServiceItem
 

=== modified file 'openlp/plugins/images/lib/imageserviceitem.py'
--- openlp/plugins/images/lib/imageserviceitem.py	2009-03-17 05:05:04 +0000
+++ openlp/plugins/images/lib/imageserviceitem.py	2009-05-09 07:01:33 +0000
@@ -39,7 +39,7 @@
       it simply tells the slide controller to use it???
 
     It contains 1 or more images
-          
+
     """
     global log
     log=logging.getLogger("ImageServiceItem")
@@ -56,7 +56,7 @@
 #         c.uniformItemSizes=True
 #         c.setModel(self.imgs)
 #         c.setGeometry(0,0,200,200)
-    
+
     def render(self):
         """
         The render method is what the plugin uses to render its meda to the
@@ -64,7 +64,7 @@
         """
         # render the "image chooser first"
 #         for f in self.imgs:
-#             fl ,  nm = os.path.split(str(f))            
+#             fl ,  nm = os.path.split(str(f))
 #             c = self.slide_controller.rowCount()
 #             self.slide_controller.setRowCount(c+1)
 #             twi = QtGui.QTableWidgetItem(str(f))
@@ -72,7 +72,7 @@
 #             twi = QtGui.QTableWidgetItem(str(nm))
 #             self.slide_controller.setItem(c , 1, twi)
 #             self.slide_controller.setRowHeight(c, 80)
-            
+
         # render the preview screen here
 
     def get_parent_node(self):
@@ -92,7 +92,7 @@
             log.info("add Item..."+str(data))
             for filename in data.get_file_list():
                 self.add(filename)
-            
+
 
     def get_oos_text(self):
         """
@@ -100,7 +100,7 @@
         """
         log.info("Get oos text")
         log.info(str(self.imgs))
-        log.info(str(self.imgs.get_file_list()))
+#        log.info(str(self.imgs.get_file_list()))
         return '\n'.join(self.imgs.get_file_list())
 
     def set_from_oos(self, text):
@@ -111,4 +111,4 @@
         files=text.split('\n')
         for f in files:
             self.imgs.addRow(f)
-        
+

=== modified file 'openlp/plugins/images/lib/listwithpreviews.py'
--- openlp/plugins/images/lib/listwithpreviews.py	2009-03-08 12:41:07 +0000
+++ openlp/plugins/images/lib/listwithpreviews.py	2009-05-11 05:09:43 +0000
@@ -29,7 +29,7 @@
         if os.path.exists(filename):
             preview = QPixmap(str(filename))
             w=self.maximagewidth;h=self.rowheight
-            preview = preview.scaled(w,h, Qt.KeepAspectRatio)
+            preview = preview.scaled(w,h, Qt.KeepAspectRatio, Qt.SmoothTransformation)
             realw=preview.width(); realh=preview.height()
             # and move it to the centre of the preview space
             p=QPixmap(w,h)

=== removed file 'resources/.openlp/data/bible/afr1953.sqlite'
Binary files resources/.openlp/data/bible/afr1953.sqlite	2009-05-01 16:29:36 +0000 and resources/.openlp/data/bible/afr1953.sqlite	1970-01-01 00:00:00 +0000 differ

Follow ups