← Back to team overview

openlp-core team mailing list archive

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

 

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

Requested reviews:
  Andreas Preikschat (googol)
  Raoul Snyman (raoul-snyman)
Related bugs:
  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/dnd/+merge/70399

Move all the Drag and Drop changes from the B1 tree which is stuck at present.
It is no possible to Dnd Images, Presentations and Media into the plugins as wee as dragging a otz file into the service manager.

Can import Folders now.
Remove duplicate popups now.

Servicefile load now checks for unsaved file and asks to save.
-- 
https://code.launchpad.net/~trb143/openlp/dnd/+merge/70399
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp.pyw'
--- openlp.pyw	2011-07-23 22:52:34 +0000
+++ openlp.pyw	2011-08-04 04:56:04 +0000
@@ -127,6 +127,8 @@
             # now kill the splashscreen
             self.splash.finish(self.mainWindow)
             log.debug(u'Splashscreen closed')
+        # make sure Qt really display 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-07-30 07:34:37 +0000
+++ openlp/core/lib/__init__.py	2011-08-04 04:56:04 +0000
@@ -233,9 +233,9 @@
     except IOError:
         pass
 
+from eventreceiver import Receiver
 from listwidgetwithdnd import ListWidgetWithDnD
 from formattingtags import FormattingTags
-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-08-04 04:56:04 +0000
@@ -27,8 +27,12 @@
 """
 Extend QListWidget to handle drag and drop functionality
 """
+import os.path
+
 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
@@ -41,6 +45,16 @@
         self.mimeDataText = name
         assert(self.mimeDataText)
 
+    def activateDnD(self):
+        """
+        Activate DnD of widget
+        """
+        self.setAcceptDrops(True)
+        self.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
+        QtCore.QObject.connect(Receiver.get_receiver(),
+            QtCore.SIGNAL(u'%s_dnd' % self.mimeDataText),
+            self.parent().loadFile)
+
     def mouseMoveEvent(self, event):
         """
         Drag and drop event does not care what data is selected
@@ -58,3 +72,39 @@
         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()
+            files = []
+            for url in event.mimeData().urls():
+                localFile = unicode(url.toLocalFile())
+                if os.path.isfile(localFile):
+                    files.append(localFile)
+                elif os.path.isdir(localFile):
+                    listing = os.listdir(localFile)
+                    for file in listing:
+                        files.append(os.path.join(localFile,file))
+            Receiver.send_message(u'%s_dnd' % self.mimeDataText,files)
+        else:
+            event.ignore()

=== modified file 'openlp/core/lib/mediamanageritem.py'
--- openlp/core/lib/mediamanageritem.py	2011-07-23 21:29:24 +0000
+++ openlp/core/lib/mediamanageritem.py	2011-08-04 04:56:04 +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)
@@ -339,26 +338,65 @@
         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:
+            self.validateAndLoad(files)
+        Receiver.send_message(u'cursor_normal')
+
+    def loadFile(self, files):
+        """
+        Turn file from Drag and Drop into an array so the Validate code
+        can run it.
+
+        ``files``
+        The list of files to be loaded
+        """
+        newFiles = []
+        errorShown = False
+        for file in files:
+            type = file.split(u'.')[-1]
+            if type.lower() not in self.onNewFileMasks:
+                if not errorShown:
                     critical_error_message_box(
-                        UiStrings().Duplicate,
+                        translate('OpenLP.MediaManagerItem',
+                        'Invalid File Type'),
                         unicode(translate('OpenLP.MediaManagerItem',
-                        'Duplicate filename %s.\nThis filename is already in '
-                        'the list')) % filename)
-                else:
-                    newFiles.append(file)
+                        'Invalid File %s.\nSuffix not supported'))
+                        % file)
+                    errorShown = True
+            else:
+                newFiles.append(file)
+        if file:
+            self.validateAndLoad(newFiles)
+
+    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(self.listView.item(count).text())
+        newFiles = []
+        duplicatesFound = False
+        for file in files:
+            filename = os.path.split(unicode(file))[1]
+            if filename in names:
+                duplicatesFound = True
+            else:
+                newFiles.append(file)
+        if newFiles:
             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())
-        Receiver.send_message(u'cursor_normal')
+        if duplicatesFound:
+            critical_error_message_box(
+                UiStrings().Duplicate,
+                unicode(translate('OpenLP.MediaManagerItem',
+                'Duplicate files found on import and ignored.')))
 
     def contextMenu(self, point):
         item = self.listView.itemAt(point)

=== modified file 'openlp/core/ui/servicemanager.py'
--- openlp/core/ui/servicemanager.py	2011-07-24 17:52:53 +0000
+++ openlp/core/ui/servicemanager.py	2011-08-04 04:56:04 +0000
@@ -408,20 +408,33 @@
                     return False
         self.newFile()
 
-    def onLoadServiceClicked(self):
+    def onLoadServiceClicked(self, loadFile=None):
+        """
+        Loads the service file and saves the existing one it there is one
+        unchanged
+
+        ``loadFile``
+            The service file to the loaded.  Will be None is from menu so
+            selection will be required.
+        """
         if self.isModified():
             result = self.saveModifiedService()
             if result == QtGui.QMessageBox.Cancel:
                 return False
             elif result == QtGui.QMessageBox.Save:
                 self.saveFile()
-        fileName = unicode(QtGui.QFileDialog.getOpenFileName(self.mainwindow,
-            translate('OpenLP.ServiceManager', 'Open File'),
-            SettingsManager.get_last_dir(
-            self.mainwindow.serviceSettingsSection),
-            translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)')))
-        if not fileName:
-            return False
+        if not loadFile:
+            fileName = unicode(QtGui.QFileDialog.getOpenFileName(
+                self.mainwindow,
+                translate('OpenLP.ServiceManager', 'Open File'),
+                SettingsManager.get_last_dir(
+                self.mainwindow.serviceSettingsSection),
+                translate('OpenLP.ServiceManager',
+                'OpenLP Service Files (*.osz)')))
+            if not fileName:
+                return False
+        else:
+            fileName = loadFile
         SettingsManager.set_last_dir(self.mainwindow.serviceSettingsSection,
             split_filename(fileName)[0])
         self.loadFile(fileName)
@@ -1239,7 +1252,14 @@
             Handle of the event pint passed
         """
         link = event.mimeData()
-        if link.hasText():
+        if event.mimeData().hasUrls():
+            event.setDropAction(QtCore.Qt.CopyAction)
+            event.accept()
+            for url in event.mimeData().urls():
+                filename = unicode(url.toLocalFile())
+                if filename.endswith(u'.osz'):
+                    self.onLoadServiceClicked(filename)
+        elif event.mimeData().hasText():
             plugin = unicode(event.mimeData().text())
             item = self.serviceManagerList.itemAt(event.pos())
             # ServiceManager started the drag and drop

=== modified file 'openlp/plugins/images/lib/mediaitem.py'
--- openlp/plugins/images/lib/mediaitem.py	2011-07-03 08:13:48 +0000
+++ openlp/plugins/images/lib/mediaitem.py	2011-08-04 04:56:04 +0000
@@ -52,6 +52,8 @@
         self.hasSearch = True
         QtCore.QObject.connect(Receiver.get_receiver(),
             QtCore.SIGNAL(u'live_theme_changed'), self.liveThemeChanged)
+        # Allow DnD from the desktop
+        self.listView.activateDnD()
 
     def retranslateUi(self):
         self.onNewPrompt = translate('ImagePlugin.MediaItem',
@@ -131,6 +133,7 @@
                 icon = self.iconFromFile(imageFile, thumb)
             item_name = QtGui.QListWidgetItem(filename)
             item_name.setIcon(icon)
+            item_name.setToolTip(imageFile)
             item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(imageFile))
             self.listView.addItem(item_name)
         if not initialLoad:

=== modified file 'openlp/plugins/media/lib/mediaitem.py'
--- openlp/plugins/media/lib/mediaitem.py	2011-07-03 08:13:48 +0000
+++ openlp/plugins/media/lib/mediaitem.py	2011-08-04 04:56:04 +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)
+        # Allow DnD from the desktop
+        self.listView.activateDnD()
 
     def retranslateUi(self):
         self.onNewPrompt = translate('MediaPlugin.MediaItem', 'Select Media')
@@ -201,17 +204,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):

=== 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-08-04 04:56:04 +0000
@@ -58,6 +58,8 @@
         self.hasSearch = True
         QtCore.QObject.connect(Receiver.get_receiver(),
             QtCore.SIGNAL(u'mediaitem_presentation_rebuild'), self.rebuild)
+        # Allow DnD from the desktop
+        self.listView.activateDnD()
 
     def retranslateUi(self):
         """
@@ -205,6 +207,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/songusage/songusageplugin.py'
--- openlp/plugins/songusage/songusageplugin.py	2011-07-23 21:29:24 +0000
+++ openlp/plugins/songusage/songusageplugin.py	2011-08-04 04:56:04 +0000
@@ -91,8 +91,8 @@
         self.toolsMenu.addAction(self.songUsageMenu.menuAction())
         self.songUsageMenu.addAction(self.songUsageStatus)
         self.songUsageMenu.addSeparator()
+        self.songUsageMenu.addAction(self.songUsageReport)
         self.songUsageMenu.addAction(self.songUsageDelete)
-        self.songUsageMenu.addAction(self.songUsageReport)
         self.songUsageActiveButton = QtGui.QToolButton(
             self.formparent.statusBar)
         self.songUsageActiveButton.setCheckable(True)


Follow ups