1 /***************************************************************************
2 * Copyright (C) 2005-2013 by the Quassel Project *
3 * devel@quassel-irc.org *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) version 3. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
22 #include <QAbstractButton>
23 #include <QFormLayout>
26 #include "coreconfigwizard.h"
27 #include "coreconnection.h"
28 #include "iconloader.h"
30 CoreConfigWizard::CoreConfigWizard(CoreConnection *connection, const QList<QVariant> &backends, QWidget *parent)
32 _connection(connection)
35 setAttribute(Qt::WA_DeleteOnClose);
37 foreach(const QVariant &v, backends)
38 _backends[v.toMap()["DisplayName"].toString()] = v;
40 setPage(IntroPage, new CoreConfigWizardPages::IntroPage(this));
41 setPage(AdminUserPage, new CoreConfigWizardPages::AdminUserPage(this));
42 setPage(StorageSelectionPage, new CoreConfigWizardPages::StorageSelectionPage(_backends, this));
43 syncPage = new CoreConfigWizardPages::SyncPage(this);
44 connect(syncPage, SIGNAL(setupCore(const QString &, const QVariantMap &)), SLOT(prepareCoreSetup(const QString &, const QVariantMap &)));
45 setPage(SyncPage, syncPage);
46 syncRelayPage = new CoreConfigWizardPages::SyncRelayPage(this);
47 connect(syncRelayPage, SIGNAL(startOver()), this, SLOT(startOver()));
48 setPage(SyncRelayPage, syncRelayPage);
49 //setPage(Page_StorageDetails, new StorageDetailsPage());
50 //setPage(Page_Conclusion, new ConclusionPage(storageProviders));
52 setStartId(IntroPage);
53 //setStartId(StorageSelectionPage);
56 setWizardStyle(ModernStyle);
59 setOption(HaveHelpButton, false);
60 setOption(NoBackButtonOnStartPage, true);
61 setOption(HaveNextButtonOnLastPage, false);
62 setOption(HaveFinishButtonOnEarlyPages, false);
63 setOption(NoCancelButton, true);
64 setOption(IndependentPages, true);
65 //setOption(ExtendedWatermarkPixmap, true);
69 setWindowTitle(tr("Core Configuration Wizard"));
70 setPixmap(QWizard::LogoPixmap, DesktopIcon("quassel"));
72 connect(connection, SIGNAL(coreSetupSuccess()), SLOT(coreSetupSuccess()));
73 connect(connection, SIGNAL(coreSetupFailed(QString)), SLOT(coreSetupFailed(QString)));
74 //connect(connection, SIGNAL(loginSuccess()), SLOT(loginSuccess()));
75 connect(connection, SIGNAL(synchronized()), SLOT(syncFinished()));
76 connect(this, SIGNAL(rejected()), connection, SLOT(disconnectFromCore()));
80 QHash<QString, QVariant> CoreConfigWizard::backends() const
86 void CoreConfigWizard::prepareCoreSetup(const QString &backend, const QVariantMap &properties)
88 // Prevent the user from changing any settings he already specified...
89 foreach(int idx, visitedPages())
90 page(idx)->setEnabled(false);
93 foo["AdminUser"] = field("adminUser.user").toString();
94 foo["AdminPasswd"] = field("adminUser.password").toString();
95 foo["Backend"] = backend;
96 foo["ConnectionProperties"] = properties;
97 coreConnection()->doCoreSetup(foo);
101 void CoreConfigWizard::coreSetupSuccess()
103 syncPage->setStatus(tr("Your core has been successfully configured. Logging you in..."));
104 syncPage->setError(false);
105 syncRelayPage->setMode(CoreConfigWizardPages::SyncRelayPage::Error);
106 coreConnection()->loginToCore(field("adminUser.user").toString(), field("adminUser.password").toString(), field("adminUser.rememberPasswd").toBool());
110 void CoreConfigWizard::coreSetupFailed(const QString &error)
112 syncPage->setStatus(tr("Core configuration failed:<br><b>%1</b><br>Press <em>Next</em> to start over.").arg(error));
113 syncPage->setError(true);
114 syncRelayPage->setMode(CoreConfigWizardPages::SyncRelayPage::Error);
115 //foreach(int idx, visitedPages()) page(idx)->setEnabled(true);
116 //setStartId(SyncPage);
121 void CoreConfigWizard::startOver()
123 foreach(int idx, visitedPages()) page(idx)->setEnabled(true);
124 setStartId(CoreConfigWizard::AdminUserPage);
129 void CoreConfigWizard::loginSuccess()
131 syncPage->setStatus(tr("Your are now logged into your freshly configured Quassel Core!<br>"
132 "Please remember to configure your identities and networks now."));
133 syncPage->setComplete(true);
134 syncPage->setFinalPage(true);
138 void CoreConfigWizard::syncFinished()
144 namespace CoreConfigWizardPages {
147 IntroPage::IntroPage(QWidget *parent) : QWizardPage(parent)
150 setTitle(tr("Introduction"));
151 //setSubTitle(tr("foobar"));
152 //setPixmap(QWizard::WatermarkPixmap, QPixmap(":icons/quassel-icon.png"));
156 int IntroPage::nextId() const
158 return CoreConfigWizard::AdminUserPage;
162 /*** Admin User Page ***/
164 AdminUserPage::AdminUserPage(QWidget *parent) : QWizardPage(parent)
167 setTitle(tr("Create Admin User"));
168 setSubTitle(tr("First, we will create a user on the core. This first user will have administrator privileges."));
170 registerField("adminUser.user*", ui.user);
171 registerField("adminUser.password*", ui.password);
172 registerField("adminUser.password2*", ui.password2);
173 registerField("adminUser.rememberPasswd", ui.rememberPasswd);
175 //ui.user->setText("foo");
176 //ui.password->setText("foo");
177 //ui.password2->setText("foo");
181 int AdminUserPage::nextId() const
183 return CoreConfigWizard::StorageSelectionPage;
187 bool AdminUserPage::isComplete() const
189 bool ok = !ui.user->text().isEmpty() && !ui.password->text().isEmpty() && ui.password->text() == ui.password2->text();
194 /*** Storage Selection Page ***/
196 StorageSelectionPage::StorageSelectionPage(const QHash<QString, QVariant> &backends, QWidget *parent)
197 : QWizardPage(parent),
203 setTitle(tr("Select Storage Backend"));
204 setSubTitle(tr("Please select a database backend for the Quassel Core storage to store the backlog and other data in."));
207 registerField("storage.backend", ui.backendList);
209 foreach(QString key, _backends.keys()) {
210 ui.backendList->addItem(_backends[key].toMap()["DisplayName"].toString(), key);
213 on_backendList_currentIndexChanged();
217 int StorageSelectionPage::nextId() const
219 return CoreConfigWizard::SyncPage;
223 QString StorageSelectionPage::selectedBackend() const
225 return ui.backendList->currentText();
229 QVariantMap StorageSelectionPage::connectionProperties() const
231 QString backend = ui.backendList->itemData(ui.backendList->currentIndex()).toString();
233 QVariantMap properties;
234 QStringList setupKeys = _backends[backend].toMap()["SetupKeys"].toStringList();
235 if (!setupKeys.isEmpty()) {
236 QVariantMap defaults = _backends[backend].toMap()["SetupDefaults"].toMap();
237 foreach(QString key, setupKeys) {
238 QWidget *widget = _connectionBox->findChild<QWidget *>(key);
240 if (defaults.contains(key)) {
243 switch (def.type()) {
246 QSpinBox *spinbox = qobject_cast<QSpinBox *>(widget);
248 def = QVariant(spinbox->value());
253 QLineEdit *lineEdit = qobject_cast<QLineEdit *>(widget);
255 def = QVariant(lineEdit->text());
258 properties[key] = def;
261 qDebug() << properties;
263 // QVariantMap properties = _backends[backend].toMap()["ConnectionProperties"].toMap();
264 // if(!properties.isEmpty() && _connectionBox) {
265 // QVariantMap::iterator propertyIter = properties.begin();
266 // while(propertyIter != properties.constEnd()) {
267 // QWidget *widget = _connectionBox->findChild<QWidget *>(propertyIter.key());
268 // switch(propertyIter.value().type()) {
269 // case QVariant::Int:
271 // QSpinBox *spinbox = qobject_cast<QSpinBox *>(widget);
272 // Q_ASSERT(spinbox);
273 // propertyIter.value() = QVariant(spinbox->value());
278 // QLineEdit *lineEdit = qobject_cast<QLineEdit *>(widget);
279 // Q_ASSERT(lineEdit);
280 // propertyIter.value() = QVariant(lineEdit->text());
290 void StorageSelectionPage::on_backendList_currentIndexChanged()
292 QString backend = ui.backendList->itemData(ui.backendList->currentIndex()).toString();
293 ui.description->setText(_backends[backend].toMap()["Description"].toString());
295 if (_connectionBox) {
296 layout()->removeWidget(_connectionBox);
297 _connectionBox->deleteLater();
301 QStringList setupKeys = _backends[backend].toMap()["SetupKeys"].toStringList();
302 if (!setupKeys.isEmpty()) {
303 QVariantMap defaults = _backends[backend].toMap()["SetupDefaults"].toMap();
304 QGroupBox *propertyBox = new QGroupBox(this);
305 propertyBox->setTitle(tr("Connection Properties"));
306 QFormLayout *formlayout = new QFormLayout;
308 foreach(QString key, setupKeys) {
311 if (defaults.contains(key)) {
314 switch (def.type()) {
317 QSpinBox *spinbox = new QSpinBox(propertyBox);
318 spinbox->setMaximum(64000);
319 spinbox->setValue(def.toInt());
325 QLineEdit *lineEdit = new QLineEdit(def.toString(), propertyBox);
326 if (key.toLower().contains("password")) {
327 lineEdit->setEchoMode(QLineEdit::Password);
332 widget->setObjectName(key);
333 formlayout->addRow(key + ":", widget);
335 propertyBox->setLayout(formlayout);
336 static_cast<QVBoxLayout *>(layout())->insertWidget(layout()->indexOf(ui.descriptionBox) + 1, propertyBox);
337 _connectionBox = propertyBox;
344 SyncPage::SyncPage(QWidget *parent) : QWizardPage(parent)
347 setTitle(tr("Storing Your Settings"));
348 setSubTitle(tr("Your settings are now stored in the core, and you will be logged in automatically."));
352 void SyncPage::initializePage()
357 StorageSelectionPage *storagePage = qobject_cast<StorageSelectionPage *>(wizard()->page(CoreConfigWizard::StorageSelectionPage));
358 QString backend = storagePage->selectedBackend();
359 QVariantMap properties = storagePage->connectionProperties();
360 Q_ASSERT(!backend.isEmpty());
361 ui.user->setText(wizard()->field("adminUser.user").toString());
362 ui.backend->setText(backend);
363 emit setupCore(backend, properties);
367 int SyncPage::nextId() const
369 if (!hasError) return -1;
370 return CoreConfigWizard::SyncRelayPage;
374 bool SyncPage::isComplete() const
380 void SyncPage::setStatus(const QString &status)
382 ui.status->setText(status);
386 void SyncPage::setError(bool e)
392 void SyncPage::setComplete(bool c)
399 /*** Sync Relay Page ***/
401 SyncRelayPage::SyncRelayPage(QWidget *parent) : QWizardPage(parent)
407 void SyncRelayPage::setMode(Mode m)
414 void SyncRelayPage::initializePage() {
416 if(mode == Success) {
424 int SyncRelayPage::nextId() const
429 }; /* namespace CoreConfigWizardPages */