Browse Source

use ISettingsAccessor for the settings viewmodels

pull/2/head
Skycoder42 7 years ago
parent
commit
a19a4452fa
No known key found for this signature in database GPG Key ID: 8E01AD9EF0578D2B
  1. 11
      src/imports/mvvmcore/plugins.qmltypes
  2. 1
      src/imports/mvvmdatasynccore/qtmvvmdatasynccore_plugin.cpp
  3. 13
      src/mvvmcore/qsettingsaccessor.cpp
  4. 2
      src/mvvmcore/qsettingsaccessor.h
  5. 57
      src/mvvmcore/settingsviewmodel.cpp
  6. 9
      src/mvvmcore/settingsviewmodel.h
  7. 2
      src/mvvmcore/settingsviewmodel_p.h
  8. 74
      src/mvvmdatasynccore/datasyncsettingsviewmodel.cpp
  9. 15
      src/mvvmdatasynccore/datasyncsettingsviewmodel.h
  10. 21
      src/mvvmdatasynccore/datasyncsettingsviewmodel_p.h
  11. 1
      src/mvvmdatasynccore/mvvmdatasynccore.pro
  12. 2
      src/mvvmwidgets/inputwidgetfactory.cpp
  13. 34
      src/mvvmwidgets/widgetspresenter.cpp
  14. 2
      src/mvvmwidgets/widgetspresenter_p.h
  15. 2
      tools/settingsgenerator/main.cpp

11
src/imports/mvvmcore/plugins.qmltypes

