]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/panels/places/placesitemmodel.cpp
Prevent folders from drag and dropping onto themselves in dolphin main view
[dolphin.git] / src / panels / places / placesitemmodel.cpp
index 8a02ead015b71e36714a6927de4412ddbda7088d..680d513b5c166dcd214984eaa3d9b5ac44da58d8 100644 (file)
@@ -22,6 +22,7 @@
  ***************************************************************************/
 
 #include "placesitemmodel.h"
+#include "placesitemsignalhandler.h"
 
 #include "dolphin_generalsettings.h"
 
@@ -32,7 +33,6 @@
 #include <KProtocolInfo>
 #include <KLocalizedString>
 #include <QStandardPaths>
-#include <KUser>
 #include <KAboutData>
 #include "placesitem.h"
 #include <QAction>
@@ -78,6 +78,7 @@ PlacesItemModel::PlacesItemModel(QObject* parent) :
     m_systemBookmarksIndexes(),
     m_bookmarkedItems(),
     m_hiddenItemToRemove(-1),
+    m_deviceToTearDown(0),
     m_updateBookmarksTimer(0),
     m_storageSetupInProgress()
 {
@@ -249,7 +250,7 @@ QAction* PlacesItemModel::ejectAction(int index) const
 {
     const PlacesItem* item = placesItem(index);
     if (item && item->device().is<Solid::OpticalDisc>()) {
-        return new QAction(QIcon::fromTheme(QStringLiteral("media-eject")), i18nc("@item", "Eject '%1'", item->text()), 0);
+        return new QAction(QIcon::fromTheme(QStringLiteral("media-eject")), i18nc("@item", "Eject"), 0);
     }
 
     return 0;
@@ -283,14 +284,13 @@ QAction* PlacesItemModel::teardownAction(int index) const
 
     QString iconName;
     QString text;
-    const QString label = item->text();
     if (device.is<Solid::OpticalDisc>()) {
-        text = i18nc("@item", "Release '%1'", label);
+        text = i18nc("@item", "Release");
     } else if (removable || hotPluggable) {
-        text = i18nc("@item", "Safely Remove '%1'", label);
+        text = i18nc("@item", "Safely Remove");
         iconName = QStringLiteral("media-eject");
     } else {
-        text = i18nc("@item", "Unmount '%1'", label);
+        text = i18nc("@item", "Unmount");
         iconName = QStringLiteral("media-eject");
     }
 
@@ -308,7 +308,7 @@ void PlacesItemModel::requestEject(int index)
         Solid::OpticalDrive* drive = item->device().parent().as<Solid::OpticalDrive>();
         if (drive) {
             connect(drive, &Solid::OpticalDrive::ejectDone,
-                    this, &PlacesItemModel::slotStorageTeardownDone);
+                    this, &PlacesItemModel::slotStorageTearDownDone);
             drive->eject();
         } else {
             const QString label = item->text();
@@ -318,15 +318,19 @@ void PlacesItemModel::requestEject(int index)
     }
 }
 
-void PlacesItemModel::requestTeardown(int index)
+void PlacesItemModel::requestTearDown(int index)
 {
     const PlacesItem* item = placesItem(index);
     if (item) {
-        Solid::StorageAccess* access = item->device().as<Solid::StorageAccess>();
-        if (access) {
-            connect(access, &Solid::StorageAccess::teardownDone,
-                    this, &PlacesItemModel::slotStorageTeardownDone);
-            access->teardown();
+        Solid::StorageAccess *tmp = item->device().as<Solid::StorageAccess>();
+        if (tmp) {
+            m_deviceToTearDown = tmp;
+            // disconnect the Solid::StorageAccess::teardownRequested
+            // to prevent emitting PlacesItemModel::storageTearDownExternallyRequested
+            // after we have emitted PlacesItemModel::storageTearDownRequested
+            disconnect(tmp, &Solid::StorageAccess::teardownRequested,
+                       item->signalHandler(), &PlacesItemSignalHandler::onTearDownRequested);
+            emit storageTearDownRequested(tmp->filePath());
         }
     }
 }
@@ -378,6 +382,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);
 
