File indexing completed on 2024-04-28 05:48:39

0001 /*
0002    SPDX-FileCopyrightText: 2010 Marco Mentasti <marcomentasti@gmail.com>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #include "connectionwizard.h"
0008 #include "sqlmanager.h"
0009 
0010 #include <KComboBox>
0011 #include <KLineEdit>
0012 #include <KLocalizedString>
0013 #include <KMessageBox>
0014 #include <KPasswordLineEdit>
0015 #include <KUrlRequester>
0016 #include <kio_version.h>
0017 
0018 #include <QFormLayout>
0019 #include <QSpinBox>
0020 #include <QSqlDatabase>
0021 #include <QSqlError>
0022 
0023 ConnectionWizard::ConnectionWizard(SQLManager *manager, Connection *conn, QWidget *parent, Qt::WindowFlags flags)
0024     : QWizard(parent, flags)
0025     , m_manager(manager)
0026     , m_connection(conn)
0027 {
0028     setWindowTitle(i18nc("@title:window", "Connection Wizard"));
0029 
0030     setPage(Page_Driver, new ConnectionDriverPage);
0031     setPage(Page_Standard_Server, new ConnectionStandardServerPage);
0032     setPage(Page_SQLite_Server, new ConnectionSQLiteServerPage);
0033     setPage(Page_Save, new ConnectionSavePage);
0034 }
0035 
0036 ConnectionWizard::~ConnectionWizard()
0037 {
0038 }
0039 
0040 ConnectionDriverPage::ConnectionDriverPage(QWidget *parent)
0041     : QWizardPage(parent)
0042 {
0043     setTitle(i18nc("@title Wizard page title", "Database Driver"));
0044     setSubTitle(i18nc("@title Wizard page subtitle", "Select the database driver"));
0045 
0046     QFormLayout *layout = new QFormLayout();
0047 
0048     driverComboBox = new KComboBox();
0049     driverComboBox->addItems(QSqlDatabase::drivers());
0050 
0051     layout->addRow(i18nc("@label:listbox", "Database driver:"), driverComboBox);
0052 
0053     setLayout(layout);
0054 
0055     registerField(QStringLiteral("driver"), driverComboBox, "currentText");
0056 }
0057 
0058 void ConnectionDriverPage::initializePage()
0059 {
0060     ConnectionWizard *wiz = static_cast<ConnectionWizard *>(wizard());
0061     Connection *c = wiz->connection();
0062 
0063     if (!c->driver.isEmpty()) {
0064         driverComboBox->setCurrentItem(c->driver);
0065     }
0066 }
0067 
0068 int ConnectionDriverPage::nextId() const
0069 {
0070     if (driverComboBox->currentText().contains(QLatin1String("QSQLITE"))) {
0071         return ConnectionWizard::Page_SQLite_Server;
0072     } else {
0073         return ConnectionWizard::Page_Standard_Server;
0074     }
0075 }
0076 
0077 ConnectionStandardServerPage::ConnectionStandardServerPage(QWidget *parent)
0078     : QWizardPage(parent)
0079 {
0080     setTitle(i18nc("@title Wizard page title", "Connection Parameters"));
0081     setSubTitle(i18nc("@title Wizard page subtitle", "Please enter connection parameters"));
0082 
0083     QFormLayout *layout = new QFormLayout();
0084 
0085     hostnameLineEdit = new KLineEdit();
0086     usernameLineEdit = new KLineEdit();
0087     passwordLineEdit = new KPasswordLineEdit();
0088     databaseLineEdit = new KLineEdit();
0089     optionsLineEdit = new KLineEdit();
0090     portSpinBox = new QSpinBox();
0091 
0092     portSpinBox->setMaximum(65535);
0093     portSpinBox->setSpecialValueText(i18nc("@item Spinbox special value", "Default"));
0094     portSpinBox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
0095 
0096     layout->addRow(i18nc("@label:textbox", "Hostname:"), hostnameLineEdit);
0097     layout->addRow(i18nc("@label:textbox", "Username:"), usernameLineEdit);
0098     layout->addRow(i18nc("@label:textbox", "Password:"), passwordLineEdit);
0099     layout->addRow(i18nc("@label:spinbox", "Port:"), portSpinBox);
0100     layout->addRow(i18nc("@label:textbox", "Database name:"), databaseLineEdit);
0101     layout->addRow(i18nc("@label:textbox", "Connection options:"), optionsLineEdit);
0102 
0103     setLayout(layout);
0104 
0105     registerField(QStringLiteral("hostname*"), hostnameLineEdit);
0106     registerField(QStringLiteral("username"), usernameLineEdit);
0107     registerField(QStringLiteral("password"), passwordLineEdit, "password", "passwordChanged");
0108     registerField(QStringLiteral("database"), databaseLineEdit);
0109     registerField(QStringLiteral("stdOptions"), optionsLineEdit);
0110     registerField(QStringLiteral("port"), portSpinBox);
0111 }
0112 
0113 ConnectionStandardServerPage::~ConnectionStandardServerPage()
0114 {
0115 }
0116 
0117 void ConnectionStandardServerPage::initializePage()
0118 {
0119     ConnectionWizard *wiz = static_cast<ConnectionWizard *>(wizard());
0120     Connection *c = wiz->connection();
0121 
0122     hostnameLineEdit->setText(QStringLiteral("localhost"));
0123 
0124     if (c->driver == field(QStringLiteral("driver")).toString()) {
0125         hostnameLineEdit->setText(c->hostname);
0126         usernameLineEdit->setText(c->username);
0127         passwordLineEdit->setPassword(c->password);
0128         databaseLineEdit->setText(c->database);
0129         optionsLineEdit->setText(c->options);
0130         portSpinBox->setValue(c->port);
0131     }
0132 
0133     hostnameLineEdit->selectAll();
0134 }
0135 
0136 bool ConnectionStandardServerPage::validatePage()
0137 {
0138     Connection c;
0139 
0140     c.driver = field(QStringLiteral("driver")).toString();
0141     c.hostname = field(QStringLiteral("hostname")).toString();
0142     c.username = field(QStringLiteral("username")).toString();
0143     c.password = field(QStringLiteral("password")).toString();
0144     c.database = field(QStringLiteral("database")).toString();
0145     c.options = field(QStringLiteral("stdOptions")).toString();
0146     c.port = field(QStringLiteral("port")).toInt();
0147 
0148     QSqlError e;
0149 
0150     ConnectionWizard *wiz = static_cast<ConnectionWizard *>(wizard());
0151 
0152     if (!wiz->manager()->testConnection(c, e)) {
0153         KMessageBox::error(this, i18n("Unable to connect to database.") + QLatin1Char('\n') + e.text());
0154         return false;
0155     }
0156 
0157     return true;
0158 }
0159 
0160 int ConnectionStandardServerPage::nextId() const
0161 {
0162     return ConnectionWizard::Page_Save;
0163 }
0164 
0165 ConnectionSQLiteServerPage::ConnectionSQLiteServerPage(QWidget *parent)
0166     : QWizardPage(parent)
0167 {
0168     setTitle(i18nc("@title Wizard page title", "Connection Parameters"));
0169     setSubTitle(
0170         i18nc("@title Wizard page subtitle", "Please enter the SQLite database file path.\nIf the file does not exist, a new database will be created."));
0171 
0172     QFormLayout *layout = new QFormLayout();
0173 
0174     pathUrlRequester = new KUrlRequester(this);
0175     optionsLineEdit = new KLineEdit();
0176 
0177     pathUrlRequester->setMode(KFile::File);
0178     pathUrlRequester->setNameFilters({i18n("Database files") + QLatin1String(" (*.db *.sqlite)"), i18n("All files") + QLatin1String(" (*)")});
0179     layout->addRow(i18nc("@label:textbox", "Path:"), pathUrlRequester);
0180     layout->addRow(i18nc("@label:textbox", "Connection options:"), optionsLineEdit);
0181 
0182     setLayout(layout);
0183 
0184     registerField(QStringLiteral("path*"), pathUrlRequester->lineEdit());
0185     registerField(QStringLiteral("sqliteOptions"), optionsLineEdit);
0186 }
0187 
0188 void ConnectionSQLiteServerPage::initializePage()
0189 {
0190     ConnectionWizard *wiz = static_cast<ConnectionWizard *>(wizard());
0191     Connection *c = wiz->connection();
0192 
0193     if (c->driver == field(QStringLiteral("driver")).toString()) {
0194         pathUrlRequester->lineEdit()->setText(c->database);
0195         optionsLineEdit->setText(c->options);
0196     }
0197 }
0198 
0199 bool ConnectionSQLiteServerPage::validatePage()
0200 {
0201     Connection c;
0202 
0203     c.driver = field(QStringLiteral("driver")).toString();
0204     c.database = field(QStringLiteral("path")).toString();
0205     c.options = field(QStringLiteral("sqliteOptions")).toString();
0206 
0207     QSqlError e;
0208 
0209     ConnectionWizard *wiz = static_cast<ConnectionWizard *>(wizard());
0210 
0211     if (!wiz->manager()->testConnection(c, e)) {
0212         KMessageBox::error(this, xi18nc("@info", "Unable to connect to database.<nl/><message>%1</message>", e.text()));
0213         return false;
0214     }
0215 
0216     return true;
0217 }
0218 
0219 int ConnectionSQLiteServerPage::nextId() const
0220 {
0221     return ConnectionWizard::Page_Save;
0222 }
0223 
0224 ConnectionSavePage::ConnectionSavePage(QWidget *parent)
0225     : QWizardPage(parent)
0226 {
0227     setTitle(i18nc("@title Wizard page title", "Connection Name"));
0228     setSubTitle(i18nc("@title Wizard page subtitle", "Enter a unique connection name"));
0229 
0230     QFormLayout *layout = new QFormLayout();
0231 
0232     connectionNameLineEdit = new KLineEdit();
0233 
0234     layout->addRow(i18nc("@label:textbox", "Connection name:"), connectionNameLineEdit);
0235 
0236     setLayout(layout);
0237 
0238     registerField(QStringLiteral("connectionName*"), connectionNameLineEdit);
0239 }
0240 
0241 void ConnectionSavePage::initializePage()
0242 {
0243     QString name;
0244 
0245     ConnectionWizard *wiz = static_cast<ConnectionWizard *>(wizard());
0246     Connection *c = wiz->connection();
0247 
0248     if (!c->name.isEmpty()) {
0249         name = c->name;
0250     } else if (field(QStringLiteral("driver")).toString().contains(QLatin1String("QSQLITE"))) {
0251         /// TODO: use db file basename
0252         name = QStringLiteral("SQLite");
0253 
0254         for (int i = 1; QSqlDatabase::contains(name); i++) {
0255             name = QStringLiteral("%1%2").arg(QLatin1String("SQLite")).arg(i);
0256         }
0257     } else {
0258         name = QStringLiteral("%1 on %2").arg(field(QStringLiteral("database")).toString()).arg(field(QStringLiteral("hostname")).toString()).simplified();
0259 
0260         for (int i = 1; QSqlDatabase::contains(name); i++) {
0261             name = QStringLiteral("%1 on %2 (%3)")
0262                        .arg(field(QStringLiteral("database")).toString())
0263                        .arg(field(QStringLiteral("hostname")).toString())
0264                        .arg(i)
0265                        .simplified();
0266         }
0267     }
0268 
0269     connectionNameLineEdit->setText(name);
0270     connectionNameLineEdit->selectAll();
0271 }
0272 
0273 bool ConnectionSavePage::validatePage()
0274 {
0275     QString name = field(QStringLiteral("connectionName")).toString().simplified();
0276 
0277     ConnectionWizard *wiz = static_cast<ConnectionWizard *>(wizard());
0278     Connection *c = wiz->connection();
0279 
0280     c->name = name;
0281     c->driver = field(QStringLiteral("driver")).toString();
0282 
0283     if (field(QStringLiteral("driver")).toString().contains(QLatin1String("QSQLITE"))) {
0284         c->database = field(QStringLiteral("path")).toString();
0285         c->options = field(QStringLiteral("sqliteOptions")).toString();
0286     } else {
0287         c->hostname = field(QStringLiteral("hostname")).toString();
0288         c->username = field(QStringLiteral("username")).toString();
0289         c->password = field(QStringLiteral("password")).toString();
0290         c->database = field(QStringLiteral("database")).toString();
0291         c->options = field(QStringLiteral("stdOptions")).toString();
0292         c->port = field(QStringLiteral("port")).toInt();
0293     }
0294 
0295     return true;
0296 }
0297 
0298 int ConnectionSavePage::nextId() const
0299 {
0300     return -1;
0301 }