@ -760,10 +760,16 @@ Module {
exports: ["de.skycoder42.QtMvvm.Core/SettingsViewModel 1.0"]
isCreatable: false
exportMetaObjectRevisions: [0]
Property { name: "accessor"; revision: 1; type: "QtMvvm::ISettingsAccessor"; isPointer: true }
Property { name: "canRestoreDefaults"; type: "bool"; isReadonly: true }
Property { name: "restoreConfig"; type: "QtMvvm::MessageConfig"; isReadonly: true }
Property { name: "settingsSetupLoader"; type: "QtMvvm::ISettingsSetupLoader"; isPointer: true }
Property { name: "__qtmvvm_inject_settingsSetupLoader"; type: "QByteArray"; isReadonly: true }
Signal {
name: "accessorChanged"
revision: 1
Parameter { name: "accessor"; type: "QtMvvm::ISettingsAccessor"; isPointer: true }
}
Signal {
name: "settingsSetupLoaderChanged"
Parameter { name: "settingsSetupLoader"; type: "QtMvvm::ISettingsSetupLoader"; isPointer: true }
@ -780,6 +786,11 @@ Module {
Parameter { name: "key"; type: "string" }
Parameter { name: "parameters"; type: "QVariantMap" }
}
Method {
name: "setAccessor"
revision: 1
Parameter { name: "accessor"; type: "QtMvvm::ISettingsAccessor"; isPointer: true }
}
Method {
name: "setSettingsSetupLoader"
Parameter { name: "settingsSetupLoader"; type: "QtMvvm::ISettingsSetupLoader"; isPointer: true }

1
src/imports/mvvmdatasynccore/qtmvvmdatasynccore_plugin.cpp

@ -7,6 +7,7 @@
#include <QtMvvmDataSyncCore/DataSyncViewModel>
#include <QtMvvmDataSyncCore/NetworkExchangeViewModel>
#include <QtMvvmDataSyncCore/DataSyncSettingsViewModel>
#include <QtMvvmDataSyncCore/DataSyncSettingsEntry>
#include <QtMvvmDataSyncCore/private/identityeditviewmodel_p.h>
#include <QtMvvmDataSyncCore/private/changeremoteviewmodel_p.h>

13
src/mvvmcore/qsettingsaccessor.cpp

@ -15,14 +15,14 @@ public:
QSettingsAccessor::QSettingsAccessor(QObject *parent) :
QSettingsAccessor{new QSettings{}, parent}
{}
{
d->settings->setParent(this);
}
QSettingsAccessor::QSettingsAccessor(QSettings *settings, QObject *parent) :
ISettingsAccessor{parent},
d{new QSettingsAccessorPrivate{settings}}
{
d->settings->setParent(this);
}
{}
QSettingsAccessor::~QSettingsAccessor() = default;
@ -53,6 +53,11 @@ void QSettingsAccessor::remove(const QString &key)
emit entryRemoved(key);
}
QSettings *QSettingsAccessor::settings() const
{
return d->settings;
}
void QSettingsAccessor::sync()
{
d->settings->sync();

2
src/mvvmcore/qsettingsaccessor.h

@ -25,6 +25,8 @@ public:
void save(const QString &key, const QVariant &value) override;
void remove(const QString &key) override;
QSettings *settings() const;
public Q_SLOTS:
void sync() override;

57
src/mvvmcore/settingsviewmodel.cpp

@ -3,9 +3,11 @@
#include "coreapp.h"
#include "qtmvvm_logging_p.h"
#include "settingssetuploader_p.h"
#include "qsettingsaccessor.h"
using namespace QtMvvm;
const QString SettingsViewModel::paramAccessor(QStringLiteral("accessor"));
const QString SettingsViewModel::paramSettings(QStringLiteral("settings"));
const QString SettingsViewModel::paramSetupFile(QStringLiteral("setupFile"));
@ -14,6 +16,11 @@ SettingsViewModel::SettingsViewModel(QObject *parent) :
d(new SettingsViewModelPrivate())
{}
ISettingsAccessor *SettingsViewModel::accessor() const
{
return d->accessor;
}
SettingsViewModel::~SettingsViewModel() = default;
QVariantHash SettingsViewModel::showParams(QSettings *settings, const QString &setupFile)
@ -56,24 +63,23 @@ SettingsElements::Setup SettingsViewModel::loadSetup(const QString &frontend) co
QSettings *SettingsViewModel::settings() const
{
return d->settings;
auto qAccessor = qobject_cast<QSettingsAccessor*>(d->accessor);
return qAccessor ? qAccessor->settings() : nullptr;
}
QVariant SettingsViewModel::loadValue(const QString &key, const QVariant &defaultValue) const
{
return d->settings->value(key, defaultValue);
return d->accessor->load(key, defaultValue);
}
void SettingsViewModel::saveValue(const QString &key, const QVariant &value)
{
d->settings->setValue(key, value);
emit valueChanged(key);
d->accessor->save(key, value);
}
void SettingsViewModel::resetValue(const QString &key)
{
d->settings->remove(key);
emit valueChanged(key);
d->accessor->remove(key);
}
void SettingsViewModel::resetAll(const SettingsElements::Setup &setup)
@ -105,6 +111,32 @@ void SettingsViewModel::callAction(const QString &key, const QVariantMap &parame
<< "and parameters" << parameters;
}
void QtMvvm::SettingsViewModel::setAccessor(ISettingsAccessor *accessor)
{
if(accessor == d->accessor)
return;
if(d->accessor) {
disconnect(d->accessor, &ISettingsAccessor::entryChanged,
this, &SettingsViewModel::valueChanged);
disconnect(d->accessor, &ISettingsAccessor::entryRemoved,
this, &SettingsViewModel::valueChanged);
}
if(d->accessor->parent() == this)
d->accessor->deleteLater();
d->accessor = accessor;
if(d->accessor) {
connect(d->accessor, &ISettingsAccessor::entryChanged,
this, &SettingsViewModel::valueChanged);
connect(d->accessor, &ISettingsAccessor::entryRemoved,
this, &SettingsViewModel::valueChanged);
}
emit accessorChanged(d->accessor);
}
void SettingsViewModel::setSettingsSetupLoader(ISettingsSetupLoader *settingsSetupLoader)
{
if (d->setupLoader == settingsSetupLoader)
@ -118,9 +150,16 @@ void SettingsViewModel::onInit(const QVariantHash &params)
{
Q_ASSERT_X(d->setupLoader, Q_FUNC_INFO, "settingsSetupLoader must not be null");
d->settings = params.value(paramSettings).value<QSettings*>();
if(!d->settings)
d->settings = new QSettings(this);
auto accessor = params.value(paramAccessor).value<ISettingsAccessor*>();
if(!accessor) {
auto settings = params.value(paramSettings).value<QSettings*>();
if(settings)
accessor = new QSettingsAccessor{settings, this};
else
accessor = new QSettingsAccessor{this};
}
setAccessor(accessor);
d->setupFile = params.value(paramSetupFile).toString();
if(d->setupFile.isEmpty())
d->setupFile = QStringLiteral(":/etc/settings.xml");

9
src/mvvmcore/settingsviewmodel.h

@ -9,6 +9,7 @@
#include "QtMvvmCore/qtmvvmcore_global.h"
#include "QtMvvmCore/settingssetup.h"
#include "QtMvvmCore/isettingsaccessor.h"
namespace QtMvvm {
@ -18,6 +19,8 @@ class Q_MVVMCORE_EXPORT SettingsViewModel : public ViewModel
{
Q_OBJECT
Q_PROPERTY(QtMvvm::ISettingsAccessor* accessor READ accessor WRITE setAccessor NOTIFY accessorChanged REVISION 1)
//! Specifies if restoring the defaults is generally allowed
Q_PROPERTY(bool canRestoreDefaults READ canRestoreDefaults CONSTANT)
//! The message configuration to be used to for a dialog to ask for settings restore
@ -28,6 +31,7 @@ class Q_MVVMCORE_EXPORT SettingsViewModel : public ViewModel
QTMVVM_INJECT(QtMvvm::ISettingsSetupLoader*, settingsSetupLoader)
public:
static const QString paramAccessor;
//! The parameter for a QSettings object for the onInit() method
static const QString paramSettings;
//! The parameter for a settings setup file for the onInit() method
@ -40,6 +44,7 @@ public:
Q_INVOKABLE explicit SettingsViewModel(QObject *parent = nullptr);
~SettingsViewModel() override;
QtMvvm::ISettingsAccessor* accessor() const;
//! @readAcFn{SettingsViewModel::canRestoreDefaults}
virtual bool canRestoreDefaults() const;
//! @readAcFn{SettingsViewModel::restoreConfig}
@ -50,7 +55,7 @@ public:
//! Loads the settings setup of the prepared file for the given frontend
SettingsElements::Setup loadSetup(const QString &frontend) const;
//! Returns the settings this viewmodel operates on
//! Returns the settings this viewmodel operates on (or null if not using QtMvvm::QSettingsAccessor)
QSettings *settings() const;
//! Loads the value for the given key from the settings
@ -65,10 +70,12 @@ public Q_SLOTS:
//! Is called when an action type edit is pressed
virtual void callAction(const QString &key, const QVariantMap &parameters);
Q_REVISION(1) void setAccessor(QtMvvm::ISettingsAccessor* accessor);
//! @writeAcFn{SettingsViewModel::settingsSetupLoader}
void setSettingsSetupLoader(QtMvvm::ISettingsSetupLoader* settingsSetupLoader);
Q_SIGNALS:
Q_REVISION(1) void accessorChanged(QtMvvm::ISettingsAccessor* accessor);
//! @notifyAcFn{SettingsViewModel::settingsSetupLoader}
void settingsSetupLoaderChanged(QtMvvm::ISettingsSetupLoader* settingsSetupLoader, QPrivateSignal);

2
src/mvvmcore/settingsviewmodel_p.h

@ -10,8 +10,8 @@ class SettingsViewModelPrivate
{
public:
ISettingsSetupLoader *setupLoader = nullptr;
ISettingsAccessor *accessor = nullptr;
QSettings *settings = nullptr;
QString setupFile;
SettingsElements::Setup currentSetup;

74
src/mvvmdatasynccore/datasyncsettingsviewmodel.cpp

@ -1,5 +1,5 @@
#include "datasyncsettingsviewmodel.h"
#include "datasyncsettingsviewmodel_p.h"
#include "datasyncsettingsaccessor.h"
#undef logDebug
#undef logInfo
@ -9,52 +9,46 @@
using namespace QtMvvm;
DataSyncSettingsViewModel::DataSyncSettingsViewModel(QObject *parent) :
SettingsViewModel{parent},
d(new DataSyncSettingsViewModelPrivate{this})
{
connect(d->store, &QtDataSync::DataTypeStoreBase::dataChanged,
this, &DataSyncSettingsViewModel::valueChanged);
}
const QString DataSyncSettingsViewModel::paramSetup(QStringLiteral("setup"));
const QString DataSyncSettingsViewModel::paramDataStore(QStringLiteral("dataStore"));
const QString DataSyncSettingsViewModel::paramDataTypeStore(QStringLiteral("dataTypeStore"));
DataSyncSettingsViewModel::~DataSyncSettingsViewModel() = default;
DataSyncSettingsViewModel::DataSyncSettingsViewModel(QObject *parent) :
SettingsViewModel{parent}
{}
QVariant DataSyncSettingsViewModel::loadValue(const QString &key, const QVariant &defaultValue) const
void DataSyncSettingsViewModel::onInit(const QVariantHash &params)
{
if(!params.contains(paramAccessor)) {
auto subParams = params;
try {
return d->store->load(key).value();
} catch (QtDataSync::NoDataException &e) {
Q_UNUSED(e)
return defaultValue;
} catch (QException &e) {
logCritical() << "Failed to load entry" << key << "from datasync settings with error:"
<< e.what();
return defaultValue;
DataSyncSettingsAccessor *accessor = nullptr;
auto setup = params.value(paramSetup).toString();
if(!setup.isNull())
accessor = new DataSyncSettingsAccessor{setup ,this};
if(!accessor) {
auto store = params.value(paramDataStore).value<QtDataSync::DataStore*>();
if(store)
accessor = new DataSyncSettingsAccessor{store ,this};
}
}
void DataSyncSettingsViewModel::saveValue(const QString &key, const QVariant &value)
{
try {
d->store->save({key, value});
} catch (QException &e) {
logCritical() << "Failed to save entry" << key << "to datasync settings with error:"
<< e.what();
if(!accessor) {
auto store = params.value(paramDataStore).value<QtDataSync::DataTypeStoreBase*>();
auto tStore = dynamic_cast<QtDataSync::DataTypeStore<DataSyncSettingsEntry>*>(store);
if(tStore)
accessor = new DataSyncSettingsAccessor{tStore ,this};
}
}
void DataSyncSettingsViewModel::resetValue(const QString &key)
{
try {
d->store->remove(key);
} catch (QException &e) {
logCritical() << "Failed to remove entry" << key << "from datasync settings with error:"
<< e.what();
if(!accessor)
accessor = new DataSyncSettingsAccessor{this};
subParams.insert(paramAccessor, QVariant::fromValue(accessor));
} catch(QtDataSync::Exception &e) {
logCritical() << "Failed to create DataSyncSettingsAccessor with error:" << e.what();
// will be initialize with the default as fallback
}
SettingsViewModel::onInit(subParams);
} else
SettingsViewModel::onInit(params);
}
// ------------- Private Implementation -------------
DataSyncSettingsViewModelPrivate::DataSyncSettingsViewModelPrivate(DataSyncSettingsViewModel *q_ptr) :
store{new QtDataSync::DataTypeStore<DataSyncSettingsEntry>{q_ptr}}
{}

15
src/mvvmdatasynccore/datasyncsettingsviewmodel.h

@ -7,25 +7,22 @@
#include <QtMvvmCore/settingsviewmodel.h>
#include "QtMvvmDataSyncCore/qtmvvmdatasynccore_global.h"
#include "QtMvvmDataSyncCore/datasyncsettingsentry.h"
namespace QtMvvm {
class DataSyncSettingsViewModelPrivate;
class Q_MVVMDATASYNCCORE_EXPORT DataSyncSettingsViewModel : public QtMvvm::SettingsViewModel
{
Q_OBJECT
public:
Q_INVOKABLE explicit DataSyncSettingsViewModel(QObject *parent = nullptr);
~DataSyncSettingsViewModel() override;
static const QString paramSetup;
static const QString paramDataStore;
static const QString paramDataTypeStore;
QVariant loadValue(const QString &key, const QVariant &defaultValue) const override;
void saveValue(const QString &key, const QVariant &value) override;
void resetValue(const QString &key) override;
Q_INVOKABLE explicit DataSyncSettingsViewModel(QObject *parent = nullptr);
private:
QScopedPointer<DataSyncSettingsViewModelPrivate> d;
protected:
void onInit(const QVariantHash &params) override;
};
}

21
src/mvvmdatasynccore/datasyncsettingsviewmodel_p.h

@ -1,21 +0,0 @@
#ifndef QTMVVM_DATASYNCSETTINGSVIEWMODEL_P_H
#define QTMVVM_DATASYNCSETTINGSVIEWMODEL_P_H
#include "qtmvvmdatasynccore_global.h"
#include "datasyncsettingsviewmodel.h"
#include <QtDataSync/DataTypeStore>
namespace QtMvvm {
class DataSyncSettingsViewModelPrivate
{
public:
DataSyncSettingsViewModelPrivate(DataSyncSettingsViewModel *q_ptr);
QtDataSync::DataTypeStore<DataSyncSettingsEntry> *store;
};
}
#endif // QTMVVM_DATASYNCSETTINGSVIEWMODEL_P_H

1
src/mvvmdatasynccore/mvvmdatasynccore.pro

@ -16,7 +16,6 @@ HEADERS += \
exchangedevicesmodel.h \
exchangedevicesmodel_p.h \
datasyncsettingsviewmodel.h \
datasyncsettingsviewmodel_p.h \
datasyncsettingsaccessor.h \
datasyncsettingsentry.h \
datasyncsettingsaccessor_p.h

2
src/mvvmwidgets/inputwidgetfactory.cpp

@ -36,7 +36,7 @@ QWidget *InputWidgetFactory::createInput(const QByteArray &type, QWidget *parent
return createInput(d->aliases.value(type), parent, viewProperties);
if(d->simpleWidgets.contains(type))
widget = d->simpleWidgets.value(type)(parent);
else if(type == QMetaType::typeName(QMetaType::Bool) || type == "switch") //TODO add extra widget
else if(type == QMetaType::typeName(QMetaType::Bool) || type == "switch")
widget = new QCheckBox(parent);
else if(type == QMetaType::typeName(QMetaType::QString) || type == "string") {
auto edit = new QLineEdit(parent);

34
src/mvvmwidgets/widgetspresenter.cpp

@ -284,8 +284,7 @@ void WidgetsPresenter::presentMessageBox(const MessageConfig &config, QPointer<M
//special properties
QSharedPointer<bool> checked;
auto props = config.viewProperties();
if(!props.value(QStringLiteral("modal"), false).toBool())
info.parent = QApplication::activeWindow();
info.parent = WidgetsPresenterPrivate::parent(props);
if(props.contains(QStringLiteral("windowTitle")))
info.windowTitle = props.value(QStringLiteral("windowTitle")).toString();
if(props.contains(QStringLiteral("details")))
@ -320,10 +319,7 @@ void WidgetsPresenter::presentMessageBox(const MessageConfig &config, QPointer<M
void WidgetsPresenter::presentInputDialog(const MessageConfig &config, QPointer<MessageResult> result)
{
auto input = d->inputViewFactory->createInput(config.subType(), nullptr, config.viewProperties());
QWidget *parent = nullptr;
if(!config.viewProperties().value(QStringLiteral("modal"), false).toBool())
parent = QApplication::activeWindow();
auto dialog = new QDialog(parent);
auto dialog = new QDialog{WidgetsPresenterPrivate::parent(config.viewProperties())};
dialog->setAttribute(Qt::WA_DeleteOnClose);
result->setCloseTarget(dialog, QStringLiteral("reject()"));
auto layout = new QVBoxLayout(dialog);
@ -379,11 +375,7 @@ void WidgetsPresenter::presentInputDialog(const MessageConfig &config, QPointer<
void WidgetsPresenter::presentFileDialog(const MessageConfig &config, QPointer<MessageResult> result)
{
auto props = config.viewProperties();
QWidget *parent = nullptr;
if(!props.value(QStringLiteral("modal"), false).toBool())
parent = QApplication::activeWindow();
auto dialog = new QFileDialog(parent);
auto dialog = new QFileDialog{WidgetsPresenterPrivate::parent(props)};
dialog->setAttribute(Qt::WA_DeleteOnClose);
result->setCloseTarget(dialog, QStringLiteral("reject()"));
@ -440,11 +432,7 @@ void WidgetsPresenter::presentFileDialog(const MessageConfig &config, QPointer<M
void WidgetsPresenter::presentColorDialog(const MessageConfig &config, const QPointer<MessageResult> &result)
{
auto props = config.viewProperties();
QWidget *parent = nullptr;
if(!props.value(QStringLiteral("modal"), false).toBool())
parent = QApplication::activeWindow();
auto dialog = new QColorDialog{parent};
auto dialog = new QColorDialog{WidgetsPresenterPrivate::parent(props)};
dialog->setAttribute(Qt::WA_DeleteOnClose);
result->setCloseTarget(dialog, QStringLiteral("reject()"));
@ -492,11 +480,7 @@ void WidgetsPresenter::presentProgressDialog(const MessageConfig &config, const
return;
}
auto props = config.viewProperties();
QWidget *parent = nullptr; //TODO move to seperate method
if(!props.value(QStringLiteral("modal"), false).toBool())
parent = QApplication::activeWindow();
auto dialog = new ProgressDialog{config, result, control, parent};
auto dialog = new ProgressDialog{config, result, control, WidgetsPresenterPrivate::parent(props)};
dialog->setAttribute(Qt::WA_DeleteOnClose);
result->setCloseTarget(dialog, QStringLiteral("reject()"));
dialog->open();
@ -529,6 +513,14 @@ WidgetsPresenter *WidgetsPresenterPrivate::currentPresenter()
}
}
QWidget *WidgetsPresenterPrivate::parent(const QVariantMap &properties)
{
if(!properties.value(QStringLiteral("modal"), false).toBool())
return QApplication::activeWindow();
else
return nullptr;
}
QValidator *QtMvvm::createUrlValidator(QStringList schemes, QObject *parent)
{
return new QUrlValidator(std::move(schemes), parent);

2
src/mvvmwidgets/widgetspresenter_p.h

@ -20,6 +20,8 @@ public:
InputWidgetFactory* inputViewFactory = nullptr;
QSet<const QMetaObject*> implicitMappings;
QHash<const QMetaObject*, const QMetaObject*> explicitMappings;
static QWidget *parent(const QVariantMap &properties);
};
Q_MVVMWIDGETS_EXPORT QValidator *createUrlValidator(QStringList schemes, QObject* parent = nullptr);

2
tools/settingsgenerator/main.cpp

@ -17,7 +17,7 @@ int main(int argc, char *argv[])
QCoreApplication::setOrganizationDomain(QStringLiteral(BUNDLE_PREFIX));
QCommandLineParser parser;
parser.setApplicationDescription(QStringLiteral("A tool to...")); //TODO description
parser.setApplicationDescription(QStringLiteral("A tool to create C++ and QML bindings for generic settings access"));
parser.addVersionOption();
parser.addHelpOption();

Loading…
Cancel
Save