┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMéven Car <[email protected]>2022-11-29 18:16:59 +0000
committerMéven Car <[email protected]>2022-11-29 18:16:59 +0000
commita2c9c05de2dfabbb2bb614390c8e03023dad2bd1 (patch)
tree5f34ae95e4cb0ea8ee95d3ee17c28b3cacd25ae9
parentde289800b22c654e8e3d8fbaea7bdb496a021b88 (diff)
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.
-rw-r--r--src/dolphinviewcontainer.cpp26
-rw-r--r--src/dolphinviewcontainer.h6
-rw-r--r--src/kitemviews/kfileitemmodel.cpp7
-rw-r--r--src/kitemviews/kfileitemmodel.h5
-rw-r--r--src/tests/kfileitemmodeltest.cpp27
-rw-r--r--src/tests/testdir.cpp11
-rw-r--r--src/tests/testdir.h1
-rw-r--r--src/views/dolphinview.cpp1
-rw-r--r--src/views/dolphinview.h5
9 files changed, 89 insertions, 0 deletions
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, <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{};
+}
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;