mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-01-14 08:50:08 -05:00
Merge pull request #1231 from keepassxreboot/refactor/remove-lockfile
Remove lock file and cleanup file handling
This commit is contained in:
commit
8f99764f24
@ -19,7 +19,6 @@
|
|||||||
#include "DatabaseTabWidget.h"
|
#include "DatabaseTabWidget.h"
|
||||||
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QLockFile>
|
|
||||||
#include <QTabWidget>
|
#include <QTabWidget>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
|
||||||
@ -42,8 +41,6 @@
|
|||||||
|
|
||||||
DatabaseManagerStruct::DatabaseManagerStruct()
|
DatabaseManagerStruct::DatabaseManagerStruct()
|
||||||
: dbWidget(nullptr)
|
: dbWidget(nullptr)
|
||||||
, lockFile(nullptr)
|
|
||||||
, saveToFilename(false)
|
|
||||||
, modified(false)
|
, modified(false)
|
||||||
, readOnly(false)
|
, readOnly(false)
|
||||||
{
|
{
|
||||||
@ -107,7 +104,7 @@ void DatabaseTabWidget::newDatabase()
|
|||||||
void DatabaseTabWidget::openDatabase()
|
void DatabaseTabWidget::openDatabase()
|
||||||
{
|
{
|
||||||
QString filter = QString("%1 (*.kdbx);;%2 (*)").arg(tr("KeePass 2 Database"), tr("All files"));
|
QString filter = QString("%1 (*.kdbx);;%2 (*)").arg(tr("KeePass 2 Database"), tr("All files"));
|
||||||
QString fileName = fileDialog()->getOpenFileName(this, tr("Open database"), QString(),
|
QString fileName = fileDialog()->getOpenFileName(this, tr("Open database"), QDir::homePath(),
|
||||||
filter);
|
filter);
|
||||||
if (!fileName.isEmpty()) {
|
if (!fileName.isEmpty()) {
|
||||||
openDatabase(fileName);
|
openDatabase(fileName);
|
||||||
@ -128,10 +125,10 @@ void DatabaseTabWidget::openDatabase(const QString& fileName, const QString& pw,
|
|||||||
QHashIterator<Database*, DatabaseManagerStruct> i(m_dbList);
|
QHashIterator<Database*, DatabaseManagerStruct> i(m_dbList);
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
i.next();
|
i.next();
|
||||||
if (i.value().canonicalFilePath == canonicalFilePath) {
|
if (i.value().fileInfo.canonicalFilePath() == canonicalFilePath) {
|
||||||
if (!i.value().dbWidget->dbHasKey() && !(pw.isNull() && keyFile.isEmpty())) {
|
if (!i.value().dbWidget->dbHasKey() && !(pw.isNull() && keyFile.isEmpty())) {
|
||||||
// If the database is locked and a pw or keyfile is provided, unlock it
|
// If the database is locked and a pw or keyfile is provided, unlock it
|
||||||
i.value().dbWidget->switchToOpenDatabase(i.value().filePath, pw, keyFile);
|
i.value().dbWidget->switchToOpenDatabase(i.value().fileInfo.absoluteFilePath(), pw, keyFile);
|
||||||
} else {
|
} else {
|
||||||
setCurrentIndex(databaseIndex(i.key()));
|
setCurrentIndex(databaseIndex(i.key()));
|
||||||
}
|
}
|
||||||
@ -157,49 +154,9 @@ void DatabaseTabWidget::openDatabase(const QString& fileName, const QString& pw,
|
|||||||
}
|
}
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
QLockFile* lockFile = new QLockFile(QString("%1/.%2.lock").arg(fileInfo.canonicalPath(), fileInfo.fileName()));
|
|
||||||
lockFile->setStaleLockTime(0);
|
|
||||||
|
|
||||||
if (!dbStruct.readOnly && !lockFile->tryLock()) {
|
|
||||||
// for now silently ignore if we can't create a lock file
|
|
||||||
// due to lack of permissions
|
|
||||||
if (lockFile->error() != QLockFile::PermissionError) {
|
|
||||||
QMessageBox msgBox;
|
|
||||||
msgBox.setWindowTitle(tr("Database already opened"));
|
|
||||||
msgBox.setText(tr("The database you are trying to open is locked by another instance of KeePassXC.\n\n"
|
|
||||||
"Do you want to open it anyway?"));
|
|
||||||
msgBox.setIcon(QMessageBox::Question);
|
|
||||||
msgBox.addButton(QMessageBox::Yes);
|
|
||||||
msgBox.addButton(QMessageBox::No);
|
|
||||||
auto readOnlyButton = msgBox.addButton(tr("Open read-only"), QMessageBox::NoRole);
|
|
||||||
msgBox.setDefaultButton(readOnlyButton);
|
|
||||||
msgBox.setEscapeButton(QMessageBox::No);
|
|
||||||
auto result = msgBox.exec();
|
|
||||||
|
|
||||||
if (msgBox.clickedButton() == readOnlyButton) {
|
|
||||||
dbStruct.readOnly = true;
|
|
||||||
delete lockFile;
|
|
||||||
lockFile = nullptr;
|
|
||||||
} else if (result == QMessageBox::Yes) {
|
|
||||||
// take over the lock file if possible
|
|
||||||
if (lockFile->removeStaleLockFile()) {
|
|
||||||
lockFile->tryLock();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
delete lockFile;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Database* db = new Database();
|
Database* db = new Database();
|
||||||
dbStruct.dbWidget = new DatabaseWidget(db, this);
|
dbStruct.dbWidget = new DatabaseWidget(db, this);
|
||||||
dbStruct.lockFile = lockFile;
|
dbStruct.fileInfo = fileInfo;
|
||||||
dbStruct.saveToFilename = !dbStruct.readOnly;
|
|
||||||
|
|
||||||
dbStruct.filePath = fileInfo.absoluteFilePath();
|
|
||||||
dbStruct.canonicalFilePath = canonicalFilePath;
|
|
||||||
dbStruct.fileName = fileInfo.fileName();
|
|
||||||
|
|
||||||
insertDatabase(db, dbStruct);
|
insertDatabase(db, dbStruct);
|
||||||
|
|
||||||
@ -207,13 +164,12 @@ void DatabaseTabWidget::openDatabase(const QString& fileName, const QString& pw,
|
|||||||
emit messageTab(tr("File opened in read only mode."), MessageWidget::Warning);
|
emit messageTab(tr("File opened in read only mode."), MessageWidget::Warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateLastDatabases(dbStruct.filePath);
|
updateLastDatabases(dbStruct.fileInfo.absoluteFilePath());
|
||||||
|
|
||||||
if (!(pw.isNull() && keyFile.isEmpty())) {
|
if (!pw.isNull() || !keyFile.isEmpty()) {
|
||||||
dbStruct.dbWidget->switchToOpenDatabase(dbStruct.filePath, pw, keyFile);
|
dbStruct.dbWidget->switchToOpenDatabase(dbStruct.fileInfo.absoluteFilePath(), pw, keyFile);
|
||||||
}
|
} else {
|
||||||
else {
|
dbStruct.dbWidget->switchToOpenDatabase(dbStruct.fileInfo.absoluteFilePath());
|
||||||
dbStruct.dbWidget->switchToOpenDatabase(dbStruct.filePath);
|
|
||||||
}
|
}
|
||||||
emit messageDismissGlobal();
|
emit messageDismissGlobal();
|
||||||
}
|
}
|
||||||
@ -322,15 +278,14 @@ bool DatabaseTabWidget::closeDatabase(Database* db)
|
|||||||
void DatabaseTabWidget::deleteDatabase(Database* db)
|
void DatabaseTabWidget::deleteDatabase(Database* db)
|
||||||
{
|
{
|
||||||
const DatabaseManagerStruct dbStruct = m_dbList.value(db);
|
const DatabaseManagerStruct dbStruct = m_dbList.value(db);
|
||||||
bool emitDatabaseWithFileClosed = dbStruct.saveToFilename;
|
bool emitDatabaseWithFileClosed = dbStruct.fileInfo.exists() && !dbStruct.readOnly;
|
||||||
QString filePath = dbStruct.filePath;
|
QString filePath = dbStruct.fileInfo.absoluteFilePath();
|
||||||
|
|
||||||
int index = databaseIndex(db);
|
int index = databaseIndex(db);
|
||||||
|
|
||||||
removeTab(index);
|
removeTab(index);
|
||||||
toggleTabbar();
|
toggleTabbar();
|
||||||
m_dbList.remove(db);
|
m_dbList.remove(db);
|
||||||
delete dbStruct.lockFile;
|
|
||||||
delete dbStruct.dbWidget;
|
delete dbStruct.dbWidget;
|
||||||
delete db;
|
delete db;
|
||||||
|
|
||||||
@ -349,24 +304,31 @@ bool DatabaseTabWidget::closeAllDatabases()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DatabaseTabWidget::saveDatabase(Database* db)
|
bool DatabaseTabWidget::saveDatabase(Database* db, QString filePath)
|
||||||
{
|
{
|
||||||
DatabaseManagerStruct& dbStruct = m_dbList[db];
|
DatabaseManagerStruct& dbStruct = m_dbList[db];
|
||||||
|
|
||||||
if (dbStruct.dbWidget->currentMode() == DatabaseWidget::LockedMode) {
|
|
||||||
// Never allow saving a locked database; it causes corruption
|
// Never allow saving a locked database; it causes corruption
|
||||||
|
Q_ASSERT(dbStruct.dbWidget->currentMode() != DatabaseWidget::LockedMode);
|
||||||
|
// Release build interlock
|
||||||
|
if (dbStruct.dbWidget->currentMode() == DatabaseWidget::LockedMode) {
|
||||||
// We return true since a save is not required
|
// We return true since a save is not required
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dbStruct.saveToFilename) {
|
if (!dbStruct.readOnly) {
|
||||||
|
if (filePath.isEmpty()) {
|
||||||
|
filePath = dbStruct.fileInfo.canonicalFilePath();
|
||||||
|
}
|
||||||
|
|
||||||
dbStruct.dbWidget->blockAutoReload(true);
|
dbStruct.dbWidget->blockAutoReload(true);
|
||||||
QString errorMessage = db->saveToFile(dbStruct.canonicalFilePath);
|
QString errorMessage = db->saveToFile(filePath);
|
||||||
dbStruct.dbWidget->blockAutoReload(false);
|
dbStruct.dbWidget->blockAutoReload(false);
|
||||||
|
|
||||||
if (errorMessage.isEmpty()) {
|
if (errorMessage.isEmpty()) {
|
||||||
// successfully saved database file
|
// successfully saved database file
|
||||||
dbStruct.modified = false;
|
dbStruct.modified = false;
|
||||||
|
dbStruct.fileInfo = QFileInfo(filePath);
|
||||||
dbStruct.dbWidget->databaseSaved();
|
dbStruct.dbWidget->databaseSaved();
|
||||||
updateTabName(db);
|
updateTabName(db);
|
||||||
emit messageDismissTab();
|
emit messageDismissTab();
|
||||||
@ -387,76 +349,31 @@ bool DatabaseTabWidget::saveDatabaseAs(Database* db)
|
|||||||
{
|
{
|
||||||
while (true) {
|
while (true) {
|
||||||
DatabaseManagerStruct& dbStruct = m_dbList[db];
|
DatabaseManagerStruct& dbStruct = m_dbList[db];
|
||||||
QString oldFileName;
|
QString oldFilePath;
|
||||||
if (dbStruct.saveToFilename) {
|
if (dbStruct.fileInfo.exists()) {
|
||||||
oldFileName = dbStruct.filePath;
|
oldFilePath = dbStruct.fileInfo.absoluteFilePath();
|
||||||
} else {
|
} else {
|
||||||
oldFileName = tr("Passwords").append(".kdbx");
|
oldFilePath = QDir::toNativeSeparators(QDir::homePath() + "/" + tr("Passwords").append(".kdbx"));
|
||||||
}
|
}
|
||||||
QString fileName = fileDialog()->getSaveFileName(this, tr("Save database as"),
|
QString newFilePath = fileDialog()->getSaveFileName(this, tr("Save database as"), oldFilePath,
|
||||||
oldFileName, tr("KeePass 2 Database").append(" (*.kdbx)"),
|
tr("KeePass 2 Database").append(" (*.kdbx)"),
|
||||||
nullptr, 0, "kdbx");
|
nullptr, 0, "kdbx");
|
||||||
if (!fileName.isEmpty()) {
|
if (!newFilePath.isEmpty()) {
|
||||||
QFileInfo fileInfo(fileName);
|
// Ensure we don't recurse back into this function
|
||||||
QString lockFilePath;
|
dbStruct.readOnly = false;
|
||||||
if (fileInfo.exists()) {
|
|
||||||
// returns empty string when file doesn't exist
|
|
||||||
lockFilePath = fileInfo.canonicalPath();
|
|
||||||
} else {
|
|
||||||
lockFilePath = fileInfo.absolutePath();
|
|
||||||
}
|
|
||||||
QString lockFileName = QString("%1/.%2.lock").arg(lockFilePath, fileInfo.fileName());
|
|
||||||
QScopedPointer<QLockFile> lockFile(new QLockFile(lockFileName));
|
|
||||||
lockFile->setStaleLockTime(0);
|
|
||||||
if (!lockFile->tryLock()) {
|
|
||||||
// for now silently ignore if we can't create a lock file
|
|
||||||
// due to lack of permissions
|
|
||||||
if (lockFile->error() != QLockFile::PermissionError) {
|
|
||||||
QMessageBox::StandardButton result = MessageBox::question(this, tr("Save database as"),
|
|
||||||
tr("The database you are trying to save as is locked by another instance of KeePassXC.\n"
|
|
||||||
"Do you want to save it anyway?"),
|
|
||||||
QMessageBox::Yes | QMessageBox::No);
|
|
||||||
|
|
||||||
if (result == QMessageBox::No) {
|
if (!saveDatabase(db, newFilePath)) {
|
||||||
return false;
|
// Failed to save, try again
|
||||||
} else {
|
|
||||||
// take over the lock file if possible
|
|
||||||
if (lockFile->removeStaleLockFile()) {
|
|
||||||
lockFile->tryLock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup variables so saveDatabase succeeds
|
|
||||||
dbStruct.saveToFilename = true;
|
|
||||||
dbStruct.canonicalFilePath = fileName;
|
|
||||||
|
|
||||||
if (!saveDatabase(db)) {
|
|
||||||
// failed to save, revert back
|
|
||||||
dbStruct.saveToFilename = false;
|
|
||||||
dbStruct.canonicalFilePath = oldFileName;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// refresh fileinfo since the file didn't exist before
|
dbStruct.dbWidget->updateFilePath(dbStruct.fileInfo.absoluteFilePath());
|
||||||
fileInfo.refresh();
|
updateLastDatabases(dbStruct.fileInfo.absoluteFilePath());
|
||||||
|
|
||||||
dbStruct.modified = false;
|
|
||||||
dbStruct.saveToFilename = true;
|
|
||||||
dbStruct.readOnly = false;
|
|
||||||
dbStruct.filePath = fileInfo.absoluteFilePath();
|
|
||||||
dbStruct.canonicalFilePath = fileInfo.canonicalFilePath();
|
|
||||||
dbStruct.fileName = fileInfo.fileName();
|
|
||||||
dbStruct.dbWidget->updateFilename(dbStruct.filePath);
|
|
||||||
delete dbStruct.lockFile;
|
|
||||||
dbStruct.lockFile = lockFile.take();
|
|
||||||
updateTabName(db);
|
|
||||||
updateLastDatabases(dbStruct.filePath);
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Canceled file selection
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -548,7 +465,7 @@ bool DatabaseTabWidget::canSave(int index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const DatabaseManagerStruct& dbStruct = indexDatabaseManagerStruct(index);
|
const DatabaseManagerStruct& dbStruct = indexDatabaseManagerStruct(index);
|
||||||
return !dbStruct.saveToFilename || (dbStruct.modified && !dbStruct.readOnly);
|
return dbStruct.modified && !dbStruct.readOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DatabaseTabWidget::isModified(int index)
|
bool DatabaseTabWidget::isModified(int index)
|
||||||
@ -566,7 +483,7 @@ QString DatabaseTabWidget::databasePath(int index)
|
|||||||
index = currentIndex();
|
index = currentIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
return indexDatabaseManagerStruct(index).filePath;
|
return indexDatabaseManagerStruct(index).fileInfo.absoluteFilePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -579,21 +496,18 @@ void DatabaseTabWidget::updateTabName(Database* db)
|
|||||||
|
|
||||||
QString tabName;
|
QString tabName;
|
||||||
|
|
||||||
if (dbStruct.saveToFilename || dbStruct.readOnly) {
|
if (dbStruct.fileInfo.exists()) {
|
||||||
if (db->metadata()->name().isEmpty()) {
|
if (db->metadata()->name().isEmpty()) {
|
||||||
tabName = dbStruct.fileName;
|
tabName = dbStruct.fileInfo.fileName();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
tabName = db->metadata()->name();
|
tabName = db->metadata()->name();
|
||||||
}
|
}
|
||||||
|
|
||||||
setTabToolTip(index, dbStruct.filePath);
|
setTabToolTip(index, dbStruct.fileInfo.absoluteFilePath());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (db->metadata()->name().isEmpty()) {
|
if (db->metadata()->name().isEmpty()) {
|
||||||
tabName = tr("New database");
|
tabName = tr("New database");
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
tabName = QString("%1 [%2]").arg(db->metadata()->name(), tr("New database"));
|
tabName = QString("%1 [%2]").arg(db->metadata()->name(), tr("New database"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -629,8 +543,7 @@ void DatabaseTabWidget::updateTabNameFromDbWidgetSender()
|
|||||||
Group *autoload = db->rootGroup()->findChildByName("AutoOpen");
|
Group *autoload = db->rootGroup()->findChildByName("AutoOpen");
|
||||||
if (autoload) {
|
if (autoload) {
|
||||||
const DatabaseManagerStruct& dbStruct = m_dbList.value(db);
|
const DatabaseManagerStruct& dbStruct = m_dbList.value(db);
|
||||||
QFileInfo dbpath(dbStruct.canonicalFilePath);
|
QDir dbFolder(dbStruct.fileInfo.canonicalPath());
|
||||||
QDir dbFolder(dbpath.canonicalPath());
|
|
||||||
for (auto entry : autoload->entries()) {
|
for (auto entry : autoload->entries()) {
|
||||||
if (entry->url().isEmpty() || entry->password().isEmpty()) {
|
if (entry->url().isEmpty() || entry->password().isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
@ -756,17 +669,14 @@ void DatabaseTabWidget::lockDatabases()
|
|||||||
DatabaseWidget* dbWidget = static_cast<DatabaseWidget*>(widget(i));
|
DatabaseWidget* dbWidget = static_cast<DatabaseWidget*>(widget(i));
|
||||||
Database* db = databaseFromDatabaseWidget(dbWidget);
|
Database* db = databaseFromDatabaseWidget(dbWidget);
|
||||||
|
|
||||||
DatabaseWidget::Mode mode = dbWidget->currentMode();
|
if (dbWidget->currentMode() == DatabaseWidget::LockedMode || !dbWidget->dbHasKey()) {
|
||||||
|
|
||||||
if ((mode != DatabaseWidget::ViewMode && mode != DatabaseWidget::EditMode)
|
|
||||||
|| !dbWidget->dbHasKey()) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// show the correct tab widget before we are asking questions about it
|
// show the correct tab widget before we are asking questions about it
|
||||||
setCurrentWidget(dbWidget);
|
setCurrentWidget(dbWidget);
|
||||||
|
|
||||||
if (mode == DatabaseWidget::EditMode && dbWidget->isEditWidgetModified()) {
|
if (dbWidget->currentMode() == DatabaseWidget::EditMode && dbWidget->isEditWidgetModified()) {
|
||||||
QMessageBox::StandardButton result =
|
QMessageBox::StandardButton result =
|
||||||
MessageBox::question(
|
MessageBox::question(
|
||||||
this, tr("Lock database"),
|
this, tr("Lock database"),
|
||||||
@ -777,23 +687,7 @@ void DatabaseTabWidget::lockDatabases()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_dbList[db].modified) {
|
||||||
if (m_dbList[db].modified && !m_dbList[db].saveToFilename) {
|
|
||||||
QMessageBox::StandardButton result =
|
|
||||||
MessageBox::question(
|
|
||||||
this, tr("Lock database"),
|
|
||||||
tr("This database has never been saved.\nYou can save the database or stop locking it."),
|
|
||||||
QMessageBox::Save | QMessageBox::Cancel, QMessageBox::Cancel);
|
|
||||||
if (result == QMessageBox::Save) {
|
|
||||||
if (!saveDatabase(db)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (result == QMessageBox::Cancel) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (m_dbList[db].modified) {
|
|
||||||
QMessageBox::StandardButton result =
|
QMessageBox::StandardButton result =
|
||||||
MessageBox::question(
|
MessageBox::question(
|
||||||
this, tr("Lock database"),
|
this, tr("Lock database"),
|
||||||
@ -828,7 +722,7 @@ void DatabaseTabWidget::modified()
|
|||||||
Database* db = static_cast<Database*>(sender());
|
Database* db = static_cast<Database*>(sender());
|
||||||
DatabaseManagerStruct& dbStruct = m_dbList[db];
|
DatabaseManagerStruct& dbStruct = m_dbList[db];
|
||||||
|
|
||||||
if (config()->get("AutoSaveAfterEveryChange").toBool() && dbStruct.saveToFilename) {
|
if (config()->get("AutoSaveAfterEveryChange").toBool() && !dbStruct.readOnly) {
|
||||||
saveDatabase(db);
|
saveDatabase(db);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QTabWidget>
|
#include <QTabWidget>
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
#include "gui/DatabaseWidget.h"
|
#include "gui/DatabaseWidget.h"
|
||||||
#include "gui/MessageWidget.h"
|
#include "gui/MessageWidget.h"
|
||||||
@ -29,7 +30,6 @@ class DatabaseWidget;
|
|||||||
class DatabaseWidgetStateSync;
|
class DatabaseWidgetStateSync;
|
||||||
class DatabaseOpenWidget;
|
class DatabaseOpenWidget;
|
||||||
class QFile;
|
class QFile;
|
||||||
class QLockFile;
|
|
||||||
class MessageWidget;
|
class MessageWidget;
|
||||||
|
|
||||||
struct DatabaseManagerStruct
|
struct DatabaseManagerStruct
|
||||||
@ -37,11 +37,7 @@ struct DatabaseManagerStruct
|
|||||||
DatabaseManagerStruct();
|
DatabaseManagerStruct();
|
||||||
|
|
||||||
DatabaseWidget* dbWidget;
|
DatabaseWidget* dbWidget;
|
||||||
QLockFile* lockFile;
|
QFileInfo fileInfo;
|
||||||
QString filePath;
|
|
||||||
QString canonicalFilePath;
|
|
||||||
QString fileName;
|
|
||||||
bool saveToFilename;
|
|
||||||
bool modified;
|
bool modified;
|
||||||
bool readOnly;
|
bool readOnly;
|
||||||
};
|
};
|
||||||
@ -106,7 +102,7 @@ private slots:
|
|||||||
void emitDatabaseUnlockedFromDbWidgetSender();
|
void emitDatabaseUnlockedFromDbWidgetSender();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool saveDatabase(Database* db);
|
bool saveDatabase(Database* db, QString filePath = "");
|
||||||
bool saveDatabaseAs(Database* db);
|
bool saveDatabaseAs(Database* db);
|
||||||
bool closeDatabase(Database* db);
|
bool closeDatabase(Database* db);
|
||||||
void deleteDatabase(Database* db);
|
void deleteDatabase(Database* db);
|
||||||
|
@ -839,10 +839,10 @@ void DatabaseWidget::openDatabase(bool accepted)
|
|||||||
m_databaseOpenWidget = nullptr;
|
m_databaseOpenWidget = nullptr;
|
||||||
delete m_keepass1OpenWidget;
|
delete m_keepass1OpenWidget;
|
||||||
m_keepass1OpenWidget = nullptr;
|
m_keepass1OpenWidget = nullptr;
|
||||||
m_fileWatcher.addPath(m_filename);
|
m_fileWatcher.addPath(m_filePath);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_fileWatcher.removePath(m_filename);
|
m_fileWatcher.removePath(m_filePath);
|
||||||
if (m_databaseOpenWidget->database()) {
|
if (m_databaseOpenWidget->database()) {
|
||||||
delete m_databaseOpenWidget->database();
|
delete m_databaseOpenWidget->database();
|
||||||
}
|
}
|
||||||
@ -950,23 +950,23 @@ void DatabaseWidget::switchToDatabaseSettings()
|
|||||||
setCurrentWidget(m_databaseSettingsWidget);
|
setCurrentWidget(m_databaseSettingsWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseWidget::switchToOpenDatabase(const QString& fileName)
|
void DatabaseWidget::switchToOpenDatabase(const QString& filePath)
|
||||||
{
|
{
|
||||||
updateFilename(fileName);
|
updateFilePath(filePath);
|
||||||
if (m_databaseOpenWidget) {
|
if (m_databaseOpenWidget) {
|
||||||
m_databaseOpenWidget->load(fileName);
|
m_databaseOpenWidget->load(filePath);
|
||||||
setCurrentWidget(m_databaseOpenWidget);
|
setCurrentWidget(m_databaseOpenWidget);
|
||||||
} else if (m_unlockDatabaseWidget) {
|
} else if (m_unlockDatabaseWidget) {
|
||||||
m_unlockDatabaseWidget->load(fileName);
|
m_unlockDatabaseWidget->load(filePath);
|
||||||
setCurrentWidget(m_unlockDatabaseWidget);
|
setCurrentWidget(m_unlockDatabaseWidget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseWidget::switchToOpenDatabase(const QString& fileName, const QString& password,
|
void DatabaseWidget::switchToOpenDatabase(const QString& filePath, const QString& password,
|
||||||
const QString& keyFile)
|
const QString& keyFile)
|
||||||
{
|
{
|
||||||
updateFilename(fileName);
|
updateFilePath(filePath);
|
||||||
switchToOpenDatabase(fileName);
|
switchToOpenDatabase(filePath);
|
||||||
if (m_databaseOpenWidget) {
|
if (m_databaseOpenWidget) {
|
||||||
m_databaseOpenWidget->enterKey(password, keyFile);
|
m_databaseOpenWidget->enterKey(password, keyFile);
|
||||||
} else if (m_unlockDatabaseWidget) {
|
} else if (m_unlockDatabaseWidget) {
|
||||||
@ -974,35 +974,35 @@ void DatabaseWidget::switchToOpenDatabase(const QString& fileName, const QString
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseWidget::switchToImportCsv(const QString& fileName)
|
void DatabaseWidget::switchToImportCsv(const QString& filePath)
|
||||||
{
|
{
|
||||||
updateFilename(fileName);
|
updateFilePath(filePath);
|
||||||
m_csvImportWizard->load(fileName, m_db);
|
m_csvImportWizard->load(filePath, m_db);
|
||||||
m_changeMasterKeyWidget->clearForms();
|
m_changeMasterKeyWidget->clearForms();
|
||||||
m_changeMasterKeyWidget->setCancelEnabled(false);
|
m_changeMasterKeyWidget->setCancelEnabled(false);
|
||||||
setCurrentWidget(m_changeMasterKeyWidget);
|
setCurrentWidget(m_changeMasterKeyWidget);
|
||||||
m_importingCsv = true;
|
m_importingCsv = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseWidget::switchToOpenMergeDatabase(const QString& fileName)
|
void DatabaseWidget::switchToOpenMergeDatabase(const QString& filePath)
|
||||||
{
|
{
|
||||||
m_databaseOpenMergeWidget->clearForms();
|
m_databaseOpenMergeWidget->clearForms();
|
||||||
m_databaseOpenMergeWidget->load(fileName);
|
m_databaseOpenMergeWidget->load(filePath);
|
||||||
setCurrentWidget(m_databaseOpenMergeWidget);
|
setCurrentWidget(m_databaseOpenMergeWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DatabaseWidget::switchToOpenMergeDatabase(const QString& fileName, const QString& password,
|
void DatabaseWidget::switchToOpenMergeDatabase(const QString& filePath, const QString& password,
|
||||||
const QString& keyFile)
|
const QString& keyFile)
|
||||||
{
|
{
|
||||||
switchToOpenMergeDatabase(fileName);
|
switchToOpenMergeDatabase(filePath);
|
||||||
m_databaseOpenMergeWidget->enterKey(password, keyFile);
|
m_databaseOpenMergeWidget->enterKey(password, keyFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseWidget::switchToImportKeepass1(const QString& fileName)
|
void DatabaseWidget::switchToImportKeepass1(const QString& filePath)
|
||||||
{
|
{
|
||||||
updateFilename(fileName);
|
updateFilePath(filePath);
|
||||||
m_keepass1OpenWidget->load(fileName);
|
m_keepass1OpenWidget->load(filePath);
|
||||||
setCurrentWidget(m_keepass1OpenWidget);
|
setCurrentWidget(m_keepass1OpenWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1172,21 +1172,21 @@ void DatabaseWidget::lock()
|
|||||||
|
|
||||||
endSearch();
|
endSearch();
|
||||||
clearAllWidgets();
|
clearAllWidgets();
|
||||||
m_unlockDatabaseWidget->load(m_filename);
|
m_unlockDatabaseWidget->load(m_filePath);
|
||||||
setCurrentWidget(m_unlockDatabaseWidget);
|
setCurrentWidget(m_unlockDatabaseWidget);
|
||||||
Database* newDb = new Database();
|
Database* newDb = new Database();
|
||||||
newDb->metadata()->setName(m_db->metadata()->name());
|
newDb->metadata()->setName(m_db->metadata()->name());
|
||||||
replaceDatabase(newDb);
|
replaceDatabase(newDb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseWidget::updateFilename(const QString& fileName)
|
void DatabaseWidget::updateFilePath(const QString &filePath)
|
||||||
{
|
{
|
||||||
if (!m_filename.isEmpty()) {
|
if (!m_filePath.isEmpty()) {
|
||||||
m_fileWatcher.removePath(m_filename);
|
m_fileWatcher.removePath(m_filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_fileWatcher.addPath(fileName);
|
m_fileWatcher.addPath(filePath);
|
||||||
m_filename = fileName;
|
m_filePath = filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseWidget::blockAutoReload(bool block)
|
void DatabaseWidget::blockAutoReload(bool block)
|
||||||
@ -1202,7 +1202,7 @@ void DatabaseWidget::blockAutoReload(bool block)
|
|||||||
void DatabaseWidget::unblockAutoReload()
|
void DatabaseWidget::unblockAutoReload()
|
||||||
{
|
{
|
||||||
m_ignoreAutoReload = false;
|
m_ignoreAutoReload = false;
|
||||||
updateFilename(m_filename);
|
updateFilePath(m_filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseWidget::onWatchedFileChanged()
|
void DatabaseWidget::onWatchedFileChanged()
|
||||||
@ -1237,13 +1237,13 @@ void DatabaseWidget::reloadDatabaseFile()
|
|||||||
emit m_db->modified();
|
emit m_db->modified();
|
||||||
m_databaseModified = true;
|
m_databaseModified = true;
|
||||||
// Rewatch the database file
|
// Rewatch the database file
|
||||||
m_fileWatcher.addPath(m_filename);
|
m_fileWatcher.addPath(m_filePath);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KeePass2Reader reader;
|
KeePass2Reader reader;
|
||||||
QFile file(m_filename);
|
QFile file(m_filePath);
|
||||||
if (file.open(QIODevice::ReadOnly)) {
|
if (file.open(QIODevice::ReadOnly)) {
|
||||||
Database* db = reader.readDatabase(&file, database()->key());
|
Database* db = reader.readDatabase(&file, database()->key());
|
||||||
if (db != nullptr) {
|
if (db != nullptr) {
|
||||||
@ -1284,12 +1284,16 @@ void DatabaseWidget::reloadDatabaseFile()
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_messageWidget->showMessage(
|
m_messageWidget->showMessage(
|
||||||
tr("Could not open the new database file while attempting to autoreload this database."),
|
tr("Could not open the new database file while attempting to autoreload this database.")
|
||||||
|
.append("\n").append(file.errorString()),
|
||||||
MessageWidget::Error);
|
MessageWidget::Error);
|
||||||
|
// HACK: Directly calling the database's signal
|
||||||
|
// Mark db as modified since existing data may differ from file or file was deleted
|
||||||
|
m_db->modified();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewatch the database file
|
// Rewatch the database file
|
||||||
m_fileWatcher.addPath(m_filename);
|
m_fileWatcher.addPath(m_filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
int DatabaseWidget::numberOfSelectedEntries() const
|
int DatabaseWidget::numberOfSelectedEntries() const
|
||||||
@ -1413,7 +1417,7 @@ EntryView* DatabaseWidget::entryView() {
|
|||||||
void DatabaseWidget::showUnlockDialog()
|
void DatabaseWidget::showUnlockDialog()
|
||||||
{
|
{
|
||||||
m_unlockDatabaseDialog->clearForms();
|
m_unlockDatabaseDialog->clearForms();
|
||||||
m_unlockDatabaseDialog->setDBFilename(m_filename);
|
m_unlockDatabaseDialog->setFilePath(m_filePath);
|
||||||
|
|
||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
autoType()->raiseWindow();
|
autoType()->raiseWindow();
|
||||||
|
@ -82,7 +82,7 @@ public:
|
|||||||
void setCurrentWidget(QWidget* widget);
|
void setCurrentWidget(QWidget* widget);
|
||||||
DatabaseWidget::Mode currentMode() const;
|
DatabaseWidget::Mode currentMode() const;
|
||||||
void lock();
|
void lock();
|
||||||
void updateFilename(const QString& filename);
|
void updateFilePath(const QString &filePath);
|
||||||
int numberOfSelectedEntries() const;
|
int numberOfSelectedEntries() const;
|
||||||
QStringList customEntryAttributes() const;
|
QStringList customEntryAttributes() const;
|
||||||
bool isGroupSelected() const;
|
bool isGroupSelected() const;
|
||||||
@ -155,13 +155,13 @@ public slots:
|
|||||||
void switchToGroupEdit();
|
void switchToGroupEdit();
|
||||||
void switchToMasterKeyChange(bool disableCancel = false);
|
void switchToMasterKeyChange(bool disableCancel = false);
|
||||||
void switchToDatabaseSettings();
|
void switchToDatabaseSettings();
|
||||||
void switchToOpenDatabase(const QString& fileName);
|
void switchToOpenDatabase(const QString& filePath);
|
||||||
void switchToOpenDatabase(const QString& fileName, const QString& password, const QString& keyFile);
|
void switchToOpenDatabase(const QString& filePath, const QString& password, const QString& keyFile);
|
||||||
void switchToImportCsv(const QString& fileName);
|
void switchToImportCsv(const QString& filePath);
|
||||||
void csvImportFinished(bool accepted);
|
void csvImportFinished(bool accepted);
|
||||||
void switchToOpenMergeDatabase(const QString& fileName);
|
void switchToOpenMergeDatabase(const QString& filePath);
|
||||||
void switchToOpenMergeDatabase(const QString& fileName, const QString& password, const QString& keyFile);
|
void switchToOpenMergeDatabase(const QString& filePath, const QString& password, const QString& keyFile);
|
||||||
void switchToImportKeepass1(const QString& fileName);
|
void switchToImportKeepass1(const QString& filePath);
|
||||||
void databaseModified();
|
void databaseModified();
|
||||||
void databaseSaved();
|
void databaseSaved();
|
||||||
void emptyRecycleBin();
|
void emptyRecycleBin();
|
||||||
@ -225,7 +225,7 @@ private:
|
|||||||
Group* m_newGroup;
|
Group* m_newGroup;
|
||||||
Entry* m_newEntry;
|
Entry* m_newEntry;
|
||||||
Group* m_newParent;
|
Group* m_newParent;
|
||||||
QString m_filename;
|
QString m_filePath;
|
||||||
Uuid m_groupBeforeLock;
|
Uuid m_groupBeforeLock;
|
||||||
Uuid m_entryBeforeLock;
|
Uuid m_entryBeforeLock;
|
||||||
MessageWidget* m_messageWidget;
|
MessageWidget* m_messageWidget;
|
||||||
|
@ -30,9 +30,9 @@ UnlockDatabaseDialog::UnlockDatabaseDialog(QWidget* parent)
|
|||||||
connect(m_view, SIGNAL(editFinished(bool)), this, SLOT(complete(bool)));
|
connect(m_view, SIGNAL(editFinished(bool)), this, SLOT(complete(bool)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnlockDatabaseDialog::setDBFilename(const QString& filename)
|
void UnlockDatabaseDialog::setFilePath(const QString &filePath)
|
||||||
{
|
{
|
||||||
m_view->load(filename);
|
m_view->load(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnlockDatabaseDialog::clearForms()
|
void UnlockDatabaseDialog::clearForms()
|
||||||
|
@ -32,7 +32,7 @@ class UnlockDatabaseDialog : public QDialog
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit UnlockDatabaseDialog(QWidget* parent = nullptr);
|
explicit UnlockDatabaseDialog(QWidget* parent = nullptr);
|
||||||
void setDBFilename(const QString& filename);
|
void setFilePath(const QString &filePath);
|
||||||
void clearForms();
|
void clearForms();
|
||||||
Database* database();
|
Database* database();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user