← Back to team overview

openlp-core team mailing list archive

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

 

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

Requested reviews:
  OpenLP Core (openlp-core)
Related bugs:
  Bug #774853 in OpenLP: "Color formatting tag displays incorrect color"
  https://bugs.launchpad.net/openlp/+bug/774853
  Bug #793745 in OpenLP: "Drag & drop support from filesystem to media/image plugins"
  https://bugs.launchpad.net/openlp/+bug/793745

For more details, see:
https://code.launchpad.net/~trb143/openlp/b1/+merge/65931

Not for merging yet
-- 
https://code.launchpad.net/~trb143/openlp/b1/+merge/65931
Your team OpenLP Core is requested to review the proposed merge of lp:~trb143/openlp/b1 into lp:openlp.
=== modified file 'openlp.pyw'
--- openlp.pyw	2011-06-12 16:02:52 +0000
+++ openlp.pyw	2011-06-27 05:08:30 +0000
@@ -93,7 +93,7 @@
         # On Windows, the args passed into the constructor are
         # ignored. Not very handy, so set the ones we want to use.
         self.args = args
-        # provide a listener for widgets to reqest a screen update.
+        # provide a listener for widgets to request a screen update.
         QtCore.QObject.connect(Receiver.get_receiver(),
             QtCore.SIGNAL(u'openlp_process_events'), self.processEvents)
         QtCore.QObject.connect(Receiver.get_receiver(),
@@ -125,6 +125,8 @@
             # now kill the splashscreen
             self.splash.finish(self.mainWindow)
             log.debug(u'Splashscreen closed')
+        # make sure Qt really removes the splash screen
+        self.processEvents()
         self.mainWindow.repaint()
         self.processEvents()
         if not has_run_wizard:

=== modified file 'openlp/core/lib/__init__.py'
--- openlp/core/lib/__init__.py	2011-06-12 16:02:52 +0000
+++ openlp/core/lib/__init__.py	2011-06-27 05:08:30 +0000
@@ -121,8 +121,7 @@
 
 def image_to_byte(image):
     """
-    Resize an image to fit on the current screen for the web and returns
-    it as a byte stream.
+    Convert an Image to a Base64 array.
 
     ``image``
         The image to converted.
@@ -233,9 +232,23 @@
     except IOError:
         pass
 
+def generate_hash_for_file(full_path, filename):
+    """
+    Convert a file path into a hash with correct file type
+
+    ``full_path``
+        Path to the file including the file name
+
+    ``filename``
+        The name of the file.
+    """
+    file_type = os.path.splitext(filename)[1]
+    hash_name = unicode(abs(hash(unicode(full_path))))
+    return u'%s%s' %(hash_name, file_type)
+
+from eventreceiver import Receiver
 from listwidgetwithdnd import ListWidgetWithDnD
 from displaytags import DisplayTags
-from eventreceiver import Receiver
 from spelltextedit import SpellTextEdit
 from settingsmanager import SettingsManager
 from plugin import PluginStatus, StringContent, Plugin

=== modified file 'openlp/core/lib/listwidgetwithdnd.py'
--- openlp/core/lib/listwidgetwithdnd.py	2011-06-12 16:02:52 +0000
+++ openlp/core/lib/listwidgetwithdnd.py	2011-06-27 05:08:30 +0000
@@ -29,6 +29,8 @@
 """
 from PyQt4 import QtCore, QtGui
 
+from openlp.core.lib import Receiver
+
 class ListWidgetWithDnD(QtGui.QListWidget):
     """
     Provide a list widget to store objects and handle drag and drop events
@@ -40,6 +42,8 @@
         QtGui.QListWidget.__init__(self, parent)
         self.mimeDataText = name
         assert(self.mimeDataText)
+        self.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
+        self.setAcceptDrops(True)
 
     def mouseMoveEvent(self, event):
         """
@@ -58,3 +62,33 @@
         drag.setMimeData(mimeData)
         mimeData.setText(self.mimeDataText)
         drag.start(QtCore.Qt.CopyAction)
+
+    def dragEnterEvent(self, event):
+        if event.mimeData().hasUrls:
+            event.accept()
+        else:
+            event.ignore()
+
+    def dragMoveEvent(self, event):
+        if event.mimeData().hasUrls:
+            event.setDropAction(QtCore.Qt.CopyAction)
+            event.accept()
+        else:
+            event.ignore()
+
+    def dropEvent(self, event):
+        """
+        Receive drop event check if it is a file and process it if it is.
+
+        ``event``
+            Handle of the event pint passed
+        """
+        if event.mimeData().hasUrls:
+            event.setDropAction(QtCore.Qt.CopyAction)
+            event.accept()
+            for url in event.mimeData().urls():
+                Receiver.send_message(u'%s_dnd' % self.mimeDataText,
+                    url.toLocalFile())
+
+        else:
+            event.ignore()

=== modified file 'openlp/core/lib/mediamanageritem.py'
--- openlp/core/lib/mediamanageritem.py	2011-06-12 16:02:52 +0000
+++ openlp/core/lib/mediamanageritem.py	2011-06-27 05:08:30 +0000
@@ -252,7 +252,6 @@
         self.listView.setSelectionMode(
             QtGui.QAbstractItemView.ExtendedSelection)
         self.listView.setAlternatingRowColors(True)
-        self.listView.setDragEnabled(True)
         self.listView.setObjectName(u'%sListView' % self.plugin.name)
         # Add to pageLayout
         self.pageLayout.addWidget(self.listView)
@@ -331,27 +330,58 @@
         log.info(u'New files(s) %s', unicode(files))
         if files:
             Receiver.send_message(u'cursor_busy')
-            names = []
-            for count in range(0, self.listView.count()):
-                names.append(self.listView.item(count).text())
-            newFiles = []
-            for file in files:
-                filename = os.path.split(unicode(file))[1]
-                if filename in names:
-                    critical_error_message_box(
-                        UiStrings().Duplicate,
-                        unicode(translate('OpenLP.MediaManagerItem',
-                        'Duplicate filename %s.\nThis filename is already in '
-                        'the list')) % filename)
-                else:
-                    newFiles.append(file)
-            self.loadList(newFiles)
-            lastDir = os.path.split(unicode(files[0]))[0]
-            SettingsManager.set_last_dir(self.settingsSection, lastDir)
-            SettingsManager.set_list(self.settingsSection,
-                self.settingsSection, self.getFileList())
+            self.validateAndLoad(files)
         Receiver.send_message(u'cursor_normal')
 
+    def loadFile(self, filename):
+        """
+        Turn file from Drag and Drop into a array so the Validate code
+        can runn it.
+
+         ``filename``
+         The file to be loaded
+        """
+        filename = unicode(filename)
+        type = filename.split(u'.')[-1]
+        if type.lower() not in self.onNewFileMasks:
+            critical_error_message_box(
+                translate('OpenLP.MediaManagerItem',
+                'Invalid File Type'),
+                unicode(translate('OpenLP.MediaManagerItem',
+                'Invalid File %s.\nSuffix not supported'))
+                % filename)
+        else:
+            self.validateAndLoad([filename])
+
+    def validateAndLoad(self, files):
+        """
+        Process a list for files either from the File Dialog or from Drag and
+        Drop
+
+         ``files``
+         The files to be loaded
+        """
+        names = []
+        for count in range(0, self.listView.count()):
+            names.append(unicode(self.listView.item(count).
+                data(QtCore.Qt.UserRole).toString()))
+        for file in files:
+            filename = unicode(file)
+            if filename in names:
+                critical_error_message_box(
+                    UiStrings().Duplicate,
+                    unicode(translate('OpenLP.MediaManagerItem',
+                    'Duplicate filename %s.\nThis filename is already in '
+                    'the list')) % filename)
+            else:
+                names.append(file)
+        self.listView.clear()
+        self.loadList(names)
+        lastDir = os.path.split(unicode(files[0]))[0]
+        SettingsManager.set_last_dir(self.settingsSection, lastDir)
+        SettingsManager.set_list(self.settingsSection,
+            self.settingsSection, self.getFileList())
+
     def contextMenu(self, point):
         item = self.listView.itemAt(point)
         # Decide if we have to show the context menu or not.
@@ -476,7 +506,6 @@
             log.debug(u'%s Preview requested', self.plugin.name)
             serviceItem = self.buildServiceItem()
             if serviceItem:
-                serviceItem.from_plugin = True
                 self.plugin.previewController.addServiceItem(serviceItem)
                 if keepFocus:
                     self.listView.setFocus()
@@ -500,8 +529,6 @@
             item = self.createItemFromId(item_id)
         serviceItem = self.buildServiceItem(item)
         if serviceItem:
-            if not item_id:
-                serviceItem.from_plugin = True
             self.plugin.liveController.addServiceItem(serviceItem)
 
     def createItemFromId(self, item_id):
@@ -531,7 +558,6 @@
     def addToService(self, item=None, replace=None):
         serviceItem = self.buildServiceItem(item, True)
         if serviceItem:
-            serviceItem.from_plugin = False
             self.plugin.serviceManager.addServiceItem(serviceItem,
                 replace=replace)
 

=== modified file 'openlp/core/lib/serviceitem.py'
--- openlp/core/lib/serviceitem.py	2011-06-18 13:36:29 +0000
+++ openlp/core/lib/serviceitem.py	2011-06-27 05:08:30 +0000
@@ -35,7 +35,10 @@
 import os
 import uuid
 
-from openlp.core.lib import build_icon, clean_tags, expand_tags
+from PyQt4 import QtCore
+
+from openlp.core.lib import build_icon, clean_tags, expand_tags, \
+    generate_hash_for_file
 from openlp.core.lib.ui import UiStrings
 
 log = logging.getLogger(__name__)
@@ -67,7 +70,7 @@
     AllowsVariableStartTime = 12
     AllowsVirtualSplit = 13
     AllowsWordSplit = 14
-
+    Version20 = 99
 
 class ServiceItem(object):
     """
@@ -84,9 +87,19 @@
         ``plugin``
             The plugin that this service item belongs to.
         """
+        self.from_plugin = False
+        self.from_service = True
+        self.capabilities = []
         if plugin:
             self.renderer = plugin.renderer
             self.name = plugin.name
+            self.from_plugin = True
+            self.from_service = False
+            # mark with latest version
+            self.add_capability(ItemCapabilities.Version20)
+        else:
+            self.from_plugin = False
+            self.from_service = True
         self.title = u''
         self.shortname = u''
         self.audit = u''
@@ -100,8 +113,6 @@
         self._display_frames = []
         self._uuid = 0
         self.notes = u''
-        self.from_plugin = False
-        self.capabilities = []
         self.is_valid = True
         self.icon = None
         self.themedata = None
@@ -115,7 +126,6 @@
         self.start_time = 0
         self.end_time = 0
         self.media_length = 0
-        self.from_service = False
         self._new_item()
 
     def _new_item(self):
@@ -198,7 +208,7 @@
         self.foot_text = \
             u'<br>'.join([footer for footer in self.raw_footer if footer])
 
-    def add_from_image(self, path, title):
+    def add_from_image(self, path, title, reference=None):
         """
         Add an image slide to the service item.
 
@@ -209,8 +219,14 @@
             A title for the slide in the service item.
         """
         self.service_item_type = ServiceItemType.Image
-        self._raw_frames.append({u'title': title, u'path': path})
-        self.renderer.image_manager.add_image(title, path)
+        print path, title, reference
+        if not reference:
+            print "No Ref"
+            reference = generate_hash_for_file(path, title)
+            print reference
+        self._raw_frames.append({u'title': title, u'path': path,
+            u'reference': reference})
+        self.renderer.image_manager.add_image(reference, path)
         self._new_item()
 
     def add_from_text(self, title, raw_slide, verse_tag=None):
@@ -231,7 +247,7 @@
             {u'title': title, u'raw_slide': raw_slide, u'verseTag': verse_tag})
         self._new_item()
 
