File indexing completed on 2024-05-12 15:27:51

0001 /***************************************************************************
0002 File                 : MQTTConnectionManagerWidget.cpp
0003 Project              : LabPlot
0004 Description          : widget for managing MQTT connections
0005 --------------------------------------------------------------------
0006 Copyright            : (C) 2018 Ferencz Kovacs (kferike98@gmail.com)
0007 Copyright            : (C) 2018-2019 Alexander Semke (alexander.semke@web.de)
0008 
0009 ***************************************************************************/
0010 
0011 /***************************************************************************
0012  *                                                                         *
0013  *  This program is free software; you can redistribute it and/or modify   *
0014  *  it under the terms of the GNU General Public License as published by   *
0015  *  the Free Software Foundation; either version 2 of the License, or      *
0016  *  (at your option) any later version.                                    *
0017  *                                                                         *
0018  *  This program is distributed in the hope that it will be useful,        *
0019  *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
0020  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
0021  *  GNU General Public License for more details.                           *
0022  *                                                                         *
0023  *   You should have received a copy of the GNU General Public License     *
0024  *   along with this program; if not, write to the Free Software           *
0025  *   Foundation, Inc., 51 Franklin Street, Fifth Floor,                    *
0026  *   Boston, MA  02110-1301  USA                                           *
0027  *                                                                         *
0028  ***************************************************************************/
0029 
0030 #include "MQTTConnectionManagerWidget.h"
0031 
0032 #include "backend/lib/macros.h"
0033 
0034 #include <KConfig>
0035 #include <KConfigGroup>
0036 #include <KLocalizedString>
0037 #include <KMessageBox>
0038 #include <KSharedConfig>
0039 
0040 #include <QTimer>
0041 #include <QtMqtt>
0042 #include <QListWidgetItem>
0043 
0044 /*!
0045    \class MQTTConnectionManagerWidget
0046    \brief widget for managing MQTT connections, embedded in \c MQTTConnectionManagerDialog.
0047 
0048    \ingroup kdefrontend
0049 */
0050 MQTTConnectionManagerWidget::MQTTConnectionManagerWidget(QWidget* parent, const QString& conn) : QWidget(parent),
0051     m_initConnName(conn) {
0052 
0053     ui.setupUi(this);
0054 
0055     m_configPath = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation).constFirst() + QStringLiteral("MQTT_connections");
0056 
0057     ui.lePort->setValidator(new QIntValidator(ui.lePort));
0058     ui.bAdd->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
0059     ui.bRemove->setIcon(QIcon::fromTheme(QStringLiteral("list-remove")));
0060     ui.bAdd->setToolTip(i18n("Add new MQTT connection"));
0061     ui.bRemove->setToolTip(i18n("Remove selected MQTT connection"));
0062     ui.bTest->setIcon(QIcon::fromTheme(QStringLiteral("network-connect")));
0063 
0064     //SIGNALs/SLOTs
0065     connect(ui.leName, &QLineEdit::textChanged, this, &MQTTConnectionManagerWidget::nameChanged);
0066     connect(ui.lwConnections, &QListWidget::currentRowChanged, this, &MQTTConnectionManagerWidget::connectionChanged);
0067     connect(ui.bAdd, &QPushButton::clicked, this, &MQTTConnectionManagerWidget::addConnection);
0068     connect(ui.bRemove, &QPushButton::clicked, this, &MQTTConnectionManagerWidget::deleteConnection);
0069     connect(ui.leHost, &QLineEdit::textChanged, this, &MQTTConnectionManagerWidget::hostChanged);
0070     connect(ui.lePort, &QLineEdit::textChanged, this, &MQTTConnectionManagerWidget::portChanged);
0071     connect(ui.leUserName, &QLineEdit::textChanged, this, &MQTTConnectionManagerWidget::userNameChanged);
0072     connect(ui.lePassword, &QLineEdit::textChanged, this, &MQTTConnectionManagerWidget::passwordChanged);
0073     connect(ui.leID, &QLineEdit::textChanged, this, &MQTTConnectionManagerWidget::clientIdChanged);
0074     connect(ui.chbAuthentication, &QCheckBox::stateChanged, this, &MQTTConnectionManagerWidget::authenticationChecked);
0075     connect(ui.chbID, &QCheckBox::stateChanged, this, &MQTTConnectionManagerWidget::idChecked);
0076     connect(ui.chbRetain, &QCheckBox::stateChanged, this, &MQTTConnectionManagerWidget::retainChecked);
0077     connect(ui.bTest, &QPushButton::clicked, this, &MQTTConnectionManagerWidget::testConnection);
0078 
0079     ui.lePassword->hide();
0080     ui.lPassword->hide();
0081     ui.lePassword->setToolTip(i18n("Please set a password."));
0082     ui.leUserName->hide();
0083     ui.lUsername->hide();
0084     ui.leUserName->setToolTip(i18n("Please set a username."));
0085     ui.leID->hide();
0086     ui.lID->hide();
0087     ui.leID->setToolTip(i18n("Please set a client ID."));
0088     ui.leHost->setToolTip(i18n("Please set a valid host name."));
0089     ui.leHost->setToolTip(i18n("Please set a valid name."));
0090 
0091     QTimer::singleShot(100, this, SLOT(loadConnections()));
0092 }
0093 
0094 MQTTConnectionManagerWidget::~MQTTConnectionManagerWidget() {
0095     delete m_client;
0096 }
0097 
0098 /*!
0099  * \brief Returns the currently selected connection's name
0100  */
0101 QString MQTTConnectionManagerWidget::connection() const {
0102     if (ui.lwConnections->currentItem())
0103         return ui.lwConnections->currentItem()->text();
0104     else
0105         return QString();
0106 }
0107 
0108 /*!
0109  * \brief Shows the settings of the currently selected connection
0110  * \param index the index of the new connection
0111  */
0112 void MQTTConnectionManagerWidget::connectionChanged(int index) {
0113     if (m_initializing)
0114         return;
0115 
0116     if (index == -1) {
0117         m_currentConnection = nullptr;
0118         return;
0119     }
0120 
0121     m_initializing = true;
0122     m_currentConnection = &m_connections[index];
0123 
0124     //show the settings for the selected connection
0125     ui.leName->setText(m_currentConnection->name);
0126     ui.leHost->setText(m_currentConnection->hostName);
0127     ui.lePort->setText(QString::number(m_currentConnection->port));
0128 
0129     if (m_currentConnection->useAuthentication) {
0130         ui.chbAuthentication->setChecked(true);
0131         ui.leUserName->setText(m_currentConnection->userName);
0132         ui.lePassword->setText(m_currentConnection->password);
0133     } else
0134         ui.chbAuthentication->setChecked(false);
0135 
0136     if (m_currentConnection->useID) {
0137         ui.chbID->setChecked(true);
0138         ui.leID->setText(m_currentConnection->clientID);
0139     } else
0140         ui.chbID->setChecked(false);
0141 
0142     ui.chbRetain->setChecked(m_currentConnection->retain);
0143 
0144     m_initializing = false;
0145 }
0146 
0147 /*!
0148  * \brief Called when the name is changed
0149  * Sets the name for the current connection
0150  */
0151 void MQTTConnectionManagerWidget::nameChanged(const QString &name) {
0152     if (name.isEmpty()) {
0153         ui.leName->setStyleSheet(QStringLiteral("QLineEdit{background: red;}"));
0154         ui.leHost->setToolTip(i18n("Please set a valid name."));
0155     } else {
0156         //check uniqueness of the provided name
0157         bool unique = true;
0158         for (int i = 0; i < ui.lwConnections->count(); ++i) {
0159             if (ui.lwConnections->currentRow() == i)
0160                 continue;
0161 
0162             if (name == ui.lwConnections->item(i)->text()) {
0163                 unique = false;
0164                 break;
0165             }
0166         }
0167 
0168         if (unique) {
0169             ui.leName->setStyleSheet(QString());
0170             ui.leName->setToolTip(QString());
0171             ui.lwConnections->currentItem()->setText(name);
0172 
0173             if (!m_initializing) {
0174                 m_currentConnection->name = name;
0175                 emit changed();
0176             }
0177         } else {
0178             ui.leName->setStyleSheet(QStringLiteral("QLineEdit{background: red;}"));
0179             ui.leHost->setToolTip(i18n("Please provide a unique name."));
0180         }
0181     }
0182 }
0183 
0184 /*!
0185  * \brief Called when the host name is changed
0186  * Sets the host name for the current connection
0187  */
0188 void MQTTConnectionManagerWidget::hostChanged(const QString& hostName) {
0189     if (hostName.isEmpty()) {
0190         ui.leHost->setStyleSheet(QStringLiteral("QLineEdit{background: red;}"));
0191         ui.leHost->setToolTip(i18n("Please set a valid host name."));
0192     } else {
0193         m_currentConnection->hostName = hostName;
0194         //check uniqueness of the provided host name
0195         bool unique = true;
0196         for (auto & c : m_connections) {
0197             if (m_currentConnection == &c)
0198                 continue;
0199 
0200             if (m_currentConnection->hostName == c.hostName && m_currentConnection->port == c.port) {
0201                 unique = false;
0202                 break;
0203             }
0204         }
0205 
0206         if (!unique) {
0207             ui.leHost->setStyleSheet(QStringLiteral("QLineEdit{background: red;}"));
0208             ui.leHost->setToolTip(i18n("Host name and port must be unique."));
0209             ui.lePort->setStyleSheet(QStringLiteral("QLineEdit{background: red;}"));
0210             ui.lePort->setToolTip(i18n("Host name and port must be unique."));
0211         } else {
0212             ui.leHost->setStyleSheet(QString());
0213             ui.leHost->setToolTip(QString());
0214             ui.lePort->setStyleSheet(QString());
0215             ui.lePort->setToolTip(QString());
0216 
0217             if (!m_initializing)
0218                 emit changed();
0219         }
0220     }
0221 }
0222 
0223 /*!
0224  * \brief Called when the port is changed
0225  * Sets the port for the current connection
0226  */
0227 void MQTTConnectionManagerWidget::portChanged(const QString& portString) {
0228     if (portString.isEmpty()) {
0229         ui.leHost->setStyleSheet(QStringLiteral("QLineEdit{background: red;}"));
0230         ui.leHost->setToolTip(i18n("Please set a valid port."));
0231     } else {
0232         m_currentConnection->port = portString.simplified().toInt();
0233         //check uniqueness of the provided host name
0234         bool unique = true;
0235         for (auto & c : m_connections) {
0236             if (m_currentConnection == &c)
0237                 continue;
0238 
0239             if (m_currentConnection->hostName == c.hostName && m_currentConnection->port == c.port) {
0240                 unique = false;
0241                 break;
0242             }
0243         }
0244 
0245         if (!unique) {
0246             ui.leHost->setStyleSheet(QStringLiteral("QLineEdit{background: red;}"));
0247             ui.leHost->setToolTip(i18n("Host name and port must be unique."));
0248             ui.lePort->setStyleSheet(QStringLiteral("QLineEdit{background: red;}"));
0249             ui.lePort->setToolTip(i18n("Host name and port must be unique."));
0250         } else {
0251             ui.leHost->setStyleSheet(QString());
0252             ui.leHost->setToolTip(QString());
0253             ui.lePort->setStyleSheet(QString());
0254             ui.lePort->setToolTip(QString());
0255 
0256             if (!m_initializing)
0257                 emit changed();
0258         }
0259     }
0260 
0261 }
0262 
0263 /*!
0264  *\brief Called when authentication checkbox's state is changed,
0265  *       if checked two lineEdits are shown so the user can set the username and password
0266  *
0267  * \param state the state of the checkbox
0268  */
0269 void MQTTConnectionManagerWidget::authenticationChecked(int state) {
0270     if (state == Qt::CheckState::Checked) {
0271         ui.lPassword->show();
0272         ui.lePassword->show();
0273         ui.lUsername->show();
0274         ui.leUserName->show();
0275 
0276         if (m_currentConnection) {
0277             ui.lePassword->setText(m_currentConnection->password);
0278             ui.leUserName->setText(m_currentConnection->userName);
0279             if (!m_initializing)
0280                 m_currentConnection->useAuthentication = true;
0281         }
0282 
0283     } else if (state == Qt::CheckState::Unchecked) {
0284         ui.lPassword->hide();
0285         ui.lePassword->hide();
0286         ui.lePassword->clear();
0287         ui.lUsername->hide();
0288         ui.leUserName->hide();
0289         ui.leUserName->clear();
0290 
0291         if (m_currentConnection && !m_initializing) {
0292             m_currentConnection->useAuthentication = false;
0293         }
0294     }
0295 
0296     if (!m_initializing)
0297         emit changed();
0298 }
0299 
0300 /*!
0301  *\brief called when ID checkbox's state is changed, if checked a lineEdit is shown so the user can set the ID
0302  * \param state the state of the checkbox
0303  */
0304 void MQTTConnectionManagerWidget::idChecked(int state) {
0305     if (state == Qt::CheckState::Checked) {
0306         ui.lID->show();
0307         ui.leID->show();
0308 
0309         if (m_currentConnection) {
0310             ui.leID->setText(m_currentConnection->clientID);
0311             if (!m_initializing)
0312                 m_currentConnection->useID = true;
0313         }
0314 
0315     } else if (state == Qt::CheckState::Unchecked) {
0316         ui.lID->hide();
0317         ui.leID->hide();
0318         ui.leID->clear();
0319 
0320         if (m_currentConnection && !m_initializing) {
0321             m_currentConnection->useID = false;
0322         }
0323     }
0324 
0325     if (!m_initializing)
0326         emit changed();
0327 }
0328 
0329 /*!
0330  * \brief called when retain checkbox's state is changed
0331  * \param state the state of the checkbox
0332  */
0333 void MQTTConnectionManagerWidget::retainChecked(int state) {
0334     if (m_initializing)
0335         return;
0336 
0337     if (m_currentConnection) {
0338         if (state == Qt::CheckState::Checked) {
0339             m_currentConnection->retain = true;
0340         } else if (state == Qt::CheckState::Unchecked) {
0341             m_currentConnection->retain = false;
0342         }
0343     }
0344     emit changed();
0345 }
0346 
0347 /*!
0348  * \brief Called when the username is changed
0349  * Sets the username for the current connection
0350  */
0351 void MQTTConnectionManagerWidget::userNameChanged(const QString& userName) {
0352     if (userName.isEmpty()) {
0353         ui.leUserName->setStyleSheet(QStringLiteral("QLineEdit{background: red;}"));
0354         ui.leUserName->setToolTip(i18n("Please set a username."));
0355     } else {
0356         ui.leUserName->setStyleSheet(QString());
0357         ui.leUserName->setToolTip(QString());
0358     }
0359 
0360     if (m_initializing)
0361         return;
0362 
0363     if (m_currentConnection)
0364         m_currentConnection->userName = userName;
0365     emit changed();
0366 }
0367 
0368 /*!
0369  * \brief Called when the password is changed
0370  * Sets the password for the current connection
0371  */
0372 void MQTTConnectionManagerWidget::passwordChanged(const QString& password) {
0373     if (password.isEmpty()) {
0374         ui.lePassword->setStyleSheet(QStringLiteral("QLineEdit{background: red;}"));
0375         ui.lePassword->setToolTip(i18n("Please set a password."));
0376     } else {
0377         ui.lePassword->setStyleSheet(QString());
0378         ui.lePassword->setToolTip(QString());
0379     }
0380 
0381     if (m_initializing)
0382         return;
0383 
0384     if (m_currentConnection)
0385         m_currentConnection->password = password;
0386     emit changed();
0387 }
0388 
0389 /*!
0390  * \brief Called when the client ID is changed
0391  * Sets the client ID for the current connection
0392  */
0393 void MQTTConnectionManagerWidget::clientIdChanged(const QString& clientID) {
0394     if (clientID.isEmpty()) {
0395         ui.leID->setStyleSheet(QStringLiteral("QLineEdit{background: red;}"));
0396         ui.leID->setToolTip(i18n("Please set a client ID."));
0397     } else {
0398         ui.leID->setStyleSheet(QString());
0399         ui.leID->setToolTip(QString());
0400     }
0401 
0402     if (m_initializing)
0403         return;
0404 
0405     if (m_currentConnection)
0406         m_currentConnection->clientID = clientID;
0407     emit changed();
0408 }
0409 
0410 /*!
0411         adds a new sample connection to the end of the list.
0412  */
0413 void MQTTConnectionManagerWidget::addConnection() {
0414     qDebug() << "Adding new connection";
0415     MQTTConnection conn;
0416     conn.name = uniqueName();
0417     conn.hostName = QStringLiteral("localhost");
0418     conn.port = 1883;
0419     conn.useAuthentication = false;
0420     conn.useID = false;
0421 
0422     m_connections.append(conn);
0423     m_currentConnection = &m_connections.back();
0424     ui.lwConnections->addItem(conn.hostName);
0425     ui.lwConnections->setCurrentRow(m_connections.size() - 1);
0426 
0427     //we have now more than one connection, enable widgets
0428     ui.bRemove->setEnabled(true);
0429     ui.leHost->setEnabled(true);
0430     ui.lePort->setEnabled(true);
0431     ui.leUserName->setEnabled(true);
0432     ui.lePassword->setEnabled(true);
0433     ui.leID->setEnabled(true);
0434     ui.leName->setEnabled(true);
0435     emit changed();
0436 }
0437 
0438 /*!
0439         removes the current selected connection.
0440  */
0441 void MQTTConnectionManagerWidget::deleteConnection() {
0442     int ret = KMessageBox::questionYesNo(this,
0443                                          i18n("Do you really want to delete the connection '%1'?", ui.lwConnections->currentItem()->text()),
0444                                          i18n("Delete Connection"));
0445     if (ret != KMessageBox::Yes)
0446         return;
0447 
0448     //remove the current selected connection
0449     m_connections.removeAt(ui.lwConnections->currentRow());
0450     m_initializing = true;
0451     delete ui.lwConnections->takeItem(ui.lwConnections->currentRow());
0452     m_initializing = false;
0453 
0454     //show the connection for the item that was automatically selected after the deletion
0455     connectionChanged(ui.lwConnections->currentRow());
0456 
0457     //disable widgets if there are no connections anymore
0458     if (!m_currentConnection) {
0459         m_initializing = true;
0460         ui.leName->clear();
0461         ui.leName->setEnabled(false);
0462         ui.bRemove->setEnabled(false);
0463         ui.leHost->clear();
0464         ui.leHost->setEnabled(false);
0465         ui.lePort->clear();
0466         ui.lePort->setEnabled(false);
0467         ui.leUserName->clear();
0468         ui.leUserName->setEnabled(false);
0469         ui.lePassword->clear();
0470         ui.lePassword->setEnabled(false);
0471         ui.leID->clear();
0472         ui.leID->setEnabled(false);
0473         m_initializing = false;
0474     }
0475     emit changed();
0476 }
0477 
0478 /*!
0479         Loads the saved connections.
0480  */
0481 void MQTTConnectionManagerWidget::loadConnections() {
0482     qDebug() << "Loading connections from " << m_configPath;
0483 
0484     m_initializing = true;
0485 
0486     KConfig config(m_configPath, KConfig::SimpleConfig);
0487     for (const auto& groupName : config.groupList()) {
0488         const KConfigGroup& group = config.group(groupName);
0489         MQTTConnection conn;
0490         conn.name = groupName;
0491         conn.hostName = group.readEntry("Host", "");
0492         conn.port = group.readEntry("Port", 0);
0493 
0494         conn.useAuthentication = group.readEntry("UseAuthentication", false);
0495         if (conn.useAuthentication) {
0496             conn.userName = group.readEntry("UserName", "");
0497             conn.password = group.readEntry("Password", "");
0498         }
0499 
0500         conn.useID = group.readEntry("UseID", false);
0501         if (conn.useID)
0502             conn.clientID = group.readEntry("ClientID", "");
0503 
0504         conn.retain = group.readEntry("Retain", false);
0505 
0506         m_connections.append(conn);
0507         ui.lwConnections->addItem(conn.name);
0508     }
0509 
0510     //show the first connection if available, create a new connection otherwise
0511     if (!m_connections.empty()) {
0512         if (!m_initConnName.isEmpty()) {
0513             auto items = ui.lwConnections->findItems(m_initConnName, Qt::MatchExactly);
0514             if (items.empty())
0515                 ui.lwConnections->setCurrentRow(ui.lwConnections->count() - 1);
0516             else
0517                 ui.lwConnections->setCurrentItem(items.constFirst());
0518         } else {
0519             ui.lwConnections->setCurrentRow(ui.lwConnections->count() - 1);
0520         }
0521     } else {
0522         addConnection();
0523     }
0524 
0525     m_initializing = false;
0526 
0527     //show the settings of the current connection
0528     connectionChanged(ui.lwConnections->currentRow());
0529 }
0530 
0531 /*!
0532  * \brief Saves the connections present in the list widget.
0533  */
0534 void MQTTConnectionManagerWidget::saveConnections() {
0535     qDebug() << "Saving connections to " << m_configPath;
0536     //delete saved connections
0537     KConfig config(m_configPath, KConfig::SimpleConfig);
0538     for (const auto& group : config.groupList())
0539         config.deleteGroup(group);
0540 
0541     //save connections
0542     for (const auto& conn : m_connections) {
0543         KConfigGroup group = config.group(conn.name);
0544         group.writeEntry("Host", conn.hostName);
0545         group.writeEntry("Port", conn.port);
0546         group.writeEntry("UseAuthentication", QString::number(conn.useAuthentication));
0547         group.writeEntry("UserName", conn.userName);
0548         group.writeEntry("Password", conn.password);
0549         group.writeEntry("UseID", QString::number(conn.useID));
0550         group.writeEntry("ClientID", conn.clientID);
0551         group.writeEntry("Retain", QString::number(conn.retain));
0552     }
0553 
0554     config.sync();
0555 }
0556 
0557 /*!
0558  * \brief Checks whether every connection's settings are alright or not
0559  */
0560 bool MQTTConnectionManagerWidget::checkConnections() {
0561     if (m_connections.isEmpty())
0562         return true;
0563 
0564     bool connectionsOk = true;
0565 
0566     for (int i = 0; i < m_connections.size(); ++i) {
0567         auto & c1 = m_connections[i];
0568         QList<QListWidgetItem*> equalNames = ui.lwConnections->findItems(c1.name, Qt::MatchExactly);
0569         bool nameOK = (!c1.name.isEmpty()) && (equalNames.size() == 1);
0570 
0571         bool authenticationUsed = c1.useAuthentication;
0572         bool idUsed = c1.useID;
0573         bool authenticationFilled = !c1.userName.isEmpty() && !c1.password.isEmpty();
0574         bool idFilled = !c1.clientID.isEmpty();
0575         bool authenticationOK = (!authenticationUsed || authenticationFilled);
0576         bool idOK = (!idUsed || idFilled);
0577 
0578         bool uniqueHost = true;
0579         for (int j = 0; j < m_connections.size(); ++j) {
0580             if (i == j)
0581                 continue;
0582             auto & c2 = m_connections[j];
0583 
0584             if (c2.hostName == c1.hostName && c2.port == c1.port) {
0585                 uniqueHost = false;
0586                 break;
0587             }
0588         }
0589         bool hostOK = (!c1.hostName.isEmpty()) && uniqueHost;
0590         bool allOk = authenticationOK && idOK && hostOK && nameOK;
0591 
0592         if (!allOk) {
0593             connectionsOk = false;
0594             ui.lwConnections->item(i)->setBackground(QBrush(Qt::red));
0595         } else
0596             ui.lwConnections->item(i)->setBackground(QBrush());
0597     }
0598     return connectionsOk;
0599 }
0600 
0601 /*!
0602  * \brief Provides a sample host name, which has to be changed before use.
0603  * \return
0604  */
0605 QString MQTTConnectionManagerWidget::uniqueName() {
0606     QString name = i18n("New connection");
0607 
0608     QStringList connectionNames;
0609     for (int row = 0; row < ui.lwConnections->count(); row++)
0610         connectionNames << ui.lwConnections->item(row)->text();
0611 
0612     if (!connectionNames.contains(name))
0613         return name;
0614 
0615     QString base = name;
0616     int lastNonDigit;
0617     for (lastNonDigit = base.size()-1; lastNonDigit >= 0 &&
0618          base[lastNonDigit].category() == QChar::Number_DecimalDigit; --lastNonDigit)
0619         base.chop(1);
0620 
0621     if (lastNonDigit >=0 && base[lastNonDigit].category() != QChar::Separator_Space)
0622         base.append(' ');
0623 
0624     int newNr = name.rightRef(name.size() - base.size()).toInt();
0625     QString newName;
0626     do
0627         newName = base + QString::number(++newNr);
0628     while (connectionNames.contains(newName));
0629 
0630     return newName;
0631 }
0632 
0633 /*!
0634  * \brief Tests the currently selected connection
0635  */
0636 void MQTTConnectionManagerWidget::testConnection() {
0637     if (!m_currentConnection)
0638         return;
0639 
0640     WAIT_CURSOR;
0641 
0642     m_testing = true;
0643 
0644     if (!m_client) {
0645         m_client = new QMqttClient;
0646         m_testTimer = new QTimer(this);
0647         m_testTimer->setInterval(5000);
0648         connect(m_client, &QMqttClient::connected, this, &MQTTConnectionManagerWidget::onConnect);
0649         connect(m_client, &QMqttClient::disconnected, this, &MQTTConnectionManagerWidget::onDisconnect);
0650         connect(m_testTimer, &QTimer::timeout, this, &MQTTConnectionManagerWidget::testTimeout);
0651     }
0652 
0653     m_client->setHostname(m_currentConnection->hostName);
0654     m_client->setPort(m_currentConnection->port);
0655 
0656     if (m_currentConnection->useID)
0657         m_client->setClientId(m_currentConnection->clientID);
0658 
0659     if (m_currentConnection->useAuthentication) {
0660         m_client->setUsername(m_currentConnection->userName);
0661         m_client->setPassword(m_currentConnection->password);
0662     }
0663 
0664     m_testTimer->start();
0665     m_client->connectToHost();
0666 }
0667 
0668 /*!
0669  * \brief Called when the client connects to the host, this means the test was successful
0670  */
0671 void MQTTConnectionManagerWidget::onConnect() {
0672     RESET_CURSOR;
0673     m_testTimer->stop();
0674 
0675     KMessageBox::information(this, i18n("Connection to the broker '%1:%2' was successful.",
0676                                    m_currentConnection->hostName, m_currentConnection->port),
0677                              i18n("Connection Successful"));
0678 
0679     m_client->disconnectFromHost();
0680 }
0681 
0682 /*!
0683  * \brief Called when testTimer times out, this means that the test wasn't successful
0684  */
0685 void MQTTConnectionManagerWidget::testTimeout() {
0686     RESET_CURSOR;
0687     m_testTimer->stop();
0688 
0689     KMessageBox::error(this, i18n("Failed to connect to the broker '%1:%2'.",
0690                              m_currentConnection->hostName, m_currentConnection->port),
0691                        i18n("Connection Failed"));
0692 
0693     m_client->disconnectFromHost();
0694 }
0695 
0696 /*!
0697  * \brief Called when the client disconnects from the host
0698  */
0699 void MQTTConnectionManagerWidget::onDisconnect() {
0700     RESET_CURSOR;
0701     if (m_testTimer->isActive()) {
0702         KMessageBox::error(this, i18n("Disconnected from the broker '%1:%2' before the connection was successful.",
0703                                  m_currentConnection->hostName, m_currentConnection->port),
0704                            i18n("Connection Failed"));
0705         m_testTimer->stop();
0706     }
0707 }