Core: Disentangle SettingsDatabase access

There's nothing inherently tied to the main window here.

Change-Id: I48ae09777a4408fc4c955d23fdee3483d8a97dd0
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
hjk
2023-09-14 17:00:11 +02:00
parent 5ec327d66d
commit 41856dd254
10 changed files with 114 additions and 141 deletions

View File

@@ -12,6 +12,7 @@
#include "mainwindow.h"
#include "modemanager.h"
#include "session.h"
#include "settingsdatabase.h"
#include "themechooser.h"
#include "actionmanager/actionmanager.h"
@@ -96,6 +97,7 @@ CorePlugin::~CorePlugin()
DesignMode::destroyModeIfRequired();
delete m_mainWindow;
SettingsDatabase::destroy();
setCreatorTheme(nullptr);
}

View File

@@ -1201,7 +1201,7 @@ static QHash<QString, IEditorFactory *> fromMap(const QMap<QString, QVariant> &m
void EditorManagerPrivate::saveSettings()
{
ICore::settingsDatabase()->setValue(documentStatesKey, d->m_editorStates);
SettingsDatabase::setValue(documentStatesKey, d->m_editorStates);
QtcSettings *qsettings = ICore::settings();
qsettings->setValueWithDefault(preferredEditorFactoriesKey,
@@ -1224,10 +1224,9 @@ void EditorManagerPrivate::readSettings()
qs->value(preferredEditorFactoriesKey).toMap());
setUserPreferredEditorTypes(preferredEditorFactories);
SettingsDatabase *settings = ICore::settingsDatabase();
if (settings->contains(documentStatesKey)) {
d->m_editorStates = settings->value(documentStatesKey)
.value<QMap<QString, QVariant> >();
if (SettingsDatabase::contains(documentStatesKey)) {
d->m_editorStates = SettingsDatabase::value(documentStatesKey)
.value<QMap<QString, QVariant>>();
}
updateAutoSave();

View File

@@ -362,21 +362,6 @@ QtcSettings *ICore::settings(QSettings::Scope scope)
return PluginManager::globalSettings();
}
/*!
Returns the application's settings database.
The settings database is meant as an alternative to the regular settings
object. It is more suitable for storing large amounts of data. The settings
are application wide.
\sa SettingsDatabase
\sa settings()
*/
SettingsDatabase *ICore::settingsDatabase()
{
return m_mainwindow->settingsDatabase();
}
/*!
Returns the application's printer object.

View File

@@ -28,7 +28,6 @@ namespace Utils { class InfoBar; }
namespace Core {
class Context;
class IWizardFactory;
class SettingsDatabase;
namespace Internal { class MainWindow; }
@@ -69,7 +68,6 @@ public:
QWidget *parent = nullptr);
static Utils::QtcSettings *settings(QSettings::Scope scope = QSettings::UserScope);
static SettingsDatabase *settingsDatabase();
static QPrinter *printer();
static QString userInterfaceLanguage();

View File

@@ -155,26 +155,26 @@ void Locator::aboutToShutdown()
void Locator::loadSettings()
{
SettingsDatabase *settings = ICore::settingsDatabase();
namespace DB = SettingsDatabase;
// check if we have to read old settings
// TOOD remove a few versions after 4.15
const QString settingsGroup = settings->contains("Locator") ? QString("Locator")
const QString settingsGroup = DB::contains("Locator") ? QString("Locator")
: QString("QuickOpen");
const Settings def;
settings->beginGroup(settingsGroup);
m_refreshTimer.setInterval(settings->value("RefreshInterval", 60).toInt() * 60000);
m_settings.useCenteredPopup = settings->value(kUseCenteredPopup, def.useCenteredPopup).toBool();
DB::beginGroup(settingsGroup);
m_refreshTimer.setInterval(DB::value("RefreshInterval", 60).toInt() * 60000);
m_settings.useCenteredPopup = DB::value(kUseCenteredPopup, def.useCenteredPopup).toBool();
for (ILocatorFilter *filter : std::as_const(m_filters)) {
if (settings->contains(filter->id().toString())) {
const QByteArray state = settings->value(filter->id().toString()).toByteArray();
if (DB::contains(filter->id().toString())) {
const QByteArray state = DB::value(filter->id().toString()).toByteArray();
if (!state.isEmpty())
filter->restoreState(state);
}
}
settings->beginGroup("CustomFilters");
DB::beginGroup("CustomFilters");
QList<ILocatorFilter *> customFilters;
const QStringList keys = settings->childKeys();
const QStringList keys = DB::childKeys();
int count = 0;
const Id directoryBaseId(Constants::CUSTOM_DIRECTORY_FILTER_BASEID);
const Id urlBaseId(Constants::CUSTOM_URL_FILTER_BASEID);
@@ -188,12 +188,12 @@ void Locator::loadSettings()
urlFilter->setIsCustomFilter(true);
filter = urlFilter;
}
filter->restoreState(settings->value(key).toByteArray());
filter->restoreState(DB::value(key).toByteArray());
customFilters.append(filter);
}
setCustomFilters(customFilters);
settings->endGroup();
settings->endGroup();
DB::endGroup();
DB::endGroup();
if (m_refreshTimer.interval() > 0)
m_refreshTimer.start();
@@ -288,19 +288,19 @@ void Locator::saveSettings() const
return;
const Settings def;
SettingsDatabase *s = ICore::settingsDatabase();
s->beginTransaction();
s->beginGroup("Locator");
s->remove(QString());
s->setValue("RefreshInterval", refreshInterval());
s->setValueWithDefault(kUseCenteredPopup, m_settings.useCenteredPopup, def.useCenteredPopup);
namespace DB = SettingsDatabase;
DB::beginTransaction();
DB::beginGroup("Locator");
DB::remove(QString());
DB::setValue("RefreshInterval", refreshInterval());
DB::setValueWithDefault(kUseCenteredPopup, m_settings.useCenteredPopup, def.useCenteredPopup);
for (ILocatorFilter *filter : m_filters) {
if (!m_customFilters.contains(filter) && filter->id().isValid()) {
const QByteArray state = filter->saveState();
s->setValueWithDefault(filter->id().toString(), state);
DB::setValueWithDefault(filter->id().toString(), state);
}
}
s->beginGroup("CustomFilters");
DB::beginGroup("CustomFilters");
int i = 0;
for (ILocatorFilter *filter : m_customFilters) {
const char *prefix = filter->id().name().startsWith(
@@ -308,12 +308,12 @@ void Locator::saveSettings() const
? kDirectoryFilterPrefix
: kUrlFilterPrefix;
const QByteArray state = filter->saveState();
s->setValueWithDefault(prefix + QString::number(i), state);
DB::setValueWithDefault(prefix + QString::number(i), state);
++i;
}
s->endGroup();
s->endGroup();
s->endTransaction();
DB::endGroup();
DB::endGroup();
DB::endTransaction();
}
/*!

View File

@@ -39,7 +39,6 @@
#include "progressmanager/progressmanager_p.h"
#include "progressmanager/progressview.h"
#include "rightpane.h"
#include "settingsdatabase.h"
#include "statusbarmanager.h"
#include "systemsettings.h"
#include "vcsmanager.h"
@@ -73,7 +72,6 @@
#include <QComboBox>
#include <QDebug>
#include <QDialogButtonBox>
#include <QFileInfo>
#include <QMenu>
#include <QMenuBar>
#include <QMessageBox>
@@ -112,9 +110,6 @@ MainWindow::MainWindow()
: AppMainWindow()
, m_coreImpl(new ICore(this))
, m_lowPrioAdditionalContexts(Constants::C_GLOBAL)
, m_settingsDatabase(
new SettingsDatabase(QFileInfo(PluginManager::settings()->fileName()).path(),
QCoreApplication::applicationName()))
, m_progressManager(new ProgressManagerPrivate)
, m_jsExpander(JsExpander::createGlobalJsExpander())
, m_vcsManager(new VcsManager)
@@ -296,9 +291,6 @@ MainWindow::~MainWindow()
delete m_jsExpander;
m_jsExpander = nullptr;
delete m_settingsDatabase;
m_settingsDatabase = nullptr;
}
void MainWindow::init()

View File

@@ -36,7 +36,6 @@ class ProgressManager;
class NavigationWidget;
enum class Side;
class RightPaneWidget;
class SettingsDatabase;
class VcsManager;
namespace Internal {
@@ -71,7 +70,6 @@ public:
ICore::OpenFilesFlags flags,
const Utils::FilePath &workingDirectory = {});
inline SettingsDatabase *settingsDatabase() const { return m_settingsDatabase; }
virtual QPrinter *printer() const;
IContext * currentContextObject() const;
QStatusBar *statusBar() const;
@@ -137,7 +135,6 @@ private:
QStringList m_aboutInformation;
Context m_highPrioAdditionalContexts;
Context m_lowPrioAdditionalContexts;
SettingsDatabase *m_settingsDatabase = nullptr;
mutable QPrinter *m_printer = nullptr;
WindowSupport *m_windowSupport = nullptr;
EditorManager *m_editorManager = nullptr;

View File

@@ -3,6 +3,8 @@
#include "settingsdatabase.h"
#include <extensionsystem/pluginmanager.h>
#include <QDir>
#include <QMap>
#include <QString>
@@ -13,13 +15,14 @@
#include <QSqlError>
#include <QSqlQuery>
#include <QDebug>
#include <QCoreApplication>
/*!
\class Core::SettingsDatabase
\namespace Core::SettingsDatabase
\inheaderfile coreplugin/settingsdatabase.h
\inmodule QtCreator
\brief The SettingsDatabase class offers an alternative to the
\brief The SettingsDatabase namespace offers an alternative to the
application-wide QSettings that is more
suitable for storing large amounts of data.
@@ -28,19 +31,20 @@
rewriting the whole file each time one of the settings change.
The SettingsDatabase API mimics that of QSettings.
\sa settings()
*/
using namespace Core;
using namespace Core::Internal;
using namespace ExtensionSystem;
enum { debug_settings = 0 };
namespace Core {
namespace Internal {
namespace Core::SettingsDatabase {
using SettingsMap = QMap<QString, QVariant>;
class SettingsDatabasePrivate
class SettingsDatabaseImpl
{
public:
QString effectiveGroup() const
@@ -65,12 +69,17 @@ public:
QSqlDatabase m_db;
};
} // namespace Internal
} // namespace Core
static SettingsDatabaseImpl *d;
SettingsDatabase::SettingsDatabase(const QString &path, const QString &application)
: d(new SettingsDatabasePrivate)
void ensureImpl()
{
if (d)
return;
d = new SettingsDatabaseImpl;
const QString path = QFileInfo(PluginManager::settings()->fileName()).path();
const QString application = QCoreApplication::applicationName();
const QLatin1Char slash('/');
// TODO: Don't rely on a path, but determine automatically
@@ -111,16 +120,21 @@ SettingsDatabase::SettingsDatabase(const QString &path, const QString &applicati
}
}
SettingsDatabase::~SettingsDatabase()
void destroy()
{
sync();
if (!d)
return;
// TODO: Delay writing of dirty keys and save them here
delete d;
d = nullptr;
QSqlDatabase::removeDatabase(QLatin1String("settings"));
}
void SettingsDatabase::setValue(const QString &key, const QVariant &value)
void setValue(const QString &key, const QVariant &value)
{
ensureImpl();
const QString effectiveKey = d->effectiveKey(key);
// Add to cache
@@ -140,8 +154,9 @@ void SettingsDatabase::setValue(const QString &key, const QVariant &value)
qDebug() << "Stored:" << effectiveKey << "=" << value;
}
QVariant SettingsDatabase::value(const QString &key, const QVariant &defaultValue) const
QVariant value(const QString &key, const QVariant &defaultValue)
{
ensureImpl();
const QString effectiveKey = d->effectiveKey(key);
QVariant value = defaultValue;
@@ -168,8 +183,9 @@ QVariant SettingsDatabase::value(const QString &key, const QVariant &defaultValu
return value;
}
bool SettingsDatabase::contains(const QString &key) const
bool contains(const QString &key)
{
ensureImpl();
// check exact key
// this already caches the value
if (value(key).isValid())
@@ -187,8 +203,9 @@ bool SettingsDatabase::contains(const QString &key) const
return false;
}
void SettingsDatabase::remove(const QString &key)
void remove(const QString &key)
{
ensureImpl();
const QString effectiveKey = d->effectiveKey(key);
// Remove keys from the cache
@@ -214,23 +231,27 @@ void SettingsDatabase::remove(const QString &key)
query.exec();
}
void SettingsDatabase::beginGroup(const QString &prefix)
void beginGroup(const QString &prefix)
{
ensureImpl();
d->m_groups.append(prefix);
}
void SettingsDatabase::endGroup()
void endGroup()
{
ensureImpl();
d->m_groups.removeLast();
}
QString SettingsDatabase::group() const
QString group()
{
ensureImpl();
return d->effectiveGroup();
}
QStringList SettingsDatabase::childKeys() const
QStringList childKeys()
{
ensureImpl();
QStringList children;
const QString g = group();
@@ -243,21 +264,20 @@ QStringList SettingsDatabase::childKeys() const
return children;
}
void SettingsDatabase::beginTransaction()
void beginTransaction()
{
ensureImpl();
if (!d->m_db.isOpen())
return;
d->m_db.transaction();
}
void SettingsDatabase::endTransaction()
void endTransaction()
{
ensureImpl();
if (!d->m_db.isOpen())
return;
d->m_db.commit();
}
void SettingsDatabase::sync()
{
// TODO: Delay writing of dirty keys and save them here
}
} // Core::SettingsDatabase

View File

@@ -5,48 +5,28 @@
#include "core_global.h"
#include <QObject>
#include <QString>
#include <QStringList>
#include <QVariant>
namespace Core {
namespace Core::SettingsDatabase {
namespace Internal { class SettingsDatabasePrivate; }
CORE_EXPORT void setValue(const QString &key, const QVariant &value);
CORE_EXPORT QVariant value(const QString &key, const QVariant &defaultValue = {});
class CORE_EXPORT SettingsDatabase final
{
public:
SettingsDatabase(const QString &path, const QString &application);
~SettingsDatabase();
CORE_EXPORT bool contains(const QString &key);
CORE_EXPORT void remove(const QString &key);
void setValue(const QString &key, const QVariant &value);
QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
CORE_EXPORT void beginGroup(const QString &prefix);
CORE_EXPORT void endGroup();
CORE_EXPORT QString group();
CORE_EXPORT QStringList childKeys();
template<typename T>
void setValueWithDefault(const QString &key, const T &val, const T &defaultValue);
template<typename T>
void setValueWithDefault(const QString &key, const T &val);
CORE_EXPORT void beginTransaction();
CORE_EXPORT void endTransaction();
bool contains(const QString &key) const;
void remove(const QString &key);
void beginGroup(const QString &prefix);
void endGroup();
QString group() const;
QStringList childKeys() const;
void beginTransaction();
void endTransaction();
void sync();
private:
Internal::SettingsDatabasePrivate *d;
};
CORE_EXPORT void destroy();
template<typename T>
void SettingsDatabase::setValueWithDefault(const QString &key, const T &val, const T &defaultValue)
void setValueWithDefault(const QString &key, const T &val, const T &defaultValue)
{
if (val == defaultValue)
remove(key);
@@ -55,7 +35,7 @@ void SettingsDatabase::setValueWithDefault(const QString &key, const T &val, con
}
template<typename T>
void SettingsDatabase::setValueWithDefault(const QString &key, const T &val)
void setValueWithDefault(const QString &key, const T &val)
{
if (val == T())
remove(key);
@@ -63,4 +43,4 @@ void SettingsDatabase::setValueWithDefault(const QString &key, const T &val)
setValue(key, QVariant::fromValue(val));
}
} // namespace Core
} // Core::SettingsDatabase

View File

@@ -36,11 +36,11 @@ static QString emSdkEnvOutput(const FilePath &sdkRoot)
return {};
const QDateTime ts = tsFile.lastModified();
Core::SettingsDatabase *db = Core::ICore::settingsDatabase();
if (db->value(emSdkEnvTSKey).toDateTime() == ts
&& FilePath::fromVariant(db->value(emSdkEnvTSFileKey)) == tsFile
&& db->contains(emSdkEnvOutputKey)) {
return db->value(emSdkEnvOutputKey).toString();
namespace DB = Core::SettingsDatabase;
if (DB::value(emSdkEnvTSKey).toDateTime() == ts
&& FilePath::fromVariant(DB::value(emSdkEnvTSFileKey)) == tsFile
&& DB::contains(emSdkEnvOutputKey)) {
return DB::value(emSdkEnvOutputKey).toString();
}
const bool isWindows = sdkRoot.osType() == OsTypeWindows;
@@ -55,9 +55,9 @@ static QString emSdkEnvOutput(const FilePath &sdkRoot)
}
emSdkEnv.runBlocking();
const QString result = emSdkEnv.allOutput();
db->setValue(emSdkEnvTSFileKey, tsFile.toVariant());
db->setValue(emSdkEnvTSKey, ts);
db->setValue(emSdkEnvOutputKey, result);
DB::setValue(emSdkEnvTSFileKey, tsFile.toVariant());
DB::setValue(emSdkEnvTSKey, ts);
DB::setValue(emSdkEnvOutputKey, result);
return result;
}
@@ -103,11 +103,11 @@ QVersionNumber version(const FilePath &sdkRoot)
return {};
const QDateTime ts = tsFile.lastModified();
Core::SettingsDatabase *db = Core::ICore::settingsDatabase();
if (db->value(emSdkVersionTSKey).toDateTime() == ts
&& FilePath::fromVariant(db->value(emSdkVersionTSFileKey)) == tsFile
&& db->contains(emSdkVersionKey)) {
return QVersionNumber::fromString(db->value(emSdkVersionKey).toString());
namespace DB = Core::SettingsDatabase;
if (DB::value(emSdkVersionTSKey).toDateTime() == ts
&& FilePath::fromVariant(DB::value(emSdkVersionTSFileKey)) == tsFile
&& DB::contains(emSdkVersionKey)) {
return QVersionNumber::fromString(DB::value(emSdkVersionKey).toString());
}
Environment env = sdkRoot.deviceEnvironment();
@@ -121,21 +121,21 @@ QVersionNumber version(const FilePath &sdkRoot)
emcc.runBlocking();
const QString versionStr = emcc.cleanedStdOut();
const QVersionNumber result = QVersionNumber::fromString(versionStr);
db->setValue(emSdkVersionTSFileKey, tsFile.toVariant());
db->setValue(emSdkVersionTSKey, ts);
db->setValue(emSdkVersionKey, result.toString());
DB::setValue(emSdkVersionTSFileKey, tsFile.toVariant());
DB::setValue(emSdkVersionTSKey, ts);
DB::setValue(emSdkVersionKey, result.toString());
return result;
}
void clearCaches()
{
Core::SettingsDatabase *db = Core::ICore::settingsDatabase();
db->remove(emSdkEnvTSFileKey);
db->remove(emSdkEnvTSKey);
db->remove(emSdkEnvOutputKey);
db->remove(emSdkVersionTSFileKey);
db->remove(emSdkVersionTSKey);
db->remove(emSdkVersionKey);
namespace DB = Core::SettingsDatabase;
DB::remove(emSdkEnvTSFileKey);
DB::remove(emSdkEnvTSKey);
DB::remove(emSdkEnvOutputKey);
DB::remove(emSdkVersionTSFileKey);
DB::remove(emSdkVersionTSKey);
DB::remove(emSdkVersionKey);
}
} // namespace WebAssembly::Internal::WebAssemblyEmSdk