Block and unblock autoreload in timed mutex style to prevent a double challenge when saving the database and the YubiKey requires user interaction

This commit is contained in:
Janek Bevendorff 2017-02-24 18:43:15 +01:00
parent 18844d096a
commit 2721317fc3
No known key found for this signature in database
GPG key ID: CFEC2F6850BFFA53
3 changed files with 42 additions and 38 deletions

View file

@ -322,17 +322,18 @@ bool DatabaseTabWidget::closeAllDatabases()
bool DatabaseTabWidget::saveDatabase(Database* db) bool DatabaseTabWidget::saveDatabase(Database* db)
{ {
DatabaseManagerStruct& dbStruct = m_dbList[db]; DatabaseManagerStruct& dbStruct = m_dbList[db];
// temporarily disable autoreload
dbStruct.dbWidget->ignoreNextAutoreload();
if (dbStruct.saveToFilename) { if (dbStruct.saveToFilename) {
QSaveFile saveFile(dbStruct.canonicalFilePath); QSaveFile saveFile(dbStruct.canonicalFilePath);
if (saveFile.open(QIODevice::WriteOnly)) { if (saveFile.open(QIODevice::WriteOnly)) {
// write the database to the file // write the database to the file
dbStruct.dbWidget->blockAutoReload(true);
m_writer.writeDatabase(&saveFile, db); m_writer.writeDatabase(&saveFile, db);
dbStruct.dbWidget->blockAutoReload(false);
if (m_writer.hasError()) { if (m_writer.hasError()) {
Q_EMIT messageTab(tr("Writing the database failed.").append("\n") emit messageTab(tr("Writing the database failed.").append("\n")
.append(m_writer.errorString()), MessageWidget::Error); .append(m_writer.errorString()), MessageWidget::Error);
return false; return false;
} }
@ -341,22 +342,19 @@ bool DatabaseTabWidget::saveDatabase(Database* db)
dbStruct.modified = false; dbStruct.modified = false;
dbStruct.dbWidget->databaseSaved(); dbStruct.dbWidget->databaseSaved();
updateTabName(db); updateTabName(db);
Q_EMIT messageDismissTab(); emit messageDismissTab();
return true; return true;
} } else {
else { emit messageTab(tr("Writing the database failed.").append("\n")
Q_EMIT messageTab(tr("Writing the database failed.").append("\n") .append(saveFile.errorString()), MessageWidget::Error);
.append(saveFile.errorString()), MessageWidget::Error);
return false; return false;
} }
} } else {
else { emit messageTab(tr("Writing the database failed.").append("\n")
Q_EMIT messageTab(tr("Writing the database failed.").append("\n") .append(saveFile.errorString()), MessageWidget::Error);
.append(saveFile.errorString()), MessageWidget::Error);
return false; return false;
} }
} } else {
else {
return saveDatabaseAs(db); return saveDatabaseAs(db);
} }
} }

View file

