diff --git a/src/imports/mvvmcore/plugins.qmltypes b/src/imports/mvvmcore/plugins.qmltypes index 5090605..a3ffee3 100644 --- a/src/imports/mvvmcore/plugins.qmltypes +++ b/src/imports/mvvmcore/plugins.qmltypes @@ -480,6 +480,10 @@ Module { Parameter { name: "settingsSetupLoader"; type: "QtMvvm::ISettingsSetupLoader"; isPointer: true } } Signal { name: "beginLoadSetup" } + Signal { + name: "valueChanged" + Parameter { name: "key"; type: "string" } + } Method { name: "callAction" Parameter { name: "key"; type: "string" } diff --git a/src/imports/mvvmquick/settingsentrymodel.cpp b/src/imports/mvvmquick/settingsentrymodel.cpp index b322ce6..5214d25 100644 --- a/src/imports/mvvmquick/settingsentrymodel.cpp +++ b/src/imports/mvvmquick/settingsentrymodel.cpp @@ -12,15 +12,21 @@ const QList SettingsEntryModel::FilterRoles { }; SettingsEntryModel::SettingsEntryModel(QObject *parent) : - QAbstractListModel(parent), - _entries() + QAbstractListModel{parent} {} void SettingsEntryModel::setup(const SettingsElements::Section §ion, SettingsViewModel *viewModel, InputViewFactory *factory) { beginResetModel(); _entries.clear(); + if(_viewModel) { + disconnect(_viewModel, &SettingsViewModel::valueChanged, + this, &SettingsEntryModel::entryChanged); + } _viewModel = viewModel; + connect(_viewModel, &SettingsViewModel::valueChanged, + this, &SettingsEntryModel::entryChanged, + Qt::QueuedConnection); //to not mess up data changes auto rIndex = 0; for(const auto &group : section.groups) { for(const auto &entry : group.entries) { @@ -122,6 +128,17 @@ Qt::ItemFlags SettingsEntryModel::flags(const QModelIndex &index) const return QAbstractListModel::flags(index) | Qt::ItemIsEditable; } +void SettingsEntryModel::entryChanged(const QString &key) +{ + for(auto i = 0; i < _entries.size(); i++) { + if(_entries[i].key == key) { + auto mIndex = index(i); + emit dataChanged(mIndex, mIndex, {SettingsValueRole}); + break; + } + } +} + SettingsEntryModel::EntryInfo::EntryInfo(SettingsElements::Entry entry, QUrl delegateUrl, SettingsElements::Group group) : diff --git a/src/imports/mvvmquick/settingsentrymodel.h b/src/imports/mvvmquick/settingsentrymodel.h index 123d63b..eaf280a 100644 --- a/src/imports/mvvmquick/settingsentrymodel.h +++ b/src/imports/mvvmquick/settingsentrymodel.h @@ -40,6 +40,9 @@ public: QHash roleNames() const override; Qt::ItemFlags flags(const QModelIndex &index) const override; +private Q_SLOTS: + void entryChanged(const QString &key); + private: struct EntryInfo : public SettingsElements::Entry { public: @@ -49,7 +52,7 @@ private: SettingsElements::Group group; }; - SettingsViewModel *_viewModel; + SettingsViewModel *_viewModel = nullptr; QList _entries; }; diff --git a/src/mvvmcore/settingsviewmodel.cpp b/src/mvvmcore/settingsviewmodel.cpp index 8bab8c0..9b713a2 100644 --- a/src/mvvmcore/settingsviewmodel.cpp +++ b/src/mvvmcore/settingsviewmodel.cpp @@ -67,11 +67,13 @@ QVariant SettingsViewModel::loadValue(const QString &key, const QVariant &defaul void SettingsViewModel::saveValue(const QString &key, const QVariant &value) { d->settings->setValue(key, value); + emit valueChanged(key); } void SettingsViewModel::resetValue(const QString &key) { d->settings->remove(key); + emit valueChanged(key); } void SettingsViewModel::callAction(const QString &key, const QVariantMap ¶meters) diff --git a/src/mvvmcore/settingsviewmodel.h b/src/mvvmcore/settingsviewmodel.h index 2ce4496..86ec9f3 100644 --- a/src/mvvmcore/settingsviewmodel.h +++ b/src/mvvmcore/settingsviewmodel.h @@ -74,6 +74,8 @@ Q_SIGNALS: //! Is emitted when the initialization has been completed and the viewmodel is ready for loading settings void beginLoadSetup(); + void valueChanged(const QString &key); //TODO add to save/reset doc + protected: void onInit(const QVariantHash ¶ms) override; diff --git a/src/mvvmquick/BoolDelegate.qml b/src/mvvmquick/BoolDelegate.qml index 9e64824..8e6012b 100644 --- a/src/mvvmquick/BoolDelegate.qml +++ b/src/mvvmquick/BoolDelegate.qml @@ -14,7 +14,7 @@ CheckDelegate { return Boolean(value); } - Component.onCompleted: checked = asBool(inputValue) + checked: asBool(inputValue) onCheckedChanged: { if(asBool(inputValue) !== checked) inputValue = checked; diff --git a/src/mvvmquick/SwitchDelegate.qml b/src/mvvmquick/SwitchDelegate.qml index c5251b0..29fc15c 100644 --- a/src/mvvmquick/SwitchDelegate.qml +++ b/src/mvvmquick/SwitchDelegate.qml @@ -14,7 +14,7 @@ Controls.SwitchDelegate { return Boolean(value); } - Component.onCompleted: checked = asBool(inputValue) + checked: asBool(inputValue) onCheckedChanged: { if(asBool(inputValue) !== checked) inputValue = checked; diff --git a/src/mvvmwidgets/settingsdialog.cpp b/src/mvvmwidgets/settingsdialog.cpp index 1072ba8..487f7c9 100644 --- a/src/mvvmwidgets/settingsdialog.cpp +++ b/src/mvvmwidgets/settingsdialog.cpp @@ -16,14 +16,17 @@ using namespace QtMvvm; SettingsDialog::SettingsDialog(ViewModel *viewModel, QWidget *parent) : - QDialog(parent), - d(new SettingsDialogPrivate(this, viewModel)) + QDialog{parent}, + d{new SettingsDialogPrivate{this, viewModel}} { d->ui->setupUi(this); connect(d->ui->buttonBox, &QDialogButtonBox::clicked, d, &SettingsDialogPrivate::buttonBoxClicked); connect(d->ui->filterLineEdit, &QLineEdit::textChanged, d, &SettingsDialogPrivate::filterTextChanged); + connect(d->viewModel, &SettingsViewModel::valueChanged, + d, &SettingsDialogPrivate::entryChanged, + Qt::QueuedConnection); // to detach updated from the bulk save operation if(parentWidget()) { setWindowModality(Qt::WindowModal); @@ -104,6 +107,15 @@ void SettingsDialogPrivate::createUi() ui->categoryListWidget->setCurrentRow(0); } +void SettingsDialogPrivate::entryChanged(const QString &key) +{ + auto content = keyMap.value(key); + if(!content) + return; + auto info = entryMap.value(content); + info.second.write(content, viewModel->loadValue(info.first.key, info.first.defaultValue)); +} + void SettingsDialogPrivate::createCategory(const SettingsElements::Category &category) { auto item = new QListWidgetItem(); @@ -195,6 +207,7 @@ void SettingsDialogPrivate::createEntry(const SettingsElements::Entry &entry, QW changedEntries.insert(content); entryMap.insert(content, {entry, property}); + keyMap.insert(entry.key, content); } catch (PresenterException &e) { logWarning() << "Failed to create settings widget for key" << entry.key diff --git a/src/mvvmwidgets/settingsdialog_p.h b/src/mvvmwidgets/settingsdialog_p.h index 101cd02..b7e7e96 100644 --- a/src/mvvmwidgets/settingsdialog_p.h +++ b/src/mvvmwidgets/settingsdialog_p.h @@ -56,6 +56,7 @@ public: using EntryInfo = QPair; QHash entryMap; + QHash keyMap; QSet changedEntries; void createCategory(const SettingsElements::Category &category); @@ -80,6 +81,7 @@ public: public Q_SLOTS: void createUi(); + void entryChanged(const QString &key); void propertyChanged(); void buttonBoxClicked(QAbstractButton *button);