22#include " view-utils.hpp"
33#include < QJsonArray>
44#include < QJsonObject>
5+ #include < QJSValue>
6+ #include < qcontainerfwd.h>
7+ #include < qstringliteral.h>
58#include < utility>
69
710ExtensionFormModel::ExtensionFormModel (NotifyFn notify, QObject *parent)
@@ -54,7 +57,14 @@ void ExtensionFormModel::setFieldValue(int index, const QVariant &value) {
5457 auto &item = m_items[index];
5558 if (!item.isField ()) return ;
5659
57- item.userValue = QJsonValue::fromVariant (value);
60+ // TODO: find out why Form.TagPicker tags would break without that
61+ QVariant normalizedValue = value;
62+
63+ if (value.metaType ().id () == qMetaTypeId<QJSValue>()) {
64+ normalizedValue = value.value <QJSValue>().toVariant ();
65+ }
66+
67+ item.userValue = QJsonValue::fromVariant (normalizedValue);
5868 item.hasUserValue = true ;
5969 emit dataChanged (createIndex (index, 0 ), createIndex (index, 0 ), {ValueRole});
6070
@@ -90,6 +100,23 @@ void ExtensionFormModel::setFilePaths(int index, const QVariantList &paths) {
90100 if (item.onChange ) { m_notify (*item.onChange , QJsonArray{arr}); }
91101}
92102
103+ void ExtensionFormModel::setPickedItems (int index, const QVariantList &pickedItems) {
104+ if (index < 0 || std::cmp_greater_equal (index, m_items.size ())) return ;
105+ auto &item = m_items[index];
106+ if (item.type != FormItemData::Type::TagPicker) return ;
107+
108+ QJsonArray arr;
109+ for (const auto &t : pickedItems) {
110+ arr.append (t.toString ());
111+ }
112+
113+ item.userValue = arr;
114+ item.hasUserValue = true ;
115+ emit dataChanged (createIndex (index, 0 ), createIndex (index, 0 ), {ValueRole});
116+
117+ if (item.onChange ) { m_notify (*item.onChange , QJsonArray{arr}); }
118+ }
119+
93120void ExtensionFormModel::dropdownSearchTextChanged (int index, const QString &text) {
94121 if (index < 0 || std::cmp_greater_equal (index, m_items.size ())) return ;
95122 const auto &item = m_items[index];
@@ -187,10 +214,16 @@ ExtensionFormModel::FormItemData ExtensionFormModel::createItem(const FormModel:
187214 data.onFocus = field->onFocus ;
188215 data.fieldData = buildFieldData (*field);
189216
190- if (field->value ) {
217+ if (field->value && !(data. type == FormItemData::Type::TagPicker && field-> value -> isNull ()) ) {
191218 data.modelValue = *field->value ;
192219 } else if (field->defaultValue ) {
193220 data.modelValue = *field->defaultValue ;
221+ } else if (data.type == FormItemData::Type::Dropdown) {
222+ if (auto *df = dynamic_cast <const FormModel::DropdownField *>(field.get ())) {
223+ if (auto first = qml::firstDropdownItemValue (df->m_items )) { data.modelValue = *first; }
224+ }
225+ } else if (data.type == FormItemData::Type::TagPicker) {
226+ data.modelValue = QJsonArray{};
194227 }
195228 } else if (auto *desc = std::get_if<FormModel::Description>(&item)) {
196229 data.type = FormItemData::Type::Description;
@@ -216,8 +249,11 @@ void ExtensionFormModel::updateItem(FormItemData &existing, const FormModel::Ite
216249 existing.fieldData = buildFieldData (*field);
217250
218251 if (field->value ) {
219- existing.modelValue = *field->value ;
220- existing.hasUserValue = false ;
252+ bool const isNullTagValue = existing.type == FormItemData::Type::TagPicker && field->value ->isNull ();
253+ if (!isNullTagValue) {
254+ existing.modelValue = *field->value ;
255+ existing.hasUserValue = false ;
256+ }
221257 }
222258 } else if (auto *desc = std::get_if<FormModel::Description>(&newItem)) {
223259 existing.label = desc->title .value_or (QString ());
@@ -233,6 +269,7 @@ ExtensionFormModel::FormItemData::Type ExtensionFormModel::fieldType(const FormM
233269 if (dynamic_cast <const FormModel::TextAreaField *>(&field)) return FormItemData::Type::TextArea;
234270 if (dynamic_cast <const FormModel::FilePickerField *>(&field)) return FormItemData::Type::FilePicker;
235271 if (dynamic_cast <const FormModel::DatePickerField *>(&field)) return FormItemData::Type::DatePicker;
272+ if (dynamic_cast <const FormModel::TagPickerField *>(&field)) return FormItemData::Type::TagPicker;
236273 return FormItemData::Type::Text;
237274}
238275
@@ -257,6 +294,8 @@ QVariantMap ExtensionFormModel::buildFieldData(const FormModel::IField &field) {
257294 if (f->min ) data[" min" ] = *f->min ;
258295 if (f->max ) data[" max" ] = *f->max ;
259296 data[" includeTime" ] = f->type .value_or (" date" ) == " dateTime" ;
297+ } else if (auto *f = dynamic_cast <const FormModel::TagPickerField *>(&field)) {
298+ data[" items" ] = qml::convertTagPickerItems (f->m_items );
260299 }
261300
262301 return data;
@@ -282,6 +321,8 @@ QString ExtensionFormModel::FormItemData::typeString() const {
282321 return QStringLiteral (" description" );
283322 case Type::Separator:
284323 return QStringLiteral (" separator" );
324+ case Type::TagPicker:
325+ return QStringLiteral (" tagpicker" );
285326 }
286327 return QStringLiteral (" text" );
287328}
0 commit comments