@ -168,14 +168,14 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
connect(m_unlockDatabaseDialog, SIGNAL(unlockDone(bool)), SLOT(unlockDatabase(bool))); connect(m_unlockDatabaseDialog, SIGNAL(unlockDone(bool)), SLOT(unlockDatabase(bool)));
connect(&m_fileWatcher, SIGNAL(fileChanged(QString)), this, SLOT(onWatchedFileChanged())); connect(&m_fileWatcher, SIGNAL(fileChanged(QString)), this, SLOT(onWatchedFileChanged()));
connect(&m_fileWatchTimer, SIGNAL(timeout()), this, SLOT(reloadDatabaseFile())); connect(&m_fileWatchTimer, SIGNAL(timeout()), this, SLOT(reloadDatabaseFile()));
connect(&m_ignoreWatchTimer, SIGNAL(timeout()), this, SLOT(onWatchedFileChanged())); connect(&m_fileWatchUnblockTimer, SIGNAL(timeout()), this, SLOT(unblockAutoReload()));
connect(this, SIGNAL(currentChanged(int)), this, SLOT(emitCurrentModeChanged())); connect(this, SIGNAL(currentChanged(int)), this, SLOT(emitCurrentModeChanged()));
m_databaseModified = false; m_databaseModified = false;
m_fileWatchTimer.setSingleShot(true); m_fileWatchTimer.setSingleShot(true);
m_ignoreWatchTimer.setSingleShot(true); m_fileWatchUnblockTimer.setSingleShot(true);
m_ignoreNextAutoreload = false; m_ignoreAutoReload = false;
m_searchCaseSensitive = false; m_searchCaseSensitive = false;
@ -1001,7 +1001,7 @@ void DatabaseWidget::lock()
void DatabaseWidget::updateFilename(const QString& fileName) void DatabaseWidget::updateFilename(const QString& fileName)
{ {
if (! m_filename.isEmpty()) { if (!m_filename.isEmpty()) {
m_fileWatcher.removePath(m_filename); m_fileWatcher.removePath(m_filename);
} }
@ -1009,26 +1009,31 @@ void DatabaseWidget::updateFilename(const QString& fileName)
m_filename = fileName; m_filename = fileName;
} }
void DatabaseWidget::ignoreNextAutoreload() void DatabaseWidget::blockAutoReload(bool block)
{ {
m_ignoreNextAutoreload = true; if (block) {
m_ignoreWatchTimer.start(100); m_ignoreAutoReload = true;
m_fileWatchTimer.stop();
} else {
m_fileWatchUnblockTimer.start(500);
}
}
void DatabaseWidget::unblockAutoReload()
{
m_ignoreAutoReload = false;
updateFilename(m_filename);
} }
void DatabaseWidget::onWatchedFileChanged() void DatabaseWidget::onWatchedFileChanged()
{ {
if (m_ignoreNextAutoreload) { if (m_ignoreAutoReload) {
// Reset the watch return;
m_ignoreNextAutoreload = false;
m_ignoreWatchTimer.stop();
m_fileWatcher.addPath(m_filename);
} }
else { if (m_fileWatchTimer.isActive())
if (m_fileWatchTimer.isActive()) return;
return;
m_fileWatchTimer.start(500); m_fileWatchTimer.start(500);
}
} }
void DatabaseWidget::reloadDatabaseFile() void DatabaseWidget::reloadDatabaseFile()

View file

@ -98,9 +98,9 @@ public:
EntryView* entryView(); EntryView* entryView();
void showUnlockDialog(); void showUnlockDialog();
void closeUnlockDialog(); void closeUnlockDialog();
void ignoreNextAutoreload(); void blockAutoReload(bool block = true);
Q_SIGNALS: signals:
void closeRequest(); void closeRequest();
void currentModeChanged(DatabaseWidget::Mode mode); void currentModeChanged(DatabaseWidget::Mode mode);
void groupChanged(); void groupChanged();
@ -118,7 +118,7 @@ Q_SIGNALS:
void entryColumnSizesChanged(); void entryColumnSizesChanged();
void updateSearch(QString text); void updateSearch(QString text);
public Q_SLOTS: public slots:
void createEntry(); void createEntry();
void cloneEntry(); void cloneEntry();
void deleteEntries(); void deleteEntries();
@ -154,7 +154,7 @@ public Q_SLOTS:
void showMessage(const QString& text, MessageWidget::MessageType type); void showMessage(const QString& text, MessageWidget::MessageType type);
void hideMessage(); void hideMessage();
private Q_SLOTS: private slots:
void entryActivationSignalReceived(Entry* entry, EntryModel::ModelColumn column); void entryActivationSignalReceived(Entry* entry, EntryModel::ModelColumn column);
void switchBackToEntryEdit(); void switchBackToEntryEdit();
void switchToHistoryView(Entry* entry); void switchToHistoryView(Entry* entry);
@ -172,6 +172,7 @@ private Q_SLOTS:
void onWatchedFileChanged(); void onWatchedFileChanged();
void reloadDatabaseFile(); void reloadDatabaseFile();
void restoreGroupEntryFocus(Uuid groupUuid, Uuid EntryUuid); void restoreGroupEntryFocus(Uuid groupUuid, Uuid EntryUuid);
void unblockAutoReload();
private: private:
void setClipboardTextAndMinimize(const QString& text); void setClipboardTextAndMinimize(const QString& text);
@ -209,8 +210,8 @@ private:
// Autoreload // Autoreload
QFileSystemWatcher m_fileWatcher; QFileSystemWatcher m_fileWatcher;
QTimer m_fileWatchTimer; QTimer m_fileWatchTimer;
bool m_ignoreNextAutoreload; QTimer m_fileWatchUnblockTimer;
QTimer m_ignoreWatchTimer; bool m_ignoreAutoReload;
bool m_databaseModified; bool m_databaseModified;
}; };