@@ -549,7 +556,11 @@ void PlacesItemModel::slotDeviceAdded(const QString& udi)
 
     m_availableDevices << udi;
     const KBookmark bookmark = PlacesItem::createDeviceBookmark(m_bookmarkManager, udi);
-    appendItem(new PlacesItem(bookmark));
+
+    PlacesItem *item = new PlacesItem(bookmark);
+    appendItem(item);
+    connect(item->signalHandler(), &PlacesItemSignalHandler::tearDownExternallyRequested,
+            this, &PlacesItemModel::storageTearDownExternallyRequested);
 }
 
 void PlacesItemModel::slotDeviceRemoved(const QString& udi)
@@ -575,11 +586,13 @@ void PlacesItemModel::slotDeviceRemoved(const QString& udi)
     }
 }
 
-void PlacesItemModel::slotStorageTeardownDone(Solid::ErrorType error, const QVariant& errorData)
+void PlacesItemModel::slotStorageTearDownDone(Solid::ErrorType error, const QVariant& errorData)
 {
     if (error && errorData.isValid()) {
         emit errorMessage(errorData.toString());
     }
+    m_deviceToTearDown->disconnect();
+    m_deviceToTearDown = nullptr;
 }
 
 void PlacesItemModel::slotStorageSetupDone(Solid::ErrorType error,
@@ -785,7 +798,10 @@ void PlacesItemModel::loadBookmarks()
     devicesItems.reserve(devicesItems.count() + devices.count());
     foreach (const QString& udi, devices) {
         const KBookmark bookmark = PlacesItem::createDeviceBookmark(m_bookmarkManager, udi);
-        devicesItems.append(new PlacesItem(bookmark));
+        PlacesItem *item = new PlacesItem(bookmark);
+        devicesItems.append(item);
+        connect(item->signalHandler(), &PlacesItemSignalHandler::tearDownExternallyRequested,
+                this, &PlacesItemModel::storageTearDownExternallyRequested);
     }
 
     QList<PlacesItem*> items;
@@ -889,7 +905,7 @@ void PlacesItemModel::createSystemBookmarks()
     // i18nc call is done after reading the bookmark. The reason why the i18nc call is not
     // done here is because otherwise switching the language would not result in retranslating the
     // bookmarks.
-    m_systemBookmarks.append(SystemBookmarkData(QUrl::fromLocalFile(KUser().homeDir()),
+    m_systemBookmarks.append(SystemBookmarkData(QUrl::fromLocalFile(QDir::homePath()),
                                                 QStringLiteral("user-home"),
                                                 I18N_NOOP2("KFile System Bookmarks", "Home")));
     m_systemBookmarks.append(SystemBookmarkData(QUrl(QStringLiteral("remote:/")),
@@ -939,6 +955,15 @@ void PlacesItemModel::clear() {
     KStandardItemModel::clear();
 }
 
+void PlacesItemModel::proceedWithTearDown()
+{
+    Q_ASSERT(m_deviceToTearDown);
+
+    connect(m_deviceToTearDown, &Solid::StorageAccess::teardownDone,
+            this, &PlacesItemModel::slotStorageTearDownDone);
+    m_deviceToTearDown->teardown();
+}
+
 void PlacesItemModel::initializeAvailableDevices()
 {
     QString predicate(QStringLiteral("[[[[ StorageVolume.ignored == false AND [ StorageVolume.usage == 'FileSystem' OR StorageVolume.usage == 'Encrypted' ]]"
@@ -1134,6 +1159,12 @@ QString PlacesItemModel::timelineDateString(int year, int month, int day)
     return date;
 }
 
+bool PlacesItemModel::isDir(int index) const
+{
+    Q_UNUSED(index);
+    return true;
+}
+
 QUrl PlacesItemModel::createSearchUrl(const QUrl& url)
 {
     QUrl searchUrl;