Commit 9074c103 authored by Jan Paul Batrina's avatar Jan Paul Batrina Committed by Elvis Angelaccio
Browse files

Display confirmation dialog only once when files in archive are modified

Since QFileSystemWatcher::fileChanged is emitted everytime flush()
is called on a file, slotWatchedFileModified gets called multiple times,
especially for large files. (see

If no new fileChanged signal is emitted 200ms after the last one,
we interpret that as "the file has been fully written"

200ms was arbitrarily chosen to be a balance between a long enough flush interval
and "instant" feedback to the user, but it can be fine tuned later.

BUG: 382606
parent 4beda227
......@@ -99,6 +99,16 @@ Part::Part(QWidget *parentWidget, QObject *parent, const KPluginMetaData &metaDa
new DndExtractAdaptor(this);
// Since QFileSystemWatcher::fileChanged is emitted for each part of the file that is flushed,
// we wait a bit to ensure that the last flush will write the file completely
// BUG: 382606, also see
// TODO: Find the most optimal flush interval
connect(&m_watchedFileChangeTimer, &QTimer::timeout, this, [this]() {
const QString pathName = QStringLiteral("/DndExtract/%1").arg(s_instanceCounter++);
if (!QDBusConnection::sessionBus().registerObject(pathName, this)) {
qCCritical(ARK) << "Could not register a D-Bus object for drag'n'drop";
......@@ -1037,7 +1047,8 @@ void Part::slotOpenExtractedEntry(KJob *job)
const QString fullName = openJob->validatedFilePath();
if (isArchiveWritable()) {
m_fileWatcher.reset(new QFileSystemWatcher);
connect(m_fileWatcher.get(), &QFileSystemWatcher::fileChanged, this, &Part::slotWatchedFileModified);
connect(m_fileWatcher.get(), &QFileSystemWatcher::fileChanged, this, &Part::slotResetFileChangeTimer);
} else {
// If archive is readonly set temporarily extracted file to readonly as
......@@ -1079,6 +1090,22 @@ void Part::slotPreviewExtractedEntry(KJob *job)
void Part::slotResetFileChangeTimer(const QString& file)
const bool timerActive = m_watchedFileChangeTimer.isActive();
// Check if a different file was changed while monitoring the previous file.
if (timerActive && !m_lastChangedFilename.isEmpty() && file != m_lastChangedFilename) {
const QString prevFile = m_lastChangedFilename;
QTimer::singleShot(0, this, [this, prevFile]() {
m_lastChangedFilename = file;
void Part::slotWatchedFileModified(const QString& file)
qCDebug(ARK) << "Watched file modified:" << file;
......@@ -33,6 +33,7 @@
#include <KMessageWidget>
#include <QModelIndex>
#include <QTimer>
class ArchiveModel;
class ArchiveSortFilterModel;
......@@ -159,6 +160,7 @@ private Q_SLOTS:
void setBusyGui();
void setReadyGui();
void setFileNameFromArchive();
void slotResetFileChangeTimer(const QString& file);
void slotWatchedFileModified(const QString& file);
void slotShowComment();
void slotAddComment();
......@@ -228,6 +230,9 @@ private:
Kerfuffle::Archive::Entry *m_destination;
QModelIndexList m_cutIndexes;
QTimer m_watchedFileChangeTimer;
QString m_lastChangedFilename;
KAbstractWidgetJobTracker *m_jobTracker;
KParts::StatusBarExtension *m_statusBarExtension;
QVBoxLayout *m_vlayout;
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment