diff --git a/src/kioexec/kioexecd.h b/src/kioexec/kioexecd.h --- a/src/kioexec/kioexecd.h +++ b/src/kioexec/kioexecd.h @@ -39,14 +39,21 @@ public Q_SLOTS: void watch(const QString &path, const QString &destUrl); + // @since 5.50 + void watchCommand(const QString &path, const QString &destUrl, const QString &command); + void removeWatchAndDirectory(const QString &path, const QString &command); private Q_SLOTS: void slotDirty(const QString &path); - void slotDeleted(const QString &path); private: KDirWatch *m_watcher; + // temporary file and remote file QMap m_watched; + // application and temporary file + QMap m_openedBy; + // counter for application + QMap m_appCounter; }; #endif diff --git a/src/kioexec/kioexecd.cpp b/src/kioexec/kioexecd.cpp --- a/src/kioexec/kioexecd.cpp +++ b/src/kioexec/kioexecd.cpp @@ -46,17 +46,17 @@ m_watcher = new KDirWatch(this); connect(m_watcher, &KDirWatch::dirty, this, &KIOExecd::slotDirty); - connect(m_watcher, &KDirWatch::deleted, this, &KIOExecd::slotDeleted); + connect(m_watcher, &KDirWatch::created, this, &KIOExecd::slotDirty); } KIOExecd::~KIOExecd() { + // Remove the remaining temporary directories with all their files. for (auto it = m_watched.constBegin(); it != m_watched.constEnd(); ++it) { QFileInfo info(it.key()); const auto parentDir = info.path(); qCDebug(KIOEXEC) << "About to delete" << parentDir << "containing" << info.fileName(); - QFile::remove(it.key()); - QDir().rmdir(parentDir); + QDir(parentDir).removeRecursively(); } } @@ -69,6 +69,24 @@ qCDebug(KIOEXEC) << "Going to watch" << path << "for changes, remote destination is" << destUrl; + // Watch the temporary file for modifications or creations + m_watcher->addFile(path); + m_watched.insert(path, QUrl(destUrl)); +} + +void KIOExecd::watchCommand(const QString &path, const QString &destUrl, const QString &command) +{ + m_openedBy.insertMulti(command, path); + m_appCounter.insertMulti(command, 1); + + if (m_watched.contains(path)) { + qCDebug(KIOEXEC) << "Already watching" << path; + return; + } + + qCDebug(KIOEXEC) << "Going to watch" << path << "for changes, remote destination is" << destUrl; + + // Watch the temporary file for modifications or creations m_watcher->addFile(path); m_watched.insert(path, QUrl(destUrl)); } @@ -96,15 +114,28 @@ }); } -void KIOExecd::slotDeleted(const QString &path) +void KIOExecd::removeWatchAndDirectory(const QString &tempFilePath, const QString &command) { - if (!m_watched.contains(path)) { + if (!m_watched.contains(tempFilePath)) { return; } - qCDebug(KIOEXEC) << "Going to forget" << path; - m_watcher->removeFile(path); - m_watched.remove(path); + m_appCounter.take(command); + // If the command does not have more opened files, stop watching + if (!m_appCounter.contains(command)) { + // Remove all the directories used by command + for (auto it = m_openedBy.constBegin(); it != m_openedBy.constEnd(); ++it) { + if (it.key() == command) { + m_watcher->removeFile(it.value()); + m_watched.remove(it.value()); + QFileInfo info(it.value()); + const auto parentDir = info.path(); + qCDebug(KIOEXEC) << "About to delete" << parentDir << "containing" << info.fileName(); + QDir(parentDir).removeRecursively(); + } + } + m_openedBy.remove(command); + } } #include "kioexecd.moc" diff --git a/src/kioexec/main.cpp b/src/kioexec/main.cpp --- a/src/kioexec/main.cpp +++ b/src/kioexec/main.cpp @@ -160,7 +160,7 @@ const QString dest = copyJob->srcUrl().toString(); qDebug() << "Telling kioexecd to watch path" << path << "dest" << dest; OrgKdeKIOExecdInterface kioexecd(QStringLiteral("org.kde.kioexecd"), QStringLiteral("/modules/kioexecd"), QDBusConnection::sessionBus()); - kioexecd.watch(path, dest); + kioexecd.watchCommand(path, dest, command.left(command.indexOf(QLatin1Char(' ')))); mUseDaemon = !kioexecd.lastError().isValid(); if (!mUseDaemon) { qDebug() << "Not using kioexecd"; @@ -258,9 +258,13 @@ QThread::currentThread()->sleep(180); // 3 mn const QString parentDir = info.path(); qDebug() << "about to delete" << parentDir << "containing" << info.fileName(); - QFile(QFile::encodeName(src)).remove(); - QDir().rmdir(parentDir); + QDir(parentDir).removeRecursively(); } + if (mUseDaemon && exit_code == 0) { + OrgKdeKIOExecdInterface kioexecd(QStringLiteral("org.kde.kioexecd"), QStringLiteral("/modules/kioexecd"), QDBusConnection::sessionBus()); + kioexecd.removeWatchAndDirectory(src, command.left(command.indexOf(QLatin1Char(' ')))); + } + } mExited = true;