]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Exit the deleted directory when it is removed
authorMéven Car <meven.car@kdemail.net>
Tue, 29 Nov 2022 18:16:59 +0000 (18:16 +0000)
committerMéven Car <meven.car@kdemail.net>
Tue, 29 Nov 2022 18:16:59 +0000 (18:16 +0000)
If current directory is a local file, try to find nearest dir ancestor and
open it. Display warning to the user.

src/dolphinviewcontainer.cpp
src/dolphinviewcontainer.h
src/kitemviews/kfileitemmodel.cpp
src/kitemviews/kfileitemmodel.h
src/tests/kfileitemmodeltest.cpp
src/tests/testdir.cpp
src/tests/testdir.h
src/views/dolphinview.cpp
src/views/dolphinview.h

index 0d2dcdafe53feac583c98dc9d620a583901816ce..a388334819c9b40d11f13fba33cffd075fc71c29 100644 (file)
@@ -172,6 +172,8 @@ DolphinViewContainer::DolphinViewContainer(const QUrl& url, QWidget* parent) :
             this, &DolphinViewContainer::slotHiddenFilesShownChanged);
     connect(m_view, &DolphinView::sortHiddenLastChanged,
             this, &DolphinViewContainer::slotSortHiddenLastChanged);
+    connect(m_view, &DolphinView::currentDirectoryRemoved,
+            this, &DolphinViewContainer::slotCurrentDirectoryRemoved);
 
     // Initialize status bar
     m_statusBar = new DolphinStatusBar(this);
@@ -939,6 +941,19 @@ void DolphinViewContainer::slotSortHiddenLastChanged(bool hiddenLast)
     }
 }
 
+void DolphinViewContainer::slotCurrentDirectoryRemoved()
+{
+    const QString location(url().toDisplayString(QUrl::PreferLocalFile));
+    if (url().isLocalFile()) {
+        const QString dirPath = url().toLocalFile();
+        const QString newPath = getNearestExistingAncestorOfPath(dirPath);
+        const QUrl newUrl = QUrl::fromLocalFile(newPath);
+        setUrl(newUrl);
+    }
+
+    showMessage(xi18n("Current location changed, <filename>%1</filename> is no longer accessible.", location), Warning);
+}
+
 void DolphinViewContainer::slotOpenUrlFinished(KJob *job)
 {
     if (job->error() && job->error() != KIO::ERR_USER_CANCELED) {
@@ -967,3 +982,14 @@ void DolphinViewContainer::tryRestoreViewState()
         m_view->restoreState(stream);
     }
 }
+
+QString DolphinViewContainer::getNearestExistingAncestorOfPath(const QString& path) const
+{
+    QDir dir(path);
+    do {
+        dir.setPath(QDir::cleanPath(dir.filePath(QStringLiteral(".."))));
+    }
+    while (!dir.exists() && !dir.isRoot());
+
+    return dir.exists() ? dir.path() : QString{};
+}
index 3ff5759703062c15d31fcba4c52b06446ba9d2a4..83d3ed1a1be89dd27872720b467461cbbab97ace 100644 (file)
@@ -400,6 +400,7 @@ private Q_SLOTS:
 
     void slotHiddenFilesShownChanged(bool showHiddenFiles);
     void slotSortHiddenLastChanged(bool hiddenLast);
+    void slotCurrentDirectoryRemoved();
 
     void slotOpenUrlFinished(KJob* job);
 
@@ -421,6 +422,11 @@ private:
      */
     void tryRestoreViewState();
 
+    /**
+     * @return Path of nearest existing ancestor directory.
+     */
+    QString getNearestExistingAncestorOfPath(const QString& path) const;
+
 private:
     QGridLayout *m_topLayout;
 
index 1c48b22754d5e2dc97e53d8094f461ea371a6784..c08f8e964b3cd9e34532d6f92df1d2aeba9f2f8e 100644 (file)
@@ -1150,7 +1150,14 @@ void KFileItemModel::slotItemsDeleted(const KFileItemList& items)
     indexesToRemove.reserve(items.count());
     KFileItemList dirsChanged;
 
+    const auto currentDir = directory();
+
     for (const KFileItem& item : items) {
+        if (item.url() == currentDir) {
+            Q_EMIT currentDirectoryRemoved();
+            return;
+        }
+
         const int indexForItem = index(item);
         if (indexForItem >= 0) {
             indexesToRemove.append(indexForItem);
index f4c09b6c5eadd64e2319b57b5b00eed67f044ec4..74aec17a943dabf855613afef4b30bd76489778d 100644 (file)
@@ -263,6 +263,11 @@ Q_SIGNALS:
      */
     void fileItemsChanged(const KFileItemList &changedFileItems);
 
+    /**
+     * It is emitted when the parent directory was removed.
+     */
+    void currentDirectoryRemoved();
+
 protected:
     void onGroupedSortingChanged(bool current) override;
     void onSortRoleChanged(const QByteArray& current, const QByteArray& previous, bool resortItems = true) override;
index f2560d9fc482b373faf681c2eecb0b3819d80bc8..fef8bd58120c682e054bb5185fda753cd4175d78 100644 (file)
@@ -93,6 +93,7 @@ private Q_SLOTS:
     void testCreateMimeData();
     void testDeleteFileMoreThanOnce();
     void testInsertAfterExpand();
+    void testCurrentDirRemoved();
 
 private:
     QStringList itemsInModel() const;
@@ -2124,6 +2125,32 @@ void KFileItemModelTest::testInsertAfterExpand()
 
 }
 
+void KFileItemModelTest::testCurrentDirRemoved()
+{
+    m_model->m_dirLister->setAutoUpdate(true);
+    QSignalSpy currentDirectoryRemovedSpy(m_model, &KFileItemModel::currentDirectoryRemoved);
+    QVERIFY(currentDirectoryRemovedSpy.isValid());
+    QSignalSpy loadingCompletedSpy(m_model, &KFileItemModel::directoryLoadingCompleted);
+    QVERIFY(loadingCompletedSpy.isValid());
+    QSignalSpy dirListerClearSpy(m_model->m_dirLister, &KCoreDirLister::clear);
+    QVERIFY(dirListerClearSpy.isValid());
+
+    m_testDir->createFiles({"dir/a.txt", "dir/b.txt"});
+    m_model->loadDirectory(QUrl::fromLocalFile(m_testDir->path() + "/dir/"));
+    QVERIFY(loadingCompletedSpy.wait());
+    QCOMPARE(m_model->count(), 2);
+    QVERIFY(m_model->isConsistent());
+
+    m_testDir->removeDir("dir");
+    QVERIFY(currentDirectoryRemovedSpy.wait());
+
+    // dirLister calls clear
+    QCOMPARE(dirListerClearSpy.count(), 2);
+    QVERIFY(m_model->isConsistent());
+    QVERIFY(m_model->m_itemData.isEmpty());
+    QCOMPARE(m_model->count(), 0);
+}
+
 QStringList KFileItemModelTest::itemsInModel() const
 {
     QStringList items;
index 5d75a5343baaef7175b75993f4217e7b3b608b39..6fbc4c426aa69df2c1dbf2420820aece02ae1315 100644 (file)
@@ -96,6 +96,17 @@ void TestDir::removeFile(const QString& path)
     QFile::remove(absolutePath);
 }
 
+void TestDir::removeDir(const QString& path)
+{
+    QString absolutePath = path;
+    QFileInfo fileInfo(absolutePath);
+    if (!fileInfo.isAbsolute()) {
+        absolutePath = TestDir::path() + QLatin1Char('/') + path;
+    }
+    QDir dirToRemove = QDir(absolutePath);
+    dirToRemove.removeRecursively();
+}
+
 void TestDir::makePathAbsoluteAndCreateParents(QString& path)
 {
     QFileInfo fileInfo(path);
index d537f9574f54f0525e7a51ef400e694a36c908b3..921a891857361f37432997e6655db228c783b219 100644 (file)
@@ -37,6 +37,7 @@ public:
 
     void removeFile(const QString& path);
     void removeFiles(const QStringList& files);
+    void removeDir(const QString& path);
 
 private:
     void makePathAbsoluteAndCreateParents(QString& path);
index 1da3ebf858c5b5114e56f467510fe2c739d88264..5f331dc270a879f3f3fc669e0ce6630a35f037d5 100644 (file)
@@ -195,6 +195,7 @@ DolphinView::DolphinView(const QUrl& url, QWidget* parent) :
     connect(m_model, &KFileItemModel::directoryRedirection, this, &DolphinView::slotDirectoryRedirection);
     connect(m_model, &KFileItemModel::urlIsFileError,            this, &DolphinView::urlIsFileError);
     connect(m_model, &KFileItemModel::fileItemsChanged,            this, &DolphinView::fileItemsChanged);
+    connect(m_model, &KFileItemModel::currentDirectoryRemoved, this, &DolphinView::currentDirectoryRemoved);
 
     connect(this, &DolphinView::itemCountChanged,
             this, &DolphinView::updatePlaceholderLabel);
index aff4c51a84d2a3aa8ae2f9cfc4444b9398eb9fc9..50b1b927040603fa6051378ee7db7c5dc10f2447 100644 (file)
@@ -637,6 +637,11 @@ Q_SIGNALS:
 
     void fileItemsChanged(const KFileItemList &changedFileItems);
 
+    /**
+     * Emitted when the current directory of the model was removed.
+     */
+    void currentDirectoryRemoved();
+
 protected:
     /** Changes the zoom level if Control is pressed during a wheel event. */
     void wheelEvent(QWheelEvent* event) override;