prettyficating the prompting for backend credentials
authorMarcus Eggenberger <egs@quassel-irc.org>
Tue, 3 Mar 2009 17:23:37 +0000 (18:23 +0100)
committerMarcus Eggenberger <egs@quassel-irc.org>
Tue, 3 Mar 2009 19:57:05 +0000 (20:57 +0100)
src/common/main.cpp
src/core/core.cpp
src/core/core.h
src/core/postgresqlstorage.cpp
src/core/postgresqlstorage.h
src/core/sqlitestorage.h
src/core/storage.h
src/qtui/coreconfigwizard.cpp

index 40922b6..b12d642 100644 (file)
@@ -100,7 +100,7 @@ int main(int argc, char **argv) {
   cliParser->addOption("configdir <path>", 'c', "Specify the directory holding configuration files, the SQlite database and the SSL Cert");
   cliParser->addOption("datadir <path>", 0, "DEPRECATED - Use --configdir instead");
   cliParser->addOption("migrate-backend <backendidentifier>", 0, "Starts an interactive session and attempts to migrate your current storage backend to the new one");
   cliParser->addOption("configdir <path>", 'c', "Specify the directory holding configuration files, the SQlite database and the SSL Cert");
   cliParser->addOption("datadir <path>", 0, "DEPRECATED - Use --configdir instead");
   cliParser->addOption("migrate-backend <backendidentifier>", 0, "Starts an interactive session and attempts to migrate your current storage backend to the new one");
-  cliParser->addOption("switch-backend <backendidentifier>", 0, "Starts an interactive session and switches your current storage backend to the new one. No migration will be done!");
+  cliParser->addOption("select-backend <backendidentifier>", 0, "Starts an interactive session and switches your current storage backend to the new one. No migration will be done!");
 #endif
 
 #ifdef HAVE_KDE
 #endif
 
 #ifdef HAVE_KDE
index d859c2a..77280c3 100644 (file)
@@ -138,8 +138,8 @@ Core::Core()
 }
 
 void Core::init() {
 }
 
 void Core::init() {
-  if(Quassel::isOptionSet("switch-backend")) {
-    switchBackend(Quassel::optionValue("switch-backend"));
+  if(Quassel::isOptionSet("select-backend")) {
+    switchBackend(Quassel::optionValue("select-backend"));
     exit(0);
   }
 
     exit(0);
   }
 
@@ -149,8 +149,8 @@ void Core::init() {
   if(!_configured) {
     if(!_storageBackends.count()) {
       qWarning() << qPrintable(tr("Could not initialize any storage backend! Exiting..."));
   if(!_configured) {
     if(!_storageBackends.count()) {
       qWarning() << qPrintable(tr("Could not initialize any storage backend! Exiting..."));
-      qWarning() << qPrintable(tr("Currently, Quassel only supports SQLite3. You need to build your\n"
-                                 "Qt library with the sqlite plugin enabled in order for quasselcore\n"
+      qWarning() << qPrintable(tr("Currently, Quassel supports SQLite3 and PostgreSQL. You need to build your\n"
+                                 "Qt library with the sqlite or postgres plugin enabled in order for quasselcore\n"
                                  "to work."));
       exit(1); // TODO make this less brutal (especially for mono client -> popup)
     }
                                  "to work."));
       exit(1); // TODO make this less brutal (especially for mono client -> popup)
     }
@@ -525,8 +525,8 @@ void Core::processClientMessage(QTcpSocket *socket, const QVariantMap &msg) {
         QVariantMap v;
         v["DisplayName"] = backend->displayName();
         v["Description"] = backend->description();
         QVariantMap v;
         v["DisplayName"] = backend->displayName();
         v["Description"] = backend->description();
-       v["ConnectionProperties"] = backend->setupKeys();
-       qDebug() << backend->setupKeys();
+       v["SetupKeys"] = backend->setupKeys();
+       v["SetupDefaults"] = backend->setupDefaults();
         backends.append(v);
       }
       reply["StorageBackends"] = backends;
         backends.append(v);
       }
       reply["StorageBackends"] = backends;
@@ -721,7 +721,7 @@ bool Core::migrateBackend(const QString &backend) {
   }
 
   Storage *storage = _storageBackends[backend];
   }
 
   Storage *storage = _storageBackends[backend];
-  QVariantMap settings = promptForSettings(storage->setupKeys());
+  QVariantMap settings = promptForSettings(storage);
 
   Storage::State storageState = storage->init(settings);
   switch(storageState) {
 
   Storage::State storageState = storage->init(settings);
   switch(storageState) {
@@ -774,7 +774,7 @@ bool Core::switchBackend(const QString &backend) {
   }
 
   Storage *storage = _storageBackends[backend];
   }
 
   Storage *storage = _storageBackends[backend];
-  QVariantMap settings = promptForSettings(storage->setupKeys());
+  QVariantMap settings = promptForSettings(storage);
 
   bool ok = initStorage(backend, settings, true /* initial setup is allowed */);
   if(ok) {
 
   bool ok = initStorage(backend, settings, true /* initial setup is allowed */);
   if(ok) {
@@ -793,36 +793,43 @@ void Core::saveBackendSettings(const QString &backend, const QVariantMap &settin
   CoreSettings().setStorageSettings(dbsettings);
 }
 
   CoreSettings().setStorageSettings(dbsettings);
 }
 
-QVariantMap Core::promptForSettings(const QVariantMap &map) {
+QVariantMap Core::promptForSettings(const Storage *storage) {
   QVariantMap settings;
   QVariantMap settings;
-  if(map.isEmpty())
+
+  QStringList keys = storage->setupKeys();
+  if(keys.isEmpty())
     return settings;
 
   QTextStream out(stdout);
   QTextStream in(stdin);
   out << "!!!Warning: echo mode is always on even if asked for a password!!!" << endl;
     return settings;
 
   QTextStream out(stdout);
   QTextStream in(stdin);
   out << "!!!Warning: echo mode is always on even if asked for a password!!!" << endl;
+  out << "Default values are in brackets" << endl;
 
 
-  QVariantMap::const_iterator iter;
+  QVariantMap defaults = storage->setupDefaults();
   QString value;
   QString value;
-  for(iter = map.constBegin(); iter != map.constEnd(); iter++) {
-    out << iter.key() << " (" << iter.value().toString() << "): ";
+  foreach(QString key, keys) {
+    QVariant val;
+    if(defaults.contains(key)) {
+      val = defaults[key];
+    }
+    out << key;
+    if(!val.toString().isEmpty()) {
+      out << " (" << val.toString() << ")";
+    }
+    out << ": ";
     out.flush();
     out.flush();
-    value = in.readLine();
+    value = in.readLine().trimmed();
 
 
-    if(value.isEmpty()) {
-      settings[iter.key()] = iter.value();
-    } else {
-      value = value.trimmed();
-      QVariant val;
-      switch(iter.value().type()) {
+    if(!value.isEmpty()) {
+      switch(defaults[key].type()) {
       case QVariant::Int:
        val = QVariant(value.toInt());
        break;
       default:
        val = QVariant(value);
       }
       case QVariant::Int:
        val = QVariant(value.toInt());
        break;
       default:
        val = QVariant(value);
       }
-      settings[iter.key()] = val;
     }
     }
+    settings[key] = val;
   }
   return settings;
 }
   }
   return settings;
 }
index de579d5..815030f 100644 (file)
@@ -427,7 +427,7 @@ private:
   bool migrateBackend(const QString &backend);
   bool switchBackend(const QString &backend);
   void saveBackendSettings(const QString &backend, const QVariantMap &settings);
   bool migrateBackend(const QString &backend);
   bool switchBackend(const QString &backend);
   void saveBackendSettings(const QString &backend, const QVariantMap &settings);
-  QVariantMap promptForSettings(const QVariantMap &map);
+  QVariantMap promptForSettings(const Storage *storage);
 
   QHash<UserId, SessionThread *> sessions;
   Storage *_storage;
 
   QHash<UserId, SessionThread *> sessions;
   Storage *_storage;
index 8d23a2d..c7d59b9 100644 (file)
@@ -61,10 +61,18 @@ QString PostgreSqlStorage::description() const {
   return tr("PostgreSQL Turbo Bomber HD!");
 }
 
   return tr("PostgreSQL Turbo Bomber HD!");
 }
 
-QVariantMap PostgreSqlStorage::setupKeys() const {
+QStringList PostgreSqlStorage::setupKeys() const {
+  QStringList keys;
+  keys << "Username"
+       << "Password"
+       << "Hostname"
+       << "Port"
+       << "Database";
+  return keys;
+}
+QVariantMap PostgreSqlStorage::setupDefaults() const {
   QVariantMap map;
   map["Username"] = QVariant(QString("quassel"));
   QVariantMap map;
   map["Username"] = QVariant(QString("quassel"));
-  map["Password"] = QVariant(QString());
   map["Hostname"] = QVariant(QString("localhost"));
   map["Port"] = QVariant(5432);
   map["Database"] = QVariant(QString("quassel"));
   map["Hostname"] = QVariant(QString("localhost"));
   map["Port"] = QVariant(5432);
   map["Database"] = QVariant(QString("quassel"));
index e3b4e36..5729ac9 100644 (file)
@@ -40,7 +40,8 @@ public slots:
   virtual bool isAvailable() const;
   virtual QString displayName() const;
   virtual QString description() const;
   virtual bool isAvailable() const;
   virtual QString displayName() const;
   virtual QString description() const;
-  virtual QVariantMap setupKeys() const;
+  virtual QStringList setupKeys() const;
+  virtual QVariantMap setupDefaults() const;
   virtual bool setup(const QVariantMap &settings = QVariantMap());
 
   // TODO: Add functions for configuring the backlog handling, i.e. defining auto-cleanup settings etc
   virtual bool setup(const QVariantMap &settings = QVariantMap());
 
   // TODO: Add functions for configuring the backlog handling, i.e. defining auto-cleanup settings etc
index 1df9ea1..1c759ab 100644 (file)
@@ -41,7 +41,8 @@ public slots:
 
   bool isAvailable() const;
   QString displayName() const;
 
   bool isAvailable() const;
   QString displayName() const;
-  inline QVariantMap setupKeys() const { return QVariantMap(); }
+  virtual inline QStringList setupKeys() const { return QStringList(); }
+  virtual inline QVariantMap setupDefaults() const { return QVariantMap(); }
   QString description() const;
 
   // TODO: Add functions for configuring the backlog handling, i.e. defining auto-cleanup settings etc
   QString description() const;
 
   // TODO: Add functions for configuring the backlog handling, i.e. defining auto-cleanup settings etc
index 5012c24..f7495f4 100644 (file)
@@ -59,9 +59,13 @@ public slots:
   /** \return A string that can be displayed by the client to describe the storage backend */
   virtual QString description() const = 0;
 
   /** \return A string that can be displayed by the client to describe the storage backend */
   virtual QString description() const = 0;
 
-  //! Returns a map where the keys are required properties to use the storage backend
+  //! Returns a list of properties required to use the storage backend
+  virtual QStringList setupKeys() const = 0;
+
+  //! Returns a map where the keys are are properties to use the storage backend
   /*  the values are QVariants with default values */
   /*  the values are QVariants with default values */
-  virtual QVariantMap setupKeys() const = 0;
+  virtual QVariantMap setupDefaults() const = 0;
+
 
   //! Setup the storage provider.
   /** This prepares the storage provider (e.g. create tables, etc.) for use within Quassel.
 
   //! Setup the storage provider.
   /** This prepares the storage provider (e.g. create tables, etc.) for use within Quassel.
@@ -71,7 +75,7 @@ public slots:
   virtual bool setup(const QVariantMap &settings = QVariantMap()) = 0;
 
   //! Initialize the storage provider
   virtual bool setup(const QVariantMap &settings = QVariantMap()) = 0;
 
   //! Initialize the storage provider
-  /** \param settings   Hostname, port, username, password, ...  
+  /** \param settings   Hostname, port, username, password, ...
    *  \return the State the storage backend is now in (see Storage::State)
    */
   virtual State init(const QVariantMap &settings = QVariantMap()) = 0;
    *  \return the State the storage backend is now in (see Storage::State)
    */
   virtual State init(const QVariantMap &settings = QVariantMap()) = 0;
@@ -130,7 +134,7 @@ public slots:
    * \param data         The Value
    */
   virtual void setUserSetting(UserId userId, const QString &settingName, const QVariant &data) = 0;
    * \param data         The Value
    */
   virtual void setUserSetting(UserId userId, const QString &settingName, const QVariant &data) = 0;
-  
+
   //! Retrieve a persistent user setting
   /**
    * \param userId       The users Id
   //! Retrieve a persistent user setting
   /**
    * \param userId       The users Id
@@ -145,7 +149,7 @@ public slots:
   virtual bool updateIdentity(UserId user, const CoreIdentity &identity) = 0;
   virtual void removeIdentity(UserId user, IdentityId identityId) = 0;
   virtual QList<CoreIdentity> identities(UserId user) = 0;
   virtual bool updateIdentity(UserId user, const CoreIdentity &identity) = 0;
   virtual void removeIdentity(UserId user, IdentityId identityId) = 0;
   virtual QList<CoreIdentity> identities(UserId user) = 0;
-  
+
   /* Network handling */
 
   //! Create a new Network in the storage backend and return it unique Id
   /* Network handling */
 
   //! Create a new Network in the storage backend and return it unique Id
@@ -179,7 +183,7 @@ public slots:
    *  \return QList<NetworkInfo>.
    */
   virtual QList<NetworkInfo> networks(UserId user) = 0;
    *  \return QList<NetworkInfo>.
    */
   virtual QList<NetworkInfo> networks(UserId user) = 0;
-  
+
   //! Get a list of Networks to restore
   /** Return a list of networks the user was connected at the time of core shutdown
    *  \note This method is threadsafe.
   //! Get a list of Networks to restore
   /** Return a list of networks the user was connected at the time of core shutdown
    *  \note This method is threadsafe.
@@ -338,7 +342,7 @@ public slots:
    */
   virtual QHash<BufferId, MsgId> bufferLastSeenMsgIds(UserId user) = 0;
 
    */
   virtual QHash<BufferId, MsgId> bufferLastSeenMsgIds(UserId user) = 0;
 
-  
+
   /* Message handling */
 
   //! Store a Message in the storage backend and set its unique Id.
   /* Message handling */
 
   //! Store a Message in the storage backend and set its unique Id.
index 030af57..0d5c977 100644 (file)
@@ -162,9 +162,12 @@ bool AdminUserPage::isComplete() const {
 
 /*** Storage Selection Page ***/
 
 
 /*** Storage Selection Page ***/
 
-StorageSelectionPage::StorageSelectionPage(const QHash<QString, QVariant> &backends, QWidget *parent) : QWizardPage(parent) {
+StorageSelectionPage::StorageSelectionPage(const QHash<QString, QVariant> &backends, QWidget *parent)
+  : QWizardPage(parent),
+    _connectionBox(0),
+    _backends(backends)
+{
   ui.setupUi(this);
   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."));
 
   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."));
@@ -189,29 +192,61 @@ QString StorageSelectionPage::selectedBackend() const {
 
 QVariantMap StorageSelectionPage::connectionProperties() const {
   QString backend = ui.backendList->itemData(ui.backendList->currentIndex()).toString();
 
 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()) {
+
+  QVariantMap properties;
+  QStringList setupKeys = _backends[backend].toMap()["SetupKeys"].toStringList();
+  if(!setupKeys.isEmpty()) {
+    QVariantMap defaults = _backends[backend].toMap()["SetupDefaults"].toMap();
+    foreach(QString key, setupKeys) {
+      QWidget *widget = _connectionBox->findChild<QWidget *>(key);
+      QVariant def;
+      if(defaults.contains(key)) {
+       def = defaults[key];
+      }
+      switch(def.type()) {
       case QVariant::Int:
        {
          QSpinBox *spinbox = qobject_cast<QSpinBox *>(widget);
          Q_ASSERT(spinbox);
       case QVariant::Int:
        {
          QSpinBox *spinbox = qobject_cast<QSpinBox *>(widget);
          Q_ASSERT(spinbox);
-         propertyIter.value() = QVariant(spinbox->value());
+         def = QVariant(spinbox->value());
        }
        break;
       default:
        {
          QLineEdit *lineEdit = qobject_cast<QLineEdit *>(widget);
          Q_ASSERT(lineEdit);
        }
        break;
       default:
        {
          QLineEdit *lineEdit = qobject_cast<QLineEdit *>(widget);
          Q_ASSERT(lineEdit);
-         propertyIter.value() = QVariant(lineEdit->text());
+         def = QVariant(lineEdit->text());
        }
       }
        }
       }
-      propertyIter++;
+      properties[key] = def;
     }
   }
     }
   }
+  qDebug() << properties;
+
+
+//   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;
 }
 
   return properties;
 }
 
@@ -225,30 +260,39 @@ void StorageSelectionPage::on_backendList_currentIndexChanged() {
     _connectionBox = 0;
   }
 
     _connectionBox = 0;
   }
 
-  QVariantMap properties = _backends[backend].toMap()["ConnectionProperties"].toMap();
-  if(!properties.isEmpty()) {
+  QStringList setupKeys = _backends[backend].toMap()["SetupKeys"].toStringList();
+  if(!setupKeys.isEmpty()) {
+    QVariantMap defaults = _backends[backend].toMap()["SetupDefaults"].toMap();
     QGroupBox *propertyBox = new QGroupBox(this);
     propertyBox->setTitle(tr("Connection Properties"));
     QFormLayout *formlayout = new QFormLayout;
 
     QGroupBox *propertyBox = new QGroupBox(this);
     propertyBox->setTitle(tr("Connection Properties"));
     QFormLayout *formlayout = new QFormLayout;
 
-    QVariantMap::const_iterator propertyIter = properties.constBegin();
-    while(propertyIter != properties.constEnd()) {
+    foreach(QString key, setupKeys) {
       QWidget *widget = 0;
       QWidget *widget = 0;
-      switch(propertyIter.value().type()) {
+      QVariant def;
+      if(defaults.contains(key)) {
+       def = defaults[key];
+      }
+      switch(def.type()) {
       case QVariant::Int:
        {
          QSpinBox *spinbox = new QSpinBox(propertyBox);
          spinbox->setMaximum(64000);
       case QVariant::Int:
        {
          QSpinBox *spinbox = new QSpinBox(propertyBox);
          spinbox->setMaximum(64000);
-         spinbox->setValue(propertyIter.value().toInt());
+         spinbox->setValue(def.toInt());
          widget = spinbox;
        }
        break;
       default:
          widget = spinbox;
        }
        break;
       default:
-       widget = new QLineEdit(propertyIter.value().toString(), propertyBox);
+       {
+         QLineEdit *lineEdit = new QLineEdit(def.toString(), propertyBox);
+         if(key.toLower().contains("password")) {
+           lineEdit->setEchoMode(QLineEdit::Password);
+         }
+         widget = lineEdit;
+       }
       }
       }
-      widget->setObjectName(propertyIter.key());
-      formlayout->addRow(propertyIter.key() + ":", widget);
-      propertyIter++;
+      widget->setObjectName(key);
+      formlayout->addRow(key + ":", widget);
     }
     propertyBox->setLayout(formlayout);
     static_cast<QVBoxLayout *>(layout())->insertWidget(layout()->indexOf(ui.descriptionBox) + 1, propertyBox);
     }
     propertyBox->setLayout(formlayout);
     static_cast<QVBoxLayout *>(layout())->insertWidget(layout()->indexOf(ui.descriptionBox) + 1, propertyBox);