Quassel IRC  Pre-Release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
coreconfigwizard.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2015 by the Quassel Project *
3  * devel@quassel-irc.org *
4  * *
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. *
9  * *
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. *
14  * *
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  ***************************************************************************/
20 
21 #include <QDebug>
22 #include <QAbstractButton>
23 #include <QFormLayout>
24 #include <QIcon>
25 #include <QSpinBox>
26 
27 #include "coreconfigwizard.h"
28 #include "coreconnection.h"
29 
30 CoreConfigWizard::CoreConfigWizard(CoreConnection *connection, const QList<QVariant> &backends, QWidget *parent)
31  : QWizard(parent),
32  _connection(connection)
33 {
34  setModal(true);
35  setAttribute(Qt::WA_DeleteOnClose);
36 
37  foreach(const QVariant &v, backends)
38  _backends[v.toMap()["DisplayName"].toString()] = v;
39 
40  setPage(IntroPage, new CoreConfigWizardPages::IntroPage(this));
44  connect(syncPage, SIGNAL(setupCore(const QString &, const QVariantMap &)), SLOT(prepareCoreSetup(const QString &, const QVariantMap &)));
45  setPage(SyncPage, syncPage);
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));
51 
52  setStartId(IntroPage);
53  //setStartId(StorageSelectionPage);
54 
55 #ifndef Q_OS_MAC
56  setWizardStyle(ModernStyle);
57 #endif
58 
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);
66 
67  setModal(true);
68 
69  setWindowTitle(tr("Core Configuration Wizard"));
70  setPixmap(QWizard::LogoPixmap, QIcon::fromTheme("quassel", QIcon(":/icons/quassel.png")).pixmap(48));
71 
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()));
77 }
78 
79 
80 QHash<QString, QVariant> CoreConfigWizard::backends() const
81 {
82  return _backends;
83 }
84 
85 
86 void CoreConfigWizard::prepareCoreSetup(const QString &backend, const QVariantMap &properties)
87 {
88  // Prevent the user from changing any settings he already specified...
89  foreach(int idx, visitedPages())
90  page(idx)->setEnabled(false);
91 
92  coreConnection()->setupCore(Protocol::SetupData(field("adminUser.user").toString(), field("adminUser.password").toString(), backend, properties));
93 }
94 
95 
97 {
98  syncPage->setStatus(tr("Your core has been successfully configured. Logging you in..."));
99  syncPage->setError(false);
101  coreConnection()->loginToCore(field("adminUser.user").toString(), field("adminUser.password").toString(), field("adminUser.rememberPasswd").toBool());
102 }
103 
104 
105 void CoreConfigWizard::coreSetupFailed(const QString &error)
106 {
107  syncPage->setStatus(tr("Core configuration failed:<br><b>%1</b><br>Press <em>Next</em> to start over.").arg(error));
108  syncPage->setError(true);
110  //foreach(int idx, visitedPages()) page(idx)->setEnabled(true);
111  //setStartId(SyncPage);
112  //restart();
113 }
114 
115 
117 {
118  foreach(int idx, visitedPages()) page(idx)->setEnabled(true);
120  restart();
121 }
122 
123 
125 {
126  syncPage->setStatus(tr("Your are now logged into your freshly configured Quassel Core!<br>"
127  "Please remember to configure your identities and networks now."));
128  syncPage->setComplete(true);
129  syncPage->setFinalPage(true);
130 }
131 
132 
134 {
135  accept();
136 }
137 
138 
139 namespace CoreConfigWizardPages {
140 /*** Intro Page ***/
141 
142 IntroPage::IntroPage(QWidget *parent) : QWizardPage(parent)
143 {
144  ui.setupUi(this);
145  setTitle(tr("Introduction"));
146  //setSubTitle(tr("foobar"));
147  //setPixmap(QWizard::WatermarkPixmap, QPixmap(":icons/quassel-icon.png"));
148 }
149 
150 
151 int IntroPage::nextId() const
152 {
154 }
155 
156 
157 /*** Admin User Page ***/
158 
159 AdminUserPage::AdminUserPage(QWidget *parent) : QWizardPage(parent)
160 {
161  ui.setupUi(this);
162  setTitle(tr("Create Admin User"));
163  setSubTitle(tr("First, we will create a user on the core. This first user will have administrator privileges."));
164 
165  registerField("adminUser.user*", ui.user);
166  registerField("adminUser.password*", ui.password);
167  registerField("adminUser.password2*", ui.password2);
168  registerField("adminUser.rememberPasswd", ui.rememberPasswd);
169 
170  //ui.user->setText("foo");
171  //ui.password->setText("foo");
172  //ui.password2->setText("foo");
173 }
174 
175 
177 {
179 }
180 
181 
183 {
184  bool ok = !ui.user->text().isEmpty() && !ui.password->text().isEmpty() && ui.password->text() == ui.password2->text();
185  return ok;
186 }
187 
188 
189 /*** Storage Selection Page ***/
190 
191 StorageSelectionPage::StorageSelectionPage(const QHash<QString, QVariant> &backends, QWidget *parent)
192  : QWizardPage(parent),
193  _connectionBox(0),
194  _backends(backends)
195 {
196  ui.setupUi(this);
197 
198  setTitle(tr("Select Storage Backend"));
199  setSubTitle(tr("Please select a database backend for the Quassel Core storage to store the backlog and other data in."));
200  setCommitPage(true);
201 
202  registerField("storage.backend", ui.backendList);
203 
204  foreach(QString key, _backends.keys()) {
205  ui.backendList->addItem(_backends[key].toMap()["DisplayName"].toString(), key);
206  }
207 
209 }
210 
211 
213 {
215 }
216 
217 
219 {
220  return ui.backendList->currentText();
221 }
222 
223 
225 {
226  QString backend = ui.backendList->itemData(ui.backendList->currentIndex()).toString();
227 
228  QVariantMap properties;
229  QStringList setupKeys = _backends[backend].toMap()["SetupKeys"].toStringList();
230  if (!setupKeys.isEmpty()) {
231  QVariantMap defaults = _backends[backend].toMap()["SetupDefaults"].toMap();
232  foreach(QString key, setupKeys) {
233  QWidget *widget = _connectionBox->findChild<QWidget *>(key);
234  QVariant def;
235  if (defaults.contains(key)) {
236  def = defaults[key];
237  }
238  switch (def.type()) {
239  case QVariant::Int:
240  {
241  QSpinBox *spinbox = qobject_cast<QSpinBox *>(widget);
242  Q_ASSERT(spinbox);
243  def = QVariant(spinbox->value());
244  }
245  break;
246  default:
247  {
248  QLineEdit *lineEdit = qobject_cast<QLineEdit *>(widget);
249  Q_ASSERT(lineEdit);
250  def = QVariant(lineEdit->text());
251  }
252  }
253  properties[key] = def;
254  }
255  }
256  qDebug() << properties;
257 
258 // QVariantMap properties = _backends[backend].toMap()["ConnectionProperties"].toMap();
259 // if(!properties.isEmpty() && _connectionBox) {
260 // QVariantMap::iterator propertyIter = properties.begin();
261 // while(propertyIter != properties.constEnd()) {
262 // QWidget *widget = _connectionBox->findChild<QWidget *>(propertyIter.key());
263 // switch(propertyIter.value().type()) {
264 // case QVariant::Int:
265 // {
266 // QSpinBox *spinbox = qobject_cast<QSpinBox *>(widget);
267 // Q_ASSERT(spinbox);
268 // propertyIter.value() = QVariant(spinbox->value());
269 // }
270 // break;
271 // default:
272 // {
273 // QLineEdit *lineEdit = qobject_cast<QLineEdit *>(widget);
274 // Q_ASSERT(lineEdit);
275 // propertyIter.value() = QVariant(lineEdit->text());
276 // }
277 // }
278 // propertyIter++;
279 // }
280 // }
281  return properties;
282 }
283 
284 
286 {
287  QString backend = ui.backendList->itemData(ui.backendList->currentIndex()).toString();
288  ui.description->setText(_backends[backend].toMap()["Description"].toString());
289 
290  if (_connectionBox) {
291  layout()->removeWidget(_connectionBox);
292  _connectionBox->deleteLater();
293  _connectionBox = 0;
294  }
295 
296  QStringList setupKeys = _backends[backend].toMap()["SetupKeys"].toStringList();
297  if (!setupKeys.isEmpty()) {
298  QVariantMap defaults = _backends[backend].toMap()["SetupDefaults"].toMap();
299  QGroupBox *propertyBox = new QGroupBox(this);
300  propertyBox->setTitle(tr("Connection Properties"));
301  QFormLayout *formlayout = new QFormLayout;
302 
303  foreach(QString key, setupKeys) {
304  QWidget *widget = 0;
305  QVariant def;
306  if (defaults.contains(key)) {
307  def = defaults[key];
308  }
309  switch (def.type()) {
310  case QVariant::Int:
311  {
312  QSpinBox *spinbox = new QSpinBox(propertyBox);
313  spinbox->setMaximum(64000);
314  spinbox->setValue(def.toInt());
315  widget = spinbox;
316  }
317  break;
318  default:
319  {
320  QLineEdit *lineEdit = new QLineEdit(def.toString(), propertyBox);
321  if (key.toLower().contains("password")) {
322  lineEdit->setEchoMode(QLineEdit::Password);
323  }
324  widget = lineEdit;
325  }
326  }
327  widget->setObjectName(key);
328  formlayout->addRow(key + ":", widget);
329  }
330  propertyBox->setLayout(formlayout);
331  static_cast<QVBoxLayout *>(layout())->insertWidget(layout()->indexOf(ui.descriptionBox) + 1, propertyBox);
332  _connectionBox = propertyBox;
333  }
334 }
335 
336 
337 /*** Sync Page ***/
338 
339 SyncPage::SyncPage(QWidget *parent) : QWizardPage(parent)
340 {
341  ui.setupUi(this);
342  setTitle(tr("Storing Your Settings"));
343  setSubTitle(tr("Your settings are now stored in the core, and you will be logged in automatically."));
344 }
345 
346 
348 {
349  complete = false;
350  hasError = false;
351 
352  StorageSelectionPage *storagePage = qobject_cast<StorageSelectionPage *>(wizard()->page(CoreConfigWizard::StorageSelectionPage));
353  QString backend = storagePage->selectedBackend();
354  QVariantMap properties = storagePage->connectionProperties();
355  Q_ASSERT(!backend.isEmpty());
356  ui.user->setText(wizard()->field("adminUser.user").toString());
357  ui.backend->setText(backend);
358  emit setupCore(backend, properties);
359 }
360 
361 
362 int SyncPage::nextId() const
363 {
364  if (!hasError) return -1;
366 }
367 
368 
370 {
371  return complete;
372 }
373 
374 
375 void SyncPage::setStatus(const QString &status)
376 {
377  ui.status->setText(status);
378 }
379 
380 
381 void SyncPage::setError(bool e)
382 {
383  hasError = e;
384 }
385 
386 
388 {
389  complete = c;
390  completeChanged();
391 }
392 
393 
394 /*** Sync Relay Page ***/
395 
396 SyncRelayPage::SyncRelayPage(QWidget *parent) : QWizardPage(parent)
397 {
398  mode = Success;
399 }
400 
401 
403 {
404  mode = m;
405 }
406 
407 
408 /*
409 void SyncRelayPage::initializePage() {
410  return;
411  if(mode == Success) {
412  wizard()->accept();
413  } else {
414  emit startOver();
415  }
416 }
417 */
418 
420 {
421  emit startOver();
422  return 0;
423 }
424 }; /* namespace CoreConfigWizardPages */