]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Ignore drops-onto-items from invalid places items
authorElvis Angelaccio <elvis.angelaccio@kde.org>
Fri, 21 Apr 2017 11:16:05 +0000 (13:16 +0200)
committerElvis Angelaccio <elvis.angelaccio@kde.org>
Sun, 11 Jun 2017 17:11:56 +0000 (19:11 +0200)
If the QMimeData object created by PlacesItemModel doesn't have any url
set (e.g. when dragging unmounted devices), it is detected by the
resulting DropJob as "drop raw data" because the mimeData has one format set
(the internalMimeType() used for dragging between places items).

This results in a crash because the DropJob schedules a PasteJob, but in
the meantime the QDrag from Dolphin ends and deletes the mimeData object
that was passed to the paste job.

The fix is to prevent the DropJob in the first place. We can introduce a
new internal mimetype that we use to blacklist drops-onto-items (while
still allowing drops-between-items). This way PlacesItemModel can set
the blacklist flag if the mimeData is being created without urls.

BUG: 373005
FIXED-IN: 17.04.3

Test Plan:
Drag and drop an unmounted device to another place item or the DolphinView, doesn't crash anymore.
Dropping the unmounted device between two places item still works.

Differential Revision: https://phabricator.kde.org/D5535

src/kitemviews/kitemlistcontroller.cpp
src/kitemviews/kitemmodelbase.cpp
src/kitemviews/kitemmodelbase.h
src/panels/places/placesitemmodel.cpp

index a9596977105e9c43698bd4fcc4924ad5bed4da56..3731895d0a982cf04da4942bcd9bb1b3e6d6fc21 100644 (file)
@@ -928,7 +928,7 @@ bool KItemListController::dropEvent(QGraphicsSceneDragDropEvent* event, const QT
         // Something has been dropped between two items.
         m_view->hideDropIndicator();
         emit aboveItemDropEvent(dropAboveIndex, event);
-    } else {
+    } else if (!event->mimeData()->hasFormat(m_model->blacklistItemDropEventMimeType())) {
         // Something has been dropped on an item or on an empty part of the view.
         emit itemDropEvent(m_view->itemAt(pos), event);
     }
index bf41b1c84bc47a45c5cf08c010734bff2d663131..ee7e81084a6b46b5bb11731e4adfb3041854502b 100644 (file)
@@ -142,6 +142,11 @@ bool KItemModelBase::supportsDropping(int index) const
     return false;
 }
 
+QString KItemModelBase::blacklistItemDropEventMimeType() const
+{
+    return QStringLiteral("application/x-dolphin-blacklist-drop");
+}
+
 void KItemModelBase::onGroupedSortingChanged(bool current)
 {
     Q_UNUSED(current);
index bd5ca1d652cfb8f7b9bad39704f9d03395a08887..45ad1f61ab99737ca2076c6929ec26c5feff5e14 100644 (file)
@@ -172,6 +172,16 @@ public:
     // decision whether it accepts the drop?
     virtual bool supportsDropping(int index) const;
 
+    /**
+     * @return An internal mimetype to signal that an itemDropEvent() should be rejected by
+     *         the receiving model.
+     *
+     *         This mimeType can be used in createMimeData() to notify that the
+     *         drop-onto-items events should be ignored, while the drop-between-items
+     *         ones should be still accepted.
+     */
+    QString blacklistItemDropEventMimeType() const;
+
 signals:
     /**
      * Is emitted if one or more items have been inserted. Each item-range consists
index a4741e74693836e031a762d09758de8e37af2bbb..04dac81b73dd00cf7d15212e0d966051116cd7bf 100644 (file)
@@ -376,6 +376,9 @@ QMimeData* PlacesItemModel::createMimeData(const KItemSet& indexes) const
     QMimeData* mimeData = new QMimeData();
     if (!urls.isEmpty()) {
         mimeData->setUrls(urls);
+    } else {
+        // #378954: prevent itemDropEvent() drops if there isn't a source url.
+        mimeData->setData(blacklistItemDropEventMimeType(), QByteArrayLiteral("true"));
     }
     mimeData->setData(internalMimeType(), itemData);