From 37aedc8b03fc4f6a837d2bac3ed3630a7136f899 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Wed, 9 Nov 2016 07:38:14 -0500 Subject: [PATCH] Cleaned up code and added spots for todo work. Fully Working! --- src/CMakeLists.txt | 1 - src/core/FileSystemWatcher.cpp | 75 ------------------------------- src/core/FileSystemWatcher.h | 47 ------------------- src/gui/DatabaseWidget.cpp | 61 +++++++++++++++++-------- src/gui/DatabaseWidget.h | 11 +++-- src/gui/SettingsWidgetGeneral.ui | 22 ++++----- tests/data/NewDatabase.kdbx | Bin 8350 -> 15150 bytes 7 files changed, 62 insertions(+), 155 deletions(-) delete mode 100644 src/core/FileSystemWatcher.cpp delete mode 100644 src/core/FileSystemWatcher.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 59ada8766..3d3d3f5f8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -40,7 +40,6 @@ set(keepassx_SOURCES autotype/test/AutoTypeTestInterface.h core/AutoTypeAssociations.cpp core/Config.cpp - core/FileSystemWatcher.cpp core/Database.cpp core/DatabaseIcons.cpp core/Endian.cpp diff --git a/src/core/FileSystemWatcher.cpp b/src/core/FileSystemWatcher.cpp deleted file mode 100644 index 93b4f6f3f..000000000 --- a/src/core/FileSystemWatcher.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2012 Felix Geyer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 or (at your option) - * version 3 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "FileSystemWatcher.h" -#include -#include -#include - -FileSystemWatcher::FileSystemWatcher (): QFileSystemWatcher ( ) -{ - connect(this,SIGNAL( fileChanged ( const QString & )), - this,SLOT( fileChangedSlot ( const QString & ))); - connect(this,SIGNAL( directoryChanged ( const QString & )), - this,SLOT( directoryChangedSlot ( const QString & ))); -} - -void FileSystemWatcher::watchFile(const QString &file) -{ - _file=file; - if (!files().isEmpty()) - removePaths(files()); - if (!directories().isEmpty()) - removePaths(directories()); - QFileInfo fileInfo(file); - if (fileInfo.exists()) - addPath(file); - QString filePath=fileInfo.absoluteDir().path(); - QFileInfo filePathInfo(filePath); - if (filePathInfo.exists()) - addPath(filePath); -} - -void FileSystemWatcher::stopWatching() -{ - watchFile( QString() ); -} - -void FileSystemWatcher::fileChangedSlot ( const QString & ) -{ - QFileInfo fileInfo(_file); - if ( fileInfo.exists() ) - fileChanged(); -} - -void FileSystemWatcher::directoryChangedSlot ( const QString & ) -{ - if (!files().contains(_file)) - { - QFileInfo fileInfo(_file); - if ( fileInfo.exists() ) - { - addPath(_file); - fileChanged(); - } - } -} - -FileSystemWatcher::~FileSystemWatcher() -{ -} - diff --git a/src/core/FileSystemWatcher.h b/src/core/FileSystemWatcher.h deleted file mode 100644 index 4721a98b7..000000000 --- a/src/core/FileSystemWatcher.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2012 Felix Geyer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 or (at your option) - * version 3 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef FILE_SYSTEM_WATCHER_H -#define FILE_SYSTEM_WATCHER_H -#include -#include -#include - - -class FileSystemWatcher : public QFileSystemWatcher -{ - Q_OBJECT ; - -public: - FileSystemWatcher (); - void watchFile( const QString & ); - void stopWatching(); - - virtual ~FileSystemWatcher(); - -private: - QString _file; - -private Q_SLOTS: - void directoryChangedSlot ( const QString & ); - void fileChangedSlot ( const QString & ); -Q_SIGNALS: - void fileChanged(); -}; - -#endif - diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index 8915e5c06..f9b635af0 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -29,7 +29,6 @@ #include #include #include -#include #include #include "autotype/AutoType.h" @@ -157,8 +156,12 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent) connect(m_databaseOpenMergeWidget, SIGNAL(editFinished(bool)), SLOT(mergeDatabase(bool))); connect(m_keepass1OpenWidget, SIGNAL(editFinished(bool)), SLOT(openDatabase(bool))); connect(m_unlockDatabaseWidget, SIGNAL(editFinished(bool)), SLOT(unlockDatabase(bool))); + connect(&m_fileWatcher, SIGNAL(fileChanged(QString)), this, SLOT(onWatchedFileChanged())); + connect(&m_fileWatchTimer, SIGNAL(timeout()), this, SLOT(reloadDatabaseFile())); connect(this, SIGNAL(currentChanged(int)), this, SLOT(emitCurrentModeChanged())); + m_fileWatchTimer.setSingleShot(true); + m_searchCaseSensitive = false; m_searchCurrentGroup = false; @@ -662,11 +665,10 @@ void DatabaseWidget::openDatabase(bool accepted) m_databaseOpenWidget = nullptr; delete m_keepass1OpenWidget; m_keepass1OpenWidget = nullptr; - if (config()->get("AutoReloadOnChange").toBool() ) - m_file_watcher.watchFile( m_filename ); + m_fileWatcher.addPath(m_filename); } else { - m_file_watcher.stopWatching(); + m_fileWatcher.removePath(m_filename); if (m_databaseOpenWidget->database()) { delete m_databaseOpenWidget->database(); } @@ -939,29 +941,52 @@ void DatabaseWidget::updateFilename(const QString& fileName) m_filename = fileName; } -void DatabaseWidget::databaseModifedExternally() +void DatabaseWidget::onWatchedFileChanged() { - if ( database() == Q_NULLPTR ) + if (m_fileWatchTimer.isActive()) return; - if ( ! config()->get("AutoReloadOnChange").toBool() ) + m_fileWatchTimer.start(500); +} + +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"), + tr("The database file has changed. Do you want to load the changes?"), + QMessageBox::Yes | QMessageBox::No); + + if (mb == QMessageBox::No) { + // TODO: taint database + + // Rewatch the database file + m_fileWatcher.addPath(m_filename); + return; + } + } + KeePass2Reader reader; QFile file(m_filename); - if (!file.open(QIODevice::ReadOnly)) { - // TODO: error message - return; + if (file.open(QIODevice::ReadOnly)) { + Database* db = reader.readDatabase(&file, database()->key()); + if (db != nullptr) { + replaceDatabase(db); + } + else { + // TODO: error message for failure to read the new db + } } - Database* db = reader.readDatabase(&file, database()->key() ); - if ( db ) - { - Database* oldDb = m_db; - m_db = db; - m_groupView->changeDatabase(m_db); - Q_EMIT databaseChanged(m_db); - delete oldDb; + else { + // TODO: error message for failure to open db file } + + // Rewatch the database file + m_fileWatcher.addPath(m_filename); } int DatabaseWidget::numberOfSelectedEntries() const diff --git a/src/gui/DatabaseWidget.h b/src/gui/DatabaseWidget.h index 57211c05f..11b5d3963 100644 --- a/src/gui/DatabaseWidget.h +++ b/src/gui/DatabaseWidget.h @@ -20,11 +20,12 @@ #include #include +#include +#include #include "core/Uuid.h" #include "gui/entry/EntryModel.h" -#include "core/FileSystemWatcher.h" class ChangeMasterKeyWidget; class DatabaseOpenWidget; @@ -42,6 +43,7 @@ class QMenu; class QSplitter; class QLabel; class UnlockDatabaseWidget; +class QFileSystemWatcher; class DatabaseWidget : public QStackedWidget { @@ -149,10 +151,12 @@ private Q_SLOTS: void updateMasterKey(bool accepted); void openDatabase(bool accepted); void mergeDatabase(bool accepted); - void databaseModifedExternally(); void unlockDatabase(bool accepted); void emitCurrentModeChanged(); void clearLastGroup(Group* group); + // Database autoreload slots + void onWatchedFileChanged(); + void reloadDatabaseFile(); private: void setClipboardTextAndMinimize(const QString& text); @@ -186,7 +190,8 @@ private: bool m_searchCaseSensitive; bool m_searchCurrentGroup; - FileSystemWatcher m_file_watcher; + QFileSystemWatcher m_fileWatcher; + QTimer m_fileWatchTimer; }; #endif // KEEPASSX_DATABASEWIDGET_H diff --git a/src/gui/SettingsWidgetGeneral.ui b/src/gui/SettingsWidgetGeneral.ui index 843e16fec..223e2b9af 100644 --- a/src/gui/SettingsWidgetGeneral.ui +++ b/src/gui/SettingsWidgetGeneral.ui @@ -7,7 +7,7 @@ 0 0 684 - 394 + 430 @@ -103,14 +103,7 @@ - - - - Show a system tray icon - - - - + QLayout::SetMaximumSize @@ -149,7 +142,7 @@ - + QLayout::SetMaximumSize @@ -179,7 +172,7 @@ - + QLayout::SetMaximumSize @@ -209,6 +202,13 @@ + + + + Show a system tray icon + + + diff --git a/tests/data/NewDatabase.kdbx b/tests/data/NewDatabase.kdbx index 4e77724c7e8cfdf22bcd951ccfcaa4ae7f49d460..f45929de27c5bd3a879623ab351175917c85b06a 100644 GIT binary patch literal 15150 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 KWiOj9qs7dxo(k&$g=mPi;WD*t_-6> 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