-    def add_from_command(self, path, file_name, image):
+    def add_from_command(self, path, file_name, image, reference=None):
         """
         Add a slide from a command.
 
@@ -243,10 +259,21 @@
 
         ``image``
             The command of/for the slide.
+
+        ``reference``
+            The unique reference the file uses
         """
         self.service_item_type = ServiceItemType.Command
+        print reference, path
+        if not reference:
+            path = os.path.join(path, file_name)
+            reference = generate_hash_for_file(path, file_name)
+        else:
+            path = os.path.join(path, reference)
+        print "video", path
         self._raw_frames.append(
-            {u'title': file_name, u'image': image, u'path': path})
+            {u'title': file_name, u'image': image, u'path': path,
+            u'reference':reference})
         self._new_item()
 
     def get_service_repr(self):
@@ -277,11 +304,18 @@
         if self.service_item_type == ServiceItemType.Text:
             service_data = [slide for slide in self._raw_frames]
         elif self.service_item_type == ServiceItemType.Image:
-            service_data = [slide[u'title'] for slide in self._raw_frames]
+            if self.is_capable(ItemCapabilities.Version20):
+                for slide in self._raw_frames:
+                    service_data.append(
+                        {u'title': slide[u'title'], u'path': slide[u'path'],
+                        u'reference': slide[u'reference']})
+            else:
+                service_data = [slide[u'title'] for slide in self._raw_frames]
         elif self.service_item_type == ServiceItemType.Command:
             for slide in self._raw_frames:
                 service_data.append(
-                    {u'title': slide[u'title'], u'image': slide[u'image']})
+                    {u'title': slide[u'title'], u'image': slide[u'image'],
+                    u'reference': slide[u'reference']})
         return {u'header': service_header, u'data': service_data}
 
     def set_from_service(self, serviceitem, path=None):
