After 3 failed saves, offer to disable safe saves

* User is prompted to disable safe saves after three failed attempts
* Completely retooled basic settings to group settings logically
* Added setting for "atomic saves"
This commit is contained in:
Jonathan White 2018-01-17 20:13:13 -05:00
parent d7f408e455
commit 3db9a86a4c
No known key found for this signature in database
GPG key ID: 440FC65F2E0C6E01
7 changed files with 384 additions and 291 deletions

View file

@ -44,6 +44,7 @@ DatabaseManagerStruct::DatabaseManagerStruct()
: dbWidget(nullptr)
, modified(false)
, readOnly(false)
, saveAttempts(0)
{
}
@ -324,12 +325,14 @@ bool DatabaseTabWidget::saveDatabase(Database* db, QString filePath)
dbStruct.dbWidget->blockAutoReload(true);
// TODO: Make this async, but lock out the database widget to prevent re-entrance
QString errorMessage = db->saveToFile(filePath, config()->get("BackupBeforeSave").toBool());
bool useAtomicSaves = config()->get("UseAtomicSaves").toBool();
QString errorMessage = db->saveToFile(filePath, useAtomicSaves, config()->get("BackupBeforeSave").toBool());
dbStruct.dbWidget->blockAutoReload(false);
if (errorMessage.isEmpty()) {
// successfully saved database file
dbStruct.modified = false;
dbStruct.saveAttempts = 0;
dbStruct.fileInfo = QFileInfo(filePath);
dbStruct.dbWidget->databaseSaved();
updateTabName(db);
@ -338,6 +341,22 @@ bool DatabaseTabWidget::saveDatabase(Database* db, QString filePath)
} else {
dbStruct.modified = true;
updateTabName(db);
if (++dbStruct.saveAttempts > 2 && useAtomicSaves) {
// Saving failed 3 times, issue a warning and attempt to resolve
auto choice = MessageBox::question(this, tr("Disable safe saves?"),
tr("KeePassXC has failed to save the database multiple times. "
"This is likely caused by file sync services holding a lock on "
"the save file.\nDisable safe saves and try again?"),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
if (choice == QMessageBox::Yes) {
config()->set("UseAtomicSaves", false);
return saveDatabase(db, filePath);
}
// Reset save attempts without changing anything
dbStruct.saveAttempts = 0;
}
emit messageTab(tr("Writing the database failed.").append("\n").append(errorMessage),
MessageWidget::Error);
return false;