+#include "icon.h"
+
+namespace {
+
+QGroupBox *createDescriptionBox(const QString &description)
+{
+ auto box = new QGroupBox;
+ auto layout = new QVBoxLayout(box);
+ auto label = new QLabel(description, box);
+ label->setWordWrap(true);
+ layout->addWidget(label);
+ layout->setAlignment(label, Qt::AlignTop);
+ box->setTitle(QCoreApplication::translate("CoreConfigWizard", "Description"));
+ return box;
+}
+
+
+template<typename FieldInfo>
+QGroupBox *createFieldBox(const QString &title, const std::vector<FieldInfo> &fieldInfos)
+{
+ // Create a config UI based on the field types sent from the backend
+ // We make some assumptions here (like integer range and password field names) that may not
+ // hold true for future authenticator types - but the only way around it for now would be to
+ // provide specialized config widgets for those (which may be a good idea anyway, e.g. if we
+ // think about client-side translations...)
+
+ auto *fieldBox = new QGroupBox;
+ fieldBox->setTitle(title);
+ auto *formLayout = new QFormLayout;
+ fieldBox->setLayout(formLayout);
+
+ for (auto &&fieldInfo : fieldInfos) {
+ QWidget *widget {nullptr};
+ switch (std::get<2>(fieldInfo).type()) {
+ case QVariant::Int:
+ widget = new QSpinBox(fieldBox);
+ // Here we assume that int fields are always in 16 bit range, like ports
+ static_cast<QSpinBox *>(widget)->setMinimum(0);
+ static_cast<QSpinBox *>(widget)->setMaximum(65535);
+ static_cast<QSpinBox *>(widget)->setValue(std::get<2>(fieldInfo).toInt());
+ break;
+ case QVariant::String:
+ widget = new QLineEdit(std::get<2>(fieldInfo).toString(), fieldBox);
+ // Here we assume that fields named something with "password" are actual password inputs
+ if (std::get<0>(fieldInfo).toLower().contains("password"))
+ static_cast<QLineEdit *>(widget)->setEchoMode(QLineEdit::Password);
+ break;
+ default:
+ qWarning() << "Unsupported type for backend property" << std::get<0>(fieldInfo);
+ }
+ if (widget) {
+ widget->setObjectName(std::get<0>(fieldInfo));
+ formLayout->addRow(std::get<1>(fieldInfo) + ":", widget);
+ }
+ }
+ return fieldBox;
+}
+
+
+template<typename FieldInfo>
+QVariantMap propertiesFromFieldWidgets(QGroupBox *fieldBox, const std::vector<FieldInfo> &fieldInfos)
+{
+ QVariantMap properties;
+ if (!fieldBox)
+ return properties;
+
+ for (auto &&fieldInfo : fieldInfos) {
+ QString key = std::get<0>(fieldInfo);
+ QVariant value;
+ switch (std::get<2>(fieldInfo).type()) {
+ case QVariant::Int: {
+ QSpinBox *spinBox = fieldBox->findChild<QSpinBox *>(key);
+ if (spinBox)
+ value = spinBox->value();
+ else
+ qWarning() << "Could not find child widget for field" << key;
+ break;
+ }
+ case QVariant::String: {
+ QLineEdit *lineEdit = fieldBox->findChild<QLineEdit *>(key);
+ if (lineEdit)
+ value = lineEdit->text();
+ else
+ qWarning() << "Could not find child widget for field" << key;
+ break;
+ }
+ default:
+ qWarning() << "Unsupported type for backend property" << key;
+ }
+ properties[key] = std::move(value);
+ }
+ return properties;
+}