From 90759d026ade2052a5d40cb5c91be771ed89701e Mon Sep 17 00:00:00 2001 From: Philipp Wolfer Date: Sun, 13 Aug 2023 11:38:44 +0200 Subject: [PATCH] Handle Qt drag and drop IgnoreAction Also ensure dragEnterEvent and dragMoveEvent indicate the actually performed action (copy in our case). This influences the icon shown to the user while dragging. On Windows this will then show the actual copy icon even if the user has modifiers pressed. --- picard/ui/coverartbox.py | 4 ++++ picard/ui/itemviews.py | 14 +++++++++++--- picard/ui/options/plugins.py | 12 ++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/picard/ui/coverartbox.py b/picard/ui/coverartbox.py index 3f7496309..fa7f3fc0e 100644 --- a/picard/ui/coverartbox.py +++ b/picard/ui/coverartbox.py @@ -132,6 +132,10 @@ class CoverArtThumbnail(ActiveLabel): event.accept() def dropEvent(self, event): + if event.proposedAction() == QtCore.Qt.DropAction.IgnoreAction: + event.acceptProposedAction() + return + accepted = False # Chromium includes the actual data of the dragged image in the drop event. This # is useful for Google Images, where the url links to the page that contains the image diff --git a/picard/ui/itemviews.py b/picard/ui/itemviews.py index 7032c5436..1bb307009 100644 --- a/picard/ui/itemviews.py +++ b/picard/ui/itemviews.py @@ -695,11 +695,16 @@ class BaseTreeView(QtWidgets.QTreeWidget): return ["text/uri-list", "application/picard.album-list"] def dragEnterEvent(self, event): - if not event.source() or event.mimeData().hasUrls(): + super().dragEnterEvent(event) + if event.isAccepted() and (not event.source() or event.mimeData().hasUrls()): + event.setDropAction(QtCore.Qt.DropAction.CopyAction) + event.accept() + + def dragMoveEvent(self, event): + super().dragMoveEvent(event) + if event.isAccepted() and (not event.source() or event.mimeData().hasUrls()): event.setDropAction(QtCore.Qt.DropAction.CopyAction) event.accept() - else: - event.acceptProposedAction() def startDrag(self, supportedActions): """Start drag, *without* using pixmap.""" @@ -763,6 +768,9 @@ class BaseTreeView(QtWidgets.QTreeWidget): tagger.add_paths(new_paths, target=target) def dropEvent(self, event): + if event.proposedAction() == QtCore.Qt.DropAction.IgnoreAction: + event.acceptProposedAction() + return # Dropping with Alt key pressed forces all dropped files being # assigned to the same track. if event.keyboardModifiers() == QtCore.Qt.KeyboardModifier.AltModifier: diff --git a/picard/ui/options/plugins.py b/picard/ui/options/plugins.py index 086398f41..f1f946380 100644 --- a/picard/ui/options/plugins.py +++ b/picard/ui/options/plugins.py @@ -247,6 +247,7 @@ class PluginsOptionsPage(OptionsPage): plugins.mimeTypes = self.mimeTypes plugins.dropEvent = self.dropEvent plugins.dragEnterEvent = self.dragEnterEvent + plugins.dragMoveEvent = self.dragMoveEvent self.ui.install_plugin.clicked.connect(self.open_plugins) self.ui.folder_open.clicked.connect(self.open_plugin_dir) @@ -700,9 +701,20 @@ class PluginsOptionsPage(OptionsPage): event.setDropAction(QtCore.Qt.DropAction.CopyAction) event.accept() + def dragMoveEvent(self, event): + event.setDropAction(QtCore.Qt.DropAction.CopyAction) + event.accept() + def dropEvent(self, event): + if event.proposedAction() == QtCore.Qt.DropAction.IgnoreAction: + event.acceptProposedAction() + return + for path in (os.path.normpath(u.toLocalFile()) for u in event.mimeData().urls()): self.manager.install_plugin(path) + event.setDropAction(QtCore.Qt.DropAction.CopyAction) + event.accept() + register_options_page(PluginsOptionsPage)