Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/keepassxreboot/keepassxc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/FileWatcher.cpp30
-rw-r--r--src/core/FileWatcher.h7
-rw-r--r--src/gui/DatabaseWidget.cpp30
-rw-r--r--src/gui/DatabaseWidget.h1
-rw-r--r--src/gui/widgets/ElidedLabel.cpp2
5 files changed, 46 insertions, 24 deletions
diff --git a/src/core/FileWatcher.cpp b/src/core/FileWatcher.cpp
index 0d1def31a..fb8e95128 100644
--- a/src/core/FileWatcher.cpp
+++ b/src/core/FileWatcher.cpp
@@ -35,11 +35,10 @@ namespace
FileWatcher::FileWatcher(QObject* parent)
: QObject(parent)
- , m_ignoreFileChange(false)
{
- connect(&m_fileWatcher, SIGNAL(fileChanged(QString)), SLOT(onWatchedFileChanged()));
+ connect(&m_fileWatcher, SIGNAL(fileChanged(QString)), SLOT(checkFileChanged()));
+ connect(&m_fileChecksumTimer, SIGNAL(timeout()), SLOT(checkFileChanged()));
connect(&m_fileChangeDelayTimer, SIGNAL(timeout()), SIGNAL(fileChanged()));
- connect(&m_fileChecksumTimer, SIGNAL(timeout()), SLOT(checkFileChecksum()));
m_fileChangeDelayTimer.setSingleShot(true);
m_fileIgnoreDelayTimer.setSingleShot(true);
}
@@ -101,17 +100,6 @@ void FileWatcher::resume()
}
}
-void FileWatcher::onWatchedFileChanged()
-{
- // Don't notify if we are ignoring events or already started a notification chain
- if (shouldIgnoreChanges()) {
- return;
- }
-
- m_fileChecksum = calculateChecksum();
- m_fileChangeDelayTimer.start(0);
-}
-
bool FileWatcher::shouldIgnoreChanges()
{
return m_filePath.isEmpty() || m_ignoreFileChange || m_fileIgnoreDelayTimer.isActive()
@@ -123,15 +111,23 @@ bool FileWatcher::hasSameFileChecksum()
return calculateChecksum() == m_fileChecksum;
}
-void FileWatcher::checkFileChecksum()
+void FileWatcher::checkFileChanged()
{
if (shouldIgnoreChanges()) {
return;
}
- if (!hasSameFileChecksum()) {
- onWatchedFileChanged();
+ // Prevent reentrance
+ m_ignoreFileChange = true;
+
+ // Only trigger the change notice if there is a checksum mismatch
+ auto checksum = calculateChecksum();
+ if (checksum != m_fileChecksum) {
+ m_fileChecksum = checksum;
+ m_fileChangeDelayTimer.start(0);
}
+
+ m_ignoreFileChange = false;
}
QByteArray FileWatcher::calculateChecksum()
diff --git a/src/core/FileWatcher.h b/src/core/FileWatcher.h
index fea05fc84..9b55badc1 100644
--- a/src/core/FileWatcher.h
+++ b/src/core/FileWatcher.h
@@ -43,8 +43,7 @@ public slots:
void resume();
private slots:
- void onWatchedFileChanged();
- void checkFileChecksum();
+ void checkFileChanged();
private:
QByteArray calculateChecksum();
@@ -56,8 +55,8 @@ private:
QTimer m_fileChangeDelayTimer;
QTimer m_fileIgnoreDelayTimer;
QTimer m_fileChecksumTimer;
- int m_fileChecksumSizeBytes;
- bool m_ignoreFileChange;
+ int m_fileChecksumSizeBytes = -1;
+ bool m_ignoreFileChange = false;
};
class BulkFileWatcher : public QObject
diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp
index 04fad9a00..5c4bf39ac 100644
--- a/src/gui/DatabaseWidget.cpp
+++ b/src/gui/DatabaseWidget.cpp
@@ -275,6 +275,11 @@ bool DatabaseWidget::isEntryEditActive() const
return currentWidget() == m_editEntryWidget;
}
+bool DatabaseWidget::isGroupEditActive() const
+{
+ return currentWidget() == m_editGroupWidget;
+}
+
bool DatabaseWidget::isEditWidgetModified() const
{
if (currentWidget() == m_editEntryWidget) {
@@ -387,6 +392,8 @@ void DatabaseWidget::createEntry()
void DatabaseWidget::replaceDatabase(QSharedPointer<Database> db)
{
+ Q_ASSERT(!isEntryEditActive() && !isGroupEditActive());
+
// Save off new parent UUID which will be valid when creating a new entry
QUuid newParentUuid;
if (m_newParent) {
@@ -1421,7 +1428,8 @@ bool DatabaseWidget::lock()
void DatabaseWidget::reloadDatabaseFile()
{
- if (!m_db || isLocked()) {
+ // Ignore reload if we are locked or currently editing an entry or group
+ if (!m_db || isLocked() || isEntryEditActive() || isGroupEditActive()) {
return;
}
@@ -1441,6 +1449,11 @@ void DatabaseWidget::reloadDatabaseFile()
}
}
+ // Lock out interactions
+ m_entryView->setDisabled(true);
+ m_groupView->setDisabled(true);
+ QApplication::processEvents();
+
QString error;
auto db = QSharedPointer<Database>::create(m_db->filePath());
if (db->open(database()->key(), &error)) {
@@ -1480,6 +1493,10 @@ void DatabaseWidget::reloadDatabaseFile()
// Mark db as modified since existing data may differ from file or file was deleted
m_db->markAsModified();
}
+
+ // Return control
+ m_entryView->setDisabled(false);
+ m_groupView->setDisabled(false);
}
int DatabaseWidget::numberOfSelectedEntries() const
@@ -1620,11 +1637,20 @@ bool DatabaseWidget::save()
m_blockAutoSave = true;
++m_saveAttempts;
- // TODO: Make this async, but lock out the database widget to prevent re-entrance
+ // TODO: Make this async
+ // Lock out interactions
+ m_entryView->setDisabled(true);
+ m_groupView->setDisabled(true);
+ QApplication::processEvents();
+
bool useAtomicSaves = config()->get("UseAtomicSaves", true).toBool();
QString errorMessage;
bool ok = m_db->save(&errorMessage, useAtomicSaves, config()->get("BackupBeforeSave").toBool());
+ // Return control
+ m_entryView->setDisabled(false);
+ m_groupView->setDisabled(false);
+
if (ok) {
m_saveAttempts = 0;
m_blockAutoSave = false;
diff --git a/src/gui/DatabaseWidget.h b/src/gui/DatabaseWidget.h
index 6f40c65c5..9f0c5c976 100644
--- a/src/gui/DatabaseWidget.h
+++ b/src/gui/DatabaseWidget.h
@@ -81,6 +81,7 @@ public:
bool isLocked() const;
bool isSearchActive() const;
bool isEntryEditActive() const;
+ bool isGroupEditActive() const;
QString getCurrentSearch();
void refreshSearch();
diff --git a/src/gui/widgets/ElidedLabel.cpp b/src/gui/widgets/ElidedLabel.cpp
index 187c2fc43..749f075c8 100644
--- a/src/gui/widgets/ElidedLabel.cpp
+++ b/src/gui/widgets/ElidedLabel.cpp
@@ -105,7 +105,7 @@ void ElidedLabel::updateElidedText()
const QFontMetrics metrix(font());
displayText = metrix.elidedText(m_rawText, m_elideMode, width() - 2);
}
-
+
bool hasUrl = !m_url.isEmpty();
setText(hasUrl ? htmlLinkTemplate.arg(m_url.toHtmlEscaped(), displayText) : displayText);
setOpenExternalLinks(!hasUrl);