@@ -324,13 +358,19 @@
                 self._raw_frames.append(slide)
         elif self.service_item_type == ServiceItemType.Image:
             for text_image in serviceitem[u'serviceitem'][u'data']:
-                filename = os.path.join(path, text_image)
-                self.add_from_image(filename, text_image)
+                if self.is_capable(ItemCapabilities.Version20):
+                    self.add_from_image(text_image[u'path'],
+                        text_image[u'title'], text_image[u'reference'])
+                else:
+                    filename = os.path.join(path, text_image)
+                    self.add_from_image(filename, text_image)
         elif self.service_item_type == ServiceItemType.Command:
             for text_image in serviceitem[u'serviceitem'][u'data']:
+                print text_image
                 filename = os.path.join(path, text_image[u'title'])
                 self.add_from_command(
-                    path, text_image[u'title'], text_image[u'image'])
+                    path, text_image[u'title'], text_image[u'image'],
+                    text_image[u'reference'])
         self._new_item()
 
     def get_display_title(self):
@@ -345,7 +385,10 @@
             elif len(self._raw_frames) > 1:
                 return self.title
             else:
-                return self._raw_frames[0][u'title']
+                if len(self._raw_frames):
+                    return self._raw_frames[0][u'title']
+                else:
+                    return u''
 
     def merge(self, other):
         """
@@ -418,6 +461,10 @@
         if self.service_item_type == ServiceItemType.Text:
             return self._display_frames[row][u'html'].split(u'\n')[0]
         elif self.service_item_type == ServiceItemType.Image:
+            if u'reference' in self._raw_frames[row]:
+                return self._raw_frames[row][u'reference']
+            else:
+                return self._raw_frames[row][u'title']
             return self._raw_frames[row][u'title']
         else:
             return self._raw_frames[row][u'image']
@@ -460,4 +507,3 @@
             return end
         else:
             return u'%s : %s' % (start, end)
-

=== modified file 'openlp/core/ui/servicemanager.py'
--- openlp/core/ui/servicemanager.py	2011-06-12 16:02:52 +0000
+++ openlp/core/ui/servicemanager.py	2011-06-27 05:08:30 +0000
@@ -34,7 +34,7 @@
 from PyQt4 import QtCore, QtGui
 
 from openlp.core.lib import OpenLPToolbar, ServiceItem, Receiver, build_icon, \
-    ItemCapabilities, SettingsManager, translate
+    ItemCapabilities, SettingsManager, translate, generate_hash_for_file
 from openlp.core.lib.theme import ThemeLevel
 from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
     context_menu_action, context_menu_separator, find_and_set_in_combo_box
@@ -475,11 +475,18 @@
             if not item[u'service_item'].uses_file():
                 continue
             for frame in item[u'service_item'].get_frames():
-                if item[u'service_item'].is_image():
-                    path_from = frame[u'path']
+#                if item[u'service_item'].is_image():
+                path_from = frame[u'path']
+                if item[u'service_item'].from_plugin:
+                    path_to = os.path.join(self.servicePath,
+                        frame[u'reference'])
                 else:
-                    path_from = os.path.join(frame[u'path'], frame[u'title'])
+                    path_to = path_from
+#                else:
+#                    path_from = os.path.join(frame[u'path'], frame[u'title'])
+#                    path_to = path_from
                 # Only write a file once
+                print path_from,  path_to
                 if path_from in write_list:
                     continue
                 file_size = os.path.getsize(path_from)
@@ -499,7 +506,7 @@
                 #        QtGui.QMessageBox.Ok)
                 #    if ans == QtGui.QMessageBox.Cancel:
                 #        continue
-                write_list.append(path_from)
+                write_list.append([path_from,  path_to])
                 total_size += file_size
         log.debug(u'ServiceManager.saveFile - ZIP contents size is %i bytes' %
             total_size)
@@ -518,8 +525,8 @@
             # We save ALL filenames into ZIP using UTF-8.
             zip.writestr(service_file_name.encode(u'utf-8'), service_content)
             # Finally add all the listed media files.
-            for path_from in write_list:
-                zip.write(path_from, path_from.encode(u'utf-8'))
+            for path_from, path_to in write_list:
+                zip.write(path_from, path_to.encode(u'utf-8'))
         except IOError:
             log.exception(u'Failed to save service to disk')
             success = False
@@ -576,6 +583,7 @@
                 osfile = unicode(QtCore.QDir.toNativeSeparators(ucsfile))
                 filePath = os.path.join(self.servicePath,
                     os.path.split(osfile)[1])
+                print "fp", filePath
                 fileTo = open(filePath, u'wb')
                 fileTo.write(zip.read(file))
                 fileTo.flush()
@@ -592,7 +600,6 @@
                 for item in items:
                     self.mainwindow.incrementProgressBar()
                     serviceItem = ServiceItem()
-                    serviceItem.from_service = True
                     serviceItem.renderer = self.mainwindow.renderer
                     serviceItem.set_from_service(item, self.servicePath)
                     self.validateItem(serviceItem)

=== modified file 'openlp/core/ui/slidecontroller.py'
--- openlp/core/ui/slidecontroller.py	2011-06-24 06:53:56 +0000
+++ openlp/core/ui/slidecontroller.py	2011-06-27 05:08:30 +0000
@@ -640,10 +640,11 @@
                     image = QtGui.QImage(frame[u'image'])
                 else:
                     # If current slide set background to image
+                    reference = self.serviceItem.get_rendered_frame(framenumber)
+                    image = self.imageManager.get_image(reference)
                     if framenumber == slideno:
                         self.serviceItem.bg_image_bytes = \
-                            self.imageManager.get_image_bytes(frame[u'title'])
-                    image = self.imageManager.get_image(frame[u'title'])
+                            self.imageManager.get_image_bytes(reference)
                 label.setPixmap(QtGui.QPixmap.fromImage(image))
                 self.previewListWidget.setCellWidget(framenumber, 0, label)
                 slideHeight = width * self.parent().renderer.screen_ratio
@@ -1130,7 +1131,7 @@
         Respond to the arrival of a media service item
         """
         log.debug(u'SlideController onMediaStart')
-        file = os.path.join(item.get_frame_path(), item.get_frame_title())
+        file = item.get_frame_path()
         if self.isLive:
             self.display.video(file, self.volume)
             self.volumeSlider.setValue(self.volume)

=== modified file 'openlp/plugins/images/lib/mediaitem.py'
--- openlp/plugins/images/lib/mediaitem.py	2011-06-12 17:56:11 +0000
+++ openlp/plugins/images/lib/mediaitem.py	2011-06-27 05:08:30 +0000
@@ -33,7 +33,7 @@
 
 from openlp.core.lib import MediaManagerItem, build_icon, ItemCapabilities, \
     SettingsManager, translate, check_item_selected, check_directory_exists, \
-    Receiver
+    Receiver, generate_hash_for_file
 from openlp.core.lib.ui import UiStrings, critical_error_message_box
 from openlp.core.utils import AppLocation, delete_file, get_images_filter
 
@@ -52,6 +52,8 @@
         self.hasSearch = True
         QtCore.QObject.connect(Receiver.get_receiver(),
             QtCore.SIGNAL(u'live_theme_changed'), self.liveThemeChanged)
+        QtCore.QObject.connect(Receiver.get_receiver(),
+            QtCore.SIGNAL(u'Images_dnd'), self.loadFile)
 
     def retranslateUi(self):
         self.onNewPrompt = translate('ImagePlugin.MediaItem',
@@ -121,7 +123,8 @@
             if not initialLoad:
                 self.plugin.formparent.incrementProgressBar()
             filename = os.path.split(unicode(imageFile))[1]
-            thumb = os.path.join(self.servicePath, filename)
+            thumb_file = generate_hash_for_file(imageFile, filename)
+            thumb = os.path.join(self.servicePath, thumb_file)
             if os.path.exists(thumb):
                 if self.validate(imageFile, thumb):
                     icon = build_icon(thumb)
@@ -132,6 +135,7 @@
             item_name = QtGui.QListWidgetItem(filename)
             item_name.setIcon(icon)
             item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(imageFile))
