mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-07-27 16:55:19 -04:00
Guarantee that configuration values are committed to disk on exit
This commit is contained in:
parent
af9e1e79cd
commit
527868a6b3
8 changed files with 115 additions and 86 deletions
|
@ -21,7 +21,6 @@
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QStandardPaths>
|
|
||||||
#include <QTemporaryFile>
|
#include <QTemporaryFile>
|
||||||
|
|
||||||
Config* Config::m_instance(nullptr);
|
Config* Config::m_instance(nullptr);
|
||||||
|
@ -51,6 +50,18 @@ void Config::set(const QString& key, const QVariant& value)
|
||||||
m_settings->setValue(key, value);
|
m_settings->setValue(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sync configuration with persistent storage.
|
||||||
|
*
|
||||||
|
* Usually, you don't need to call this method manually, but if you are writing
|
||||||
|
* configurations after an emitted \link QCoreApplication::aboutToQuit() signal,
|
||||||
|
* use it to guarantee your config values are persisted.
|
||||||
|
*/
|
||||||
|
void Config::sync()
|
||||||
|
{
|
||||||
|
m_settings->sync();
|
||||||
|
}
|
||||||
|
|
||||||
Config::Config(const QString& fileName, QObject* parent)
|
Config::Config(const QString& fileName, QObject* parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
{
|
{
|
||||||
|
@ -106,6 +117,7 @@ Config::~Config()
|
||||||
void Config::init(const QString& fileName)
|
void Config::init(const QString& fileName)
|
||||||
{
|
{
|
||||||
m_settings.reset(new QSettings(fileName, QSettings::IniFormat));
|
m_settings.reset(new QSettings(fileName, QSettings::IniFormat));
|
||||||
|
connect(qApp, &QCoreApplication::aboutToQuit, this, &Config::sync);
|
||||||
|
|
||||||
m_defaults.insert("SingleInstance", true);
|
m_defaults.insert("SingleInstance", true);
|
||||||
m_defaults.insert("RememberLastDatabases", true);
|
m_defaults.insert("RememberLastDatabases", true);
|
||||||
|
@ -162,7 +174,7 @@ void Config::createConfigFromFile(const QString& file)
|
||||||
void Config::createTempFileInstance()
|
void Config::createTempFileInstance()
|
||||||
{
|
{
|
||||||
Q_ASSERT(!m_instance);
|
Q_ASSERT(!m_instance);
|
||||||
QTemporaryFile* tmpFile = new QTemporaryFile();
|
auto* tmpFile = new QTemporaryFile();
|
||||||
bool openResult = tmpFile->open();
|
bool openResult = tmpFile->open();
|
||||||
Q_ASSERT(openResult);
|
Q_ASSERT(openResult);
|
||||||
Q_UNUSED(openResult);
|
Q_UNUSED(openResult);
|
||||||
|
|
|
@ -29,12 +29,15 @@ class Config : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~Config();
|
Q_DISABLE_COPY(Config)
|
||||||
|
|
||||||
|
~Config() override;
|
||||||
QVariant get(const QString& key);
|
QVariant get(const QString& key);
|
||||||
QVariant get(const QString& key, const QVariant& defaultValue);
|
QVariant get(const QString& key, const QVariant& defaultValue);
|
||||||
QString getFileName();
|
QString getFileName();
|
||||||
void set(const QString& key, const QVariant& value);
|
void set(const QString& key, const QVariant& value);
|
||||||
bool hasAccessError();
|
bool hasAccessError();
|
||||||
|
void sync();
|
||||||
|
|
||||||
static Config* instance();
|
static Config* instance();
|
||||||
static void createConfigFromFile(const QString& file);
|
static void createConfigFromFile(const QString& file);
|
||||||
|
@ -49,8 +52,6 @@ private:
|
||||||
|
|
||||||
QScopedPointer<QSettings> m_settings;
|
QScopedPointer<QSettings> m_settings;
|
||||||
QHash<QString, QVariant> m_defaults;
|
QHash<QString, QVariant> m_defaults;
|
||||||
|
|
||||||
Q_DISABLE_COPY(Config)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Config* config() {
|
inline Config* config() {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
|
|
||||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||||
|
* Copyright (C) 2011 Felix Geyer <debfx@fobos.de>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -51,7 +51,7 @@ class DatabaseTabWidget : public QTabWidget
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DatabaseTabWidget(QWidget* parent = nullptr);
|
explicit DatabaseTabWidget(QWidget* parent = nullptr);
|
||||||
~DatabaseTabWidget();
|
~DatabaseTabWidget() override;
|
||||||
void openDatabase(const QString& fileName, const QString& pw = QString(),
|
void openDatabase(const QString& fileName, const QString& pw = QString(),
|
||||||
const QString& keyFile = QString());
|
const QString& keyFile = QString());
|
||||||
void mergeDatabase(const QString& fileName);
|
void mergeDatabase(const QString& fileName);
|
||||||
|
@ -116,7 +116,7 @@ private:
|
||||||
void connectDatabase(Database* newDb, Database* oldDb = nullptr);
|
void connectDatabase(Database* newDb, Database* oldDb = nullptr);
|
||||||
|
|
||||||
QHash<Database*, DatabaseManagerStruct> m_dbList;
|
QHash<Database*, DatabaseManagerStruct> m_dbList;
|
||||||
DatabaseWidgetStateSync* m_dbWidgetStateSync;
|
QPointer<DatabaseWidgetStateSync> m_dbWidgetStateSync;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KEEPASSX_DATABASETABWIDGET_H
|
#endif // KEEPASSX_DATABASETABWIDGET_H
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
|
||||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||||
|
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
|
||||||
* Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
|
* Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
|
||||||
* Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
|
* Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
|
||||||
*
|
*
|
||||||
|
@ -19,6 +20,7 @@
|
||||||
#include "DatabaseWidgetStateSync.h"
|
#include "DatabaseWidgetStateSync.h"
|
||||||
|
|
||||||
#include "core/Config.h"
|
#include "core/Config.h"
|
||||||
|
#include <QCoreApplication>
|
||||||
|
|
||||||
DatabaseWidgetStateSync::DatabaseWidgetStateSync(QObject* parent)
|
DatabaseWidgetStateSync::DatabaseWidgetStateSync(QObject* parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
|
@ -31,9 +33,18 @@ DatabaseWidgetStateSync::DatabaseWidgetStateSync(QObject* parent)
|
||||||
m_hidePasswords = config()->get("GUI/HidePasswords").toBool();
|
m_hidePasswords = config()->get("GUI/HidePasswords").toBool();
|
||||||
m_listViewState = config()->get("GUI/ListViewState").toByteArray();
|
m_listViewState = config()->get("GUI/ListViewState").toByteArray();
|
||||||
m_searchViewState = config()->get("GUI/SearchViewState").toByteArray();
|
m_searchViewState = config()->get("GUI/SearchViewState").toByteArray();
|
||||||
|
|
||||||
|
connect(qApp, &QCoreApplication::aboutToQuit, this, &DatabaseWidgetStateSync::sync);
|
||||||
}
|
}
|
||||||
|
|
||||||
DatabaseWidgetStateSync::~DatabaseWidgetStateSync()
|
DatabaseWidgetStateSync::~DatabaseWidgetStateSync()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sync state with persistent storage.
|
||||||
|
*/
|
||||||
|
void DatabaseWidgetStateSync::sync()
|
||||||
{
|
{
|
||||||
config()->set("GUI/SplitterState", intListToVariant(m_mainSplitterSizes));
|
config()->set("GUI/SplitterState", intListToVariant(m_mainSplitterSizes));
|
||||||
config()->set("GUI/DetailSplitterState", intListToVariant(m_detailSplitterSizes));
|
config()->set("GUI/DetailSplitterState", intListToVariant(m_detailSplitterSizes));
|
||||||
|
@ -41,12 +52,13 @@ DatabaseWidgetStateSync::~DatabaseWidgetStateSync()
|
||||||
config()->set("GUI/HidePasswords", m_hidePasswords);
|
config()->set("GUI/HidePasswords", m_hidePasswords);
|
||||||
config()->set("GUI/ListViewState", m_listViewState);
|
config()->set("GUI/ListViewState", m_listViewState);
|
||||||
config()->set("GUI/SearchViewState", m_searchViewState);
|
config()->set("GUI/SearchViewState", m_searchViewState);
|
||||||
|
config()->sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabaseWidgetStateSync::setActive(DatabaseWidget* dbWidget)
|
void DatabaseWidgetStateSync::setActive(DatabaseWidget* dbWidget)
|
||||||
{
|
{
|
||||||
if (m_activeDbWidget) {
|
if (m_activeDbWidget) {
|
||||||
disconnect(m_activeDbWidget, 0, this, 0);
|
disconnect(m_activeDbWidget, nullptr, this, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_activeDbWidget = dbWidget;
|
m_activeDbWidget = dbWidget;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
|
||||||
* Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
|
* Copyright (C) 2014 Felix Geyer <debfx@fobos.de>
|
||||||
* Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
|
* Copyright (C) 2014 Florian Geyer <blueice@fobos.de>
|
||||||
*
|
*
|
||||||
|
@ -27,7 +28,7 @@ class DatabaseWidgetStateSync : public QObject
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DatabaseWidgetStateSync(QObject* parent = nullptr);
|
explicit DatabaseWidgetStateSync(QObject* parent = nullptr);
|
||||||
~DatabaseWidgetStateSync();
|
~DatabaseWidgetStateSync() override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setActive(DatabaseWidget* dbWidget);
|
void setActive(DatabaseWidget* dbWidget);
|
||||||
|
@ -38,12 +39,13 @@ private slots:
|
||||||
void blockUpdates();
|
void blockUpdates();
|
||||||
void updateSplitterSizes();
|
void updateSplitterSizes();
|
||||||
void updateViewState();
|
void updateViewState();
|
||||||
|
void sync();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static QList<int> variantToIntList(const QVariant& variant);
|
static QList<int> variantToIntList(const QVariant& variant);
|
||||||
static QVariant intListToVariant(const QList<int>& list);
|
static QVariant intListToVariant(const QList<int>& list);
|
||||||
|
|
||||||
DatabaseWidget* m_activeDbWidget;
|
QPointer<DatabaseWidget> m_activeDbWidget;
|
||||||
|
|
||||||
bool m_blockUpdates;
|
bool m_blockUpdates;
|
||||||
QList<int> m_mainSplitterSizes;
|
QList<int> m_mainSplitterSizes;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
|
||||||
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
@ -88,11 +89,11 @@ EntryView::EntryView(QWidget* parent)
|
||||||
// Stretching of last section interferes with fitting columns to window
|
// Stretching of last section interferes with fitting columns to window
|
||||||
header()->setStretchLastSection(false);
|
header()->setStretchLastSection(false);
|
||||||
header()->setContextMenuPolicy(Qt::CustomContextMenu);
|
header()->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
connect(header(), SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showHeaderMenu(QPoint)));
|
connect(header(), SIGNAL(customContextMenuRequested(QPoint)), SLOT(showHeaderMenu(QPoint)));
|
||||||
connect(header(), SIGNAL(sectionCountChanged(int, int)), this, SIGNAL(viewStateChanged()));
|
connect(header(), SIGNAL(sectionCountChanged(int, int)), SIGNAL(viewStateChanged()));
|
||||||
connect(header(), SIGNAL(sectionMoved(int, int, int)), this, SIGNAL(viewStateChanged()));
|
connect(header(), SIGNAL(sectionMoved(int, int, int)), SIGNAL(viewStateChanged()));
|
||||||
connect(header(), SIGNAL(sectionResized(int, int, int)), this, SIGNAL(viewStateChanged()));
|
connect(header(), SIGNAL(sectionResized(int, int, int)), SIGNAL(viewStateChanged()));
|
||||||
connect(header(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), this, SIGNAL(viewStateChanged()));
|
connect(header(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), SIGNAL(viewStateChanged()));
|
||||||
|
|
||||||
// TODO: not working as expected, columns will end up being very small,
|
// TODO: not working as expected, columns will end up being very small,
|
||||||
// most likely due to the widget not being sized properly at this time
|
// most likely due to the widget not being sized properly at this time
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2018 KeePassXC Team <team@keepassxc.org>
|
||||||
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
* Copyright (C) 2010 Felix Geyer <debfx@fobos.de>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue