MQTT Subscriptions

 // Copyright (C) 2017 The Qt Company Ltd.
 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

 #include "mainwindow.h"
 #include "subscriptionwindow.h"
 #include "ui_mainwindow.h"

 #include <QtCore/QDateTime>
 #include <QtMqtt/QMqttClient>
 #include <QtWidgets/QMessageBox>

 using namespace Qt::StringLiterals;

 MainWindow::MainWindow(QWidget *parent) :
     QMainWindow(parent),
     ui(new Ui::MainWindow)
 {
     ui->setupUi(this);

     m_client = new QMqttClient(this);
     m_client->setHostname(ui->lineEditHost->text());
     m_client->setPort(static_cast<quint16>(ui->spinBoxPort->value()));

     connect(m_client, &QMqttClient::stateChanged, this, &MainWindow::updateLogStateChange);
     connect(m_client, &QMqttClient::disconnected, this, &MainWindow::brokerDisconnected);

     connect(m_client, &QMqttClient::messageReceived, this, [this](const QByteArray &message, const QMqttTopicName &topic) {
         const QString content = QDateTime::currentDateTime().toString()
                     + " Received Topic: "_L1
                     + topic.name()
                     + " Message: "_L1
                     + message
                     + u'\n';
         ui->editLog->insertPlainText(content);
     });

     connect(m_client, &QMqttClient::pingResponseReceived, this, [this]() {
         const QString content = QDateTime::currentDateTime().toString()
                     + " PingResponse\n"_L1;
         ui->editLog->insertPlainText(content);
     });

     connect(ui->lineEditHost, &QLineEdit::textChanged, m_client, &QMqttClient::setHostname);
     connect(ui->spinBoxPort, QOverload<int>::of(&QSpinBox::valueChanged), this, &MainWindow::setClientPort);
     connect(ui->lineEditUser, &QLineEdit::textChanged, m_client, &QMqttClient::setUsername);
     connect(ui->lineEditPassword, &QLineEdit::textChanged, m_client, &QMqttClient::setPassword);
     updateLogStateChange();
 }

 MainWindow::~MainWindow()
 {
     delete ui;
     qApp->quit();
 }

 void MainWindow::on_buttonConnect_clicked()
 {
     if (m_client->state() == QMqttClient::Disconnected) {
         ui->lineEditHost->setEnabled(false);
         ui->spinBoxPort->setEnabled(false);
         ui->lineEditUser->setEnabled(false);
         ui->lineEditPassword->setEnabled(false);
         ui->buttonConnect->setText(tr("Disconnect"));
         m_client->connectToHost();
     } else {
         ui->lineEditHost->setEnabled(true);
         ui->spinBoxPort->setEnabled(true);
         ui->lineEditUser->setEnabled(true);
         ui->lineEditPassword->setEnabled(true);
         ui->buttonConnect->setText(tr("Connect"));
         m_client->disconnectFromHost();
     }
 }

 void MainWindow::on_buttonQuit_clicked()
 {
     QApplication::quit();
 }

 void MainWindow::updateLogStateChange()
 {
     const QString content = QDateTime::currentDateTime().toString()
                     + ": State Change"_L1
                     + QString::number(m_client->state())
                     + u'\n';
     ui->editLog->insertPlainText(content);
 }

 void MainWindow::brokerDisconnected()
 {
     ui->lineEditHost->setEnabled(true);
     ui->spinBoxPort->setEnabled(true);
     ui->lineEditUser->setEnabled(true);
     ui->lineEditPassword->setEnabled(true);
     ui->buttonConnect->setText(tr("Connect"));
 }

 void MainWindow::setClientPort(int p)
 {
     m_client->setPort(static_cast<quint16>(p));
 }

 void MainWindow::on_buttonPublish_clicked()
 {
     if (m_client->publish(ui->lineEditTopic->text(), ui->lineEditMessage->text().toUtf8(),
                           static_cast<quint8>(ui->spinQoS_2->text().toUInt()),
                           ui->checkBoxRetain->isChecked())
         == -1)
         QMessageBox::critical(this, u"Error"_s, u"Could not publish message"_s);
 }

 void MainWindow::on_buttonSubscribe_clicked()
 {
     auto subscription = m_client->subscribe(ui->lineEditTopic->text(),
                                             static_cast<quint8>(ui->spinQoS->text().toUInt()));
     if (!subscription) {
         QMessageBox::critical(this, u"Error"_s,
                               u"Could not subscribe. Is there a valid connection?"_s);
         return;
     }
     auto subWindow = new SubscriptionWindow(subscription);
     subWindow->setWindowTitle(subscription->topic().filter());
     subWindow->show();
 }