mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-11-23 00:10:37 -05:00
Implemented major autoreload functionality
* Ignore autoreload on save / save-as * Consolidated db save code * Corrected bug (crash) in merge entry code due to not cloning the entry * Enhanced known modified status of database * Implemented test cases for autoreload
This commit is contained in:
parent
20c3ca7d37
commit
7fb33653ad
9 changed files with 190 additions and 55 deletions
|
|
@ -29,7 +29,6 @@
|
|||
#include <QProcess>
|
||||
#include <QHeaderView>
|
||||
#include <QApplication>
|
||||
#include <QtDebug>
|
||||
|
||||
#include "autotype/AutoType.h"
|
||||
#include "core/Config.h"
|
||||
|
|
@ -162,9 +161,14 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
|
|||
connect(m_unlockDatabaseDialog, SIGNAL(unlockDone(bool)), SLOT(unlockDatabase(bool)));
|
||||
connect(&m_fileWatcher, SIGNAL(fileChanged(QString)), this, SLOT(onWatchedFileChanged()));
|
||||
connect(&m_fileWatchTimer, SIGNAL(timeout()), this, SLOT(reloadDatabaseFile()));
|
||||
connect(&m_ignoreWatchTimer, SIGNAL(timeout()), this, SLOT(onWatchedFileChanged()));
|
||||
connect(this, SIGNAL(currentChanged(int)), this, SLOT(emitCurrentModeChanged()));
|
||||
|
||||
m_databaseModified = false;
|
||||
|
||||
m_fileWatchTimer.setSingleShot(true);
|
||||
m_ignoreWatchTimer.setSingleShot(true);
|
||||
m_ignoreNextAutoreload = false;
|
||||
|
||||
m_searchCaseSensitive = false;
|
||||
m_searchCurrentGroup = false;
|
||||
|
|
@ -298,7 +302,7 @@ void DatabaseWidget::replaceDatabase(Database* db)
|
|||
Database* oldDb = m_db;
|
||||
m_db = db;
|
||||
m_groupView->changeDatabase(m_db);
|
||||
Q_EMIT databaseChanged(m_db);
|
||||
Q_EMIT databaseChanged(m_db, m_databaseModified);
|
||||
delete oldDb;
|
||||
}
|
||||
|
||||
|
|
@ -818,6 +822,16 @@ void DatabaseWidget::switchToImportKeepass1(const QString& fileName)
|
|||
setCurrentWidget(m_keepass1OpenWidget);
|
||||
}
|
||||
|
||||
void DatabaseWidget::databaseModified()
|
||||
{
|
||||
m_databaseModified = true;
|
||||
}
|
||||
|
||||
void DatabaseWidget::databaseSaved()
|
||||
{
|
||||
m_databaseModified = false;
|
||||
}
|
||||
|
||||
void DatabaseWidget::search(const QString& searchtext)
|
||||
{
|
||||
if (searchtext.isEmpty())
|
||||
|
|
@ -956,15 +970,34 @@ void DatabaseWidget::lock()
|
|||
|
||||
void DatabaseWidget::updateFilename(const QString& fileName)
|
||||
{
|
||||
if (! m_filename.isEmpty()) {
|
||||
m_fileWatcher.removePath(m_filename);
|
||||
}
|
||||
|
||||
m_fileWatcher.addPath(fileName);
|
||||
m_filename = fileName;
|
||||
}
|
||||
|
||||
void DatabaseWidget::ignoreNextAutoreload()
|
||||
{
|
||||
m_ignoreNextAutoreload = true;
|
||||
m_ignoreWatchTimer.start(100);
|
||||
}
|
||||
|
||||
void DatabaseWidget::onWatchedFileChanged()
|
||||
{
|
||||
if (m_fileWatchTimer.isActive())
|
||||
return;
|
||||
if (m_ignoreNextAutoreload) {
|
||||
// Reset the watch
|
||||
m_ignoreNextAutoreload = false;
|
||||
m_ignoreWatchTimer.stop();
|
||||
m_fileWatcher.addPath(m_filename);
|
||||
}
|
||||
else {
|
||||
if (m_fileWatchTimer.isActive())
|
||||
return;
|
||||
|
||||
m_fileWatchTimer.start(500);
|
||||
m_fileWatchTimer.start(500);
|
||||
}
|
||||
}
|
||||
|
||||
void DatabaseWidget::reloadDatabaseFile()
|
||||
|
|
@ -972,16 +1005,16 @@ void DatabaseWidget::reloadDatabaseFile()
|
|||
if (m_db == nullptr)
|
||||
return;
|
||||
|
||||
// TODO: Also check if db is currently modified before reloading
|
||||
if (! config()->get("AutoReloadOnChange").toBool()) {
|
||||
// Ask if we want to reload the db
|
||||
QMessageBox::StandardButton mb = MessageBox::question(this, tr("Reload database file"),
|
||||
QMessageBox::StandardButton mb = MessageBox::question(this, tr("Autoreload Request"),
|
||||
tr("The database file has changed. Do you want to load the changes?"),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
if (mb == QMessageBox::No) {
|
||||
// TODO: taint database
|
||||
|
||||
// Notify everyone the database does not match the file
|
||||
emit m_db->modified();
|
||||
m_databaseModified = true;
|
||||
// Rewatch the database file
|
||||
m_fileWatcher.addPath(m_filename);
|
||||
return;
|
||||
|
|
@ -993,14 +1026,37 @@ void DatabaseWidget::reloadDatabaseFile()
|
|||
if (file.open(QIODevice::ReadOnly)) {
|
||||
Database* db = reader.readDatabase(&file, database()->key());
|
||||
if (db != nullptr) {
|
||||
if (m_databaseModified) {
|
||||
// Ask if we want to merge changes into new database
|
||||
QMessageBox::StandardButton mb = MessageBox::question(this, tr("Merge Request"),
|
||||
tr("The database file has changed and you have unsaved changes."
|
||||
"Do you want to merge your changes?"),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
if (mb == QMessageBox::Yes) {
|
||||
// Merge the old database into the new one
|
||||
m_db->setEmitModified(false);
|
||||
db->merge(m_db);
|
||||
}
|
||||
else {
|
||||
// Since we are accepting the new file as-is, internally mark as unmodified
|
||||
// TODO: when saving is moved out of DatabaseTabWidget, this should be replaced
|
||||
m_databaseModified = false;
|
||||
}
|
||||
}
|
||||
|
||||
replaceDatabase(db);
|
||||
}
|
||||
else {
|
||||
// TODO: error message for failure to read the new db
|
||||
MessageBox::critical(this, tr("Autoreload Failed"),
|
||||
tr("Could not parse or unlock the new database file while attempting"
|
||||
"to autoreload this database."));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// TODO: error message for failure to open db file
|
||||
MessageBox::critical(this, tr("Autoreload Failed"),
|
||||
tr("Could not open the new database file while attempting to autoreload"
|
||||
"this database."));
|
||||
}
|
||||
|
||||
// Rewatch the database file
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue