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 https://bugreports.qt.io/browse/QTBUG-8244)

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 https://bugreports.qt.io/browse/QTBUG-8244
// TODO: Find the most optimal flush interval
m_watchedFileChangeTimer.setSingleShot(true);
m_watchedFileChangeTimer.setInterval(200);
connect(&m_watchedFileChangeTimer, &QTimer::timeout, this, [this]() {
slotWatchedFileModified(m_lastChangedFilename);
});
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);
m_fileWatcher->addPath(fullName);
} else {
// If archive is readonly set temporarily extracted file to readonly as
......@@ -1079,6 +1090,22 @@ void Part::slotPreviewExtractedEntry(KJob *job)
setReadyGui();
}
void Part::slotResetFileChangeTimer(const QString& file)
{
const bool timerActive = m_watchedFileChangeTimer.isActive();
m_watchedFileChangeTimer.stop();
// 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]() {
slotWatchedFileModified(prevFile);
});
}
m_lastChangedFilename = file;
m_watchedFileChangeTimer.start();
}
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;
......
Markdown is supported
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