From f1902ade5ac3701f4f445a49bbd326468cb7e4c6 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Wed, 27 Jul 2011 19:28:35 +0100 Subject: [PATCH 1/4] Fix up drag and drop code --- openlp.pyw | 4 +- openlp/core/lib/__init__.py | 2 +- openlp/core/lib/listwidgetwithdnd.py | 41 +++++++++++ openlp/core/lib/mediamanageritem.py | 69 +++++++++++++------ openlp/core/ui/servicemanager.py | 9 ++- openlp/plugins/images/lib/mediaitem.py | 5 ++ openlp/plugins/media/lib/mediaitem.py | 23 ++++--- openlp/plugins/presentations/lib/mediaitem.py | 5 ++ 8 files changed, 126 insertions(+), 32 deletions(-) diff --git a/openlp.pyw b/openlp.pyw index a39f6cf65..9d291bbca 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -93,7 +93,7 @@ class OpenLP(QtGui.QApplication): # 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 @@ class OpenLP(QtGui.QApplication): # 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: diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index 7fbd5243c..cc2c170e5 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -233,9 +233,9 @@ def check_directory_exists(dir): except IOError: pass +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 diff --git a/openlp/core/lib/listwidgetwithdnd.py b/openlp/core/lib/listwidgetwithdnd.py index 48793c12e..69bd67fdd 100644 --- a/openlp/core/lib/listwidgetwithdnd.py +++ b/openlp/core/lib/listwidgetwithdnd.py @@ -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,13 @@ class ListWidgetWithDnD(QtGui.QListWidget): self.mimeDataText = name assert(self.mimeDataText) + def activateDnD(self): + """ + Activate DnD of widget + """ + self.setAcceptDrops(True) + self.setDragDropMode(QtGui.QAbstractItemView.DragDrop) + def mouseMoveEvent(self, event): """ Drag and drop event does not care what data is selected @@ -58,3 +69,33 @@ class ListWidgetWithDnD(QtGui.QListWidget): 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(): + if os.path.isfile(url.toLocalFile()): + Receiver.send_message(u'%s_dnd' % self.mimeDataText, + url.toLocalFile()) + else: + event.ignore() diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 66bf89f49..2b2e8c6e3 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -252,7 +252,6 @@ class MediaManagerItem(QtGui.QWidget): 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,27 +338,57 @@ class MediaManagerItem(QtGui.QWidget): 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(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()) + def contextMenu(self, point): item = self.listView.itemAt(point) # Decide if we have to show the context menu or not. diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 351e5bbc6..6d86097f2 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -1239,7 +1239,14 @@ class ServiceManager(QtGui.QWidget): 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.loadFile(filename) + elif event.mimeData().hasText(): plugin = unicode(event.mimeData().text()) item = self.serviceManagerList.itemAt(event.pos()) # ServiceManager started the drag and drop diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index 3c4489bbc..09811ead7 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -52,6 +52,10 @@ class ImageMediaItem(MediaManagerItem): 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() + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'images_dnd'), self.loadFile) def retranslateUi(self): self.onNewPrompt = translate('ImagePlugin.MediaItem', @@ -131,6 +135,7 @@ class ImageMediaItem(MediaManagerItem): 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: diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index 77f91a529..54682dbf6 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -39,6 +39,8 @@ from PyQt4.phonon import Phonon 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 @@ class MediaMediaItem(MediaManagerItem): 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,10 @@ class MediaMediaItem(MediaManagerItem): QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'openlp_phonon_creation'), self.createPhonon) + # Allow DnD from the desktop + self.listView.activateDnD() + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'media_dnd'), self.loadFile) def retranslateUi(self): self.onNewPrompt = translate('MediaPlugin.MediaItem', 'Select Media') @@ -201,17 +206,17 @@ class MediaMediaItem(MediaManagerItem): 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): diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index 07b490d83..abd597c6c 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -58,6 +58,10 @@ class PresentationMediaItem(MediaManagerItem): 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() + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'presentations_dnd'), self.loadFile) def retranslateUi(self): """ @@ -205,6 +209,7 @@ class PresentationMediaItem(MediaManagerItem): 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: From 644706a62a6558a76e072e2dbf4f3e0d91077337 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Tue, 2 Aug 2011 06:07:09 +0100 Subject: [PATCH 2/4] Fix review comments and cleanups --- openlp/core/lib/listwidgetwithdnd.py | 17 +++++-- openlp/core/lib/mediamanageritem.py | 50 +++++++++++-------- openlp/plugins/images/lib/mediaitem.py | 2 - openlp/plugins/media/lib/mediaitem.py | 2 - openlp/plugins/presentations/lib/mediaitem.py | 2 - 5 files changed, 42 insertions(+), 31 deletions(-) diff --git a/openlp/core/lib/listwidgetwithdnd.py b/openlp/core/lib/listwidgetwithdnd.py index 69bd67fdd..8474821a4 100644 --- a/openlp/core/lib/listwidgetwithdnd.py +++ b/openlp/core/lib/listwidgetwithdnd.py @@ -51,6 +51,9 @@ class ListWidgetWithDnD(QtGui.QListWidget): """ 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): """ @@ -71,7 +74,7 @@ class ListWidgetWithDnD(QtGui.QListWidget): drag.start(QtCore.Qt.CopyAction) def dragEnterEvent(self, event): - if event.mimeData().hasUrls: + if event.mimeData().hasUrls(): event.accept() else: event.ignore() @@ -93,9 +96,15 @@ class ListWidgetWithDnD(QtGui.QListWidget): if event.mimeData().hasUrls(): event.setDropAction(QtCore.Qt.CopyAction) event.accept() + files = [] for url in event.mimeData().urls(): - if os.path.isfile(url.toLocalFile()): - Receiver.send_message(u'%s_dnd' % self.mimeDataText, - url.toLocalFile()) + 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() diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 2b2e8c6e3..7852a0d5c 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -341,25 +341,31 @@ class MediaManagerItem(QtGui.QWidget): self.validateAndLoad(files) Receiver.send_message(u'cursor_normal') - def loadFile(self, filename): + def loadFile(self, files): """ - Turn file from Drag and Drop into a array so the Validate code - can runn it. + Turn file from Drag and Drop into an array so the Validate code + can run it. - ``filename`` - The file to be loaded + ``files`` + The list of files 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]) + 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( + translate('OpenLP.MediaManagerItem', + 'Invalid File Type'), + unicode(translate('OpenLP.MediaManagerItem', + 'Invalid File %s.\nSuffix not supported')) + % file) + errorShown = True + else: + newFiles.append(file) + if file: + self.validateAndLoad(newFiles) def validateAndLoad(self, files): """ @@ -373,14 +379,11 @@ class MediaManagerItem(QtGui.QWidget): 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: - critical_error_message_box( - UiStrings().Duplicate, - unicode(translate('OpenLP.MediaManagerItem', - 'Duplicate filename %s.\nThis filename is already in ' - 'the list')) % filename) + duplicatesFound = True else: newFiles.append(file) self.loadList(newFiles) @@ -388,6 +391,11 @@ class MediaManagerItem(QtGui.QWidget): SettingsManager.set_last_dir(self.settingsSection, lastDir) SettingsManager.set_list(self.settingsSection, self.settingsSection, self.getFileList()) + 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) diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index 09811ead7..acd420880 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -54,8 +54,6 @@ class ImageMediaItem(MediaManagerItem): QtCore.SIGNAL(u'live_theme_changed'), self.liveThemeChanged) # Allow DnD from the desktop self.listView.activateDnD() - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'images_dnd'), self.loadFile) def retranslateUi(self): self.onNewPrompt = translate('ImagePlugin.MediaItem', diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index 54682dbf6..e3c36bd77 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -63,8 +63,6 @@ class MediaMediaItem(MediaManagerItem): self.createPhonon) # Allow DnD from the desktop self.listView.activateDnD() - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'media_dnd'), self.loadFile) def retranslateUi(self): self.onNewPrompt = translate('MediaPlugin.MediaItem', 'Select Media') diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index abd597c6c..85721c65d 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -60,8 +60,6 @@ class PresentationMediaItem(MediaManagerItem): QtCore.SIGNAL(u'mediaitem_presentation_rebuild'), self.rebuild) # Allow DnD from the desktop self.listView.activateDnD() - QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'presentations_dnd'), self.loadFile) def retranslateUi(self): """ From 0b4616542934b24a8a8860aebeee688716e8964f Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Tue, 2 Aug 2011 19:17:07 +0100 Subject: [PATCH 3/4] Last set of fixes --- openlp/core/lib/mediamanageritem.py | 11 ++++---- openlp/core/ui/servicemanager.py | 31 +++++++++++++++------ openlp/plugins/songusage/songusageplugin.py | 2 +- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 7852a0d5c..a721fabf6 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -386,11 +386,12 @@ class MediaManagerItem(QtGui.QWidget): duplicatesFound = True 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()) + 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()) if duplicatesFound: critical_error_message_box( UiStrings().Duplicate, diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 6d86097f2..0755a0143 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -408,20 +408,33 @@ class ServiceManager(QtGui.QWidget): 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) @@ -1245,7 +1258,7 @@ class ServiceManager(QtGui.QWidget): for url in event.mimeData().urls(): filename = unicode(url.toLocalFile()) if filename.endswith(u'.osz'): - self.loadFile(filename) + self.onLoadServiceClicked(filename) elif event.mimeData().hasText(): plugin = unicode(event.mimeData().text()) item = self.serviceManagerList.itemAt(event.pos()) diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py index a657d700d..4ca23aeb0 100644 --- a/openlp/plugins/songusage/songusageplugin.py +++ b/openlp/plugins/songusage/songusageplugin.py @@ -91,8 +91,8 @@ class SongUsagePlugin(Plugin): self.toolsMenu.addAction(self.songUsageMenu.menuAction()) self.songUsageMenu.addAction(self.songUsageStatus) self.songUsageMenu.addSeparator() - self.songUsageMenu.addAction(self.songUsageDelete) self.songUsageMenu.addAction(self.songUsageReport) + self.songUsageMenu.addAction(self.songUsageDelete) self.songUsageActiveButton = QtGui.QToolButton( self.formparent.statusBar) self.songUsageActiveButton.setCheckable(True) From 5ff39a7d83cd9c67295dd435bf234a72f77ef340 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Wed, 3 Aug 2011 16:52:29 +0100 Subject: [PATCH 4/4] Fix missing() --- openlp/core/lib/listwidgetwithdnd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/core/lib/listwidgetwithdnd.py b/openlp/core/lib/listwidgetwithdnd.py index 8474821a4..69fb23092 100644 --- a/openlp/core/lib/listwidgetwithdnd.py +++ b/openlp/core/lib/listwidgetwithdnd.py @@ -80,7 +80,7 @@ class ListWidgetWithDnD(QtGui.QListWidget): event.ignore() def dragMoveEvent(self, event): - if event.mimeData().hasUrls: + if event.mimeData().hasUrls(): event.setDropAction(QtCore.Qt.CopyAction) event.accept() else: