#include "ConnectionConfigurationWidget.h" #include "SslModeModel.h" #include "ConnectionConfig.h" #include "ConnectionController.h" #include "ConnectionListModel.h" #include "Pgsql_Connection.h" #include "Pgsql_PgException.h" #include "util.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define SET_OBJECT_NAME(var) var->setObjectName(#var) void ConnectionConfigurationWidget::editExistingInWindow(ConnectionController *connection_controller, const ConnectionConfig &cfg, std::function save_func) { try { auto w = new ConnectionConfigurationWidget(connection_controller); w->setData(cfg); auto btn_hbox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal); auto vbox = new QVBoxLayout; vbox->addWidget(w); vbox->addWidget(btn_hbox); auto win = new QDialog; win->setWindowTitle(tr("Edit connection configuration")); win->setLayout(vbox); win->setAttribute( Qt::WA_DeleteOnClose, true ); QObject::connect(btn_hbox, &QDialogButtonBox::accepted, [w, win, save_func] () { save_func(*w); win->accept(); }); QObject::connect(btn_hbox, &QDialogButtonBox::rejected, [win] () { win->reject(); }); win->show(); } catch (const std::exception &ex) { qDebug() << "exception: " << QString::fromUtf8(ex.what()); } } ConnectionConfigurationWidget::ConnectionConfigurationWidget( ConnectionController *connection_controller, QWidget *parent) : QWidget(parent) , m_connectionController(connection_controller) , m_connectionModel(connection_controller->getConnectionTreeModel()) { lblGroup = new QLabel; cmbbxGroup = new QComboBox; cmbbxGroup->setModel(m_connectionModel); cmbbxGroup->setModelColumn(0); lblGroup->setBuddy(cmbbxGroup); lblName = new QLabel; SET_OBJECT_NAME(lblName); edtName = new QLineEdit ; SET_OBJECT_NAME(edtName); lblName->setBuddy(edtName); lblHost = new QLabel; SET_OBJECT_NAME(lblHost); edtHost = new QLineEdit; SET_OBJECT_NAME(edtHost); lblHost->setBuddy(edtHost); lblPort = new QLabel; SET_OBJECT_NAME(lblPort); spinPort = new QSpinBox; SET_OBJECT_NAME(spinPort); spinPort->setRange(1, std::numeric_limits::max()); lblPort->setBuddy(spinPort); lblUser = new QLabel; SET_OBJECT_NAME(lblUser); edtUser = new QLineEdit; SET_OBJECT_NAME(edtUser); lblUser->setBuddy(edtUser); lblPassword = new QLabel; SET_OBJECT_NAME(lblPassword); edtPassword = new QLineEdit; SET_OBJECT_NAME(edtPassword); edtPassword->setEchoMode(QLineEdit::PasswordEchoOnEdit); connect(edtPassword, &QLineEdit::textEdited, this, &ConnectionConfigurationWidget::passwordEdited); cbSavePassword = new QCheckBox; SET_OBJECT_NAME(cbSavePassword); lblDbName = new QLabel; SET_OBJECT_NAME(lblDbName); cmbDbname = new QComboBox; cmbDbname->setEditable(true); // allows to enter the database name even if test failed. cmbDbname->setInsertPolicy(QComboBox::InsertAlphabetically); lblSsl = new QLabel; SET_OBJECT_NAME(lblSsl); cmbbxSsl = new QComboBox; SET_OBJECT_NAME(cmbbxSsl); cmbbxSsl->setModelColumn(0); auto ssl_model = new SslModeModel(this); cmbbxSsl->setModel(ssl_model); lblSsl->setBuddy(cmbbxSsl); lblCert = new QLabel; SET_OBJECT_NAME(lblCert); edtCert = new QLineEdit; SET_OBJECT_NAME(edtCert); lblCert->setBuddy(edtCert); lblKey = new QLabel; SET_OBJECT_NAME(lblKey); edtKey = new QLineEdit; SET_OBJECT_NAME(edtKey); lblKey->setBuddy(edtKey); lblRootCert = new QLabel; SET_OBJECT_NAME(lblRootCert); edtRootCert = new QLineEdit; SET_OBJECT_NAME(edtRootCert); lblRootCert->setBuddy(edtRootCert); lblCrl = new QLabel; SET_OBJECT_NAME(lblCrl); edtCrl = new QLineEdit; SET_OBJECT_NAME(edtCrl); lblCrl->setBuddy(edtCrl); btnTest = new QPushButton; connect(btnTest, &QPushButton::clicked, this, &ConnectionConfigurationWidget::testConnection); lblResult = new QLabel; formLayout = new QFormLayout; formLayout->addRow(lblGroup, cmbbxGroup); formLayout->addRow(lblName, edtName); formLayout->addRow(lblHost, edtHost); formLayout->addRow(lblPort, spinPort); formLayout->addRow(lblUser, edtUser); formLayout->addRow(lblPassword, edtPassword); formLayout->addRow(nullptr, cbSavePassword); formLayout->addRow(lblDbName, cmbDbname); formLayout->addRow(lblSsl, cmbbxSsl); formLayout->addRow(lblCert, edtCert); formLayout->addRow(lblKey, edtKey); formLayout->addRow(lblRootCert, edtRootCert); formLayout->addRow(lblCrl, edtCrl); formLayout->addRow(btnTest, lblResult); setLayout(formLayout); retranslateUi(); } void ConnectionConfigurationWidget::retranslateUi() { lblGroup->setText(QApplication::translate("ConnectionConfigurationWidget", "&Group", nullptr)); lblName->setText(QApplication::translate("ConnectionConfigurationWidget", "&Name", nullptr)); lblHost->setText(QApplication::translate("ConnectionConfigurationWidget", "&Host", nullptr)); lblPort->setText(QApplication::translate("ConnectionConfigurationWidget", "&Port", nullptr)); lblUser->setText(QApplication::translate("ConnectionConfigurationWidget", "&Username", nullptr)); lblPassword->setText(QApplication::translate("ConnectionConfigurationWidget", "Password", nullptr)); cbSavePassword->setText(QApplication::translate("ConnectionConfigurationWidget", "&Save password", nullptr)); lblDbName->setText(QApplication::translate("ConnectionConfigurationWidget", "Database", nullptr)); lblSsl->setText(QApplication::translate("ConnectionConfigurationWidget", "&SSL mode", nullptr)); lblCert->setText(QApplication::translate("ConnectionConfigurationWidget", "&Certificate", nullptr)); lblKey->setText(QApplication::translate("ConnectionConfigurationWidget", "&Key", nullptr)); lblRootCert->setText(QApplication::translate("ConnectionConfigurationWidget", "&Root cert.", nullptr)); lblCrl->setText(QApplication::translate("ConnectionConfigurationWidget", "Revocation &list", nullptr)); btnTest->setText(QApplication::translate("ConnectionConfigurationWidget", "Test", nullptr)); } void ConnectionConfigurationWidget::setData(const ConnectionConfig &cfg) { auto group = cfg.parent(); if (group) { auto group_idx = m_connectionModel->findGroup(group->conngroup_id); cmbbxGroup->setCurrentIndex(group_idx); } m_uuid = cfg.uuid(); edtName->setText(cfg.name()); edtHost->setText(cfg.host()); spinPort->setValue(cfg.port()); edtUser->setText(cfg.user()); edtPassword->setText(""); cmbDbname->setCurrentText(cfg.dbname()); cmbbxSsl->setCurrentIndex(static_cast(cfg.sslMode())); edtCert->setText(cfg.sslCert()); edtKey->setText(cfg.sslKey()); edtRootCert->setText(cfg.sslRootCert()); edtCrl->setText(cfg.sslCrl()); encodedPassword = cfg.encodedPassword(); cbSavePassword->setCheckState( encodedPassword.isEmpty() ? Qt::CheckState::Unchecked : Qt::CheckState::Checked ); passwordChanged = false; } ConnectionConfig ConnectionConfigurationWidget::data() const { ConnectionConfig cfg; cfg.setUuid(m_uuid); cfg.setName(edtName->text()); cfg.setHost(edtHost->text()); cfg.setPort(static_cast(spinPort->value())); cfg.setUser(edtUser->text()); cfg.setPassword(edtPassword->text()); cfg.setDbname(cmbDbname->currentText()); cfg.setSslMode(static_cast(cmbbxSsl->currentIndex())); cfg.setSslCert(edtCert->text()); cfg.setSslKey(edtKey->text()); cfg.setSslRootCert(edtRootCert->text()); cfg.setSslCrl(edtCrl->text()); cfg.setEncodedPassword(encodedPassword); // this could be old, it will be overriden later when there is a new password to save. return cfg; } QString ConnectionConfigurationWidget::group() const { return cmbbxGroup->currentText(); } bool ConnectionConfigurationWidget::savePassword() const { return cbSavePassword->isChecked() && !edtPassword->text().isEmpty() && passwordChanged; } bool ConnectionConfigurationWidget::clearPassword() const { return !cbSavePassword->isChecked(); } void ConnectionConfigurationWidget::testConnection() { QString password = edtPassword->text(); if (password.isEmpty() && !encodedPassword.isEmpty()) { m_connectionController->decodeConnectionPassword(m_uuid, encodedPassword, password); } auto cc = data(); cc.setPassword(password); auto qthis = QPointer(this); QFuture result = QtConcurrent::run( [cc] { return TestConnection(cc); } ).then(qApp, [qthis](TestConnectionResult result) { if (qthis) qthis.data()->handleTestResult(result); } ); } void ConnectionConfigurationWidget::handleTestResult(TestConnectionResult result) { lblResult->setText(result.message()); QString current = cmbDbname->currentText(); cmbDbname->clear(); for (auto &dbn : result.databases()) cmbDbname->addItem(dbn); cmbDbname->setCurrentText(current); } void ConnectionConfigurationWidget::passwordEdited(const QString &) { passwordChanged = true; }