Skip to content

Commit ba9ec67

Browse files
committed
Make UI more dynamic
1 parent 5f94fd7 commit ba9ec67

11 files changed

Lines changed: 502 additions & 503 deletions

src/dialogs/adapterconnectionsettings.cpp

Lines changed: 0 additions & 148 deletions
This file was deleted.

src/dialogs/adapterconnectionsettings.h

Lines changed: 0 additions & 47 deletions
This file was deleted.

src/dialogs/adaptersettings.cpp

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#include "adaptersettings.h"
2+
3+
#include "customwidgets/addabletabwidget.h"
4+
#include "customwidgets/schemaformwidget.h"
5+
#include "models/adapterdata.h"
6+
#include "models/settingsmodel.h"
7+
8+
#include <QJsonArray>
9+
#include <QVBoxLayout>
10+
11+
AdapterSettings::AdapterSettings(SettingsModel* pSettingsModel,
12+
const QString& adapterId,
13+
const QString& propertyKey,
14+
QWidget* parent)
15+
: QWidget(parent), _pSettingsModel(pSettingsModel), _adapterId(adapterId), _propertyKey(propertyKey)
16+
{
17+
auto* layout = new QVBoxLayout(this);
18+
setLayout(layout);
19+
20+
const AdapterData* pAdapter = pSettingsModel->adapterData(adapterId);
21+
const QJsonObject propSchema = pAdapter->schema().value("properties").toObject().value(propertyKey).toObject();
22+
const QJsonValue configValue = pAdapter->effectiveConfig().value(propertyKey);
23+
24+
buildSection(propSchema, configValue, layout);
25+
}
26+
27+
bool AdapterSettings::isRenderableProperty(const QJsonObject& propSchema)
28+
{
29+
const QString type = propSchema.value("type").toString();
30+
if (type == "array")
31+
{
32+
return !propSchema.value("items").toObject().isEmpty();
33+
}
34+
if (type == "object")
35+
{
36+
return !propSchema.value("properties").toObject().isEmpty();
37+
}
38+
return false;
39+
}
40+
41+
void AdapterSettings::buildSection(const QJsonObject& propSchema, const QJsonValue& configValue, QVBoxLayout* layout)
42+
{
43+
const QString type = propSchema.value("type").toString();
44+
45+
if (type == "array")
46+
{
47+
_itemSchema = propSchema.value("items").toObject();
48+
_pItemTabs = new AddableTabWidget(this);
49+
50+
const QJsonArray itemsArray = configValue.toArray();
51+
QList<QWidget*> pages;
52+
QStringList names;
53+
for (int i = 0; i < itemsArray.size(); ++i)
54+
{
55+
auto* form = new SchemaFormWidget(_pItemTabs);
56+
form->setSchema(_itemSchema, itemsArray.at(i).toObject());
57+
pages.append(form);
58+
names.append(QString("%1 %2").arg(_propertyKey[0].toUpper() + _propertyKey.mid(1)).arg(i + 1));
59+
}
60+
61+
if (!pages.isEmpty())
62+
{
63+
_pItemTabs->setTabs(pages, names);
64+
}
65+
66+
connect(_pItemTabs, &AddableTabWidget::addTabRequested, this, [this]() {
67+
auto* form = new SchemaFormWidget(_pItemTabs);
68+
QJsonObject defaultValues;
69+
const QJsonArray defaultItems =
70+
_pSettingsModel->adapterData(_adapterId)->defaults().value(_propertyKey).toArray();
71+
if (!defaultItems.isEmpty())
72+
{
73+
defaultValues = defaultItems.first().toObject();
74+
}
75+
form->setSchema(_itemSchema, defaultValues);
76+
const int newIndex = _pItemTabs->count() + 1;
77+
const QString name = QString("%1 %2").arg(_propertyKey[0].toUpper() + _propertyKey.mid(1)).arg(newIndex);
78+
_pItemTabs->addNewTab(name, form);
79+
});
80+
81+
layout->addWidget(_pItemTabs, 1);
82+
}
83+
else
84+
{
85+
_pForm = new SchemaFormWidget(this);
86+
_pForm->setSchema(propSchema, configValue.toObject());
87+
layout->addWidget(_pForm);
88+
layout->addStretch();
89+
}
90+
}
91+
92+
void AdapterSettings::acceptValues()
93+
{
94+
QJsonObject config = _pSettingsModel->adapterData(_adapterId)->effectiveConfig();
95+
96+
if (_pItemTabs)
97+
{
98+
QJsonArray itemsArray;
99+
for (int i = 0; i < _pItemTabs->count(); ++i)
100+
{
101+
auto* form = qobject_cast<SchemaFormWidget*>(_pItemTabs->tabContent(i));
102+
if (form)
103+
{
104+
itemsArray.append(form->values());
105+
}
106+
}
107+
config[_propertyKey] = itemsArray;
108+
}
109+
else if (_pForm)
110+
{
111+
config[_propertyKey] = _pForm->values();
112+
}
113+
114+
_pSettingsModel->setAdapterCurrentConfig(_adapterId, config);
115+
}

src/dialogs/adaptersettings.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#ifndef ADAPTERSETTINGS_H
2+
#define ADAPTERSETTINGS_H
3+
4+
#include <QJsonObject>
5+
#include <QString>
6+
#include <QWidget>
7+
8+
class SettingsModel;
9+
class SchemaFormWidget;
10+
class AddableTabWidget;
11+
class QVBoxLayout;
12+
13+
/*!
14+
* \brief Settings page for a single adapter schema property.
15+
*
16+
* Renders one top-level property from an adapter's JSON Schema as an editable
17+
* form. The property key (e.g. \c "connections" or \c "general") is supplied at
18+
* construction time. Schema type determines layout:
19+
* \c "type":"array" renders as a tabbed interface (one tab per item);
20+
* \c "type":"object" renders as a single form.
21+
*/
22+
class AdapterSettings : public QWidget
23+
{
24+
Q_OBJECT
25+
26+
public:
27+
explicit AdapterSettings(SettingsModel* pSettingsModel,
28+
const QString& adapterId,
29+
const QString& propertyKey,
30+
QWidget* parent = nullptr);
31+
~AdapterSettings() = default;
32+
33+
/*!
34+
* \brief Returns true if the schema property produces a non-empty page.
35+
*
36+
* \c "type":"array" requires non-empty items schema.
37+
* \c "type":"object" requires non-empty properties.
38+
* Scalar types always return false.
39+
*/
40+
static bool isRenderableProperty(const QJsonObject& propSchema);
41+
42+
/*!
43+
* \brief Write the current form values back to the adapter's configuration.
44+
*/
45+
void acceptValues();
46+
47+
private:
48+
void buildSection(const QJsonObject& propSchema, const QJsonValue& configValue, QVBoxLayout* layout);
49+
50+
SettingsModel* _pSettingsModel;
51+
QString _adapterId;
52+
QString _propertyKey;
53+
54+
AddableTabWidget* _pItemTabs{ nullptr };
55+
SchemaFormWidget* _pForm{ nullptr };
56+
57+
QJsonObject _itemSchema;
58+
};
59+
60+
#endif // ADAPTERSETTINGS_H

0 commit comments

Comments
 (0)