+            item_name.setToolTip(imageFile)
             self.listView.addItem(item_name)
         if not initialLoad:
             self.plugin.formparent.finishedProgressBar()
@@ -208,7 +212,9 @@
             filename = unicode(bitem.data(QtCore.Qt.UserRole).toString())
             if os.path.exists(filename):
                 (path, name) = os.path.split(filename)
-                self.plugin.liveController.display.directImage(name, filename)
+                reference = generate_hash_for_file(filename, name)
+                self.plugin.liveController.display.directImage(reference,
+                    filename)
                 self.resetAction.setVisible(True)
             else:
                 critical_error_message_box(UiStrings().LiveBGError,

=== modified file 'openlp/plugins/media/lib/mediaitem.py'
--- openlp/plugins/media/lib/mediaitem.py	2011-06-12 17:56:11 +0000
+++ openlp/plugins/media/lib/mediaitem.py	2011-06-27 05:08:30 +0000
@@ -39,6 +39,8 @@
 
 log = logging.getLogger(__name__)
 
+CLAPPERBOARD = QtGui.QPixmap(u':/media/media_video.png').toImage()
+
 class MediaMediaItem(MediaManagerItem):
     """
     This is the custom media manager item for Media Slides.
@@ -48,8 +50,7 @@
     def __init__(self, parent, plugin, icon):
         self.IconPath = u'images/image'
         self.background = False
-        self.PreviewFunction = QtGui.QPixmap(
-            u':/media/media_video.png').toImage()
+        self.PreviewFunction = CLAPPERBOARD
         MediaManagerItem.__init__(self, parent, plugin, icon)
         self.singleServiceItem = False
         self.hasSearch = True
@@ -60,6 +61,8 @@
         QtCore.QObject.connect(Receiver.get_receiver(),
             QtCore.SIGNAL(u'openlp_phonon_creation'),
             self.createPhonon)
+        QtCore.QObject.connect(Receiver.get_receiver(),
+            QtCore.SIGNAL(u'Media_dnd'), self.loadFile)
 
     def retranslateUi(self):
         self.onNewPrompt = translate('MediaPlugin.MediaItem', 'Select Media')
@@ -197,17 +200,17 @@
             SettingsManager.set_list(self.settingsSection,
                 u'media', self.getFileList())
 
-    def loadList(self, files):
+    def loadList(self, media):
         # Sort the themes by its filename considering language specific
         # characters. lower() is needed for windows!
-        files.sort(cmp=locale.strcoll,
+        media.sort(cmp=locale.strcoll,
             key=lambda filename: os.path.split(unicode(filename))[1].lower())
-        for file in files:
-            filename = os.path.split(unicode(file))[1]
+        for track in media:
+            filename = os.path.split(unicode(track))[1]
             item_name = QtGui.QListWidgetItem(filename)
-            img = QtGui.QPixmap(u':/media/media_video.png').toImage()
-            item_name.setIcon(build_icon(img))
-            item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
+            item_name.setIcon(build_icon(CLAPPERBOARD))
+            item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(track))
+            item_name.setToolTip(track)
             self.listView.addItem(item_name)
 
     def createPhonon(self):
@@ -216,11 +219,11 @@
             self.mediaObject = Phonon.MediaObject(self)
 
     def search(self, string):
-        files = SettingsManager.load_list(self.settingsSection, u'media')
+        images = SettingsManager.load_list(self.settingsSection, u'media')
         results = []
         string = string.lower()
-        for file in files:
-            filename = os.path.split(unicode(file))[1]
+        for image in images:
+            filename = os.path.split(unicode(image))[1]
             if filename.lower().find(string) > -1:
                 results.append([file, filename])
         return results

=== modified file 'openlp/plugins/presentations/lib/mediaitem.py'
--- openlp/plugins/presentations/lib/mediaitem.py	2011-06-12 17:56:11 +0000
+++ openlp/plugins/presentations/lib/mediaitem.py	2011-06-27 05:08:30 +0000
@@ -32,7 +32,8 @@
 from PyQt4 import QtCore, QtGui
 
 from openlp.core.lib import MediaManagerItem, build_icon, SettingsManager, \
-    translate, check_item_selected, Receiver, ItemCapabilities
+    translate, check_item_selected, Receiver, ItemCapabilities, \
+    generate_hash_for_file
 from openlp.core.lib.ui import UiStrings, critical_error_message_box, \
     media_item_combo_box
 from openlp.plugins.presentations.lib import MessageListener
@@ -58,6 +59,8 @@
         self.hasSearch = True
         QtCore.QObject.connect(Receiver.get_receiver(),
             QtCore.SIGNAL(u'mediaitem_presentation_rebuild'), self.rebuild)
+        QtCore.QObject.connect(Receiver.get_receiver(),
+            QtCore.SIGNAL(u'Presentations_dnd'), self.loadFile)
 
     def retranslateUi(self):
         """
@@ -205,6 +208,7 @@
             item_name = QtGui.QListWidgetItem(filename)
             item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
             item_name.setIcon(icon)
+            item_name.setToolTip(file)
             self.listView.addItem(item_name)
         Receiver.send_message(u'cursor_normal')
         if not initialLoad:

=== modified file 'openlp/plugins/presentations/lib/messagelistener.py'
--- openlp/plugins/presentations/lib/messagelistener.py	2011-06-15 22:34:40 +0000
+++ openlp/plugins/presentations/lib/messagelistener.py	2011-06-27 05:08:30 +0000
@@ -277,8 +277,7 @@
         item = message[0]
         log.debug(u'Startup called with message %s' % message)
         hide_mode = message[2]
-        file = os.path.join(item.get_frame_path(),
-            item.get_frame_title())
+        file = item.get_frame_title()
         self.handler = item.title
         if self.handler == self.mediaitem.Automatic:
             self.handler = self.mediaitem.findControllerByType(file)

=== modified file 'openlp/plugins/presentations/lib/presentationcontroller.py'
--- openlp/plugins/presentations/lib/presentationcontroller.py	2011-06-12 16:02:52 +0000
+++ openlp/plugins/presentations/lib/presentationcontroller.py	2011-06-27 05:08:30 +0000
@@ -31,7 +31,7 @@
 
 from PyQt4 import QtCore
 
-from openlp.core.lib import Receiver, resize_image
+from openlp.core.lib import Receiver, resize_image, generate_hash_for_file
 from openlp.core.utils import AppLocation
 
 log = logging.getLogger(__name__)
@@ -133,8 +133,9 @@
         """
         The location where thumbnail images will be stored
         """
-        return os.path.join(
-            self.controller.thumbnail_folder, self.get_file_name())
+        hash_name = generate_hash_for_file(self.controller.thumbnail_folder,
+            self.get_file_name())
+        return os.path.join(self.controller.thumbnail_folder, hash_name)
 
     def get_temp_folder(self):
         """