From: Méven Car Date: Tue, 29 Nov 2022 18:16:59 +0000 (+0000) Subject: Exit the deleted directory when it is removed X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/a2c9c05de2dfabbb2bb614390c8e03023dad2bd1 Exit the deleted directory when it is removed If current directory is a local file, try to find nearest dir ancestor and open it. Display warning to the user. --- diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp index 0d2dcdafe..a38833481 100644 --- a/src/dolphinviewcontainer.cpp +++ b/src/dolphinviewcontainer.cpp @@ -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, %1 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{}; +} diff --git a/src/dolphinviewcontainer.h b/src/dolphinviewcontainer.h index 3ff575970..83d3ed1a1 100644 --- a/src/dolphinviewcontainer.h +++ b/src/dolphinviewcontainer.h @@ -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; diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index 1c48b2275..c08f8e964 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -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); diff --git a/src/kitemviews/kfileitemmodel.h b/src/kitemviews/kfileitemmodel.h index f4c09b6c5..74aec17a9 100644 --- a/src/kitemviews/kfileitemmodel.h +++ b/src/kitemviews/kfileitemmodel.h @@ -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; diff --git a/src/tests/kfileitemmodeltest.cpp b/src/tests/kfileitemmodeltest.cpp index f2560d9fc..fef8bd581 100644 --- a/src/tests/kfileitemmodeltest.cpp +++ b/src/tests/kfileitemmodeltest.cpp @@ -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; diff --git a/src/tests/testdir.cpp b/src/tests/testdir.cpp index 5d75a5343..6fbc4c426 100644 --- a/src/tests/testdir.cpp +++ b/src/tests/testdir.cpp @@ -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); diff --git a/src/tests/testdir.h b/src/tests/testdir.h index d537f9574..921a89185 100644 --- a/src/tests/testdir.h +++ b/src/tests/testdir.h @@ -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); diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index 1da3ebf85..5f331dc27 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -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); diff --git a/src/views/dolphinview.h b/src/views/dolphinview.h index aff4c51a8..50b1b9270 100644 --- a/src/views/dolphinview.h +++ b/src/views/dolphinview.h @@ -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;