/***************************************************************************
- * Copyright (C) 2005-09 by the Quassel Project *
+ * Copyright (C) 2005-2016 by the Quassel Project *
* devel@quassel-irc.org *
* *
* This program is free software; you can redistribute it and/or modify *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include <QDebug>
#include <QAbstractButton>
+#include <QCoreApplication>
#include <QFormLayout>
+#include <QIcon>
#include <QSpinBox>
#include "coreconfigwizard.h"
-#include "iconloader.h"
-
-CoreConfigWizard::CoreConfigWizard(const QList<QVariant> &backends, QWidget *parent) : QWizard(parent) {
- foreach(QVariant v, backends) _backends[v.toMap()["DisplayName"].toString()] = v;
- setPage(IntroPage, new CoreConfigWizardPages::IntroPage(this));
- setPage(AdminUserPage, new CoreConfigWizardPages::AdminUserPage(this));
- setPage(StorageSelectionPage, new CoreConfigWizardPages::StorageSelectionPage(_backends, this));
- syncPage = new CoreConfigWizardPages::SyncPage(this);
- connect(syncPage, SIGNAL(setupCore(const QString &, const QVariantMap &)), this, SLOT(prepareCoreSetup(const QString &, const QVariantMap &)));
- setPage(SyncPage, syncPage);
- syncRelayPage = new CoreConfigWizardPages::SyncRelayPage(this);
- connect(syncRelayPage, SIGNAL(startOver()), this, SLOT(startOver()));
- setPage(SyncRelayPage, syncRelayPage);
- //setPage(Page_StorageDetails, new StorageDetailsPage());
- //setPage(Page_Conclusion, new ConclusionPage(storageProviders));
-
- setStartId(IntroPage);
- //setStartId(StorageSelectionPage);
-
-#ifndef Q_WS_MAC
- setWizardStyle(ModernStyle);
+#include "coreconnection.h"
+
+#include "client.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...)
+
+ QGroupBox *fieldBox = new QGroupBox;
+ fieldBox->setTitle(title);
+
+ QFormLayout *formLayout = new QFormLayout(fieldBox);
+ 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;
+}
+
+} // anon
+
+
+CoreConfigWizard::CoreConfigWizard(CoreConnection *connection, const QVariantList &backendInfos, const QVariantList &authInfos, QWidget *parent)
+ : QWizard(parent),
+ _connection{connection}
+{
+ setModal(true);
+ setAttribute(Qt::WA_DeleteOnClose);
+
+ setPage(IntroPage, new CoreConfigWizardPages::IntroPage(this));
+ setPage(AdminUserPage, new CoreConfigWizardPages::AdminUserPage(this));
+ setPage(AuthenticationSelectionPage, new CoreConfigWizardPages::AuthenticationSelectionPage(authInfos, this));
+ setPage(StorageSelectionPage, new CoreConfigWizardPages::StorageSelectionPage(backendInfos, this));
+ syncPage = new CoreConfigWizardPages::SyncPage(this);
+ connect(syncPage, SIGNAL(setupCore(const QString &, const QVariantMap &, const QString &, const QVariantMap &)),
+ SLOT(prepareCoreSetup(const QString &, const QVariantMap &, const QString &, const QVariantMap &)));
+ setPage(SyncPage, syncPage);
+ syncRelayPage = new CoreConfigWizardPages::SyncRelayPage(this);
+ connect(syncRelayPage, SIGNAL(startOver()), this, SLOT(startOver()));
+ setPage(SyncRelayPage, syncRelayPage);
+
+ setStartId(IntroPage);
+
+#ifndef Q_OS_MAC
+ setWizardStyle(ModernStyle);
#endif
- setOption(HaveHelpButton, false);
- setOption(NoBackButtonOnStartPage, true);
- setOption(HaveNextButtonOnLastPage, false);
- setOption(HaveFinishButtonOnEarlyPages, false);
- setOption(NoCancelButton, true);
- setOption(IndependentPages, true);
- //setOption(ExtendedWatermarkPixmap, true);
+ setOption(HaveHelpButton, false);
+ setOption(NoBackButtonOnStartPage, true);
+ setOption(HaveNextButtonOnLastPage, false);
+ setOption(HaveFinishButtonOnEarlyPages, false);
+ setOption(NoCancelButton, true);
+ setOption(IndependentPages, true);
+
+ setModal(true);
- setModal(true);
+ setWindowTitle(tr("Core Configuration Wizard"));
+ setPixmap(QWizard::LogoPixmap, QIcon::fromTheme("quassel", QIcon(":/icons/quassel.png")).pixmap(48));
- setWindowTitle(tr("Core Configuration Wizard"));
- setPixmap(QWizard::LogoPixmap, DesktopIcon("quassel"));
+ connect(connection, SIGNAL(coreSetupSuccess()), SLOT(coreSetupSuccess()));
+ connect(connection, SIGNAL(coreSetupFailed(QString)), SLOT(coreSetupFailed(QString)));
+ connect(connection, SIGNAL(synchronized()), SLOT(syncFinished()));
+ connect(this, SIGNAL(rejected()), connection, SLOT(disconnectFromCore()));
+
+
+ // Resize all pages to the size hint of the largest one, so the wizard is large enough
+ QSize maxSize;
+ for (int id : pageIds()) {
+ auto p = page(id);
+ p->adjustSize();
+ maxSize = maxSize.expandedTo(p->sizeHint());
+ }
+ for (int id : pageIds()) {
+ page(id)->setFixedSize(maxSize);
+ }
}
-QHash<QString, QVariant> CoreConfigWizard::backends() const {
- return _backends;
+
+void CoreConfigWizard::prepareCoreSetup(const QString &backend, const QVariantMap &properties, const QString &authenticator, const QVariantMap &authProperties)
+{
+ // Prevent the user from changing any settings he already specified...
+ for (auto &&idx : visitedPages())
+ page(idx)->setEnabled(false);
+
+ // FIXME? We need to be able to set up older cores that don't have auth backend support.
+ // So if the core doesn't support that feature, don't pass those parameters.
+ if (!(Client::coreFeatures() & Quassel::Authenticators)) {
+ coreConnection()->setupCore(Protocol::SetupData(field("adminUser.user").toString(), field("adminUser.password").toString(), backend, properties));
+ }
+ else {
+ coreConnection()->setupCore(Protocol::SetupData(field("adminUser.user").toString(), field("adminUser.password").toString(), backend, properties, authenticator, authProperties));
+ }
}
-void CoreConfigWizard::prepareCoreSetup(const QString &backend, const QVariantMap &properties) {
- // Prevent the user from changing any settings he already specified...
- foreach(int idx, visitedPages())
- page(idx)->setEnabled(false);
- QVariantMap foo;
- foo["AdminUser"] = field("adminUser.user").toString();
- foo["AdminPasswd"] = field("adminUser.password").toString();
- foo["Backend"] = backend;
- foo["ConnectionProperties"] = properties;
- emit setupCore(foo);
+void CoreConfigWizard::coreSetupSuccess()
+{
+ syncPage->setStatus(tr("Your core has been successfully configured. Logging you in..."));
+ syncPage->setError(false);
+ syncRelayPage->setMode(CoreConfigWizardPages::SyncRelayPage::Success);
+ coreConnection()->loginToCore(field("adminUser.user").toString(), field("adminUser.password").toString(), field("adminUser.rememberPasswd").toBool());
}
-void CoreConfigWizard::coreSetupSuccess() {
- syncPage->setStatus(tr("Your core has been successfully configured. Logging you in..."));
- syncPage->setError(false);
- syncRelayPage->setMode(CoreConfigWizardPages::SyncRelayPage::Error);
- QVariantMap loginData;
- loginData["User"] = field("adminUser.user");
- loginData["Password"] = field("adminUser.password");
- loginData["RememberPasswd"] = field("adminUser.rememberPasswd");
- emit loginToCore(loginData);
+
+void CoreConfigWizard::coreSetupFailed(const QString &error)
+{
+ syncPage->setStatus(tr("Core configuration failed:<br><b>%1</b><br>Press <em>Next</em> to start over.").arg(error));
+ syncPage->setError(true);
+ syncRelayPage->setMode(CoreConfigWizardPages::SyncRelayPage::Error);
+ //foreach(int idx, visitedPages()) page(idx)->setEnabled(true);
+ //setStartId(SyncPage);
+ //restart();
}
-void CoreConfigWizard::coreSetupFailed(const QString &error) {
- syncPage->setStatus(tr("Core configuration failed:<br><b>%1</b><br>Press <em>Next</em> to start over.").arg(error));
- syncPage->setError(true);
- syncRelayPage->setMode(CoreConfigWizardPages::SyncRelayPage::Error);
- //foreach(int idx, visitedPages()) page(idx)->setEnabled(true);
- //setStartId(SyncPage);
- //restart();
+
+void CoreConfigWizard::startOver()
+{
+ foreach(int idx, visitedPages()) page(idx)->setEnabled(true);
+ setStartId(CoreConfigWizard::AdminUserPage);
+ restart();
}
-void CoreConfigWizard::startOver() {
- foreach(int idx, visitedPages()) page(idx)->setEnabled(true);
- setStartId(CoreConfigWizard::AdminUserPage);
- restart();
+
+void CoreConfigWizard::syncFinished()
+{
+ accept();
}
-void CoreConfigWizard::loginSuccess() {
- syncPage->setStatus(tr("Your are now logged into your freshly configured Quassel Core!<br>"
- "Please remember to configure your identities and networks now."));
- syncPage->setComplete(true);
- syncPage->setFinalPage(true);
+
+namespace CoreConfigWizardPages {
+/*** Intro Page ***/
+
+IntroPage::IntroPage(QWidget *parent) : QWizardPage(parent)
+{
+ ui.setupUi(this);
+ setTitle(tr("Introduction"));
+ //setSubTitle(tr("foobar"));
+ //setPixmap(QWizard::WatermarkPixmap, QPixmap(":icons/quassel-icon.png"));
}
-void CoreConfigWizard::syncFinished() {
- // TODO: display identities and networks settings if appropriate!
- // accept();
+
+int IntroPage::nextId() const
+{
+ return CoreConfigWizard::AdminUserPage;
}
-namespace CoreConfigWizardPages {
-/*** Intro Page ***/
+/*** Admin User Page ***/
+
+AdminUserPage::AdminUserPage(QWidget *parent) : QWizardPage(parent)
+{
+ ui.setupUi(this);
+ setTitle(tr("Create Admin User"));
+ setSubTitle(tr("First, we will create a user on the core. This first user will have administrator privileges."));
+
+ registerField("adminUser.user*", ui.user);
+ registerField("adminUser.password*", ui.password);
+ registerField("adminUser.password2*", ui.password2);
+ registerField("adminUser.rememberPasswd", ui.rememberPasswd);
+}
-IntroPage::IntroPage(QWidget *parent) : QWizardPage(parent) {
- ui.setupUi(this);
- setTitle(tr("Introduction"));
- //setSubTitle(tr("foobar"));
- //setPixmap(QWizard::WatermarkPixmap, QPixmap(":icons/quassel-icon.png"));
+int AdminUserPage::nextId() const
+{
+ // If the core doesn't support auth backends, skip that page!
+ if (!(Client::coreFeatures() & Quassel::Authenticators)) {
+ return CoreConfigWizard::StorageSelectionPage;
+ }
+ else {
+ return CoreConfigWizard::AuthenticationSelectionPage;
+ }
}
-int IntroPage::nextId() const {
- return CoreConfigWizard::AdminUserPage;
+bool AdminUserPage::isComplete() const
+{
+ bool ok = !ui.user->text().isEmpty() && !ui.password->text().isEmpty() && ui.password->text() == ui.password2->text();
+ return ok;
}
-/*** Admin User Page ***/
+/*** Authentication Selection Page ***/
+
+AuthenticationSelectionPage::AuthenticationSelectionPage(const QVariantList &authInfos, QWidget *parent)
+ : QWizardPage(parent)
+{
+ ui.setupUi(this);
+
+ setTitle(tr("Select Authentication Backend"));
+ setSubTitle(tr("Please select a backend for Quassel Core to use for authenticating users."));
+
+ registerField("authentication.backend", ui.backendList);
+
+ for (auto &&authInfo : authInfos) {
+ auto props = authInfo.toMap();
+ // Extract field infos to avoid having to reparse the list
+ std::vector<FieldInfo> fields;
+ const auto &list = props["SetupData"].toList();
+ for (int i = 0; i + 2 < list.size(); i += 3) {
+ fields.emplace_back(std::make_tuple(list[i].toString(), list[i+1].toString(), list[i+2]));
+ }
+ props.remove("SetupData");
+
+ _authProperties.emplace_back(std::move(props));
+ _authFields.emplace_back(std::move(fields));
+
+ // Create widgets
+ ui.backendList->addItem(_authProperties.back()["DisplayName"].toString(), _authProperties.back()["BackendId"].toString());
+ ui.descriptionStack->addWidget(createDescriptionBox(_authProperties.back()["Description"].toString()));
+ ui.authSettingsStack->addWidget(createFieldBox(tr("Authentication Settings"), _authFields.back()));
+ }
+
+ // Do some trickery to make the page large enough
+ setSizePolicy({QSizePolicy::Fixed, QSizePolicy::Fixed});
-AdminUserPage::AdminUserPage(QWidget *parent) : QWizardPage(parent) {
- ui.setupUi(this);
- setTitle(tr("Create Admin User"));
- setSubTitle(tr("First, we will create a user on the core. This first user will have administrator privileges."));
+ QSizePolicy sp{QSizePolicy::MinimumExpanding, QSizePolicy::Fixed};
+#if QT_VERSION >= 0x050200
+ sp.setRetainSizeWhenHidden(true);
+#else
+ ui.authSettingsStack->setVisible(true); // ugly hack that will show an empty box, but we'll deprecate Qt4 soon anyway
+#endif
+ ui.descriptionStack->setSizePolicy(sp);
+ ui.authSettingsStack->setSizePolicy(sp);
- registerField("adminUser.user*", ui.user);
- registerField("adminUser.password*", ui.password);
- registerField("adminUser.password2*", ui.password2);
- registerField("adminUser.rememberPasswd", ui.rememberPasswd);
+ ui.descriptionStack->adjustSize();
+ ui.authSettingsStack->adjustSize();
- //ui.user->setText("foo");
- //ui.password->setText("foo");
- //ui.password2->setText("foo");
+ ui.backendList->setCurrentIndex(0);
}
-int AdminUserPage::nextId() const {
- return CoreConfigWizard::StorageSelectionPage;
+int AuthenticationSelectionPage::nextId() const
+{
+ return CoreConfigWizard::StorageSelectionPage;
}
-bool AdminUserPage::isComplete() const {
- bool ok = !ui.user->text().isEmpty() && !ui.password->text().isEmpty() && ui.password->text() == ui.password2->text();
- return ok;
+
+QString AuthenticationSelectionPage::displayName() const
+{
+ return ui.backendList->currentText();
+}
+
+
+QString AuthenticationSelectionPage::authenticator() const
+{
+#if QT_VERSION >= 0x050200
+ return ui.backendList->currentData().toString();
+#else
+ return ui.backendList->itemData(ui.backendList->currentIndex()).toString();
+#endif
+}
+
+
+QVariantMap AuthenticationSelectionPage::authProperties() const
+{
+ return propertiesFromFieldWidgets(qobject_cast<QGroupBox *>(ui.authSettingsStack->currentWidget()),
+ _authFields[ui.backendList->currentIndex()]);
+}
+
+
+void AuthenticationSelectionPage::on_backendList_currentIndexChanged(int index)
+{
+ ui.descriptionStack->setCurrentIndex(index);
+ ui.authSettingsStack->setCurrentIndex(index);
+ ui.authSettingsStack->setVisible(!_authFields[index].empty());
}
/*** Storage Selection Page ***/
-StorageSelectionPage::StorageSelectionPage(const QHash<QString, QVariant> &backends, QWidget *parent) : QWizardPage(parent) {
- ui.setupUi(this);
- _backends = backends;
-
- setTitle(tr("Select Storage Backend"));
- setSubTitle(tr("Please select a database backend for the Quassel Core storage to store the backlog and other data in."));
- setCommitPage(true);
-
- registerField("storage.backend", ui.backendList);
-
- foreach(QString key, _backends.keys()) {
- ui.backendList->addItem(_backends[key].toMap()["DisplayName"].toString(), key);
- }
-
- on_backendList_currentIndexChanged();
-}
-
-int StorageSelectionPage::nextId() const {
- return CoreConfigWizard::SyncPage;
-}
-
-QString StorageSelectionPage::selectedBackend() const {
- return ui.backendList->currentText();
-}
-
-QVariantMap StorageSelectionPage::connectionProperties() const {
- QString backend = ui.backendList->itemData(ui.backendList->currentIndex()).toString();
- QVariantMap properties = _backends[backend].toMap()["ConnectionProperties"].toMap();
- if(!properties.isEmpty() && _connectionBox) {
- QVariantMap::iterator propertyIter = properties.begin();
- while(propertyIter != properties.constEnd()) {
- QWidget *widget = _connectionBox->findChild<QWidget *>(propertyIter.key());
- switch(propertyIter.value().type()) {
- case QVariant::Int:
- {
- QSpinBox *spinbox = qobject_cast<QSpinBox *>(widget);
- Q_ASSERT(spinbox);
- propertyIter.value() = QVariant(spinbox->value());
- }
- break;
- default:
- {
- QLineEdit *lineEdit = qobject_cast<QLineEdit *>(widget);
- Q_ASSERT(lineEdit);
- propertyIter.value() = QVariant(lineEdit->text());
- }
- }
- propertyIter++;
- }
- }
- return properties;
-}
-
-void StorageSelectionPage::on_backendList_currentIndexChanged() {
- QString backend = ui.backendList->itemData(ui.backendList->currentIndex()).toString();
- ui.description->setText(_backends[backend].toMap()["Description"].toString());
-
- if(_connectionBox) {
- layout()->removeWidget(_connectionBox);
- _connectionBox->deleteLater();
- _connectionBox = 0;
- }
-
- QVariantMap properties = _backends[backend].toMap()["ConnectionProperties"].toMap();
- if(!properties.isEmpty()) {
- QGroupBox *propertyBox = new QGroupBox(this);
- propertyBox->setTitle(tr("Connection Properties"));
- QFormLayout *formlayout = new QFormLayout;
-
- QVariantMap::const_iterator propertyIter = properties.constBegin();
- while(propertyIter != properties.constEnd()) {
- QWidget *widget = 0;
- switch(propertyIter.value().type()) {
- case QVariant::Int:
- {
- QSpinBox *spinbox = new QSpinBox(propertyBox);
- spinbox->setMaximum(64000);
- spinbox->setValue(propertyIter.value().toInt());
- widget = spinbox;
- }
- break;
- default:
- widget = new QLineEdit(propertyIter.value().toString(), propertyBox);
- }
- widget->setObjectName(propertyIter.key());
- formlayout->addRow(propertyIter.key() + ":", widget);
- propertyIter++;
+StorageSelectionPage::StorageSelectionPage(const QVariantList &backendInfos, QWidget *parent)
+ : QWizardPage(parent)
+{
+ ui.setupUi(this);
+
+ setTitle(tr("Select Storage Backend"));
+ setSubTitle(tr("Please select a storage backend for Quassel Core."));
+ setCommitPage(true);
+
+ registerField("storage.backend", ui.backendList);
+
+ int defaultIndex {0}; // Legacy cores send backend infos in arbitrary order
+
+ for (auto &&backendInfo : backendInfos) {
+ auto props = backendInfo.toMap();
+ // Extract field infos to avoid having to reparse the list
+ std::vector<FieldInfo> fields;
+
+ // Legacy cores (prior to 0.13) didn't send SetupData for storage backends; deal with this
+ if (!props.contains("SetupData")) {
+ const auto &defaultValues = props["SetupDefaults"].toMap();
+ for (auto &&key : props["SetupKeys"].toStringList()) {
+ fields.emplace_back(std::make_tuple(key, key, defaultValues.value(key, QString{})));
+ }
+ if (props.value("IsDefault", false).toBool()) {
+ defaultIndex = ui.backendList->count();
+ }
+ }
+ else {
+ const auto &list = props["SetupData"].toList();
+ for (int i = 0; i + 2 < list.size(); i += 3) {
+ fields.emplace_back(std::make_tuple(list[i].toString(), list[i+1].toString(), list[i+2]));
+ }
+ props.remove("SetupData");
+ }
+ props.remove("SetupKeys");
+ props.remove("SetupDefaults");
+ // Legacy cores (prior to 0.13) don't send the BackendId property
+ if (!props.contains("BackendId"))
+ props["BackendId"] = props["DisplayName"];
+ _backendProperties.emplace_back(std::move(props));
+ _backendFields.emplace_back(std::move(fields));
+
+ // Create widgets
+ ui.backendList->addItem(_backendProperties.back()["DisplayName"].toString(), _backendProperties.back()["BackendId"].toString());
+ ui.descriptionStack->addWidget(createDescriptionBox(_backendProperties.back()["Description"].toString()));
+ ui.storageSettingsStack->addWidget(createFieldBox(tr("Storage Settings"), _backendFields.back()));
}
- propertyBox->setLayout(formlayout);
- static_cast<QVBoxLayout *>(layout())->insertWidget(layout()->indexOf(ui.descriptionBox) + 1, propertyBox);
- _connectionBox = propertyBox;
- }
+
+ // Do some trickery to make the page large enough
+ setSizePolicy({QSizePolicy::Fixed, QSizePolicy::Fixed});
+
+ QSizePolicy sp{QSizePolicy::MinimumExpanding, QSizePolicy::Fixed};
+#if QT_VERSION >= 0x050200
+ sp.setRetainSizeWhenHidden(true);
+#else
+ ui.storageSettingsStack->setVisible(true); // ugly hack that will show an empty box, but we'll deprecate Qt4 soon anyway
+#endif
+ ui.descriptionStack->setSizePolicy(sp);
+ ui.storageSettingsStack->setSizePolicy(sp);
+
+ ui.descriptionStack->adjustSize();
+ ui.storageSettingsStack->adjustSize();
+
+ ui.backendList->setCurrentIndex(defaultIndex);
}
-/*** Sync Page ***/
-SyncPage::SyncPage(QWidget *parent) : QWizardPage(parent) {
- ui.setupUi(this);
- setTitle(tr("Storing Your Settings"));
- setSubTitle(tr("Your settings are now stored in the core, and you will be logged in automatically."));
+int StorageSelectionPage::nextId() const
+{
+ return CoreConfigWizard::SyncPage;
}
-void SyncPage::initializePage() {
- complete = false;
- hasError = false;
- StorageSelectionPage *storagePage = qobject_cast<StorageSelectionPage *>(wizard()->page(CoreConfigWizard::StorageSelectionPage));
- QString backend = storagePage->selectedBackend();
- QVariantMap properties = storagePage->connectionProperties();
- Q_ASSERT(!backend.isEmpty());
- ui.user->setText(wizard()->field("adminUser.user").toString());
- ui.backend->setText(backend);
- emit setupCore(backend, properties);
+QString StorageSelectionPage::displayName() const
+{
+ return ui.backendList->currentText();
}
-int SyncPage::nextId() const {
- if(!hasError) return -1;
- return CoreConfigWizard::SyncRelayPage;
+
+QString StorageSelectionPage::backend() const
+{
+#if QT_VERSION >= 0x050200
+ return ui.backendList->currentData().toString();
+#else
+ return ui.backendList->itemData(ui.backendList->currentIndex()).toString();
+#endif
}
-bool SyncPage::isComplete() const {
- return complete;
+
+QVariantMap StorageSelectionPage::backendProperties() const
+{
+ return propertiesFromFieldWidgets(qobject_cast<QGroupBox *>(ui.storageSettingsStack->currentWidget()),
+ _backendFields[ui.backendList->currentIndex()]);
}
-void SyncPage::setStatus(const QString &status) {
- ui.status->setText(status);
+
+void StorageSelectionPage::on_backendList_currentIndexChanged(int index)
+{
+ ui.descriptionStack->setCurrentIndex(index);
+ ui.storageSettingsStack->setCurrentIndex(index);
+ ui.storageSettingsStack->setVisible(!_backendFields[index].empty());
}
-void SyncPage::setError(bool e) {
- hasError = e;
+
+/*** Sync Page ***/
+
+SyncPage::SyncPage(QWidget *parent) : QWizardPage(parent)
+{
+ ui.setupUi(this);
+ setTitle(tr("Storing Your Settings"));
+ setSubTitle(tr("Your settings are now being stored in the core, and you will be logged in automatically."));
+}
+
+
+void SyncPage::initializePage()
+{
+ _complete = false;
+ _hasError = false;
+ emit completeChanged();
+
+ // Fill in sync info about the storage layer.
+ StorageSelectionPage *storagePage = qobject_cast<StorageSelectionPage *>(wizard()->page(CoreConfigWizard::StorageSelectionPage));
+ QString backend = storagePage->backend();
+ QVariantMap backendProperties = storagePage->backendProperties();
+ ui.backend->setText(storagePage->displayName());
+
+ // Fill in sync info about the authentication layer.
+ AuthenticationSelectionPage *authPage = qobject_cast<AuthenticationSelectionPage *>(wizard()->page(CoreConfigWizard::AuthenticationSelectionPage));
+ QString authenticator = authPage->authenticator();
+ QVariantMap authProperties = authPage->authProperties();
+ ui.authenticator->setText(authPage->displayName());
+
+ ui.user->setText(wizard()->field("adminUser.user").toString());
+
+ emit setupCore(backend, backendProperties, authenticator, authProperties);
}
-void SyncPage::setComplete(bool c) {
- complete = c;
- completeChanged();
+
+int SyncPage::nextId() const
+{
+ if (!_hasError)
+ return -1;
+ return CoreConfigWizard::SyncRelayPage;
}
-/*** Sync Relay Page ***/
-SyncRelayPage::SyncRelayPage(QWidget *parent) : QWizardPage(parent) {
- mode = Success;
+bool SyncPage::isComplete() const
+{
+ return _complete || _hasError;
}
-void SyncRelayPage::setMode(Mode m) {
- mode = m;
+
+void SyncPage::setStatus(const QString &status)
+{
+ ui.status->setText(status);
}
-/*
-void SyncRelayPage::initializePage() {
- return;
- if(mode == Success) {
- wizard()->accept();
- } else {
- emit startOver();
- }
+
+void SyncPage::setError(bool e)
+{
+ _hasError = e;
+ setFinalPage(!e);
+ emit completeChanged();
+}
+
+
+void SyncPage::setComplete(bool c)
+{
+ _complete = c;
+ completeChanged();
+}
+
+
+/*** Sync Relay Page ***/
+
+SyncRelayPage::SyncRelayPage(QWidget *parent) : QWizardPage(parent)
+{
+ mode = Success;
}
-*/
-int SyncRelayPage::nextId() const {
- emit startOver();
- return 0;
+
+void SyncRelayPage::setMode(Mode m)
+{
+ mode = m;
}
+int SyncRelayPage::nextId() const
+{
+ emit startOver();
+ return 0;
+}
}; /* namespace CoreConfigWizardPages */