diff --git a/.gitignore b/.gitignore index fab7372..58feb1e 100644 --- a/.gitignore +++ b/.gitignore @@ -71,3 +71,5 @@ Thumbs.db *.dll *.exe +# Build files +/build*/ diff --git a/mainwindow.cpp b/mainwindow.cpp index 65b5179..14758bc 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -3,6 +3,7 @@ #include #include +#include // utilities namespace { @@ -23,9 +24,14 @@ MainWindow::MainWindow(QWidget *parent) : connect(m_ui->lineEditUrl, &QLineEdit::returnPressed, this, &MainWindow::connectClicked); connect(m_ui->pushButtonConnect, &QAbstractButton::clicked, this, &MainWindow::connectClicked); - connect(m_ui->lineEditSend, &QLineEdit::returnPressed, this, &MainWindow::sendClicked); + connect(m_ui->comboBoxSend->lineEdit(), &QLineEdit::returnPressed, this, &MainWindow::sendClicked); connect(m_ui->pushButtonSend, &QAbstractButton::clicked, this, &MainWindow::sendClicked); + connect(m_ui->saveSlot, &QComboBox::currentIndexChanged, this, &MainWindow::loadSelectedUrl); + connect(m_ui->pushButtonSave, &QAbstractButton::clicked, this, &MainWindow::saveSettings); + + connect(m_ui->autoReconnectBox, &QCheckBox::toggled, this, &MainWindow::setAutoReconnect); + connect(&m_webSocket, &QWebSocket::connected, this, &MainWindow::connected); connect(&m_webSocket, &QWebSocket::disconnected, this, &MainWindow::disconnected); connect(&m_webSocket, &QWebSocket::stateChanged, this, &MainWindow::stateChanged); @@ -34,7 +40,15 @@ MainWindow::MainWindow(QWidget *parent) : connect(&m_webSocket, qOverload(&QWebSocket::error), this, &MainWindow::error); connect(&m_webSocket, &QWebSocket::pong, this, &MainWindow::pong); + for (uint8_t i = 1; i <= m_url_slots.size(); i++) { + m_ui->saveSlot->addItem("Slot "+QString::number(i)); + } + + loadSettings(); + stateChanged(m_webSocket.state()); + + qApp->installEventFilter(this); } MainWindow::~MainWindow() = default; @@ -43,28 +57,14 @@ void MainWindow::connectClicked() { if (m_webSocket.state() == QAbstractSocket::UnconnectedState) { - const auto url = QUrl::fromUserInput(m_ui->lineEditUrl->text()); - if (url.isEmpty()) - { - QMessageBox::warning(this, tr("Invalid url entered!"), tr("Invalid url entered!")); - return; - } - - if (url.scheme().toLower() != "ws" && - url.scheme().toLower() != "wss") - { - QMessageBox::warning(this, tr("Invalid url entered!"), tr("Only urls starting with ws:// or wss:// are allowed!")); - return; - } - - m_ui->plainTextEdit->appendHtml(QStringLiteral("%0 %1
") - .arg(QTime::currentTime().toString()) - .arg(tr("Connecting to %0").arg(url.toString()))); - - m_webSocket.open(url); + connectToWebsocket(); } else + { + m_ui->autoReconnectBox->setChecked(false); + m_autoReconnect = false; m_webSocket.close(); + } } void MainWindow::sendClicked() @@ -75,9 +75,9 @@ void MainWindow::sendClicked() return; } - const auto msg = m_ui->lineEditSend->text(); + const auto msg = m_ui->comboBoxSend->currentText(); m_webSocket.sendTextMessage(msg); - m_ui->lineEditSend->clear(); + m_ui->comboBoxSend->setCurrentIndex(m_ui->comboBoxSend->count()); m_ui->plainTextEdit->appendHtml(QStringLiteral("%0 %2: %3
") .arg(QTime::currentTime().toString()) @@ -86,11 +86,35 @@ void MainWindow::sendClicked() .arg(msg)); } +void MainWindow::connectToWebsocket() +{ + const auto url = QUrl::fromUserInput(m_ui->lineEditUrl->text()); + if (url.isEmpty()) + { + QMessageBox::warning(this, tr("Invalid url entered!"), tr("Invalid url entered!")); + return; + } + + if (url.scheme().toLower() != "ws" && + url.scheme().toLower() != "wss") + { + QMessageBox::warning(this, tr("Invalid url entered!"), tr("Only urls starting with ws:// or wss:// are allowed!")); + return; + } + + m_ui->plainTextEdit->appendHtml(QStringLiteral("%0 %1
") + .arg(QTime::currentTime().toString()) + .arg(tr("Connecting to %0").arg(url.toString()))); + + m_webSocket.open(url); +} + void MainWindow::connected() { m_ui->plainTextEdit->appendHtml(QStringLiteral("%0 %1
") .arg(QTime::currentTime().toString()) .arg(tr("Connected"))); + m_autoReconnectTries = 0; } void MainWindow::disconnected() @@ -98,14 +122,32 @@ void MainWindow::disconnected() m_ui->plainTextEdit->appendHtml(QStringLiteral("%0 %1
") .arg(QTime::currentTime().toString()) .arg(tr("Disconnected"))); + if (m_autoReconnect && m_autoReconnectTries < 5) + { + m_ui->plainTextEdit->appendHtml(QStringLiteral("%0 %1
") + .arg(QTime::currentTime().toString()) + .arg(tr("Auto-Reconnecting..."))); + connectToWebsocket(); + m_autoReconnectTries++; + } + else if (m_autoReconnectTries >= 5) + { + m_ui->plainTextEdit->appendHtml(QStringLiteral("%0 %1
") + .arg(QTime::currentTime().toString()) + .arg(tr("Maximum attempts reached."))); + m_ui->autoReconnectBox->setChecked(false); + m_autoReconnect = false; + } } void MainWindow::stateChanged(QAbstractSocket::SocketState state) { m_ui->lineEditUrl->setEnabled(state == QAbstractSocket::UnconnectedState); + m_ui->saveSlot->setEnabled(state == QAbstractSocket::UnconnectedState); + m_ui->pushButtonSave->setEnabled(state == QAbstractSocket::UnconnectedState); m_ui->pushButtonConnect->setText(state == QAbstractSocket::UnconnectedState ? tr("Connect") : tr("Disconnect")); m_ui->labelStatus->setText(qtEnumToString(state)); - m_ui->lineEditSend->setEnabled(state == QAbstractSocket::ConnectedState); + m_ui->comboBoxSend->setEnabled(state == QAbstractSocket::ConnectedState); m_ui->pushButtonSend->setEnabled(state == QAbstractSocket::ConnectedState); } @@ -136,3 +178,38 @@ void MainWindow::pong(quint64 elapsedTime, const QByteArray &payload) { qDebug() << "pong" << elapsedTime; } + +void MainWindow::saveSettings() +{ + QSettings settings; + m_url_slots[m_ui->saveSlot->currentIndex()] = m_ui->lineEditUrl->text(); + for (uint8_t i = 1; i <= m_url_slots.size(); i++) { + settings.setValue("slot"+QString::number(i-1), m_url_slots[i-1]); + } +} + +void MainWindow::loadSettings() +{ + QSettings settings; + for (uint8_t i = 1; i <= m_url_slots.size(); i++) { + QString key = "slot"+QString::number(i-1); + m_url_slots[i-1] = settings.value(key, "ws://localhost:1234/path/to/ws").toString(); + } + loadSelectedUrl(); + saveSettings(); +} + +void MainWindow::loadSelectedUrl() +{ + const auto tmpSocketState = m_webSocket.state(); + m_webSocket.close(); + m_ui->lineEditUrl->setText(m_url_slots[m_ui->saveSlot->currentIndex()]); + + if (tmpSocketState == QAbstractSocket::ConnectedState) + connectToWebsocket(); +} + +void MainWindow::setAutoReconnect(bool state) +{ + m_autoReconnect = state; +} diff --git a/mainwindow.h b/mainwindow.h index dc4da40..9a5202b 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -2,6 +2,7 @@ #include #include +#include #include @@ -18,6 +19,7 @@ public: private slots: void connectClicked(); void sendClicked(); + void connectToWebsocket(); void connected(); void disconnected(); @@ -27,7 +29,16 @@ private slots: void error(QAbstractSocket::SocketError error); void pong(quint64 elapsedTime, const QByteArray &payload); + void saveSettings(); + void loadSettings(); + void loadSelectedUrl(); + + void setAutoReconnect(bool state); + private: const std::unique_ptr m_ui; QWebSocket m_webSocket; + std::array m_url_slots; + bool m_autoReconnect; + uint8_t m_autoReconnectTries{0}; }; diff --git a/mainwindow.ui b/mainwindow.ui index 0d7fbc8..ba49bd0 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -6,10 +6,16 @@ 0 0 - 800 - 600 + 995 + 709 + + + 0 + 0 + + WebSocket Tester @@ -17,6 +23,22 @@ + + + + false + + + + + + -1 + + + 10 + + + @@ -24,6 +46,13 @@ + + + + Save + + + @@ -38,15 +67,47 @@ + + + + true + + + AutoReconnect + + + false + + + false + + + - + + + + 0 + 0 + + + + true + + + + + 80 + 16777215 + + Send