From ddc695ceccedaefcf32a0b9f8c7ffde5ac475826 Mon Sep 17 00:00:00 2001 From: Philipp Wolfer Date: Sat, 12 Aug 2023 18:53:57 +0200 Subject: [PATCH] PICARD-2696: Fix file deletion when shift-dropping files on Windows When dropping while pressing shift on Windows the files get sent as a "move" event to the application. Accepting this results in file deletion. Picard must always handle such events as "copy" to avoid this. --- picard/ui/coverartbox.py | 13 +++++-------- picard/ui/itemviews.py | 12 +++++++++--- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/picard/ui/coverartbox.py b/picard/ui/coverartbox.py index 54f390d73f..3f74963096 100644 --- a/picard/ui/coverartbox.py +++ b/picard/ui/coverartbox.py @@ -127,13 +127,9 @@ def __eq__(self, other): else: return True - @staticmethod - def dragEnterEvent(event): - event.acceptProposedAction() - - @staticmethod - def dragMoveEvent(event): - event.acceptProposedAction() + def dragEnterEvent(self, event): + event.setDropAction(QtCore.Qt.DropAction.CopyAction) + event.accept() def dropEvent(self, event): accepted = False @@ -170,7 +166,8 @@ def dropEvent(self, event): self.image_dropped.emit(QtCore.QUrl(''), dropped_data) if accepted: - event.acceptProposedAction() + event.setDropAction(QtCore.Qt.DropAction.CopyAction) + event.accept() def scaled(self, *dimensions): return (round(self.pixel_ratio * dimension) for dimension in dimensions) diff --git a/picard/ui/itemviews.py b/picard/ui/itemviews.py index 07d227b529..7032c54364 100644 --- a/picard/ui/itemviews.py +++ b/picard/ui/itemviews.py @@ -6,7 +6,7 @@ # Copyright (C) 2007 Robert Kaye # Copyright (C) 2008 Gary van der Merwe # Copyright (C) 2008 Hendrik van Antwerpen -# Copyright (C) 2008-2011, 2014-2015, 2018-2022 Philipp Wolfer +# Copyright (C) 2008-2011, 2014-2015, 2018-2023 Philipp Wolfer # Copyright (C) 2009 Carlin Mangar # Copyright (C) 2009 Nikolai Prokoschenko # Copyright (C) 2011 Tim Blechmann @@ -695,7 +695,7 @@ def mimeTypes(self): return ["text/uri-list", "application/picard.album-list"] def dragEnterEvent(self, event): - if event.mimeData().hasUrls(): + if not event.source() or event.mimeData().hasUrls(): event.setDropAction(QtCore.Qt.DropAction.CopyAction) event.accept() else: @@ -767,7 +767,13 @@ def dropEvent(self, event): # assigned to the same track. if event.keyboardModifiers() == QtCore.Qt.KeyboardModifier.AltModifier: self._move_to_multi_tracks = False - return QtWidgets.QTreeView.dropEvent(self, event) + QtWidgets.QTreeView.dropEvent(self, event) + # The parent dropEvent implementation automatically accepts the proposed + # action. Override this, for external drops we never support move (which + # can result in file deletion, e.g. on Windows). + if event.isAccepted() and (not event.source() or event.mimeData().hasUrls()): + event.setDropAction(QtCore.Qt.DropAction.CopyAction) + event.accept() def dropMimeData(self, parent, index, data, action): target = None