[graphics/koko] src: Added undo when deleting a file

Oliver Beard <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit 7856966a0d9146274988c260d578acd54a546ba5 by Oliver Beard, on behalf of Jan Miksa.
Committed on 01/08/2026 at 20:13.
Pushed by olib into branch 'master'.

Added undo when deleting a file

Added passive notification to undo when files are deleted

BUG: 519270

M  +14   -1    src/filemenumanager.cpp
M  +2    -0    src/filemenumanager.h
M  +15   -0    src/qml/gallery/GalleryPage.qml
M  +15   -0    src/qml/mediaview/MediaViewPage.qml

https://invent.kde.org/graphics/koko/-/commit/7856966a0d9146274988c260d578acd54a546ba5

diff --git a/src/filemenumanager.cpp b/src/filemenumanager.cpp
index 6c7bb9dd..ea78b667 100644
--- a/src/filemenumanager.cpp
+++ b/src/filemenumanager.cpp
@@ -43,6 +43,7 @@
 #include <KIO/Paste>
 #include <KIO/PasteJob>
 #include <KIO/RenameFileDialog>
+#include <KIO/RestoreJob>
 #include <KIO/WidgetsAskUserActionHandler>
 
 using namespace Qt::StringLiterals;
@@ -167,6 +168,10 @@ bool FileMenuManager::canProperties() const
     return m_canProperties;
 }
 
+void FileMenuManager::undoTrash(QList<QUrl> urls) {
+    KIO::restoreFromTrash(urls);
+}
+
 void FileMenuManager::updateActions()
 {
     KirigamiActions::ActionCollection *collection = KirigamiActions::ActionCollections::self()->collection(u"org.kde.koko.file"_s);
@@ -453,11 +458,19 @@ void FileMenuManager::updateActions()
                 return;
             }
             auto handler = new KIO::WidgetsAskUserActionHandler(this);
-            connect(handler, &KIO::WidgetsAskUserActionHandler::askUserDeleteResult, [handler](bool allow, const QList<QUrl> &urls) {
+            connect(handler, &KIO::WidgetsAskUserActionHandler::askUserDeleteResult, [this, handler](bool allow, const QList<QUrl> &urls) {
                 if (allow) {
                     auto job = KIO::trash(urls);
                     job->uiDelegate()->setAutoErrorHandlingEnabled(true);
                     KIO::FileUndoManager::self()->recordJob(KIO::FileUndoManager::Trash, urls, QUrl(QStringLiteral("trash:/")), job);
+
+                    auto trashUrls = std::make_shared<QList<QUrl>>();
+                    connect(job, &KIO::CopyJob::copyingDone, [trashUrls](KIO::Job *job, const QUrl &from, const QUrl &to, const QDateTime &mtime, bool directory, bool renamed) {
+                        *trashUrls << to;
+                    });
+                    connect(job, &KJob::finished, [this,trashUrls]() {
+                        Q_EMIT filesTrashed(*trashUrls);
+                    });
                 }
                 handler->deleteLater();
             });
diff --git a/src/filemenumanager.h b/src/filemenumanager.h
index df1252c9..de050a98 100644
--- a/src/filemenumanager.h
+++ b/src/filemenumanager.h
@@ -63,6 +63,7 @@ public:
     [[nodiscard]] bool canDeleteFile() const;
     [[nodiscard]] bool canPrint() const;
     [[nodiscard]] bool canProperties() const;
+    Q_INVOKABLE void undoTrash(QList<QUrl> urls);
 
 Q_SIGNALS:
     void urlsChanged();
@@ -82,6 +83,7 @@ Q_SIGNALS:
     void canPropertiesChanged();
 
     void pastedUrls(QList<QUrl> urls);
+    void filesTrashed(QList<QUrl> urls);
 
 private:
     QList<QUrl> m_urls;
diff --git a/src/qml/gallery/GalleryPage.qml b/src/qml/gallery/GalleryPage.qml
index 382095a7..73f8a004 100644
--- a/src/qml/gallery/GalleryPage.qml
+++ b/src/qml/gallery/GalleryPage.qml
@@ -173,6 +173,21 @@ Kirigami.ScrollablePage {
         exclusive: true
     }
 
+    Connections {
+        target: fileMenuManager
+
+        function onFilesTrashed(urls) {
+            mainWindow.showPassiveNotification(
+                i18ncp("@info", "%1 item moved to trash", "%1 item moved to trash", urls.length),
+                "long",
+                i18nc("@action:button Undo moving items to trash", "Undo"),
+                function() {
+                    fileMenuManager.undoTrash(urls);
+                }
+            );
+        }
+    }
+
     readonly property list<QtObject> toolBarActions: [
         // Selection
         Kirigami.Action {
diff --git a/src/qml/mediaview/MediaViewPage.qml b/src/qml/mediaview/MediaViewPage.qml
index dbfb7b1e..6f92e5f6 100644
--- a/src/qml/mediaview/MediaViewPage.qml
+++ b/src/qml/mediaview/MediaViewPage.qml
@@ -64,6 +64,21 @@ Kirigami.Page {
         }
     }
 
+    Connections {
+        target: fileMenuManager
+
+        function onFilesTrashed(urls) {
+            mainWindow.showPassiveNotification(
+                i18ncp("@info","%1 item moved to trash", "%1 item moved to trash", urls.length),
+                "long",
+                i18nc("Undo moving items to trash", "Undo"),
+                function() {
+                    fileMenuManager.undoTrash(urls);
+                }
+            )
+        }
+    }
+
     // exit full screen on mobile, where only image view should be full screen.
     onBackRequested: {
         if (Kirigami.Settings.isMobile && applicationWindow().visibility === Window.FullScreen) {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.